001/**************************************************************************** 002 * Copyright/Copyleft: 003 * 004 * For this source the LGPL Lesser General Public License, 005 * published by the Free Software Foundation is valid. 006 * It means: 007 * 1) You can use this source without any restriction for any desired purpose. 008 * 2) You can redistribute copies of this source to everybody. 009 * 3) Every user of this source, also the user of redistribute copies 010 * with or without payment, must accept this license for further using. 011 * 4) But the LPGL is not appropriate for a whole software product, 012 * if this source is only a part of them. It means, the user 013 * must publish this part of source, 014 * but don't need to publish the whole source of the own product. 015 * 5) You can study and modify (improve) this source 016 * for own using or for redistribution, but you have to license the 017 * modified sources likewise under this LGPL Lesser General Public License. 018 * You mustn't delete this Copyright/Copyleft inscription in this source file. 019 * 020 * @author Hartmut Schorrig: hartmut.schorrig@vishia.de, www.vishia.org 021 * @version 0.93 2011-01-05 (year-month-day) 022 *******************************************************************************/ 023package org.vishia.java2C; 024 025import java.util.Iterator; 026import java.util.List; 027 028import org.vishia.zbnf.ZbnfParseResultItem; 029 030 031/**Describes a method of a class. 032 * <br> 033 * <img src="../../../../Java2C/img/MethodData_omdJava2C.png" /> 034 * <br> 035 * All methods of a class are stored in the private attribute {@link ClassData#methods}, 036 * filled using {@link #addMethod(String sNameJava, String sCName, int modifier, LocalIdents.IdentInfos returnType, ClassData[] paramsType)} 037 * and there derivatives. 038 * <br> 039 * A Method of class can be find out calling {@link ClassData#searchMethod(String, List, boolean)} 040 * with given name and given actual Parameters 041 * 042 * @author JcHartmut 043 * 044 */ 045public class Method 046{ 047 /**Version, history and license. 048 * <ul> 049 * <li>2014-09-05 Hartmut new: Regard a different {@link FieldData#modeAccess} for method arguments and set {@link ClassData.CastInfo#kCastAccessDiff} 050 * to force a access conversion. 051 * <li>2008 Hartmut created: 052 * </ul> 053 * <br><br> 054 * <b>Copyright/Copyleft</b>: 055 * For this source the LGPL Lesser General Public License, 056 * published by the Free Software Foundation is valid. 057 * It means: 058 * <ol> 059 * <li> You can use this source without any restriction for any desired purpose. 060 * <li> You can redistribute copies of this source to everybody. 061 * <li> Every user of this source, also the user of redistribute copies 062 * with or without payment, must accept this license for further using. 063 * <li> But the LPGL is not appropriate for a whole software product, 064 * if this source is only a part of them. It means, the user 065 * must publish this part of source, 066 * but don't need to publish the whole source of the own product. 067 * <li> You can study and modify (improve) this source 068 * for own using or for redistribution, but you have to license the 069 * modified sources likewise under this LGPL Lesser General Public License. 070 * You mustn't delete this Copyright/Copyleft inscription in this source file. 071 * </ol> 072 * If you are intent to use this sources without publishing its usage, you can get 073 * a second license subscribing a special contract with the author. 074 * 075 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 076 */ 077 public final static String sVersion = "2014-09-05"; 078 079 /**Name of the method used in Java. */ 080 public final String sJavaName; 081 082 /**Search name of method in Map {@link ClassData#methods}. It is the {@link #sJavaName} plus <code>#9</code> 083 * where <code>9</code> symbols the number of arguments. 084 * */ 085 public final String sKeyName; 086 087 /**Name of the method used in C, with suffixes. 088 * If the method is able to override, this is not the implementation name 089 * but the name of calling from user. 090 * The implementation of this method uses the method table to call the correct implementation. */ 091 public final String sCName; 092 093 /**<code>The first name of the method in an overridden-sequence. The method has the postfix 094 * of the first declaring interfaces or class, see {@link #declaringClass}. 095 * This identifier is used to build the <code>MT_<i>NAME</i></code>-identifier in the method table, 096 * see {@link ClassData#gen_MethodTableDefinitionContent()}. 097 * <code>null</code> if the method doesn't override any other and the method won't be overridden. 098 * 099 */ 100 public final String sMethodTypeName; 101 102 103 /**Name of the implementation of the method, null if not exists (interface). 104 * If the method is able to override, than the name has the suffix _F. 105 */ 106 public final String sImplementationName; 107 108 109 /**Name of the method in method tables, base name of the method. It is the Java-name 110 * if the method is only found with one set of parameter types. 111 * If the same Java-name is used for several methods with different parameter sets, 112 * this name is unambiguous. It contains the type of paramter as short information. 113 */ 114 public final String sNameUnambiguous; 115 116 117 118 /**Reference to a primary method if the method overloads another method, else null. 119 */ 120 public final Method primaryMethod; 121 122 123 /**If the method is declared in a base class or interface too, it is the path to the method table-part. 124 * Elsewhere it is null. This attribute is able to use also to detect whether the method is virtual. 125 */ 126 public final String sPathToMtbl; 127 128 /**If the method is declared in a base class or interface too, it is the path necessary to address 129 * the base class or interface started from <code>ythis</code> 130 */ 131 public final String sPathToBase; 132 133 /**All argument type of the method. */ 134 public final FieldData[] paramsType; 135 136 /**Return type of the method. */ 137 public final FieldData returnType; 138 139 /**The class which declares the method primary. It may be an interface or superclass 140 * or the creating class itself, if the method are not found in deeper base. 141 */ 142 public final ClassData firstDeclaringClass; 143 144 /**The class which declares the implementation of the method. . */ 145 public ClassData declaringClass; 146 147 /**The idents which are seen in the methods focus. They are the class level idents and the method parameters. 148 * This element remains with null, if the method is only declared, no body is generated 149 * (external classes without code generation). */ 150 private LocalIdents methodIdents; 151 152 /**Set if _thCxt is need in method calls */ 153 public final boolean need_thCxt; 154 155 /**The method head definition is set, if a method is parsed in first pass. 156 * It is used in the second path. 157 */ 158 private String sMethodShortDescription; 159 160 String sReturnTypeDefinition; 161 162 /**The parameter definition after the method name. */ 163 String sMethodFormalListDefiniton; 164 165 /**Set if it is a ctor. */ 166 public final static int modeCtor = 0x1; 167 168 /**Set if it is a ctor of a non-static inner class. */ 169 public final static int modeCtorNonStatic = 0x2; 170 171 /**Set if it is a ctor of an anonymous class. */ 172 public final static int modeCtorAnonymous = 0x4; 173 174 /**Modifier bit, when set the method has ThCxt as last argument. 175 * If not set, than it is a simple method without exceptions, 176 * so the thread context pointer may be overmuch. 177 */ 178 public final static int modeNoThCxt = 0x0040; 179 180 public final static int modeNoStacktrace = 0x0080; 181 182 /**Modifier bit, when set the method is static. */ 183 public final static int modeStatic = 0x0200; 184 185 /**Modifier bit, when set the method is overrideable (virtual). */ 186 public final static int modeOverrideable = 0x0400; 187 188 /**Modifier bit, when set the method returns the same instance as the calling one. */ 189 public final static int modeReturnThis = 0x0800; 190 191 /**Modifier bit, when set the method returns a new created instance which isn't activated for garbabe collection. */ 192 public final static int modeReturnNew = 0x1000; 193 194 /**Modifier bit, when set, the method returns a StringJc-instance, which's String is replaced in the thread context 195 * or it isn't persistent in other way. */ 196 public final static int modeReturnNonPersistring = 0x2000; 197 198 public final static int modeUnknownMethod = 0x8000; 199 200 /**Some mode bits, ones of {@link #modeNoThCxt}, {@link #modeStatic}. */ 201 public final int mode; 202 203 /**Set true if more as one methode with the same name is stored. */ 204 private boolean bUnambiguousness; 205 206 /**If it is an overrideable method, its number in InheritanceInfo. Else -1. */ 207 private final short idxMtbl= -1; 208 209 /**Initializes a method to store in ClassData. 210 * @param declaringClass The class which declares this method. 211 * @param primaryMethodP <code>null</code> or the method of the super-class or interface. 212 * If the method is not an implementation of a super- or interface-declared method, 213 * it is <code>null</code> 214 * @param sKeyName Name to search 215 * @param sNameJava Name of the method in Java 216 * @param sNameUnambiguous Name of the method to translate in C. If more than 1 method 217 * with the same sNameJava is given, the sCName should be unambiguous. 218 * But it is without suffix of className. 219 * @param sImplementationName null if the implementation is not override-able. 220 * If the method is override-able and this param is null, than the suffix for the 221 * implementationName is "_F". Elsewhere it defines the sImplementationName-attribute of the class. 222 * @param modifier see {@link #mode} 223 * <ul> 224 * <li> {@link #modeNoThCxt} 225 * <li> {@link #modeStatic} 226 * <li> {@link #modeOverrideable} 227 * <li> {@link #modeUnknownMethod} 228 * </ul> 229 * @param returnType The type of return. It isn't a Classdata, but a IdentInfo, 230 * because some additional properties like return by value or reference should be present. 231 * @param params Array of all argument types. 232 * @param sPathToMtbl 233 * @param sPathToBase 234 */ 235 public Method(ClassData declaringClass, Method primaryMethodP 236 , String sKeyName, String sNameJava, String sNameUnambiguous, String sImplementationName 237 , int modifier, FieldData returnType 238 , FieldData[] params, String sPathToMtbl, String sPathToBase) 239 { this.declaringClass = declaringClass; 240 if(returnType !=null && (returnType.getName() == null || returnType.getName().equals("null"))) 241 stop(); 242 //this.firstDeclaringClass = firstDeclaringClass; 243 this.primaryMethod = primaryMethodP == null ? this : primaryMethodP; 244 this.firstDeclaringClass = this.primaryMethod.declaringClass; 245 this.sKeyName = sKeyName; this.sJavaName = sNameJava; 246 this.sPathToMtbl = sPathToMtbl; 247 this.sPathToBase = sPathToBase; 248 if(sNameUnambiguous != null && sNameUnambiguous.startsWith("testIfc")) 249 stop(); 250 if(sNameUnambiguous != null){ 251 boolean bSimpleName = sNameUnambiguous.startsWith("!"); 252 if(bSimpleName) 253 { sNameUnambiguous = sNameUnambiguous.substring(1); 254 } 255 this.sNameUnambiguous = sNameUnambiguous; 256 if(bSimpleName){ 257 this.sCName = this.sMethodTypeName = sNameUnambiguous; 258 if(sImplementationName == null){ this.sImplementationName = sNameUnambiguous; 259 } else { this.sImplementationName = sImplementationName; 260 } 261 } else { 262 this.sCName = sNameUnambiguous + (declaringClass != null ? "_" + declaringClass.getClassIdentName() : ""); 263 this.sMethodTypeName = (firstDeclaringClass != null) 264 ? sNameUnambiguous + "_" + firstDeclaringClass.getClassIdentName() 265 : null; 266 this.sImplementationName = declaringClass != null && declaringClass.isInterface() ? null 267 : sImplementationName != null ? sImplementationName 268 : sCName + ((modifier & modeOverrideable)!= 0 || sKeyName.charAt(0)=='!' ? "_F" : ""); 269 270 } 271 } else { 272 /**The method is only registered to detect ambiguously. */ 273 this.sNameUnambiguous = this.sCName = this.sMethodTypeName = this.sImplementationName = null; 274 } 275 276 this.paramsType = params; this.returnType = returnType; 277 assert( (modifier & ~(modeUnknownMethod|modeNoThCxt|modeStatic|modeOverrideable|modeReturnThis|modeReturnNew|modeNoStacktrace|modeReturnNonPersistring|modeCtor|modeCtorAnonymous|modeCtorNonStatic)) == 0); 278 this.mode = modifier; 279 this.need_thCxt = (modifier & modeNoThCxt) == 0; 280 bUnambiguousness = true; 281 } 282 283 284 /**Arguments of the method. */ 285 //private List<MethodArg> args; 286 287 /**Sets the definiton of a method (C-code). This method could only call one time. */ 288 public void setMethodHeadDefiniton(String description, String retType, String def) 289 { assert(sMethodFormalListDefiniton == null); //set only 1 time. 290 sMethodShortDescription = description; 291 sReturnTypeDefinition = retType; 292 sMethodFormalListDefiniton = def; 293 } 294 295 /**Gets the definition of a method head for the C-code. */ 296 public String gen_MethodForwardDeclaration() 297 { String ret = ""; 298 if(sMethodShortDescription != null){ 299 ret += "\n/**" + sMethodShortDescription + "*/"; 300 } 301 if((mode & modeOverrideable) != 0 && declaringClass == firstDeclaringClass){ 302 /**Only in first declaration level: Method type declaration for Method table. */ 303 ret += "\ntypedef " + sReturnTypeDefinition + " MT_" + sCName + sMethodFormalListDefiniton + ";"; 304 } 305 /**The normal forward declaration: */ 306 if((mode & modeOverrideable)==0){ 307 ret += "\nMETHOD_C " + sReturnTypeDefinition + " " + sCName + sMethodFormalListDefiniton + ";"; 308 } 309 else if( sImplementationName != null //null only on interface definition. 310 && sCName.equals(sImplementationName)) { 311 /**final method, which implements any override-able method: */ 312 ret += "\n/* J2C:Implementation of the method, non-dynamic in this class: */"; 313 ret += "\nMETHOD_C " + sReturnTypeDefinition + " " + sCName + sMethodFormalListDefiniton + ";"; 314 } else { 315 /**Dynamic override-able method: */ 316 if(sImplementationName != null){ 317 ret += "\n/* J2C:Implementation of the method, used for an immediate non-dynamic call: */"; 318 ret += "\nMETHOD_C " + sReturnTypeDefinition + " " + sImplementationName + sMethodFormalListDefiniton + ";"; 319 } 320 ret += "\n/* J2C:Call of the method at this class level, executes a dynamic call of the override-able method: */"; 321 ret += "\nMETHOD_C " + sReturnTypeDefinition + " " + sCName + sMethodFormalListDefiniton + ";"; 322 } 323 ret += "\n"; 324 return ret; 325 } 326 327 328 329 /**Gets the definition of a method head for the C-code. */ 330 public String gen_MethodDefinition() 331 { StringBuilder ret = new StringBuilder(); 332 if(sMethodShortDescription != null){ 333 ret.append("\n/**").append(sMethodShortDescription).append("*/"); 334 } 335 ret.append("\n#define ").append(sCName).append("("); 336 String sSep; 337 if((mode & modeStatic)==0){ 338 ret.append("THIZ"); 339 sSep = ", "; 340 } else { 341 sSep = ""; 342 } 343 344 if(paramsType !=null){ 345 for(int ix=0; ix<paramsType.length; ++ix){ 346 ret.append(sSep).append(paramsType[ix].getName()); 347 sSep = ", "; //for further args 348 } 349 } 350 ret.append(") \\\n"); 351 352 return ret.toString(); 353 } 354 355 356 357 /**Gets the definition of a method (C-code), used in second pass. */ 358 public String gen_MethodHeadDefinition() 359 { if(sImplementationName.startsWith("testIfc_ImplIfc_Test")) 360 stop(); 361 return sReturnTypeDefinition + " " + sImplementationName + sMethodFormalListDefiniton; 362 } 363 364 365 public void putFieldIdent(FieldData field) 366 { 367 methodIdents.putElement(field.getName(), field); 368 } 369 370 371 /**Sets the method ambiguous. This method is called, if a method with the same java name 372 * and the same number of arguments, but other argument types are found in translation process. 373 */ 374 void setAmbiguousness(){ bUnambiguousness = false; } 375 376 377 378 379 /**Checks whether all parameters from an actual method call are matching 380 * @param paramsTypeCheck 381 * @return The score 0..4 see {@link ClassData.CastInfo#kCastAble}. 382 */ 383 int checkParameter(List<CCodeData> paramsTypeCheck) 384 { //boolean bMatching = false; 385 int score; 386 int idxParam = 0; 387 if(paramsTypeCheck == null && (this.paramsType == null || this.paramsType.length == 0)) 388 { score = 3; 389 //bMatching = true; 390 } 391 else 392 { //bMatching = true; //default, abort test if false. 393 score = Integer.MAX_VALUE; //start with highest 394 Iterator<CCodeData> iterParamAct = paramsTypeCheck.iterator(); 395 //while(bMatching && iterParamAct.hasNext()) 396 boolean bVarg = false; 397 while(!bVarg && score > 0 && iterParamAct.hasNext()) 398 { CCodeData actParam = iterParamAct.next(); 399 FieldData infoActParam = actParam.identInfo; 400 FieldData typeParamMethod = this.paramsType[idxParam++]; 401 int scoreParam; 402 if(actParam.cCode.equals("null") && !typeParamMethod.typeClazz.isPrimitiveType()){ 403 scoreParam = 3; //null-pointer matches to all references 404 } 405 else if(typeParamMethod.typeClazz == CRuntimeJavalikeClassData.clazz_va_argRaw){ 406 scoreParam = ClassData.CastInfo.kCastCommon; //maybe matched. 407 bVarg = true; //abort check. 408 } else if(infoActParam.getDimensionArray() >0){ 409 //it is an array, 410 if(typeParamMethod.typeClazz == infoActParam.typeClazz){ 411 if(typeParamMethod.modeAccess == infoActParam.modeAccess){ scoreParam = ClassData.CastInfo.kCastEqual; } 412 else { 413 //Access is different, maybe exist a better variant. 414 scoreParam = ClassData.CastInfo.kCastAccessDiff; 415 } 416 } else if(typeParamMethod.typeClazz == CRuntimeJavalikeClassData.clazzByteStringJc){ 417 scoreParam = ClassData.CastInfo.kCastAble; //all is able to present as ByteStringJc 418 } else if( typeParamMethod.typeClazz == CRuntimeJavalikeClassData.clazzObjectJc 419 && "XY".indexOf(infoActParam.modeAccess) >=0 //an ObjectArrayJc-based array 420 ){ 421 scoreParam = ClassData.CastInfo.kCastAble; //Object as Baseclass 422 } else { 423 scoreParam = ClassData.CastInfo.kCastNo; //does match only to itself or Object 424 } 425 } else { 426 scoreParam = typeParamMethod.typeClazz.matchedToTypeSrc(infoActParam.typeClazz); 427 } 428 if(scoreParam < score) 429 { //bMatching = false; 430 score = scoreParam; //may be 0, than abort check. 431 } 432 } 433 } 434 return score; 435 } 436 437 438 /**Checks all parameter of the method with given parameter set. 439 * @param paramsTypeCheck 440 * @return true only if are the same parameter. 441 */ 442 boolean sameParameterTypes(FieldData[] paramsTypeCheck) 443 { boolean bMatching = false; 444 int idxParam = 0; 445 int zParamsCheck = paramsTypeCheck == null ? 0: paramsTypeCheck.length; 446 int zParamsThis = this.paramsType == null ? 0: this.paramsType.length; 447 bMatching = (zParamsCheck == zParamsThis); //false if different nr of params. 448 while(bMatching && idxParam < zParamsCheck) 449 { //Check params: 450 FieldData infoActParam = paramsTypeCheck[idxParam]; 451 FieldData typeParamMethod = this.paramsType[idxParam++]; 452 //if(!typeParamMethod.typeClazz.matchedTo(infoActParam.typeClazz)) 453 if(typeParamMethod.typeClazz != (infoActParam.typeClazz)) 454 { bMatching = false; 455 } 456 } 457 return bMatching; 458 } 459 460 461 /**Returns true, if more as one method with the same java name and the same number of arguments exists. 462 */ 463 public boolean isAmbigous(){ return !bUnambiguousness; } 464 465 /**Returns true if the method is able to override (dynamic linked) in an inheriting class. */ 466 public boolean noStacktrace(){ return (mode & modeNoStacktrace) != 0; } 467 468 /**Returns true if the method is able to override (dynamic linked) in an inheriting class. */ 469 public boolean isOverrideable(){ return (mode & modeOverrideable) != 0; } 470 471 /**Returns true if the method returns its own calling instance. */ 472 public boolean isReturnThis(){ return (mode & modeReturnThis) != 0; } 473 474 /**Returns true if the method returns a new instance which isn't activated for garbage collection. */ 475 public boolean isReturnNew(){ return (mode & modeReturnNew) != 0; } 476 477 /**Returns true if the method returns a new instance which isn't activated for garbage collection. */ 478 public boolean isReturnNonPersistring(){ return (mode & modeReturnNonPersistring) != 0; } 479 480 /**Returns true if the method is static. */ 481 public boolean isStatic(){ return (mode & modeStatic) != 0; } 482 483 /**Returns true if the method is auto-created while used, it is not defined. */ 484 public boolean isUnknownMethod(){ return (mode & modeUnknownMethod) != 0; } 485 486 487 /**Writes the structure information of the method for file.stc. The structure information is parsed 488 * to know the class with its method without processing the first pass of translation, 489 * if the file.java is older as existing file.h and file.c 490 * @return String with the informations for the file.stc. 491 */ 492 public String writeStruct() 493 { StringBuffer out = new StringBuffer(200); 494 out.append( sJavaName); 495 496 //if(sNameUnambiguous != sJavaName && sNameUnambiguous.startsWith(sJavaName)){ 497 if(sNameUnambiguous != null && sNameUnambiguous.length() >0 && !sNameUnambiguous.equals(sJavaName)){ 498 if(sNameUnambiguous.startsWith(sJavaName)){ 499 out.append("+").append(sNameUnambiguous.substring(sJavaName.length())); 500 } else { 501 assert(false); //should start always with sJavaName 502 } 503 } 504 String sClassIdentName = declaringClass.getClassIdentName(); 505 int posClassSuffix = sCName.lastIndexOf(sClassIdentName); 506 if(posClassSuffix >= sNameUnambiguous.length()){ 507 int posClassSuffixEnd = posClassSuffix + sClassIdentName.length(); 508 assert(sCName.startsWith(sNameUnambiguous)); 509 out.append("-").append(sCName.substring(sNameUnambiguous.length(), posClassSuffix)); //may be empty. 510 out.append("$"); //ZBNF: [$<?classSuffixName>] 511 if(posClassSuffixEnd > sCName.length()){ 512 out.append("%").append(sCName.substring(posClassSuffixEnd)); //ZBNF: %<$?implementationSuffix> 513 } 514 } 515 if(primaryMethod != null && primaryMethod != this){ 516 out.append(", defined: ").append(primaryMethod.declaringClass.sClassNameJavaFullqualified); 517 out.append(".").append(primaryMethod.sNameUnambiguous); 518 } 519 520 char cSep = ' '; 521 if(mode != 0){ 522 out.append(", mode="); 523 if( (mode & modeCtor) != 0){ out.append(cSep).append("ctor"); cSep = '+'; } 524 if( (mode & modeCtorAnonymous) != 0){ out.append(cSep).append("anonymousCtor"); cSep = '+'; } 525 if( (mode & modeCtorNonStatic) != 0){ out.append(cSep).append("nonStaticCtor"); cSep = '+'; } 526 if( (mode & modeNoStacktrace) != 0){ out.append(cSep).append("noStacktrace"); cSep = '+'; } 527 if( (mode & modeNoThCxt) != 0) { out.append(cSep).append("noThCxt"); cSep = '+'; } 528 if( (mode & modeOverrideable) != 0){ out.append(cSep).append("overrideable"); cSep = '+'; } 529 if( (mode & modeReturnThis) != 0) { out.append(cSep).append("returnThis"); cSep = '+'; } 530 if( (mode & modeReturnNew) != 0) { out.append(cSep).append("returnNew"); cSep = '+'; } 531 if( (mode & modeReturnNonPersistring) != 0) { out.append(cSep).append("returnNonPersistring"); cSep = '+'; } 532 if( (mode & modeStatic) != 0) { out.append(cSep).append("static"); cSep = '+'; } 533 } 534 535 out.append(": "); 536 //out = sJavaName + "; " + sNameUnambiguous + "; " + sCName + "; " + sImplementationName + "; " + sMethodTypeName + "; "; 537 out.append(returnType == null ? "void_ C.. return; " : returnType.writeStruct()); 538 if(out.indexOf("null") >0) 539 stop(); 540 out.append("("); 541 { String separator = ""; 542 if(paramsType != null && paramsType.length >0) 543 for(FieldData param: paramsType) 544 { out.append(separator).append(param.writeStruct()); 545 separator = ","; 546 } 547 out.append(")"); 548 } 549 out.append(";"); 550 /* 551 out.append("//info" 552 + "; mode=0x"+ Integer.toHexString(mode) 553 + "; sKeyName=" + sKeyName 554 + "; sCName=" + sCName 555 + "; sMethodTypeName=" + sMethodTypeName 556 + "; sImplementationName="+ sImplementationName 557 + "; primaryMethod.sCName="+ primaryMethod.sCName 558 + "; sPathtoBase="+ sPathToBase 559 + "; sPathToMtbl="+ sPathToMtbl 560 + "; firstDeclaringClass.sClassNameC="+ firstDeclaringClass.sClassNameC 561 //only for own generation: + "; sMethodFormalListDefiniton="+ sMethodFormalListDefiniton 562 + "\n"; 563 */ 564 return out.toString(); 565 } 566 567 /**Returns -1 if it is a final method, or 0..., the index in the InheritanceInfo. */ 568 public int getIdxMtbl(){ return idxMtbl; } 569 570 571 /**Helpfull for debugging in eclipse. 572 * @see java.lang.Object#toString() 573 */ 574 @Override 575 public String toString() 576 { return sCName; 577 } 578 579 public final LocalIdents getMethodIdents(){ return methodIdents;} 580 581 public final void setMethodIdents(LocalIdents methodIdents) 582 { assert(this.methodIdents == null); //call only one time! 583 this.methodIdents = methodIdents; 584 } 585 586 void stop(){} 587 588 589 590 591 592 593} 594