Clover coverage report - Java Language Levels Test Coverage (javalanglevels-20120305-r5436)
Coverage timestamp: Sun Mar 4 2012 22:02:46 CST
file stats: LOC: 394   Methods: 25
NCLOC: 262   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
InterfaceBodyIntermediateVisitor.java 70% 89.7% 80% 86.8%
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.plt.reflect.JavaVersion;
 42    import edu.rice.cs.plt.iter.IterUtil;
 43    import java.util.*;
 44    import java.io.*;
 45   
 46    import junit.framework.TestCase;
 47   
 48    /** Language Level Visitor that represents the Intermediate Language Level. Enforces constraints during the first walk of
 49    * the AST (checking for langauge specific errors and building the symbol table). This class enforces things that are
 50    * common to all contexts reachable within an interface body at the Intermediate Language Level.
 51    */
 52    public class InterfaceBodyIntermediateVisitor extends IntermediateVisitor {
 53   
 54    /**The SymbolData corresponding to this interface.*/
 55    private SymbolData _enclosing;
 56   
 57    /** Constructor for InterfaceBodyIntermediateVisitor.
 58    * @param sd The SymbolData that encloses the context we are visiting.
 59    * @param file The source file this came from.
 60    * @param packageName The package the source file is in
 61    * @importedFiles A list of classes that were specifically imported
 62    * @param importedPackages A list of package names that were specifically imported
 63    * @param classesInThisFile A list of the classes that are yet to be defined in this source file
 64    * @param continuations A hashtable corresponding to the continuations (unresolved Symbol Datas) that will need to be resolved
 65    */
 66  22 public InterfaceBodyIntermediateVisitor(SymbolData sd,
 67    File file,
 68    String packageName,
 69    LinkedList<String> importedFiles,
 70    LinkedList<String> importedPackages,
 71    HashSet<String> classesInThisFile,
 72    Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>> continuations,
 73    LinkedList<Command> fixUps) {
 74  22 super(file, packageName, sd.getName(), importedFiles, importedPackages, classesInThisFile, continuations, fixUps);
 75  22 _enclosing = sd;
 76    }
 77   
 78    /*Throw an appropriate error*/
 79  0 public Void forStatementDoFirst(Statement that) {
 80  0 _addError("Statements cannot appear outside of method bodies", that);
 81  0 return null;
 82    }
 83   
 84    /*Throw an appropriate error*/
 85  1 public Void forConcreteMethodDefDoFirst(ConcreteMethodDef that) {
 86  1 _addError("You cannot have concrete methods definitions in interfaces", that);
 87  1 return null;
 88    }
 89   
 90    /**Throw an appropriate error*/
 91  1 public Void forInstanceInitializerDoFirst(InstanceInitializer that) {
 92  1 _addError("This open brace must mark the beginning of an interface body", that);
 93  1 return null;
 94    }
 95   
 96    /**No fields in interfaces at Intermediate Level. Give an appropriate error.*/
 97  1 public Void forVariableDeclarationDoFirst(VariableDeclaration that) {
 98  1 _addError("You cannot have fields in interfaces at the Intermediate level", that);
 99  1 return null;
 100    }
 101   
 102    /** No super references for interfaces--give an appropriate error.*/
 103  2 public Void forSuperReferenceDoFirst(SuperReference that) {
 104  2 _addAndIgnoreError("The field 'super' does not exist in interfaces. Only classes have a 'super' field", that);
 105  2 return null;
 106    }
 107   
 108    /**No This literal in interfaces--give an appropriate error*/
 109  2 public Void forThisReferenceDoFirst(ThisReference that) {
 110  2 _addAndIgnoreError("The field 'this' does not exist in interfaces. Only classes have a 'this' field.", that);
 111  2 return null;
 112    }
 113   
 114    /* Make sure that the method is not declared to be private or protected. Make it public and abstract
 115    * if it is not already declared to be so (since this is the default in the absence of modifiers).
 116    * Make sure the method name is not the same as the interface name.
 117    */
 118  21 public Void forAbstractMethodDef(AbstractMethodDef that) {
 119  21 forAbstractMethodDefDoFirst(that);
 120  0 if (_checkError()) return null;
 121   
 122  21 MethodData md = createMethodData(that, _enclosing);
 123   
 124    //All interface methods are considered public by default: enforce this.
 125  21 if (md.hasModifier("private")) {
 126  1 _addAndIgnoreError("Interface methods cannot be private. They must be public.", that.getMav());
 127    }
 128  21 if (md.hasModifier("protected")) {
 129  1 _addAndIgnoreError("Interface methods cannot be protected. They must be public.", that.getMav());
 130    }
 131   
 132    // All interface methods are considered public by default.
 133  21 md.addModifier("public");
 134  21 md.addModifier("abstract"); //and all interface methods are abstract.
 135  21 String className = getUnqualifiedClassName(_enclosing.getName());
 136  21 if (className.equals(md.getName())) {
 137  1 _addAndIgnoreError("Only constructors can have the same name as the class they appear in, " +
 138    "and constructors cannot appear in interfaces.", that);
 139    }
 140  20 else _enclosing.addMethod(md);
 141  21 return null;
 142    }
 143   
 144    /** Throw an error: Interfaces cannot have constructors */
 145  1 public Void forConstructorDefDoFirst(ConstructorDef that) {
 146  1 _addAndIgnoreError("Constructor definitions cannot appear in interfaces", that);
 147  1 return null;
 148    }
 149   
 150    /** Processes a static field declaration within an interface. Calls the super method to convert the VariableDeclaration
 151    * to a VariableData array, then makes sure that each VariableData is final and static, as required in an
 152    * interface.
 153    * @param enclosingData The Data immediately enclosing the variables
 154    */
 155  0 protected VariableData[] _variableDeclaration2VariableData(VariableDeclaration vd, Data enclosingData) {
 156  0 VariableData[] vds = super._variableDeclaration2VariableData(vd, enclosingData);
 157  0 for (int i = 0; i < vds.length; i++) {
 158  0 vds[i].setFinalAndStatic();
 159    }
 160  0 return vds;
 161    }
 162   
 163    /** Delegate to method in LLV */
 164  0 public Void forComplexAnonymousClassInstantiation(ComplexAnonymousClassInstantiation that) {
 165  0 complexAnonymousClassInstantiationHelper(that, _enclosing); // TODO: the wrong enclosing context?
 166  0 return null;
 167    }
 168   
 169    /** Delegate to method in LLV */
 170  0 public Void forSimpleAnonymousClassInstantiation(SimpleAnonymousClassInstantiation that) {
 171  0 simpleAnonymousClassInstantiationHelper(that, _enclosing);
 172  0 return null;
 173    }
 174   
 175    /** Test the methods declared in the above class. */
 176    public static class InterfaceBodyIntermediateVisitorTest extends TestCase {
 177   
 178    private InterfaceBodyIntermediateVisitor _ibiv;
 179   
 180    private SymbolData _sd1;
 181    private ModifiersAndVisibility _publicMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"public"});
 182    private ModifiersAndVisibility _protectedMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"protected"});
 183    private ModifiersAndVisibility _privateMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"private"});
 184    private ModifiersAndVisibility _packageMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[0]);
 185    private ModifiersAndVisibility _abstractMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"abstract"});
 186    private ModifiersAndVisibility _finalMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"final"});
 187   
 188   
 189  0 public InterfaceBodyIntermediateVisitorTest() {
 190  0 this("");
 191    }
 192  10 public InterfaceBodyIntermediateVisitorTest(String name) {
 193  10 super(name);
 194    }
 195   
 196  10 public void setUp() {
 197  10 _sd1 = new SymbolData("i.like.monkey");
 198  10 _sd1.setIsContinuation(false);
 199  10 _sd1.setInterface(false);
 200  10 _sd1.setPackage("");
 201  10 _sd1.setTypeParameters(new TypeParameter[0]);
 202  10 _sd1.setInterfaces(new ArrayList<SymbolData>());
 203   
 204  10 errors = new LinkedList<Pair<String, JExpressionIF>>();
 205  10 LanguageLevelConverter.symbolTable.clear();
 206  10 LanguageLevelConverter._newSDs.clear();
 207  10 LanguageLevelConverter.OPT = new Options(JavaVersion.JAVA_5, IterUtil.make(new File("lib/buildlib/junit.jar")));
 208  10 visitedFiles = new LinkedList<Pair<LanguageLevelVisitor, edu.rice.cs.javalanglevels.tree.SourceFile>>();
 209    // _hierarchy = new Hashtable<String, TypeDefBase>();
 210  10 _ibiv =
 211    new InterfaceBodyIntermediateVisitor(_sd1,
 212    new File(""),
 213    "",
 214    new LinkedList<String>(),
 215    new LinkedList<String>(),
 216    new HashSet<String>(),
 217    new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>(),
 218    new LinkedList<Command>());
 219  10 _ibiv._classesInThisFile = new HashSet<String>();
 220  10 _ibiv.continuations = new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>();
 221  10 _ibiv._importedPackages.addFirst("java.lang");
 222  10 _ibiv._enclosingClassName = "i.like.monkey";
 223  10 _ibiv.symbolTable.put("i.like.monkey", _sd1);
 224  10 _errorAdded = false;
 225    }
 226   
 227  1 public void testForConcreteMethodDefDoFirst() {
 228    // Check that an error is thrown
 229  1 ConcreteMethodDef cmd = new ConcreteMethodDef(SourceInfo.NONE,
 230    _publicMav,
 231    new TypeParameter[0],
 232    new PrimitiveType(SourceInfo.NONE, "int"),
 233    new Word(SourceInfo.NONE, "methodName"),
 234    new FormalParameter[0],
 235    new ReferenceType[0],
 236    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 237  1 cmd.visit(_ibiv);
 238  1 assertEquals("There should not be 1 error", 1, errors.size());
 239  1 assertEquals("The error message should be correct", "You cannot have concrete methods definitions in interfaces", errors.getLast().getFirst());
 240   
 241    }
 242   
 243  1 public void testForAbstractMethodDefDoFirst() {
 244    // Check one that works
 245  1 _ibiv._enclosing.setMav(_abstractMav);
 246  1 AbstractMethodDef amd2 = new AbstractMethodDef(SourceInfo.NONE,
 247    _abstractMav,
 248    new TypeParameter[0],
 249    new PrimitiveType(SourceInfo.NONE, "double"),
 250    new Word(SourceInfo.NONE, "methodName"),
 251    new FormalParameter[0],
 252    new ReferenceType[0]);
 253  1 amd2.visit(_ibiv);
 254  1 assertEquals("There should be no errors", 0, errors.size());
 255  1 assertTrue("The method def should be public", _ibiv._enclosing.getMethods().get(0).hasModifier("public"));
 256   
 257    }
 258   
 259  1 public void testForInstanceInitializerDoFirst() {
 260  1 InstanceInitializer ii = new InstanceInitializer(SourceInfo.NONE,
 261    new Block(SourceInfo.NONE,
 262    new BracedBody(SourceInfo.NONE, new BodyItemI[0])));
 263  1 ii.visit(_ibiv);
 264  1 assertEquals("There should be one error.", 1, errors.size());
 265  1 assertEquals("The error message should be correct.", "This open brace must mark the beginning of an interface body", errors.get(0).getFirst());
 266    }
 267   
 268  1 public void testForSimpleThisReferenceDoFirst() {
 269  1 SimpleThisReference tl = new SimpleThisReference(SourceInfo.NONE);
 270  1 tl.visit(_ibiv);
 271  1 assertEquals("There should be one error", 1, errors.size());
 272  1 assertEquals("The error message should be correct", "The field 'this' does not exist in interfaces. Only classes have a 'this' field.", errors.get(0).getFirst());
 273    }
 274   
 275   
 276  1 public void testForComplexThisReferenceDoFirst() {
 277  1 ComplexThisReference tl = new ComplexThisReference(SourceInfo.NONE, new NullLiteral(SourceInfo.NONE));
 278  1 tl.visit(_ibiv);
 279  1 assertEquals("There should be one error", 1, errors.size());
 280  1 assertEquals("The error message should be correct", "The field 'this' does not exist in interfaces. Only classes have a 'this' field.", errors.get(0).getFirst());
 281   
 282    }
 283   
 284  1 public void testForSimpleSuperReferenceDoFirst() {
 285  1 SimpleSuperReference sr = new SimpleSuperReference(SourceInfo.NONE);
 286  1 sr.visit(_ibiv);
 287  1 assertEquals("There should be one error", 1, errors.size());
 288  1 assertEquals("The error message should be correct", "The field 'super' does not exist in interfaces. Only classes have a 'super' field", errors.get(0).getFirst());
 289    }
 290   
 291  1 public void testForComplexSuperReferenceDoFirst() {
 292  1 ComplexSuperReference cr = new ComplexSuperReference(SourceInfo.NONE, new NullLiteral(SourceInfo.NONE));
 293  1 cr.visit(_ibiv);
 294  1 assertEquals("There should be one error", 1, errors.size());
 295  1 assertEquals("The error message should be correct", "The field 'super' does not exist in interfaces. Only classes have a 'super' field", errors.get(0).getFirst());
 296    }
 297   
 298   
 299  1 public void testForVariableDeclarationDoFirst() {
 300    // Check that an error is thrown
 301  1 VariableDeclaration vdecl = new VariableDeclaration(SourceInfo.NONE,
 302    _packageMav,
 303    new VariableDeclarator[] {
 304    new UninitializedVariableDeclarator(SourceInfo.NONE,
 305    new PrimitiveType(SourceInfo.NONE, "double"),
 306    new Word (SourceInfo.NONE, "field1")),
 307    new UninitializedVariableDeclarator(SourceInfo.NONE,
 308    new PrimitiveType(SourceInfo.NONE, "boolean"),
 309    new Word (SourceInfo.NONE, "field2"))});
 310  1 vdecl.visit(_ibiv);
 311  1 assertEquals("There should be one error", 1, errors.size());
 312  1 assertEquals("The error message should be correct", "You cannot have fields in interfaces at the Intermediate level", errors.getLast().getFirst());
 313    }
 314   
 315  1 public void testForAbstractMethodDef() {
 316    // Test one that works.
 317  1 MethodDef mdef = new AbstractMethodDef(SourceInfo.NONE,
 318    _abstractMav,
 319    new TypeParameter[0],
 320    new PrimitiveType(SourceInfo.NONE, "int"),
 321    new Word(SourceInfo.NONE, "methodName"),
 322    new FormalParameter[0],
 323    new ReferenceType[0]);
 324  1 _ibiv._enclosing.setMav(_abstractMav);
 325   
 326  1 mdef.visit(_ibiv);
 327  1 assertEquals("There should not be any errors.", 0, errors.size());
 328   
 329    // Test one that doesn't work.
 330  1 mdef = new AbstractMethodDef(SourceInfo.NONE,
 331    _abstractMav,
 332    new TypeParameter[0],
 333    new PrimitiveType(SourceInfo.NONE, "int"),
 334    new Word(SourceInfo.NONE, "monkey"),
 335    new FormalParameter[0],
 336    new ReferenceType[0]);
 337  1 mdef.visit(_ibiv);
 338  1 assertEquals("There should be one error.", 1, errors.size());
 339  1 assertEquals("The error message should be correct.",
 340    "Only constructors can have the same name as the class they appear in, and constructors cannot appear in interfaces.",
 341    errors.get(0).getFirst());
 342   
 343   
 344    //It's okay for the method to be public
 345  1 AbstractMethodDef amd3 = new AbstractMethodDef(SourceInfo.NONE,
 346    _publicMav,
 347    new TypeParameter[0],
 348    new PrimitiveType(SourceInfo.NONE, "double"),
 349    new Word(SourceInfo.NONE, "methodName2"),
 350    new FormalParameter[0],
 351    new ReferenceType[0]);
 352  1 amd3.visit(_ibiv);
 353  1 assertEquals("There should still be one error", 1, errors.size());
 354  1 assertTrue("The method def should be public", _ibiv._enclosing.getMethods().get(1).hasModifier("public"));
 355   
 356    //What if the method is called private? Should throw error
 357  1 AbstractMethodDef amd4 = new AbstractMethodDef(SourceInfo.NONE,
 358    _privateMav,
 359    new TypeParameter[0],
 360    new PrimitiveType(SourceInfo.NONE, "double"),
 361    new Word(SourceInfo.NONE, "methodName3"),
 362    new FormalParameter[0],
 363    new ReferenceType[0]);
 364  1 amd4.visit(_ibiv);
 365  1 assertEquals("There should be two errors", 2, errors.size());
 366  1 assertEquals("The error message should be correct","Interface methods cannot be private. They must be public." , errors.get(1).getFirst());
 367   
 368    //What if the method is protected: Should throw error
 369  1 AbstractMethodDef amd5 = new AbstractMethodDef(SourceInfo.NONE,
 370    _protectedMav,
 371    new TypeParameter[0],
 372    new PrimitiveType(SourceInfo.NONE, "double"),
 373    new Word(SourceInfo.NONE, "methodName4"),
 374    new FormalParameter[0],
 375    new ReferenceType[0]);
 376  1 amd5.visit(_ibiv);
 377  1 assertEquals("There should be three errors", 3, errors.size());
 378  1 assertEquals("The error message should be correct","Interface methods cannot be protected. They must be public." , errors.get(2).getFirst());
 379    }
 380   
 381   
 382  1 public void testForConstructorDef() {
 383    ///this is a ConstructorDef with no formal paramaters and no throws
 384  1 ConstructorDef cd = new ConstructorDef(SourceInfo.NONE, new Word(SourceInfo.NONE, "MyClass"), _publicMav, new FormalParameter[0], new ReferenceType[0],
 385    new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
 386   
 387    //Check that the appropriate error is thrown.
 388  1 cd.visit(_ibiv);
 389  1 assertEquals("There should now be one error", 1, errors.size());
 390  1 assertEquals("The error message should be correct", "Constructor definitions cannot appear in interfaces", errors.get(0).getFirst());
 391   
 392    }
 393    }
 394    }