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 }