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 2008-04-06  (year-month-day)
022     * list of changes:
023     * 2008-04-06 JcHartmut: some correction
024     * 2008-03-15 JcHartmut: creation
025     *
026     ****************************************************************************/
027    package org.vishia.java2C;
028    
029    import java.io.File;
030    import java.io.FileOutputStream;
031    import java.io.FileWriter;
032    import java.io.BufferedWriter;
033    import java.io.IOException;
034    import java.io.OutputStreamWriter;
035    import java.io.StringWriter;
036    import java.util.Collection;
037    import java.util.Iterator;
038    import java.util.LinkedList;
039    import java.util.List;
040    import java.util.Map;
041    import java.util.Queue;
042    import java.util.Set;
043    import java.util.TreeMap;
044    import java.util.Map.Entry;
045    
046    import org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile;
047    import org.vishia.mainCmd.Report;
048    import org.vishia.msgDispatch.LogMessage;
049    import org.vishia.zbnf.ZbnfParseResultItem;
050    
051    
052    
053    /**This class represents the content of a java class while Translation.
054     * The instance is created and filled while executing the first pass of translation,
055     * that is the detecting of the class elements and generating the C-header. 
056     * It is used for the second pass, the generation of C-file.
057     * <br>
058     * Chars are used to identify the kind of a element or type:
059     * <table>
060     * <tr><td>C</td><td>a class type identifier</td></tr>
061     * <tr><td>I</td><td>an interface type identifier</td></tr>
062     * <tr><td>B</td><td>a basic scalar type</td></tr>
063     * </table>
064     */
065    class ClassData implements JavaSources.ClassDataOrJavaSrcFile
066    {
067      /**The full name, like produced in C. If it is an inner class, outer__inner. */
068      public final String sClassNameC;
069      
070      /**The full name in java, dot to separate outer.inner class names. */
071      public final String sClassNameJava;
072      
073      /**Short form of type-name for argument sensitive C-routine names. */
074      public final String sArgSensitiveName;
075      
076      public final String sPackage;
077      
078      public final String sClassNameJavaFullqualified;
079      
080      /**Char which identifies a value in a variable argument list. The following chars are used:
081       * <ul>
082       * <li><code>Z</code>: boolean
083       * <li><code>B</code>: byte, uint8
084       * <li><code>C</code>: char
085       * <li><code>L</code>: Object
086       * <li><code>D</code>: double
087       * <li><code>F</code>: float
088       * <li><code>I</code>: int
089       * <li><code>J</code>: long
090       * <li><code>S</code>: short
091       * <li><code>z</code>: zero terminated string literal
092       * <li><code>s</code>: StringJc
093       * <li><code>b</code>: StringBufferJc
094       * <li><code>x</code>: ExceptionJc
095       * <li><code>t</code>: OS_TimeStamp
096       * <li><code>.</code>: unknown
097       * </ul>
098       * The upper-case-chars are the same, which are used in Java language 
099       * to identify Array types returned by <code>java.lang.Class.getName()</code>.
100       * 
101       */
102      public final char cVaArgIdent;
103      
104      /**The file were the class is defined in C. Without extension .h.
105       * 
106       */
107      public final String sFileName;
108      
109      /**The context of generating the whole file, where the class is defined. */
110      final GenerateFile fileContainsClass;
111      
112      
113      /**The source, from where the ClassData are created. It is used as a hint 
114       * in exception message, if any method, field or etc. is missed. */
115      public final String sSourceOfClassData;
116      
117      
118      /**Set if <code>java2c = staticInstance</code> is found in description of the class.
119       * A class is a static instance if the class should not be created dynamically using garbage collection,
120       * but only in the construction path of the application.
121       * In such classes all final references to final classes (may not be staticInstance itself)
122       * are simple pointers in the C Conversion. Otherwise enhanced references are to be used.
123       */
124      public final boolean isStaticInstanciated;
125      
126      /**Information String given in constructor.
127       */
128      private final String sInfo;
129    
130      /**Set if the class is final. */
131      public final boolean isFinal;
132    
133      /**Set if the class is a non-static inner class (only inner classes can be static or non-static). */
134      public final boolean isNonStaticInner;
135    
136      /**Set if the class or interface has only get-methods, so that it is able to declare as const* in C. */ 
137      public final boolean isConstant;
138      
139      /**Mode of anynymous class:
140       * <ul><li>C: inner class at class level
141       * <li>F: class at file level
142       * <li>P: primary class created in CRuntimeJavalike
143       * <li>Y: anonymous class
144       * <li>b: In a statement block.
145       * <li>.: Non anonymous class
146       * </ul>
147       */
148      public final char creationMode;
149      
150      private final boolean basedOnObject;
151      
152      /**Set if instances should only used embedded. 
153       * It is a property able to set to classes with less elements. */
154      public final boolean bEmbedded;
155      
156      /**Set if it is an interface. */
157      private final boolean bInterface;
158      
159      /**Set if it is an abstract class. */
160      public final boolean isAbstract; 
161      
162      /**Set true if any enhanced reference type is need. */
163      private boolean bFinalizeNeed;
164      
165      /**For second pass, the parse result. NOTE: Not final because it should be removed after running second path. */
166      private ZbnfParseResultItem zbnfClass;
167    
168      /**True if the class isn't known in Java2C context. It is a external used class.*/
169            private final boolean bExternal;
170    
171            /**For finalize method body, null if no finalize method is defined for java. */
172      private ZbnfParseResultItem zbnfFinalizeMethod;
173      
174      /**Some bits set if the array form of the type is need anywhere. The bits are coded in the set- and get-methods.
175       * See {@link #need_Y()}, {@link #isneed_Y()} etc.
176       */
177      private short bitArrayNeed;
178      
179      /**All known identifiers of this class. Also fields of the outer classes and base classes.
180       * To search any known field identifier in class context, only an access to this instance should be necessary.
181       */
182      public final LocalIdents classLevelIdents;
183      
184      /**All identifiers of only this class. Used for reflection generation and the stc-File.
185       */
186      public final List<FieldData> classLevelIdentsOwn;
187      
188      /**All inner classes of only this class. 
189       * Used for completion of inner classes with outer identifiers. */
190      private List<ClassData> innerClasses;
191      
192      
193      /**true if it has fields. Used for reflection generation. */
194      private boolean hasFields = false;
195      
196      /**All identifiers of only this class.
197       */
198      public final Map<String, ClassData> classLevelUsageTypes;
199      
200      /**Simple Data class to hold Strings and modes for generation casting.
201       * The class contains a  pre- and a suffix String and the access modes. 
202       * They will be disposed around the input expression to build a expression with cast.
203       * The class is used to check and execute possible casts. Some casts where done both in Java
204       * and in C implicitly, but the Java2C-translator should known it. Than pre- and suffixes are empty. 
205       */ 
206      public static class CastInfo
207      { 
208            /**5 Levels of cast-ability. equal: same types. automatic: cast from compiler, forex short to int.*/
209            public final static int kCastEqual=4, kCastAutomatic=3, kCastAble=2, kCastCommon=1, kCastNo=0;
210            
211            
212            /**C-Code before and after the expression, which is to cast. 
213         * At example <code>(int32(</code> and <code>)</code> to cast from float or double. */
214        final String pre, post;
215        
216        /**The provided access mode of the result. */
217        final char modeAccessDst;
218        
219        /**The expected access mode of the input. */
220        final char modeAccessSrc;
221        
222        final ClassData castType;
223        
224        /**Constructs the data. */
225        CastInfo(ClassData castType, String pre, String post, char modeAccessDst, char modeAccessSrc)
226        { this.pre = pre; this.post = post; 
227          this.modeAccessDst = modeAccessDst; 
228          this.modeAccessSrc = modeAccessSrc; 
229          this.castType = castType;
230        }
231      }
232      
233      /**Types from which a cast for initial values is possible, and its cast rule. 
234       * This list is build using {@link #addCastInitializer(ClassData srcType, String cast)}
235       * and used in {@link #testAndcast(ClassData srcType, String value, char intension)}.
236       */
237      private TreeMap<String, CastInfo> castableInitializerFromType;
238      
239      /**Types from which a cast is possible, and its cast rule. 
240       * This list is build using {@link #addCastFromType(ClassData srcType, String cast, String modes)}
241       * and at least used in {@link FieldData#testAndcast(CCodeData)}. 
242       * This class provides the info via {@link #getCastInfoFromType(String)}
243       * The key is the C-typename.
244       */
245      private TreeMap<String, CastInfo> castableFromType;
246      
247      /**Types to which a cast is possible, and its cast rule. 
248       * This list is build using {@link #addCastToType(ClassData srcType, String cast, String modes)}
249       * and at least used in {@link FieldData#testAndcast(CCodeData)}. 
250       * This class provides the info via {@link #getCastInfoToType(String)}
251       * The key is the C-typename.
252       */
253      private TreeMap<String, CastInfo> castableToType;
254      
255      
256      /**Holds Informations about superclasses and interfaces.
257       * <ul>
258       * <li>Reference to the ClassData of the given level.
259       * <li>Reference to InheritanceInfo of the superclass.
260       * <li>List of References to InheritanceInfo of all Interfaces of this level.
261       * <li>All Methods of this level, which are able to override (virtual methods).
262       * </ul>
263       */
264      static class InheritanceInfo
265      { 
266        /**The ClassData associated to this node of inheritance information. The toplevel node of
267         * {@link ClassData#inheritanceInfo} references the declaring class itself, but the 
268         * {@link #superClass}-referenced instance references the {@link ClassData} of the superclass etc.
269         * 
270         */
271        final ClassData classData;
272        
273        /**The Superclass of the current {@link #classData}. It isn't a instance of {@link ClassData}, 
274         * but an instance of this classtype, because the names of the overridden methods are different
275         * from the Methods named in the parallel list in {@link ClassData#inheritanceInfo} of the superclass.*/
276        InheritanceInfo superInheritance;
277        
278        /**All Interfaces of the current {@link #classData}. */
279        //private Map<String, InheritanceInfo> ifcInheritance;
280        private InheritanceInfo[] ifcInheritance;
281        
282        /**Array of all methods of this inheritance level of ClassData with methods, 
283         * which are able to override and which are overridden. Each element refers the method in its
284         * originally representation (associated to the superclass or interface) and its overriding name
285         * in this class. The overriding name is the name, which is set to the Mtbl_Type in C.
286         */
287        private MethodOverrideable[] methodTable;
288        
289    
290        
291        /**Creates a new instance for a new creating class. This constructor is called inside the Constructor of 
292         * {@link ClassData#ClassData(GenerateFile, String, String, String, String, String, char, ClassData, ClassData, ClassData[], ZbnfParseResultItem, boolean, boolean, boolean, LocalIdents)}).
293         * The constructor creates the tree of some {@link ClassData.InheritanceInfo} and their instances 
294         * of {@link ClassData.MethodOverrideable}. The picture shows that:
295         * <img src="../../../../Java2C/img/ctor_InheritanceInfo_omdJava2C.png" />
296         * The tree of {@link ClassData.MethodOverrideable} are determined by the source tree of the superclass.
297         * To create the inner InheritanceInfo-instances, the {@link ClassData.InheritanceInfo#InheritanceInfo(ClassData, ClassData, ClassData[])}-constructor
298         * is used. This constructor uses the given source-InheritanceInfo to get the next deeper level. 
299         * The InheritanceInfo- tree of the superClass contains the correct names of the implementation routines, 
300         * attribute {@link ClassData.MethodOverrideable#sNameOverriding}. But the parallel existing instance 
301         * referenced from any own class immediately, showing in green but red crossed out doesn't contain 
302         * the correct implementation names. It contain the implementation name of this class-level. 
303         * The class is a deeper superclass of the superclass, the methods may be overridden long ago.    
304         * 
305         * @param classDataP The creating class. A backward aggregation is set: {@link #classData}.
306         * @param superClassP The superclass of the creating class. The superclass is referenced only here, 
307         *   not in the {@link ClassData}. The {@link ClassData#inheritanceInfo} of the superclass is the source
308         *   for all inheritance infos of this class. The picture show the referenced instance of this parameter 
309         *   in yellow on top-right, and the source of all inheritance infos referenced from there in cyan color.
310         * @param ifcClassDataP The interfaces of the creating class. 
311         *   The interfaces are referenced only here, not in the {@link ClassData}.
312         *   The all-inheritance-infos of interface tree are got from here, see picture in bottom area.
313         */
314        private InheritanceInfo(ClassData classDataP, ClassData superClassP, ClassData[] ifcClassDataP)
315        { this.classData = classDataP; 
316          if(classDataP.sClassNameJava.equals("ImplIfc"))
317            stop();
318          if(classDataP.sClassNameJava.equals("TestAllConcepts"))
319            stop();
320          if(superClassP != null)
321          { InheritanceInfo srcSuperInheritance = superClassP.inheritanceInfo;
322            this.superInheritance = new InheritanceInfo(superClassP, srcSuperInheritance);  //recursively call.
323          }
324          if(ifcClassDataP != null)
325          { this.ifcInheritance = new InheritanceInfo[ifcClassDataP.length];
326            //this.ifcInheritance = new TreeMap<String, InheritanceInfo>();
327            for(int idxIfc = 0; idxIfc< ifcClassDataP.length; idxIfc++){
328              ClassData interfaceClass = ifcClassDataP[idxIfc];
329            //for(ClassData interfaceClass: ifcClassDataP){
330              InheritanceInfo ifcInfo = new InheritanceInfo(interfaceClass, interfaceClass.inheritanceInfo); //recursively call.
331              this.ifcInheritance[idxIfc] = ifcInfo; 
332              //this.ifcInheritance.put(interfaceClass.getClassNameJava(), ifcInfo); 
333            }//for
334          }//if
335        }
336        
337    
338        
339        /**The constructor for the inner InheritanceInfos, see picture on other constructor.
340         * @param classDataP The associated class.
341         * @param srcInheritance The InheritanceInfo, but from the tree of the primary super class,
342         *   but not from classDataP immediately. See picture. It may be null, if the class hasn't any 
343         *   override-able methods.
344         */
345        private InheritanceInfo(ClassData classDataP, InheritanceInfo srcInheritance)
346        { this.classData = classDataP; 
347          if(srcInheritance != null)
348          { //final ClassData superSuperClass = superClassP.getSuperClassData();  //superclass of next level? 
349            //final ClassData[] ifcSuperClass = superClassP.getInterfaces();
350            if(srcInheritance.superInheritance != null){
351              //MethodOverrideable[] srcSuperMethods = srcInheritance.methodTable;
352              InheritanceInfo srcSuperSuperInheritance = srcInheritance.superInheritance;
353              //ClassData superClass = srcInheritance.classData;
354              this.superInheritance = new InheritanceInfo(srcSuperSuperInheritance.classData, srcSuperSuperInheritance);  //recursively call.
355            }
356            if(srcInheritance.ifcInheritance != null) {
357              this.ifcInheritance = new InheritanceInfo[srcInheritance.ifcInheritance.length];
358              //this.ifcInheritance = new TreeMap<String, InheritanceInfo>();
359              //Set<Entry<String, InheritanceInfo>> entrySet = srcInheritance.ifcInheritance.entrySet();
360              int idxIfc = 0;
361              for(InheritanceInfo srcSuperifcInheritance: srcInheritance.ifcInheritance){
362              //for(Entry<String, InheritanceInfo> ifcEntry: entrySet){
363                //InheritanceInfo srcSuperifcInheritance = ifcEntry.getValue();
364                ClassData ifcClass = srcSuperifcInheritance.classData;
365                /**Super interfaces, an interface can extend another one, the last of this is ObjectJc. */
366                InheritanceInfo ifcInheritance = new InheritanceInfo(ifcClass, srcSuperifcInheritance);
367                this.ifcInheritance[idxIfc++] = ifcInheritance;
368                //this.ifcInheritance.put(ifcClass.getClassNameJava(), ifcInheritance);
369              }
370              
371            }
372            MethodOverrideable[] srcMethodTable = srcInheritance.methodTable;
373            if( srcMethodTable != null 
374              //&& superClassP != Java2C_Main.CRuntimeJavalikeClassData.clazzObjectJc
375              )
376            { //methodTable of given superclass
377              int zMethodTable = srcMethodTable.length;
378              this.methodTable = new MethodOverrideable[zMethodTable];
379              for(int ix=0; ix<zMethodTable; ix++){
380                this.methodTable[ix] = srcMethodTable[ix].clone();
381              }
382            }  
383          }
384        }
385        
386        
387        
388        
389        
390        @Override public String toString()
391        { return classData + " extends "+ superInheritance.classData + ", ifc:"+ ifcInheritance;
392        }
393        
394        void stop(){}
395      }
396      
397      /**Tree of all method tables of interfaces and the superclasses. */
398      InheritanceInfo inheritanceInfo;  
399      
400      /**unused yet, need? */
401      static class MethodArg
402      { ClassData type;
403        
404      }
405      
406      class MethodWithZbnfItem
407      { final Method method;
408        final ZbnfParseResultItem zbnfMethod;
409        final Method supermethod;
410        private final char isConstructor;
411        
412        /**Constructs.
413         * @param method The method
414         * @param zbnfMethod The parse result item, used for the body.
415         * @param supermethod If it is a ctor of an anonymous class, the found super ctor. It should be called.
416         * @param isConstructor 'c' if it is an constrcutor
417         */
418        public MethodWithZbnfItem(Method method, ZbnfParseResultItem zbnfMethod
419        , Method supermethod, char isConstructor
420        )
421        { this.method = method;
422          this.zbnfMethod = zbnfMethod;
423          this.supermethod = supermethod;
424          this.isConstructor = isConstructor;
425          if(isConstructor == 'c'){ nrofConstructor +=1; } 
426        }
427    
428        public final boolean isConstructor()
429        { return isConstructor == 'c';
430        }
431        
432      }
433      
434      
435      
436      /**This class composed the reference of a method and the name of implementation of the method
437       * in an inheriting class. The class is used in all {@link ClassData.InheritanceInfo#methodTable}
438       * to allow definition of an implementing name to override the method.
439       */
440      private static class MethodOverrideable
441      { 
442        /**The method. */
443        final Method method;
444      
445        /**The implementing name in the class, to which this instance is associated.  */
446        private String sNameOverriding;
447        
448        /**Creates.
449         * @param method The method which is able to override
450         * @param sNamePrimary The primary name of the implementation. The instance will be create
451         *        if the method is declared first.
452         */
453        MethodOverrideable(Method method, String sNamePrimary)
454        { this.method = method; sNameOverriding =sNamePrimary; 
455        }
456        
457        /**An inheriting class should have its own instance. clone it.
458         * The method reference is the same, because its content isn't changed.
459         * The {@link #sNameOverriding} can be changed. 
460         */
461        public MethodOverrideable clone()
462        {
463          return new MethodOverrideable(method, sNameOverriding);
464        }
465        
466        public String toString(){ return sNameOverriding; }
467        
468        private void stop(){}
469      }
470      
471      
472      /**Instances of this class are created only temporary while running first pass of this class.
473       * This class stores some data about methods from super classes and interfaces.
474       * After finish first pass this informations are stored in the methods of the class. All methods, 
475       * from supers and interfaces too, are stored finally in {@link ClassData#methods} 
476       * and are provided by {@link ClassData#searchMethod(String, List)}.
477       * to access it while running second passes (method call).
478       */
479      private static class MethodOverrideCheck
480      { 
481        /**The method. This element is null if the method is referenced in {@link #listOccurence},
482         * because the method is referenced there.
483         * It is only used for new methods of this class.*/
484        final Method method;
485        
486        /**The path to the super method table for calling. */
487        final String sPathToMtbl;
488      
489        /**If the method is declared in a base class or interface too, it is the path necessary to address
490         * the base class or interface started from <code>ythis</code>
491         */
492        public final String sPathToBase;
493    
494        public static class MethodIndex
495        { final MethodOverrideable[] ref;
496          final int idx;
497          
498          /**Constructs.
499           * @param ref reference in any {@link ClassData.InheritanceInfo#methodTable2}
500           * @param idx index in the reference
501           */
502          public MethodIndex(MethodOverrideable[] ref, int idx)
503          { this.idx = idx;
504            this.ref = ref;
505          }
506        }
507        
508        /**Index of all occurences of this method in superclasses and interfaces. */
509        private final List<MethodIndex> listOccurence = new LinkedList<MethodIndex>();
510        
511        /**Creates.
512         * @param method The method which is able to override
513         * @param sNamePrimary The primary name of the implementation. The instance will be create
514         *        if the method is declared first.
515         */
516        MethodOverrideCheck(Method method, String sPathToMtbl, String sPathToBase)
517        { this.method = method; 
518          this.sPathToMtbl = sPathToMtbl;
519          this.sPathToBase = sPathToBase;
520        }
521        
522        /**Adds a occurence of the method in any method table of superclasses or interfaces.
523         * It is called on construction of a {@link ClassData} and takes informations from base classes
524         * and interfaces.
525           * @param ref reference in any {@link ClassData.InheritanceInfo#methodTable2}
526           * @param index index in the reference
527         */
528        void addOccurence(MethodOverrideable[] ref, int index)
529        { listOccurence.add(new MethodIndex(ref, index));
530          
531        }
532        
533        public String toString(){ return "" + listOccurence.size(); }
534      }
535      
536      
537      /**Index of all methods with the same number of arguments. 
538       * The key is the java method name, following "#nr", where nr is the number of arguments.
539       * The value is either a {@link Method} or a List<Methode> if more as one method 
540       * with the same number of argumentes exists.  
541       */
542      private TreeMap<String, Object> methods;
543      
544      /**Index of all methods with its C name.  
545       */
546      private TreeMap<String, Method> methodsCname;
547      
548      
549      
550      /**This index is only temporary used while the first pass is running. 
551       * All override-able methods from base classes and interfaces are referenced here, 
552       * via the {@link ClassData.InheritanceInfo#methodTable} reference and the index in the table.
553       * Any occurrence of the same method in nested or parallel interfaces and super classes 
554       * is registered only one time here. 
555       * If a method is declared in an interface, and also declared in another parallel interface, 
556       * than implemented in a super class, it is found here only one time with its unambiguous name 
557       * (respecting same name but different parameter types). The unambiguous name is the same 
558       * in all occurrences of the same method.
559       * <br>
560       * The key of this Map is the unambiguous name of the method.  
561       */
562      private TreeMap<String, Object> methodsCheckOverriding = new TreeMap<String, Object>();
563    
564     
565      
566      /**This index stores methods, which are designated as override-able, but they are defined in this class, 
567       * the aren't found in any base class. 
568       * The list is used only temporary while running the first pass. After them the content of this list
569       * will be stored in {@link #inheritanceInfo} and there in {@link ClassData.InheritanceInfo#methodTable} 
570       * of the primary level. A list but not an array is used first to add a unknown amount of methods.
571       * <br>
572       * The order of methods and hence the order of method in {@link ClassData.InheritanceInfo#methodTable}
573       * and in the generated method table in C-code is adequate the order of methods in the java source code.
574       * The order is important if the compiled C-unit is used as part of library, and using C-units 
575       * should not be recompiled if inner functionality is changed in the library. The Headerfile contains
576       * and shows this order. It is the same problem like virtual methods in C++.
577       */
578      private List<MethodOverrideable> methodsOverrideableNew = null;
579        
580      
581      final Queue<MethodWithZbnfItem> methodsWithZbnf = new LinkedList<MethodWithZbnfItem>(); 
582      
583      int nrofConstructor = 0;
584      
585      /**If <code>this</code> or a unnamed instance of the class is used as a reference, 
586       * this field supplied the necessary instance infos.
587       * It represents the instance as simple forward reference, like <code>this</code>
588       * respectively <code>ythis</code> in C.
589       * <br>
590       * An Unnamed instance is especially a returned instance reference or a instance per value (StringJc) 
591       * of a method call.
592       * <br>
593       * In opposite: The {@link #typeCodeInfo} contains a quasi-FieldData for static access. 
594       */
595      public final FieldData classTypeInfo;
596      
597      /**This codeinfo is used if a classlevel ident is accessed. It is the CcodeData of this. */
598      final CCodeData thisCodeInfo;
599      
600      /**This codeinfo is used if a super constructor is called. It is either a reference to ObjectJc or MemC. */
601      final CCodeData ctorCodeInfo;
602      
603      /**This codeinfo contains an cCode == "" and the correct type. The modeAccess is 'C'. It is used
604       * if a static access to a class member is translated. 
605       * It is used in {@link SecondPass.StatementBlock#gen_reference(String[], ZbnfParseResultItem, LocalIdents, CCodeData, char)}.
606       */
607      final CCodeData typeCodeInfo;
608      
609      /**The superclass of this or null. */
610      //final ClassData superClazz;
611      
612      
613      /**The outer class of this or null. */
614      final ClassData outerClazz;
615      
616      /**This class saves the position of zbnfInit in a parse result to the named variable.
617       * It is used if the initialization is generated.
618       */
619      static class InitInfoVariable
620      { /**The zbnf parse result element which contains the <code>value::=</code> 
621         * or <code>newObject::=</code> or <code>newArray::=</code> or <code>constArray::=</code>. 
622         */
623        final ZbnfParseResultItem zbnfInit;
624        
625        final FieldData identInfos;
626        
627        public InitInfoVariable(FieldData identInfo, ZbnfParseResultItem zbnfValue)
628        { this.zbnfInit = zbnfValue; this.identInfos = identInfo;
629        }
630        
631      }
632    
633      /**List of parse result items of initial values for variables. 
634       * Filled in first path, used in second pass.
635       */
636      private final List<InitInfoVariable> variablesToInit;
637    
638      public List<InitInfoVariable> getVariablesToInit(){ return variablesToInit; }
639      
640      /**List of all static variables either with initial values or not.
641       * Filled in first path, used in second pass.
642       */
643      final List<InitInfoVariable> staticVariables;
644    
645      /**Initializes new translated classes.
646       * @param fileContainsClass
647       * @param sFileName
648       * @param sPkgJava
649       * @param sNameJava The Name of the class from Java, 
650       * @param sNameCP The Name of the class used in C-code
651       * @param sArgSensitiveName Short type-identifier for parameter-sensitive C-routine-name-part 
652       * @param cVaArgIdent Should be 'L' always
653       * @param outerClassData null if it isn't an inner class.
654       * @param superClassData if the class doesn't extend any other class, it is ObjectJc. 
655       *                       But if the class doesn't base on ObjectJc, it is null. 
656       *                       It is controlled by <code>@ java2c=noObject</code>.
657       * @param ifcClassData null or array of all interfaces.                      
658       * @param zbnfClass The parse result of the class code. It is given to run the second pass
659       *                  of translation. See {@link #zbnfClass} of the class.
660       * @param nonStaticInner
661       * @param bFinal
662       * @param fileLevelIdents The localIdents from the file level containing all known classes in the file
663       *                 including the imported classes
664       */
665      /**
666       * @param sSourceOfClassData
667       * @param fileContainsClass
668       * @param sFileName
669       * @param sPkgJava
670       * @param sNameJava
671       * @param sNameCP
672       * @param sArgSensitiveName
673       * @param cVaArgIdent
674       * @param outerClassData
675       * @param superClassData
676       * @param ifcClassData
677       * @param zbnfClass
678       * @param infos
679       * @param intension Intension of creation, P: primary (file level), C: inner class, 
680       *                                         Y: anonymous inner class at class level,
681       *                                         m, b etc: anonymous or not at statement block level 
682       * @param fileLevelIdents
683       */
684      ClassData(String sSourceOfClassData
685        , GenerateFile fileContainsClass, final String sFileName
686        , String sPkgJava, String sNameJava, String sNameCP
687        , String sArgSensitiveName, char cVaArgIdent 
688        , ClassData outerClassData, ClassData superClassData, ClassData[] ifcClassData    
689        , ZbnfParseResultItem zbnfClass
690        , char access, String infos
691        , char creationMode
692        //, LocalIdents fileLevelIdents    
693      )
694      { assert(sPkgJava == null || sPkgJava.length()==0 || sPkgJava.endsWith("/"));
695        Java2C_Main.singleton.console.reportln(Report.debug, "Java2C-ClassData.ctor:(" + sSourceOfClassData 
696            + ", nameJava=" + sNameJava
697            + ", nameC=" + sNameCP + ", " + sArgSensitiveName + ", ..., " + infos);
698            if(sNameCP.startsWith("InterProcessCommFactorySocket"))
699                    stop();
700        assert("PFCYb".indexOf(creationMode)>=0);
701        this.creationMode = creationMode;
702        this.sSourceOfClassData = sSourceOfClassData;
703        this.sFileName = sFileName;
704        this.fileContainsClass = fileContainsClass;
705        this.sClassNameC = sNameCP; 
706        
707        this.sClassNameJava = sNameJava;
708                    this.outerClazz = outerClassData;
709        
710        this.sPackage = sPkgJava;
711        if(sNameCP.equals("StringJc"))
712          stop();
713        { String sFullName = "";
714          ClassData outerClazz1 = this;
715          while( (outerClazz1 = outerClazz1.outerClazz) != null)
716          { sFullName = outerClazz1.sClassNameJava + "." + sFullName;  //add left
717          }
718          sFullName = sPkgJava + sFullName;  //add left
719          sFullName += sNameJava;
720          sClassNameJavaFullqualified = sFullName;
721        }
722        this.sArgSensitiveName = sArgSensitiveName;
723        this.cVaArgIdent = cVaArgIdent;
724        if(sNameCP.equals("ReadTargetFromText__Target"))
725          stop();
726        if(sNameCP.contains("/"))
727          stop();
728        this.zbnfClass= zbnfClass;
729        String sInfo = infos;
730        this.sInfo = sInfo;
731        this.isNonStaticInner = infos.contains("+nonStaticInner+");
732        this.bExternal = infos.contains("+extern+");
733        this.bEmbedded = infos.contains("+embedded+");
734        this.isAbstract = infos.contains("+abstract+");
735        this.isStaticInstanciated = infos.contains("+static+");
736        this.isFinal = infos.contains("+final+");
737        this.bInterface = infos.contains("+interface+");
738        this.isConstant = infos.contains("+const+");
739        if(this.isNonStaticInner){ sInfo += "nonStaticInner+"; }
740        if(infos.contains("+ObjectJc+")){
741                            superClassData = CRuntimeJavalikeClassData.clazzObjectJc;
742                    }
743        if(superClassData != null || ifcClassData != null){
744          /**The inheritanceInfo is null if the class is a simple data struct. without virtual methods.*/
745          inheritanceInfo = new InheritanceInfo(this, superClassData, ifcClassData);
746          fillMethodsOverrideable(inheritanceInfo, "", "");
747          Java2C_Main.singleton.console.report(Report.debug, " + super/ifc");
748        }
749        
750        this.basedOnObject = (superClassData != null && (superClassData.basedOnObject || superClassData == CRuntimeJavalikeClassData.clazzObjectJc));
751        if(infos.contains("+primitive+"))
752        { this.classLevelIdents = null; //identsParent);
753          this.classLevelIdentsOwn = null;
754          this.classLevelUsageTypes = null;
755                            this.ctorCodeInfo = null;
756    
757        } else { 
758          this.classLevelIdents = new LocalIdents(this);     //after fill inheritanceInfo because it needs superClass infos 
759          this.classLevelIdentsOwn = new LinkedList<FieldData>();
760          this.classLevelUsageTypes = new TreeMap<String, ClassData>();
761          this.ctorCodeInfo = isBasedOnObject() 
762                            ? new CCodeData("othis", CRuntimeJavalikeClassData.clazz_unknown.classTypeInfo, '*', 0)
763                            : new CCodeData("mthis", CRuntimeJavalikeClassData.clazz_unknown.classTypeInfo, '*', 0);
764        }
765                    this.variablesToInit = bExternal ? null : new LinkedList<InitInfoVariable>();
766        this.staticVariables = bExternal ? null : new LinkedList<InitInfoVariable>();
767        this.classTypeInfo = new FieldData(sNameCP, this, null, null, null, '.', access, 0, null, '.', this );
768        this.thisCodeInfo = new CCodeData("ythis", classTypeInfo, access == '*' ? '~' : access, 0);
769        this.typeCodeInfo = new CCodeData("", classTypeInfo, 'C', 0);
770        //CCodeData for class member reference: use ythis as simple pointer.
771        if(outerClazz != null){
772            addCastToType(outerClazz, "(?)->outer", "**");
773                if(outerClazz.outerClazz != null){
774                    addCastToType(outerClazz.outerClazz, "(?)->outer->outer", "**");
775                }
776        }
777        //if(superClassData !=null && superClassData.isFinalizeNeed()){
778            bFinalizeNeed = false;
779        //}
780        
781      }
782    
783      
784      
785    
786      ClassData(String sSourceOfClassData
787      , String sPkgJava, String sNameJava, String sNameC, String sArgSensitiveName, char cVaArgIdent
788      , String sFileName, char access, String infos
789      ) //, LocalIdents identsParent)
790      {
791        this(sSourceOfClassData, null, sFileName, sPkgJava, sNameJava, sNameC, sArgSensitiveName, cVaArgIdent
792            , null, null, null, null, access, infos, 'P');
793        
794      }
795      
796      
797      /**returns the instance because it is.
798       * @see org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile#getClassData()
799       */
800      public ClassData getClassData()
801      {
802        return this;
803      }
804    
805    
806      /**returns null because it is not.
807       * @see org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile#getJavaSrc()
808       */
809      public JavaSrcTreeFile getJavaSrc()
810      {
811        return null;
812      }
813      
814      
815      /**Sets the body for the finalize method.
816       * @param zbnfFinalizeMethod
817       */
818      void setBodyForFinalize(ZbnfParseResultItem zbnfFinalizeMethod)
819      { this.zbnfFinalizeMethod = zbnfFinalizeMethod;
820        needFinalize();
821      }
822      
823      /**Gets the body for the finalize method.
824       * @param zbnfFinalizeMethod
825       */
826      ZbnfParseResultItem getBodyForFinalize()
827      { return zbnfFinalizeMethod;
828      }
829      
830      
831      
832      
833      /**Returns true if the ClassData represents an Array type. */
834      //public boolean isArray(){ return dimensionArrayOrFixSize >0; }
835      
836      void      need_Y() {         bitArrayNeed |= 0x01; }
837      boolean isneed_Y() { return (bitArrayNeed  & 0x01) !=0; }
838      void      need_YP(){         bitArrayNeed |= 0x02; }
839      boolean isneed_YP(){ return (bitArrayNeed  & 0x02) !=0; }
840      
841      
842      
843      public void addField(String sIdent, FieldData identInfo)
844      {
845        //classLevelIdents.putClassElement(sIdent, identInfo);
846        classLevelIdents.putElement(sIdent, identInfo);
847        //if(classLevelIdentsOwn == null) { classLevelIdentsOwn = new LinkedList<FieldData>(); }
848        if(identInfo.nClassLevel == 1 && identInfo.nOuterLevel == 1) {
849            classLevelIdentsOwn.add(identInfo);
850        }
851        if(identInfo.modeStatic != 'd')
852        { classLevelUsageTypes.put(identInfo.getTypeName(), identInfo.typeClazz);
853          hasFields = true;
854        }  
855        
856      }
857      
858      /**Test whether the field is known and returns it data.
859       * @param name The name of the field. The field can be local or in super scopes.
860       * @return null if the field isn't existing.
861       */
862      public FieldData getFieldIdent(String name){ return classLevelIdents.getField(name); }
863      
864      public boolean hasFields(){ return hasFields; } 
865      
866      
867      /**adds a casting possibility for initializer.
868       * @param srcType The src type for which the cast is valid.
869       * @param cast String in form "pre?post". To implement the cast the pre and post part will wrap the value.
870       */
871      public void addCastInitializerFromType(ClassData srcType, String cast, String modeAccessDstSrc)
872      { int posSep = cast.indexOf('?');
873        String sPre = cast.substring(0, posSep);
874        String sPost = cast.substring(posSep+1);
875        CastInfo castInfo = new CastInfo(srcType, sPre, sPost, modeAccessDstSrc.charAt(0), modeAccessDstSrc.charAt(1));
876        if(castableInitializerFromType == null){ castableInitializerFromType = new TreeMap<String, CastInfo>(); }
877        castableInitializerFromType.put(srcType.sClassNameC, castInfo);
878        
879      }
880      
881      
882      
883      /**adds a casting possibility from a given type to this. This is used for special cases. 
884       * The cast from a base class to all its derived class is not registered here. It needs 
885       * instead a cast at programming level in Java.
886       * @param srcType Type from which the cast is possible
887       * @param cast String in form "pre?post". To implement the cast the pre and post part will wrap the value.
888       * @param modeAccessDstSrc first and second char is modeAccessDst and modeAccessSrc, 
889       *        typically "**" if both are pointers or "%%" if both are primitives.
890       *        Only in special cases the modeAccess is differently
891       */
892      public void addCastFromType(ClassData srcType, String cast, String modeAccessDstSrc)
893      { int posSep = cast.indexOf('?');
894        String sPre = cast.substring(0, posSep);
895        if(sPre.equals("toString_StringBuilderJc("))
896            stop();
897        String sPost = cast.substring(posSep+1);
898        CastInfo castInfo = new CastInfo(srcType, sPre, sPost, modeAccessDstSrc.charAt(0), modeAccessDstSrc.charAt(1));
899        if(castableFromType == null){ castableFromType = new TreeMap<String, CastInfo>(); }
900        castableFromType.put(srcType.sClassNameC, castInfo);
901        //castableFromType.put(srcType.sClassNameJavaFullqualified, castInfo);
902        
903      }
904      
905      
906      /**adds a casting possibility to a given type from this. This is the typically cause for downcast
907       * form a derived class to its super class.
908       * @param dstType Type to which the cast is possible
909       * @param cast String in form "pre?post". To implement the cast the pre and post part will wrap the value.
910       * @param modeAccessDstSrc first and second char is modeAccessDst and modeAccessSrc, 
911       *        typically "**" if both are pointers or "%%" if both are primitives.
912       *        Only in special cases the modeAccess is differently
913       */
914      public void addCastToType(ClassData dstType, String cast, String modeAccessDstSrc)
915      { int posSep = cast.indexOf('?');
916        String sPre = cast.substring(0, posSep);
917        String sPost = cast.substring(posSep+1);
918        CastInfo castInfo = new CastInfo(dstType, sPre, sPost, modeAccessDstSrc.charAt(0), modeAccessDstSrc.charAt(1));
919        if(castableToType == null){ castableToType = new TreeMap<String, CastInfo>(); }
920        castableToType.put(dstType.sClassNameC, castInfo);
921        //castableToType.put(dstType.sClassNameJavaFullqualified, castInfo);
922        
923      }
924      
925      
926      /**tests wether a cast is necessary, if it, returns the casted value.
927       * This is checked to srcType. If srcType is the same as this, no cast occurs, the value is returned direct.
928       * If srcType is a derivateable type of this, the cast is set with {@link #addCast(ClassData, String)}.
929       * That is used to produce the casted return value. 
930       * @param srcType The type of the value
931       * @param value The value string.
932       * @param intension 'i' init-value may be in {...}
933       * @return The value itself if no cast is necessary
934       */
935      public String xxxtestAndcast(ClassData srcType, String value, char intension)
936      { String sRet;
937        CastInfo castInfo;
938        if(  srcType == this 
939          || this == CRuntimeJavalikeClassData.clazz_void  //void as argument is a void*
940          || this == CRuntimeJavalikeClassData.clazz_va_argRaw  //any type is valid
941          ) 
942        { //no cast necessary
943          sRet = value; 
944        }
945        else if( value.equals("null"))
946        { //a null-pointer should be compatible with all expect StringJc.
947          if(sClassNameC.equals("StringJc")){ 
948            sRet = "null_StringJc"; }
949          else {
950            sRet = value; } 
951        }
952        else
953        { //normal value
954          if(  intension == 'i' && castableInitializerFromType != null
955            && (castInfo = castableInitializerFromType.get(srcType.sClassNameC)) != null
956            )
957          { sRet = castInfo.pre + value + castInfo.post;
958          }
959          else if( castableFromType != null
960            && (castInfo = castableFromType.get(srcType.sClassNameC)) != null
961            )
962          { sRet = castInfo.pre + value + castInfo.post;
963          }
964          else
965          { sRet = "((/*cast*/" + sClassNameC + (isPrimitiveType()? "" : "*") + ")(" + value + "))";
966          }
967        }
968        return sRet;    
969      }
970      
971      
972      /**Registers a Method if the class is parsed or a standard class is initialized.
973       * Inside {@link #addMethod(String, String, int, org.vishia.java2C.FieldData, org.vishia.java2C.FieldData[])}
974       * is called with {@link ClassData#classTypeInfo}. 
975       * @param sNameJava Name of the method in Java
976       * @param sCName Name of the method to translate in C. If more than 1 method with the same sNameJava is given,
977       *               the sCName should be unambiguous.
978       * @param modifier Ones of {@link ClassData.Method#modeStatic}, {@link ClassData.Method#modeNoThCxt}               
979       * @param returnType The type of return. It isn't a Classdata, but a IdentInfo, 
980       *                   because some additional properties like return by value or reference should be present.
981       * @param paramsType Array of all argument types. They are given in form of pure types, 
982       *                   because they are taken with standard conventions: simple pointers or simple primitive types.
983       */
984      public void addMethod(String sNameJava, String sNameUnambiguous, int modifier, FieldData returnType, ClassData[] paramsType)
985      { FieldData[] paramsIdent = new FieldData[paramsType.length];
986        if(sNameUnambiguous.equals("ctorO_Target"))
987          stop();
988        for(int ii=0; ii<paramsType.length; ii++)
989        { paramsIdent[ii] = paramsType[ii].classTypeInfo;
990        }
991        addMethod(sNameJava, sNameUnambiguous, modifier, returnType,paramsIdent);
992      }
993    
994      /**Adds. @deprecated, use {@link #addMethod(String, String, int, FieldData, ClassData[])}
995       * 
996       * @param sNameJava
997       * @param sCName
998       * @param returnType
999       * @param paramsType
1000       */
1001      public void addMethod(String sNameJava, String sNameUnambiguous, FieldData returnType, ClassData[] paramsType)
1002      { final int modifier = 0;
1003        addMethod(sNameJava, sNameUnambiguous, modifier, returnType, paramsType);
1004      }
1005    
1006      /**Registers a argumentless method if the class is parsed or a standard class is initialized.
1007       * @param sNameJava
1008       * @param sCName
1009       * @param modifier
1010       * @param returnType
1011       */
1012      public void addMethod(String sNameJava, String sNameUnambiguous, int modifier, FieldData returnType)
1013      { FieldData[] paramsIdent = null;
1014        addMethod(sNameJava, sNameUnambiguous, modifier, returnType, paramsIdent);
1015      }
1016    
1017      
1018      final Method addMethod
1019      ( String sMethodNameJava
1020                    , String sMethodNameUnambiguous
1021              , int modifier
1022      , FieldData retType
1023      , FieldData[] argTypes
1024      )
1025      {
1026            return addMethod(sMethodNameJava, sMethodNameUnambiguous, null, modifier, retType, argTypes);
1027      }
1028      
1029      /**Creates a method and adds it to the lists. 
1030       * Test whether this method is already defined in a superclass or interface and overrides it.
1031       * The name of the override-able method in {@link ClassData.InheritanceInfo#methodTable} 
1032       * (aggregation {@link #inheritanceInfo}) is changed to the name of this method for all overridden methods.
1033       * It is possible that more as one overridden method is found, if the same method is defined 
1034       * in an interface, in more as one parallel inherited interfaces or in more as one nested interfaces or super-classes.
1035       * 
1036       * @param sMethodNameJava given method-name in Java or <code>ctorO</code> or <code>ctorM</code>
1037       * @param sMethodNameUnambiguous The java name plus argument type designations if the method is ambiguous.
1038       * @param argTypes Array of all argument types with there type modifier.
1039       * @param modifier Contains bits {@link ClassData.Method#modeStatic}, {@link ClassData.Method#modeNoThCxt}
1040       *                 or {@link ClassData.Method#modeOverrideable}. <br>
1041       *                 If the method is able to override, its unambiguous name is saved in {@link #methodsOverrideableNew} of this ClassData.
1042       *                 The keyname is ... TODO. The method name is also saved in {@link ClassData.InheritanceInfo#methodTable}.
1043       *                 This information is used primary to write out the method table. The names are copied and changed in an inherited class.
1044       * @param retType The type of return. It isn't a Classdata, but a IdentInfo, 
1045       *                   because some additional properties like return by value or reference should be present.
1046       * @return The created and registered instance of method. 
1047       */
1048      final Method addMethod
1049      ( String sMethodNameJava
1050                    , String sMethodNameUnambiguous
1051                    , String sImplementationName
1052              , int modifier
1053      , FieldData retType
1054      , FieldData[] argTypes
1055      )
1056      { /**The declaring class of the method may be a super-class or interface. */
1057        final ClassData declaringClassOfMethod;
1058        
1059        if(sMethodNameJava.equals("processIfcMethod") && sClassNameJava.equals("ImplIfc"))
1060          stop();
1061        
1062        final String sPathToMtbl;
1063        final String sPathToBase;
1064        final Method primaryMethod;
1065        if(sMethodNameUnambiguous.startsWith("processIfcMethod"))
1066          stop();
1067        
1068        /**Check whether the method is already declared in a base class or interface: */
1069        MethodOverrideCheck method1Found = searchOverrideableMethod(sMethodNameJava, argTypes);
1070        //MethodOverrideCheck method1Found = methodsCheckOverriding.get(sMethodNameUnambiguous);
1071        if(method1Found != null){
1072          /**The method is defined in a superclass or interface and will be overridden here: */
1073          //sMethodNameUnambiguous = method1Found.method.sNameUnambiguous; //this name is valid.
1074          final String sNameCFinal;  //use the same algorithm like in Method.ctor!!!
1075          if(sMethodNameUnambiguous.startsWith("!")){
1076            /**Special case, name not ending with class, only for base methods. */
1077            sNameCFinal = sMethodNameUnambiguous.substring(1);
1078          } else {
1079            sNameCFinal = sMethodNameUnambiguous + "_" + getClassIdentName() 
1080                             + ( (modifier & Method.modeOverrideable) != 0 ? "_F" : "");
1081          }
1082          for(MethodOverrideCheck.MethodIndex methodIndex: method1Found.listOccurence){
1083            /**Change all names of methods which are overridden with the given method. */
1084            methodIndex.ref[methodIndex.idx].sNameOverriding = sNameCFinal;
1085          }
1086          primaryMethod = method1Found.method;
1087          declaringClassOfMethod = primaryMethod.declaringClass;
1088          sPathToMtbl = method1Found.sPathToMtbl;
1089          sPathToBase = method1Found.sPathToBase;
1090          /**Inherit the some mode bits from the overridden method: */
1091          modifier |= primaryMethod.mode & (Method.modeNoThCxt);
1092        } else {
1093          /**The method isn't found in a base class or interface. */
1094          declaringClassOfMethod = this;
1095          /**sPathToMtbl is used if the method can bei overridden. Set "" in this case.
1096           * If the method isn't able to override, the sPathToMtbl is not need anywhere.
1097           * Set it to null to mark 'not able to override' additionally.
1098           */ 
1099          sPathToMtbl = (modifier & Method.modeOverrideable) != 0 ? "" : null;
1100          sPathToBase = "";
1101          primaryMethod = null;
1102        }
1103          
1104        /**primary super class or interface which defines the method. */
1105        ClassData.InheritanceInfo primaryInheritanceInfo = null;
1106        /**Test of super classes...*/
1107        if(!sMethodNameJava.startsWith("ctor"))
1108          stop();
1109    
1110            final int nrofArguments = argTypes == null ? 0 : argTypes.length;
1111        final boolean bVaArg;
1112        if(nrofArguments >=1 && argTypes[nrofArguments-1].typeClazz == CRuntimeJavalikeClassData.clazz_va_argRaw){
1113            bVaArg = true;
1114        } else { bVaArg = false; }
1115        final String sKeyName = sMethodNameJava +"#" 
1116            + (bVaArg ? "*" :nrofArguments);
1117        
1118        Method method = new Method(this, primaryMethod, sKeyName, sMethodNameJava
1119            , sMethodNameUnambiguous, sImplementationName, modifier, retType, argTypes, sPathToMtbl, sPathToBase);
1120        
1121        Java2C_Main.singleton.console.reportln(Report.debug, "Java2C-ClassData.addMethod: to Class:" 
1122            + getClassIdentName() + ", method: " + method.writeStruct());
1123       
1124        addMethodToList(method);
1125        
1126        if(method1Found == null && method.isOverrideable()){
1127          /**A new override-able method, not defined in a base class or interface: */
1128          MethodOverrideable method1 = new MethodOverrideable(method, method.sImplementationName);
1129          if(methodsOverrideableNew == null){ methodsOverrideableNew = new LinkedList<MethodOverrideable>(); }
1130          methodsOverrideableNew.add(method1);
1131          
1132        }
1133          
1134        return method;
1135      }
1136    
1137      /**Adds the method to the lists {@link #methods} and {@link #methodsCname}
1138       * @param method
1139       */
1140      private void addMethodToList(Method method)
1141      { Object oMethods;
1142            String sKeyName = method.sKeyName;
1143        if(sKeyName.startsWith("sendMsg"))
1144            stop();
1145        if(methods == null)
1146        { methods = new TreeMap<String, Object>();
1147          oMethods = null;
1148        }
1149        else {
1150          oMethods = methods.get(sKeyName);
1151        }
1152        
1153        if(oMethods == null){
1154          /**methods with the given number of parameter is unknown, add as first method. */
1155          methods.put(method.sKeyName, method);
1156        }
1157        else {
1158          if(oMethods instanceof Method)
1159          { List<Method> list = new LinkedList<Method>();
1160            list.add((Method)oMethods);  //the first
1161            list.add(method);  //the second
1162            methods.put(sKeyName, list);  //now it is a list.
1163          }
1164          else
1165          { assert(oMethods instanceof List);
1166            @SuppressWarnings("unchecked")
1167            List<Method> list = (List<Method>)oMethods; //it is already a list
1168            list.add(method);
1169          }
1170        }
1171        
1172        if(methodsCname == null) { methodsCname = new TreeMap<String, Method>(); }
1173        methodsCname.put(method.sCName, method);
1174      }
1175      
1176      
1177      /**searches whether a method found in the first pass of a translated class is already declared
1178       * in an super class or interface of this class.
1179       * If the method is found more as one time in parallel interfaces, there is noted only one time.
1180       * But the occurrence is stored in the returned instance.
1181       * <br>
1182       * <img src="../../../../Java2C/img/MethodsOverride_omdJava2C.png" />
1183       * @param sMethodNameJava The method name in Java
1184       * @param argTypes arg types of the found method.
1185       * @return null if the method isn't declared already, elsewhere the override-able method description.
1186       */
1187      MethodOverrideCheck searchOverrideableMethod(String sMethodNameJava, FieldData[] argTypes)
1188      { MethodOverrideCheck methodFound;
1189        if(sMethodNameJava.equals("anotherIfcmethod"))
1190          stop();
1191        Object omethodFound = methodsCheckOverriding==null ? null : methodsCheckOverriding.get(sMethodNameJava);
1192        boolean bMatching;
1193        if(omethodFound != null) {
1194          if(omethodFound instanceof MethodOverrideCheck)
1195          { /**Only one method with that name is known. Check it whether the parameter set is equal. */
1196            methodFound = (MethodOverrideCheck)omethodFound;
1197            bMatching = methodFound.method.sameParameterTypes(argTypes);
1198            if(!bMatching){
1199              methodFound = null;
1200            }  
1201          }
1202          else
1203          { /**If it isn't instanceof MethodOverrideCheck, it is instanceof List and it has at least one element. 
1204             * Now check whether one of the methods have the same parameter types.
1205             */
1206            @SuppressWarnings("unchecked")
1207            List<MethodOverrideCheck> listMethods = (List<MethodOverrideCheck>)omethodFound;
1208            Iterator<MethodOverrideCheck> iterMethods = listMethods.iterator();
1209            bMatching = false;
1210            do 
1211            { methodFound = iterMethods.next();
1212              bMatching = methodFound.method.sameParameterTypes(argTypes);
1213              if(!bMatching){
1214                methodFound = null;
1215              }  
1216            } while(!bMatching && iterMethods.hasNext());
1217          }
1218        }
1219        else { 
1220          methodFound = null; //not found in methodsCheckOverriding
1221        }
1222        return methodFound;
1223      }
1224      
1225      
1226      
1227      
1228      
1229    
1230      /**Registers a given Method. This routine is used if a file.stc is parsed.
1231       * @param m The Method data.
1232       */
1233      public void addMethod(Method m)
1234      { addMethodToList(m);
1235      }
1236    
1237    
1238    
1239      /**If a type is used as enhanced reference in the code of the class, it is noted here and in Java2CMain.
1240       * The information will be used to define the enhanced references in the Headerfile,
1241       * it is also transformed to the stc file. (?)
1242       * @param sRefType The referenced type.
1243       */
1244      public void addEnhancedRefType(String sRefType)
1245      {
1246        fileContainsClass.addEnhancedRefType(sRefType);
1247      }
1248    
1249    
1250      /**Adds in inner class to the class.
1251       * @param innerClass
1252       */
1253      void addInnerClass(ClassData innerClass)
1254      {
1255        if(innerClasses ==null){ innerClasses = new LinkedList<ClassData>(); }
1256            innerClasses.add(innerClass);
1257      }
1258      
1259      
1260      
1261      
1262    
1263      
1264      /**Copies all field idents of this class to its  non-static inner classes,
1265       * because the inner classes should know the idents of its outer class. */
1266      void completeFieldIdentsForInnerClasses()
1267      {
1268            if(innerClasses !=null)
1269            for(ClassData innerClassData: innerClasses){
1270                    //if(innerClassData.isNonStaticInner){
1271                    classLevelIdents.copyFieldsTo(innerClassData);
1272                    //}
1273                    innerClassData.completeFieldIdentsForInnerClasses();  //recursively for inner inner classes.
1274            }
1275      }
1276    
1277      /**Completes the type information of this outer class for all its inner classes. 
1278       * This routine is called after {@link GenerateFile#runFirstPassFile(ZbnfParseResultItem, String, String, String)}
1279       * of this class is finished. Then all types of this class, they are the inner classes,
1280       * are gathered. All inner classes have to know all the other inner classes too, the inner classes
1281       * should be known together. Additional the inner classes should know its outer one as type too.
1282       * <br><br>
1283       * This routine is called recursively for all its own inner classes too. 
1284       */
1285      void completeTypesForInnerClasses()
1286      { if(innerClasses !=null){
1287          stop();
1288                    for(ClassData innerClassData: innerClasses){
1289                  classLevelIdents.copyTypesTo(innerClassData);     
1290                  innerClassData.completeTypesForInnerClasses();  //call recursively if more levels of inner classes        
1291                    }
1292        }
1293      }
1294      
1295      
1296      
1297      
1298      /**Sets the finalize bit. This method is called if any condition is met which requires
1299       * the generation of a finalize method. It is, if the class contains enhanced references
1300       * or if a finalize method is given in Java code.
1301       */
1302      public void needFinalize()
1303      {
1304        bFinalizeNeed = true;
1305      }
1306      
1307      
1308      
1309      /**If a type is used as method-table- reference in the code of the class, it is noted here.
1310       * The information will be used to define the enhanced references in the Headerfile,
1311       * it is also transformed to the stc file. (?)
1312       * @param sRefType The referenced type.
1313       */
1314      public void addMtblRefType(String sRefType, char intension)
1315      {
1316        fileContainsClass.addMtblRefType(sRefType, intension);
1317      }
1318      
1319      
1320      
1321      
1322      
1323      /*
1324      public ClassData nextArrayDimension()
1325      { if(arrayType == null)
1326        { //An arraytype doesn't exist, create it because it is required. 
1327          arrayType = new ClassData(this ); //special private constructor for next array dimension.
1328          //NOTE: special constructor is necessary because some final fields.
1329        }
1330        return arrayType;
1331      }
1332      */
1333      
1334      
1335      /**Tests whether a method is registered, registers it or set it to ambiguous if it exists already.
1336       * This routine is called processing the first pass of translation. 
1337       * It creates an entry with key sNameJava + "?" to check ambiguously.
1338       * In the second pass the methods are registered with full informations.
1339       * @param sNameJava The method name.
1340       */
1341      public void testAndSetAmbiguousnessOfMethod(String sNameJava)
1342      { if(methods == null) { methods = new TreeMap<String, Object>(); }
1343        Method m = (Method)methods.get(sNameJava+"?");
1344        if(m != null)
1345        { //The method with the same java name is present already:
1346          m.setAmbiguousness();
1347        }
1348        else
1349        { m = new Method(this, null, sNameJava+"?", sNameJava, null, null, 0, null, null, null, "");  //it is a preliminary instance.
1350          methods.put(sNameJava+"?", m);
1351        }
1352      }
1353    
1354      
1355      /**tests whether the method is ambiguous. The method have to be exist.
1356       * @param sNameJava
1357       * @return true if more as one method with the same Java name exists. 
1358       */
1359      public boolean isAmbiguousnessMethod(String sNameJava)
1360      { Method m = (Method)methods.get(sNameJava+"?");
1361        if(m == null)
1362        { stop();
1363          return false;
1364        }
1365        return m.isAmbigous();  //true if it is the second method
1366      }
1367    
1368      
1369      
1370      
1371      private boolean checkParameterTypesMethod(Method methodTest, FieldData[] paramsType)
1372      {
1373        boolean bMatching;
1374        int idxParam = 0;
1375        if(paramsType == null && (methodTest.paramsType == null || methodTest.paramsType.length == 0))
1376        { 
1377          bMatching = true;
1378        }
1379        else
1380        { bMatching = true; //default, abort test if false.
1381          int idxParamsType = 0;
1382          while(bMatching && idxParamsType < paramsType.length)
1383          { FieldData infoActParam = paramsType[idxParamsType++];
1384            FieldData typeParamMethod = methodTest.paramsType[idxParam++];
1385            if(typeParamMethod.typeClazz != infoActParam.typeClazz)
1386              //TODO test array properties
1387            { bMatching = false;
1388            }
1389          }
1390        }
1391        return bMatching;
1392      }              
1393      
1394      
1395      Method getMethodPerCname(String sNameC){ return methodsCname.get(sNameC); }
1396      
1397      
1398      /**Searches a method with the given Java name and all argument types.
1399       * @param sNameJavaP The name in Java.
1400       * @param paramsTypeCheck All argument types. It is tested whether the argument types 
1401       *                   are able to cast to the matching types.
1402       * 
1403       * @param strict true then the method is not created if if isn't found. It should be found.
1404       * @param sPathMtbl Starting with "", a seach in a super-class adds the path.
1405       * @return The appropriate method or null if no method matches.
1406       */
1407      public Method searchMethod( 
1408                    final String sNameJavaP, final List<CCodeData> paramsTypeCheck, boolean strict
1409        , String[] sPathMtbl
1410      )
1411      { boolean bFound = false;
1412        //String sNameTranslate = null;
1413        Method methodFound = null;
1414        String sPathMtbl1 = "";
1415        String sKeyName, sKeyNameVarg;
1416        if(sNameJavaP.equals("assert"))
1417        {
1418          return Java2C_Main.singleton.standardClassData.methodASSERT; 
1419        }
1420        else
1421        {
1422          if(sNameJavaP.equals("setBigEndian")) // && sClassNameJava.equals("Thread"))
1423            stop();
1424          sKeyName = sNameJavaP +"#"+ (paramsTypeCheck == null ? "0" : paramsTypeCheck.size());
1425          sKeyNameVarg = paramsTypeCheck == null ? "???" : sNameJavaP +"#*";
1426          if(methods != null) { 
1427            if(sNameJavaP.equals("arraycopy") ) // && this.sClassNameJava.equals("StringFormatter"))
1428              stop();
1429            if(sKeyName.equals("ctorO#1") && this.sClassNameJava.equals("StringFormatter"))
1430              stop();
1431            Object omethodFound;;
1432            if( (omethodFound = methods.get(sKeyName))!= null){
1433                    methodFound = checkParameterMethod(omethodFound, paramsTypeCheck);
1434            }
1435            /**methodFound is !=null if the parameters are matched. */
1436            if(methodFound ==null && (omethodFound = methods.get(sKeyNameVarg))!= null){
1437              /**method with matched parameters not found, 
1438               * but a method with variable argument list is found with given name, check it: */
1439                    methodFound = checkParameterMethod(omethodFound, paramsTypeCheck);
1440            }
1441          }//if methods!=null 
1442          if(methodFound == null)
1443          { /**Try to search in all super classes and their outer classes
1444             * It is a recursively call. First search in all super classes, than in the outer classes.
1445             * It is the order like in Java.
1446             */
1447            if(sNameJavaP.equals("setBigEndian"))
1448              stop();
1449            if(sNameJavaP.equals("ctorO"))
1450              stop();
1451            ClassData superClass = getSuperClassData();
1452            if(!sNameJavaP.startsWith("ctorO") && superClass != null) {
1453                    //it may be a recursively call.
1454                    String[] sPathMtblSuper = new String[1];
1455                    sPathMtblSuper[0] = sPathMtbl[0];
1456                    methodFound = superClass.searchMethod(sNameJavaP, paramsTypeCheck, true, sPathMtbl);
1457                    if(methodFound !=null){
1458                            sPathMtbl1 = superClass.getClassIdentName() + "." 
1459                              + (sPathMtbl !=null && sPathMtbl[0] !=null ? sPathMtbl[0] : "");
1460                    }
1461            }
1462          }
1463          if(methodFound == null){
1464            /**Try to search in all outer classes, and their super-classes.
1465             * It is a recursively call. First search in all super classes, than in the outer classes.
1466             * It is the order like in Java.
1467             */
1468            ClassData outerClass = getOuterClass();
1469            if(outerClass != null) {
1470              methodFound = outerClass.searchMethod(sNameJavaP, paramsTypeCheck, true, sPathMtbl);
1471            }
1472          }
1473          if(!strict && methodFound == null){
1474            /**Method not found: */
1475            String sNameC1 = sNameJavaP /* + "/*" + sKeyName + "?method(";
1476            String delim = "";
1477            if(paramsType != null) for(CCodeData param:paramsType)
1478            { sNameC1 += delim + param.identInfo.toString();
1479              delim = ",";
1480            }
1481            sNameC1 += ")* /" */;
1482            methodFound = new Method(this, null, sKeyName, sNameJavaP, sNameC1, null, Method.modeUnknownMethod
1483                , CRuntimeJavalikeClassData.clazz_unknown.classTypeInfo, null, null, "");
1484          }
1485          if(sPathMtbl !=null){ 
1486            sPathMtbl[0] = sPathMtbl1;
1487          }
1488          return methodFound;
1489          //return sNameTranslate;
1490        }  
1491      }
1492      
1493    
1494            private Method checkParameterMethod(Object omethodFound, final List<CCodeData> paramsTypeCheck)
1495            { Method methodFound = null;
1496                    if(omethodFound instanceof Method)
1497              { methodFound = (Method)omethodFound; 
1498              }
1499              else
1500              { @SuppressWarnings("unchecked")
1501                    List<Method> listMethods = (List<Method>)omethodFound;
1502                //boolean bMatching = false;
1503                Iterator<Method> iterMethods = listMethods.iterator();
1504                //while(!bMatching && iterMethods.hasNext())
1505                int scoreFound = 0;
1506                //while(methodFound==null && iterMethods.hasNext())
1507                while(iterMethods.hasNext())
1508                { Method methodTest = iterMethods.next();
1509                  int scoreMethod = methodTest.checkParameter(paramsTypeCheck);
1510                  //if(methodTest.checkParameter(paramsTypeCheck))
1511                  if(scoreMethod > scoreFound )
1512                  { methodFound = methodTest;  //the last method with highest score wins.
1513                    scoreFound = scoreMethod;
1514                  }
1515                }
1516              }
1517                    return methodFound; //maybe null
1518            }
1519      
1520      
1521      
1522      /**Returns the name of the class used as C-type. If it is an generated class, that type names
1523       * have an extension <code>_s</code>. The type name without this extension is useable, 
1524       * if a C++-wrapper-class of that type is desired. 
1525       */
1526      public String getClassCtype_s(){ return sClassNameC; }
1527      
1528      
1529      /**Returns the name of the class used in Java without package information.
1530       */
1531      public String getClassNameJava(){ return sClassNameJava; }
1532      
1533      
1534      /**Returns the indentification name of a class. If the class is generated from java2c, 
1535       * it is the name without the <code>_s</code> or <code>_i</code> on end.
1536       * The identification is used as postfix of the static visible class elements.
1537       * But the <code>struct</code> type have the additional postfix <code>_s</code> or <code>_i</code>
1538       * to to distinguish between its possible C++-class.
1539       */
1540      public String getClassIdentName()
1541      { if(sClassNameC.endsWith("_s") || sClassNameC.endsWith("_i"))
1542        { return sClassNameC.substring(0, sClassNameC.length()-2); }
1543        else{ return sClassNameC; }
1544      }
1545      
1546      
1547      public String getClassNameJavaFullqualified(){ return sClassNameJavaFullqualified; }
1548      
1549      /**Returns true if it is a primitive type without any own elements. It is, if the element 
1550       * {@link #classLevelIdents} is null.
1551       */
1552      public boolean isPrimitiveType(){ return classTypeInfo.modeAccess == '%'; } //return classLevelIdents == null; }
1553    
1554      /**Returns true if the type is 'String'.
1555       */
1556      public boolean isString(){ return classTypeInfo.modeAccess == 't'; } //return classLevelIdents == null; }
1557    
1558    
1559      public boolean xxxisObject(){ return inheritanceInfo != null; }
1560      public boolean xisObject(){ return basedOnObject; }
1561      
1562      
1563      /**Returns true if it is an interface.
1564       */
1565      public boolean isInterface(){ return bInterface; }
1566    
1567    
1568      /**Returns true if the finalize is need but it is not written in Java.
1569       */
1570      public boolean isFinalizeNeed(){ return bFinalizeNeed; }
1571      
1572      /**Returns the superclass or null. */
1573      public ClassData getSuperClassData()
1574      {
1575        final ClassData superClass;  //superclass of next level? 
1576        if(inheritanceInfo != null)
1577        { InheritanceInfo superInheritanceInfo = inheritanceInfo.superInheritance;
1578          superClass = (superInheritanceInfo == null) ? null : superInheritanceInfo.classData;
1579        }
1580        else
1581        { superClass = null;
1582        }
1583        return superClass;        
1584      }
1585      
1586      /**Returns the ClassData of outer class or null.
1587       */
1588      public ClassData getOuterClass()
1589      { return outerClazz;
1590      }
1591      
1592      
1593      /**Returns all interfaces of immediate level (not interfaces of base classes).
1594       * @return The interfaces are provided in an array.
1595       */
1596      public ClassData[] getInterfaces()
1597      { final ClassData[] ifc;
1598        //final TreeMap<String, InheritanceInfo> ifc;  //superclass of next level? 
1599        if(inheritanceInfo != null)
1600        { //Map<String, InheritanceInfo> ifcInheritanceInfo = inheritanceInfo.ifcInheritance;
1601          if(inheritanceInfo.ifcInheritance != null){
1602          //if(ifcInheritanceInfo != null){
1603            ifc = new ClassData[inheritanceInfo.ifcInheritance.length];
1604            //ifc = new ClassData[ifcInheritanceInfo.size()];
1605            int ix=0;
1606            //Set<Entry<String,InheritanceInfo>> entrySet = inheritanceInfo.ifcInheritance.entrySet();
1607            for(InheritanceInfo srcIfcInheritance : inheritanceInfo.ifcInheritance){
1608            //for(Entry<String,InheritanceInfo> entry : entrySet){
1609              ClassData ifcData = srcIfcInheritance.classData;
1610              //ClassData ifcData = entry.getValue().classData;
1611              ifc[ix++] = ifcData;
1612            }
1613          } else {
1614            ifc = null;
1615          }
1616        } else {
1617          ifc = null;
1618        }
1619        return ifc;        
1620      }
1621      
1622      
1623      /**returns a String, which describes the access to the ObjectJc-base, or return null,
1624       * if the class isn't based on any class. It assumes, all superclasses should have the name "super",
1625       * the ObjectJc-superclass should have the name "object".
1626       * At ex. returns "object"
1627       * 
1628       * @return
1629       */
1630      public String xxxgetRefObjectJc()
1631      { String ret = "";
1632        ClassData superClazz = getSuperClassData();
1633        while( superClazz != null)
1634        { if(superClazz == CRuntimeJavalikeClassData.clazzObjectJc)
1635          { ret += "base.object";
1636          }
1637          else
1638          { ret += "base.super";
1639          }
1640          superClazz = superClazz.getSuperClassData();
1641        }
1642        return ret.length() ==0 ? null: ret.substring(1);  //without first "."
1643      }
1644      
1645      
1646      
1647      /**returns a String, which describes the access to the ObjectJc-base, or return null,
1648       * if the class isn't based on any class. It assumes, all superclasses should have the name "super",
1649       * the ObjectJc-superclass should have the name "object".
1650       * At ex. returns "object"
1651       * 
1652       * @return
1653       */
1654      public String xxxxxgetRefObjectJc()
1655      { return "base.object";
1656      }
1657      
1658      
1659      
1660      public boolean isBasedOnObject(){ return basedOnObject; }
1661      public boolean xxxisBasedOnObject()
1662      { boolean ret = false;
1663        ClassData superClazz = getSuperClassData();
1664        while(superClazz != null)
1665        { if(superClazz == CRuntimeJavalikeClassData.clazzObjectJc)
1666          { ret = true;
1667          }
1668          superClazz = superClazz.getSuperClassData();
1669        }
1670        return ret;    
1671      }
1672      
1673      
1674      /**Returns true if the class isn't known in Java2C context. It is a external used class.*/
1675      public boolean isExternal(){ return bExternal; }
1676      
1677      
1678      /**Returns the info how to cast from this type to another.
1679       * @param typeSrc Name of the source type.
1680       * @return CastInfo contains pre- and suffix C-Code and the modeAccess.
1681       */
1682      public CastInfo getCastInfoFromType(String typeSrc)
1683      { if(castableFromType != null) { return castableFromType.get(typeSrc); } //may be null if not found.
1684        else return null;  //no cast info.
1685      }
1686      
1687      
1688      
1689      /**Returns the info how to downcast from this type to another.
1690       * @param typeSrc Name of the source type.
1691       * @return CastInfo contains pre- and suffix C-Code and the modeAccess.
1692       */
1693      public CastInfo getCastInfoToType(String typeSrc)
1694      { if(castableToType != null) { return castableToType.get(typeSrc); } //may be null if not found.
1695        else return null;  //no cast info.
1696      }
1697      
1698      
1699      /**Returns the info how to downcast from this type to another.
1700       * @param typeSrc Name of the source type.
1701       * @return CastInfo contains pre- and suffix C-Code and the modeAccess.
1702       */
1703      public CastInfo getCastInitializerFromType(String typeSrc)
1704      { if(castableInitializerFromType != null) { return castableInitializerFromType.get(typeSrc); } //may be null if not found.
1705        else return null;  //no cast info.
1706      }
1707      
1708      
1709      
1710      /**Checks whether the src matches to this class with or without type casting.
1711       * @param src The type to compare
1712       * @return the score. 0: doesn't match 1 .. 4 see {@link CastInfo#kCastAble}. 
1713       */
1714      int matchedToTypeSrc(ClassData src)
1715      { String typeSrc = src.sClassNameC;
1716        CastInfo castInfo;
1717        if(this.sClassNameC.equals(src.sClassNameC)) return CastInfo.kCastEqual;
1718        else if(  (castInfo = getCastInfoFromType(typeSrc)) != null  //the typeSrc is found in castableFromType, apropriate to some conversions
1719               || (castInfo = src.getCastInfoToType(sClassNameC)) != null){
1720            if( (castInfo.pre == null || castInfo.pre.length()==0)
1721                    &&(castInfo.post == null || castInfo.post.length()==0)  
1722                    ){
1723                    return CastInfo.kCastAutomatic;  //types are castable without any additional cast expression.
1724            } else {
1725              return CastInfo.kCastAble;  //this is found in castableFromType of srctype, appropritate to base class
1726          }
1727        }
1728        else if(this.sClassNameJava.equals("va_argRaw")){
1729            return CastInfo.kCastCommon;  //the src is matching to a raw variable argument always.
1730        }
1731        else return CastInfo.kCastNo;  //not able to cast.
1732      }
1733    
1734      ZbnfParseResultItem getParseResult(){ return zbnfClass; }
1735    
1736      /**relinquishes the parse result, because it is processed. It should not consumed memory.*/
1737      void relinquishParseResult(){ zbnfClass = null; }
1738    
1739      /**Helper variable to generate indentation, see {@link #indent(int)} */
1740      private final static String newLineIndent = "\n                                            ";
1741      
1742      /**Generates an indentation, used inside {@link #writeStructureClass(BufferedWriter, int)}
1743       * @param recursion nesting level
1744       * @return A newline char and the appropritate number of spaces for indentation. 
1745       */
1746      private String indent(int recursion){ return newLineIndent.substring(0, 2*recursion +1); } 
1747      
1748      
1749      public void reportContent(Report console, int reportlevel){
1750        console.reportln(reportlevel, "==Structure of class==");
1751            StringWriter buffer = new StringWriter();
1752            BufferedWriter out = new BufferedWriter(buffer);
1753            try{ 
1754                    writeStructureClass(out,0);
1755                    out.close();
1756        } catch(IOException exc){
1757                    console.writeError("error", exc);
1758            }
1759        String sReport = buffer.toString();
1760        LogMessage msg = console.getLogMessageOutputFile();
1761        msg.sendMsg(105, sReport);
1762        msg.sendMsg(106, "Ident of instance: " + sClassNameJavaFullqualified + ": %s", toString());
1763            for(Map.Entry<String,JavaSources.ClassDataOrJavaSrcFile> setInnerClass: this.classLevelIdents.getTypeSet()){
1764              ClassData innerClass = setInnerClass.getValue().getClassData();
1765              msg.sendMsg(107, "Ident of innerclasses: " + innerClass.sClassNameJava + ": %s", innerClass.toString());
1766              
1767            }
1768        msg.flush();
1769        //console.report(reportlevel, buffer.toString());
1770            //console.flushReport();
1771            //console.flush();
1772      }
1773      
1774    
1775      /**returns the definition of the methodtable of the class and all superclasses.
1776       */
1777      public String gen_MethodTableDefinitionContent()
1778      { String ret = "MtblHeadJc head;";
1779        if(inheritanceInfo != null) {
1780          if(inheritanceInfo.methodTable != null){
1781            /**Content of methods of the own class. */
1782            for(MethodOverrideable methodOverridden: inheritanceInfo.methodTable)
1783            { ret += "\n  MT_" + methodOverridden.method.sMethodTypeName + "* " + methodOverridden.method.sNameUnambiguous + ";";
1784            }
1785          }
1786          if(inheritanceInfo.superInheritance != null){
1787            /**Only the direct Superclass is written, it contains the inner superclasses and ObjectJc. */
1788            String sSuperName = inheritanceInfo.superInheritance.classData.getClassIdentName();
1789            ret += "\n  Mtbl_" + sSuperName + " " + sSuperName + ";";
1790          }
1791          if(inheritanceInfo.ifcInheritance != null){
1792            ret += "\n  //Method table of interfaces:";
1793            //Set<Entry<String,InheritanceInfo>> entrySet = inheritanceInfo.ifcInheritance.entrySet();
1794            for(InheritanceInfo ifcInheritance : inheritanceInfo.ifcInheritance){
1795            //for(Entry<String,InheritanceInfo> entry : entrySet){
1796              ClassData ifcData = ifcInheritance.classData;
1797              //ClassData ifcData = entry.getValue().classData;
1798              String sIfcName = ifcData.getClassIdentName();
1799              ret += "\n  Mtbl_" + sIfcName + " " + sIfcName + ";";
1800            }
1801          }
1802        }  
1803        return ret;
1804      }    
1805      
1806            /**Generates the content of the class definition for C++,
1807             * to write in the header-file. 
1808             * @return
1809             */
1810            public String gen_ClassCppDefinitionContent()
1811            {
1812                    StringBuilder u = new StringBuilder(5000);
1813                    if(methodsCname !=null){
1814                            Collection<Method> methods = methodsCname.values();
1815                            for(Method method: methods){
1816                                    int bitsStringJcParam;
1817                                    if(method.sCName.startsWith("ctorM")){
1818                                     //TODO
1819                                    }       
1820                                    else if(method.sCName.startsWith("finalize")){
1821                                            //TODO
1822                                    } else {
1823                                //bitsStringJcParam = 
1824                                gen_MethodCpp(u, method, 0); //StringJc-parameter-variant
1825                                /*
1826                                int bitZchar = 1;
1827                                while(bitZchar <= bitsStringJcParam){
1828                                  while((bitZchar & bitsStringJcParam)==0){ bitZchar <<=1; }
1829                                  gen_MethodCpp(u, method, bitZchar);
1830                                  bitZchar <<=1;
1831                                } 
1832                                */ 
1833                                    }
1834                            }
1835                    }
1836                    return u.toString();
1837            }
1838      
1839    
1840            private int gen_MethodCpp(StringBuilder u, Method method, int bitZchar)         
1841            {       int bitsStringJcParam = 0;
1842    
1843                    String sReturnTypeDefinition = method.sReturnTypeDefinition;
1844                    if(sReturnTypeDefinition == null){ sReturnTypeDefinition = "void"; }
1845                    else if(method.isReturnThis()){ sReturnTypeDefinition = getClassIdentName() + "&";}
1846                    if(method.sCName.startsWith("ctorO")){
1847                            u.append("\n\n  ").append(getClassIdentName());  //ctor in C++ with class-name
1848                    } else { 
1849                            u.append("\n\n  ");
1850                            if(method.isOverrideable()){
1851                                    u.append("virtual ");
1852                            }
1853                            u.append(sReturnTypeDefinition).append(" ").append(method.sJavaName);
1854                    }
1855                    u.append("(");
1856                    String sSeparator = "";
1857                    int mBitStringJcParam = 1;
1858                    /**formal parameter for C++-method-head. */
1859                    int bitZcharTest = 1;
1860                    if(method.paramsType!=null)
1861                    for(FieldData param: method.paramsType){
1862                            if( param.typeClazz == CRuntimeJavalikeClassData.clazzStringJc
1863                                    && param.getDimensionArray() == 0
1864                                    ){
1865                                    bitsStringJcParam |= mBitStringJcParam;
1866                                    /**Use StringJcpp instead StringJc, because a type conversion from "literal" is supported.*/
1867                                    u.append(sSeparator).append("StringJcpp ").append(param.getName());
1868                            } else {
1869                                    u.append(sSeparator).append(param.gen_VariableDefinition('b'));
1870                            }
1871                            /*
1872                            if((bitZchar & mBitStringJcParam)!=0){
1873                                    u.append(sSeparator).append("char const* ").append(param.getName());
1874                            } else {
1875                                    u.append(sSeparator).append(param.gen_VariableDefinition());
1876                            }
1877                            */
1878                            mBitStringJcParam <<=1;   
1879                            sSeparator = ", ";
1880                    }
1881                    u.append(")");
1882                    if(isInterface()){
1883                            u.append("=0;");
1884                    } else {
1885                            u.append("{ ");
1886                            if(method.sCName.startsWith("ctorO")){
1887                                    //u.append("memset((ObjectJc*)this, sizeof(").append(sClassNameC).append("), 0); ");
1888                                    u.append("init_ObjectJc(&this->base.object, sizeof(").append(sClassNameC).append("), 0); ");
1889                                    u.append("setReflection_ObjectJc(&this->base.object, &reflection_").append(sClassNameC).append(", 0); "); 
1890                                    u.append(method.sCName).append("(").append("&this->base.object");
1891                              sSeparator = ", ";
1892                            }
1893                            else { 
1894                                    if(!sReturnTypeDefinition.equals("void") && !method.isReturnThis()){ 
1895                                            u.append(" return "); 
1896                                    }
1897                                    /**Method name call:*/
1898                                    u.append(method.sCName);
1899                                    if(method.isOverrideable()){
1900                                            u.append("_F");
1901                                    }       
1902                                    u.append("(");
1903                                    if(method.isStatic()){ sSeparator = "";}
1904                                    else {
1905                                            sSeparator = ", ";
1906                                            if(method.sPathToBase.length() >0){
1907                                              u.append("&this->").append(method.sPathToBase.substring(1));  //without first dot because ->        
1908                                  if(method.firstDeclaringClass.isInterface()){
1909                                    u.append(".base.object");  //call an interface method via ObjectJc*. It is not part of sPathToBase, why?
1910                                  }
1911                                            } else {
1912                                              u.append("this");     
1913                                            }
1914                                    }
1915                      }
1916                            mBitStringJcParam = 1;
1917                            /**actual parameter for C-routine-call. */
1918                            if(method.paramsType!=null)
1919                            for(FieldData param: method.paramsType){
1920                                    /*
1921                                    if((bitZchar & mBitStringJcParam)!=0){
1922                                            u.append(sSeparator).append("z_StringJc(").append(param.getName()).append(")");
1923                                    } else */{
1924                                            u.append(sSeparator).append(param.getName());
1925                                    }
1926                                    mBitStringJcParam <<=1;
1927                                    sSeparator = ", ";
1928                            }
1929                            if(method.need_thCxt){ u.append(sSeparator).append(" null/*_thCxt*/"); }
1930                            u.append("); ");
1931                            if(method.isReturnThis()){ 
1932                                    u.append(" return *this; "); 
1933                            }
1934                            u.append("}");
1935                    }
1936                    return bitsStringJcParam;
1937            }
1938    
1939    
1940    
1941      /**returns the definition of the methodtable of the class and all superclasses.
1942       * @param classDataP
1943       * @return
1944       */
1945      String genMethodTableContent(ClassData.InheritanceInfo inheritanceInfo, String sClassName, int indent)
1946      { String ret;
1947        char cSeparator;
1948        String sClassIdentNameCurrent = inheritanceInfo.classData.getClassIdentName();  //from superclass etc.  
1949        if(sClassNameJava.equals("TestAllConcepts"))
1950          stop();
1951        assert(inheritanceInfo != null);
1952        if(indent==0){
1953          ret = GenerateClass.genIndent(indent) + "{ ";
1954        } else {
1955          ret = GenerateClass.genIndent(indent-1) + ", { ";
1956        }
1957        int nrofMethods = inheritanceInfo.methodTable == null ? 0 : inheritanceInfo.methodTable.length;
1958        ret += "{ sign_Mtbl_" + sClassIdentNameCurrent + "//J2C: Head of methodtable." 
1959        //    + ", (struct Size_Mtbl_t*)sizeof(Mtbl_" + sClassIdentNameCurrent + ") } //head";      
1960            + GenerateClass.genIndent(indent) + "  , (struct Size_Mtbl_t*)((" + nrofMethods + " +2) * sizeof(void*)) //size. NOTE: all elements are standard-pointer-types."      
1961            + GenerateClass.genIndent(indent) + "  }";      
1962        cSeparator = ',';
1963        if(nrofMethods >0 ){
1964          /**Content of methods of the own class. */
1965          for(MethodOverrideable methodOverridden: inheritanceInfo.methodTable)
1966          { ret += GenerateClass.genIndent(indent) + ", " + methodOverridden.sNameOverriding + " //" + methodOverridden.method.sNameUnambiguous;
1967            cSeparator = ',';
1968          }
1969        }
1970    
1971        
1972        if(inheritanceInfo.superInheritance != null){
1973          ret += genMethodTableContent(inheritanceInfo.superInheritance, sClassName, indent+1);
1974          cSeparator = ',';
1975        }
1976        
1977        if(inheritanceInfo.ifcInheritance != null){
1978          ret += GenerateClass.genIndent(indent) + "  /**J2C: Mtbl-interfaces of " + sClassName + ": */";
1979          //Set<Map.Entry<String,ClassData.InheritanceInfo>> entrySet = inheritanceInfo.ifcInheritance.entrySet();
1980          for(InheritanceInfo ifcData : inheritanceInfo.ifcInheritance){
1981          //for(Map.Entry<String,ClassData.InheritanceInfo> entry : entrySet){
1982            //ClassData.InheritanceInfo ifcData = entry.getValue();
1983            ret += genMethodTableContent(ifcData, sClassName, indent+1);
1984          }
1985        }
1986        
1987        ret += GenerateClass.genIndent(indent) + "}";
1988        return ret;
1989      }    
1990      
1991      
1992      
1993      String xxxwrite_OwnOverrideableMethods()
1994      { String sClassIdentName = getClassIdentName();
1995        String ret = "\n\n/* J2C:ClassData.write_OwnOverrideableMethods()" 
1996                   + "\n * This method may be called in C, it implements the dynamic call. \n*/\n";
1997        for(MethodOverrideable method1: inheritanceInfo.methodTable){
1998          Method method = method1.method;
1999          ret += method.sReturnTypeDefinition + " " + method.sCName + method.sMethodFormalListDefiniton;
2000          if(method.firstDeclaringClass.isInterface()){
2001            ret += "\n{ Mtbl_" + sClassIdentName + " const* mtbl = (Mtbl_" + sClassIdentName 
2002              + " const*)getMtbl_ObjectJc(ithis, sign_Mtbl_" + sClassIdentName + ");";
2003          } else {
2004            ret += "\n{ Mtbl_" + sClassIdentName + " const* mtbl = (Mtbl_" + sClassIdentName 
2005              + " const*)getMtbl_ObjectJc(&ythis->base.object, sign_Mtbl_" + sClassIdentName + ");";
2006          }
2007          //ret += "\n  ASSERT(mtbl != null && mtbl->head.sign == sign_Mtbl_" + sClassIdentName +  ");";
2008          if(method.returnType != null && method.returnType != CRuntimeJavalikeClassData.clazz_void.classTypeInfo){
2009            ret += "\n  return ";
2010          } else {
2011            ret += "\n  ";
2012          }
2013          ret += "mtbl->" + method.sNameUnambiguous + "(";
2014          if(method.firstDeclaringClass.isInterface()){
2015            ret += "ithis"; //it is of type ObjectJc* and declared in sMethodFormalListDefiniton
2016          } else {
2017            /**Method is not defined first in an interface, but in an super class. */
2018            ret += "(" + method.firstDeclaringClass.sClassNameC + "*)ythis";
2019          }
2020          if(method.paramsType != null) for(FieldData param: method.paramsType){
2021            ret += ", " + param.getName();
2022          }
2023          if(method.need_thCxt){ ret += ", _thCxt"; }
2024          ret += ");";
2025          ret += "\n}\n";
2026        }
2027        return ret;
2028      }
2029      
2030      
2031      
2032      
2033      /**Fills the {@link #methodsCheckOverriding} with the informations given in {@link #inheritanceInfo}.
2034       * This routine is called only after {@link #inheritanceInfo} is initalized in the constructor of this.
2035       * <img src="../../../../Java2C/img/InheritanceInfo_omdJava2C.png" />
2036       * In the picture ...TODO
2037       * @param inheritanceInfo of the adequate level, this routine is called recursively for all supers and interfaces.
2038       */
2039      private void fillMethodsOverrideable(ClassData.InheritanceInfo inheritanceInfo, String sPathToMtbl, String sPathToBase)
2040      { assert(inheritanceInfo != null);
2041        if(sClassNameJava.equals("ImplIfc"))
2042          stop();
2043        if(inheritanceInfo.superInheritance != null){
2044          /**Superclass - recursively. */
2045          ClassData.InheritanceInfo superInfo = inheritanceInfo.superInheritance;
2046          String sPathToMtblSuper = sPathToMtbl + superInfo.classData.getClassIdentName() + "."; 
2047          String superName = superInfo.classData.getClassIdentName();
2048          if(superName.equals("ObjectJc")){
2049            superName = "object";
2050          } else {
2051            superName = "super";
2052          }
2053          String sPathToBaseSuper = sPathToBase + ".base." + superName; 
2054          /**Adds the cast and fills the methods related to this class. Don't use the derived classes. */
2055          addCastToType(superInfo.classData, "(?)" + sPathToBaseSuper, "$$");  //NOTE: ? expected as embedded instance, because .base
2056          fillMethodsOverrideable(superInfo, sPathToMtblSuper, sPathToBaseSuper);
2057        }
2058        
2059        if(inheritanceInfo.ifcInheritance != null){
2060          /**Interfaces: */
2061          //Set<Map.Entry<String,ClassData.InheritanceInfo>> entrySet = inheritanceInfo.ifcInheritance.entrySet();
2062          for(InheritanceInfo ifcData : inheritanceInfo.ifcInheritance){
2063          //for(Map.Entry<String,ClassData.InheritanceInfo> entry : entrySet){
2064            //ClassData.InheritanceInfo ifcData = entry.getValue();
2065            String sPathToMtblIfc = sPathToMtbl + ifcData.classData.getClassIdentName() + "."; 
2066            String sPathToBaseIfc = sPathToBase + ".base." + ifcData.classData.getClassIdentName(); 
2067            /**Adds the cast and fills the methods related to this class. Don't use the interface classes. */
2068            addCastToType(ifcData.classData, "(?)." + sPathToBaseIfc.substring(1), "$$");
2069            fillMethodsOverrideable(ifcData, sPathToMtblIfc, sPathToBaseIfc);
2070          }
2071        }
2072    
2073        if(inheritanceInfo.methodTable != null){
2074          /**Captures the methods of this inheritance level and adds it to {@link #methodsCheckOverriding}
2075           * of this-ClassData (left yellow class in description picture). */
2076          for(int ix=0; ix<inheritanceInfo.methodTable.length; ix++)
2077          { /**Steps through the methodTable of the inheritance level: */
2078            MethodOverrideable src = inheritanceInfo.methodTable[ix];
2079            /**Gets from the original Method instance: */
2080            String sNameUnambiguous = src.method.sNameUnambiguous;
2081            String sNameJava = src.method.sJavaName;
2082            if(sNameJava.equals("processIfcMethod"))
2083              stop();
2084            /**Check whether the method is existing in the class with other signature, 
2085             * sets the ambigous of a searched instance with key <code>sNameJava+"?"</code>,
2086             * It is important for ambigous of another method of class with same Java name.: */
2087            testAndSetAmbiguousnessOfMethod(sNameJava);  //to detect whether a method with equal name is defined here additionally
2088            /**Check whether the method is registered as override-able of this ClassData, 
2089             * it is if the method was found in another base class already: */
2090            MethodOverrideCheck methodOverideable = searchOverrideableMethod(sNameJava, src.method.paramsType);
2091            if(methodOverideable == null){
2092              /**If not found yet, create. */
2093              methodOverideable = new MethodOverrideCheck(src.method, sPathToMtbl, sPathToBase);
2094              /**The method is not registered yet, register it. */
2095              Object oMethodOverideable = methodsCheckOverriding.get(sNameJava);
2096              if(oMethodOverideable != null){
2097                if(oMethodOverideable instanceof List<?>){
2098                  @SuppressWarnings("unchecked")
2099                    List<MethodOverrideCheck> listMethodOverrideable = ((List<MethodOverrideCheck>)oMethodOverideable); 
2100                    listMethodOverrideable.add(methodOverideable);
2101                } else {
2102                  /**No List, than only one method is registered, instance of MethodOverrideCheck.
2103                   * Build a list with now 2 methods.
2104                   */
2105                  MethodOverrideCheck firstmethod = (MethodOverrideCheck)oMethodOverideable;
2106                  List<MethodOverrideCheck> listmethods = new LinkedList<MethodOverrideCheck>();
2107                  listmethods.add(firstmethod);
2108                  listmethods.add(methodOverideable);
2109                  methodsCheckOverriding.put(sNameJava, listmethods); //exchange with a list.
2110                }
2111              }
2112              else {
2113                methodsCheckOverriding.put(sNameJava, methodOverideable);
2114              }  
2115            }
2116            /**Adds an occurrence to the override-able method. This is the finite action of this part of routine. 
2117             * If an implementation is found in the class later, all that occurrences are handled.*/
2118            methodOverideable.listOccurence.add(new MethodOverrideCheck.MethodIndex(inheritanceInfo.methodTable, ix));
2119          }
2120        }
2121    
2122      }    
2123      
2124     
2125      /**copies the new override-able methods of this class in the inheritance info.
2126       * The methods were captured in {@link #methodsOverrideableNew}. It will be written
2127       * to {@link #inheritanceInfo}.{@link InheritanceInfo#methodTable}.
2128       * The order of the given is important for method table Mtbl in C
2129       * <br>
2130       * The {@link #methodsOverrideableNew} and the {@link #methodsCheckOverriding} were cleared
2131       * (set to null) because its content isn't necessary for translation the other classes.  
2132       */
2133      public void completeInheritanceWithOwnMethods()
2134      { if(methodsOverrideableNew != null){
2135          int zMethods = methodsOverrideableNew.size();
2136          if(inheritanceInfo == null){
2137            inheritanceInfo = new InheritanceInfo(this, null, null);
2138          }
2139          assert(inheritanceInfo.methodTable == null);  
2140          inheritanceInfo.methodTable = new MethodOverrideable[zMethods];
2141          int ix= 0;
2142          for(MethodOverrideable entry: methodsOverrideableNew){
2143            inheritanceInfo.methodTable[ix++] = entry;
2144          }
2145          methodsOverrideableNew = null; //delete it, it isn't necessary furthermore.
2146          methodsCheckOverriding = null; //it isn't also necessary furthermore.
2147        }  
2148      }
2149      
2150      
2151      
2152      /**copies the override-able methods given in param  in the inheritance info.
2153       * It will be written
2154       * to {@link #inheritanceInfo}.{@link InheritanceInfo#methodTable}.
2155       * <br>
2156       * The {@link #methodsOverrideableNew} and the {@link #methodsCheckOverriding} were cleared
2157       * (set to null) because its content isn't necessary for translation the other classes.  
2158       * @param methodNames List of names with that methods, which are to write in the Inheritanceinfo.
2159       *   The order is important for method table Mtbl in C
2160       */
2161      public void completeInheritanceWithListMethods(List<String> methodNames)
2162      { int zMethods = methodNames.size();
2163        if(inheritanceInfo == null){
2164          inheritanceInfo = new InheritanceInfo(this, null, null);
2165        }
2166        assert(inheritanceInfo.methodTable == null);  
2167        inheritanceInfo.methodTable = new MethodOverrideable[zMethods];
2168        int ix= 0;
2169        for(String name: methodNames){
2170          Method method = getMethodPerCname(name);
2171          if(method == null){
2172            throw new IllegalArgumentException("Error: methods-overrideable-entry in " + getClassCtype_s() + ".stc fault: " + name);
2173          }
2174          MethodOverrideable methodOverrideable = new MethodOverrideable(method, method.sImplementationName);
2175          inheritanceInfo.methodTable[ix++] = methodOverrideable;
2176        }
2177        methodsOverrideableNew = null; //delete it, it isn't necessary furthermore.
2178        methodsCheckOverriding = null; //it isn't also necessary furthermore.
2179      }
2180      
2181      
2182      
2183      /**returns the definition of the method-table of a superclass or interface as embedded struct.
2184       */
2185      private String gen_MethodTableSuperStruct()
2186      { String ret = "";
2187        if(inheritanceInfo != null) // && classDataP.inheritanceInfo.methodTable != null)
2188        { String sClassNameC = getClassIdentName();
2189          ret += "\n  Mtbl_" + sClassNameC + " mtbl" + sClassNameC + ";  //methods from "  + sClassNameC;
2190        }
2191        return ret;
2192      }    
2193      
2194      
2195      
2196      
2197      
2198      /**Helpfull for debugging in eclipse. The infos from Object.toString() is given too.
2199       * @see java.lang.Object#toString()
2200       */
2201      public String toString()
2202      { String sObject = super.toString();
2203        int posAt = sObject.indexOf('@');
2204        return sClassNameJavaFullqualified + "=" + sClassNameC + ": ClassData" + sObject.substring(posAt); 
2205      }
2206      
2207      
2208      
2209      /* (non-Javadoc)
2210       * @see org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile#getLocalIdents()
2211       */
2212      public LocalIdents getLocalIdents(String sClassName)
2213      { return classLevelIdents;
2214      }
2215    
2216    
2217    
2218      /**Implements {@link JavaSources.ClassDataOrJavaSrcFile#getJavaPkg()}
2219       */
2220      public JavaSrcTreePkg getJavaPkg()
2221      {
2222        return null; // it isn't a JavaSrcTreePkg
2223      }
2224    
2225    
2226    
2227      /**Implements {@link JavaSources.ClassDataOrJavaSrcFile#getTypeName()}
2228       */
2229      public String getTypeName()
2230      {
2231        return sClassNameJava;
2232      }
2233    
2234    
2235    
2236            /**This method returns null because for ready-to-use types this informations are not necessary.
2237             * @see org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile#getReplaceCinfo()
2238             */
2239            @Override
2240            public org.vishia.java2C.ConfigSrcPathPkg_ifc.Set getReplaceCinfo() {
2241                    //It isn't necessary here.
2242                    return null;
2243            }
2244    
2245    
2246    
2247            /**Returns false any time, because all informations are ready to use here.
2248             * @see org.vishia.java2C.JavaSources.ClassDataOrJavaSrcFile#isToTranslate()
2249             */
2250            @Override
2251            public boolean isToTranslate() {
2252                    return false;
2253            }
2254    
2255    
2256    
2257            /**Writes the structure data of the class in file.stc.
2258             * @param out destination
2259             * @param recursion nesting level
2260             * @throws IOException
2261             */
2262            public void writeStructureClass(final BufferedWriter out, final int recursion) 
2263            throws IOException
2264            { if(sClassNameJava.equals("TestWaitNotify"))
2265                      stop();
2266                    out.append(indent(recursion));
2267              if(bExternal){ out.append("extern "); }
2268              if(isFinal){ out.append("final "); }
2269              if(bEmbedded){ out.append("embedded "); }
2270              if(isAbstract){ out.append("abstract "); }
2271            if(isNonStaticInner){ out.append("nonStaticInner "); }  //only inner classes may be static
2272              if("PFC".indexOf(creationMode) <0){
2273                    //an anonymous class or class at statement block level:
2274                    switch(creationMode){
2275                    case 'Y': out.append("anonymous "); break;
2276                    default: out.append("statementBlock:").append(creationMode).append(' ');
2277                    }
2278                    }
2279              
2280              out.append(bInterface ? "interface " : "class "); 
2281              out.append(sClassNameJava + "; nameC="+ sClassNameC + "; argIdent=" + sArgSensitiveName + ";");
2282              if(inheritanceInfo != null) {
2283                if(inheritanceInfo.superInheritance != null){
2284                  ClassData superClass = inheritanceInfo.superInheritance.classData;
2285                  out.append(" extends " + superClass.sClassNameJavaFullqualified);
2286                }
2287                if(inheritanceInfo.ifcInheritance != null){
2288                  String sSeparator = " implements ";
2289                  //Set<Entry<String, InheritanceInfo>> entrySet = inheritanceInfo.ifcInheritance.entrySet();
2290                  for(InheritanceInfo ifcInheritance : inheritanceInfo.ifcInheritance) {
2291                  //for(Entry<String, InheritanceInfo> entry : entrySet) {
2292                    ClassData ifcClass = ifcInheritance.classData;
2293                    //ClassData ifcClass = entry.getValue().classData;
2294                    out.append(sSeparator + ifcClass.sClassNameJavaFullqualified);
2295                    sSeparator = ", ";
2296                  }
2297                }
2298              }
2299              out.append(" //creationMode=").append(creationMode);
2300              out.append(indent(recursion) + "{  ");
2301              Set<Map.Entry<String, JavaSources.ClassDataOrJavaSrcFile>> typeSet = classLevelIdents.getTypeSet();
2302              if(typeSet.size() >0)
2303              { //out.append(indent(recursion+1) + "InnerClassList" + "{ ");
2304                for(Map.Entry<String, JavaSources.ClassDataOrJavaSrcFile> innerClassEntry: typeSet)
2305                { JavaSources.ClassDataOrJavaSrcFile innerClass = innerClassEntry.getValue();
2306                  String sName = innerClass.getClassData().getClassIdentName();
2307                  out.append(indent(recursion+2)).append("//Innerclass: ").append(sName);
2308                    }
2309              }  
2310              if(innerClasses !=null){
2311                    out.append(indent(recursion+1) + "InnerClass" + "{ ");
2312                for(ClassData innerClassdata: innerClasses){
2313                  innerClassdata.writeStructureClass(out, recursion+2);
2314                      } 
2315                out.append(indent(recursion+1)).append("}");
2316                    }
2317              if(classLevelIdents.fieldIdents != null)
2318              { out.append(indent(recursion)).append("fieldIdents {");
2319                Set<Entry<String,FieldData>> listEntries = classLevelIdents.fieldIdents.entrySet();
2320                for(Entry<String,FieldData> field: listEntries)
2321                { //String sName = field.getKey();
2322                  FieldData identInfos = field.getValue();
2323                  if(identInfos.getName().equals("fixArray"))
2324                    stop();
2325                  out.append( indent(recursion+1));
2326                  if(identInfos.nClassLevel != 1 || identInfos.nOuterLevel != 1){
2327                    out.append("//outer=" + identInfos.nOuterLevel);
2328                    out.append(" ,super=" + identInfos.nClassLevel);
2329                    out.append(": ");
2330                        }
2331                  out.append(identInfos.writeStruct()).append(";");
2332                  
2333                }
2334                out.append(indent(recursion)).append("}");
2335              }  
2336              
2337              if(methods != null)
2338              { out.append(indent(recursion+1)).append("methods {  ");
2339                Set<Map.Entry<String,Object>> listEntries = methods.entrySet();
2340                for(Map.Entry<String,Object> field: listEntries)
2341                { String sKey = field.getKey();
2342                  Object methodEntry = field.getValue();
2343                  if(methodEntry instanceof Method)
2344                  { Method method2 = (Method)(methodEntry);
2345                    if(method2.sCName != null)
2346                    { //out.append( indent(recursion+2)).append("method;").append(sKey).append(";").append(method2.writeStruct() + "\n");
2347                      out.append( indent(recursion+2)).append(method2.writeStruct());
2348                    }
2349                  }
2350                  else //it is a list, otherwise ClassCastException!
2351                  { @SuppressWarnings("unchecked")
2352                    List<Method> listMethod1 = (List<Method>)methodEntry;
2353                    for(Method method: listMethod1)
2354                    { if(method.sCName != null)
2355                      { //out.append( indent(recursion+2) + "method;" + sKey + ";" + method.writeStruct());
2356                        out.append( indent(recursion+2)).append( method.writeStruct());
2357                      }
2358                    }  
2359                  }
2360                }
2361                out.append(indent(recursion+1) +  "}\n" );
2362              }
2363              
2364              if(inheritanceInfo != null && inheritanceInfo.methodTable != null){
2365                out.append(indent(recursion+1) + "methods-overrideable {");
2366                for(MethodOverrideable methodOverrideable: inheritanceInfo.methodTable){
2367                  out.append( indent(recursion+2) + methodOverrideable.method.sCName + ";");
2368                }
2369                out.append(indent(recursion+1) +  "}\n" );
2370              }
2371              
2372              if(castableToType != null){
2373                    out.append(indent(recursion+1) + "castTo {");
2374                for( Map.Entry<String, CastInfo>entry: castableToType.entrySet()){
2375                    CastInfo castInfo = entry.getValue();
2376                    out.append( indent(recursion+2))
2377                            .append(castInfo.castType.sClassNameJavaFullqualified).append(": ")
2378                            .append(castInfo.modeAccessDst)
2379                            .append(" \"").append(castInfo.pre + "?").append(castInfo.post + "\" ")
2380                            .append(castInfo.modeAccessSrc)
2381                            .append(";");
2382                    }
2383                out.append(indent(recursion+1) +  "}\n" );
2384              }
2385              if(castableFromType != null){
2386                    out.append(indent(recursion+1) + "castFrom {");
2387                for( Map.Entry<String, CastInfo>entry: castableFromType.entrySet()){
2388                    CastInfo castInfo = entry.getValue();
2389                    out.append( indent(recursion+2))
2390                            .append(castInfo.castType.sClassNameJavaFullqualified).append(": ")
2391                            .append(castInfo.modeAccessSrc)
2392                            .append(" \"").append(castInfo.pre + "?").append(castInfo.post + "\" ")
2393                            .append(castInfo.modeAccessDst)
2394                            .append(";");
2395            
2396                    }
2397                out.append(indent(recursion+1) +  "}\n" );
2398              }
2399              
2400              
2401              
2402              
2403              /*
2404              Set<Map.Entry<String,Object>> listUsedEnhancedRefTypes = usedEnhancedRefTypes.entrySet();
2405              if(listUsedEnhancedRefTypes.size() >0)
2406              { out.append(indent(recursion+1) +  "usedEnhancedRefTypes{\n" );
2407                for(Map.Entry<String,Object> usedType: listUsedEnhancedRefTypes)
2408                {
2409                  out.append(indent(recursion+2) + usedType.getKey() + ";\n" );
2410                }
2411                out.append(indent(recursion+1) +  "}\n" );
2412              }
2413              */
2414              out.append(indent(recursion) + "}\n");
2415            }
2416    
2417      @Override public void setClassData(ClassData data){
2418            throw new IllegalArgumentException("internal: ClassData twice");
2419      }
2420    
2421            /**Helper method for debugging. */
2422            private void stop(){}
2423      
2424      
2425    }