001    package org.vishia.java2C;
002    
003    import java.io.FileNotFoundException;
004    import java.io.IOException;
005    import java.text.ParseException;
006    import java.util.Map;
007    import java.util.Set;
008    import java.util.TreeMap;
009    import java.util.Map.Entry;
010    
011    import org.vishia.java2C.ClassData.MethodWithZbnfItem;
012    import org.vishia.mainCmd.Report;
013    
014    
015    /**This class contains all identifiers visible at class level or visible at a local position of code.
016     * It means, visible at class level by generating the class members,
017     * visible at level of a block statement including stack variable etc.
018     * @author JcHartmut
019     * {@link FieldData#typeClazz}
020     *
021     */
022    public class LocalIdents
023    {
024      
025      /**List of known fields of this context. */
026      final TreeMap<String, FieldData> fieldIdents;
027    
028      /**List of known types of this context. */
029      //private final TreeMap<String, FieldData> typeIdents;
030      private final TreeMap<String, JavaSources.ClassDataOrJavaSrcFile> typeIdents;
031    
032      /**The parent idents. They contained the visible types of super levels, 
033       * for example the class types, if this is a LocalIdents of a statement block.*/
034      private final LocalIdents parent;
035      
036      /**Only for toString in debugging/reporting. */
037      private final String debugPath;
038      
039      /**Access to the package level idents. TODO: don't use for normal search from outside,
040       * it should not stored here, but it should given in an extra parameter calling {@link #getTypeInfo(String, LocalIdents)}!
041       * 
042       */
043      //private final LocalIdents fileLevelIdents;
044      
045      /**The ClassData for which is this member of, or null if it isn't classLevelIdents of {@link ClassData}. } */
046      private final ClassData declaringClassData;
047      
048      /**constructs a new empty instance. 
049      public LocalIdents()
050      { this(Java2C_Main.singleton.userTypes);
051      }
052     */ 
053      
054      
055      /**constructs a new instance copying all parent identifier. 
056       * This method is called especially if the identifier infos of a class is built.
057       * @param parent The identifier infos of the parent scope are copied,
058       *               the parent scope is not touched (changed). This parameter should be <code>null</code>
059       *               while the LocalIdents of a non-inner class is created because there aren't
060       *               any identifiers to copy outside of a top-level class. 
061       *               It should be given, if the LocalIdents of a method or statement blocks 
062       *               or of an inner class is created.
063       * @param declaringClassData All identifier infos of all super and outer classes
064       *               of this class are copied. This parameter should be <code>null</code>
065       *               while the LocalIdents of methods or statement blocks are created.
066       * @param fileLevelIdents LocalIdents of the package.              
067       */
068      public LocalIdents(LocalIdents parent, ClassData declaringClassData, boolean hasFields, String sPkgName)
069      { if(hasFields){
070          fieldIdents = new TreeMap<String, FieldData>();
071          if(parent != null && parent.fieldIdents != null) { fieldIdents.putAll(parent.fieldIdents); }
072        } else {
073          fieldIdents = null;
074          //a given parent should not have fieldIdents too!
075          assert(parent == null || parent.fieldIdents == null || parent.fieldIdents.size()==0);
076        }
077        typeIdents = new TreeMap<String, JavaSources.ClassDataOrJavaSrcFile>();
078        if(parent!=null){
079          /**copy types to locally localIdents or from outer to inner class.
080           * don't copy the fileLevelIdents! They are given extra on search.
081           */
082            typeIdents.putAll(parent.typeIdents);
083        }
084        this.parent = parent;
085        //this.fileLevelIdents = fileLevelIdents != null ? fileLevelIdents 
086        //                 : parent != null ? parent.fileLevelIdents
087        //                   : null;
088        this.declaringClassData = declaringClassData; //maybe null
089        if(declaringClassData != null)
090        {
091            assert(sPkgName == null || sPkgName.length() ==0);
092              debugPath = declaringClassData.sClassNameJavaFullqualified;
093          if(declaringClassData.sClassNameJava.equals("Object"))
094            stop();
095          ClassData superClass = declaringClassData.getSuperClassData();
096          //int superLevel = 1;
097          if( superClass != null){ //fields from the super-class, it contains super-super too.
098            if(!superClass.sClassNameJava.equals("Object"))
099              stop();
100            Set<Entry<String,FieldData>> entrySet = superClass.classLevelIdents.fieldIdents.entrySet();
101            for(Entry<String,FieldData> entry: entrySet)
102            { FieldData field = entry.getValue();
103              FieldData superField = new FieldData(field, 1, 0, '.', '.');
104              String sName = superField.getName();
105              if(sName.equals("x1") && field.nClassLevel == 2)
106                    stop();
107              fieldIdents.put(sName, superField);
108            }
109            //superClass = superClass.getSuperClassData();
110            //superLevel +=1;
111          }
112        } else {
113            if(parent == null){
114                    debugPath = sPkgName;   //the given name from outside.
115            } else {
116                    assert(sPkgName == null || sPkgName.length() ==0);
117              debugPath = parent.debugPath + "{";
118            }  
119        }
120      }
121    
122      
123      /**constructs a new instance with copy all parent identifier as base. 
124       * This constructor is called especially if the identifier infos
125       * of a local scope (method, statement block) are built. 
126       * @param parent The identifier infos of the parent scope is copied,
127       *               but the parent scope should be not touched (changed).
128       */
129      public LocalIdents(LocalIdents parent, String sPkgName)
130      { this(parent, null, true, sPkgName);
131        
132      }
133      
134    
135      /**constructs a new Instance for primary types. Field Identifier are not planned. 
136       */
137      public LocalIdents(String sPkgName)
138      { this(null, null, false, sPkgName);
139      }
140      
141    
142      /**constructs a new instance for a class level. 
143       * All identifiers of outer and super classes of the declaring class are copied too. They are visible
144       * as super identifiers or outer identifiers.
145       * @param declaringClass The class where the LocalIdents are assigned to.
146       * @param fileLevelIdents The LocalIdents of the package containing all package visible and commonly types.
147       */
148      public LocalIdents(ClassData declaringClass)
149      { this(null, declaringClass, true, null);  //ignore the fileLevelIdents, given extra on search.
150      }
151      
152      
153      
154      
155      
156      
157      /**searches the infos to the given identifier.
158       * 
159       * @param sIdent The identifier.
160       * @return null if not found. 
161       */
162      public FieldData get(String sIdent)
163      { return fieldIdents.get(sIdent);
164      }
165      
166      /**searches the ClassData to the given type identifier.
167       * If the type is found as a {@link JavaSrcTreeFile}, which isn't translated, its first pass is run now.
168       * The first pass translates the file either, or it reads its structure (stc-)file.
169       * <br><br>
170       * If the type isn't found, neither as {@link JavaSrcTreeFile} nor as {@link ClassData}, 
171       * this method returns <code>null</code>.
172       * It may be possible that the type should be exists as a <i>unknown<i> type, than it is created, outside of this routine
173       * see {@link GenerateClass#getType(org.vishia.zbnf.ZbnfParseResultItem, LocalIdents)}. 
174       * It may be possible too, that the identifier may be either a type
175       * or an association. If it isn't found as type, it may be found as association. Therefore this routine
176       * have to be returned <code>null</code> at unknown identifiers.
177       * 
178       * @param sIdent The identifier.
179       * @return null if the identifier is not found, elsewhere the found instance.
180       * @throws IllegalArgumentException if any problem while running first pass occurs. 
181       */
182      public ClassData getType(final String sIdent, LocalIdents fileLevelIdents)
183      throws ParseException
184      { //Search the type-info in the local idents, then in the fileLevelIdents, then in the stdTypes.
185        //They may have ClassData or not.
186            final JavaSources.ClassDataOrJavaSrcFile infos = getTypeInfo(sIdent, fileLevelIdents);
187        if(infos == null) return null;
188        else
189        { ClassData retClassData = infos.getClassData();
190          if(retClassData == null){
191            JavaSrcTreeFile javaFile = infos.getJavaSrc();
192            if(infos.isToTranslate() && javaFile == null) 
193              throw new IllegalArgumentException("no javaSrc available for. " + sIdent);
194            else if(javaFile == null){
195                    retClassData = null;  //admissible if it should be checked whether it is a reference.
196            } 
197            else {
198                    try
199                    { /**If a identifier is found, but it has not ClassData, it is a non-translated file.
200                       * Than run the first pass to get the ClassData. It may be that a stc-file is read.
201                       */
202                      retClassData = Java2C_Main.singleton.runRequestedFirstPass(javaFile, sIdent);
203                            if(sIdent.equals("org/vishia/msgDispatch/LogMessage"))
204                                    stop();
205                    } 
206                    catch (FileNotFoundException e){ throw new IllegalArgumentException("file not found: " + javaFile.toString()); }
207                    catch (IOException e){ throw new IllegalArgumentException("file error: " + javaFile.toString()); }
208                    //catch (ParseException e)
209                    //{ //e.printStackTrace();
210                      //throw new IllegalArgumentException("parse exception: " + e.getMessage() + " in "+ javaFile.toString()); 
211                    //}
212                    catch (InstantiationException e){ throw new IllegalArgumentException("instanciation exception: " + javaFile.toString()); }
213                    catch (IllegalAccessException e){ throw new IllegalArgumentException("illegal access: " + javaFile.toString()); }
214                    //catch (IllegalArgumentException e){ throw new IllegalArgumentException("file not found: " + javaFile.toString()); }
215            }
216          }
217          return retClassData;
218        }
219      }
220      
221      /**searches the infos to the given type identifier. A translation process isn't activated from here,
222       * see {@link #getType(String, LocalIdents)}.
223       * <br><br>
224       * The identifier respectively the first package is searched in this LocalIdents and all its parents
225       * firstly. That are local visible idents. The parent of this are the outer blocks of statement,
226       * the class and the outer classes. and super classes.
227       * <br><br>
228       * If the type isn't found there, it is searched in the given fileLevelIdents. The fileLevelIdents
229       * are the idents of the package, where the to-translate-class is member of 
230       * (not the declaring class of this!). The fileLevelIdents contains the types too, which are given 
231       * with the import-statements of the to-translate-class.
232       * <br><br>
233       * If the type isn't found neither in the local context nor in the fileLevelIdents, 
234       * they are searched as top-level-package. Consider, that this routine is called recursively
235       * to dissolve a given package path. Therefore the top-level package should be found. If a local
236       * package exists with the same name like a top level, it is found first and used therefore.
237       * <br><br>
238       * If the identifier isn't found, than it is searched in the global visible types. That are
239       * the standard types like <code>int</code> etc. and the <code>java.lang</code>.Types. 
240       * It are referred by {@link CRuntimeJavalikeClassData#stdTypes}.
241       * <br><br>
242       * At least the type is searched in {@link Java2C_Main#externalTypes}.  
243       * <br><br> 
244       * It may be possible in the users Java-code, that the identifier may be either a type
245       * or an association. That isn't able to different by the syntax, because both cases
246       * are written as "Type.element" or "association.element". The usual distinction using an upper case
247       * letter to start for types can't be us for a decision really. Therefore this routine 
248       * returns <code>null</code> at unknown identifiers.
249       * An exception or error message mustn't create here.
250       * 
251       * 
252       * 
253       * @param sIdent The identifier. It is possible it is a package path, 
254       *               at example <code>java.lang.Object</code>. The separator between package idents
255       *               can be a slash or a dot.
256       * @param fileLevelIdents Contains all types which are known as environment for translation
257       *                        of this file. They are all package level types 
258       *                        and all types, which are known because import-statements. 
259       * @return null if not found. Than the type isn't known. If not null, than it may be an instance
260       *   of {@link ClassData} for simple types, or it is an instance of {@link JavaSrcTreeFile}.
261       *   If the file is translated already, calling {@link JavaSources.ClassDataOrJavaSrcFile#getClassData()}
262       *   supplies the ClassData, if it isn't translated yet but only known as Java-File, getClassData() returns <code>null</code>.
263       * @throws ParseException 
264       */
265      //public FieldData getType(String sIdent)
266      public JavaSources.ClassDataOrJavaSrcFile getTypeInfo(final String sIdentP, LocalIdents fileLevelIdents)
267      { 
268        String sIdent = sIdentP.replace('/','.');  //NOTE: if '/' isn't contain, the method is optimized.
269        int posDot;
270        if(sIdentP.contains("FieldJc"))
271            stop();
272        if(sIdentP.equals("org/vishia/msgDispatch/LogMessage"))
273            stop();
274        LocalIdents envIdents = this;
275        //JavaSources.ClassDataOrJavaSrcFile envInfosWithReplaceInfo = null;
276        /**Infos of the last package. */
277        ConfigSrcPathPkg_ifc.Set replaceCinfosPkg = null;
278        JavaSrcTreePkg lastPackage = null;
279        boolean hasPath = false;
280        while( (posDot = sIdent.indexOf('.')) >=0){
281            hasPath = true;
282            String sEnvIdent = sIdent.substring(0, posDot);
283          //recursively call of the same method!
284          JavaSources.ClassDataOrJavaSrcFile envInfos = envIdents.getTypeInfo(sEnvIdent, envIdents == this ? fileLevelIdents : null);
285          if(envInfos == null){
286            throw new IllegalArgumentException("ReadStructure: package not found: " + sEnvIdent + " for " + sIdent);        
287          }
288          else {
289            if(envInfos instanceof JavaSrcTreePkg){
290                    //mostly it is a package, because it is written before dot.
291              lastPackage = (JavaSrcTreePkg)envInfos;  
292            }
293            envIdents = envInfos.getLocalIdents(sEnvIdent);  //if it is a JavaSrcTreePackage, get the pkgIdents 
294            if(envIdents == null){
295                    throw new IllegalArgumentException("Class has no classlevelIdents: " + sEnvIdent + " for " + sIdent);        
296            }
297          }
298          sIdent = sIdent.substring(posDot+1);
299          replaceCinfosPkg = envInfos.getReplaceCinfo();
300        } //while envIdent.type
301        //The envIdent is the ident of the given environment or this.    
302        //Search from there.
303        JavaSources.ClassDataOrJavaSrcFile infos;
304        if(envIdents.declaringClassData !=null && envIdents.declaringClassData.sClassNameJava.equals(sIdent))
305        { infos = envIdents.declaringClassData;  //the own class is requested.
306        }
307        else
308        { infos = envIdents.typeIdents.get(sIdent);  //may be found at current level or not, then null.
309        }
310        //if infos == null, search in parent definitions, towards outer block statements, towards outer classes
311        while(infos == null && (envIdents = envIdents.parent) != null){
312            infos = envIdents.typeIdents.get(sIdent);
313        }
314        //if infos == null, it aren't found in the environment.
315        //Search in the fileLevelIdents. That are all idents of the package and imported classes and packages.
316        if(infos == null && !hasPath && fileLevelIdents != null){ // && envIdents == this && fileLevelIdents != null){
317          /**search in given fileLevelIdents only if no environment ident is given.
318           * At example if pkgX.class is given, the file level idents are used already to search pkgX.
319           */
320          infos = fileLevelIdents.typeIdents.get(sIdent);  
321        }
322        //if infos == null, it aren't found in the file level idents too.
323        //It may be the name of a root package like "java", "org" etc. 
324        //Consider that this routine is called recursively to dissolve a package path like "org.etc" 
325        if( infos == null && !hasPath){
326            infos = Java2C_Main.getRootPkg(sIdent); 
327        }
328        //if infos == null, it isn't a root package too.
329        //Search in the global visible idents. It is for simple types, and standard types.
330        if( infos == null && !hasPath){
331          //at last search in the standard types. Threre are simple types.
332            infos = CRuntimeJavalikeClassData.singleton.stdTypes.typeIdents.get(sIdent); 
333        }
334        //if infos == null, it isn't a root package too.
335        //Last not least search in external (unknwon) types.
336        if(infos == null && !hasPath){ // &&  envIdents != Java2C_Main.externalTypes){
337          infos = Java2C_Main.externalTypes.typeIdents.get(sIdent); 
338          if(infos !=null)
339            stop();
340        }
341        if(infos == null && replaceCinfosPkg != null){
342            //The identifier isn't found. 
343            //But there is a package-globally replacement information for the given package
344            // the file is registered now as file of the package.
345            infos = new JavaSrcTreeFile(lastPackage, null, null, sIdent, replaceCinfosPkg, null, false);
346        }
347        return infos;  //null if not found.  
348      }
349      
350      
351      /**puts a new class element (field, attribute, reference) in the container.
352       * 
353       * @param sIdent The textual representation of the identifier in java code context.
354       * @param sType The associated type string if it is a field or method. null if it is a type.
355       * @param typeClazz The associated type class
356       * @param sModifier Kind of the identifier. See table in the description of the class {@link ClassData}.
357       * @param clazz The associated class data
358       */
359      public void putClassElement
360      ( String sIdent, String sType, ClassData typeClazz, char staticMode
361      , char modeAccess
362      , String sModifier
363      , int dimensionArray
364      , String[] fixArraySizes
365      , char modeArrayElement
366      , ClassData clazz
367      )
368      { FieldData value = new FieldData(sIdent, typeClazz, null, null, null, staticMode, modeAccess, dimensionArray, fixArraySizes, modeArrayElement, clazz);
369        putClassElement(sIdent, value);  
370      }
371      
372      /**puts a new class element (field, attribute, reference) in the container.
373       * @param sIdent name
374       * @param identInfo all infos to the field
375       */
376      public void putClassElement(String sIdent, FieldData identInfo)
377      { identInfo.nClassLevel = 1;
378        identInfo.nOuterLevel = 1;
379        declaringClassData.addField(sIdent, identInfo); //added to this.fieldIdents via putElement, but does somewhat else. 
380        Java2C_Main.singleton.console.reportln(Report.debug, "Java2C-LocalIdents.putClassElement-1-1: class=" 
381            + this.declaringClassData.toString() + ", field=" + identInfo.toString());
382      }
383      
384      
385      
386      /**puts a new inner class as a Type of the class in the container.
387       * 
388       * @param sTypeIdent The textual representation of the identifier in java code context.
389       * @param sTypeNameC The type name in C, with outerclass__sTypeIdent.
390       * @param typeClazz The associated type class
391       * @param sModifier Kind of the identifier. See table in the description of the class {@link ClassData}.
392       * @param clazz The associated class data
393       * @deprecated use {@link #putClassType(String, ClassData)}
394       */
395      public void putClassType
396      ( String sTypeIdent
397      , String sTypeNameC
398      , ClassData typeClazz
399      , String sModifier
400      , ClassData clazz
401      )
402      { putClassType(sTypeIdent, typeClazz);
403      }
404      
405      
406      public void putClassType
407      ( String sTypeIdent
408      , JavaSources.ClassDataOrJavaSrcFile typeClazz
409      )
410      { //FieldData value = new FieldData(sTypeNameC, typeClazz, '.', sModifier, null, clazz);
411        //value.nClassLevel = 1;
412        //value.nOuterLevel = 1;
413        //typeIdents.put(sTypeIdent, value);
414        if(sTypeIdent.equals("SetValueGenerator"))
415          stop();
416        typeIdents.put(sTypeIdent, typeClazz);
417      }
418      
419      public void putClassType
420      ( ClassData typeClazz
421      )
422      { String sName = typeClazz.getClassNameJava();
423            JavaSources.ClassDataOrJavaSrcFile typeInfo = typeIdents.get(sName);
424            if(typeInfo !=null && typeInfo instanceof JavaSrcTreeFile){
425                    JavaSrcTreeFile javaSrc = (JavaSrcTreeFile)typeInfo;
426                    javaSrc.setClassData(typeClazz);
427            } else {
428              
429              typeIdents.put(sName, typeClazz);
430            }
431      }
432      
433      /**Puts the class into the typeIdents, with key with and without package.
434       * The class is able to found with its name only, but with its package too.
435       * @param typeClazz The class.
436       */
437      public void putClassTypeStandard( ClassData typeClazz)
438      { String sPkgClass = typeClazz.sPackage + typeClazz.sClassNameJava;
439        typeIdents.put(sPkgClass, typeClazz);
440        typeIdents.put(typeClazz.getClassNameJava(), typeClazz);
441      }
442      
443      
444      public void putClassTypesAll(LocalIdents parent)
445      {
446        for(Entry<String, JavaSources.ClassDataOrJavaSrcFile> entry: parent.typeIdents.entrySet()){
447          String key = entry.getKey();
448          JavaSources.ClassDataOrJavaSrcFile data = entry.getValue();
449          typeIdents.put(key, data);
450        }
451      }
452      
453      
454      /**puts a new stack-local element in the container.
455       * @param sIdent
456       * @param identInfo
457       */
458      public void putLocalElement(String sIdent, FieldData identInfo)
459      { identInfo.nClassLevel = 0;
460        identInfo.nOuterLevel = 0;
461        fieldIdents.put(sIdent, identInfo);
462      }
463      
464      /**puts a new stack-local element in the container.
465       * @param sIdent
466       * @param identInfo
467       */
468      void putElement(String sIdent, FieldData identInfo)
469      { fieldIdents.put(sIdent, identInfo);
470      }
471      
472      /**Test whether the field is known and returns it data.
473       * @param name The name of the field. The field can be local or in super scopes.
474       * @return null if the field isn't existing.
475       */
476      public FieldData getField(String name)
477      { return fieldIdents.get(name); 
478      }
479      
480            /**Adds all fields known here to the non-static inner classes
481             * and their methods.
482             * This routine is called for {@link ClassData#classLevelIdents}
483             * for all classes. 
484             * <br><br> 
485             * The fields were not be added before because the inner class was built first,
486             * after them the outer class was processed in first pass.
487             * But the non-static inner class should know all idents from the outer too.
488             */
489      void xxxcompleteFieldIdentsForInnerClasses()
490      {
491        for(Map.Entry<String,JavaSources.ClassDataOrJavaSrcFile> innerClass: typeIdents.entrySet()){
492            ClassData innerClassData = innerClass.getValue().getClassData();
493            if(innerClassData.isNonStaticInner) {
494                    copyFieldsTo(innerClassData);
495                    
496            }       
497        }
498      }
499      
500      
501      
502      
503      /**Copies all field idents from the current level (called for the outer class)
504       * to the named inner class and all methods bodies (its main statement block).
505       * That is necessary because all idents are known only at the end of the first pass of the
506       * outer class, but the first pass of the inner class is finished already, without knowledge
507       * of all outer idents. All idents should be known while running the second pass only.
508       * <br><br>
509       * The method {@link ClassData#completeFieldIdentsFromOuterClass(LocalIdents)} is called unlike
510       * if a class is generated in the second pass inside a block statement. In this case the 
511       * first pass of this class is running only in the second pass of the environment.
512       * <br><br>
513       * The situation of same identifier in the outer and inner class is detected in that
514       * complete-methods. The inner identifier covers the outer one.
515       * @param innerClassData
516       */
517      void copyFieldsTo(ClassData innerClassData){
518                    for(Map.Entry<String,FieldData> fieldEntry: fieldIdents.entrySet()){
519                            /**Get the field from the outer class. */
520                            String name = fieldEntry.getKey();
521                            if(innerClassData.getFieldIdent(name) == null){
522                                    //do it only if the field is not known in the inner class.
523                                    //It may be a local defined field in that scope which covers the outer!
524                                    FieldData fieldOuter = fieldEntry.getValue();
525                                    if(  innerClassData.isNonStaticInner 
526                                      || "sSd".indexOf(fieldOuter.modeStatic)>=0  //static variable are known anytime.
527                                      ){
528                                            //Build a FieldData with the correct outerLevel.
529                                    FieldData fieldInner = new FieldData(fieldOuter, 0, 1, '.', '.');
530                                            /**Add the field to the non-static inner class. 
531                                             * It was not be added before because the inner class was built first,
532                                             * after them the outer class was processed in first pass.
533                                             * But the non-static inner class should know all idents from the outer too.
534                                             */
535                                    innerClassData.addField(name, fieldInner);
536                                            //All methods of the inner class should be completed with the field too. 
537                                    // Note: The methods have only the head data until now, the body isn't translated.*/
538                                            for(MethodWithZbnfItem method: innerClassData.methodsWithZbnf){
539                                                    method.method.putFieldIdent(fieldInner);
540                                            }
541                                    }       
542                            }
543              }
544            }
545     
546    
547      void copyTypesTo(ClassData innerClass)
548      {
549            LocalIdents innerClassIdents = innerClass.classLevelIdents;
550            for(Map.Entry<String,JavaSources.ClassDataOrJavaSrcFile> typeEntry: typeIdents.entrySet()){
551            JavaSources.ClassDataOrJavaSrcFile type = typeEntry.getValue();
552            ClassData typeClass = type.getClassData();
553            assert(typeClass !=null);  //it is translated anytime.
554            if("PC".indexOf(typeClass.creationMode)>=0){ //regard knowledge of only non-anonymous  
555                    String name = typeEntry.getKey();       //and class level classes
556                    innerClassIdents.typeIdents.put(name, type);
557            }
558        }
559            innerClassIdents.typeIdents.put(declaringClassData.getClassNameJavaFullqualified(), declaringClassData);
560      }
561      
562      private final static String newLineIndent = "\n                                            ";
563      
564      String indent(int recursion){ return newLineIndent.substring(0, 2*recursion +1); } 
565      
566      
567      public String xxxwriteStructOwnClassFields(int recursion)
568      { String out = "";
569        /*
570        if(typeIdents != null)
571        { out += indent(recursion) + "typeIdents {  ";
572          Set<Entry<String,ClassData>> listEntries = typeIdents.entrySet();
573          for(Entry<String,ClassData> field: listEntries)
574          { //String sName = field.getKey();
575            ClassData identInfos = field.getValue();
576            out += indent(recursion+1) + "type;" + identInfos.getClassIdentName();
577          }
578          out += indent(recursion) + "}";
579        }
580        */  
581        return out;
582      }
583      
584      
585      /**Returns a String with all available type idents comma separated. 
586       * This String is usefull for help on error unknown type.
587       */
588      public String getAllTypeIdents()
589      {
590        String ret = "class-Level:";
591        for(String sKey: typeIdents.keySet()){
592          ret += " " + sKey;
593        }
594        //if(fileLevelIdents != null){
595        //  ret += "\nfile-level:";
596        //  for(String sKey: fileLevelIdents.typeIdents.keySet()){
597        //  ret += " " + sKey;
598        //} }
599        if(Java2C_Main.singleton.standardClassData.stdTypes != this){
600          ret += "\nlang-level:";
601          for(String sKey: Java2C_Main.singleton.standardClassData.stdTypes.typeIdents.keySet()){
602          ret += " " + sKey;
603        } }
604        return ret;
605      }
606      
607      
608      /**Returns an iterable list with all typeIdents.
609       */
610      public Set<Map.Entry<String,JavaSources.ClassDataOrJavaSrcFile>> getTypeSet()
611      { return typeIdents.entrySet();
612      }
613      
614      @Override public String toString(){ return debugPath; }
615      
616      /**It's a debug helper. The method is empty, but it is a mark to set a breakpoint. */
617      void stop(){}
618    }
619    
620    
621