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 ist 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 JcHartmut: hartmut.schorrig@vishia.de
021 * @version 0.82
022 * list of changes:
023 * 2008-04-06 JcHartmut: some correction
024 * 2008-03-15 JcHartmut: creation
025 *
026 ****************************************************************************/
027package org.vishia.java2C;
028
029import java.io.File;
030import java.io.FileNotFoundException;
031import java.io.IOException;
032import java.text.ParseException;
033import java.util.Iterator;
034import java.util.LinkedList;
035import java.util.List;
036import java.util.Map;
037import java.util.Set;
038import java.util.TreeMap;
039
040import org.vishia.java2C.ClassData.InitInfoVariable;
041import org.vishia.mainCmd.Report;
042import org.vishia.zbnf.ZbnfParseResultItem;
043
044/**This class processes the first pass of translating Java to C of a detect class in a java file.
045 * Parsing the content of the java file is done before, see {@link GenerateFile}.
046 * In the first pass all declared elements of a class are captured and store in the {@link ClassData}.  
047 * 
048 * @author JcHartmut
049 *
050 */
051public class FirstPass extends GenerateClass
052{
053  
054  /**Version, history and license.
055   * <ul>
056   * <li>2014-08-16 Hartmut new: call {@link ClassData#completeOverriddenMethods()} as last action of {@link #write_HeaderContent(StringBuilder, GenerateFile, ZbnfParseResultItem, boolean, String, ClassData, ClassData[])}.
057   * <li>2014-08-16 Hartmut new: {@link #gatherAllDefinitions()} before running {@link #runFirstPass2(StringBuilder)} because for generation methods as C-MACROs (#define)
058   *   all definitions of variables should be known. 
059   * <li>2014-08-16 Hartmut new: @Java4C.exclude for varariable definitions. 
060   * <li>2014-01-12 Hartmut new: The 'Java4C.inline' annotation is realized. It generates a define for C.
061   *   TODO: While generating the statements of a inline method other methods are not known yet in the {@link ClassData}
062   *   because there are not registered yet calling {@link #gen_methodHeadAndRegisterMethod(ZbnfParseResultItem, int, ClassData, ClassData, String, FieldData, FieldData[], boolean, boolean)}.
063   *   First all methods should be registered. After them the header file should be generated. 
064   *   Yet called methods should be declared before calling methods in the Java source.
065   * <li>2014-01-10 Hartmut chg: second parameter 'classMethodBody' in gen_methodHeadAndRegisterMethod(...) 
066   *   is identical with 'classContainsMethod' usually, but not if it is a ctor of an inner non static class.
067   *   The bug, class variable are not known in a inner ctor, are resolved therewith. 
068   * <li>2008 Hartmut created:    
069   * </ul>
070   * <br><br>
071   * <b>Copyright/Copyleft</b>:
072   * For this source the LGPL Lesser General Public License,
073   * published by the Free Software Foundation is valid.
074   * It means:
075   * <ol>
076   * <li> You can use this source without any restriction for any desired purpose.
077   * <li> You can redistribute copies of this source to everybody.
078   * <li> Every user of this source, also the user of redistribute copies
079   *    with or without payment, must accept this license for further using.
080   * <li> But the LPGL ist not appropriate for a whole software product,
081   *    if this source is only a part of them. It means, the user
082   *    must publish this part of source,
083   *    but don't need to publish the whole source of the own product.
084   * <li> You can study and modify (improve) this source
085   *    for own using or for redistribution, but you have to license the
086   *    modified sources likewise under this LGPL Lesser General Public License.
087   *    You mustn't delete this Copyright/Copyleft inscription in this source file.
088   * </ol>
089   * If you are intent to use this sources without publishing its usage, you can get
090   * a second license subscribing a special contract with the author. 
091   * 
092   * @author Hartmut Schorrig = hartmut.schorrig@vishia.de
093   */
094  public final static String sVersion = "2014-08-17"; 
095
096
097  
098  
099
100  private List<FirstPass> innerClasses;
101  
102  private ZbnfParseResultItem zbnfClass;
103  
104  /**Created on {@link #gatherAllDefinitions(GenerateFile, ZbnfParseResultItem)}, used in {@link #runFirstPass2(StringBuilder)}
105   * 
106   */
107  private StatementBlock statementBlockClassLevel;
108  
109  boolean bDontWriteCtor;
110        
111  /**initializes the instances with the given associations. */ 
112  //FirstPass(iWriteContent writeContent, TreeMap<String, ClassData> pkgIdents, RunRequiredFirstPass_ifc runRequiredFirstPass)
113  FirstPass(iWriteContent writeContent, GenerateFile parentGenerateFile
114  , LocalIdents fileLevelIdents, RunRequiredFirstPass_ifc runRequiredFirstPass
115  , Report log
116  )
117  { super(writeContent, parentGenerateFile, fileLevelIdents, runRequiredFirstPass, log, true);
118  }
119
120
121  /**Builds the type information of the given class or interface and recursively 
122   * all of its inner classes and interfaces. This creates the {@link ClassData} 
123   * of the class or interface. It is the first pass of the translation. 
124   * <br><br>
125   * All internal classes and interfaces are detect, this method is called recursively with it.
126   * @param sourceOfClassDataP Info for message on errors, where the ClassData comes from. 
127   *        The name of the class will be added in form "sourceOfClassDataP-className" then. 
128   * @param fileContainsClass The generation environment
129   * @param sFileName Name of the file for C without extension .c or .h, not the Java-filename
130   *        It is stored in the created ClassData of the class
131   *        to allow the generating of a include statement, if another class uses this class.
132   * @param sPkgIdent Package where the Java file is found. With <code>/</code> as Separator and at end.
133   * @param sPrefix To Build the Classname for C
134   * @param sPostfix To Build the Classname for C.
135   * @param zbnfClass parse result of <code>class::=</code>
136   * @param sOuterClassName "" or the name of the outer class. 
137   *        The name of the outer class is set as prefix of the name of the struct in C
138   * @param outerClassData The outer class data or null, to register the inner class in a outer.
139   * @param listAllClassesForSecondPath List to add the detect ClassData. 
140   *        The list is used as input for running the second path of classes. 
141   *        See {@link GenerateFile.itemsClassesForSecondPath}.  
142   * @param bInterface
143   * @param identsParent
144   * @return
145   * @throws IOException
146   * @throws ParseException
147   * @throws IllegalArgumentException
148   * @throws IllegalAccessException
149   * @throws InstantiationException
150   */
151  /**
152   * @param uResult
153   * @param sourceOfClassDataP
154   * @param fileContainsClass
155   * @param sFileNameC
156   * @param sPkgIdent
157   * @param sPrefixClassCname
158   * @param sSuffixClassCname
159   * @param zbnfClass
160   * @param bDontWriteCtor
161   * @param sOuterClassName
162   * @param outerClassData
163   * @param listAllClassesForSecondPath
164   * @param bInterface
165   * @param classBase
166   * @param intension C: inner class, P: file-level (primary) class, Y: class level anonymous, 
167   *                     other: anonymous inner class at statement block level
168   * @return
169   * @throws IOException
170   * @throws ParseException
171   * @throws IllegalArgumentException
172   * @throws IllegalAccessException
173   * @throws InstantiationException
174   */
175  ClassData buildType
176  ( StringBuilder uResult
177  , String sourceOfClassDataP
178  , GenerateFile fileContainsClass
179  , String sFileNameC
180  , String sPkgIdent    
181  , String sPrefixClassCname, String sSuffixClassCname
182  , ZbnfParseResultItem zbnfClass
183  , boolean bDontWriteCtor
184  , String sOuterClassName
185  , ClassData outerClassData
186  , List<ClassData> listAllClassesForSecondPath
187  , boolean bInterface
188  , ClassData classBase
189  , char intension
190  //, String sFirstInterfaceType
191  )
192  throws IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
193  {
194        this.zbnfClass = zbnfClass;
195        this.bDontWriteCtor = bDontWriteCtor;
196    ZbnfParseResultItem itemClassDescription = zbnfClass.getChild("description");
197    /**true if the class has the modifier static, Java-syntax: */
198    boolean bStaticClass = zbnfClass.getChild("static")!=null;
199    boolean bAbstractClass = zbnfClass.getChild("abstract")!=null;
200    /**true if the class isn't handled by GC, it is a java2c-annotation: */
201    boolean bStaticInstance =  itemClassDescription != null
202                            && itemClassDescription.getChild("staticInstance")!= null;
203    boolean bFinal = zbnfClass.getChild("final")!= null;
204    ZbnfParseResultItem itemClassIdent = zbnfClass.getChild("classident");
205    /**itemClassIdent is null if it is an anonymous class. */
206    final String sClassNameLocal;
207    if(itemClassIdent !=null){
208        sClassNameLocal =itemClassIdent.getParsedString();
209    } else {
210        /**Anonymous inner class: the variable name is given with the param sPrefixName. 
211         * Build a className specially, the source code doesn't contain a class name.*/
212        sClassNameLocal = sPrefixClassCname;
213    }
214    if(sClassNameLocal.equals("TestThread"))
215      stop();
216    //The sourceOfClassData ist build with path/file.java-className-innerClassname
217    final String sourceOfClassData = sourceOfClassDataP + "-" + sClassNameLocal;
218    final String sClassNameC;
219    final String sClassNameJava;
220    
221    LocalIdents localIdentsTypes = outerClassData !=null ? outerClassData.classLevelIdents
222                                         : fileLevelIdents;
223    final ClassData firstInterface;
224    final ClassData superClazz;
225    if(classBase != null && !classBase.isInterface()){
226        superClazz = classBase;
227        firstInterface = null;
228    } else {
229      superClazz = zbnfResultSuperclass(zbnfClass, itemClassDescription, outerClassData);
230      firstInterface = classBase;  //may be null
231    }
232    ClassData[] ifcClassData = zbnfResultInterfaces(zbnfClass, itemClassDescription, localIdentsTypes, firstInterface);
233    
234    String sProp = "+";
235    if(bStaticInstance){sProp +="static+"; }
236    if(bFinal){sProp +="final+"; }
237    if(bAbstractClass){sProp +="abstract+"; }
238    if(bInterface){sProp +="interface+"; }
239    if(outerClassData != null)
240    { //sClassNameC = outerClassData.getClassIdentName() + "__" + sClassNameLocal;
241        if(!bStaticClass){ sProp += "nonStaticInner+"; }
242      sClassNameC = sClassNameLocal + "_" + outerClassData.getClassIdentName(); //+ sOuterClassName;
243      sClassNameJava = sClassNameLocal;  ////
244      Java2C_Main.singleton.console.reportln(Report.debug, "Java2C-FirstPass.buildType-inner: src=" + sourceOfClassData
245        + ", name=" + sClassNameC);
246      //NOTE: use sClassName for classData from outer class "__" + read from itemClassIdent 
247      classData = new ClassData(sourceOfClassData, fileContainsClass, sFileNameC, sPkgIdent, sClassNameJava, sClassNameC + "_s"
248          , "XX", 'L', outerClassData, superClazz, ifcClassData, zbnfClass
249          , '*', sProp, intension);
250      //An inner class is known in the outer by name. This type is known also in all other inner classes.
251      //Therefore it is part of the classlevelIdents.
252      outerClassData.classLevelIdents.putClassType(sClassNameLocal, classData);
253      //The inner class is known to completion idents after running its first pass
254      //and to build the stc-file.       
255      outerClassData.addInnerClass(classData);
256    }
257    else
258    { //NOTE: use sClassName for classData only read from itemClassIdent 
259      //NOTE: if sSuffixClassCname == null, then the full class name is given as prefix.
260        //       The suffix may be empty. The suffix is != null but empty if "prefix*" is written in the config file.
261        sClassNameC = sPrefixClassCname + (sSuffixClassCname != null ?  sClassNameLocal + sSuffixClassCname : "");
262      sClassNameJava = sClassNameLocal;
263      Java2C_Main.singleton.console.reportln(Report.debug, "Java2C-FirstPass.buildType: src=" + sourceOfClassData
264        + ", name=" + sClassNameC);
265      classData = new ClassData(sourceOfClassData, fileContainsClass, sFileNameC, sPkgIdent, sClassNameJava, sClassNameC + "_s"
266          , "XX", 'L', null, superClazz, ifcClassData, zbnfClass
267          , '*', sProp, intension);
268      //Put in list of this package.
269      //A non-inner class is known in the package by name. Store it to find out later in package by name. */
270      fileLevelIdents.putClassType(sClassNameLocal, classData); 
271      //Register the class just now, to prevent circular call of first pass 
272      // if an one-another internal usage of a class as reference is programmed in Java. */
273      fileContainsClass.registerClassInFile(classData);  //TODO check also from inner classes???
274      
275    }
276    //store the classData to run the second pass later.
277    if(listAllClassesForSecondPath!=null){
278        listAllClassesForSecondPath.add(classData);  //to process in the second path sorted per file
279    }
280    //
281    //run the buildType for all inner classes, so that all inner types are knwon,
282    //before the class-definitions are processed. The inner types may be used for declarations in outer
283    //not in the order of writing in the java-source-file.
284    List<ZbnfParseResultItem> listSubClasses = zbnfClass.listChildren("classDefinition");
285    if(listSubClasses != null)
286    {   innerClasses = new LinkedList<FirstPass>();
287      for(ZbnfParseResultItem itemSubClasses : listSubClasses) {
288        FirstPass innerClassFirst = new FirstPass(writeContent, fileContainsClass, fileLevelIdents, runRequiredFirstPass, log);
289        innerClasses.add(innerClassFirst);
290        innerClassFirst.buildType(uResult, sourceOfClassData, fileContainsClass, sFileNameC, sPkgIdent, null, null
291        , itemSubClasses, bInterface, sClassNameLocal, classData , listAllClassesForSecondPath
292        , false, null, 'C'
293        );
294    } }
295    //
296    //classData.needFinalize();  //set it as default. TODO  
297    return classData;
298  }
299
300  
301  
302  /**Gathers all definitions in this Java source and writes it to the ClassLevelIdents. It is before any inline methods are evaluated.
303   * @throws IOException 
304   * @throws ParseException 
305   * @throws InstantiationException 
306   * @throws IllegalAccessException 
307   * @throws IllegalArgumentException 
308   * @throws FileNotFoundException 
309   * 
310   */
311  void gatherAllDefinitions() 
312  throws FileNotFoundException, IllegalArgumentException, IllegalAccessException, InstantiationException, ParseException, IOException
313  {
314    if(innerClasses != null)
315    { for(FirstPass genClass: innerClasses) {
316        genClass.gatherAllDefinitions();
317    } }
318
319    //The statement block for any usage for classLevel variables.
320    statementBlockClassLevel = new StatementBlock(this,classData.classLevelIdents, true, false, 1);
321    List<ZbnfParseResultItem> listVariables = zbnfClass.listChildren("variableDefinition");
322    if(listVariables != null)
323    for(ZbnfParseResultItem itemVariable : listVariables)
324    { if(itemVariable.getChild("exclude")==null && itemVariable.getChild("static")== null)
325      { //only non static members.
326        { String sVariableName = itemVariable.getChild("variableName").getParsedString();
327          if(sVariableName.equals("stressTest"))
328            stop();
329        }
330        ZbnfParseResultItem zbnfVariableDescription = itemVariable.getChild("description"); //may be null.
331        CCodeData sDef = gen_variableDefinition(
332            itemVariable, zbnfVariableDescription
333        , classData.classLevelIdents
334        , statementBlockClassLevel
335        , classData.getVariablesToInit()
336        , 'C'
337        );
338        statementBlockClassLevel.fieldsNonStatic.add(sDef);
339      }  
340    }
341    if(listVariables != null)for(ZbnfParseResultItem itemVariable : listVariables)
342    { if(itemVariable.getChild("exclude")==null && itemVariable.getChild("static")!= null)
343      { //only static members.
344        ZbnfParseResultItem zbnfVariableDescription = itemVariable.getChild("description"); //may be null.
345        { String sVariableName = itemVariable.getChild("variableName").getParsedString();
346          if(sVariableName.equals("empty"))
347            stop();
348        }
349        List<InitInfoVariable> variablesToInit = classData.getVariablesToInit();  //maybe add the variable there.
350        CCodeData sDef = gen_variableDefinition(
351            itemVariable, zbnfVariableDescription
352        , classData.classLevelIdents
353        , statementBlockClassLevel
354        , variablesToInit
355        , 's');
356        statementBlockClassLevel.fieldsStatic.add(sDef);
357      }  
358    }
359    
360  }
361  
362
363  
364  
365  
366  /**Generates the content of a class in the h-file with given ZBNF parse result item of the class.
367   * This is the second part of the first pass of translation.
368   * This routine is called from {@link GenerateFile}.  
369   * <ul>
370   * <li>The detected class-fields are written in a struct in the h-File. 
371   * <li> The static-fields are written in h-file as extern declaration.
372   * <li> The constructors are written as forward declaration in h-file of routines ctor...
373   * <li> The methods are written as forward declaration in h-file.
374   * </ul> 
375   * For fields, the initial values are detected and stored in {@link ClassData#listVariablesToInit}.
376   * This action is done inside the called routine {@link GenerateClass#gen_variableDefinition(ZbnfParseResultItem, LocalIdents, List, char, ClassData[])}.
377   * <br>
378   * The method heads are generated calling {@link #write_methodDeclaration(ZbnfParseResultItem, String, LocalIdents)}. 
379   * @param uResult
380   * @throws IllegalArgumentException
381   * @throws IOException
382   * @throws ParseException
383   * @throws IllegalAccessException
384   * @throws InstantiationException
385   */
386  void runFirstPass2(StringBuilder uResult
387    ) throws IllegalArgumentException, IOException, ParseException, IllegalAccessException, InstantiationException
388  {
389    //Then run the first pass of inner classes.
390    if(innerClasses != null)
391    { for(FirstPass genClass: innerClasses) {
392        genClass.runFirstPass2(uResult);
393    } }
394
395        Java2C_Main.singleton.console.reportln(Report.debug, "Java2C-FirstPass.runFirstPass2: name=" + classData.sClassNameC);
396    
397    if(classData.getClassNameJava().equals("ExpandedDataStruct"))
398      stop();
399    //setInitialTypeIdentifiers();
400
401    /**Generate content of header: */
402    { List<ZbnfParseResultItem> listSubInterfaces = zbnfClass.listChildren("interfaceDefinition");
403      if(listSubInterfaces != null)
404      { for(ZbnfParseResultItem itemSubInterfaces : listSubInterfaces)
405        { write_Interface(itemSubInterfaces, classData.sClassNameJava + "__", classData, uResult);
406      } }
407    }
408
409    /**Inner classes will be written before, The types {@link ClassData} are known. 
410     * now generate the classdata-content of the own class.
411     * This call may call recursive this method if some other files should be translated.  
412     * */ 
413    write_HeaderContent(uResult, classData.fileContainsClass, zbnfClass, bDontWriteCtor, classData.sClassNameC, classData.getSuperClassData(), classData.getInterfaces());
414    //writeContent.writeClassH(uHeader.toString());  //TODO inner classes in body: write in the C-file.
415    //
416    /**The identifier of the outer class are known yet, 
417     * it should be transported to all non-static inner classes too 
418     * because they should be known there: */
419    if(classData.sClassNameJava.equals("MainController"))
420      stop();
421    //After finishing the first pass, all indentifiers are known. The inner classes are built before.
422    //But all identifiers of the outer class should be known to run the second pass.
423    //Therefore they are completed now.
424    classData.completeFieldIdentsForInnerClasses();
425    
426  }
427  
428  
429
430  /**Gets the superClass from ZBNF parse result item.
431   * @param zbnfClass The parse result item of <code>classDefinition::=...</code>
432   * @param zbnfDescription The parse result item of <code>< description>... test_description::=</code>
433   *        inside the <code>classDefinition::=...</code>  
434   * @param outerClassData a given outerclass
435   * @return The ClassData of the superClass. It is {@link Java2C_Main.CRuntimeJavalikeClassData#clazzObjectJc}
436   *         if no superclass is given in Java-code (no <code>extends ...</code>). 
437   *         It is null if the description contains <code>@java2c=noObject.</code> and no other superclass is given.
438   * @throws FileNotFoundException The Superclass may be translated yet nested, it may be cause some errors. 
439   * @throws IllegalArgumentException Errors see {@link #runFirstPassClass(GenerateFile, String, String, String, String, ZbnfParseResultItem, String, ClassData, List, boolean, LocalIdents)}.
440   * @throws IOException
441   * @throws IllegalAccessException
442   * @throws InstantiationException
443   * @throws ParseException 
444   */
445  ClassData zbnfResultSuperclass(ZbnfParseResultItem zbnfClass, ZbnfParseResultItem zbnfDescription, ClassData outerClassData) 
446  throws FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException, ParseException
447  { final ClassData superClazz;
448    boolean bNoObject =  zbnfDescription != null && zbnfDescription.getChild("noObject")!= null;
449    if(bNoObject)
450      stop();
451    final ZbnfParseResultItem zbnfSuperClass = zbnfClass.getChild("Superclass");
452    if(zbnfSuperClass != null)
453    { String sSuperClass = zbnfSuperClass.getParsedString();
454      stop();
455      if(outerClassData != null)
456      { /*If there is an outer class, the superclass may be part of them or may be known in the file. */
457        //superClazz = outerClassData.classLevelIdents.getTypeContingentlyRunFirstPass(sSuperClass, runRequiredFirstPass);
458        superClazz = outerClassData.classLevelIdents.getType(sSuperClass, fileLevelIdents);
459      }
460      else {
461        //superClazz = fileLevelIdents.getTypeContingentlyRunFirstPass(sSuperClass, runRequiredFirstPass);
462        superClazz = fileLevelIdents.getType(sSuperClass, null);
463      }
464    }
465    else
466    {
467      superClazz = bNoObject ? null : CRuntimeJavalikeClassData.clazzObjectJc;
468    }
469    return superClazz;
470  }  
471
472  
473  
474  
475  
476  /**Gets the interfaces from ZBNF parse result item.
477   * @param zbnfClass The parse result item of <code>classDefinition::=...</code>
478   * @param zbnfDescription The parse result item of <code>< description>... test_description::=</code>
479   *        inside the <code>classDefinition::=...</code>  
480   * @param outerClassData a given outerclass
481   * @param sFirstInterface name of the interface for anonymous classes
482   * @return Array of ClassData[] of all Interfaces. If the class hasn't interfaces, it is null.
483   * @throws FileNotFoundException The Superclass may be translated yet nested, it may be cause some errors. 
484   * @throws IllegalArgumentException Errors see {@link #runFirstPassClass(GenerateFile, String, String, String, String, ZbnfParseResultItem, String, ClassData, List, boolean, LocalIdents)}.
485   * @throws IOException
486   * @throws IllegalAccessException
487   * @throws InstantiationException
488   * @throws ParseException 
489   */
490  private ClassData[] zbnfResultInterfaces
491  ( ZbnfParseResultItem zbnfClass, ZbnfParseResultItem zbnfDescription
492  , LocalIdents localIdentsIfcType
493  //            , ClassData outerClassData
494  , ClassData firstInterface) 
495  throws FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException, ParseException
496  { final ClassData[] interfaceClazzes;
497    int ixIfc = firstInterface !=null ? 1 : 0;
498    final List<ZbnfParseResultItem> zbnflistInterfaces = zbnfClass.listChildren("ImplementedInterface");
499    if(zbnflistInterfaces != null){
500      interfaceClazzes = new ClassData[zbnflistInterfaces.size() + ixIfc];  //+1 if sFirstInterface given.
501      for(ZbnfParseResultItem zbnfInterface: zbnflistInterfaces)
502      { String sIdentInterface = zbnfInterface.getParsedString();
503        //if(outerClassData != null)
504        { /*If there is an outer class, the superclass may be part of them or may be known in the file. */
505          //interfaceClazzes[ixIfc] = outerClassData.classLevelIdents.getType(sIdentInterface, fileLevelIdents);
506        }
507        //else {
508          //interfaceClazzes[ixIfc] = fileLevelIdents.getTypeContingentlyRunFirstPass(sIdentInterface, runRequiredFirstPass);
509          ClassData ifcClass = localIdentsIfcType.getType(sIdentInterface, fileLevelIdents);
510          if(ifcClass == null) 
511            throw new IllegalArgumentException("unknown class: " + sIdentInterface);
512          interfaceClazzes[ixIfc] = ifcClass;  
513        //}
514        ixIfc +=1;
515      }
516    }
517    else
518    { if(ixIfc ==1){ interfaceClazzes = new ClassData[1]; 
519      } else { interfaceClazzes = null;
520      }
521    }
522    if(firstInterface !=null){
523      interfaceClazzes[0] = firstInterface;  
524    }
525    return interfaceClazzes;
526  }  
527
528  
529  
530  
531  
532  
533  
534  
535  /**Write out the header part of the class.
536   * It writes:
537   * <pre>
538   * /*@CLASS_C NAME @@@@@@@@@@@@@@@@@@@@@* /
539   * typedef struct NAME_t
540   * { union base_{ ObjectJc object; SUPER super; IFC IFC; } base
541   *   VARIABLETYPE VARIABLENAME;
542   * } NAME_s;
543   * 
544   * typedef struct NAME_Y_t { ObjectArrayJc head; " + NAME + "_s data[50]; } NAME_Y;");
545   * 
546   * extern_C struct ClassJc_t const reflection_NAME_s;
547   *
548   * extern STATICVARIABLEDEF NAME;
549   * 
550   * ...etc TODO  
551   * </pre>  
552   * @param uHeader The buffer for output.
553   * @param fileContainsClass The calling instance.
554   * @param zbnfClass The parse result item of the class definition.
555   * @param bDontWriteCtor if it is an interface or anonymous class.
556   * @param sClassNameC The name, it is dissolved already from zbnfClass
557   * @param superClazz The superclass or ObjectJc or null
558   * @param ifcClassData null or interfaces
559   *
560   * @throws FileNotFoundException
561   * @throws IllegalArgumentException
562   * @throws ParseException
563   * @throws IOException
564   * @throws IllegalAccessException
565   * @throws InstantiationException
566   */
567  private void write_HeaderContent
568  ( StringBuilder uHeader
569  , GenerateFile fileContainsClass
570  , ZbnfParseResultItem zbnfClass
571  , boolean bDontWriteCtor
572  , String XXXsClassNameC
573  , ClassData superClazz
574  , ClassData[] ifcClassData
575  ) 
576  throws FileNotFoundException, IllegalArgumentException, ParseException, IOException, IllegalAccessException, InstantiationException
577  { String sClassNameC = classData.getClassIdentName();
578        uHeader.append("\n\n/*@CLASS_C " + sClassNameC + " @@@@@@@@@@@@@@@@@@@@@@@@*/");
579    uHeader.append("\n\ntypedef struct " + sClassNameC + "_t\n{ ");
580    ClassData superClass = classData.getSuperClassData();
581    if(superClass != null || ifcClassData != null)
582    { uHeader.append("\n  union { ");
583      if(superClass !=null){
584                final String sNameSuper; sNameSuper = (superClass).sClassNameC;
585              if(superClass.isBasedOnObject() || sNameSuper.equals("ObjectJc"))
586              { /**either the superclass based on or is an Object: */
587                uHeader.append("ObjectJc object; ");
588              }
589              if(!sNameSuper.equals("ObjectJc"))
590              { uHeader.append(sNameSuper + " super;");
591                fileContainsClass.addIncludeH(superClazz.sFileName, "superclass");
592              }
593      }
594      if(ifcClassData != null) for(ClassData ifc: ifcClassData)
595      { String sNameIfc_s = ifc.sClassNameC;
596        String sNameIfc = ifc.getClassIdentName();
597        uHeader.append(sNameIfc_s+ " " + sNameIfc +";");  //Type and name are identical
598        fileContainsClass.addIncludeH(ifc.sFileName, "interface");
599      }
600      uHeader.append("} base; ");
601    }
602    else
603      stop();
604    ClassData outerClass = classData.getOuterClass();
605    //if( outerClass !=null)   ////TODO next is correct. 
606    if(classData.isNonStaticInner)
607    { /*implicit  reference to the outer class: */
608      uHeader.append("\n  struct " + outerClass.getClassIdentName() + "_t* outer;  //J2C: Reference to outer class, implicit in Java");
609    }
610    //if(outerClass )
611    
612    if(sClassNameC.equals("ImplIfc_TestAll"))
613      stop();
614    
615    //process the class Content, write all class variable in the struct
616    for(CCodeData sDef: statementBlockClassLevel.fieldsNonStatic) {
617      uHeader.append("\n  " + sDef.cCode);
618      
619    }
620    
621    uHeader.append("\n} " + sClassNameC + "_s;\n  \n");
622    uHeader.append("\n#define sizeof_" + sClassNameC + "_s sizeof(" + sClassNameC + "_s)\n");
623
624    uHeader.append("\n\n/**J2c: Definitions of the enhanced reference. It's conditinally because it may be defined in a included header before. */");
625    uHeader.append("\n#ifndef " + sClassNameC + "REFDEF");
626    uHeader.append("\n  //J2C: definition of enhanced reference where it was need firstly: ");
627    uHeader.append("\n  #define " + sClassNameC + "REFDEF");
628    uHeader.append("\n  struct " + sClassNameC + "_t;");
629    /*
630    uHeader.append("\n  #ifdef STRUCT_REFJc");
631    uHeader.append("\n    //J2C: macro STRUCT_REFJc should be defined in <fw_Platform_conventions.h> ");
632    uHeader.append("\n    typedef struct " + sClassNameC + "REF_t STRUCT_REFJc(struct " + sClassNameC + "_t) " + sClassNameC + "REF;");
633    uHeader.append("\n  #else");
634    uHeader.append("\n    //J2C: simple reference instead enhanced reference if macro is not defined");
635    uHeader.append("\n    #define " + sClassNameC + "REF struct " + sClassNameC + "_t* ");
636    uHeader.append("\n  #endif");
637    */
638    uHeader.append("\n  DEFINE_EnhancedRefJc("  + sClassNameC + ");");
639    uHeader.append("\n#endif");
640    uHeader.append("\n\n/**J2c: Definitions of the array forms. NOTE: The number of elements are a helper for debug, the really used number depends on the memory size! */");
641    uHeader.append("\ntypedef struct " + sClassNameC + "_X_t { ObjectArrayJc head; " + sClassNameC + "REF data[50]; } " + sClassNameC + "_X;");
642    uHeader.append("\ntypedef struct " + sClassNameC + "_Y_t { ObjectArrayJc head; " + sClassNameC + "_s data[50]; } " + sClassNameC + "_Y;");
643    
644    uHeader.append("\n\n extern_C struct ClassJc_t const reflection_" + sClassNameC + "_s;\n  \n");
645
646    uHeader.append("\n\n/**CONST_Type useable as initializer for embedded/stack-instances*/\n");
647    uHeader.append("#define CONST_").append(sClassNameC).append("(OBJP) { CONST_ObjectJc(sizeof(")
648           .append(sClassNameC).append("_s), OBJP, &reflection_").append(sClassNameC).append("_s), 0 }\n\n");
649
650    uHeader.append("/**J2C: finalize declaration. It is called by Garbage collector and inside other finalized methods.\n")
651           .append(" * It should be called by the user if the instance is removed. */\n")
652           .append("void finalize_")
653           .append(sClassNameC);
654    if(classData.isBasedOnObject()){
655        uHeader.append("_F(ObjectJc* othis, ThCxt* _thCxt);\n\n");
656    } else {
657        uHeader.append("_F(").append(sClassNameC).append("_s* thiz, ThCxt* _thCxt);\n\n");
658    }
659    
660    //process the class Content, write all class variable in the struct
661    for(CCodeData sDef: statementBlockClassLevel.fieldsStatic) {
662      if(sDef.identInfo.modeStatic=='d'){
663        uHeader.append("\n" + sDef.cCode);
664      }else{
665        uHeader.append("\n extern " + sDef.cCode);
666      }
667      
668    }
669    uHeader.append("\n\n");
670    
671    if(!bDontWriteCtor){
672      writeCtor(zbnfClass, outerClass, uHeader);
673    }
674    
675    { List<ZbnfParseResultItem> listMethods = zbnfClass.listChildren("methodDefinition");
676      if(listMethods != null)
677      { 
678        for(ZbnfParseResultItem itemMethod : listMethods)
679        { String sName = itemMethod.getChild("name").getParsedString();
680          //register the method with following "?" to test if it is ambiguous.
681          classData.testAndSetAmbiguousnessOfMethod(sName);
682        } 
683        for(ZbnfParseResultItem itemMethod : listMethods)
684        { boolean bExclude = itemMethod.getChild("exclude") !=null;
685          if(!bExclude){
686            boolean bInline;
687            ZbnfParseResultItem zbnfBody = itemMethod.getChild("methodbody");
688            if(zbnfBody !=null){
689              List<ZbnfParseResultItem> listStatements = zbnfBody.listChildren();
690              bInline = itemMethod.getChild("inline") !=null 
691                ; //|| listStatements !=null && listStatements.size() ==1 && listStatements.get(0).getChild("return")!=null;
692              //note: bDefine if the method contains only the return statement.
693            } else { 
694              bInline = false; 
695            }
696            if(bInline){
697              write_methodInline(itemMethod, sClassNameC, classData.classLevelIdents, uHeader);
698            } else {
699              write_methodDeclaration(itemMethod, sClassNameC, classData.classLevelIdents, uHeader);
700            }
701          }
702        } 
703      }
704    }
705    
706    if(classData.isFinalizeNeed()){
707      /**Finalize is not written in Java, but need because enhanced references: */
708      classData.addMethod("finalize", "finalize", Method.modeOverrideable, CRuntimeJavalikeClassData.clazz_void.classTypeInfo);
709    }
710    if(classData.inheritanceInfo != null){
711      classData.completeInheritanceWithOwnMethods();
712    }  
713    //check all super implementations whether methods exists.
714    classData.completeOverriddenMethods();
715    
716    if(classData.isBasedOnObject()){
717      write_Mtbl(uHeader);
718    }
719    write_ClassCpp(uHeader);
720  }  
721  
722  
723  
724  
725  /**
726   * @param zbnfClass
727   * @param outerClass
728   * @param uHeader
729   * @throws IllegalArgumentException
730   * @throws IOException
731   * @throws ParseException
732   * @throws IllegalAccessException
733   * @throws InstantiationException
734   */
735  private void writeCtor(ZbnfParseResultItem zbnfClass, ClassData outerClass
736  //, boolean bInterface
737  , StringBuilder uHeader
738  ) 
739  throws IllegalArgumentException, IOException, ParseException, IllegalAccessException, InstantiationException
740  {
741    /**Generate ctor. */
742    final ClassData classOfCtor;  //
743    final ClassData outerClassOfCtor;  //TODO check classOfCtor-usage.
744    final String sNameCtor; // = classData.isBasedOnObject()?  "ctorO" : "ctorM";
745    int modeCtor = Method.modeCtor;
746    if(classData.isNonStaticInner){
747        stop();
748        /**Register the ctor in the outer class, because the ctor is a method of the outer class, using this.new Type. */
749        classOfCtor = outerClass;
750        modeCtor |= Method.modeCtorNonStatic;
751        sNameCtor = (classData.isBasedOnObject()?  "ctorO_" : "ctorM_") + classData.getClassNameJava();
752      //outerClassOfCtor = outerClass;
753    } else {
754        /**Register the ctor as static method in the class, where it constructs. */
755        classOfCtor = classData;
756        sNameCtor = classData.isBasedOnObject()?  "ctorO" : "ctorM";
757    }
758    //if(!bInterface)
759    { List<ZbnfParseResultItem> listConstructors = zbnfClass.listChildren("constructorDefinition");
760      if(listConstructors != null)
761      { boolean bArgumentSensitive = (listConstructors.size() >1);
762        for(ZbnfParseResultItem zbnfConstructor : listConstructors)
763        { Method method = gen_methodHeadAndRegisterMethod(
764                        zbnfConstructor
765                , modeCtor
766                , classOfCtor  //may be outer class if it is a non-static inner class
767                , classData    //ClassData for the method body
768                , sNameCtor
769                , classData.classTypeInfo //return-type
770          , null                    //argTypes-array uninitialized, because zbnfConstructor is given.
771                , bArgumentSensitive
772          , false  
773          );
774          uHeader.append(method.gen_MethodForwardDeclaration());
775          ClassData.MethodWithZbnfItem methodDef = classOfCtor.new MethodWithZbnfItem(method, zbnfConstructor, null, 'c'); 
776          classData.methodsWithZbnf.add(methodDef);
777        }
778      }
779      else
780      { //no constructor found, create a default constructor because all variable initializations should be done.
781        Method method = gen_methodHeadAndRegisterMethod(
782                null
783        , modeCtor
784        , classOfCtor  //may be outer class if it is a non-static inner class
785        , classData    //ClassData for the method body
786        , sNameCtor
787        , classData.classTypeInfo //return-type
788        , null                    //argTypes-array uninitialized, because it haven't args.
789        , false                   //bArgumentSensitive = false. Only one.
790        , false  
791        );
792        uHeader.append(method.gen_MethodForwardDeclaration());
793        ClassData.MethodWithZbnfItem methodDef = classOfCtor.new MethodWithZbnfItem(method, null, null, 'c'); 
794        classData.methodsWithZbnf.add(methodDef);
795      }
796      //uHeader.append("\n\n" + "void finalize_" + sClassNameC + "(ObjectJc* yObj, ThCxt* _thCxt);\n\n");
797    }
798  }
799  
800  
801  private void write_Mtbl(StringBuilder uHeader)
802  {  
803    String sClassIdentName = classData.getClassIdentName();
804    String sClassName_s = classData.getClassCtype_s();
805    boolean isObject;
806    uHeader.append("\n\n/* J2C: Method table contains all dynamic linked (virtual) methods");      
807    uHeader.append("\n * of the class and all super classes and interfaces. */");      
808    uHeader.append("\n extern const char sign_Mtbl_" + sClassIdentName + "[]; //marker for methodTable check");
809    uHeader.append("\ntypedef struct Mtbl_" + sClassIdentName + "_t");      
810    uHeader.append("\n{ ");      
811    String sMtbl = classData.gen_MethodTableDefinitionContent();  //from this class and all its super classes and interfaces.
812    uHeader.append(sMtbl);
813    uHeader.append("\n} Mtbl_" + sClassIdentName + ";\n\n");      
814  }  
815  
816  
817  
818  
819  
820  private void write_ClassCpp(StringBuilder uHeader)
821  {  
822    String sClassIdentName = classData.getClassIdentName();
823    String sClassName_s = classData.getClassCtype_s();
824    boolean isObject;
825    uHeader.append("\n\n#if defined(__CPLUSPLUSJcpp) && defined(__cplusplus)");
826    uHeader.append("\n/* J2C: The C++-class-definition. */");      
827    uHeader.append("\nclass " + sClassIdentName + " : private " + sClassIdentName + "_s" );      
828    uHeader.append("\n{ public:");      
829    String sMethods = classData.gen_ClassCppDefinitionContent(writeContent);  //from this class and all its super classes and interfaces.
830    uHeader.append(sMethods);
831    uHeader.append("\n};\n\n");      
832    uHeader.append("#endif /*__CPLUSPLUSJcpp*/\n\n");
833  }  
834  
835  
836  
837  
838  
839  /**Generates the content of an interface in c- and h-file. 
840   * @throws InstantiationException 
841   * @throws IllegalAccessException 
842   * @throws IllegalArgumentException */
843  void write_Interface(ZbnfParseResultItem itemClass, String sOuterClassName
844                , ClassData outerClassData, StringBuilder uHeader)
845  throws IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
846  {
847    //ZbnfParseResultItem resultItem = resultItemClass.nextSkipIntoComponent(resultItemClass);
848
849    ZbnfParseResultItem itemClassIdent = itemClass.getChild("classident");
850    if(itemClassIdent == null) 
851        throw new IllegalArgumentException("<$?classident> not found in " + itemClass.toString());
852    ZbnfParseResultItem itemDescription = itemClass.getChild("description");
853    if(itemDescription != null)
854    { write_Description(itemDescription, uHeader);
855    }
856
857
858    String sClassName = sOuterClassName + itemClassIdent.getParsedString();
859    uHeader.append("typedef struct " + sClassName + "_t  /*interface*/\n{");
860    uHeader.append("ObjectJc object;");
861
862    if(sClassName == null) throw new ParseException("no className found", 0);
863
864    Iterator<ZbnfParseResultItem> iterMethod = itemClass.iterChildren("methodDefinition");
865    if(iterMethod != null)
866    { while(iterMethod.hasNext())
867      { ZbnfParseResultItem itemMethod = iterMethod.next();
868        write_methodDeclaration(itemMethod, sClassName, classData.classLevelIdents, uHeader);
869    } }
870
871    uHeader.append("\n} " + sClassName + "_i;\n  \n");
872    
873    List<ZbnfParseResultItem> listSubClasses = itemClass.listChildren("classDefinition");
874    if(listSubClasses != null)
875    { for(ZbnfParseResultItem itemSubClasses : listSubClasses)
876      { //runFirstPass(itemSubClasses, sClassName + "__", itemsxxx);
877      }
878    }
879  }
880
881
882
883  /**writes a method-forward-declaration in Headerfile and registers the method to generate definition.
884   * It calls 
885   *
886   * @param zbnfMethod  with syntax methodDefinition::=.
887   * @throws IOException
888   * @throws ParseException
889   * @throws InstantiationException 
890   * @throws IllegalAccessException 
891   * @throws IllegalArgumentException 
892   */
893  public void write_methodDeclaration(ZbnfParseResultItem zbnfMethod, String sClassName
894      , LocalIdents localIdents, StringBuilder uHeader)
895  throws IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
896  { String sNameJava = zbnfMethod.getChild("name").getParsedString();
897    if(sNameJava.equals("getData"))
898      stop();
899    //if(!sName.equals("finalize"))  //NOTE: finalize Method see write_finalizeDefinition()
900    {    
901      //Method method = classData.searchMethod(sName + "?", null);
902      boolean bArgumentSensitive = classData.isAmbiguousnessMethod(sNameJava); //method.isAmbigous();
903      ZbnfParseResultItem itemType = zbnfMethod.getChild("type");
904      ZbnfParseResultItem zbnfDescription = zbnfMethod.getChild("description");
905      ZbnfParseResultItem zbnfReturnDescription = zbnfDescription == null ? null : zbnfDescription.getChild("returnDescription");
906      boolean bReturnNew = zbnfDescription != null && zbnfDescription.getChild("return-new")!= null;
907      char definitionCondition = bReturnNew ? 'n' : 'r';
908      FieldData methodType = createFieldInfo(null, itemType, zbnfReturnDescription, zbnfMethod, null, localIdents, null, null, 'a', definitionCondition); 
909      if(methodType.modeAccess=='&' || methodType.modeArrayElement=='&')
910      { /**A variable-definition of TypeMTB of the type is needed in this source.
911         * Registers the type for the class.
912         * The reference will be defined in the dst.h or dst.c at first. */
913        classData.addMtblRefType(methodType.typeClazz.getClassIdentName(), 'a');  //to define the REF-Type.
914      }
915      Method method = gen_methodHeadAndRegisterMethod(
916        zbnfMethod
917      , 0
918      , classData
919      , classData
920      , sNameJava
921      , methodType         //return-type
922      , null               //argTypes-array uninitialized, because zbnfMethod is given.
923      , bArgumentSensitive
924      , false  
925      );
926      if(sNameJava.equals("finalize")){
927        /**NOTE: finalize Method see write_finalizeDefinition()*/
928        classData.setBodyForFinalize(zbnfMethod);
929      }
930      else {
931        uHeader.append(method.gen_MethodForwardDeclaration());
932      }
933      ClassData.MethodWithZbnfItem methodDef = classData.new MethodWithZbnfItem(method, zbnfMethod, null, 'm'); 
934      classData.methodsWithZbnf.add(methodDef);
935             
936    }
937  }
938
939
940  
941
942  /**writes a method-forward-declaration in Headerfile and registers the method to generate definition.
943   * It calls 
944   *
945   * @param zbnfMethod  with syntax methodDefinition::=.
946   * @throws IOException
947   * @throws ParseException
948   * @throws InstantiationException 
949   * @throws IllegalAccessException 
950   * @throws IllegalArgumentException 
951   */
952  public void write_methodInline(ZbnfParseResultItem zbnfMethod, String sClassName
953      , LocalIdents localIdents, StringBuilder uHeader)
954  throws IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
955  { String sNameJava = zbnfMethod.getChild("name").getParsedString();
956    if(sNameJava.equals("toString"))
957      stop();
958    //Method method = classData.searchMethod(sName + "?", null);
959    boolean bArgumentSensitive = classData.isAmbiguousnessMethod(sNameJava); //method.isAmbigous();
960    ZbnfParseResultItem itemType = zbnfMethod.getChild("type");
961    ZbnfParseResultItem zbnfDescription = zbnfMethod.getChild("description");
962    ZbnfParseResultItem zbnfReturnDescription = zbnfDescription == null ? null : zbnfDescription.getChild("returnDescription");
963    boolean bReturnNew = zbnfDescription != null && zbnfDescription.getChild("return-new")!= null;
964    char definitionCondition = bReturnNew ? 'n' : 'r';
965    FieldData methodType = createFieldInfo(null, itemType, zbnfReturnDescription, zbnfMethod, null, localIdents, null, null, 'a', definitionCondition); 
966    Method method = gen_methodHeadAndRegisterMethod(
967      zbnfMethod
968    , Method.modeNoThCxt   //a define does not need a ThCtx-Parameter
969    , classData
970    , classData
971    , sNameJava
972    , methodType         //return-type
973    , null               //argTypes-array uninitialized, because zbnfMethod is given.
974    , bArgumentSensitive
975    , true  
976    );
977    uHeader.append(method.gen_MethodDefinition());
978    ZbnfParseResultItem zbnfBody = zbnfMethod.getChild("methodbody");
979    StatementBlock statementBlockMethodFrame = new StatementBlock(this, method.getMethodIdents(), true, true, 1);
980    List<ZbnfParseResultItem> listStatements = zbnfBody.listChildren();
981    if(listStatements.size() >=1){
982      //only return statement ?
983      ZbnfParseResultItem zstm = listStatements.get(0);
984      ZbnfParseResultItem zret = zstm.getChild("return");
985      ZbnfParseResultItem zretVal = zret == null ? null : zret.getChild("value");
986      if(zretVal !=null){
987        uHeader.append("(");
988        final CCodeData retValue = statementBlockMethodFrame.gen_value(zretVal, zbnfDescription, zbnfMethod, method.returnType.modeStatic=='r', 'e');
989        String sRetValue = method.returnType.testAndcast(retValue, '.');
990        uHeader.append(sRetValue);
991        uHeader.append(")");
992      } else {
993        //uHeader.append("{  \\\n");
994        String statements = statementBlockMethodFrame.gen_statementBlock(zbnfBody, null, 0, CRuntimeJavalikeClassData.clazz_void.classTypeInfo, this, 'h');;
995        uHeader.append(statements);
996        //uHeader.append("}\n");
997      }
998    } else {
999      stop();
1000    }
1001    uHeader.append("\n");
1002    //String sBody = gen_statementBlock(zbnfBody, 1, statementBlockMethodFrame, method.returnType, 'm');  //it is a statementBlock
1003
1004    //ClassData.MethodWithZbnfItem methodDef = classData.new MethodWithZbnfItem(method, zbnfMethod, null, 'm'); 
1005    //classData.methodsWithZbnf.add(methodDef);
1006             
1007  }
1008
1009
1010  
1011
1012  /**Generates a method head with syntax <code>methodDefinition::=</code> from given ZBNF parse result item
1013   * and registers the method in the classData. The ambiguousness of the method should be tested before this call,
1014   * but the unambiguous method name for C is built here: Methods with equal names but different parameter types 
1015   * are different methods.
1016   * 
1017   * @param zbnfMethod Zbnf item defined in <code>&lt;methodDefinition></code> 
1018   *        or <code>&lt;constructorDefinition></code>. The head hasn't an own zbnf-result item.
1019   *        The following contained elements are tested:
1020   *        <ul>
1021   *        <li><code>&lt;description></code>, calling {@link #get_shortDescription(ZbnfParseResultItem)}
1022   *        <li><code>&lt;static></code> defined in <code>Modifier::=<?></code> 
1023   *        <li><code>&lt;argumentList></code>, calling {@link #gen_methodArguments(ZbnfParseResultItem, LocalIdents, char, String[], List)}
1024   *        </ul>
1025   *        If this argument is null, a default constructor is generated.
1026   * @param modeMethod start value for {@link Method#mode}, addtional bits are set from zbnfMethod
1027   *   Especially checked: {@link Method#modeCtor}, {@link Method#modeCtorNonStatic} 
1028   * xxx@param ctor '.' if it isn't a ctor, 'C'-static ctor of class 'n'-ctor of non-static inner class. 'y'-ctor of anonymous class      
1029   * @param classContainsMethod environment class, for non-static constructors the outer class.
1030   * @param classMethodBody
1031   * @param sMethodNameJava Name of the method, "ctorO" if a constructor from given ObjectJc should be generated.
1032   * @param typeReturn Type of the method, get outside because this routine is also used to generate constructors.
1033   *        On constructor generation this argument should be equal the environment class type. 
1034   * @param argTypes
1035   * @param bArgumentSensitive true than more as one method with the same Java-name exists. 
1036   *        It is tested before calling {@link ClassData#isAmbiguousnessMethod(String)}.
1037   *        The C-name of the method is built regarding the type of the arguments.
1038   * @param bDefine
1039   * @return The created Method. It contains the head definition in one line in its private attribute 
1040   *         {@link Method#sMethodFormalListDefiniton} 
1041   *         promoted in {@link Method#gen_MethodForwardDeclaration()} and 
1042   *         {@link Method#gen_MethodHeadDefinition()}. 
1043   * @throws IOException
1044   * @throws ParseException
1045   * @throws InstantiationException 
1046   * @throws IllegalAccessException 
1047   * @throws IllegalArgumentException 
1048   */
1049  Method gen_methodHeadAndRegisterMethod
1050  ( ZbnfParseResultItem zbnfMethod
1051  , int modeMethod
1052  , ClassData classContainsMethod    
1053  , ClassData classMethodBody    
1054  , String sMethodNameJava
1055  , FieldData typeReturn
1056  , FieldData[] argTypes
1057  , boolean bArgumentSensitive
1058  , boolean bDefine
1059  )
1060  throws IOException, ParseException, IllegalArgumentException, IllegalAccessException, InstantiationException
1061  { LocalIdents methodIdents = new LocalIdents(classMethodBody.classLevelIdents, null);
1062    ZbnfParseResultItem zbnfDescription = zbnfMethod == null ? null : zbnfMethod.getChild("description");
1063    String sDescription = zbnfMethod!=null ? get_shortDescription(zbnfDescription) : "Default constructor. ";
1064    //assert(classOfMethod == classData);  //the argument classOfMethod is unnecessary.
1065    String sNameUnambiguous = sMethodNameJava;
1066    String sArguments;
1067    String sClassName = classContainsMethod.getClassIdentName();
1068    String sMethodClassType_s = classContainsMethod.getClassCtype_s();
1069    if(sMethodNameJava.equals("specifyLengthElement")) // && sClassName.equals("LogMessageFile_MSG"))
1070      stop();
1071    final boolean isStatic = (zbnfMethod !=null && zbnfMethod.getChild("static") != null)
1072                          || (((modeMethod & Method.modeCtor) !=0) && ((modeMethod & Method.modeCtorNonStatic)==0)); 
1073    final boolean bFinal = zbnfMethod ==null || zbnfMethod.getChild("final")!=null;  
1074    if(bFinal)
1075      stop();
1076    int modifier = modeMethod;
1077    if( classContainsMethod.isInterface() 
1078        ||(  !sMethodNameJava.startsWith("ctor") 
1079                && !bFinal                 //final keyword on method
1080                && !isStatic
1081                && !classContainsMethod.isFinal  //if the class is final, its methods can't be overridden
1082        ) )
1083    { //dynamic called method. 
1084      modifier |= Method.modeOverrideable;
1085    }
1086    if(isStatic){  //static keyword or static ctor
1087      modifier |= Method.modeStatic;
1088    }
1089    if(zbnfDescription != null){
1090      //if(zbnfDescription.getChild("override-able")!= null){ modifier |= Method.modeOverrideable;}
1091      if(zbnfDescription.getChild("return-this")!= null)  { modifier |= Method.modeReturnThis; }
1092      if(zbnfDescription.getChild("return-new")!= null)  { modifier |= Method.modeReturnNew; }
1093      if(zbnfDescription.getChild("noStacktrace")!= null)  { modifier |= (Method.modeNoStacktrace | Method.modeNoThCxt); }
1094      if(zbnfDescription.getChild("noThCxt")!= null)  { modifier |= Method.modeNoThCxt; }
1095    }
1096    if(argTypes == null && zbnfMethod!=null) //not the default constructor
1097    { //NOTE: call without zbnfMethod if a default ctor is created.
1098      String[] sArgSensitive = bArgumentSensitive ? new String[1] : null;
1099      List<FieldData> listArgTypes = new LinkedList<FieldData>(); //more than 30 args are not expected.
1100      char intensionArgument = 'a'; //(intension == 'h') ? 'A' : 'a'; //declaration or definition list.
1101      sArguments = gen_methodArguments(zbnfMethod, methodIdents, intensionArgument, sArgSensitive, listArgTypes);
1102      if(bArgumentSensitive && sArgSensitive[0].length() >0)
1103      { sNameUnambiguous += "_" + sArgSensitive[0];
1104      }
1105      if(listArgTypes != null && listArgTypes.size() >0)
1106      { argTypes = new FieldData[listArgTypes.size()];
1107        listArgTypes.toArray(argTypes);
1108      }
1109      else
1110      { argTypes = null;
1111      }
1112    }
1113    else if(argTypes != null){
1114        StringBuilder uArguments = new StringBuilder(100);
1115        String sSeparator = "";
1116        for(FieldData argType: argTypes){
1117                uArguments.append(sSeparator).append(argType.getTypeName()).append(" ").append(argType.getName());
1118          sSeparator = ", ";
1119        }
1120        sArguments = uArguments.toString();
1121    } else { 
1122        sArguments = "";
1123    }
1124    
1125    final Method methodData = classContainsMethod.addMethod( sMethodNameJava, sNameUnambiguous 
1126      , modifier, typeReturn, argTypes);
1127
1128    methodData.setMethodIdents(methodIdents);  //classLevelIdents plus arguments.
1129    String sTypeReturn = typeReturn.gen_Declaration(writeContent);
1130    String sMethodHead = "(";  //use the really name.
1131    String sSep = ", ";
1132    //if(sMethodNameJava.equals("ctorO"))
1133    if( (modeMethod & Method.modeCtor) != 0)  //if it is a ctor
1134    { if((modeMethod & Method.modeCtorNonStatic) != 0){
1135          //ctor of non-static or anonymous class
1136          sMethodHead += "struct " + classContainsMethod.getClassIdentName() + "_t* outer, ";
1137        }
1138        //ClassData outerClass = classData.getOuterClass();
1139                //if(outerClass!=null && !classData.isStaticInner){
1140        //      sMethodHead += outerClass.getClassCtype_s() + "* ythis, ";
1141        //}
1142      if(classData.isBasedOnObject()){
1143        sMethodHead += "ObjectJc* othis";
1144      } else {
1145        sMethodHead += "MemC mthis";    
1146      }
1147    }
1148    else if(methodData.firstDeclaringClass.isInterface())
1149    { /**An overridden method of an interface-declared method. */
1150      sMethodHead += "ObjectJc* ithis";  //Note: all interface methods are called with an Object-reference.
1151    }
1152    else if(methodData.firstDeclaringClass != classContainsMethod)
1153    { /**An overridden method of an superclass-declared method. */
1154      sMethodHead += methodData.firstDeclaringClass.getClassCtype_s() + "* ithis";
1155    }
1156    else if(!isStatic)
1157    { sMethodHead += sMethodClassType_s + "* thiz";
1158    }
1159    else
1160    { sMethodHead += "/*static*/ ";
1161      sSep = "";
1162    }
1163    if(sArguments.length() >0){
1164      sMethodHead += sSep + sArguments;
1165      sSep = ", ";
1166    }  
1167    if(methodData.need_thCxt){
1168      sMethodHead += sSep + "ThCxt* _thCxt)";
1169    }
1170    else{
1171      sMethodHead += ")";
1172    }
1173      
1174    methodData.setMethodHeadDefiniton(sDescription, sTypeReturn, sMethodHead);
1175    
1176    return methodData;
1177  }
1178
1179
1180  
1181  
1182  
1183  /**Generates the formal argument list of a method used both by generating method declaration or method definition.
1184   * @param zbnfMethod Zbnf item defined in <code>argumentList::=<?>...</code>.
1185   * @param localIdents The known identificators of the calling environment, the type identificators are used especially.
1186   *        This parameter is used calling {@link #gen_variableDefinition(ZbnfParseResultItem, LocalIdents, List, char intension, ClassData[])}
1187   *        inside with the parameters of the head. If the intension=='a' (Method definition in C-File),the parameter-variables are added to the localIdents.
1188   * @param intension Intension of call: 'A'-declaration in h-File, 'a'-definition in c-file, passing on <code>gen_variableDefinition()</code>. 
1189   * @param retArgSensitiveName [0] is filled with the short name of arg types if not null.
1190   * @param retArgTypes The list is filled with the detect argument types, used for argument sensitive method call.
1191   * @return String of formal arguments.
1192   * @throws ParseException
1193   * @throws InstantiationException 
1194   * @throws IllegalAccessException 
1195   * @throws IOException 
1196   * @throws IllegalArgumentException 
1197   * @throws FileNotFoundException 
1198   */
1199  String gen_methodArguments
1200  ( ZbnfParseResultItem zbnfMethod
1201  , LocalIdents localIdents
1202  , char intension
1203  , String[] retArgSensitiveName
1204  , List<FieldData> retArgTypes
1205  ) 
1206  throws ParseException, FileNotFoundException, IllegalArgumentException, IOException, IllegalAccessException, InstantiationException
1207  { final Map<String, ZbnfParseResultItem> indexParamDescription;
1208    ZbnfParseResultItem zbnfDescription = zbnfMethod.getChild("description");
1209    if(zbnfDescription != null) /**Creates a Map sorted by parameter name with param description: */
1210    { final List<ZbnfParseResultItem> listZbnfParamDescription = zbnfDescription.listChildren("param");
1211      if(listZbnfParamDescription != null)
1212      { indexParamDescription = new TreeMap<String, ZbnfParseResultItem>();
1213        for(ZbnfParseResultItem zbnfParamDescription: listZbnfParamDescription)
1214        { String sName = zbnfParamDescription.getChild("variableName").getParsedString();
1215          indexParamDescription.put(sName, zbnfParamDescription);  
1216        }
1217      }
1218      else { indexParamDescription = null; }
1219    }
1220    else { indexParamDescription = null; }
1221    
1222    Iterator<ZbnfParseResultItem> iterParam = zbnfMethod.iterChildren("argument");
1223    boolean bArgumentSensitive = (retArgSensitiveName != null);
1224    String sArgs = "";
1225    String sArgSensitiveName = "";
1226    String sArgSeparator = "";
1227    if(iterParam != null)
1228    { byte idxArg = 0;
1229      boolean bFirst = true;
1230      while(iterParam.hasNext())
1231      { ZbnfParseResultItem zbnfParam = iterParam.next();
1232        String sName = zbnfParam.getChild("variableName").getParsedString();
1233        ZbnfParseResultItem zbnfParamDescription = indexParamDescription == null ? null : indexParamDescription.get(sName);
1234        if(zbnfParamDescription != null)
1235          stop();
1236        if(sName.equals("args"))
1237          stop();
1238        CCodeData codeArg = gen_variableDefinition(
1239                zbnfParam
1240        , zbnfParamDescription
1241        , localIdents
1242        , null              //blockEnvironment unused because no intial values possible.
1243        , null
1244        , intension
1245        );
1246        //sArgs += sArgSeparator + sArg;
1247        if(bFirst){ 
1248          bFirst = false;
1249        } else { 
1250          sArgs += ", ";
1251        }  
1252        sArgs += codeArg.cCode;
1253        if(bArgumentSensitive)
1254        { //sArgSensitiveName += typeVariable[0].sArgSensitiveName;
1255          sArgSensitiveName += codeArg.identInfo.typeClazz.sArgSensitiveName;
1256          int dimension = codeArg.identInfo.getDimensionArray();
1257          while(dimension >0)
1258          { dimension -=1;
1259            sArgSensitiveName += "Y";  //array  
1260          }
1261        }
1262        if(retArgTypes != null) { retArgTypes.add(codeArg.identInfo); }
1263        idxArg +=1;
1264        sArgSeparator = ", ";
1265      }
1266    }
1267    if(bArgumentSensitive){ retArgSensitiveName[0] = sArgSensitiveName; }
1268    return sArgs;
1269  }  
1270
1271
1272  
1273  
1274  
1275  
1276}