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