001    /*BEGIN_COPYRIGHT_BLOCK
002     *
003     * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
004     * All rights reserved.
005     * 
006     * Redistribution and use in source and binary forms, with or without
007     * modification, are permitted provided that the following conditions are met:
008     *    * Redistributions of source code must retain the above copyright
009     *      notice, this list of conditions and the following disclaimer.
010     *    * Redistributions in binary form must reproduce the above copyright
011     *      notice, this list of conditions and the following disclaimer in the
012     *      documentation and/or other materials provided with the distribution.
013     *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014     *      names of its contributors may be used to endorse or promote products
015     *      derived from this software without specific prior written permission.
016     * 
017     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024     * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025     * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026     * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028     *
029     * This software is Open Source Initiative approved Open Source Software.
030     * Open Source Initative Approved is a trademark of the Open Source Initiative.
031     * 
032     * This file is part of DrJava.  Download the current version of this project
033     * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034     * 
035     * END_COPYRIGHT_BLOCK*/
036    
037    package edu.rice.cs.javalanglevels;
038    
039    import edu.rice.cs.javalanglevels.tree.*;
040    import edu.rice.cs.javalanglevels.parser.*;
041    import java.util.*;
042    import java.io.*;
043    import edu.rice.cs.plt.reflect.JavaVersion;
044    import edu.rice.cs.plt.iter.*;
045    
046    import junit.framework.TestCase;
047    
048    /** Top-level Language Level Visitor that represents the Intermediate Language Level.  Enforces constraints during the
049      * first walk of the AST (checking for langauge specific errors and building the symbol table).
050      * This class enforces things that are common to all contexts reachable at the Intermediate Language Level 
051      * (i.e., inside class bodies, method bodies, interface bodies, etc), but also enforces specific top level 
052      * constraints (i.e. you cannot have try catch statements at the top level, etc.)
053      */
054    public class IntermediateVisitor extends LanguageLevelVisitor {
055      
056      /* Inheriting the following fields:
057       * 
058       File _file;
059       String _package;
060       String _enclosingClassName;
061       LinkedList<String> _importedFiles;
062       LinkedList<String> _importedPackages;
063       HashMap<String, SymbolData> _generic types
064       *
065       */
066      
067      /** This constructor is called when creating a new instance of IntermediateVisitor.  The default value for className
068        * is the empty string.  The default value of _genericTypes (a field of LanguageLevelVisitor) is an empty HashMap.
069        */
070      public IntermediateVisitor(File file, 
071                                 String packageName,
072                                 String enclosingClassName,
073                                 LinkedList<String> importedFiles, 
074                                 LinkedList<String> importedPackages,
075                                 HashSet<String> classesInThisFile, 
076                                 Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>> continuations,
077                                 LinkedList<Command> fixUps) {
078        super(file, packageName, enclosingClassName, importedFiles, importedPackages, classesInThisFile, continuations, fixUps);
079      }
080    
081      /** This constructor is called when testing.  It initializes all of the static fields of LanguageLevelVisitor. */
082      public IntermediateVisitor(File file) {
083        this(file, 
084             new LinkedList<Pair<String, JExpressionIF>>(),
085             new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>(), 
086             new LinkedList<Command>(),
087             new LinkedList<Pair<LanguageLevelVisitor, SourceFile>>());
088      }
089      
090      /** This constructor is called from LanguageLevelVisitor and LanguageLevelConverter when they are instantiating a new
091        * IntermediateVisitor to visit a new file with.  _package is set to "" by default. _enclosingClassName is set to null
092        * @param file  The File corresponding to the source file we are visiting
093        * @param errors  The list of errors that have been encountered so far.
094        * @param continuations  The table of classes we have encountered but still need to resolve
095        * @param fixUps   This list of symbolTable fixups to perform after visitation
096        * @param visitedFiles  The list of files we have visited
097        */
098      public IntermediateVisitor(File file,
099                                 LinkedList<Pair<String, JExpressionIF>> errors,
100                                 Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>> continuations,
101                                 LinkedList<Command> fixUps,
102                                 LinkedList<Pair<LanguageLevelVisitor, SourceFile>> visitedFiles) {
103        this(file, new LinkedList<String>(), errors, continuations, fixUps, visitedFiles);
104      }
105      
106      /** This constructor is called from LanguageLevelVisitor and LanguageLevelConverter when they are instantiating a new
107        * IntermediateVisitor to visit a new file with.  _package is set to "" by default. _enclosingClassName is set to null
108        * @param file             The File corresponding to the source file we are visiting
109        * @param importedPackages The list of strings describing the imported packages for this file
110        * @param errors           The list of errors that have been encountered so far.
111        * @param continuations    The table of classes we have encountered but still need to resolve
112        * @param fixUps           This list of symbolTable fixups to perform after visitation
113        * @param visitedFiles     The list of files we have visited
114        */
115      public IntermediateVisitor(File file,
116                                 LinkedList<String> importedPackages,
117                                 LinkedList<Pair<String, JExpressionIF>> errors,
118                                 Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>> continuations,
119                                 LinkedList<Command> fixUps,
120                                 LinkedList<Pair<LanguageLevelVisitor, SourceFile>> visitedFiles) {
121        super(file, "", null, new LinkedList<String>(), importedPackages, new HashSet<String>(), continuations, fixUps);
122        this.errors = errors;
123        this.visitedFiles= visitedFiles;
124    //    _hierarchy = new Hashtable<String, TypeDefBase>(); //hierarchy;
125      }
126      
127      /** Factory method inherited from LLV class. */
128      public LanguageLevelVisitor newClassBodyVisitor(SymbolData anonSD, String anonName) {
129        return new ClassBodyFullJavaVisitor(anonSD, anonName, _file, _package, _importedFiles, _importedPackages, 
130                                            _classesInThisFile, continuations, fixUps);
131      }
132      
133      /** Check to make sure the inner class def is well-formed, resolve it, and store the resulting symbol in the outer 
134        * class's list of inner classes.  This method is used in InterfaceBodyIntermediateVisitor but needs the correct 
135        * Data so we pass it in.  This method is tested in those files.  We use the fully qualified name so that we 
136        * don't accidentally conflict with another class in the symbol table.
137        * @param that  AST Node for the inner class def
138        * @param enclosing  Data that encloses this inner class; the inner class can be in a class or a method.
139        * @param relName The relative name of the inner class including no qualifiers
140        * @param name  Fully qualified name of the inner class. For a local class, we construct the same name as the Java 
141        *   compiler, which inserts "$<seq#>" as the delimiter preceding the raw class name. For example, if class A
142        *   has a method B with a local class C, then qualified name for this class is "A$1C", provided the class is the
143        *   first local class (including anonymous classes) in the enclosing class.
144        */
145      // TODO: add a factory method for constructing the classbody visitor (so it is different for FullJava and Functional
146      // and hoist this code into LanguageLevelVisitor
147      protected void handleInnerClassDef(InnerClassDef that, Data enclosing, String relName, String name) {
148    //    System.err.println("Processing InnerClassDef for " + name + " defined in " + enclosing.getName());
149        
150        assert (enclosing instanceof SymbolData) || (enclosing instanceof MethodData);
151        forInnerClassDefDoFirst(that);
152        if (prune(that)) return;
153        
154        that.getMav().visit(this);
155        that.getName().visit(this);
156        
157        // TODO: type parameters are illegal in functional code.  Fix this!!!
158    //    for (int i = 0; i < that.getTypeParameters().length; i++) that.getTypeParameters()[i].visit(this);
159        
160        that.getSuperclass().visit(this);  // formerly commented out.  Why?
161        
162        for (int i = 0; i < that.getInterfaces().length; i++) that.getInterfaces()[i].visit(this);
163        
164        SymbolData sd = defineInnerSymbolData(that, relName, name, enclosing);
165        if (sd != null) { // We have a SymbolData to work with, so visit the body and augment
166          that.getBody().visit(new ClassBodyIntermediateVisitor(sd,
167                                                                sd.getName(),
168                                                                _file, 
169                                                                _package,
170                                                                _importedFiles, 
171                                                                _importedPackages, 
172                                                                _classesInThisFile, 
173                                                                continuations,
174                                                                fixUps));
175          
176          // The following methods are no-ops in FullJavaVisitor
177          createAccessors(sd, _file);
178          createToString(sd);
179          createHashCode(sd);
180          createEquals(sd);
181        }
182        // IMPORTANT: error message if sd is null?
183        // Inner classes are not entered in _classesInThisFile since they are parsed when their outer classes are parsed.
184        
185        forInnerClassDefOnly(that);
186      }
187      
188      /** Confirms that the inner interface is well-formed, resolves it, and stores it in the outer class's list of inner 
189        * classes.  This method is common to both ClassBodyIntermediateVisitor and InterfaceBodyIntermediateVisitor but 
190        * needs the correct SymbolData so we pass it in.  This method is tested in those files.
191        * @param that  AST Node for the inner class def
192        * @param enclosing  Data that encloses this inner class; the inner class can be in a class or a method.
193        * @param name  Fully qualified name of the inner class. For a local class, we construct the same name as the Java 
194        *   compiler (??), which inserts "$<seq#>" as the delimiter preceding the raw class name. For example, if class A
195        *   has a method B with a local class C, then qualified name for this class is "A$1C", provided the class is the
196        *   first local class (including anonymous classes) in the enclosing class.
197        */
198      // TODO: add a factory method for constructing the classbody visitor (so it is different for FullJava and Functional
199      // and hoist this code into LanguageLevelVisitor
200      protected void handleInnerInterfaceDef(InnerInterfaceDef that, Data enclosing, String relName, String name) {
201    //    System.err.println("Processing InnerInterfaceDef for " + name);
202        assert (enclosing instanceof SymbolData) || (enclosing instanceof MethodData);
203        forInnerInterfaceDefDoFirst(that);
204        if (prune(that)) return;
205        
206        that.getMav().visit(this);
207        that.getName().visit(this);
208            
209        // Type parameters are illegal in functional code.  TODO: Fix this!!!!
210    //    assert that.getTypeParameters().length == 0;
211    
212        for (int i = 0; i < that.getInterfaces().length; i++) that.getInterfaces()[i].visit(this);
213        
214        SymbolData sd = defineInnerSymbolData(that, relName, name, enclosing);
215        if (sd != null) { 
216          that.getBody().visit(new InterfaceBodyIntermediateVisitor(sd, 
217                                                                    _file, 
218                                                                    _package,
219                                                                    _importedFiles, 
220                                                                    _importedPackages,
221                                                                    _classesInThisFile, 
222                                                                    continuations,
223                                                                    fixUps));
224        }
225        
226        forInnerInterfaceDefOnly(that);
227      }
228      
229      /** Only abstract, public, private, protected, static and final are allowed in language levels.*/
230      public Void forModifiersAndVisibilityDoFirst(ModifiersAndVisibility that) {
231        String[] modifiersAndVisibility = that.getModifiers();
232        StringBuffer sb = new StringBuffer();
233        String temp;
234        int count = 0;    
235        for(int i = 0; i < modifiersAndVisibility.length; i++) {
236          temp = modifiersAndVisibility[i];
237          if (! temp.equals("final") && ! temp.equals("abstract") && ! temp.equals("public") && ! temp.equals("private") && 
238              ! temp.equals("protected") && ! temp.equals("static")) {
239            sb.append(" \"" + temp + "\"");
240            count++;
241          }
242        }
243        // check if any illegal keywords were found
244        temp = "The keyword";
245        if (sb.length() > 0) {
246          if (count > 1)  temp = temp + "s";
247          _addAndIgnoreError(temp + sb.toString() + " cannot be used at the Intermediate level", that);
248          return null;
249        }
250        return super.forModifiersAndVisibilityDoFirst(that);
251      }
252      
253    //  /** Do not allow explicit Package Statements at the Intermediate Level. */
254    //  public Void forPackageStatementDoFirst(PackageStatement that) {
255    ////    _addError("Package statements cannot be used at the Intermediate level.  " +
256    ////              "All Intermediate level classes and interfaces are assumed to be in the default package", that);
257    //    return null;
258    //  }
259    //  
260      /* The following two overrides appear unnecessary. */
261    //  /** Allow inner classes at the Intermediate Level.  Override any inherited code. */
262    //  public Void forInnerClassDefDoFirst(InnerClassDef that) {
263    ////    _addError("Inner classes cannot be used at the Intermediate level", that);
264    //    return null;
265    //  }
266    //  
267    //  /** Allow inner interfaces at the Intermediate Level. Override any inherited code. */
268    //    public Void forInnerInterfaceDefDoFirst(InnerInterfaceDef that) {
269    ////    _addError("Nested interfaces cannot be used at the Intermediate level", that);
270    //    return null;
271    //  }
272      
273    //  /**Do not allow static intiializers at the Intermediate Level.*/
274    //  public Void forStaticInitializerDoFirst(StaticInitializer that) {
275    //    _addError("Static initializers cannot be used at the Intermediate level", that);
276    //    return null;
277    //  }
278      
279    //  /**Do not allow labeled statements at the Intermediate Level.*/
280    //  public Void forLabeledStatementDoFirst(LabeledStatement that) {
281    //    _addError("Labeled statements cannot be used at the Intermediate level", that);
282    //    return null;
283    //  }
284      
285    //  /**Do not allow switch statements at the Intermediate Level.*/
286    //  public Void forSwitchStatementDoFirst(SwitchStatement that) {
287    //    _addError("Switch statements cannot be used at the Intermediate level", that);
288    //    return null;
289    //  }
290      
291    //  /**Do not allow while statements at the Intermediate Level.*/
292    //  public Void forWhileStatementDoFirst(WhileStatement that) {
293    //    _addError("While statements cannot be used at the Intermediate level", that);
294    //    return null;
295    //  }
296      
297    //  /**Do not allow do statements at the Intermediate Level.*/
298    //  public Void forDoStatementDoFirst(DoStatement that) {
299    //    _addError("Do statements cannot be used at the Intermediate level", that);
300    //    return null;
301    //  }
302      
303    //  /**Do not allow for statements at the Intermediate Level.*/
304    //  public Void forForStatementDoFirst(ForStatement that) {
305    //    _addError("For statements cannot be used at the Intermediate level", that);
306    //    return null;
307    //  }
308      
309    //  /**Do not allow break statements at the Intermediate Level.*/
310    //  public Void forBreakStatementDoFirst(BreakStatement that) {
311    //    _addError("Break statements cannot be used at the Intermediate level", that);
312    //    return null;
313    //  }
314      
315    //  /**Do not allow continue statements at the Intermediate Level.*/
316    //  public Void forContinueStatementDoFirst(ContinueStatement that) {
317    //    _addError("Continue statements cannot be used at the Intermediate level", that);
318    //    return null;
319    //  }
320      
321      /**Do not allow synchronized statements at the Intermediate Level.*/
322      public Void forSynchronizedStatementDoFirst(SynchronizedStatement that) {
323        _addError("Synchronized statements cannot be used at the Intermediate level", that);
324        return null;
325      }
326      
327    //  /**Do not allow try-catch statements at the Intermediate Level.*/
328    //  public Void forTryCatchStatementDoFirst(TryCatchStatement that) {
329    //    _addAndIgnoreError("A try-catch statement cannot appear here", that);
330    //    return null;
331    //  }
332      
333    //  /**Make sure that the formal parameter is not final*/
334    //  public Void forFormalParameterDoFirst(FormalParameter that) {
335    //    if (that.isIsFinal()) {
336    //      _addError("The keyword \"final\" cannot be used at the Intermediate level", that);
337    //    return null;
338    //    }
339    //    else {
340    //      return forJExpressionDoFirst(that);
341    //    }
342    //  }
343      
344      /**Do not allow type parameters (generics) at the Intermediate level*/
345      public Void forTypeParameterDoFirst(TypeParameter that) {
346        _addError("Type Parameters cannot be used at the Intermediate level", that);
347        return null;
348      }
349      
350    //  /**Only allow the 4 basic primitives: int, double, boolean, and char*/
351    //  public Void forPrimitiveTypeDoFirst(PrimitiveType that) {
352    //    String name = that.getName();
353    //    if (!(name.equals("int") || name.equals("double") || name.equals("boolean") || name.equals("char"))) {
354    //      _addError("Only the primitive types \"int\", \"double\", \"boolean\", and \"char\" can be used " +
355    //                "at the Intermediate level", that);
356    //    return null;
357    //    }
358    //    else {
359    //      return forTypeDoFirst(that);
360    //    }
361    //  }
362      
363    //  /**Do not allow arrays at the Intermediate Level*/
364    //  public Void forArrayTypeDoFirst(ArrayType that) {
365    //    _addError("Arrays cannot be used at the Intermediate level", that);
366    //    return null;
367    //  }
368      
369    //  /**Do not allow conditional expressions at the Intermediate Level*/
370    //  public Void forConditionalExpressionDoFirst(ConditionalExpression that) {
371    //    _addError("Conditional expressions cannot be used at the Intermediate level", that);
372    //    return null;
373    //  }
374      
375    //  /**Do not allow instanceof expressions at the Intermediate Level*/
376    //  public Void forInstanceofExpressionDoFirst(InstanceofExpression that) {
377    //    _addError("Instanceof expressions cannot be used at the Intermediate level", that);
378    //    return null;
379    //  }
380      
381      
382      /*Check to see if className is one of the classes declared in the current source file,
383       * by looking through classesInThisFile.*/
384      private boolean _isClassInCurrentFile(String className) {
385        Iterator<String> iter = _classesInThisFile.iterator();
386        while (iter.hasNext()) {
387          String s = iter.next();
388          if (s.equals(className) || s.endsWith('.' + className)) {
389            return true;
390          }
391        }
392        return false;   
393      }  
394      
395      /** Use the doFirst method to make sure there aren't any errors with the declaration.  Then, use defineSymbolData to 
396        * create the appropriate SymbolData, and then visit the class body.  Finally, autogenerate the toString, equals, 
397        * hashCode, and accessor methods.  The constructor will be autogenerated right before the TypeChecking pass starts.
398        * Once the class def has been handled, remove it from _classesInThisFile.
399        */
400      public Void forClassDef(ClassDef that) {    
401        forClassDefDoFirst(that);
402        if (prune(that)) return null;
403        
404        String className = getQualifiedClassName(that.getName().getText());
405    //    System.err.println("Processing class " + className);
406        
407        String superName = that.getSuperclass().getName();
408          
409        SymbolData sd = defineSymbolData(that, className);
410      
411        // Note: sd returns null only if there is an error such as redefining a class
412    //    assert getQualifiedSymbolData(className, that.getSourceInfo()) != null;
413    
414        that.getMav().visit(this);
415        that.getName().visit(this);
416        that.getSuperclass().visit(this);
417        
418        if (sd != null) identifyInnerClasses(that);
419        
420        // Type parameters are illegal in functional code.
421    //    for (int i = 0; i < that.getTypeParameters().length; i++) that.getTypeParameters()[i].visit(this);
422        
423        for (int i = 0; i < that.getInterfaces().length; i++) that.getInterfaces()[i].visit(this);
424        
425        if (sd != null) {
426          // Perform special processing for classes extending TestCase   
427          if (superName.equals("TestCase") || superName.equals("junit.framework.TestCase")) {
428            // Test cases are automatically public; isTestCase => sd != null
429            sd.addModifier("public");
430            // Check to see if we need to autognerate an import of TestCase class
431            if (! _importedPackages.contains("junit.framework") && ! _importedFiles.contains("junit.framework.TestCase")) {
432              sd.setHasAutoGeneratedJunitImport(true);
433              _importedFiles.addLast("junit.framework.TestCase");
434              createImportedSymbolContinuation("junit.framework.TestCase", that.getSourceInfo());
435    //          System.err.println("*********** Imported symbol continuation created for junit.framework.TestCase");
436            }
437            assert getQualifiedSymbolData("junit.framework.TestCase", that.getSourceInfo()) != null;
438          }
439          
440          that.getBody().visit(new ClassBodyIntermediateVisitor(sd, className, _file, _package, _importedFiles, 
441                                                                _importedPackages, _classesInThisFile, continuations,
442                                                                fixUps));
443          createAccessors(sd, _file);
444          createToString(sd);
445          createHashCode(sd);
446          createEquals(sd);
447        }
448        
449        forClassDefOnly(that);
450        _classesInThisFile.remove(className);
451        return null;
452      }
453      
454      /** Use the doFirst method to make sure that there aren't any errors with the declaration.  Define a SymbolData 
455        * corresponding to this interface definition. Then visit the body to handle anything defined inside the interfac
456        * Once the interface has been resolved, remove it from _classesInThisFile.
457        */
458      public Void forInterfaceDef(InterfaceDef that) {
459        forInterfaceDefDoFirst(that);
460        if (prune(that)) return null;
461        String className = getQualifiedClassName(that.getName().getText());
462        
463        // Type parameters are illegal in functional code.  Fix this!!!
464    //    assert that.getTypeParameters().length == 0;
465        
466        for (int i = 0; i < that.getInterfaces().length; i++) that.getInterfaces()[i].visit(this);
467    
468        SymbolData sd = defineSymbolData(that, className);
469        // Note: sd can only be null if an error occurs in defineSymbol
470        
471        if (sd != null) {
472          sd.setInterface(true);
473          identifyInnerClasses(that);  // inner interfaces??
474          that.getBody().visit(new InterfaceBodyIntermediateVisitor(sd, _file, _package, _importedFiles, _importedPackages, 
475                                                                    _classesInThisFile, continuations, fixUps));
476        }
477        
478        that.getMav().visit(this);
479        that.getName().visit(this);
480        forInterfaceDefOnly(that);
481        _classesInThisFile.remove(className);
482        return null;
483      }
484      
485      /**Bitwise operators are not allowed at any language level...*/
486      public Void forShiftAssignmentExpressionDoFirst(ShiftAssignmentExpression that) {
487        _addAndIgnoreError("Shift assignment operators cannot be used at any language level", that);
488        return null;
489      }
490      public Void forBitwiseAssignmentExpressionDoFirst(BitwiseAssignmentExpression that) {
491        _addAndIgnoreError("Bitwise operators cannot be used at any language level", that);
492        return null;
493      }
494      public Void forBitwiseBinaryExpressionDoFirst(BitwiseBinaryExpression that) {
495        _addAndIgnoreError("Bitwise binary expressions cannot be used at any language level", that);
496        return null;
497      }
498      public Void forBitwiseOrExpressionDoFirst(BitwiseOrExpression that) {
499    //    System.err.println("Visiting BitwiseOrExpression: " + that);
500        _addAndIgnoreError("Bitwise or expressions cannot be used in the functional language level." + 
501                           "  Perhaps you meant to compare two values using regular or (||)", that);
502        return null;
503      }
504      public Void forBitwiseXorExpressionDoFirst(BitwiseXorExpression that) {
505        _addAndIgnoreError("Bitwise xor expressions cannot be used at any language level", that);
506        return null;
507      }
508      public Void forBitwiseAndExpressionDoFirst(BitwiseAndExpression that) {
509        _addAndIgnoreError("Bitwise and expressions cannot be used at any language level." + 
510                           "  Perhaps you meant to compare two values using regular and (&&)", that);
511        return null;
512      }
513      public Void forBitwiseNotExpressionDoFirst(BitwiseNotExpression that) {
514        _addAndIgnoreError("Bitwise not expressions cannot be used at any language level." + 
515                           "  Perhaps you meant to negate this value using regular not (!)", that);
516        return null;
517      }
518      public Void forShiftBinaryExpressionDoFirst(ShiftBinaryExpression that) {
519        _addAndIgnoreError("Bit shifting operators cannot be used at any language level", that);
520        return null;
521      }
522      public Void forBitwiseNotExpressionDoFirst(ShiftBinaryExpression that) {
523        _addAndIgnoreError("Bitwise operators cannot be used at any language level", that);
524        return null;
525      }
526      
527    //  /** Call the super method to convert these to a VariableData array, then make sure that
528    //    * each VariableData is final, as required at the Intermediate level.
529    //    * @param enclosingData  The Data which contains the variables
530    //     */
531    //  protected VariableData[] _variableDeclaration2VariableData(VariableDeclaration vd, Data enclosingData) {
532    //    VariableData[] vds = super._variableDeclaration2VariableData(vd, enclosingData);
533    //    for (int i = 0; i < vds.length; i++) {
534    //      if ((vds[i].hasModifier("static") && vds[i].getMav().getModifiers().length > 1) || 
535    //          (! vds[i].hasModifier("static") && vds[i].getMav().getModifiers().length > 0)) {
536    //        StringBuffer s = new StringBuffer("the keyword(s) ");
537    //        String[] modifiers = vds[i].getMav().getModifiers();
538    //        for (int j = 0; j<modifiers.length; j++) {
539    //          if (! modifiers[j].equals("static")) {s.append("\"" + modifiers[j] + "\" ");}
540    //        }
541    //        _addAndIgnoreError("You cannot use " + s.toString() + "to declare a field at the Intermediate level.  " + 
542    //                           "Only the keyword 'static' is allowed", vd);
543    //      }
544    //      if (vds[i].hasModifier("static")) vds[i].addModifier("public");
545    //      else vds[i].addModifier("private"); 
546    //      vds[i].setFinal();
547    //    }
548    //    return vds;
549    //  }
550      
551      /** Pass this call directly onto the language level visitor.  This is a hack to bypass the privateAndFinal setting 
552        * when we are dealing with local variables.
553        */
554      protected VariableData[] llVariableDeclaration2VariableData(VariableDeclaration vd, Data enclosingData) {
555        return super._variableDeclaration2VariableData(vd, enclosingData);
556      }
557      
558    //  /** Do the work that is shared between SimpleAnonymousClassInstantiations and ComplexAnonymousClassInstantiations.  Do
559    //    * not generate automatic accessors for the anonymous class--this will be done in type checker pass.
560    //    * @param that  The AnonymousClassInstantiation being visited
561    //    * @param enclosing  The enclosing Data
562    //    * @param superC  The super class being instantiated--i.e. new A() { ...}, would have a super class of A.
563    //    */
564    //  public void anonymousClassInstantiationHelper(AnonymousClassInstantiation that, SymbolData enclosing, 
565    //    SymbolData superC) {
566    //  
567    //    that.getArguments().visit(this); 
568    //    
569    //    // Generate the internal class name for this anonymous inner class
570    //    String anonName = getQualifiedClassName(enclosing.getSymbolData().getName()) + "$" + 
571    //      enclosing.getSymbolData().preincrementAnonymousInnerClassNum();
572    //    
573    //    // Create the SymbolData that will correspond to this anonymous class
574    //    SymbolData sd = new SymbolData(anonName);
575    //    enclosing.addInnerClass(sd);
576    //    sd.setOuterData(enclosing);
577    //    
578    //    if (superC != null && ! superC.isInterface()) {
579    //      sd.setSuperClass(superC); // the super class is what was passed in
580    //    }
581    //    sd.setPackage(_package);
582    //    
583    //    createToString(sd);
584    //    createHashCode(sd);
585    //    createEquals(sd);
586    //    //accessors will be filled in in typeChecker pass
587    //    
588    //    //visit the body to get it all nice and resolved.  NOTE: what about the fact that all of the methods MUST BE PUBLIC
589    //    that.getBody().visit(new ClassBodyIntermediateVisitor(sd, anonName, _file, _package, _importedFiles,
590    //                                                          _importedPackages, _classesInThisFile, continuations,
591    //                                                          fixUps));
592    //  }
593      
594      /** Look up the supertype of this class instantiation and add it to the symbol table. Visit the body of the class 
595        * instantiation.  The processing of this anonymous inner class (i.e. adding it to the enclosing SD's list of inner 
596        * classes, creating a SymbolData for the anonyomous inner class, etc) will be handled in the TypeChecker pass.
597        * This is because no one will depend on that symbolData until we create it.
598        * @param that       The SimpleAnonymousClassInstantiation being processed.
599        * @param enclosing  The SymbolData of the enclosing class.
600        */
601      public void simpleAnonymousClassInstantiationHelper(SimpleAnonymousClassInstantiation that, SymbolData enclosing) {
602        forSimpleAnonymousClassInstantiationDoFirst(that);
603        if (prune(that)) return;
604        
605        String superName = that.getType().getName();
606        anonymousClassInstantiationHelper(that, enclosing, superName);
607        
608        forSimpleAnonymousClassInstantiationOnly(that);
609      }
610      
611      /** Do not resolve the super class type of this instantiation, because it will have already been resolved (it is an
612        * inner class of the enclosing SD.  When the enclosing SD was resolved, all of its inner classes 
613        * should have also been resolved).  Visit the body of the class instantiation.  
614        * @param that  The ComplexAnonymousClassInstantiation being processed.
615        * @param enclosing  The SymbolData of the enclosing class.
616        */
617      public void complexAnonymousClassInstantiationHelper(ComplexAnonymousClassInstantiation that, SymbolData enclosing) {
618        forComplexAnonymousClassInstantiationDoFirst(that);
619        if (prune(that)) return;
620        
621        //visit the enclosing 
622        that.getEnclosing().visit(this);
623        
624        String superName = that.getType().getName();
625        anonymousClassInstantiationHelper(that, enclosing, superName);
626        
627        forComplexAnonymousClassInstantiationOnly(that);
628      }
629      
630      /** Test the methods declared in the above class. */
631      public static class IntermediateVisitorTest extends TestCase {
632        
633        private IntermediateVisitor _iv;
634        
635        private SymbolData _sd1;
636        private SymbolData _sd2;
637        private SymbolData _sd3;
638        private SymbolData _sd4;
639        private SymbolData _sd5;
640        private SymbolData _sd6;
641        public static final ModifiersAndVisibility PUBLIC_MAV = 
642          new ModifiersAndVisibility(SourceInfo.NONE, new String[] { "public" });
643        public static final ModifiersAndVisibility PROTECTED_MAV = 
644          new ModifiersAndVisibility(SourceInfo.NONE, new String[] { "protected" });
645        public static final ModifiersAndVisibility PRIVATE_MAV = 
646          new ModifiersAndVisibility(SourceInfo.NONE, new String[] { "private" });
647        public static final ModifiersAndVisibility PACKAGE_MAV = new ModifiersAndVisibility(SourceInfo.NONE, new String[0]);
648        public static final ModifiersAndVisibility ABSTRACT_MAV = 
649          new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"abstract"});
650        public static final ModifiersAndVisibility PRIVATE_ABSTRACT_MAV = 
651          new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"abstract", "private"});  // illegal
652        public static final ModifiersAndVisibility STATIC_MAV = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"static"});
653        public static final ModifiersAndVisibility FINAL_MAV = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"final"});
654        
655        public IntermediateVisitorTest() { this(""); }
656        public IntermediateVisitorTest(String name) {
657          super(name);
658    //      _file = File.createTempFile("DrJava-test", ".java");
659    //      _iv = new ElementaryVisitor(new File(""), "", new LinkedList<String>(), new LinkedList<String>(), 
660    //                                 new LinkedList<String>());
661        }
662        
663        public void setUp() {
664          
665          errors = new LinkedList<Pair<String, JExpressionIF>>();
666          LanguageLevelConverter.symbolTable.clear();
667          LanguageLevelConverter._newSDs.clear();
668          LanguageLevelConverter.OPT = new Options(JavaVersion.JAVA_5, IterUtil.make(new File("lib/buildlib/junit.jar")));
669          visitedFiles = new LinkedList<Pair<LanguageLevelVisitor, SourceFile>>();      
670    //      _hierarchy = new Hashtable<String, TypeDefBase>();
671          
672          _iv = new IntermediateVisitor(new File(""),
673                                        errors,
674                                        continuations,
675                                        new LinkedList<Command>(),
676                                        new LinkedList<Pair<LanguageLevelVisitor, SourceFile>>());
677          LanguageLevelConverter.OPT = new Options(JavaVersion.JAVA_5, IterUtil.make(new File("lib/buildlib/junit.jar")));
678          _iv._classesInThisFile = new HashSet<String>();
679          _iv.continuations = new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>();
680    //      _iv._resetNonStaticFields();
681          _iv._importedPackages.addFirst("java.lang");
682          _errorAdded = false;
683          _sd1 = new SymbolData("i.like.monkey");
684          _sd2 = new SymbolData("i.like.giraffe");
685          _sd3 = new SymbolData("zebra");
686          _sd4 = new SymbolData("u.like.emu");
687          _sd5 = new SymbolData("");
688          _sd6 = new SymbolData("cebu");
689          
690          _sd1.setIsContinuation(false);
691          _sd1.setInterface(false);
692          _sd1.setPackage("");
693          _sd1.setTypeParameters(new TypeParameter[0]);
694          _sd1.setInterfaces(new ArrayList<SymbolData>()); 
695          
696          _iv._enclosingClassName = "i.like.monkey";
697          _iv.symbolTable.put("i.like.monkey", _sd1);
698          SymbolData objectSD = _iv.getQualifiedSymbolData("java.lang.Object", SourceInfo.NONE);
699          _sd1.setSuperClass(objectSD);
700          _errorAdded = false;  // static field of this.  TODO: fix this!
701        }
702        
703        public void initTopLevel() {
704          _iv._enclosingClassName = null;
705        }
706        
707        public void testForModifiersAndVisibilityDoFirst() {
708          
709          // Check that the proper modifiers are allowed:
710          _iv.forModifiersAndVisibilityDoFirst(ABSTRACT_MAV);
711          _iv.forModifiersAndVisibilityDoFirst(PUBLIC_MAV);
712          _iv.forModifiersAndVisibilityDoFirst(PRIVATE_MAV);
713          _iv.forModifiersAndVisibilityDoFirst(PROTECTED_MAV);
714          _iv.forModifiersAndVisibilityDoFirst(STATIC_MAV);
715          
716          ModifiersAndVisibility mavs = new ModifiersAndVisibility(SourceInfo.NONE, 
717                                                                   new String[] {"private", "static"});
718          _iv.forModifiersAndVisibilityDoFirst(mavs);
719          assertEquals("there should still be 0 errors", 0, errors.size());
720          
721          //check errors:
722          
723          _iv.forModifiersAndVisibilityDoFirst(FINAL_MAV);
724    //      assertEquals("there should now be 1 errors", 1, errors.size());
725    //      assertEquals("The error message should be correct for private modifier:", 
726    //                   "The keyword \"final\" cannot be used at the Intermediate level", errors.get(0).getFirst());
727          
728          ModifiersAndVisibility mavs2 = new ModifiersAndVisibility(SourceInfo.NONE, 
729                                                                    new String[] {"private", "final"});
730          
731          _iv.forModifiersAndVisibilityDoFirst(mavs2);
732          assertEquals("There should still be 0 errors", 0, errors.size());
733          
734          ModifiersAndVisibility mavs3 = new ModifiersAndVisibility(SourceInfo.NONE, 
735                                                                    new String[] {"final", "native"});
736          
737          _iv.forModifiersAndVisibilityDoFirst(mavs3);
738          assertEquals("There should now be 1 errors", 1, errors.size());
739          assertEquals("The error message should be correct for 1 bad modifier:",
740                       "The keyword \"native\" cannot be used at the Intermediate level", 
741                       errors.get(0).getFirst());
742        }
743        
744        public void testForClassDefDoFirst() {
745          //check an example that works
746          ClassDef cd0 = new ClassDef(SourceInfo.NONE, PUBLIC_MAV, new Word(SourceInfo.NONE, "Lisa"),
747                                      new TypeParameter[0], 
748                                      new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]), 
749                                      new ReferenceType[0], 
750                                      new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
751          
752          _iv.forClassDefDoFirst(cd0);
753          assertEquals("should be no errors", 0, errors.size());
754          
755          //check that an error is not thrown if a class doesn't explicitely extend another class
756          ClassDef cd1 = new ClassDef(SourceInfo.NONE, PUBLIC_MAV, 
757                                      new Word(SourceInfo.NONE, "Test"), new TypeParameter[0], JExprParser.NO_TYPE,
758                                      new ReferenceType[0], new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
759          
760          _iv.forClassDefDoFirst(cd1);
761          assertEquals("there should still be 0 errors", 0, errors.size());
762          
763          //check that an error is not thrown if a class implements any interfaces.
764          ClassDef cd2 = 
765            new ClassDef(SourceInfo.NONE, PUBLIC_MAV, 
766                         new Word(SourceInfo.NONE, "Test"),
767                         new TypeParameter[0],
768                         new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]), 
769                         new ReferenceType[] {new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0])}, 
770                         new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
771          
772          
773          _iv.forClassDefDoFirst(cd2);
774          assertEquals("there should still be 0 errors", 0, errors.size());
775        }
776        
777        public void testForFormalParameterDoFirst() {
778          PrimitiveType pt = new PrimitiveType(SourceInfo.NONE, "int");
779          Word w = new Word(SourceInfo.NONE, "param");
780          UninitializedVariableDeclarator uvd = new UninitializedVariableDeclarator(SourceInfo.NONE, pt, w);
781          
782          // check an example that works
783          FormalParameter fp = new FormalParameter(SourceInfo.NONE, uvd, false);
784          _iv.forFormalParameterDoFirst(fp);
785          assertEquals("should be no errors", 0, errors.size());
786          
787          // check that an error is thrown if the FormalParameter is final
788          FormalParameter fp2 = new FormalParameter(SourceInfo.NONE, uvd, true);  
789          _iv.forFormalParameterDoFirst(fp2);
790          assertEquals("should be no errors", 0, errors.size());
791        }
792        
793        public void test_NotAllowed() {
794          SourceInfo noInfo = SourceInfo.NONE;
795          Word w = new Word(SourceInfo.NONE, "word");
796          TypeParameter[] tps = new TypeParameter[0];
797          ReferenceType[] rts = new ReferenceType[0];
798          BracedBody emptyBody = new BracedBody(SourceInfo.NONE, new BodyItemI[0]);
799          ClassOrInterfaceType superClass = new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]);
800          FormalParameter[] fps = new FormalParameter[0];
801          CompoundWord cw = new CompoundWord(noInfo, new Word[0]);
802          Statement stmt = new EmptyStatement(noInfo);
803          Expression e = new NullLiteral(noInfo);
804          Block b = new Block(noInfo, emptyBody);
805          //      ClassModifier cm = ClassModifier.NONE;
806          TypeVariable tv = new TypeVariable(noInfo, "name");
807          
808          InnerInterfaceDef ii = new InnerInterfaceDef(noInfo, PUBLIC_MAV, w, tps, rts, emptyBody);
809          InnerClassDef ic = new InnerClassDef(noInfo, PUBLIC_MAV, w, tps, superClass, rts, emptyBody);
810          
811          StaticInitializer si = new StaticInitializer(noInfo, b);
812          LabeledStatement ls = new LabeledStatement(noInfo, new Word(noInfo, "label"), stmt);
813          SwitchStatement ss = new SwitchStatement(noInfo, e, new SwitchCase[0]);
814          WhileStatement ws = new WhileStatement(noInfo, e, stmt);
815          DoStatement ds = new DoStatement(noInfo, stmt, e);
816          ForStatement fs = new ForStatement(noInfo, new UnparenthesizedExpressionList(noInfo, new Expression[] {e}), 
817                                             e, new UnparenthesizedExpressionList(noInfo, new Expression[] {e}),
818                                             stmt);
819          BreakStatement bs = new UnlabeledBreakStatement(noInfo);
820          ContinueStatement cs = new UnlabeledContinueStatement(noInfo);
821          SynchronizedStatement syncs = new SynchronizedStatement(noInfo, e, b);
822          TypeParameter tp = new TypeParameter(noInfo, tv, superClass);
823          ArrayInitializer ai = new ArrayInitializer(noInfo, new VariableInitializerI[0]);
824          ArrayType at = new ArrayType(noInfo, "myName", tv);
825          VoidReturn vr = new VoidReturn(noInfo, "string");
826          ConditionalExpression ce = new ConditionalExpression(noInfo, e, e, e);
827          
828          BracedBody hasBitOperator = 
829            new BracedBody(SourceInfo.NONE, new BodyItemI[] { 
830            new ExpressionStatement(SourceInfo.NONE, 
831                                    new BitwiseOrAssignmentExpression(SourceInfo.NONE, 
832                                                                      new SimpleNameReference(SourceInfo.NONE, 
833                                                                                              new Word(SourceInfo.NONE, 
834                                                                                                       "i")), 
835                                                                      new IntegerLiteral(SourceInfo.NONE, 5)))});
836          
837          TryCatchStatement tcs = new NormalTryCatchStatement(noInfo, b, new CatchBlock[0]);
838          
839          si.visit(_iv);
840          assertEquals("After visiting static initializer, errors should still be 0", 0, errors.size());
841          
842          ii.visit(_iv);
843          assertEquals("After visiting inner interface, errors should still be 0", 0, errors.size());
844          
845          ic.visit(_iv);
846          assertEquals("After visiting inner class, errors should still be 0", 0, errors.size());
847          
848          ls.visit(_iv);
849          assertEquals("After visiting labeled statment, errors should still be 0", 0, errors.size());
850          
851          ss.visit(_iv);
852          assertEquals("After visiting switch statment, errors should still be 0", 0, errors.size());
853          
854          ws.visit(_iv);
855          assertEquals("After visiting while statment, errors should still be 0", 0, errors.size());
856          
857          ds.visit(_iv);
858          assertEquals("After visiting do statment, errors should still be 0", 0, errors.size());
859          
860          fs.visit(_iv);
861          assertEquals("After visiting for statment, errors should still be 0", 0, errors.size());
862          
863          bs.visit(_iv);
864          assertEquals("After visiting break statment, errors should still be 0", 0, errors.size());
865          
866          cs.visit(_iv);
867          assertEquals("After visiting continue statment, errors should still be 0", 0, errors.size());
868          
869          syncs.visit(_iv);
870          assertEquals("After visiting synchronized statment, errors should now be 1", 1, errors.size());
871          assertEquals("SynchronizedStatement is not allowed", 
872                       "Synchronized statements cannot be used at the Intermediate level", 
873                       errors.getLast().getFirst());
874          
875          tp.visit(_iv);
876          assertEquals("After visiting type parameter, errors should now be 2", 2, errors.size());
877          assertEquals("TypeParameters are not allowed", 
878                       "Type Parameters cannot be used at the Intermediate level", 
879                       errors.getLast().getFirst());
880        }
881        
882        public void testForPrimitiveTypeDoFirst() {
883          
884          SourceInfo noInfo = SourceInfo.NONE;
885          
886          //only primative types boolean, char, int, and double are allowed at Intermediate level. 
887          PrimitiveType i = new PrimitiveType(noInfo, "int");
888          PrimitiveType c = new PrimitiveType(noInfo, "char");
889          PrimitiveType d = new PrimitiveType(noInfo, "double");
890          PrimitiveType b = new PrimitiveType(noInfo, "boolean");
891          
892          i.visit(_iv);
893          assertEquals("After visiting int, errors should still be 0", 0, errors.size());
894          
895          c.visit(_iv);
896          assertEquals("After visiting char, errors should still be 0", 0, errors.size());
897          
898          d.visit(_iv);
899          assertEquals("After visiting double, errors should still be 0", 0, errors.size());
900          
901          b.visit(_iv);
902          assertEquals("After visiting boolean, errors should still be 0", 0, errors.size());
903          
904          // now the types that formerly threw errors:
905          
906          PrimitiveType byt = new PrimitiveType(noInfo, "byte");
907          PrimitiveType s = new PrimitiveType(noInfo, "short");
908          PrimitiveType l = new PrimitiveType(noInfo, "long");
909          PrimitiveType f = new PrimitiveType(noInfo, "float");
910          
911          byt.visit(_iv);
912          assertEquals("After visiting byte, errors should be 0", 0, errors.size());
913          
914          s.visit(_iv);
915          assertEquals("After visiting short, errors should be 0", 0, errors.size());
916          
917          l.visit(_iv);
918          assertEquals("After visiting long, errors should be 0", 0, errors.size());
919          
920          f.visit(_iv);
921          assertEquals("After visiting float, errors should be 0", 0, errors.size());
922        }
923        
924        public void test_isClassInCurrentFile() {
925          assertFalse("class not in file should return false", _iv._isClassInCurrentFile("NotInFile"));
926          _iv._classesInThisFile.add("package.MyClass");
927          assertTrue("full class name in file should return true", _iv._isClassInCurrentFile("package.MyClass"));
928          assertTrue("unqualified class name in file should return true", _iv._isClassInCurrentFile("MyClass"));
929          
930          assertFalse("partial name in file, not same class, should return false", _iv._isClassInCurrentFile("Class"));
931          
932        }
933      
934        /** Tests createConstructor.  Must ensure that no fixups remain pending before invoking this method. */
935        public void testCreateConstructor() {
936          SymbolData sd =
937            new SymbolData("ClassName", PUBLIC_MAV, new TypeParameter[0], null, new ArrayList<SymbolData>(), null);
938          VariableData v1 = new VariableData("i", PUBLIC_MAV, SymbolData.INT_TYPE, false, sd);
939          VariableData v2 = new VariableData("j", PUBLIC_MAV, SymbolData.CHAR_TYPE, false, sd);
940          sd.addVar(v1);
941          sd.addVar(v2);
942          sd.setSuperClass(_sd1);
943          sd.setIsContinuation(false);
944    
945    //      System.err.println("****** Creating constructor for " + _sd1);
946          _iv.createConstructor(_sd1);  // Cannot create constructor for s1 without creating one for its superclass.
947          
948          /* Construct expected MethodData */
949          // Copy vars without visibility
950          LinkedList<VariableData> params = new LinkedList<VariableData>();
951          for (VariableData vd: sd.getVars()) {
952            VariableData newParam = vd.copyWithoutVisibility();
953            newParam.setGenerated(true);
954            params.add(newParam);
955          };
956            
957          MethodData md = new MethodData("ClassName", 
958                                         PUBLIC_MAV, 
959                                         new TypeParameter[0], 
960                                         sd, 
961                                         params.toArray(new VariableData[params.size()]), 
962                                         new String[0], 
963                                         sd,
964                                         null);
965          md.addVars(md.getParams());     
966          md.setGenerated(true);
967          
968    //      System.err.println("****** Before creating Classname constructor, ClassName methods = " + sd.getMethods());
969    //      System.err.println("****** Creating constructor for " + sd);
970          _iv.createConstructor(sd);
971    //      System.err.println("****** After creating constructor, ClassName method = " + sd.getMethods());
972    
973          MethodData conSD = sd.getMethods().getFirst();
974              
975    //      System.err.println("****** Generated MethodData: " + conSD.toBigString());
976    //      System.err.println("****** Expectred MethodData: " + md.toBigString());
977          assertEquals("sd should have 1 method: its own constructor", md, conSD);
978          
979    //      // Since this is the only constructor in the SymbolData, all the fields should be assigned after visiting sd.
980    //      v1 = new VariableData("i", PUBLIC_MAV, SymbolData.INT_TYPE, true, sd);
981    //      v2 = new VariableData("j", PUBLIC_MAV, SymbolData.CHAR_TYPE, true, sd);
982          
983          // We no longer do this in createConstructor
984    //      assertTrue("v1 should be correct--set to true", sd.getVars().contains(v1));
985    //      assertTrue("v2 should be correct--set to true", sd.getVars().contains(v2));
986    
987          // Now test a subclass of sd:
988    
989          SymbolData subSD = 
990            new SymbolData("Subclass", PUBLIC_MAV, new TypeParameter[0], null, new ArrayList<SymbolData>(), null);
991          VariableData v3 = new VariableData("var", PUBLIC_MAV, SymbolData.DOUBLE_TYPE, false, subSD);
992          subSD.addVar(v3);
993          
994    //      // Revise params rather than recreating them, because they contain hidden fields like enclosingData that
995    //      // must be right for equality testing to succeeed
996    //      params.get(0).setName("super_i");
997    //      params.get(1).setName("super_j");
998    //      VariableData v3Param = v3.copyWithoutVisibility();
999    //      v3Param.setGenerated(true);
1000    //      params.add(v3Param);
1001          
1002          subSD.setSuperClass(sd);
1003          
1004          // Create copies of v1, v2. v3 with Package MAV
1005          VariableData v1Param = new VariableData("super_i", PACKAGE_MAV, SymbolData.INT_TYPE, true, subSD);
1006          VariableData v2Param = new VariableData("super_j", PACKAGE_MAV, SymbolData.CHAR_TYPE, true, subSD);
1007          VariableData v3Param = new VariableData("var", PACKAGE_MAV, SymbolData.DOUBLE_TYPE, true, subSD);
1008              
1009          v1Param.setGenerated(true);
1010          v2Param.setGenerated(true);
1011          v3Param.setGenerated(true);
1012          
1013          VariableData[] newParams = new VariableData[] { v1Param, v2Param, v3Param };
1014          
1015    //      VariableData[] newParams = params.toArray(new VariableData[params.size()]);
1016          
1017          MethodData md2 = 
1018            new MethodData("Subclass", 
1019                           PUBLIC_MAV, 
1020                           new TypeParameter[0], 
1021                           subSD, 
1022                           newParams,
1023                           new String[0], 
1024                           subSD, 
1025                           null);
1026          
1027          md2.addVars(md2.getParams());
1028          md2.setGenerated(true);
1029          
1030          _iv.createConstructor(subSD);
1031          
1032          conSD = subSD.getMethods().getFirst();  // Reusing conSD local variable
1033    //      System.err.println("****** Expected params = " + Arrays.toString(md2.getParams()));
1034    //      System.err.println("****** Results  params = " + Arrays.toString(conSD.getParams()));
1035          
1036    //      System.err.println("****** Expected vars = " + md2.getVars());
1037    //      System.err.println("****** Results  vars = " + conSD.getVars());
1038          
1039    //      System.err.println("****** Constructor for Subclass is: " + conSD.toBigString());
1040    //      System.err.println("****** Expected MethodData is: " + md2.toBigString());
1041          
1042          assert md2.getName().equals(conSD.getName());
1043          assert md2.getMav().equals(conSD.getMav());
1044          assert arrayEquals(md2.getTypeParameters(), conSD.getTypeParameters());
1045          assert arrayEquals(md2.getThrown(), conSD.getThrown());
1046          assert md2.getEnclosingData().equals(conSD.getEnclosingData());
1047          LinkedList<VariableData> mVars = md2.getVars();
1048          LinkedList<VariableData> cVars = conSD.getVars();
1049          assert mVars.size() == cVars.size();
1050          for (int i = 0; i < mVars.size(); i++) {
1051    //        System.err.println("****** EnclosingData of mVars " + i + " = " + mVars.get(i).getEnclosingData());
1052    //        System.err.println("****** EnclosingData of cVars " + i + " = " + cVars.get(i).getEnclosingData());
1053            assertEquals("Var Test" + i, mVars.get(i), cVars.get(i));
1054          }
1055            
1056          assert md2.getVars().equals(conSD.getVars());
1057          assert arrayEquals(md2.getParams(), conSD.getParams());
1058    
1059          assertEquals("subSD should have 1 method: its own constructor.", md2, conSD);
1060        }
1061        
1062        public void test_getFieldAccessorName() {
1063          // This may change in the future if we change getFieldAccessorName
1064          assertEquals("Should correctly convert from lower case to upper case", "name", _iv.getFieldAccessorName("name"));
1065        }
1066        
1067        public void testCreateToString() {
1068          SymbolData sd = 
1069            new SymbolData("ClassName", PUBLIC_MAV, new TypeParameter[0], null, new ArrayList<SymbolData>(), null);
1070          
1071          MethodData md = new MethodData("toString", 
1072                                         PUBLIC_MAV,
1073                                         new TypeParameter[0],
1074                                         _iv.getSymbolData("java.lang.String", SourceInfo.make("java.lang.String")), 
1075                                         new VariableData[0],
1076                                         new String[0], 
1077                                         sd,
1078                                         null); // no SourceInfo
1079          
1080          _iv.createToString(sd);
1081          assertEquals("sd should have 1 method: toString", md, sd.getMethods().getFirst());
1082        }
1083        
1084        public void testCreateHashCode() {
1085          SymbolData sd = new SymbolData("ClassName", 
1086                                         PUBLIC_MAV, 
1087                                         new TypeParameter[0], 
1088                                         null, 
1089                                         new ArrayList<SymbolData>(), 
1090                                         null);      
1091          MethodData md = new MethodData("hashCode",
1092                                         PUBLIC_MAV, 
1093                                         new TypeParameter[0], 
1094                                         SymbolData.INT_TYPE, 
1095                                         new VariableData[0],
1096                                         new String[0], 
1097                                         sd,
1098                                         null);
1099          _iv.createHashCode(sd);
1100          assertEquals("sd should have 1 method: hashCode()", md, sd.getMethods().getFirst());
1101        }
1102        
1103        public void testCreateEquals() {
1104          SymbolData sd =
1105            new SymbolData("ClassName", PUBLIC_MAV, new TypeParameter[0], null, new ArrayList<SymbolData>(), null);
1106          VariableData[] vds =
1107            new VariableData[] { new VariableData(_iv.getSymbolData("java.lang.Object", SourceInfo.make("java.lang.Object"))) };
1108          MethodData md = new MethodData("equals",
1109                                         PUBLIC_MAV, 
1110                                         new TypeParameter[0], 
1111                                         SymbolData.BOOLEAN_TYPE, 
1112                                         vds,
1113                                         new String[0], 
1114                                         sd,
1115                                         null);
1116          _iv.createEquals(sd);
1117          md.getParams()[0].setEnclosingData(sd.getMethods().getFirst());                               
1118          assertEquals("sd should have 1 method: equals()", md, sd.getMethods().getFirst());
1119        }
1120        
1121        public void testForClassDef() {
1122          //check an example that's not abstract
1123          initTopLevel();
1124          ClassDef cd0 = 
1125            new ClassDef(SourceInfo.NONE, PACKAGE_MAV, new Word(SourceInfo.NONE, "Lisa"),
1126                         new TypeParameter[0], 
1127                         new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]), 
1128                         new ReferenceType[0], 
1129                         new BracedBody(SourceInfo.NONE, new BodyItemI[0])); 
1130          
1131          cd0.visit(_iv);
1132          assertEquals("There should be no errors", 0, errors.size());
1133          assertTrue("Should have resolved java.lang.Object", 
1134                     LanguageLevelConverter.symbolTable.containsKey("java.lang.Object"));
1135          assertFalse("Should not be a continuation", 
1136                      LanguageLevelConverter.symbolTable.get("java.lang.Object").isContinuation());
1137          SymbolData sd = LanguageLevelConverter.symbolTable.get("Lisa");
1138          assertTrue("Lisa should be in _newSDs", LanguageLevelConverter._newSDs.containsKey(sd));
1139          MethodData md2 = 
1140            new MethodData("equals",
1141                           PUBLIC_MAV, 
1142                           new TypeParameter[0], 
1143                           SymbolData.BOOLEAN_TYPE, 
1144                           new VariableData[] { new VariableData(_iv.getSymbolData("java.lang.Object", 
1145                                                                                   SourceInfo.make("java.lang.Object"))) },
1146                           new String[0], 
1147                           sd,
1148                           null);
1149          
1150          md2.getParams()[0].setEnclosingData(sd.getMethods().getLast());  
1151          
1152          assertEquals("sd's last method should be equals()", md2, sd.getMethods().getLast());
1153          assertEquals("sd's package should be correct", "", sd.getPackage());
1154          
1155          //check an example that's abstract
1156          _iv._package = "";
1157          ClassDef cd1 = new ClassDef(SourceInfo.NONE, 
1158                                      ABSTRACT_MAV, 
1159                                      new Word(SourceInfo.NONE, "Bart"),
1160                                      new TypeParameter[0],
1161                                      new ClassOrInterfaceType(SourceInfo.NONE, "System", new Type[0]), 
1162                                      new ReferenceType[0], 
1163                                      new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
1164          cd1.visit(_iv);
1165          assertEquals("There should be no errors", 0, errors.size());
1166          assertTrue("Should have resolved java.lang.System", 
1167                     LanguageLevelConverter.symbolTable.containsKey("java.lang.System"));
1168          assertFalse("Should not be a continuation", 
1169                      LanguageLevelConverter.symbolTable.get("java.lang.System").isContinuation());
1170          sd = LanguageLevelConverter.symbolTable.get("Bart");
1171          
1172          assertEquals("There should be 3 methods", 3, sd.getMethods().size());
1173          
1174          
1175          //Check an example where the class extends TestCase, and has a test method that returns void.
1176          ConcreteMethodDef cmd = new ConcreteMethodDef(SourceInfo.NONE, 
1177                                                        PACKAGE_MAV, 
1178                                                        new TypeParameter[0], 
1179                                                        new VoidReturn(SourceInfo.NONE, "void"), 
1180                                                        new Word(SourceInfo.NONE, "testMethodName"),
1181                                                        new FormalParameter[0],
1182                                                        new ReferenceType[0], 
1183                                                        new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
1184          
1185          ClassDef cd3 = new ClassDef(SourceInfo.NONE, 
1186                                      ABSTRACT_MAV, 
1187                                      new Word(SourceInfo.NONE, "TestSuper2"),
1188                                      new TypeParameter[0], 
1189                                      new ClassOrInterfaceType(SourceInfo.NONE, "TestCase", new Type[0]), 
1190                                      new ReferenceType[0], 
1191                                      new BracedBody(SourceInfo.NONE, new BodyItemI[] { cmd }));
1192          
1193          _iv._file=new File("TestSuper2.dj0");
1194          _iv._importedFiles.addLast("junit.framework.TestCase");
1195          LanguageLevelConverter.symbolTable.put("junit.framework.TestCase", new SymbolData("junit.framework.TestCase"));
1196          cd3.visit(_iv);
1197          assertEquals("There should still just be no errors", 0, errors.size());
1198          assertNotNull("Should have looked up TestSuper2", LanguageLevelConverter.symbolTable.get("TestSuper2"));
1199          
1200          // Check a method with void return, but name not starting with test, but it's still okay.
1201          //This is now checked in the type checker!
1202          ConcreteMethodDef cmd2 = new ConcreteMethodDef(SourceInfo.NONE, 
1203                                                         PACKAGE_MAV, 
1204                                                         new TypeParameter[0], 
1205                                                         new VoidReturn(SourceInfo.NONE, "void"), 
1206                                                         new Word(SourceInfo.NONE, "uhOh"),
1207                                                         new FormalParameter[0],
1208                                                         new ReferenceType[0], 
1209                                                         new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
1210          
1211          ClassDef cd4 = new ClassDef(SourceInfo.NONE, 
1212                                      ABSTRACT_MAV, 
1213                                      new Word(SourceInfo.NONE, "TestVoidNoTestMethod"),
1214                                      new TypeParameter[0], 
1215                                      new ClassOrInterfaceType(SourceInfo.NONE, "junit.framework.TestCase", new Type[0]), 
1216                                      new ReferenceType[0], 
1217                                      new BracedBody(SourceInfo.NONE, new BodyItemI[] { cmd2 }));
1218          
1219          
1220          
1221          _iv._file=new File("TestVoidNoTestMethod.dj0");
1222          cd4.visit(_iv);
1223          
1224          assertEquals("There should still be 0 errors", 0, errors.size());
1225          _iv._importedFiles.remove("junit.framework.TestCase");
1226          
1227        }
1228        
1229        public void testForInterfaceDef() {
1230          initTopLevel();
1231          AbstractMethodDef amd = new AbstractMethodDef(SourceInfo.NONE, 
1232                                                        PUBLIC_MAV, 
1233                                                        new TypeParameter[0], 
1234                                                        new PrimitiveType(SourceInfo.NONE, "int"),
1235                                                        new Word(SourceInfo.NONE, "myMethod"), 
1236                                                        new FormalParameter[0], 
1237                                                        new ReferenceType[0]);
1238          AbstractMethodDef amd2 = new AbstractMethodDef(SourceInfo.NONE, 
1239                                                         PUBLIC_MAV, 
1240                                                         new TypeParameter[0], 
1241                                                         new PrimitiveType(SourceInfo.NONE, "int"),
1242                                                         new Word(SourceInfo.NONE, "myMethod"), 
1243                                                         new FormalParameter[0], 
1244                                                         new ReferenceType[0]);
1245          InterfaceDef id = new InterfaceDef(SourceInfo.NONE, 
1246                                             PUBLIC_MAV, 
1247                                             new Word(SourceInfo.NONE, "id"), 
1248                                             new TypeParameter[0], 
1249                                             new ReferenceType[0], 
1250                                             new BracedBody(SourceInfo.NONE, new BodyItemI[] {amd}));
1251          InterfaceDef id2 = 
1252            new InterfaceDef(SourceInfo.NONE, 
1253                             PUBLIC_MAV, 
1254                             new Word(SourceInfo.NONE, "id2"), 
1255                             new TypeParameter[0], 
1256                             new ReferenceType[] { new ClassOrInterfaceType(SourceInfo.NONE, "id", new Type[0]) }, 
1257                             new BracedBody(SourceInfo.NONE, new BodyItemI[] { amd2 }));
1258          SymbolData sd = new SymbolData("id", PUBLIC_MAV, new TypeParameter[0], new ArrayList<SymbolData>(), null);
1259          sd.setIsContinuation(true);
1260          MethodData md = 
1261            new MethodData("myMethod", PUBLIC_MAV, new TypeParameter[0], SymbolData.INT_TYPE, new VariableData[0], 
1262                           new String[0], sd, amd);
1263          
1264          ArrayList<SymbolData> interfaces = new ArrayList<SymbolData>();
1265          interfaces.add(sd);
1266          SymbolData sd2 = new SymbolData("id2", PUBLIC_MAV, new TypeParameter[0], interfaces, null);
1267          sd2.setIsContinuation(true);
1268          MethodData md2 = 
1269            new MethodData("myMethod", PUBLIC_MAV, new TypeParameter[0], SymbolData.INT_TYPE, new VariableData[0], 
1270                           new String[0], sd2, amd2);
1271          LanguageLevelConverter.symbolTable.put("id", sd);
1272          LanguageLevelConverter.symbolTable.put("id2", sd2);
1273          
1274          id.visit(_iv);
1275          id2.visit(_iv);
1276          
1277          assertEquals("Should be no errors", 0, errors.size());
1278          assertEquals("Should return the same symbol datas: id", sd, LanguageLevelConverter.symbolTable.get("id"));
1279          assertEquals("Should return the same symbol datas:id2 ", sd2, LanguageLevelConverter.symbolTable.get("id2"));
1280        }
1281        
1282        
1283        
1284        public void testCreateMethodData() {
1285          // Test one that doesn't work.
1286          MethodDef mdef = new AbstractMethodDef(SourceInfo.NONE, 
1287                                                 PRIVATE_ABSTRACT_MAV, 
1288                                                 new TypeParameter[0], 
1289                                                 new PrimitiveType(SourceInfo.NONE, "int"), 
1290                                                 new Word(SourceInfo.NONE, "methodName"),
1291                                                 new FormalParameter[0],
1292                                                 new ReferenceType[0]); 
1293          
1294          MethodData mdata = new MethodData("methodName", PRIVATE_ABSTRACT_MAV, new TypeParameter[0], SymbolData.INT_TYPE, 
1295                                            new VariableData[0], 
1296                                            new String[0],
1297                                            _sd1,
1298                                            null);
1299          _iv._package = "i.like";
1300          _iv._enclosingClassName = "i.like.monkey";
1301          _iv.symbolTable.put("i.like.monkey", _sd1);
1302    //      System.err.println("SymbolData for i.like.monkey = " + _iv.getQualifiedSymbolData("i.like.monkey", SourceInfo.NONE));
1303          assertEquals("Should return the correct MethodData", mdata, _iv.createMethodData(mdef, _sd1));
1304          assertEquals("There should be one errors.", 1, errors.size());
1305    //      assertEquals("The error message should be correct.", 
1306    //      "The keyword \"final\" cannot be used at the Intermediate level", 
1307    //        errors.get(0).getFirst());
1308          
1309          // Test one that does work.
1310          UninitializedVariableDeclarator uvd1 =
1311            new UninitializedVariableDeclarator(SourceInfo.NONE, 
1312                                                new PrimitiveType(SourceInfo.NONE, "double"), 
1313                                                new Word(SourceInfo.NONE, "field1"));
1314          UninitializedVariableDeclarator uvd2 =
1315            new UninitializedVariableDeclarator(SourceInfo.NONE, 
1316                                                new PrimitiveType(SourceInfo.NONE, "int"), 
1317                                                new Word(SourceInfo.NONE, "field1"));
1318          mdef = 
1319            new AbstractMethodDef(SourceInfo.NONE, 
1320                                  ABSTRACT_MAV, 
1321                                  new TypeParameter[] { new TypeParameter(SourceInfo.NONE,
1322                                                                          new TypeVariable(SourceInfo.NONE, "T"),
1323                                                                          new TypeVariable(SourceInfo.NONE, "U"))},
1324                                  new VoidReturn(SourceInfo.NONE, "void"), 
1325                                  new Word(SourceInfo.NONE, "methodName"),
1326                                  new FormalParameter[] {
1327                                    new FormalParameter(SourceInfo.NONE, 
1328                                                        uvd1,
1329                                                        false
1330                                                       ),
1331                                      new FormalParameter(SourceInfo.NONE, 
1332                                                          uvd2,
1333                                                          false
1334                                                         )},
1335                                  new ReferenceType[] { new TypeVariable(SourceInfo.NONE, "X") }
1336                                  );
1337          mdata = 
1338            new MethodData("methodName", 
1339                           ABSTRACT_MAV, 
1340                           new TypeParameter[] { new TypeParameter(SourceInfo.NONE,
1341                                                                   new TypeVariable(SourceInfo.NONE, "T"),
1342                                                                   new TypeVariable(SourceInfo.NONE, "U"))}, 
1343                           SymbolData.VOID_TYPE, 
1344                           new VariableData[] { new VariableData("field1", FINAL_MAV, SymbolData.DOUBLE_TYPE, true, _sd1),
1345                             new VariableData("field1", FINAL_MAV, SymbolData.INT_TYPE, true, _sd1) }, 
1346                           new String[] { "X" },
1347                           _sd1,
1348                           null);
1349          
1350          
1351          MethodData result = _iv.createMethodData(mdef, _sd1);
1352          /* Enclosing data for formal parameters is the enclosing class, not the enclosing method. */
1353    //      mdata.getParams()[0].setEnclosingData(result);
1354    //      mdata.getParams()[1].setEnclosingData(result);
1355          
1356          // have to add the parameters to the vars manually
1357          mdata.addVars(new VariableData[] { new VariableData("field1", FINAL_MAV, SymbolData.DOUBLE_TYPE, true, _sd1) });
1358    //      System.err.println("****** mdata  = " + mdata);
1359    //      System.err.println("****** result = " + result);
1360          assertEquals("Should return the correct MethodData", mdata, result);
1361          assertEquals("There should be 2 errors.", 2, errors.size());
1362          // This is now caught in the type checker.
1363    //      assertEquals("The second error message should be correct.", 
1364    //                   "The keyword \"void\" cannot be used at the Intermediate level", 
1365    //                   errors.get(1).getFirst());
1366          assertEquals("The second error message should be correct.", 
1367                       "You cannot have two method parameters with the same name", 
1368                       errors.get(1).getFirst());
1369        }
1370        
1371        public void testSimpleAnonymousClassInstantiationHelper() {
1372          SimpleAnonymousClassInstantiation basic = 
1373            new SimpleAnonymousClassInstantiation(SourceInfo.NONE, 
1374                                                  new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]), 
1375                                                  new ParenthesizedExpressionList(SourceInfo.NONE, new Expression[0]),
1376                                                  new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
1377          _iv._package = "i.like";
1378          _iv._enclosingClassName = "i.like.monkey";
1379          _iv.symbolTable.put("i.like.monkey", _sd1);
1380    //      System.err.println("SymbolData for i.like.monkey = " + _iv.getQualifiedSymbolData("i.like.monkey", SourceInfo.NONE));
1381          _iv.simpleAnonymousClassInstantiationHelper(basic, _sd1);
1382          assertEquals("There should be no errors", 0, errors.size());
1383          SymbolData obj = LanguageLevelConverter.symbolTable.get("java.lang.Object");
1384          assertNotNull("Object should be in the symbol table", obj);
1385          assertEquals("sd1 should have one inner class", 1, _sd1.getInnerClasses().size());
1386          SymbolData inner = _sd1.getInnerClasses().get(0);
1387          assertEquals("The inner class should have the proper name", "i.like.monkey$1", inner.getName());
1388          assertEquals("The inner class should have proper outer data", _sd1, inner.getOuterData());
1389          assertEquals("The inner class should have proper super class", obj, inner.getSuperClass());
1390          assertEquals("The inner class should have the right package", "i.like", inner.getPackage());
1391          assertEquals("The inner class should have 3 methods", 3, inner.getMethods().size());
1392        }
1393        
1394        public void testComplexAnonymousClassInstantiationHelper() {
1395          SimpleNameReference snr =
1396            new SimpleNameReference(SourceInfo.NONE, new Word(SourceInfo.NONE, "java.lang.Object"));
1397          ComplexAnonymousClassInstantiation basic = 
1398            new ComplexAnonymousClassInstantiation(SourceInfo.NONE, 
1399                                                   snr,
1400                                                   new ClassOrInterfaceType(SourceInfo.NONE, "Inner", new Type[0]), 
1401                                                   new ParenthesizedExpressionList(SourceInfo.NONE, new Expression[0]),
1402                                                   new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
1403          _iv._package = "i.like";
1404          _iv._enclosingClassName = "i.like.monkey";
1405          _iv.complexAnonymousClassInstantiationHelper(basic, _sd1); // TODO: the wrong enclosing context?
1406          assertEquals("There should be no errors", 0, errors.size());
1407          SymbolData obj = LanguageLevelConverter.symbolTable.get("java.lang.Object");
1408          assertNotNull("Object should be in the symbol table", obj);
1409          SymbolData objInner = LanguageLevelConverter.symbolTable.get("java.lang.Object.Inner");
1410          assertEquals("sd1 should have one inner class", 1, _sd1.getInnerClasses().size());
1411          SymbolData inner = _sd1.getInnerClasses().get(0);
1412          assertEquals("The inner class should have the proper name", "i.like.monkey$1", inner.getName());
1413          assertEquals("The inner class should have proper outer data", _sd1, inner.getOuterData());
1414          assertEquals("The inner class should have null as its super class", null, inner.getSuperClass());
1415          assertEquals("The inner class should have the right package", "i.like", inner.getPackage());
1416          assertEquals("The inner class should have 3 methods", 3, inner.getMethods().size());
1417        }
1418        
1419        public void testForVariableDeclaration() {
1420          // Confirm that if forVariableDeclaration is called with a AnonymousClassInstantiation, the symboldata is only 
1421          // added once. This is to make sure an old bug stays fixed.
1422          SimpleAnonymousClassInstantiation basic = 
1423            new SimpleAnonymousClassInstantiation(SourceInfo.NONE, 
1424                                                  new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]), 
1425                                                  new ParenthesizedExpressionList(SourceInfo.NONE, new Expression[0]),
1426                                                  new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
1427          
1428          
1429          
1430          VariableDeclarator[] d1 = { 
1431            new InitializedVariableDeclarator(SourceInfo.NONE, 
1432                                              new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]), 
1433                                              new Word(SourceInfo.NONE, "b"), basic)};
1434          
1435          VariableDeclaration vd1 = new VariableDeclaration(SourceInfo.NONE,PUBLIC_MAV, d1); 
1436          
1437          ClassBodyIntermediateVisitor cbiv = 
1438            new ClassBodyIntermediateVisitor(_sd1,
1439                                             _sd1.getName(),
1440                                             _iv._file, 
1441                                             _iv._package,
1442                                             _iv._importedFiles, 
1443                                             _iv._importedPackages, 
1444                                             _iv._classesInThisFile, 
1445                                             _iv.continuations,
1446                                             _iv.fixUps);
1447          
1448          vd1.visit(cbiv);
1449          assertEquals("Should be 1 inner class of _sd1", 1, _sd1.getInnerClasses().size());
1450        }
1451        
1452        public void testForPackageStatementDoFirst() {
1453          PackageStatement ps = new PackageStatement(SourceInfo.NONE, new CompoundWord(SourceInfo.NONE, new Word[0]));
1454          ps.visit(_iv);
1455          assertEquals("Should be no errors", 0, errors.size());
1456    //      assertEquals("Error message should be correct", "Package statements cannot be used at the Intermediate level."
1457    //                     + "  All Intermediate level classes and interfaces are assumed to be in the default package", 
1458    //                   errors.getLast().getFirst());
1459        }
1460      }
1461    }