Clover coverage report - Java Language Levels Test Coverage (javalanglevels-20120305-r5436)
Coverage timestamp: Sun Mar 4 2012 22:02:46 CST
file stats: LOC: 817   Methods: 25
NCLOC: 505   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
ClassBodyIntermediateVisitor.java 90.6% 97.1% 88% 95.5%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.javalanglevels;
 38   
 39    import edu.rice.cs.javalanglevels.tree.*;
 40    import edu.rice.cs.javalanglevels.parser.*;
 41    import edu.rice.cs.javalanglevels.util.*;
 42   
 43    import java.util.*;
 44    import java.io.*;
 45   
 46    import junit.framework.TestCase;
 47   
 48    /*
 49    * Language Level Visitor that represents the Intermediate Language Level. Enforces constraints during the
 50    * first walk of the AST (checking for langauge specific errors and building the symbol table).
 51    * This class enforces things that are common to all contexts reachable within a class body at
 52    * the Intermediate Language Level.
 53    */
 54    public class ClassBodyIntermediateVisitor extends IntermediateVisitor {
 55   
 56    /** The SymbolData corresponding to this class. */
 57    private SymbolData _enclosing;
 58   
 59    /** Constructor for ClassBodyAdvancedVisitor.
 60    * @param sd The SymbolData that encloses the context we are visiting.
 61    * @param file The source file this came from.
 62    * @param packageName The package the source file is in
 63    * @importedFiles A list of classes that were specifically imported
 64    * @param importedPackages A list of package names that were specifically imported
 65    * @param classesInThisFile A list of the classes that are yet to be defined in this source file
 66    * @param continuations A hashtable corresponding to the continuations (unresolved Symbol Datas) that will need to
 67    * be resolved
 68    * @param fixUps A list of commands to be performed after this pass to fixup the symbolTable
 69    */
 70  124 public ClassBodyIntermediateVisitor(SymbolData sd,
 71    String className,
 72    File file,
 73    String packageName,
 74    LinkedList<String> importedFiles,
 75    LinkedList<String> importedPackages,
 76    HashSet<String> classesInThisFile,
 77    Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>> continuations,
 78    LinkedList<Command> fixUps) {
 79  124 super(file, packageName, className, importedFiles, importedPackages, classesInThisFile, continuations, fixUps);
 80  124 _enclosing = sd;
 81    }
 82   
 83    /*Add an appropriate error*/
 84  0 public Void forStatementDoFirst(Statement that) {
 85  0 _addError("Statements cannot appear outside of method bodies", that);
 86  0 return null;
 87    }
 88   
 89    /** Ignore AbstractMake sure that this abstract method def is declared to be abstract. */
 90  6 public Void forAbstractMethodDefDoFirst(AbstractMethodDef that) {
 91   
 92    // ModifiersAndVisibility mav = that.getMav();
 93    // String[] modifiers = mav.getModifiers();
 94  6 if (! _enclosing.isInterface() && ! _enclosing.hasModifier("abstract")) { // interfaces not yet marked abstract
 95  1 _addError("Abstract methods can only be declared in abstract classes", that);
 96    }
 97  6 return super.forAbstractMethodDefDoFirst(that);
 98    }
 99   
 100    /**Add an appropriate error*/
 101  1 public Void forInstanceInitializerDoFirst(InstanceInitializer that) {
 102  1 _addError("This open brace must mark the beginning of a method or class body", that);
 103  1 return null;
 104    }
 105   
 106    /** Processes a field declaration. Converts VariableDeclaration to VariableData[]. Ensures that no fields are
 107    * declared to be abstract. Finally, adds the variable datas to the symbol data, and emits an
 108    * error if two fields have the same names. */
 109  88 public Void forVariableDeclarationOnly(VariableDeclaration that) {
 110    // System.err.println("Calling _variableDeclaration2VariableData on " + that);
 111  88 VariableData[] vds = _variableDeclaration2VariableData(that, _enclosing);
 112    // System.err.println("Constructed vds array = " + Arrays.toString(vds));
 113    // make sure that every non-static field is private and no static field are uninitialized:
 114    // LinkedList<VariableData> vdsList = new LinkedList<VariableData>();
 115  88 for (int i = 0; i < vds.length; i++) {
 116  81 if (! vds[i].isStatic()) vds[i].setPrivate();
 117  12 else if (that.getDeclarators()[i] instanceof UninitializedVariableDeclarator) {
 118  2 _addAndIgnoreError("All static fields must be initialized", that);
 119    }
 120    // TODO: where is abstract check?
 121    }
 122    // System.err.println("Processed vds array = " + Arrays.toString(vds));
 123  88 if (! _enclosing.addFinalVars(vds /* vdsList.toArray(new VariableData[vdsList.size()]) */)) {
 124    // System.err.println("Duplicate variable declaration found");
 125  2 _addAndIgnoreError("You cannot have two fields with the same name. Either you already have a field by that "
 126    + "name in this class, or one of your superclasses or interfaces has a field by that name",
 127    that);
 128    }
 129  88 return null;
 130    }
 131   
 132    // TODO: lift the following two methods to LLV since they are identical in ClassBodyFullJavaVisitor.
 133   
 134    /** Call the method in FullJavaVisitor since it's common to this and FullJavaBodyFullJavaVisitor. */
 135  1 public Void forInnerInterfaceDef(InnerInterfaceDef that) {
 136  1 String relName = that.getName().getText();
 137  1 String innerClassName = getQualifiedClassName(_enclosing.getName()) + '.' + relName;
 138  1 handleInnerInterfaceDef(that, _enclosing, relName, innerClassName);
 139  1 return null;
 140    }
 141    /** Process a local inner class definition */
 142  2 public Void forInnerClassDef(InnerClassDef that) {
 143    // System.err.println("CBIV.forInnerClassDef called on " + that.getName());
 144  2 String relName = that.getName().getText();
 145  2 String innerClassName = getQualifiedClassName(_enclosing.getName()) + '.' + relName;
 146  2 handleInnerClassDef(that, _enclosing, relName, innerClassName);
 147  2 return null;
 148    }
 149   
 150    /** Creates a method data corresponding to this method declaration, and then visit the concrete method def with a new
 151    * bodybody visitor, passing it the enclosing method data. Methods are still public by default, but this can be
 152    * overridden by the user. Make sure the method name is different from the class name.
 153    */
 154  105 public Void forConcreteMethodDef(ConcreteMethodDef that) {
 155  105 forConcreteMethodDefDoFirst(that);
 156  1 if (prune(that)) return null;
 157  104 MethodData md = createMethodData(that, _enclosing);
 158   
 159    // At Intermediate Level, methods are still public by default.
 160  104 if (! md.hasModifier("public") && ! md.hasModifier("private") && ! md.hasModifier("protected")) {
 161  74 md.addModifier("public");
 162    }
 163   
 164  104 String className = getUnqualifiedClassName(_enclosing.getName());
 165  104 if (className.equals(md.getName())) {
 166  1 _addAndIgnoreError("Only constructors can have the same name as the class they appear in, and constructors do "
 167    + "not have an explicit return type",
 168    that);
 169    }
 170  103 else _enclosing.addMethod(md);
 171   
 172  104 that.getBody().visit(new BodyBodyIntermediateVisitor(md, _file, _package, _enclosingClassName, _importedFiles,
 173    _importedPackages, _classesInThisFile, continuations,
 174    fixUps, new HashSet<String>()));
 175  104 return forConcreteMethodDefOnly(that);
 176    }
 177   
 178    /** Create a method data corresponding to this method declaration.
 179    * Make sure the method name is different from the class name.
 180    * At the Intermediate Level, methods are public by default, but this can be overridden by the user.
 181    */
 182  6 public Void forAbstractMethodDef(AbstractMethodDef that) {
 183  6 forAbstractMethodDefDoFirst(that);
 184  1 if (prune(that)) return null;
 185  5 MethodData md = createMethodData(that, _enclosing);
 186   
 187    // At Intermediate Level, methods are still public by default.
 188  5 if (! md.hasModifier("public") && ! md.hasModifier("private") && ! md.hasModifier("protected")) {
 189  5 md.addModifier("public");
 190    }
 191   
 192  5 String className = getUnqualifiedClassName(_enclosing.getName());
 193  5 if (className.equals(md.getName())) {
 194  1 _addAndIgnoreError("Only constructors can have the same name as the class they appear in, and constructors do "
 195    + "not have an explicit return type",
 196    that);
 197    }
 198  4 else _enclosing.addMethod(md);
 199   
 200  5 return forAbstractMethodDefOnly(that);
 201    }
 202   
 203    /** Create a constructor corresponding to the specifications in the ConstructorDef. */
 204  18 public Void forConstructorDef(ConstructorDef that) {
 205  18 forConstructorDefDoFirst(that);
 206  0 if (prune(that)) return null;
 207   
 208  18 that.getMav().visit(this);
 209  18 String name = getUnqualifiedClassName(that.getName().getText());
 210  18 if (! name.equals(getUnqualifiedClassName(_enclosing.getName()))) {
 211  1 _addAndIgnoreError("The constructor return type and class name must match", that);
 212    }
 213   
 214    // Turn the thrown exceptions from a ReferenceType[] to a String[]
 215  18 String[] throwStrings = referenceType2String(that.getThrows());
 216   
 217  18 SymbolData returnType = _enclosing;
 218  18 MethodData md = new MethodData(name, that.getMav(), new TypeParameter[0], returnType,
 219    new VariableData[0], throwStrings, _enclosing, that); // VariableData is dummy
 220   
 221    // At Intermediate Level, constructors are still public by default.
 222  18 if (! md.hasModifier("public") && ! md.hasModifier("private") && ! md.hasModifier("protected")) {
 223  10 md.addModifier("public");
 224    }
 225   
 226  18 _checkError(); // reset check flag
 227   
 228    // Turn the parameters from a FormalParameterList to a VariableData[]
 229  18 VariableData[] vds = formalParameters2VariableData(that.getParameters(), _enclosing);
 230  18 if (! _checkError()) { // if there was an error converting the formalParameters, don't use them.
 231  18 md.setParams(vds);
 232  18 if (! md.addFinalVars(vds)) {
 233  1 _addAndIgnoreError("You cannot have two method parameters with the same name", that);
 234    }
 235    }
 236   
 237  18 _enclosing.addMethod(md);
 238  18 that.getStatements().visit(new BodyBodyIntermediateVisitor(md, _file, _package, _enclosingClassName, _importedFiles,
 239    _importedPackages, _classesInThisFile, continuations,
 240    fixUps, new HashSet<String>()));
 241    //note that we have seen a constructor.
 242  18 _enclosing.incrementConstructorCount();
 243  18 return forConstructorDefOnly(that);
 244    }
 245   
 246    /** Delegate to method in LLV. */
 247  0 public Void forComplexAnonymousClassInstantiation(ComplexAnonymousClassInstantiation that) {
 248  0 complexAnonymousClassInstantiationHelper(that, _enclosing); // TODO: the wrong enclosing context?
 249  0 return null;
 250    }
 251   
 252    /** Delegate to method in LLV. */
 253  2 public Void forSimpleAnonymousClassInstantiation(SimpleAnonymousClassInstantiation that) {
 254  2 simpleAnonymousClassInstantiationHelper(that, _enclosing);
 255  2 return null;
 256    }
 257   
 258    // /** Check for problems with modifiers that are specific to method definitions. */
 259    // public Void forModifiersAndVisibilityDoFirst(ModifiersAndVisibility that) {
 260    // String[] modifiers = that.getModifiers();
 261    // if (Utilities.isAbstract(modifiers) && Utilities.isStatic(modifiers)) _badModifiers("static", "abstract", that);
 262    // return super.forModifiersAndVisibilityDoFirst(that);
 263    // }
 264   
 265    /** Test the methods in the above (enclosing) class. */
 266    public static class ClassBodyIntermediateVisitorTest extends TestCase {
 267   
 268    private ClassBodyIntermediateVisitor _cbiv;
 269   
 270    private SymbolData _sd1;
 271    private ModifiersAndVisibility _publicMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"public"});
 272    private ModifiersAndVisibility _publicFinalMav =
 273    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"public", "final"});
 274    private ModifiersAndVisibility _protectedMav =
 275    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"protected"});
 276    private ModifiersAndVisibility _privateMav =
 277    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"private"});
 278    private ModifiersAndVisibility _packageMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[0]);
 279    private ModifiersAndVisibility _abstractMav =
 280    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"abstract"});
 281    private ModifiersAndVisibility _finalMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"final"});
 282    private ModifiersAndVisibility _staticMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"static"});
 283    private ModifiersAndVisibility _abstractStaticMav =
 284    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"abstract", "static"});
 285    private ModifiersAndVisibility _privateAbstractMav =
 286    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"private", "abstract"});
 287    private ModifiersAndVisibility _staticFinalMav =
 288    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"static", "final"});
 289    private ModifiersAndVisibility _finalStaticMav =
 290    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"final", "static"});
 291    private ModifiersAndVisibility _finalPrivateMav =
 292    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"final", "private"});
 293    private ModifiersAndVisibility _privateFinalMav =
 294    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"private", "final"});
 295   
 296   
 297  0 public ClassBodyIntermediateVisitorTest() { this(""); }
 298  10 public ClassBodyIntermediateVisitorTest(String name) { super(name); }
 299   
 300  10 public void setUp() {
 301  10 _sd1 = new SymbolData("i.like.monkey");
 302   
 303  10 errors = new LinkedList<Pair<String, JExpressionIF>>();
 304  10 LanguageLevelConverter.symbolTable.clear();
 305  10 LanguageLevelConverter._newSDs.clear();
 306  10 LanguageLevelConverter.symbolTable.put("i.like.monkey", _sd1);
 307  10 visitedFiles = new LinkedList<Pair<LanguageLevelVisitor, edu.rice.cs.javalanglevels.tree.SourceFile>>();
 308    // _hierarchy = new Hashtable<String, TypeDefBase>();
 309  10 _cbiv = new ClassBodyIntermediateVisitor(_sd1,
 310    _sd1.getName(),
 311    new File(""),
 312    "",
 313    new LinkedList<String>(),
 314    new LinkedList<String>(),
 315    new HashSet<String>(),
 316    new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>(),
 317    new LinkedList<Command>());
 318  10 _cbiv.continuations = new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>(); // no _sd1
 319  10 _cbiv._classesInThisFile = new HashSet<String>();
 320    // _cbiv._resetNonStaticFields();
 321  10 _cbiv._importedPackages.addFirst("java.lang");
 322  10 _errorAdded = false;
 323    }
 324   
 325  1 public void testForConcreteMethodDefDoFirst() {
 326    // Check one that works
 327  1 ConcreteMethodDef cmd = new ConcreteMethodDef(SourceInfo.NONE,
 328    _privateMav,
 329    new TypeParameter[0],
 330    new PrimitiveType(SourceInfo.NONE, "int"),
 331    new Word(SourceInfo.NONE, "methodName"),
 332    new FormalParameter[0],
 333    new ReferenceType[0],
 334    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 335  1 cmd.visit(_cbiv);
 336  1 assertEquals("There should not be any errors", 0, errors.size());
 337   
 338   
 339   
 340    // Check one that doesn't work because it is declared abstract but is actually a concrete method
 341  1 ConcreteMethodDef cmd2 = new ConcreteMethodDef(SourceInfo.NONE,
 342    _abstractMav,
 343    new TypeParameter[0],
 344    new PrimitiveType(SourceInfo.NONE, "double"),
 345    new Word(SourceInfo.NONE, "methodName"),
 346    new FormalParameter[0],
 347    new ReferenceType[0],
 348    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 349  1 cmd2.visit(_cbiv);
 350  1 assertEquals("There should be one error", 1, errors.size());
 351  1 assertEquals("The error message should be correct",
 352    "Methods that have a braced body cannot be declared \"abstract\"",
 353    errors.get(0).getFirst());
 354   
 355    // // Check one that doesn't work because it is static
 356    // ConcreteMethodDef cmd3 = new ConcreteMethodDef(SourceInfo.NONE,
 357    // _staticMav,
 358    // new TypeParameter[0],
 359    // new PrimitiveType(SourceInfo.NONE, "double"),
 360    // new Word(SourceInfo.NONE, "methodName"),
 361    // new FormalParameter[0],
 362    // new ReferenceType[0],
 363    // new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 364    // cmd3.visit(_cbiv);
 365    // assertEquals("There should be two errors", 2, errors.size());
 366    // assertEquals("The error message should be correct",
 367    // "Static methods cannot be used at the Intermediate level",
 368    // errors.get(1).getFirst());
 369    //
 370   
 371    }
 372   
 373  1 public void testForAbstractMethodDefDoFirst() {
 374    // Check one that doesn't work
 375  1 AbstractMethodDef amd = new AbstractMethodDef(SourceInfo.NONE,
 376    _abstractMav,
 377    new TypeParameter[0],
 378    new PrimitiveType(SourceInfo.NONE, "int"),
 379    new Word(SourceInfo.NONE, "methodName"),
 380    new FormalParameter[0],
 381    new ReferenceType[0]);
 382  1 amd.visit(_cbiv);
 383  1 assertEquals("There should be one error.", 1, errors.size());
 384  1 assertEquals("The error message should be correct.", "Abstract methods can only be declared in abstract classes",
 385    errors.get(0).getFirst());
 386   
 387    // Check one that works
 388  1 _cbiv._enclosing.setMav(_abstractMav);
 389  1 AbstractMethodDef amd2 = new AbstractMethodDef(SourceInfo.NONE,
 390    _abstractMav,
 391    new TypeParameter[0],
 392    new PrimitiveType(SourceInfo.NONE, "double"),
 393    new Word(SourceInfo.NONE, "methodName"),
 394    new FormalParameter[0],
 395    new ReferenceType[0]);
 396  1 amd2.visit(_cbiv);
 397  1 assertEquals("There should still be one error", 1, errors.size());
 398   
 399    // // Check one that doesn't work because it is static
 400    // AbstractMethodDef amd3 = new AbstractMethodDef(SourceInfo.NONE,
 401    // _abstractStaticMav,
 402    // new TypeParameter[0],
 403    // new PrimitiveType(SourceInfo.NONE, "double"),
 404    // new Word(SourceInfo.NONE, "methodName"),
 405    // new FormalParameter[0],
 406    // new ReferenceType[0]);
 407    // amd3.visit(_cbiv);
 408    // assertEquals("There should be two errors", 2, errors.size());
 409    // assertEquals("The error message should be correct", "Static methods cannot be used at the Intermediate level",
 410    // errors.get(1).getFirst());
 411    }
 412   
 413  1 public void testForInstanceInitializerDoFirst() {
 414  1 InstanceInitializer ii = new InstanceInitializer(SourceInfo.NONE,
 415    new Block(SourceInfo.NONE,
 416    new BracedBody(SourceInfo.NONE, new BodyItemI[0])));
 417  1 ii.visit(_cbiv);
 418  1 assertEquals("There should be one error.", 1, errors.size());
 419  1 assertEquals("The error message should be correct.",
 420    "This open brace must mark the beginning of a method or class body",
 421    errors.get(0).getFirst());
 422    }
 423   
 424    /* These test is shared with BodyIntermediateVisitor,
 425    * perhaps we could factor it out. */
 426   
 427  1 public void testForVariableDeclarationOnly() {
 428    // Check one that works
 429  1 VariableDeclaration vdecl = new VariableDeclaration(SourceInfo.NONE,
 430    _packageMav,
 431    new VariableDeclarator[] {
 432    new UninitializedVariableDeclarator(SourceInfo.NONE,
 433    new PrimitiveType(SourceInfo.NONE, "double"),
 434    new Word (SourceInfo.NONE, "field1")),
 435    new UninitializedVariableDeclarator(SourceInfo.NONE,
 436    new PrimitiveType(SourceInfo.NONE, "boolean"),
 437    new Word (SourceInfo.NONE, "field2"))});
 438  1 VariableData vd1 =
 439    new VariableData("field1", _privateFinalMav, SymbolData.DOUBLE_TYPE, false, _cbiv._enclosing);
 440  1 VariableData vd2 =
 441    new VariableData("field2", _privateFinalMav, SymbolData.BOOLEAN_TYPE, false, _cbiv._enclosing);
 442  1 vdecl.visit(_cbiv);
 443   
 444    // VariableData vd0 = _sd1.getVars().get(0);
 445    // System.err.println("Errors were: " + errors);
 446  1 assertEquals("There should not be any errors.", 0, errors.size());
 447    // System.err.println("_sd1.getVars() = " + _sd1.getVars());
 448    //
 449    // System.err.println("vd1 = " + vd1);
 450    // System.err.println("vd1.getMav() = " + vd1.getMav());
 451    // System.err.println("vd1.getType() = " + vd1.getType());
 452    // System.err.println("vd1.getMav().getModifiers() = " + vd1.getMav().getModifiers());
 453    // assertEquals("enclosingData are equal", vd1.getEnclosingData(), vd0.getEnclosingData());
 454    // assertEquals("mavs are equal", vd1.getMav(), vd0.getMav());
 455    // assertEquals("vd1.equals(vd0)", vd1, vd0);
 456   
 457    // System.err.println("_sd1 vars = " + _sd1.getVars());
 458    // System.err.println("vd1 = " + vd1 + "; vd2 = " + vd2);
 459  1 assertTrue("field1 was added.", _sd1.getVars().contains(vd1));
 460  1 assertTrue("field2 was added.", _sd1.getVars().contains(vd2));
 461   
 462    //TODO: Test that static fields are made public
 463   
 464    // Check one that doesn't work
 465  1 VariableDeclaration vdecl2 = new VariableDeclaration(SourceInfo.NONE,
 466    _packageMav,
 467    new VariableDeclarator[] {
 468    new UninitializedVariableDeclarator(SourceInfo.NONE,
 469    new PrimitiveType(SourceInfo.NONE, "double"),
 470    new Word (SourceInfo.NONE, "field3")),
 471    new UninitializedVariableDeclarator(SourceInfo.NONE,
 472    new PrimitiveType(SourceInfo.NONE, "int"),
 473    new Word (SourceInfo.NONE, "field3"))});
 474  1 VariableData vd3 =
 475    new VariableData("field3", _privateFinalMav, SymbolData.DOUBLE_TYPE, false, _cbiv._enclosing);
 476  1 vdecl2.visit(_cbiv);
 477  1 assertEquals("There should be one error.", 1, errors.size());
 478  1 assertEquals("The error message should be correct",
 479    "You cannot have two fields with the same name. Either you already have a field by that name in "
 480    + "this class, or one of your superclasses or interfaces has a field by that name",
 481    errors.get(0).getFirst());
 482    // System.err.println("_sd1 vars = " + _sd1.getVars());
 483    // System.err.println("vd3 = " + vd3);
 484  1 assertTrue("field3 was added.", _sd1.getVars().contains(vd3));
 485   
 486    //Check a static field that has not been assigned is an error
 487  1 VariableDeclaration vdecl3 = new VariableDeclaration(SourceInfo.NONE,
 488    _staticMav,
 489    new VariableDeclarator[] {
 490    new UninitializedVariableDeclarator(SourceInfo.NONE,
 491    new PrimitiveType(SourceInfo.NONE, "double"),
 492    new Word (SourceInfo.NONE, "field4"))});
 493  1 VariableData vd4 =
 494    new VariableData("field4", _staticFinalMav, SymbolData.DOUBLE_TYPE, false, _cbiv._enclosing);
 495   
 496  1 vdecl3.visit(_cbiv);
 497    // System.err.println("vd4 = " + vd4);;
 498    // assertEquals("There should still be one error", 1, errors.size());
 499  1 assertEquals("The error message should be correct", "All static fields must be initialized",
 500    errors.get(1).getFirst());
 501    // System.err.println("_sd1 vars = " + _sd1.getVars());
 502  1 assertTrue("field4 was added.", _sd1.getVars().contains(vd4));
 503   
 504    // Check a non-static field that has been assigned.
 505  1 VariableDeclaration vdecl5 = new VariableDeclaration(SourceInfo.NONE,
 506    _packageMav,
 507    new VariableDeclarator[] {
 508    new InitializedVariableDeclarator(SourceInfo.NONE,
 509    new PrimitiveType(SourceInfo.NONE, "double"),
 510    new Word (SourceInfo.NONE, "field5"),
 511    new DoubleLiteral(SourceInfo.NONE, 2.4))});
 512  1 vdecl5.visit(_cbiv);
 513  1 VariableData vd5 =
 514    new VariableData("field5", _privateFinalMav, SymbolData.DOUBLE_TYPE, true, _cbiv._enclosing);
 515  1 vd5.setHasInitializer(true);
 516    // VariableData vd0 = _sd1.getVars().get(4);
 517    // System.err.println("vd5 = " + vd5);
 518    // System.err.println("vd0 = " + vd0);
 519    // System.err.println("vd5.getMav() = " + vd5.getMav());
 520    // System.err.println("vd5.getType() = " + vd5.getType());
 521    // System.err.println("vd0.getMav() = " + vd0.getMav());
 522    // System.err.println("vd0.getType() = " + vd0.getType());
 523    // assertEquals("mavs are equal", vd5.getMav(), vd0.getMav());
 524    // assertEquals("enclosingData are equal", vd5.getEnclosingData(), vd0.getEnclosingData());
 525    // assertEquals("vd5.equals(vd0)", vd5, vd0);
 526  1 assertTrue("Field 5 was added.", _sd1.getVars().contains(vd5));
 527   
 528    // Check one that overrides the super class's field
 529  1 VariableDeclaration vdecl6 = new VariableDeclaration(SourceInfo.NONE,
 530    _packageMav,
 531    new VariableDeclarator[] {
 532    new UninitializedVariableDeclarator(SourceInfo.NONE,
 533    new PrimitiveType(SourceInfo.NONE, "double"),
 534    new Word (SourceInfo.NONE, "field6"))});
 535   
 536   
 537  1 VariableData vd6 =
 538    new VariableData("field6", _finalPrivateMav, SymbolData.DOUBLE_TYPE, false, _cbiv._enclosing);
 539  1 SymbolData myData = new SymbolData("myData");
 540  1 myData.addVar(vd6);
 541  1 _cbiv._enclosing.setSuperClass(myData);
 542  1 vdecl6.visit(_cbiv);
 543  1 assertEquals("There should be three errors.", 3, errors.size());
 544  1 assertEquals("The error message should be correct", "You cannot have two fields with the same name. Either you" +
 545    " already have a field by that name in this class, or one of your superclasses or interfaces has a" +
 546    " field by that name",
 547    errors.getLast().getFirst());
 548   
 549    }
 550   
 551  1 public void testFormalParameters2VariableData() {
 552  1 FormalParameter[] fps = new FormalParameter[] {
 553    new FormalParameter(SourceInfo.NONE,
 554    new UninitializedVariableDeclarator(SourceInfo.NONE,
 555    new PrimitiveType(SourceInfo.NONE, "double"),
 556    new Word (SourceInfo.NONE, "field1")),
 557    false),
 558    new FormalParameter(SourceInfo.NONE,
 559    new UninitializedVariableDeclarator(SourceInfo.NONE,
 560    new PrimitiveType(SourceInfo.NONE, "boolean"),
 561    new Word (SourceInfo.NONE, "field2")),
 562    false)};
 563   
 564  1 MethodData md = new MethodData("methodName",
 565    _packageMav,
 566    new TypeParameter[0],
 567    SymbolData.INT_TYPE,
 568    new VariableData[0], // a dummy value
 569    new String[0],
 570    _sd1, // enclosing class
 571    null); // no SourceInfo
 572  1 VariableData vd1 = new VariableData("field1", _finalMav, SymbolData.DOUBLE_TYPE, true, _sd1);
 573  1 VariableData vd2 = new VariableData("field2", _finalMav, SymbolData.BOOLEAN_TYPE, true, _sd1);
 574    // System.err.println("vd1 = " + vd1);
 575    // System.err.println("vd2 = " + vd2);
 576  1 VariableData[] vds = _cbiv.formalParameters2VariableData(fps, _sd1);
 577  1 assertEquals("There should not be any errors.", 0, errors.size());
 578    // System.err.println("vds[0] = " + vds[0]);
 579    // System.err.println("vds[1] = " + vds[1]);
 580  1 assertEquals("vd1 should be the first entry in vds.", vd1, vds[0]);
 581  1 assertEquals("vd2 should be the second entry in vds.", vd2, vds[1]);
 582    }
 583   
 584   
 585   
 586   
 587   
 588  1 public void testForConcreteMethodDef() {
 589    // Test one that works.
 590  1 MethodDef mdef = new ConcreteMethodDef(SourceInfo.NONE,
 591    _privateMav,
 592    new TypeParameter[0],
 593    new PrimitiveType(SourceInfo.NONE, "int"),
 594    new Word(SourceInfo.NONE, "methodName"),
 595    new FormalParameter[0],
 596    new ReferenceType[0],
 597    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 598  1 mdef.visit(_cbiv);
 599  1 assertEquals("There should not be any errors.", 0, errors.size());
 600   
 601   
 602    //Check one that works but needs to be augmented with public
 603  1 ConcreteMethodDef cmd1 = new ConcreteMethodDef(SourceInfo.NONE,
 604    _packageMav,
 605    new TypeParameter[0],
 606    new PrimitiveType(SourceInfo.NONE, "int"),
 607    new Word(SourceInfo.NONE, "noMavMethod"),
 608    new FormalParameter[0],
 609    new ReferenceType[0],
 610    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 611   
 612  1 cmd1.visit(_cbiv);
 613  1 assertEquals("There should not be any errors", 0, errors.size());
 614  1 assertEquals("_sd1 should contain 2 methods", 2, _sd1.getMethods().size());
 615  1 assertTrue("The second method should be default public", _sd1.getMethods().get(1).hasModifier("public"));
 616   
 617   
 618   
 619    // Test one that doesn't work.
 620  1 mdef = new ConcreteMethodDef(SourceInfo.NONE,
 621    _packageMav,
 622    new TypeParameter[0],
 623    new PrimitiveType(SourceInfo.NONE, "int"),
 624    new Word(SourceInfo.NONE, "monkey"),
 625    new FormalParameter[0],
 626    new ReferenceType[0],
 627    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 628  1 mdef.visit(_cbiv);
 629  1 assertEquals("There should be one error.", 1, errors.size());
 630  1 assertEquals("The error message should be correct.",
 631    "Only constructors can have the same name as the class they appear in, and constructors do not "
 632    + "have an explicit return type",
 633    errors.get(0).getFirst());
 634    }
 635   
 636  1 public void testForAbstractMethodDef() {
 637    // Test one that works but needs to be augmented with public.
 638  1 MethodDef mdef = new AbstractMethodDef(SourceInfo.NONE,
 639    _abstractMav,
 640    new TypeParameter[0],
 641    new PrimitiveType(SourceInfo.NONE, "int"),
 642    new Word(SourceInfo.NONE, "methodName"),
 643    new FormalParameter[0],
 644    new ReferenceType[0]);
 645  1 _cbiv._enclosing.setMav(_abstractMav);
 646   
 647  1 mdef.visit(_cbiv);
 648  1 assertEquals("There should not be any errors", 0, errors.size());
 649  1 assertEquals("_sd1 should contain 1 methods", 1, _sd1.getMethods().size());
 650  1 assertTrue("The method should be default public", _sd1.getMethods().getFirst().hasModifier("public"));
 651   
 652   
 653   
 654   
 655    // Test one that doesn't work.
 656  1 mdef = new AbstractMethodDef(SourceInfo.NONE,
 657    _abstractMav,
 658    new TypeParameter[0],
 659    new PrimitiveType(SourceInfo.NONE, "int"),
 660    new Word(SourceInfo.NONE, "monkey"),
 661    new FormalParameter[0],
 662    new ReferenceType[0]);
 663  1 mdef.visit(_cbiv);
 664  1 assertEquals("There should be one error.", 1, errors.size());
 665  1 assertEquals("The error message should be correct.",
 666    "Only constructors can have the same name as the class they appear in, " +
 667    "and constructors do not have an explicit return type",
 668    errors.get(0).getFirst());
 669    }
 670   
 671    /* These test is shared with BodyIntermediateVisitor,
 672    * perhaps we could factor it out. */
 673   
 674    // public void testForOtherExpressionOnly() {
 675    // // Test that if the OtherExpression contains a Word, that the Word is resolved.
 676    // assertFalse("java.lang.System should not be in the symbolTable.", symbolTable.containsKey("java.lang.System"));
 677    // Expression ex = new Expression( SourceInfo.NONE,
 678    // new ExpressionPiece[] { new OtherExpression(SourceInfo.NONE,
 679    // new Word(SourceInfo.NONE,
 680    // "System"))});
 681    // ex.visit(_cbiv);
 682    // assertEquals("There should not be any errors.", 0, errors.size());
 683    // assertTrue("java.lang.System should be in the symbolTable.", symbolTable.containsKey("java.lang.System"));
 684    // }
 685   
 686  1 public void testForInitializedVariableDeclaratorDoFirst() {
 687  1 InitializedVariableDeclarator ivd =
 688    new InitializedVariableDeclarator(SourceInfo.NONE,
 689    new PrimitiveType(SourceInfo.NONE, "int"),
 690    new Word(SourceInfo.NONE, "i"),
 691    new IntegerLiteral(SourceInfo.NONE, 5));
 692   
 693  1 ivd.visit(_cbiv);
 694   
 695  1 assertEquals("There should be no errors now", 0, errors.size());
 696    // assertEquals("Error message should be correct",
 697    // "Cannot initialize a class's fields at the Intermediate level. To set the value of a field, when" +
 698    // "you instantiate the class, assign the desired value using the class's constructor",
 699    // errors.get(0).getFirst());
 700    }
 701   
 702   
 703  1 public void testForInnerInterfaceDef() {
 704  1 InnerInterfaceDef cd1 = new InnerInterfaceDef(SourceInfo.NONE, _packageMav,
 705    new Word(SourceInfo.NONE, "Bart"),
 706    new TypeParameter[0], new ReferenceType[0],
 707    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 708   
 709  1 InnerInterfaceDef cd0 = new InnerInterfaceDef(SourceInfo.NONE, _packageMav,
 710    new Word(SourceInfo.NONE, "Lisa"),
 711    new TypeParameter[0], new ReferenceType[0],
 712    new BracedBody(SourceInfo.NONE, new BodyItemI[] {cd1}));
 713   
 714  1 SymbolData sd0 = new SymbolData(_cbiv._enclosing.getName() + "$Lisa", _packageMav, new TypeParameter[0],
 715    new ArrayList<SymbolData>(), null);
 716  1 SymbolData sd1 = new SymbolData(_cbiv._enclosing.getName() + "$Lisa$Bart", _packageMav, new TypeParameter[0],
 717    new ArrayList<SymbolData>(), null);
 718  1 sd0.addInnerInterface(sd1);
 719  1 sd0.setIsContinuation(true);
 720  1 sd1.setIsContinuation(true);
 721   
 722  1 LanguageLevelConverter.symbolTable.put(_cbiv._enclosing.getName() + "$Lisa", sd0);
 723  1 LanguageLevelConverter.symbolTable.put(_cbiv._enclosing.getName() + "$Lisa$Bart", sd1);
 724   
 725  1 cd0.visit(_cbiv);
 726   
 727  1 SymbolData sd = _cbiv._enclosing.getInnerClassOrInterface("Lisa");
 728   
 729    // NOTE: No longer allowing inner interfaces at the intermediate level
 730  1 assertEquals("There should be no errors", 0, errors.size());
 731    // Nested interfaces now work
 732    }
 733   
 734  1 public void testForConstructorDef() {
 735    //this is a ConstructorDef with no formal parameters and no throws
 736  1 ConstructorDef cd = new ConstructorDef(SourceInfo.NONE,
 737    new Word(SourceInfo.NONE, "MyClass"), _publicMav,
 738    new FormalParameter[0], new ReferenceType[0],
 739    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 740   
 741    //What if constructor name and SymbolData name don't match? Should throw an error.
 742  1 _cbiv._enclosing = new SymbolData("NotRightName");
 743  1 cd.visit(_cbiv);
 744  1 assertEquals("Should be 1 error", 1, errors.size());
 745  1 assertEquals("Error message should be correct",
 746    "The constructor return type and class name must match", errors.getLast().getFirst());
 747   
 748    //If they are the same, it should work just fine.
 749  1 _cbiv._enclosing = new SymbolData("MyClass");
 750   
 751  1 MethodData constructor = new MethodData("MyClass", _publicMav, new TypeParameter[0], _cbiv._enclosing,
 752    new VariableData[0],
 753    new String[0],
 754    _cbiv._enclosing,
 755    null);
 756   
 757   
 758  1 cd.visit(_cbiv);
 759   
 760   
 761  1 assertEquals("Should still be 1 error", 1, errors.size());
 762  1 assertEquals("SymbolData should have 1 method", 1, _cbiv._enclosing.getMethods().size());
 763  1 assertTrue("SymbolData's constructor should be correct", _cbiv._enclosing.getMethods().contains(constructor));
 764   
 765    //With a ConstructorDef with more throws and variables, should work okay.
 766  1 FormalParameter fp =
 767    new FormalParameter(SourceInfo.NONE,
 768    new UninitializedVariableDeclarator(SourceInfo.NONE,
 769    new PrimitiveType(SourceInfo.NONE, "int"),
 770    new Word(SourceInfo.NONE, "i")), false);
 771  1 ReferenceType rt = new TypeVariable(SourceInfo.NONE, "MyMadeUpException");
 772  1 ConstructorDef cd2 = new ConstructorDef(SourceInfo.NONE,
 773    new Word(SourceInfo.NONE, "MyClass"),
 774    _publicMav,
 775    new FormalParameter[] {fp},
 776    new ReferenceType[] {rt},
 777    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 778   
 779  1 VariableData vd = new VariableData("i", _finalMav, SymbolData.INT_TYPE, true, _cbiv._enclosing);
 780  1 MethodData constructor2 = new MethodData("MyClass",
 781    _publicMav,
 782    new TypeParameter[0],
 783    _cbiv._enclosing,
 784    new VariableData[] {vd},
 785    new String[] {"MyMadeUpException"},
 786    _cbiv._enclosing,
 787    null);
 788   
 789   
 790  1 constructor2.addVar(vd);
 791  1 cd2.visit(_cbiv);
 792    // vd.setEnclosingData(_cbiv._enclosing.getMethods().getLast());
 793  1 assertEquals("Should still be 1 error", 1, errors.size());
 794  1 assertEquals("SymbolData should have 2 methods", 2, _cbiv._enclosing.getMethods().size());
 795   
 796  1 assertTrue("SymbolData should have new constructor", _cbiv._enclosing.getMethods().contains(constructor2));
 797   
 798   
 799    //If two variable names are duplicated, should throw an error.
 800  1 FormalParameter fp2 =
 801    new FormalParameter(SourceInfo.NONE,
 802    new UninitializedVariableDeclarator(SourceInfo.NONE,
 803    new PrimitiveType(SourceInfo.NONE, "double"),
 804    new Word(SourceInfo.NONE, "i")), false);
 805   
 806  1 ConstructorDef cd3 = new ConstructorDef(SourceInfo.NONE,
 807    new Word(SourceInfo.NONE, "MyClass"), _publicMav,
 808    new FormalParameter[] {fp, fp2}, new ReferenceType[] {rt},
 809    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 810  1 cd3.visit(_cbiv);
 811   
 812  1 assertEquals("Should now be 2 errors", 2, errors.size());
 813  1 assertEquals("Error message should be correct", "You cannot have two method parameters with the same name",
 814    errors.getLast().getFirst());
 815    }
 816    }
 817    }