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