Clover coverage report - Java Language Levels Test Coverage (javalanglevels-20120305-r5436)
Coverage timestamp: Sun Mar 4 2012 22:02:46 CST
file stats: LOC: 2,207   Methods: 142
NCLOC: 1,496   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
SymbolData.java 82% 92.5% 83.1% 89.4%
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    package edu.rice.cs.javalanglevels;
 37   
 38    import edu.rice.cs.javalanglevels.tree.*;
 39    import edu.rice.cs.javalanglevels.parser.JExprParser;
 40    import java.util.*;
 41   
 42    import junit.framework.TestCase;
 43   
 44    import edu.rice.cs.plt.reflect.JavaVersion;
 45   
 46    /** Represents the data for a given class. There are two states of SymbolData. One is a continuation which
 47    * is created when a type is referenced, but the corresponding class has not been read for its members. The
 48    * other is a complete SymbolData containing all of the member data.
 49    */
 50    public class SymbolData extends TypeData {
 51   
 52    /***************Singleton primitive SymbolDatas********************/
 53   
 54    /** This anonymous class represents the boolean primitive type */
 55    public static final SymbolData BOOLEAN_TYPE = new PrimitiveData("boolean") {
 56   
 57    /** You can only cast a boolean primitive to a boolean primitive or a Boolean object (in 1.5). */
 58  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 59  0 return isAssignableTo(castTo, version);
 60    }
 61   
 62    /** Returns true if the specified SymbolData is a boolean type. */
 63  55 public boolean isAssignableTo(SymbolData toCheck, JavaVersion version) {
 64  0 if (toCheck == null) return false;
 65  55 if (LanguageLevelConverter.versionSupportsAutoboxing(version) && !toCheck.isPrimitiveType()) {
 66  3 SymbolData autoBoxMe = LanguageLevelConverter.symbolTable.get("java.lang.Boolean");
 67  3 return (autoBoxMe != null && autoBoxMe.isAssignableTo(toCheck, version));
 68    }
 69  52 return toCheck == BOOLEAN_TYPE;
 70    }
 71    };
 72   
 73    /** This anonymous class represents the char primitive type. */
 74    public static final SymbolData CHAR_TYPE = new PrimitiveData("char") {
 75   
 76    /** You can cast a char to a char, int, long, float, double or short or byte or Character object (in 1.5) */
 77  1 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 78  1 return isAssignableTo(castTo, version) || castTo == SymbolData.SHORT_TYPE || castTo == SymbolData.BYTE_TYPE;
 79    }
 80   
 81    /** You can assign a char primitive to a char, int, long, float, double or Character object (in 1.5) */
 82  70 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 83  0 if (assignTo == null) return false;
 84  70 if (LanguageLevelConverter.versionSupportsAutoboxing(version) && !assignTo.isPrimitiveType()) {
 85  10 SymbolData autoBoxMe = LanguageLevelConverter.symbolTable.get("java.lang.Character");
 86  10 return autoBoxMe != null && autoBoxMe.isAssignableTo(assignTo, version);
 87    }
 88   
 89  60 return assignTo == SymbolData.INT_TYPE ||
 90    assignTo == SymbolData.LONG_TYPE ||
 91    assignTo == SymbolData.FLOAT_TYPE ||
 92    assignTo == SymbolData.DOUBLE_TYPE ||
 93    assignTo == SymbolData.CHAR_TYPE;
 94    }
 95    };
 96   
 97    /** This anonymous class represents the byte primitive type */
 98    public static final SymbolData BYTE_TYPE = new PrimitiveData("byte") {
 99   
 100    /** You can cast a byte primitive to a char, int, long, float, double or short or byte or Byte object (in 1.5) */
 101  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 102  0 return isAssignableTo(castTo, version) || castTo == SymbolData.CHAR_TYPE;
 103    }
 104   
 105    /** You can assign a byte primitive to a byte, short, int, long, float, double, or Byte object(in 1.5). */
 106  4 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 107  0 if (assignTo == null) return false;
 108   
 109  4 if (LanguageLevelConverter.versionSupportsAutoboxing(version) && !assignTo.isPrimitiveType()) {
 110  0 SymbolData autoBoxMe = LanguageLevelConverter.symbolTable.get("java.lang.Byte");
 111  0 return autoBoxMe != null && autoBoxMe.isAssignableTo(assignTo, version);
 112    }
 113   
 114  4 return assignTo == SymbolData.BYTE_TYPE ||
 115    assignTo == SymbolData.SHORT_TYPE ||
 116    assignTo == SymbolData.INT_TYPE ||
 117    assignTo == SymbolData.LONG_TYPE ||
 118    assignTo == SymbolData.FLOAT_TYPE ||
 119    assignTo == SymbolData.DOUBLE_TYPE;
 120    }
 121    };
 122   
 123    /** This anonymous class represents the short primitive type. */
 124    public static final SymbolData SHORT_TYPE = new PrimitiveData("short") {
 125   
 126    /** You can cast a short primitive to a char, int, long, float, double or short or byte or Short object (in 1.5) */
 127  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 128  0 return isAssignableTo(castTo, version) || castTo == SymbolData.CHAR_TYPE || castTo == SymbolData.BYTE_TYPE;
 129    }
 130   
 131    /** You can assign a short primitive to a short, int, long, float, double, or Short object(in 1.5) */
 132  17 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 133  0 if (assignTo == null) return false;
 134   
 135  17 if (LanguageLevelConverter.versionSupportsAutoboxing(version) && !assignTo.isPrimitiveType()) {
 136  2 SymbolData autoBoxMe = LanguageLevelConverter.symbolTable.get("java.lang.Short");
 137  2 return autoBoxMe != null && autoBoxMe.isAssignableTo(assignTo, version);
 138    }
 139   
 140  15 return assignTo==SymbolData.SHORT_TYPE ||
 141    assignTo == SymbolData.INT_TYPE ||
 142    assignTo == SymbolData.LONG_TYPE ||
 143    assignTo == SymbolData.FLOAT_TYPE ||
 144    assignTo == SymbolData.DOUBLE_TYPE;
 145    }
 146    };
 147   
 148    /** This anonymous class represents the int primitive type. */
 149    public static final SymbolData INT_TYPE = new PrimitiveData("int") {
 150   
 151    /** You can cast a int primitive to a char, int, long, float, double or short or byte or Short object (in 1.5) */
 152  2 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 153  2 return isAssignableTo(castTo, version) || castTo == SymbolData.CHAR_TYPE || castTo == SymbolData.SHORT_TYPE
 154    || castTo == SymbolData.BYTE_TYPE;
 155    }
 156   
 157    /** You can assign a int primitive to a int, long, float, double, or Integer/Long/Float/Double or
 158    * Number/Object type (in 1.5) */
 159  2943 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 160  0 if (assignTo == null) return false;
 161   
 162  2943 if (LanguageLevelConverter.versionSupportsAutoboxing(version) && !assignTo.isPrimitiveType()) {
 163  2402 SymbolData autoBoxMe = LanguageLevelConverter.symbolTable.get("java.lang.Integer");
 164  2402 return autoBoxMe != null && autoBoxMe.isAssignableTo(assignTo, version);
 165    }
 166   
 167  541 return assignTo == SymbolData.INT_TYPE || assignTo == SymbolData.LONG_TYPE ||
 168    assignTo == SymbolData.FLOAT_TYPE || assignTo == SymbolData.DOUBLE_TYPE;
 169    }
 170    };
 171   
 172    /** This represents the long primitive */
 173    public static final SymbolData LONG_TYPE = new PrimitiveData("long"){
 174   
 175    /** You can cast a long primitive to a char, int, long, float, double or short or byte or Short object (in 1.5) */
 176  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 177  0 return isAssignableTo(castTo, version) || castTo == SymbolData.CHAR_TYPE || castTo == SymbolData.INT_TYPE ||
 178    castTo == SymbolData.SHORT_TYPE || castTo == SymbolData.BYTE_TYPE;
 179    }
 180   
 181    /** You can assign a long primitive to a long, float, double, or Long object(in 1.5) */
 182  7 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 183  0 if (assignTo == null) {return false;}
 184   
 185  7 if (LanguageLevelConverter.versionSupportsAutoboxing(version) && !assignTo.isPrimitiveType()) {
 186  0 SymbolData autoBoxMe = LanguageLevelConverter.symbolTable.get("java.lang.Long");
 187  0 return autoBoxMe != null && autoBoxMe.isAssignableTo(assignTo, version);
 188    }
 189   
 190  7 return assignTo == SymbolData.LONG_TYPE ||
 191    assignTo == SymbolData.FLOAT_TYPE ||
 192    assignTo == SymbolData.DOUBLE_TYPE;
 193   
 194    }
 195    };
 196   
 197    /** This represents the float primitive */
 198    public static final SymbolData FLOAT_TYPE = new PrimitiveData("float"){
 199   
 200    /** You can cast a float primitive to a char, int, long, float, double or short or byte or Short object (in 1.5) */
 201  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 202  0 return isAssignableTo(castTo, version) || castTo == SymbolData.CHAR_TYPE || castTo == SymbolData.INT_TYPE
 203    || castTo == SymbolData.LONG_TYPE || castTo == SymbolData.SHORT_TYPE || castTo == SymbolData.BYTE_TYPE;
 204    }
 205   
 206    /** You can assign a float primitive to a float, double, or Float object(in 1.5) */
 207  2 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 208  0 if (assignTo == null) return false;
 209   
 210  2 if (LanguageLevelConverter.versionSupportsAutoboxing(version) && !assignTo.isPrimitiveType()) {
 211  1 SymbolData autoBoxMe = LanguageLevelConverter.symbolTable.get("java.lang.Float");
 212  1 return autoBoxMe != null && autoBoxMe.isAssignableTo(assignTo, version);
 213    }
 214   
 215  1 return assignTo == SymbolData.FLOAT_TYPE || assignTo == SymbolData.DOUBLE_TYPE;
 216    }
 217    };
 218   
 219    /**This represents the double primitive*/
 220    public static final SymbolData DOUBLE_TYPE = new PrimitiveData("double"){
 221   
 222    /** A double primitive can be cast to a char, int, long, float, double, short or byte primitive or a Float
 223    * or Double object, */
 224  6 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 225  6 return isAssignableTo(castTo, version) || castTo == SymbolData.CHAR_TYPE || castTo == SymbolData.INT_TYPE
 226    || castTo == SymbolData.LONG_TYPE || castTo == SymbolData.DOUBLE_TYPE || castTo == SymbolData.SHORT_TYPE
 227    || castTo == SymbolData.BYTE_TYPE;
 228    }
 229   
 230    /** You can assign a double primitive to a float, double, or Float object(in 1.5) */
 231  46 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 232  0 if (assignTo == null) { return false; }
 233   
 234  46 if (LanguageLevelConverter.versionSupportsAutoboxing(version) && ! assignTo.isPrimitiveType()) {
 235  5 SymbolData autoBoxMe = LanguageLevelConverter.symbolTable.get("java.lang.Double");
 236  5 return autoBoxMe != null && autoBoxMe.isAssignableTo(assignTo, version);
 237    }
 238  41 return assignTo == SymbolData.DOUBLE_TYPE;
 239    }
 240    };
 241   
 242    /** Used for the void type. */
 243    public static final SymbolData VOID_TYPE = new PrimitiveData("void") {
 244   
 245    /** A void value cannot be cast to anything */
 246  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) { return false; }
 247   
 248    /** A void value can be assigned to itself */
 249  1 public boolean isAssignableTo(SymbolData toCheck, JavaVersion version) { return this == toCheck; }
 250    };
 251   
 252    /** Used for an exception */
 253    public static final SymbolData EXCEPTION = new SymbolData("exception") {
 254    /** You cannot cast an exception to anything. */
 255  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) { return false; }
 256   
 257    /** Returns true, because an exception takes the place of a return.
 258    * This SymbolData is only used when the user has thrown an Exception.
 259    */
 260  2 public boolean isAssignableTo(SymbolData toCheck, JavaVersion version) { return true; }
 261   
 262    };
 263   
 264    /** Used to signal a symbol table search that failed. */
 265    public static final SymbolData NOT_FOUND = new SymbolData("not found") {
 266   
 267    /** A not-found value cannot be cast to anything */
 268  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) { return false; }
 269   
 270    /** A not-found value cannot be assigned to anything */
 271  0 public boolean isAssignableTo(SymbolData toCheck, JavaVersion version) { return false; }
 272    };
 273   
 274    /** Singleton class representing null*/
 275    public static final SymbolData NULL_TYPE = new SymbolData("null") {
 276   
 277    /** You can cast null to any reference type (i.e. something that is not a primitive). */
 278  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 279  0 return isAssignableTo(castTo, version);
 280    }
 281   
 282    /** You can assign a null to any reference (non-primitive) type */
 283  10 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 284  10 return (assignTo != null) && ! assignTo.isPrimitiveType();
 285    }
 286   
 287    };
 288   
 289    /** Used when 2 or more SymbolDatas could match*/
 290    public static final SymbolData AMBIGUOUS_REFERENCE = new SymbolData("ambiguous reference") {
 291    /** An ambiguous reference cannot be cast to anything */
 292  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) { return false; }
 293   
 294    /** An ambiguous reference cannot be assigned to anything */
 295  0 public boolean isAssignableTo(SymbolData toCheck, JavaVersion version) { return false; }
 296    };
 297   
 298    /** Used when a this constructor invocation is seen. */
 299    public static final SymbolData THIS_CONSTRUCTOR = new SymbolData("this constructor") {
 300    /** Cannot be cast to anything */
 301  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) { return false; }
 302   
 303    /** Cannot be assigned to anything */
 304  0 public boolean isAssignableTo(SymbolData toCheck, JavaVersion version) { return false; }
 305    };
 306   
 307    /** Used when a super constructor invocation is seen. */
 308    public static final SymbolData SUPER_CONSTRUCTOR = new SymbolData("super constructor") {
 309    /** Cannot be cast to anything */
 310  0 public boolean isCastableTo(SymbolData castTo, JavaVersion version) { return false; }
 311   
 312    /** Cannot be assigned to anything */
 313  0 public boolean isAssignableTo(SymbolData toCheck, JavaVersion version) { return false; }
 314    };
 315   
 316    /** Do some initialization*/
 317    static {
 318  29 ModifiersAndVisibility _publicMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"public"});
 319  29 VOID_TYPE.setIsContinuation(false);
 320  29 VOID_TYPE.setMav(_publicMav);
 321  29 NOT_FOUND.setIsContinuation(false);
 322  29 NOT_FOUND.setMav(_publicMav);
 323  29 EXCEPTION.setMav(_publicMav);
 324  29 EXCEPTION.setIsContinuation(false);
 325    }
 326   
 327    /********Instance fields***********/
 328   
 329    /* The inherited _name field is fully qualified. */
 330   
 331    /**True iff this symbol data is a continuation (i.e. hasn't been resolved)*/
 332    private boolean _isContinuation;
 333   
 334    /* True iff this symbol corresponds to a file with an autogenerated "import junit.framework.*;" */
 335    private boolean _hasAutoGeneratedJunitImport;
 336   
 337    /**The generic type information for this class. Not used. */
 338    private TypeParameter[] _typeParameters;
 339   
 340    /**List of methods defined in this class*/
 341    private LinkedList<MethodData> _methods;
 342   
 343    /**The SymbolData corresponding to this class's super class. */
 344    private SymbolData _superClass;
 345   
 346    /**List of SymbolDatas corresponding to super interfaces. */
 347    private ArrayList<SymbolData> _interfaces;
 348   
 349    /**List of SymbolDatas corresponding to inner interfaces. */
 350    private LinkedList<SymbolData> _innerInterfaces;
 351   
 352    /** Flag that is true if this SymbolData is an interface. */
 353    private boolean _isInterface;
 354   
 355    /** Stores the package information for this symbol data. May not be set. */
 356    private String _package;
 357   
 358    /** Represents an instance of this class--i.e. an instantiation of it.*/
 359    private InstanceData _instanceData;
 360   
 361    /**The current constructor count. Incremented during first pass, decremented during second pass. */
 362    private int _constructorNumber;
 363   
 364    /** The number of local classes, used in naming them. */
 365    private int _localClassNum;
 366   
 367    /* The number of anonymous inner classes, used in naming them. */
 368    private int _anonymousInnerClassNum;
 369   
 370    /** Constructors */
 371   
 372    /** Constructor for SymbolData
 373    * @param name The name of this class or interface
 374    * @param modifiersAndVisibility The modifiersAndVisibility of this class or interface
 375    * @param typeParameters Generic type info, not used
 376    * @param superClass The super class of this class
 377    * @param interfaces The super interfaces
 378    * @param outerData The enclosing data of this class, or null
 379    */
 380  22 public SymbolData(String name, ModifiersAndVisibility modifiersAndVisibility, TypeParameter[] typeParameters,
 381    SymbolData superClass, ArrayList<SymbolData> interfaces, Data outerData) {
 382  22 super(outerData);
 383  22 _name = name;
 384  22 _modifiersAndVisibility = modifiersAndVisibility;
 385  22 _typeParameters = typeParameters;
 386  22 _methods = new LinkedList<MethodData>();
 387  22 _superClass = superClass;
 388  22 _interfaces = interfaces;
 389   
 390  22 assert interfaces != null;
 391   
 392  3 for (SymbolData sd: interfaces) { addEnclosingData(sd); }
 393   
 394    /* Add first because we want to look at the super class first */
 395  22 _enclosingData.addFirst(_superClass);
 396  22 _innerClasses = new LinkedList<SymbolData>();
 397  22 _innerInterfaces = new LinkedList<SymbolData>();
 398  22 _isContinuation = false;
 399  22 _hasAutoGeneratedJunitImport = false;
 400  22 _isInterface = false;
 401  22 _localClassNum = 0;
 402  22 _anonymousInnerClassNum = 0;
 403  22 _package = "";
 404  22 _constructorNumber = 0;
 405  22 _instanceData = new InstanceData(this);
 406    }
 407   
 408    /** Constructor for SymbolData
 409    * @param name The name of this class or interface
 410    * @param modifiersAndVisibility The modifiersAndVisibility of this class or interface
 411    * @param typeParameters Generic type info, not used
 412    * @param superClass The super class of this class
 413    * @param interfaces The super interfaces
 414    * @param outerData The enclosing data of this class, or null
 415    */
 416  0 public SymbolData(String name, ModifiersAndVisibility modifiersAndVisibility, TypeParameter[] typeParameters,
 417    SymbolData superClass, ArrayList<SymbolData> interfaces, Data outerData, String pkg) {
 418  0 this(name, modifiersAndVisibility, typeParameters, superClass, interfaces, outerData);
 419  0 _package = pkg;
 420    }
 421   
 422    /** This constructor is only called by Interfaces. Thus, there is never a super class, and _isInterface
 423    * is set to true.
 424    * @param name The name of this class or interface
 425    * @param modifiersAndVisibility The modifiersAndVisibility of this class or interface
 426    * @param typeParameters Generic type info, not used
 427    * @param interfaces The super interfaces
 428    * @param outerData The enclosing data of this class, or null
 429    */
 430  6 public SymbolData(String name, ModifiersAndVisibility modifiersAndVisibility, TypeParameter[] typeParameters,
 431    ArrayList<SymbolData> interfaces, Data outerData) {
 432  6 this(name, modifiersAndVisibility, typeParameters, null, interfaces, outerData);
 433  6 _isInterface = true;
 434    }
 435   
 436    /** Creates a continuation symbol for the specified name; does not enter this name in any table. */
 437  65682 public SymbolData(String name) { this(name, SourceInfo.NONE); }
 438   
 439    /** Creates a continuation symbol for the specified name and source info; does not enter this name in any table. */
 440  65682 public SymbolData(String name, SourceInfo si) {
 441  65682 super(null);
 442  65682 _name = name;
 443  65682 _modifiersAndVisibility = new ModifiersAndVisibility(si, new String[0]);
 444  65682 _typeParameters = new TypeParameter[0];
 445  65682 _methods = new LinkedList<MethodData>();
 446  65682 _superClass = null;
 447  65682 _interfaces = new ArrayList<SymbolData>();
 448  65682 _innerClasses = new LinkedList<SymbolData>();
 449  65682 _innerInterfaces = new LinkedList<SymbolData>();
 450  65682 _isContinuation = true;
 451  65682 _isInterface = false;
 452  65682 _package = "";
 453  65682 _instanceData = new InstanceData(this);
 454    }
 455   
 456    /** No reference type is a Primitive type. */
 457  7572 public boolean isPrimitiveType() { return false; }
 458   
 459  54615 public String toString() {
 460  107 if (_isContinuation) return "? " + _name;
 461  54508 return "!" + _name;
 462    }
 463   
 464    /**
 465    * See if this can be assigned to assignTo.
 466    * An assignment is legal:
 467    * 1. if this is a class type
 468    * - if assignTo is a class type, then the types must be the same, or this must be a subclass of assignTo
 469    * - if assignTo is an interface, then we must implement it.
 470    * - if assignTo is an array, then it is not assignable.
 471    * 2. if this is an interface
 472    * - if assignTo is a class, assignTo must be java.lang.Object.
 473    * - if assignTo is an interface, then the types must be the same, or this must be a subinterface of assignTo.
 474    * - if assignTo is an array, then it is not assignable
 475    * All of these rules are followed in isSubclassOf(), which traverses the hierarchy.
 476    */
 477  5160 public boolean isAssignableTo(SymbolData assignTo, JavaVersion version) {
 478  5160 if (assignTo != null) {
 479  5160 if (assignTo.isPrimitiveType() && LanguageLevelConverter.versionSupportsAutoboxing(version)) {
 480    // You never box the left, so see if this can be unboxed to be a primitive.
 481  68 SymbolData unboxedType = this.unbox();
 482  49 if (unboxedType == null) return false;
 483  19 else return unboxedType.isAssignableTo(assignTo, version);
 484    }
 485  5092 else return this.isSubClassOf(assignTo);
 486    }
 487  0 return false;
 488    }
 489   
 490    /** Resolves this symbol using the visitor llv.
 491    * @return the new symbol definition. */
 492  6 public SymbolData resolve(SourceInfo si, LanguageLevelVisitor llv) { return llv.resolveSymbol(si, this); }
 493   
 494    /** If this SymbolData is a wrapper class for a primitive, return the primitive type. Else return null.
 495    * @return the Primitive this SymbolData wraps, if there is one. Otherwise return null.
 496    */
 497  68 private SymbolData unbox() {
 498  68 String name = getName();
 499  6 if (name.equals("java.lang.Integer")) {return SymbolData.INT_TYPE;}
 500  1 if (name.equals("java.lang.Character")) {return SymbolData.CHAR_TYPE;}
 501  8 if (name.equals("java.lang.Short")) {return SymbolData.SHORT_TYPE;}
 502  0 if (name.equals("java.lang.Byte")) {return SymbolData.BYTE_TYPE;}
 503  0 if (name.equals("java.lang.Float")) {return SymbolData.FLOAT_TYPE;}
 504  1 if (name.equals("java.lang.Double")) {return SymbolData.DOUBLE_TYPE;}
 505  1 if (name.equals("java.lang.Long")) {return SymbolData.LONG_TYPE;}
 506  2 if (name.equals("java.lang.Boolean")) {return SymbolData.BOOLEAN_TYPE;}
 507  49 return null;
 508    }
 509   
 510    /**
 511    * See if this can be cast as a castTo.
 512    * A cast is legal if:
 513    * 1. if both sides are the same type
 514    * 2. Both are primitives and
 515    * - a widening primitive coversion is possible OR
 516    * - a narrowing primitive conversion is possible
 517    * 3. this is a class type and
 518    * - castTo is a class type and one is the super class of the other
 519    * - castTo is an interface type and this is not final OR this implements castTo
 520    * - castTo is an array type, and this is Object
 521    * 4. this is an interface type and
 522    * - castTo is a class type and is not final OR this implements this
 523    * - castTo is an interface type and this and castTo do not contain one or more methods with the same signature
 524    * but different return types
 525    * - castTo is an array type and this is either Serializable or Cloneable.
 526    * @param castTo The TypeData we are trying to cast to. (castTo) this
 527    * @return true If the cast is legal, false otherwise.
 528    */
 529  11 public boolean isCastableTo(SymbolData castTo, JavaVersion version) {
 530  11 if (castTo != null) {
 531  11 if (castTo.isPrimitiveType()) {
 532  0 if (LanguageLevelConverter.versionSupportsAutoboxing(version)) {
 533    //You never box the left, so see if this can be unboxed to be a primitive.
 534  0 SymbolData unboxedType = this.unbox();
 535  0 if (unboxedType == null) {return false;}
 536  0 else {return unboxedType.isCastableTo(castTo, version);}
 537    }
 538  0 else {return false;} //without autoboxing, cannot cast an object to a primitive
 539    }
 540   
 541  11 else if (!this.isInterface()) { //we're a class
 542  10 if (!castTo.isInterface()) {//castTo is a class or array
 543  10 return this.isSubClassOf(castTo) || castTo.isSubClassOf(this);
 544    }
 545   
 546    else { //castTo is an interface
 547  0 return (!castTo.hasModifier("final") || castTo.isSubClassOf(this));
 548    }
 549   
 550    }
 551   
 552    else { // this is an interface
 553   
 554  1 if (!castTo.isInterface()) {//castTo is a class or array
 555  0 return !castTo.hasModifier("final") || castTo.isSubClassOf(this);
 556    }
 557   
 558    else { // castTo is an interface
 559    // return false if this and castTo contain methods with the same signature but different return types.
 560  1 if (LanguageLevelConverter.versionSupportsAutoboxing(version)) return true;
 561  0 for (MethodData md: this.getMethods()) {
 562  0 if (checkDifferentReturnTypes(md, castTo, false, version)) {
 563    /* TypeChecker._addError("Types " + this.getName() + " and " + castTo.getName() + " are incompatible.
 564    Both implement " + md.getName() + " but have different return types", md.getSourceInfo()); */
 565  0 return false;
 566    }
 567    }
 568  0 return true;
 569    }
 570    }
 571    }
 572  0 return false;
 573    }
 574   
 575    /** Depth-first traversal of the tree of enclosing data checking to see if sd is above this SymbolData
 576    * in the class hierarchy.
 577    */
 578  15903 public boolean isSubClassOf(SymbolData sd) {
 579  0 if (sd == null) return false;
 580  5085 if (this.equals(sd)) return true;
 581  10818 if (sd.isInterface()) {
 582  54 for (SymbolData i: _interfaces) {
 583  0 if (i == null) continue;
 584  28 if (i.equals(sd)) return true;
 585  4 if (i.isSubClassOf(sd)) return true;
 586    }
 587    }
 588   
 589  10322 if (_superClass != null) return _superClass.isSubClassOf(sd);
 590  464 return false;
 591    }
 592   
 593    /** Checks to see if this SymbolData is an inner class of outerClass (that is, that outerClass appears
 594    * somewhere in its enclosing data chain. If stopAtStatic flag is true, stop as soon as we see a static class
 595    * in the chain. This is because we are trying to resolve something, such as a "this" call, that cannot be seen outside
 596    * of a static inner class.
 597    * @param outerClass The SymbolData we believe might be our outer class.
 598    * @param stopAtStatic boolean flag, true if we want to stop at a static outer class.
 599    * @return true if we are its inner class, false otherwise.
 600    */
 601  41 public boolean isInnerClassOf(SymbolData outerClass, boolean stopAtStatic) {
 602  13 if (this == outerClass) return true;
 603  28 Data outerData = this.getOuterData();
 604  4 if (outerData == null) return false;
 605  5 if (stopAtStatic && this.hasModifier("static")) {return false;}
 606  19 return outerData.getSymbolData().isInnerClassOf(outerClass, stopAtStatic);
 607    }
 608   
 609    /**@return false, since this is a SymbolData and not an InstanceData*/
 610  79 public boolean isInstanceType() { return false; }
 611   
 612    /**@return this SymbolData.*/
 613  3614 public SymbolData getSymbolData() { return this; }
 614   
 615    /** @return the InstanceData corresponding to this class. */
 616  1829 public InstanceData getInstanceData() { return _instanceData; }
 617   
 618    /** Sets the InstanceData for this class to the specified value. */
 619  0 public void setInstanceData(InstanceData id) { _instanceData = id; }
 620   
 621    /** @return the package */
 622  143146 public String getPackage() { return _package; }
 623   
 624    /** Sets the package to the specified value */
 625  63637 public void setPackage(String pkg) { _package = pkg; }
 626   
 627    /** @return the generic type parameters */
 628  179846 public TypeParameter[] getTypeParameters() {
 629  179846 return _typeParameters;
 630    }
 631   
 632    /**Set the generic type parameters to the specified value*/
 633  282 public void setTypeParameters(TypeParameter[] typeParameters) {
 634  282 _typeParameters = typeParameters;
 635    }
 636   
 637    /**@return true if this is an interface*/
 638  152089 public boolean isInterface() {
 639  152089 return _isInterface;
 640    }
 641   
 642  63664 public void setInterface(boolean ii) {
 643  63664 _isInterface = ii;
 644    }
 645   
 646    /**@return the list of inner interfaces*/
 647  140538 public LinkedList<SymbolData> getInnerInterfaces() {
 648  140538 return _innerInterfaces;
 649    }
 650   
 651    /** Takes in a name and tries to match it with one of this Data's inner classes or inner interfaces. The input string
 652    * is a name relative to this SymbolData (such as B.C to request the class A.B.C from class A) and may be delimited
 653    * by '.' or '$'.
 654    * TODO; NO!!! This is broken. '$' appears in anonymous class names and local class names, where it is NOT
 655    * used as a name segment separator
 656    * Checks the super class and interfaces of this SymbolData to see if the inner class or interface
 657    * can be found there. If no matching visibile inner classes or interfaces are found, but one or more that are not
 658    * visible are found, one of the non-visibile ones will be returned.
 659    * @return The SymbolData for the matching inner class or interface or null if there isn't one or SymbolData.
 660    * AMBIGUOUS_REFERENCE if the reference is ambiguous.
 661    */
 662  3561 protected SymbolData getInnerClassOrInterfaceHelper(String nameToMatch, int firstIndexOfDot) {
 663  3561 Iterator<SymbolData> iter = innerClassesAndInterfacesIterator();
 664  3561 while (iter.hasNext()) {
 665  372 SymbolData sd = iter.next();
 666  372 String sdName = sd.getName();
 667   
 668  372 sdName = LanguageLevelVisitor.getUnqualifiedClassName(sdName);
 669  372 if (firstIndexOfDot == -1) {
 670  336 if (sdName.equals(nameToMatch))
 671  109 return sd;
 672    }
 673    else {
 674  36 if (sdName.equals(nameToMatch.substring(0, firstIndexOfDot))) {
 675  8 return sd.getInnerClassOrInterface(nameToMatch.substring(firstIndexOfDot + 1));
 676    }
 677    }
 678    }
 679   
 680  3444 SymbolData result = null;
 681  3444 SymbolData newResult = null;
 682  3444 SymbolData privateResult = null;
 683   
 684    // Next, look through the inner classes/interfaces of this class's super class
 685    // Check accessibility, because if you cannot see the super class's inner class, you can't use it.
 686  3444 if (_superClass != null) {
 687  1407 newResult = _superClass.getInnerClassOrInterfaceHelper(nameToMatch, firstIndexOfDot);
 688  1407 if (newResult != null) {
 689  10 SymbolData outerPiece;
 690   
 691  10 if (firstIndexOfDot > 0)
 692  0 outerPiece = _superClass.getInnerClassOrInterfaceHelper(nameToMatch.substring(0, firstIndexOfDot), -1);
 693  10 else outerPiece = newResult;
 694   
 695  7 if (TypeChecker.checkAccess(outerPiece.getMav(), outerPiece, this)) {result = newResult;}
 696  3 else privateResult = newResult;
 697    }
 698    }
 699   
 700    // Next, look through the inner classes/interfaces of each of this class's interfaces
 701    // Check accessibility, because if you cannot see the super class's inner class, you can't use it.
 702  3444 for (SymbolData id: _interfaces) { // TODO: find out how null is being inserted in _interfaces
 703  182 if (id == null) {
 704    // System.err.println("In SymbolData " + getName() + ", _interfaces contains a null entry");
 705    // assert false;
 706  0 continue;
 707    }
 708  182 newResult = id.getInnerClassOrInterfaceHelper(nameToMatch, firstIndexOfDot);
 709  182 if (newResult != null) {
 710  11 SymbolData outerPiece;
 711  11 if (firstIndexOfDot > 0) {
 712  1 outerPiece = _superClass.getInnerClassOrInterfaceHelper(nameToMatch.substring(0, firstIndexOfDot), -1);
 713    }
 714  10 else { outerPiece = newResult; }
 715  11 if (TypeChecker.checkAccess(outerPiece.getMav(), outerPiece, this)) {
 716  2 if (result == null) {result = newResult;}
 717  7 else {return SymbolData.AMBIGUOUS_REFERENCE;}
 718    }
 719  2 else {privateResult = newResult;}
 720    }
 721    }
 722  2 if (result != null) {return result;}
 723  3435 return privateResult; //this will be null if no matching inner classes/interfaces were found.
 724    }
 725   
 726   
 727    /**Iterate over first the inner classes and then the inner interfaces.*/
 728  3561 public Iterator<SymbolData> innerClassesAndInterfacesIterator() {
 729  3561 return new Iterator<SymbolData>() {
 730    private Iterator<SymbolData> _first = _innerClasses.iterator();
 731    private Iterator<SymbolData> _second = _innerInterfaces.iterator();
 732   
 733  3816 public boolean hasNext() { return _first.hasNext() || _second.hasNext(); }
 734   
 735  372 public SymbolData next() {
 736  359 if (_first.hasNext()) return _first.next();
 737  13 else return _second.next();
 738    }
 739   
 740  0 public void remove() { throw new UnsupportedOperationException(); }
 741    };
 742    }
 743   
 744   
 745    /**Add the specified innerInterface to the list of innerInterfaces*/
 746  16 public void addInnerInterface(SymbolData innerInterface) { _innerInterfaces.addLast(innerInterface); }
 747   
 748    /**Increment the local class num and return it*/
 749  9 public int preincrementLocalClassNum() { return ++_localClassNum; }
 750   
 751    /**Set the anonymous inner class num to the specified value*/
 752  212 public void setAnonymousInnerClassNum(int i) { _anonymousInnerClassNum=i; }
 753   
 754    /**Increment the anonymous inner class num, and return it*/
 755  29 public int preincrementAnonymousInnerClassNum() { return ++_anonymousInnerClassNum; }
 756   
 757    /**@return the anonymous inner class num*/
 758  0 public int getAnonymousInnerClassNum() { return _anonymousInnerClassNum; }
 759   
 760    /**Return the local class num, and then decrement it*/
 761  0 public int postdecrementLocalClassNum() { return _localClassNum--; }
 762   
 763    /**Return the anonymous inner class num, and then decrement it*/
 764  0 public int postdecrementAnonymousInnerClassNum() { return _anonymousInnerClassNum--; }
 765   
 766    /** Adds a (perhaps mutable) variable or field to a SymbolData. */
 767  293302 public boolean addVar(VariableData var) {
 768    // Next line commented out because local variables do not have a initial value
 769    // if (! var.isFinal()) var.setHasValue();
 770  293302 return super.addVar(var);
 771    }
 772   
 773    /** Adds fields or variables to a SymboLData.*/
 774  59 public boolean addVars(VariableData[] vars) {
 775  59 boolean success = true;
 776  59 for (int i = 0; i<vars.length; i++) {
 777  65 LinkedList<SymbolData> seen = new LinkedList<SymbolData>();
 778  65 if (! _repeatedName(vars[i], seen)) {
 779    // Next line commented out because local variables do not have a initial value
 780    // if (! vars[i].isFinal()) vars[i].setHasValue();
 781  62 _vars.addLast(vars[i]);
 782    }
 783  3 else success = false;
 784    }
 785  59 return success;
 786    }
 787   
 788    /** Add the array of variable datas to the list of variables defined in this scope, unless a name has already been
 789    * used. Return true if all variables were added successfully, false otherwise. Set each of the variable datas in
 790    * the array to be final before adding them.
 791    * Since this method is used to add fields at the Functional level,
 792    * and at this level, we do not want the user to be able to shadow fields defined
 793    * in the superclass hierarchy, instead of using the normal repeated Name method,
 794    * check the repeated name throughout the hierarchy.
 795    *
 796    * @param vars The VariableData[] that we want to add.
 797    * @return true if all VariableDatas were added successfully, false otherwise.
 798    */
 799  92 public boolean addFinalVars(VariableData[] vars) {
 800  92 boolean success = true;
 801  92 for (int i = 0; i<vars.length; i++) {
 802  98 LinkedList<SymbolData> seen = new LinkedList<SymbolData>();
 803  98 if (!_repeatedNameInHierarchy(vars[i], seen)) {
 804  92 if (! vars[i].isFinal()) vars[i].setFinal();
 805  94 _vars.addLast(vars[i]);
 806    }
 807    else {
 808  4 success = false;
 809    }
 810    }
 811  92 return success;
 812    }
 813   
 814    /** Checks to see if a variable with the same name as vr has already been defined in the scope of this data. If so,
 815    * return true. Otherwise, return false.
 816    * @param vr The VariableData whose name we are searching for.
 817    * @return true if that name has already been used in this scope, false otherwise.
 818    */
 819  65 private boolean _repeatedName(VariableData vr, LinkedList<SymbolData> seen) {
 820  65 seen.addLast(this);
 821  65 Iterator<VariableData> iter = _vars.iterator();
 822  65 while (iter.hasNext()) {
 823  3 if (vr.getName().equals(iter.next().getName())) return true;
 824    }
 825  62 return false;
 826    }
 827   
 828    /** Checks to see if a variable with the same name as vr has already been defined in the scope of this data or its
 829    * super class/interfaces. If so, return true. Otherwise, return false.
 830    * @param vr The VariableData whose name we are searching for.
 831    * @return true if that name has already been used in this scope, false otherwise.
 832    */
 833  204 private boolean _repeatedNameInHierarchy (VariableData vr, LinkedList<SymbolData> seen) {
 834  204 seen.addLast(this);
 835  204 Iterator<VariableData> iter = _vars.iterator();
 836  204 while (iter.hasNext()) {
 837  7 if (vr.getName().equals(iter.next().getName())) return true;
 838    }
 839   
 840    // Does this shadow something in the super class?
 841  2 if (_superClass != null && _superClass._repeatedNameInHierarchy(vr, seen)) return true;
 842   
 843    //Does this shadow something in the super interfaces? TODO: postpone this test until all interfaces have been identified.
 844  195 for (SymbolData sd: _interfaces) {
 845  1 if (sd != null && sd._repeatedNameInHierarchy(vr, seen)) return true;
 846    }
 847  194 return false;
 848    }
 849   
 850    /** @return the list of methods defined in this symbol data*/
 851  182635 public LinkedList<MethodData> getMethods() { return _methods; }
 852   
 853    /** Returns true if there is a method with the given name in this SymbolData.
 854    * @param name The name of the method to return
 855    * @return true if a MethodData is found or false otherwise.
 856    */
 857  178 public boolean hasMethod(String name) {
 858  178 for (int i = 0; i < _methods.size(); i++) {
 859  470 MethodData currMd = _methods.get(i);
 860  22 if (currMd.getName().equals(name)) return true;
 861    }
 862  156 return false;
 863    }
 864   
 865    /** Returns the method with the given name and param types.
 866    * @param name The name of the method to return
 867    * @param paramTypes Array of the TypeDatas correpsonding to the parameters to the method.
 868    * @return The matched MethodData or null if it is not found
 869    */
 870  336 public MethodData getMethod(String name, TypeData[] paramTypes) {
 871  336 for (MethodData currMd: _methods) {
 872  919 if (currMd.getName().equals(name)) {
 873  320 if (paramTypes.length == currMd.getParams().length) {
 874  311 boolean match = true;
 875  311 for (int j = 0; j < paramTypes.length; j++) { // TODO; clean up this coding!
 876  42 if (paramTypes[j] == null || paramTypes[j].getSymbolData() == null || currMd.getParams()[j].getType() == null)
 877  0 continue; // prevents a null pointer exception
 878  42 if (! paramTypes[j].getSymbolData().equals(currMd.getParams()[j].getType().getSymbolData())) {
 879  0 match = false;
 880  0 break;
 881    }
 882    }
 883  311 if (match) return currMd;
 884    }
 885    }
 886    }
 887  25 return null;
 888    }
 889   
 890    /**Sets the list of methods to the specified one*/
 891  6 public void setMethods(LinkedList<MethodData> methods) {
 892  6 _methods = methods;
 893    }
 894   
 895    /**Calls repeatedSignature with fromClassFile set to false by default.*/
 896  1798 public static MethodData repeatedSignature(LinkedList<MethodData> listOfMethods, MethodData method) {
 897  1798 return repeatedSignature(listOfMethods, method, false);
 898    }
 899   
 900    /** Checks if two methods in this SymbolData have the same name and parameters.
 901    * @param listOfMethods The methods in this SymbolData
 902    * @param method The MethodData for the method to be added
 903    * @param fromClassFile Whether or not a class file is adding this method.
 904    * Important because bridge methods, which differ only in return type,
 905    * can be added from a class file and are legal but cannot exist in source code.
 906    * @return the MethodData that was already in listOfMethods that method duplicates if there is one or null otherwise.
 907    */
 908  1800 public static MethodData repeatedSignature(LinkedList<MethodData> listOfMethods, MethodData method,
 909    boolean fromClassFile) {
 910  1800 Iterator<MethodData> iter = listOfMethods.iterator();
 911  1800 VariableData[] methodParams = method.getParams();
 912  1800 while (iter.hasNext()) {
 913  5453 boolean match = true;
 914  5453 MethodData currMd = iter.next();
 915    // Check if names are the same and if this is called from a class file check if return types are the same.
 916  5453 if (currMd.getName().equals(method.getName()) &&
 917    (! fromClassFile || currMd.getReturnType() == method.getReturnType())) {
 918  135 VariableData[] currMdParams = currMd.getParams();
 919  135 if (currMdParams.length == methodParams.length) {
 920  96 for (int i = 0; i < currMdParams.length; i++) {
 921  65 if (currMdParams[i].getType() != methodParams[i].getType()) {
 922  10 match = false;
 923  10 break;
 924    }
 925    }
 926  86 if (match) return currMd;
 927    }
 928    }
 929    }
 930  1714 return null;
 931    }
 932   
 933   
 934   
 935    /** @return true if this is a primitive boolean or a Boolean with autoboxing enabled*/
 936  119 boolean isBooleanType(JavaVersion version) {
 937  119 return this == BOOLEAN_TYPE ||
 938    (getName().equals("java.lang.Boolean") && LanguageLevelConverter.versionSupportsAutoboxing(version));
 939    }
 940   
 941   
 942    /** @return true if this is a primitive char or a Character with autoboxing enabled*/
 943  78 boolean isCharType(JavaVersion version) {
 944  78 return this == CHAR_TYPE || (getName().equals("java.lang.Character") &&
 945    LanguageLevelConverter.versionSupportsAutoboxing(version));
 946    }
 947   
 948    /** @return true if this is a primitive byte or a Byte with autoboxing enabled*/
 949  50 boolean isByteType(JavaVersion version) {
 950  50 return this == BYTE_TYPE || (getName().equals("java.lang.Byte") &&
 951    LanguageLevelConverter.versionSupportsAutoboxing(version));
 952    }
 953   
 954    /** @return true if this is a primitive short or a Short with autoboxing enabled*/
 955  41 boolean isShortType(JavaVersion version) {
 956  41 return this == SHORT_TYPE || (getName().equals("java.lang.Short") &&
 957    LanguageLevelConverter.versionSupportsAutoboxing(version));
 958    }
 959   
 960    /**@return true if this is a primitive int or an Integer with autoboxing enabled*/
 961  288 boolean isIntType(JavaVersion version) {
 962  288 return this==INT_TYPE || (getName().equals("java.lang.Integer") &&
 963    LanguageLevelConverter.versionSupportsAutoboxing(version));
 964    }
 965   
 966    /**@return true if this is a primitive long or a Long with autoboxing enabled*/
 967  359 boolean isLongType(JavaVersion version) {
 968  359 return this == LONG_TYPE || (this.getName().equals("java.lang.Long") &&
 969    LanguageLevelConverter.versionSupportsAutoboxing(version));
 970    }
 971   
 972    /**@return true if this is a primitive char or a Character with autoboxing enabled*/
 973  358 boolean isFloatType(JavaVersion version) {
 974  358 return this == FLOAT_TYPE || (getName().equals("java.lang.Float") &&
 975    LanguageLevelConverter.versionSupportsAutoboxing(version));
 976    }
 977   
 978    /**@return true if this is a primitive double or a Double with autoboxing enabled*/
 979  382 boolean isDoubleType(JavaVersion version) {
 980  382 return this == DOUBLE_TYPE ||
 981    (getName().equals("java.lang.Double") && LanguageLevelConverter.versionSupportsAutoboxing(version));
 982    }
 983   
 984    /** Compares the ModifiersAndVisibility of the 2 method data to determine if overwriting can override the access
 985    * priviledges of overwritten.
 986    */
 987  36 private static boolean _isCompatible(MethodData overwritten, MethodData overwriting) {
 988  36 if (overwritten.hasModifier("public")) { // A public method can only be overwritten by a public method.
 989  30 return overwriting.hasModifier("public");
 990    }
 991  6 if (overwritten.hasModifier("protected")) { // A protected method can only be overwritten by protected/public method
 992  1 return overwriting.hasModifier("protected") || overwriting.hasModifier("public");
 993    }
 994  5 if (! overwritten.hasModifier("private")) { // default methods can be overridden by a non-private method
 995  4 return ! overwriting.hasModifier("private");
 996    }
 997  1 return true;
 998    }
 999   
 1000    /**Call checkDifferentReturnTypes with addError set to true by default*/
 1001  293 protected static boolean checkDifferentReturnTypes(MethodData md, SymbolData sd, JavaVersion version) {
 1002  293 return checkDifferentReturnTypes(md, sd, true, version);
 1003    }
 1004   
 1005    /** Called to make sure that no method has the same name and parameters as a method it inherits while having
 1006    * different return types.
 1007    * @param md The MethodData we're currently trying to add
 1008    * @param sd The SymbolData of the class whose enclosingDatas we're examining for
 1009    * different return types.
 1010    * @param addError true if errors should be added to the type checker
 1011    * @return Whether there exists a conflict
 1012    */
 1013  293 protected static boolean checkDifferentReturnTypes(MethodData md, SymbolData sd, boolean addError,
 1014    JavaVersion version) {
 1015    // We only want to check the super class and interfaces, not outer classes.
 1016  293 ArrayList<SymbolData> interfaces = sd.getInterfaces();
 1017  293 LinkedList<SymbolData> enclosingData = new LinkedList<SymbolData>();
 1018  293 enclosingData.addAll(interfaces);
 1019  293 SymbolData superClass = sd.getSuperClass();
 1020  293 if (superClass != null) {
 1021  164 enclosingData.add(superClass);
 1022    }
 1023  293 Iterator<SymbolData> iter = enclosingData.iterator();
 1024  293 while (iter.hasNext()) {
 1025  202 SymbolData currSd = iter.next();
 1026  202 MethodData matchingMd = repeatedSignature(currSd.getMethods(), md);
 1027  202 if (matchingMd != null) {
 1028  0 if (matchingMd.hasModifier("private")) return false;
 1029  33 boolean subclass = md.getReturnType().isSubClassOf(matchingMd.getReturnType());
 1030  33 if (matchingMd.getReturnType() != md.getReturnType() && ! subclass &&
 1031    LanguageLevelConverter.versionIs15(version)) {
 1032  4 StringBuffer methodSignature = new StringBuffer(md.getName() + "(");
 1033  4 VariableData[] params = md.getParams();
 1034  4 for (int i = 0; i < params.length; i++) {
 1035  0 if (i > 0) methodSignature.append(", ");
 1036  1 methodSignature.append(params[i].getType().getName());
 1037    }
 1038  4 methodSignature.append(")");
 1039  4 String methodSigString = methodSignature.toString();
 1040    // This entire method is only called from the type checker, so add an error to its error list.
 1041  4 if (addError) {
 1042  4 TypeChecker.errors.addLast(new Pair<String, JExpressionIF>(methodSigString + " in " + sd.getName() +
 1043    " cannot override " + methodSigString + " in " +
 1044    currSd.getName() +
 1045    "; attempting to use different return types",
 1046    md.getJExpression())); }
 1047  4 return true;
 1048    }
 1049   
 1050  29 if (! _isCompatible(matchingMd, md)) { // check compatibility of visiblity modifiers
 1051  1 String access = "package";
 1052  0 if (matchingMd.hasModifier("private")) access = "private";
 1053  1 if (matchingMd.hasModifier("public")) access = "public";
 1054  0 if (matchingMd.hasModifier("protected")) access = "protected";
 1055  1 if (addError) {
 1056  1 TypeChecker.errors.
 1057    addLast(new Pair<String, JExpressionIF>(md.getName() + " in " + md.getSymbolData().getName()
 1058    + " cannot override " + matchingMd.getName() + " in "
 1059    + matchingMd.getSymbolData().getName() +
 1060    ". You are attempting to assign weaker access priviledges. In "
 1061    + matchingMd.getSymbolData().getName() + ", "
 1062    + matchingMd.getName() + " was "
 1063    + access, md.getJExpression())); }
 1064  1 return true;
 1065    }
 1066    }
 1067  2 else if (checkDifferentReturnTypes(md, currSd, version)) return true;
 1068    }
 1069  286 return false;
 1070    }
 1071   
 1072    /** Checks to see if methodName is used in this SymbolData's scope. If so, finds a new name for the method by
 1073    * appending a counter to its name until an unused method name results. Returns the new name.
 1074    * @param methodName The initial String name of the variable we are creating.
 1075    * @return The new variable name which does not shadow anything in vars.
 1076    */
 1077  257 public String createUniqueMethodName(String methodName) {
 1078  257 LinkedList<SymbolData> toCheck = new LinkedList<SymbolData>();
 1079  257 toCheck.add(this);
 1080  257 Set<String> names = new HashSet<String>();
 1081  257 while(toCheck.size() > 0) {
 1082  718 SymbolData sd = toCheck.removeFirst();
 1083  718 LinkedList<MethodData> methods = sd.getMethods();
 1084  6598 for(MethodData md : methods) { names.add(md.getName()); }
 1085  391 if (sd.getSuperClass() != null) { toCheck.add(sd.getSuperClass()); }
 1086  718 toCheck.addAll(sd.getInterfaces());
 1087  17 if (sd.getOuterData() != null) { toCheck.add(sd.getOuterData().getSymbolData()); }
 1088    }
 1089   
 1090  257 String newName = methodName;
 1091  257 int counter = 0; // Note: loop tests for counter overflow, but memory would be exhausted much earlier
 1092  257 while (names.contains(newName) && counter != -1) {
 1093  11 newName = methodName + counter;
 1094  11 counter++;
 1095    }
 1096   
 1097  0 if (counter == -1) throw
 1098    new RuntimeException("Internal Program Error: Unable to rename method " + methodName
 1099    + ". All possible names were taken. Please report this bug.");
 1100   
 1101  257 return newName;
 1102    }
 1103   
 1104   
 1105    /** Called to generate an error message when two methods are created with the same signature. */
 1106  5 private String _createErrorMessage(MethodData md) {
 1107  5 StringBuffer message =
 1108    new StringBuffer("In the class \"" + md.getSymbolData().getName() +
 1109    "\", you cannot have two methods with the same name: \"" + md.getName() + "\"");
 1110  5 VariableData[] params = md.getParams();
 1111  5 if (params.length > 0) {
 1112  3 message.append(" and parameter type");
 1113  3 if (params.length > 1) {
 1114  2 message.append("s");
 1115    }
 1116  3 message.append(":");
 1117    }
 1118  5 for (int i = 0; i < params.length; i++) {
 1119  5 VariableData p = params[i];
 1120  5 if (p != null && p.getType() != null) {
 1121  5 if (i > 0) {
 1122  2 message.append(",");
 1123    }
 1124  5 message.append(" " + p.getType().getName());
 1125    }
 1126    }
 1127  5 return message.toString();
 1128    }
 1129   
 1130    /** When adding a method, we must check that the method's signature (name and parameters)
 1131    * does not match that of any other method in the same class. We also must check that
 1132    * a method does not have the same signature but a different return type from a method
 1133    * in its superclass or one of its interfaces.
 1134    ` */
 1135  362 public void addMethod(MethodData method) {
 1136    // Detect repeated methods
 1137  362 if (repeatedSignature(_methods, method) != null) {
 1138  2 LanguageLevelVisitor.errors.addLast(new Pair<String, JExpressionIF>(_createErrorMessage(method),
 1139    method.getJExpression()));
 1140    }
 1141    else {
 1142  360 _methods.addLast(method);
 1143    // System.err.println("*** Adding method " + method.getName() + " to " + this);
 1144    }
 1145    }
 1146   
 1147    /** This version of addMethod is called whenever the method corresponds to one that is auto-generated
 1148    * (toString, equals, hashCode, etc.) and is necessary because we need to check if the user defined
 1149    * a method with the same signature and, if so, highlight the user method instead of trying to highlight
 1150    * the auto-generated method (which doesn't appear in the raw version of the source anyway).
 1151    */
 1152  590 public void addMethod(MethodData method, boolean isAugmentedCode) {
 1153    // Detect if a method was user-defined that matches the signature of an auto-generated method.
 1154  590 MethodData md = repeatedSignature(_methods, method);
 1155  590 if (md != null) {
 1156  1 LanguageLevelVisitor.errors.
 1157    addLast(new Pair<String, JExpressionIF>("This method's signature conflicts with an automatically generated "
 1158    + "method's signature",
 1159    md.getJExpression()));
 1160    }
 1161    else {
 1162  589 _methods.addLast(method);
 1163    }
 1164    }
 1165   
 1166    /**
 1167    * Important to know if this is called from a class file since JSR14 allows methods to have the same
 1168    * name and parameters with different return types for bridge methods.
 1169    */
 1170  802694 public void addMethod(MethodData method, boolean isAugmentedCode, boolean fromClassFile) {
 1171    // This checking cannot be performed until symbolTable is complete
 1172    // // Detect if a method was user-defined that matches the signature of an auto-generated method.
 1173    // MethodData md = repeatedSignature(_methods, method, fromClassFile);
 1174    // if (md != null) {
 1175    // LanguageLevelVisitor.errors.
 1176    // addLast(new Pair<String, JExpressionIF>(_createErrorMessage(method), md.getJExpression()));
 1177    // }
 1178    // else {
 1179  802694 _methods.addLast(method);
 1180    // }
 1181    }
 1182   
 1183    /**@return the superClass of this symbol data*/
 1184  156479 public SymbolData getSuperClass() {
 1185  156479 return _superClass;
 1186    }
 1187   
 1188  248 public void clearSuperClass() { _superClass = null; }
 1189   
 1190    /** Set the super class to the specified value. */
 1191  63527 public void setSuperClass(SymbolData superClass) {
 1192  63527 assert superClass != null;
 1193  63527 _superClass = superClass;
 1194  63527 addEnclosingData(superClass);
 1195    }
 1196   
 1197    /**@return the interfaces of this symbol data*/
 1198  154811 public ArrayList<SymbolData> getInterfaces() { return _interfaces; }
 1199   
 1200    /** Add an interface to the list of interfaces. TODO: find out where null is being added as an interface! */
 1201  40521 public void addInterface(SymbolData interphace) {
 1202  40521 if (interphace != null) {
 1203  40521 _interfaces.add(interphace);
 1204  40521 addEnclosingData(interphace);
 1205    }
 1206    }
 1207   
 1208    /**Set the interfaces to be the specified list*/
 1209  284 public void setInterfaces(ArrayList<SymbolData> interfaces) {
 1210  284 assert interfaces != null;
 1211  284 _interfaces = interfaces;
 1212  14 for (SymbolData sd: interfaces) { if (sd != null) addEnclosingData(sd); }
 1213    }
 1214   
 1215    /**Add one to the number of constructors for this symbol data*/
 1216  29 public void incrementConstructorCount() {
 1217  29 _constructorNumber ++;
 1218    }
 1219   
 1220    /**Subtract one from the number of constructors for this symbol data*/
 1221  18 public void decrementConstructorCount() {
 1222  18 _constructorNumber --;
 1223    }
 1224   
 1225    /**@return the number of constructors*/
 1226  18 public int getConstructorCount() {
 1227  18 return _constructorNumber;
 1228    }
 1229   
 1230    /**@return true if this is a continuation*/
 1231  9305360 public boolean isContinuation() {
 1232  9305360 return _isContinuation;
 1233    }
 1234   
 1235    /**Set the isContinuation flag to the specified value*/
 1236  64188 public void setIsContinuation(boolean isContinuation) {
 1237  64188 _isContinuation = isContinuation;
 1238    }
 1239   
 1240    /**@return true if this is a continuation*/
 1241  80 public boolean hasAutoGeneratedJunitImport() {
 1242  80 return _hasAutoGeneratedJunitImport;
 1243    }
 1244   
 1245    /**Set the isContinuation flag to the specified value*/
 1246  3 public void setHasAutoGeneratedJunitImport(boolean hasAutoGeneratedJunitImport) {
 1247  3 _hasAutoGeneratedJunitImport = hasAutoGeneratedJunitImport;
 1248    }
 1249   
 1250    /**@return true if this Symbol Data is a primitive type that is a number type*/
 1251  16 public boolean isNumberTypeWithoutAutoboxing() {
 1252  16 return (this == SymbolData.INT_TYPE ||
 1253    this == SymbolData.DOUBLE_TYPE ||
 1254    this == SymbolData.LONG_TYPE ||
 1255    this == SymbolData.CHAR_TYPE ||
 1256    this == SymbolData.FLOAT_TYPE ||
 1257    this == SymbolData.SHORT_TYPE ||
 1258    this == SymbolData.BYTE_TYPE);
 1259    }
 1260   
 1261    /**@return true if this Symbol Data is a primitive type that is a number type or is
 1262    * a Object number type with autoboxing enabled.*/
 1263  268 public boolean isNumberType(JavaVersion version) {
 1264  268 if (!LanguageLevelConverter.versionSupportsAutoboxing(version)) {
 1265  0 return isNumberTypeWithoutAutoboxing();
 1266    }
 1267  268 if (this.isDoubleType(version) ||
 1268    this.isFloatType(version) ||
 1269    this.isLongType(version) ||
 1270    this.isIntType(version) ||
 1271    this.isCharType(version) ||
 1272    this.isShortType(version) ||
 1273    this.isByteType(version)) {
 1274  247 return true;
 1275    }
 1276  21 return false;
 1277    }
 1278   
 1279   
 1280    /**@return true if this is a non float or boolean type, with autoboxing if it is allowed, or without autoboxing*/
 1281  24 public boolean isNonFloatOrBooleanType(JavaVersion version) {
 1282  24 if (!LanguageLevelConverter.versionSupportsAutoboxing(version)) {
 1283  0 return isNonFloatOrBooleanTypeWithoutAutoboxing();
 1284    }
 1285   
 1286  24 return (this.isIntType(version) ||
 1287    this.isLongType(version) ||
 1288    this.isCharType(version) ||
 1289    this.isShortType(version) ||
 1290    this.isByteType(version) ||
 1291    this.isBooleanType(version));
 1292    }
 1293   
 1294    /** @return true if this is a non float or boolean type, without autoboxing*/
 1295  0 public boolean isNonFloatOrBooleanTypeWithoutAutoboxing() {
 1296  0 return (this==SymbolData.INT_TYPE ||
 1297    this==SymbolData.LONG_TYPE ||
 1298    this==SymbolData.CHAR_TYPE ||
 1299    this==SymbolData.SHORT_TYPE ||
 1300    this==SymbolData.BYTE_TYPE ||
 1301    this==SymbolData.BOOLEAN_TYPE);
 1302   
 1303    }
 1304   
 1305   
 1306    /**
 1307    * Returns true if the provided Object is equal to this symbol data.
 1308    * SymbolDatas are equal if their fields are the same.
 1309    * */
 1310  4183195 public boolean equals(Object obj) {
 1311  6 if (obj == null) return false;
 1312  4183189 if ((obj.getClass() != this.getClass())) { //|| (obj.hashCode() != this.hashCode())) {
 1313  707 return false;
 1314    }
 1315  4182482 SymbolData sd = (SymbolData) obj;
 1316   
 1317    /*Return true if the fields are all .equals.*/
 1318   
 1319  4182482 return this.isContinuation() == sd.isContinuation() &&
 1320    this.getMav().equals(sd.getMav()) &&
 1321    LanguageLevelVisitor.arrayEquals(this.getTypeParameters(), sd.getTypeParameters()) &&
 1322    this.getMethods().equals(sd.getMethods()) &&
 1323    this.getSuperClass() == sd.getSuperClass() && //could be null
 1324    this.getInterfaces().equals(sd.getInterfaces()) &&
 1325    this.getOuterData() == sd.getOuterData() && //could be null
 1326    this.getInnerClasses().equals(sd.getInnerClasses()) &&
 1327    this.getName().equals(sd.getName()) &&
 1328    this.getInnerInterfaces().equals(sd.getInnerInterfaces()) &&
 1329    this.getPackage().equals(sd.getPackage()) &&
 1330    this.isInterface() == sd.isInterface();
 1331   
 1332   
 1333    }
 1334   
 1335    /**
 1336    * Since SymbolDatas have unique names, in any given symboltable, hash on the name
 1337    */
 1338  656 public int hashCode() {
 1339  656 return getName().hashCode();
 1340    }
 1341   
 1342    /** Check to see if this class is one of the 5 known classes that implement Runnable. Checking each class recursively
 1343    * to see if it extends Runnable is too time consuming, so we are hoping this short cut will work.
 1344    * Clearly, this has some disadvantages.
 1345    */
 1346  916 public boolean implementsRunnable() {
 1347  916 return this.getName().equals("java.lang.Thread") || this.getName().equals("java.util.TimerTask")
 1348    || this.getName().equals("javax.swing.text.AsyncBoxView$ChildState")
 1349    || this.getName().equals("java.awt.image.renderable.RenderableImageProducer")
 1350    || this.getName().equals("java.util.concurrent.FutureTask");// || this.getName().equals("java.lang.Runnable");
 1351    }
 1352   
 1353    /**Check to see if the interface i appears anywhere in the hierarchy for this class/interface*/
 1354  288 public boolean hasInterface(SymbolData i) {
 1355  0 if (i == null) return false;
 1356   
 1357  8 if (getInterfaces().contains(i)) { return true; }
 1358   
 1359  1 if ((this.getSuperClass() != null) && this.getSuperClass().hasInterface(i)) { return true; }
 1360   
 1361  279 for (int j = 0; j < getInterfaces().size(); j++) {
 1362  6 if (getInterfaces().get(j).hasInterface(i)) return true;
 1363    }
 1364  273 return false;
 1365    }
 1366   
 1367    /**
 1368    * Get all of your vars and all vars that you inherit.
 1369    */
 1370  345 public LinkedList<VariableData> getAllSuperVars() {
 1371  345 LinkedList<VariableData> myVars = new LinkedList<VariableData>();
 1372  345 if (this.getSuperClass() != null) {
 1373  179 myVars.addAll(this.getSuperClass().getVars());
 1374  179 myVars.addAll(this.getSuperClass().getAllSuperVars());
 1375    }
 1376  345 for (int i = 0; i<getInterfaces().size(); i++) {
 1377  19 myVars.addAll(this.getInterfaces().get(i).getVars());
 1378  19 myVars.addAll(this.getInterfaces().get(i).getAllSuperVars());
 1379    }
 1380  345 return myVars;
 1381    }
 1382   
 1383    /** Test the methods defined in the above class */
 1384    public static class SymbolDataTest extends TestCase {
 1385   
 1386    private SymbolData _sd;
 1387   
 1388    private ModifiersAndVisibility _publicMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"public"});
 1389    private ModifiersAndVisibility _protectedMav =
 1390    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"protected"});
 1391    private ModifiersAndVisibility _privateMav =
 1392    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"private"});
 1393    private ModifiersAndVisibility _packageMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[0]);
 1394    private ModifiersAndVisibility _abstractMav =
 1395    new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"abstract"});
 1396    private ModifiersAndVisibility _finalMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"final"});
 1397    private ModifiersAndVisibility _publicFinalMav =
 1398    new ModifiersAndVisibility(SourceInfo.NONE, new String[]{"public", "final"});
 1399   
 1400  0 public SymbolDataTest() {
 1401  0 this("");
 1402    }
 1403  24 public SymbolDataTest(String name) {
 1404  24 super(name);
 1405    }
 1406   
 1407  24 public void setUp() {
 1408  24 _sd = new SymbolData("i.like.monkey");
 1409  24 LanguageLevelVisitor.errors = new LinkedList<Pair<String, JExpressionIF>>();
 1410    }
 1411   
 1412  1 public void testRepeatedSignatures() {
 1413  1 MethodData md = new MethodData("methodName", _publicMav, new TypeParameter[0], SymbolData.INT_TYPE,
 1414    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE),
 1415    new VariableData(SymbolData.BOOLEAN_TYPE)},
 1416    new String[0],
 1417    _sd,
 1418    null);
 1419  1 md.getParams()[0].setEnclosingData(md);
 1420  1 md.getParams()[1].setEnclosingData(md);
 1421  1 LinkedList<MethodData> mds = new LinkedList<MethodData>();
 1422  1 mds.addFirst(md);
 1423    // Test same name, return type, and params from a source file.
 1424  1 MethodData md2 = new MethodData("methodName", _publicMav, new TypeParameter[0], SymbolData.INT_TYPE,
 1425    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE),
 1426    new VariableData(SymbolData.BOOLEAN_TYPE) },
 1427    new String[0],
 1428    _sd,
 1429    null);
 1430  1 md2.getParams()[0].setEnclosingData(md2);
 1431  1 md2.getParams()[1].setEnclosingData(md2);
 1432   
 1433  1 assertTrue("repeatedSignatures should return md exactly.", md == _sd.repeatedSignature(mds, md2));
 1434    // Test same name, return type, and params from a class file.
 1435  1 MethodData md3 = new MethodData("methodName", _publicMav, new TypeParameter[0], SymbolData.INT_TYPE,
 1436    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE),
 1437    new VariableData(SymbolData.BOOLEAN_TYPE) },
 1438    new String[0],
 1439    _sd,
 1440    null);
 1441  1 md3.getParams()[0].setEnclosingData(md3);
 1442  1 md3.getParams()[1].setEnclosingData(md3);
 1443   
 1444  1 assertTrue("repeatedSignatures should return md exactly.", md == _sd.repeatedSignature(mds, md3, true));
 1445    // Test same name, different return type, and params from a class file.
 1446  1 MethodData md4 = new MethodData("methodName", _publicMav, new TypeParameter[0], SymbolData.SHORT_TYPE,
 1447    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE),
 1448    new VariableData(SymbolData.BOOLEAN_TYPE) },
 1449    new String[0],
 1450    _sd,
 1451    null);
 1452  1 md4.getParams()[0].setEnclosingData(md4);
 1453  1 md4.getParams()[1].setEnclosingData(md4);
 1454   
 1455   
 1456  1 assertEquals("repeatedSignatures should return null.", null, _sd.repeatedSignature(mds, md4, true));
 1457    // Test same name, return type, and different params from a source file.
 1458  1 MethodData md5 = new MethodData("methodName", _publicMav, new TypeParameter[0], SymbolData.SHORT_TYPE,
 1459    new VariableData[] { new VariableData(SymbolData.BOOLEAN_TYPE) },
 1460    new String[0],
 1461    _sd,
 1462    null);
 1463  1 md5.getParams()[0].setEnclosingData(md5);
 1464   
 1465  1 assertEquals("repeatedSignatures should return null.", null, _sd.repeatedSignature(mds, md5));
 1466    // Test same name, return type, and different order params from a source file.
 1467  1 MethodData md6= new MethodData("methodName", _publicMav, new TypeParameter[0], SymbolData.SHORT_TYPE,
 1468    new VariableData[] { new VariableData(SymbolData.BOOLEAN_TYPE),
 1469    new VariableData(SymbolData.CHAR_TYPE) },
 1470    new String[0],
 1471    _sd,
 1472    null);
 1473  1 md6.getParams()[0].setEnclosingData(md6);
 1474  1 md6.getParams()[1].setEnclosingData(md6);
 1475   
 1476  1 assertEquals("repeatedSignatures should return null.", null, _sd.repeatedSignature(mds, md6));
 1477    }
 1478   
 1479  1 public void testCheckDifferentReturnTypes() {
 1480   
 1481  1 TypeChecker.errors = new LinkedList<Pair<String, JExpressionIF>>();
 1482   
 1483    // Create a super class and give it a method.
 1484  1 SymbolData superSd = new SymbolData("superClass");
 1485  1 MethodData md = new MethodData("methodName",
 1486    _publicMav,
 1487    new TypeParameter[0],
 1488    SymbolData.INT_TYPE,
 1489    new VariableData[0],
 1490    new String[0],
 1491    superSd,
 1492    null);
 1493  1 superSd.addMethod(md);
 1494  1 _sd.setSuperClass(superSd);
 1495    // Test with an exact copy of the method.
 1496  1 MethodData md2 = new MethodData("methodName",
 1497    _publicMav,
 1498    new TypeParameter[0],
 1499    SymbolData.INT_TYPE,
 1500    new VariableData[0],
 1501    new String[0],
 1502    _sd,
 1503    null);
 1504  1 assertFalse("There should not be a conflict.", checkDifferentReturnTypes(md2, _sd, JavaVersion.JAVA_5));
 1505  1 assertEquals("There should not be an error.", 0, TypeChecker.errors.size());
 1506    // Test with an exact copy of the method except for differing return types.
 1507  1 MethodData md3 = new MethodData("methodName",
 1508    _publicMav,
 1509    new TypeParameter[0],
 1510    SymbolData.CHAR_TYPE,
 1511    new VariableData[0],
 1512    new String[0],
 1513    _sd,
 1514    null);
 1515  1 assertTrue("There should be a conflict.", checkDifferentReturnTypes(md3, _sd, JavaVersion.JAVA_5));
 1516  1 assertEquals("There should be one error.", 1, TypeChecker.errors.size());
 1517  1 assertEquals("The error message should be correct.",
 1518    "methodName() in i.like.monkey cannot override methodName() in superClass;" +
 1519    " attempting to use different return types",
 1520    TypeChecker.errors.get(0).getFirst());
 1521    // Create a super super class and give it a method.
 1522  1 SymbolData superSuperSd = new SymbolData("superSuperClass");
 1523  1 MethodData md4 = new MethodData("superSuperMethodName",
 1524    _publicMav,
 1525    new TypeParameter[0],
 1526    SymbolData.INT_TYPE,
 1527    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE) },
 1528    new String[0],
 1529    superSuperSd,
 1530    null);
 1531  1 md4.getParams()[0].setEnclosingData(md4);
 1532  1 superSuperSd.addMethod(md4);
 1533  1 superSd.setSuperClass(superSuperSd);
 1534    // Test with an exact copy except for differing parameters.
 1535  1 MethodData md5 = new MethodData("superSuperMethodName",
 1536    _publicMav,
 1537    new TypeParameter[0],
 1538    SymbolData.INT_TYPE,
 1539    new VariableData[0],
 1540    new String[0],
 1541    null,
 1542    null);
 1543  1 assertFalse("There should not be a conflict.", checkDifferentReturnTypes(md5, _sd, JavaVersion.JAVA_5));
 1544  1 assertEquals("There should still be one error.", 1, TypeChecker.errors.size());
 1545    // Test with an exact copy except for diffeing return types.
 1546  1 MethodData md6 = new MethodData("superSuperMethodName",
 1547    _publicMav,
 1548    new TypeParameter[0],
 1549    SymbolData.BYTE_TYPE,
 1550    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE) },
 1551    new String[0],
 1552    null,
 1553    null);
 1554  1 md6.getParams()[0].setEnclosingData(md6);
 1555  1 assertTrue("There should be a conflict.", checkDifferentReturnTypes(md6, _sd, JavaVersion.JAVA_5));
 1556  1 assertEquals("There should be two errors.", 2, TypeChecker.errors.size());
 1557   
 1558    //Test a method that restricts the mav of the super class's method
 1559  1 MethodData md7 = new MethodData("superSuperMethodName",
 1560    _privateMav,
 1561    new TypeParameter[0],
 1562    SymbolData.INT_TYPE,
 1563    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE) },
 1564    new String[0],
 1565    new SymbolData("myData"),
 1566    null);
 1567   
 1568  1 md7.getParams()[0].setEnclosingData(md7);
 1569  1 assertTrue("There should be a conflict", checkDifferentReturnTypes(md7, _sd, JavaVersion.JAVA_5));
 1570  1 assertEquals("There should be three errors", 3, TypeChecker.errors.size());
 1571  1 assertEquals("The error message should be correct",
 1572    "superSuperMethodName in myData cannot override superSuperMethodName in " + superSuperSd.getName() +
 1573    ". You are attempting to assign weaker access priviledges. In " + superSuperSd.getName() +
 1574    ", superSuperMethodName was public", TypeChecker.errors.get(2).getFirst());
 1575   
 1576   
 1577    //Test a method that narrows the return type of the super class's method
 1578  1 SymbolData stringSd = new SymbolData("java.lang.String");
 1579  1 stringSd.setIsContinuation(false);
 1580  1 stringSd.setSuperClass(SymbolData.INT_TYPE);
 1581   
 1582  1 MethodData md8 = new MethodData("superSuperMethodName",
 1583    _publicMav,
 1584    new TypeParameter[0],
 1585    stringSd,
 1586    new VariableData[] {new VariableData(SymbolData.CHAR_TYPE)},
 1587    new String[0],
 1588    new SymbolData("myData"),
 1589    null);
 1590   
 1591  1 assertFalse("There should be no conflict", checkDifferentReturnTypes(md8, _sd, JavaVersion.JAVA_5));
 1592  1 assertEquals("There should still be 3 errors", 3, TypeChecker.errors.size());
 1593    /* Java 1.4 is not supported. */
 1594    // assertTrue("There should be a conflict in 1.4", checkDifferentReturnTypes(md8, _sd, JavaVersion.JAVA_1_4));
 1595    // assertEquals("There should now be 4 errors", 4, TypeChecker.errors.size());
 1596    // assertEquals("The error message should be correct", TypeChecker.errors.getLast().getFirst(),
 1597    // "superSuperMethodName(char) in superClass cannot override superSuperMethodName(char) in " +
 1598    // superSuperSd.getName() + "; attempting to use different return types");
 1599    }
 1600   
 1601  1 public void test_createErrorMessage() {
 1602    // Test with a method with no parameters.
 1603  1 MethodData md = new MethodData("methodName",
 1604    _publicMav,
 1605    new TypeParameter[0],
 1606    SymbolData.INT_TYPE,
 1607    new VariableData[0],
 1608    new String[0],
 1609    _sd,
 1610    null);
 1611  1 assertEquals("The error message should be correct.",
 1612    "In the class \"i.like.monkey\", you cannot have two methods with the same name: \"methodName\"",
 1613    _sd._createErrorMessage(md));
 1614    // Test with a method with one parameter.
 1615  1 MethodData md2 = new MethodData("superSuperMethodName",
 1616    _publicMav,
 1617    new TypeParameter[0],
 1618    SymbolData.INT_TYPE,
 1619    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE) },
 1620    new String[0],
 1621    _sd,
 1622    null);
 1623  1 assertEquals("The error message should be correct.",
 1624    "In the class \"i.like.monkey\", you cannot have two methods with the same name: "
 1625    + "\"superSuperMethodName\" and parameter type: char",
 1626    _sd._createErrorMessage(md2));
 1627  1 md2.getParams()[0].setEnclosingData(md2);
 1628    // Test with a method with two parameters.
 1629  1 MethodData md3 = new MethodData("superSuperMethodName",
 1630    _publicMav,
 1631    new TypeParameter[0],
 1632    SymbolData.INT_TYPE,
 1633    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE),
 1634    new VariableData(SymbolData.CHAR_TYPE) },
 1635    new String[0],
 1636    _sd,
 1637    null);
 1638  1 md3.getParams()[0].setEnclosingData(md3);
 1639  1 md3.getParams()[1].setEnclosingData(md3);
 1640   
 1641  1 assertEquals("The error message should be correct.",
 1642    "In the class \"i.like.monkey\", you cannot have two methods with the same name: "
 1643    + "\"superSuperMethodName\" and parameter types: char, char",
 1644    _sd._createErrorMessage(md3));
 1645   
 1646    }
 1647   
 1648  1 public void testAddMethod() {
 1649  1 MethodData md = new MethodData("methodName", _publicMav, new TypeParameter[0], SymbolData.INT_TYPE,
 1650    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE),
 1651    new VariableData(SymbolData.BOOLEAN_TYPE)},
 1652    new String[0],
 1653    _sd,
 1654    null);
 1655   
 1656  1 md.getParams()[0].setEnclosingData(md);
 1657  1 md.getParams()[1].setEnclosingData(md);
 1658   
 1659  1 _sd.addMethod(md);
 1660  1 assertEquals("There should be no errors.", 0, LanguageLevelVisitor.errors.size());
 1661    // Test same name, return type, and params from a source file.
 1662  1 MethodData md2 = new MethodData("methodName", _publicMav, new TypeParameter[0], SymbolData.INT_TYPE,
 1663    new VariableData[] { new VariableData(SymbolData.CHAR_TYPE),
 1664    new VariableData(SymbolData.BOOLEAN_TYPE) },
 1665    new String[0],
 1666    _sd,
 1667    null);
 1668  1 md2.getParams()[0].setEnclosingData(md2);
 1669  1 md2.getParams()[1].setEnclosingData(md2);
 1670   
 1671  1 _sd.addMethod(md2);
 1672  1 assertEquals("There should be one error.", 1, LanguageLevelVisitor.errors.size());
 1673  1 assertEquals("The error message should be correct.", "In the class \"" + _sd.getName() +
 1674    "\", you cannot have two methods with the same name: \"" + md.getName()
 1675    + "\" and parameter types: char, boolean",
 1676    LanguageLevelVisitor.errors.get(0).getFirst());
 1677  1 MethodData md4 = new MethodData("methodName",
 1678    _publicMav,
 1679    new TypeParameter[0],
 1680    SymbolData.INT_TYPE,
 1681    new VariableData[0],
 1682    new String[0],
 1683    _sd,
 1684    null);
 1685  1 _sd.addMethod(md4);
 1686  1 assertEquals("There should still be one error.", 1, LanguageLevelVisitor.errors.size());
 1687  1 MethodData md5 = new MethodData("methodNamePlusStuff",
 1688    _publicMav,
 1689    new TypeParameter[0],
 1690    SymbolData.INT_TYPE,
 1691    new VariableData[0],
 1692    new String[0],
 1693    _sd,
 1694    null);
 1695  1 _sd.addMethod(md5);
 1696  1 assertEquals("There should still be one error.", 1, LanguageLevelVisitor.errors.size());
 1697    // Check that _sd only has two methods, the original md and md5.
 1698  1 assertEquals("There are three methods in _sd.", 3, _sd.getMethods().size());
 1699  1 assertEquals("The original method was added.", md, _sd.getMethods().get(0));
 1700  1 assertEquals("md5 was added.", md5, _sd.getMethods().get(2));
 1701   
 1702    // Check that adding a method from augmented code produces the correct error message.
 1703  1 _sd.addMethod(md2, true);
 1704  1 assertEquals("There should be two errors.", 2, LanguageLevelVisitor.errors.size());
 1705  1 assertEquals("The error message should be correct.",
 1706    "This method's signature conflicts with an automatically generated method's signature",
 1707    LanguageLevelVisitor.errors.get(1).getFirst());
 1708    }
 1709   
 1710  1 public void testIsNumberType() {
 1711  1 assertTrue(SymbolData.INT_TYPE.isNumberType(JavaVersion.JAVA_5));
 1712  1 assertTrue(new SymbolData("java.lang.Integer").isNumberType(JavaVersion.JAVA_5));
 1713  1 assertTrue(SymbolData.DOUBLE_TYPE.isNumberType(JavaVersion.JAVA_5));
 1714  1 assertTrue(new SymbolData("java.lang.Double").isNumberType(JavaVersion.JAVA_5));
 1715  1 assertTrue(SymbolData.LONG_TYPE.isNumberType(JavaVersion.JAVA_5));
 1716  1 assertTrue(new SymbolData("java.lang.Long").isNumberType(JavaVersion.JAVA_5));
 1717  1 assertTrue(SymbolData.CHAR_TYPE.isNumberType(JavaVersion.JAVA_5));
 1718  1 assertTrue(new SymbolData("java.lang.Character").isNumberType(JavaVersion.JAVA_5));
 1719  1 assertTrue(SymbolData.FLOAT_TYPE.isNumberType(JavaVersion.JAVA_5));
 1720  1 assertTrue(new SymbolData("java.lang.Float").isNumberType(JavaVersion.JAVA_5));
 1721  1 assertTrue(SymbolData.SHORT_TYPE.isNumberType(JavaVersion.JAVA_5));
 1722  1 assertTrue(new SymbolData("java.lang.Short").isNumberType(JavaVersion.JAVA_5));
 1723  1 assertTrue(SymbolData.BYTE_TYPE.isNumberType(JavaVersion.JAVA_5));
 1724  1 assertTrue(new SymbolData("java.lang.Byte").isNumberType(JavaVersion.JAVA_5));
 1725  1 assertFalse(SymbolData.BOOLEAN_TYPE.isNumberType(JavaVersion.JAVA_5));
 1726  1 assertFalse(new SymbolData("java.lang.Boolean").isNumberType(JavaVersion.JAVA_5));
 1727    }
 1728   
 1729  1 public void testIsNumberTypeWithoutAutoboxing() {
 1730  1 assertTrue(SymbolData.INT_TYPE.isNumberTypeWithoutAutoboxing());
 1731  1 assertFalse((new SymbolData("java.lang.Integer")).isNumberTypeWithoutAutoboxing());
 1732  1 assertTrue(SymbolData.DOUBLE_TYPE.isNumberTypeWithoutAutoboxing());
 1733  1 assertFalse((new SymbolData("java.lang.Double")).isNumberTypeWithoutAutoboxing());
 1734  1 assertTrue(SymbolData.LONG_TYPE.isNumberTypeWithoutAutoboxing());
 1735  1 assertFalse((new SymbolData("java.lang.Long")).isNumberTypeWithoutAutoboxing());
 1736  1 assertTrue(SymbolData.CHAR_TYPE.isNumberTypeWithoutAutoboxing());
 1737  1 assertFalse((new SymbolData("java.lang.Character")).isNumberTypeWithoutAutoboxing());
 1738  1 assertTrue(SymbolData.FLOAT_TYPE.isNumberTypeWithoutAutoboxing());
 1739  1 assertFalse((new SymbolData("java.lang.Float")).isNumberTypeWithoutAutoboxing());
 1740  1 assertTrue(SymbolData.SHORT_TYPE.isNumberTypeWithoutAutoboxing());
 1741  1 assertFalse((new SymbolData("java.lang.Short")).isNumberTypeWithoutAutoboxing());
 1742  1 assertTrue(SymbolData.BYTE_TYPE.isNumberTypeWithoutAutoboxing());
 1743  1 assertFalse((new SymbolData("java.lang.Byte")).isNumberTypeWithoutAutoboxing());
 1744  1 assertFalse(SymbolData.BOOLEAN_TYPE.isNumberTypeWithoutAutoboxing());
 1745  1 assertFalse((new SymbolData("java.lang.Boolean")).isNumberTypeWithoutAutoboxing());
 1746    }
 1747   
 1748   
 1749  1 public void testIsIntType() {
 1750  1 assertTrue(SymbolData.INT_TYPE.isIntType(JavaVersion.JAVA_5));
 1751  1 assertTrue((new SymbolData("java.lang.Integer")).isIntType(JavaVersion.JAVA_5));
 1752  1 assertFalse(SymbolData.DOUBLE_TYPE.isIntType(JavaVersion.JAVA_5));
 1753  1 assertFalse((new SymbolData("java.lang.Double")).isIntType(JavaVersion.JAVA_5));
 1754  1 assertFalse(SymbolData.LONG_TYPE.isIntType(JavaVersion.JAVA_5));
 1755  1 assertFalse((new SymbolData("java.lang.Long")).isIntType(JavaVersion.JAVA_5));
 1756  1 assertFalse(SymbolData.CHAR_TYPE.isIntType(JavaVersion.JAVA_5));
 1757  1 assertFalse((new SymbolData("java.lang.Character")).isIntType(JavaVersion.JAVA_5));
 1758  1 assertFalse(SymbolData.FLOAT_TYPE.isIntType(JavaVersion.JAVA_5));
 1759  1 assertFalse((new SymbolData("java.lang.Float")).isIntType(JavaVersion.JAVA_5));
 1760  1 assertFalse(SymbolData.SHORT_TYPE.isIntType(JavaVersion.JAVA_5));
 1761  1 assertFalse((new SymbolData("java.lang.Short")).isIntType(JavaVersion.JAVA_5));
 1762  1 assertFalse(SymbolData.BYTE_TYPE.isIntType(JavaVersion.JAVA_5));
 1763  1 assertFalse((new SymbolData("java.lang.Byte")).isIntType(JavaVersion.JAVA_5));
 1764  1 assertFalse(SymbolData.BOOLEAN_TYPE.isIntType(JavaVersion.JAVA_5));
 1765  1 assertFalse((new SymbolData("java.lang.Boolean")).isIntType(JavaVersion.JAVA_5));
 1766    }
 1767   
 1768   
 1769  1 public void testIsDoubleType() {
 1770  1 assertFalse(SymbolData.INT_TYPE.isDoubleType(JavaVersion.JAVA_5));
 1771  1 assertFalse((new SymbolData("java.lang.Integer")).isDoubleType(JavaVersion.JAVA_5));
 1772  1 assertTrue(SymbolData.DOUBLE_TYPE.isDoubleType(JavaVersion.JAVA_5));
 1773  1 assertTrue((new SymbolData("java.lang.Double")).isDoubleType(JavaVersion.JAVA_5));
 1774  1 assertFalse(SymbolData.CHAR_TYPE.isDoubleType(JavaVersion.JAVA_5));
 1775  1 assertFalse((new SymbolData("java.lang.Character")).isDoubleType(JavaVersion.JAVA_5));
 1776  1 assertFalse(SymbolData.FLOAT_TYPE.isDoubleType(JavaVersion.JAVA_5));
 1777  1 assertFalse((new SymbolData("java.lang.Float")).isDoubleType(JavaVersion.JAVA_5));
 1778  1 assertFalse(SymbolData.SHORT_TYPE.isDoubleType(JavaVersion.JAVA_5));
 1779  1 assertFalse((new SymbolData("java.lang.Short")).isDoubleType(JavaVersion.JAVA_5));
 1780  1 assertFalse(SymbolData.BYTE_TYPE.isDoubleType(JavaVersion.JAVA_5));
 1781  1 assertFalse((new SymbolData("java.lang.Byte")).isDoubleType(JavaVersion.JAVA_5));
 1782  1 assertFalse(SymbolData.BOOLEAN_TYPE.isDoubleType(JavaVersion.JAVA_5));
 1783  1 assertFalse((new SymbolData("java.lang.Boolean")).isDoubleType(JavaVersion.JAVA_5));
 1784    }
 1785   
 1786  1 public void testIsCharType() {
 1787  1 assertFalse(SymbolData.INT_TYPE.isCharType(JavaVersion.JAVA_5));
 1788  1 assertFalse((new SymbolData("java.lang.Integer")).isCharType(JavaVersion.JAVA_5));
 1789  1 assertFalse(SymbolData.DOUBLE_TYPE.isCharType(JavaVersion.JAVA_5));
 1790  1 assertFalse((new SymbolData("java.lang.Double")).isCharType(JavaVersion.JAVA_5));
 1791  1 assertTrue(SymbolData.CHAR_TYPE.isCharType(JavaVersion.JAVA_5));
 1792  1 assertTrue((new SymbolData("java.lang.Character")).isCharType(JavaVersion.JAVA_5));
 1793  1 assertFalse(SymbolData.FLOAT_TYPE.isCharType(JavaVersion.JAVA_5));
 1794  1 assertFalse((new SymbolData("java.lang.Float")).isCharType(JavaVersion.JAVA_5));
 1795  1 assertFalse(SymbolData.SHORT_TYPE.isCharType(JavaVersion.JAVA_5));
 1796  1 assertFalse((new SymbolData("java.lang.Short")).isCharType(JavaVersion.JAVA_5));
 1797  1 assertFalse(SymbolData.BYTE_TYPE.isCharType(JavaVersion.JAVA_5));
 1798  1 assertFalse((new SymbolData("java.lang.Byte")).isCharType(JavaVersion.JAVA_5));
 1799  1 assertFalse(SymbolData.BOOLEAN_TYPE.isCharType(JavaVersion.JAVA_5));
 1800  1 assertFalse((new SymbolData("java.lang.Boolean")).isCharType(JavaVersion.JAVA_5));
 1801    }
 1802   
 1803  1 public void testIsFloatType() {
 1804  1 assertFalse(SymbolData.INT_TYPE.isFloatType(JavaVersion.JAVA_5));
 1805  1 assertFalse((new SymbolData("java.lang.Integer")).isFloatType(JavaVersion.JAVA_5));
 1806  1 assertFalse(SymbolData.DOUBLE_TYPE.isFloatType(JavaVersion.JAVA_5));
 1807  1 assertFalse((new SymbolData("java.lang.Double")).isFloatType(JavaVersion.JAVA_5));
 1808  1 assertFalse(SymbolData.CHAR_TYPE.isFloatType(JavaVersion.JAVA_5));
 1809  1 assertFalse((new SymbolData("java.lang.Character")).isFloatType(JavaVersion.JAVA_5));
 1810  1 assertTrue(SymbolData.FLOAT_TYPE.isFloatType(JavaVersion.JAVA_5));
 1811  1 assertTrue((new SymbolData("java.lang.Float")).isFloatType(JavaVersion.JAVA_5));
 1812  1 assertFalse(SymbolData.SHORT_TYPE.isFloatType(JavaVersion.JAVA_5));
 1813  1 assertFalse((new SymbolData("java.lang.Short")).isFloatType(JavaVersion.JAVA_5));
 1814  1 assertFalse(SymbolData.BYTE_TYPE.isFloatType(JavaVersion.JAVA_5));
 1815  1 assertFalse((new SymbolData("java.lang.Byte")).isFloatType(JavaVersion.JAVA_5));
 1816  1 assertFalse(SymbolData.BOOLEAN_TYPE.isFloatType(JavaVersion.JAVA_5));
 1817  1 assertFalse((new SymbolData("java.lang.Boolean")).isFloatType(JavaVersion.JAVA_5));
 1818    }
 1819   
 1820   
 1821  1 public void testIsByteType() {
 1822  1 assertFalse(SymbolData.INT_TYPE.isByteType(JavaVersion.JAVA_5));
 1823  1 assertFalse((new SymbolData("java.lang.Integer")).isByteType(JavaVersion.JAVA_5));
 1824  1 assertFalse(SymbolData.DOUBLE_TYPE.isByteType(JavaVersion.JAVA_5));
 1825  1 assertFalse((new SymbolData("java.lang.Double")).isByteType(JavaVersion.JAVA_5));
 1826  1 assertFalse(SymbolData.CHAR_TYPE.isByteType(JavaVersion.JAVA_5));
 1827  1 assertFalse((new SymbolData("java.lang.Character")).isByteType(JavaVersion.JAVA_5));
 1828  1 assertFalse(SymbolData.FLOAT_TYPE.isByteType(JavaVersion.JAVA_5));
 1829  1 assertFalse((new SymbolData("java.lang.Float")).isByteType(JavaVersion.JAVA_5));
 1830  1 assertFalse(SymbolData.SHORT_TYPE.isByteType(JavaVersion.JAVA_5));
 1831  1 assertFalse((new SymbolData("java.lang.Short")).isByteType(JavaVersion.JAVA_5));
 1832  1 assertTrue(SymbolData.BYTE_TYPE.isByteType(JavaVersion.JAVA_5));
 1833  1 assertTrue((new SymbolData("java.lang.Byte")).isByteType(JavaVersion.JAVA_5));
 1834  1 assertFalse(SymbolData.BOOLEAN_TYPE.isByteType(JavaVersion.JAVA_5));
 1835  1 assertFalse((new SymbolData("java.lang.Boolean")).isByteType(JavaVersion.JAVA_5));
 1836    }
 1837   
 1838  1 public void testIsBooleanType() {
 1839  1 assertFalse(SymbolData.INT_TYPE.isBooleanType(JavaVersion.JAVA_5));
 1840  1 assertFalse((new SymbolData("java.lang.Integer")).isBooleanType(JavaVersion.JAVA_5));
 1841  1 assertFalse(SymbolData.DOUBLE_TYPE.isBooleanType(JavaVersion.JAVA_5));
 1842  1 assertFalse((new SymbolData("java.lang.Double")).isBooleanType(JavaVersion.JAVA_5));
 1843  1 assertFalse(SymbolData.CHAR_TYPE.isBooleanType(JavaVersion.JAVA_5));
 1844  1 assertFalse((new SymbolData("java.lang.Character")).isBooleanType(JavaVersion.JAVA_5));
 1845  1 assertFalse(SymbolData.FLOAT_TYPE.isBooleanType(JavaVersion.JAVA_5));
 1846  1 assertFalse((new SymbolData("java.lang.Float")).isBooleanType(JavaVersion.JAVA_5));
 1847  1 assertFalse(SymbolData.SHORT_TYPE.isBooleanType(JavaVersion.JAVA_5));
 1848  1 assertFalse((new SymbolData("java.lang.Short")).isBooleanType(JavaVersion.JAVA_5));
 1849  1 assertFalse(SymbolData.BYTE_TYPE.isBooleanType(JavaVersion.JAVA_5));
 1850  1 assertFalse((new SymbolData("java.lang.Byte")).isBooleanType(JavaVersion.JAVA_5));
 1851  1 assertTrue(SymbolData.BOOLEAN_TYPE.isBooleanType(JavaVersion.JAVA_5));
 1852  1 assertTrue((new SymbolData("java.lang.Boolean")).isBooleanType(JavaVersion.JAVA_5));
 1853    }
 1854   
 1855  1 public void testIsNonFloatOrBooleanType() {
 1856  1 assertTrue(SymbolData.INT_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1857  1 assertTrue(new SymbolData("java.lang.Integer").isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1858  1 assertFalse(SymbolData.DOUBLE_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1859  1 assertFalse(new SymbolData("java.lang.Double").isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1860  1 assertTrue(SymbolData.CHAR_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1861  1 assertTrue(new SymbolData("java.lang.Character").isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1862  1 assertFalse(SymbolData.FLOAT_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1863  1 assertFalse(new SymbolData("java.lang.Float").isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1864  1 assertTrue(SymbolData.SHORT_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1865  1 assertTrue(new SymbolData("java.lang.Short").isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1866  1 assertTrue(SymbolData.BYTE_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1867  1 assertTrue(new SymbolData("java.lang.Byte").isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1868  1 assertTrue(SymbolData.LONG_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1869  1 assertTrue(new SymbolData("java.lang.Long").isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1870  1 assertTrue(SymbolData.BOOLEAN_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1871  1 assertTrue(new SymbolData("java.lang.Boolean").isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1872   
 1873    }
 1874   
 1875  1 public void testIsNonFloatOrBooleanTypeWithoutAutoboxing() {
 1876  1 assertTrue(SymbolData.INT_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1877  1 assertFalse(SymbolData.DOUBLE_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1878  1 assertTrue(SymbolData.CHAR_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1879  1 assertFalse(SymbolData.FLOAT_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1880  1 assertTrue(SymbolData.SHORT_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1881  1 assertTrue(SymbolData.BYTE_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1882  1 assertTrue(SymbolData.LONG_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1883  1 assertTrue(SymbolData.BOOLEAN_TYPE.isNonFloatOrBooleanType(JavaVersion.JAVA_5));
 1884    }
 1885   
 1886   
 1887  1 public void testEquals() {
 1888  1 SymbolData superSd = new SymbolData("superClass");
 1889  1 _sd =
 1890    new SymbolData("i.like.monkey", _publicMav, new TypeParameter[0], superSd, new ArrayList<SymbolData>(), null);
 1891   
 1892    //check variables that are equal;
 1893  1 SymbolData _sd2 =
 1894    new SymbolData("i.like.monkey", _publicMav, new TypeParameter[0], superSd, new ArrayList<SymbolData>(), null);
 1895  1 assertTrue("Equals should return true if two SymbolDatas are equal", _sd.equals(_sd2));
 1896  1 assertTrue("Equals should return true in opposite direction as well", _sd2.equals(_sd));
 1897   
 1898    //comparison to null
 1899  1 assertFalse("Equals should return false if SymbolData is compared to null",_sd.equals(null));
 1900   
 1901    //different names
 1902  1 _sd2 = new SymbolData("q", _publicMav, new TypeParameter[0], superSd, new ArrayList<SymbolData>(), null);
 1903  1 assertFalse("Equals should return false if class names are different", _sd.equals(_sd2));
 1904   
 1905    //different MAV
 1906  1 _sd2 =
 1907    new SymbolData("i.like.monkey", _protectedMav, new TypeParameter[0], superSd, new ArrayList<SymbolData>(), null);
 1908  1 assertFalse("Equals should return false if class modifiers are different", _sd.equals(_sd2));
 1909   
 1910    //different type parameters
 1911  1 _sd2 =
 1912    new SymbolData("i.like.monkey",
 1913    _publicMav,
 1914    new TypeParameter[] { new TypeParameter(SourceInfo.NONE,
 1915    new TypeVariable(SourceInfo.NONE,"tv"),
 1916    new TypeVariable(SourceInfo.NONE,"i")) },
 1917    superSd,
 1918    new ArrayList<SymbolData>(), null);
 1919  1 assertFalse("Equals should return false if class type parameters are different", _sd.equals(_sd2));
 1920   
 1921    //different super classes
 1922  1 _sd2 = new SymbolData("i.like.monkey", _publicMav, new TypeParameter[0], null, new ArrayList<SymbolData>(), null);
 1923  1 assertFalse("Equals should return false if super classes are different", _sd.equals(_sd2));
 1924   
 1925    //different interfaces
 1926  1 ArrayList<SymbolData> interfaces = new ArrayList<SymbolData>();
 1927  1 interfaces.add(SymbolData.INT_TYPE);
 1928  1 _sd2 = new SymbolData("i.like.monkey", _publicMav, new TypeParameter[0], superSd, interfaces, null);
 1929  1 assertFalse("Equals should return false if the interfaces are different", _sd.equals(_sd2));
 1930    }
 1931   
 1932  1 public void testImplementsRunnable() {
 1933  1 SymbolData sd1 = new SymbolData("java.lang.Thread");
 1934  1 SymbolData sd2 = new SymbolData("java.util.TimerTask");
 1935  1 SymbolData sd3 = new SymbolData("javax.swing.text.AsyncBoxView$ChildState");
 1936  1 SymbolData sd4 = new SymbolData("java.awt.image.renderable.RenderableImageProducer");
 1937  1 SymbolData sd5 = new SymbolData("java.util.concurrent.FutureTask");
 1938  1 SymbolData sd6 = new SymbolData("java.util.Vector");
 1939  1 assertTrue("Should implement Runnable", sd1.implementsRunnable());
 1940  1 assertTrue("Should implement Runnable", sd2.implementsRunnable());
 1941  1 assertTrue("Should implement Runnable", sd3.implementsRunnable());
 1942  1 assertTrue("Should implement Runnable", sd4.implementsRunnable());
 1943  1 assertTrue("Should implement Runnable", sd5.implementsRunnable());
 1944  1 assertFalse("Should not implement Runnable", sd6.implementsRunnable());
 1945    }
 1946   
 1947  1 public void testHasInterface() {
 1948    /* Runnable has two subinterfacers, subRunnable and subRunnable2. subRunnable has a subclass someSd and
 1949    subRunnable2 has a subclass someOtherSd. */
 1950   
 1951  1 SymbolData runnable = new SymbolData("java.lang.Runnable");
 1952  1 runnable.setInterface(true);
 1953  1 SymbolData subRunnable = new SymbolData("edgar");
 1954  1 subRunnable.setInterface(true);
 1955  1 subRunnable.addInterface(runnable);
 1956  1 assertTrue(subRunnable.hasInterface(runnable));
 1957  1 SymbolData subRunnable2 = new SymbolData("jones");
 1958  1 subRunnable2.setInterface(true);
 1959  1 subRunnable2.addInterface(runnable);
 1960  1 assertTrue(subRunnable2.hasInterface(runnable));
 1961  1 SymbolData someSd = new SymbolData("someSd");
 1962  1 someSd.addInterface(subRunnable);
 1963  1 assertTrue(someSd.hasInterface(runnable));
 1964  1 SymbolData someOtherSd = new SymbolData("someOtherSd");
 1965  1 someOtherSd.addInterface(subRunnable2);
 1966  1 assertTrue(someOtherSd.hasInterface(runnable));
 1967  1 SymbolData notRunnable = new SymbolData("aksdf");
 1968  1 assertFalse(notRunnable.hasInterface(runnable));
 1969  1 someOtherSd.addInterface(notRunnable);
 1970  1 assertTrue(someOtherSd.hasInterface(runnable));
 1971   
 1972    // Try myClass without setting a super class, then try it once it's super class is someSd.
 1973  1 SymbolData myClass = new SymbolData("myClass");
 1974  1 assertFalse(myClass.hasInterface(runnable));
 1975  1 myClass.setSuperClass(someSd);
 1976  1 assertTrue(myClass.hasInterface(runnable));
 1977  1 SymbolData myClass2 = new SymbolData("myClass2");
 1978  1 assertFalse(myClass2.hasInterface(runnable));
 1979  1 myClass2.addInterface(someOtherSd);
 1980  1 assertTrue(myClass2.hasInterface(runnable));
 1981    }
 1982   
 1983  1 public void test_isAssignable() {
 1984  1 MethodData md =
 1985    new MethodData("Overwritten", _publicMav, new TypeParameter[0], _sd, new VariableData[0], new String[0], _sd,
 1986    new NullLiteral(SourceInfo.NONE));
 1987  1 MethodData md2 =
 1988    new MethodData("Overwriting", _publicMav, new TypeParameter[0], _sd, new VariableData[0], new String[0], _sd,
 1989    new NullLiteral(SourceInfo.NONE));
 1990   
 1991    //tests a wide variety of possibilities, but not all possibilities.
 1992  1 assertTrue("Should be assignable", _isCompatible(md, md2));
 1993  1 md.setMav(_protectedMav);
 1994  1 assertTrue("Should be assignable", _isCompatible(md, md2));
 1995  1 md.setMav(_privateMav);
 1996  1 assertTrue("Should be assignable", _isCompatible(md, md2));
 1997  1 md.setMav(_packageMav);
 1998  1 assertTrue("Should be assignable", _isCompatible(md, md2));
 1999  1 md2.setMav(_protectedMav);
 2000  1 assertTrue("Should be assignable", _isCompatible(md, md2));
 2001  1 md2.setMav(_privateMav);
 2002  1 assertFalse("Should not be assignable", _isCompatible(md, md2));
 2003  1 md2.setMav(_packageMav);
 2004  1 assertTrue("Should be assignable", _isCompatible(md, md2));
 2005   
 2006    }
 2007   
 2008   
 2009  1 public void testRepeatedNameInHierarchy() {
 2010  1 SymbolData _d = new SymbolData("myname");
 2011   
 2012  1 VariableData vd = new VariableData("v1", _publicMav, SymbolData.INT_TYPE, false, _d);
 2013   
 2014    //compare a vd to an symbol data with no vars
 2015  1 assertFalse("No variables to repeat name", _d._repeatedNameInHierarchy(vd, new LinkedList<SymbolData>()));
 2016   
 2017    //compare a vd to a symbol data with 1 var with a different name
 2018  1 _d.addVar(new VariableData("v2", _protectedMav, SymbolData.BOOLEAN_TYPE, true, _d));
 2019  1 assertFalse("No repeated name", _d._repeatedNameInHierarchy(vd, new LinkedList<SymbolData>()));
 2020   
 2021    //compare a vd to a symbol data who has a var with the same name
 2022  1 _d.addVar(vd);
 2023  1 assertTrue("Should be repeated name", _d._repeatedNameInHierarchy(vd, new LinkedList<SymbolData>()));
 2024   
 2025    //what if super class has var
 2026  1 _d.setVars(new LinkedList<VariableData>());
 2027  1 SymbolData superC = new SymbolData("I am a super class");
 2028  1 superC.addVar(new VariableData(vd.getName(), _protectedMav, SymbolData.DOUBLE_TYPE, false, superC));
 2029  1 _d.setSuperClass(superC);
 2030  1 assertTrue("Should be repeated name", _d._repeatedNameInHierarchy(vd, new LinkedList<SymbolData>()));
 2031   
 2032    //what if interface has var
 2033  1 _d.clearSuperClass();
 2034  1 _d.addInterface(superC);
 2035  1 assertTrue("Should also be repeated name", _d._repeatedNameInHierarchy(vd, new LinkedList<SymbolData>()));
 2036    }
 2037   
 2038  1 public void testAddFinalVars() {
 2039  1 SymbolData _d = new SymbolData("genius");
 2040  1 VariableData vd = new VariableData("v1", _publicMav, SymbolData.INT_TYPE, true, _d);
 2041  1 VariableData vd2 = new VariableData("v2", _publicMav, SymbolData.CHAR_TYPE, true, _d);
 2042  1 VariableData[] toAdd = new VariableData[] {vd, vd2};
 2043  1 LinkedList<VariableData> myVds = new LinkedList<VariableData>();
 2044   
 2045    //first adding array
 2046  1 myVds.addLast(vd);
 2047  1 myVds.addLast(vd2);
 2048  1 assertTrue("Should be able to add new vars array", _d.addFinalVars(toAdd));
 2049  1 assertEquals("Variable list should have 2 variables", myVds, _d.getVars());
 2050   
 2051    //trying to read array whose variables are already there.
 2052  1 assertFalse("Should not be able to add same variables again", _d.addFinalVars(toAdd));
 2053  1 assertEquals("Variable list should not have changed", myVds, _d.getVars());
 2054  1 assertTrue("vd should now be final", _d.getVars().get(0).hasModifier("final"));
 2055  1 assertTrue("vd2 should now be final", _d.getVars().get(1).hasModifier("final"));
 2056   
 2057   
 2058   
 2059    //trying to add a different array
 2060  1 VariableData vd3 = new VariableData("v3", _publicFinalMav, SymbolData.INT_TYPE, true, _d);
 2061  1 VariableData[] toAdd2 = new VariableData[] {vd3};
 2062  1 myVds.addLast(vd3);
 2063   
 2064  1 assertTrue("Should be able to add new variable array", _d.addFinalVars(toAdd2));
 2065  1 assertEquals("Variable list should now have 3 variables", myVds, _d.getVars());
 2066  1 assertTrue("vd3 should now be final", _d.getVars().get(2).hasModifier("final"));
 2067   
 2068   
 2069    //try adding an empty array of variable datas
 2070  1 assertTrue("Should be able to add an empty array", _d.addFinalVars(new VariableData[0]));
 2071  1 assertEquals("Variable list should not have changed by adding empty array", myVds, _d.getVars());
 2072    }
 2073   
 2074  1 public void testGetAllVars() {
 2075  1 SymbolData sd1 = new SymbolData("SubSub");
 2076  1 SymbolData sd2 = new SymbolData("Sub");
 2077  1 SymbolData sd3 = new SymbolData("Super");
 2078  1 SymbolData sd4 = new SymbolData("SuperInterface");
 2079  1 sd4.setInterface(true);
 2080  1 SymbolData sd5 = new SymbolData("NotRelated");
 2081   
 2082  1 sd1.setSuperClass(sd2);
 2083  1 sd2.setSuperClass(sd3);
 2084  1 sd2.addInterface(sd4);
 2085   
 2086  1 VariableData vd1 = new VariableData("vd1", _finalMav, SymbolData.INT_TYPE, false, sd1);
 2087  1 VariableData vd2 = new VariableData("vd2", _finalMav, SymbolData.INT_TYPE, false, sd2);
 2088  1 VariableData vd3 = new VariableData("vd3", _finalMav, SymbolData.INT_TYPE, false, sd3);
 2089  1 VariableData vd4 = new VariableData("vd4", _finalMav, SymbolData.INT_TYPE, false, sd4);
 2090  1 VariableData vd5 = new VariableData("vd5", _finalMav, SymbolData.INT_TYPE, false, sd5);
 2091   
 2092  1 sd1.addVar(vd1);
 2093  1 sd2.addVar(vd2);
 2094  1 sd3.addVar(vd3);
 2095  1 sd4.addVar(vd4);
 2096  1 sd5.addVar(vd5);
 2097   
 2098  1 LinkedList<VariableData> shouldContain = new LinkedList<VariableData>();
 2099  1 shouldContain.addLast(vd2);
 2100  1 shouldContain.addLast(vd3);
 2101  1 shouldContain.addLast(vd4);
 2102   
 2103  1 LinkedList<VariableData> vds = sd1.getAllSuperVars();
 2104  1 assertEquals("the list should have 3 elements", 3, vds.size());
 2105  1 assertEquals("The list should be correct", shouldContain, vds);
 2106    }
 2107   
 2108  1 public void testIsSubclassOf() {
 2109  1 _sd = new SymbolData("subClass");
 2110  1 SymbolData superC = new SymbolData("superC");
 2111  1 _sd._superClass = superC;
 2112   
 2113    //not subclass
 2114  1 assertFalse("subClass, int, and boolean are not related", _sd.isSubClassOf(SymbolData.BOOLEAN_TYPE));
 2115   
 2116    //same class
 2117  1 assertTrue("subClass is a subclass of itself", _sd.isSubClassOf(_sd));
 2118   
 2119    //direct subclass
 2120  1 assertTrue("subClass is a subclass of its super class", _sd.isSubClassOf(superC));
 2121   
 2122    //subclass of subclass of provided data
 2123  1 superC._superClass = SymbolData.CHAR_TYPE;
 2124  1 assertTrue("subClass is a subclass of its super class's super class", _sd.isSubClassOf(SymbolData.CHAR_TYPE));
 2125   
 2126    //Interface
 2127  1 SymbolData myData = new SymbolData("yes");
 2128  1 SymbolData yourData = new SymbolData("interface");
 2129  1 yourData.setInterface(true);
 2130  1 myData.setIsContinuation(false);
 2131  1 myData.addInterface(yourData);
 2132  1 yourData.setIsContinuation(false);
 2133  1 assertTrue("Should be assignable", myData.isSubClassOf(yourData));
 2134    }
 2135   
 2136  1 public void testIsInnerClassOf() {
 2137  1 _sd = new SymbolData("innerClass");
 2138  1 SymbolData outer1 = new SymbolData("outer1");
 2139  1 outer1.addInnerClass(_sd);
 2140  1 _sd.setOuterData(outer1);
 2141  1 SymbolData outer2 = new SymbolData("outer2");
 2142  1 outer2.addInnerClass(outer1);
 2143  1 outer1.setOuterData(outer2);
 2144  1 outer2.setMav(new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"static"}));
 2145  1 SymbolData outer3 = new SymbolData("outer3");
 2146  1 outer3.addInnerClass(outer2);
 2147  1 outer2.setOuterData(outer3);
 2148   
 2149   
 2150  1 SymbolData notInChain = new SymbolData("no");
 2151   
 2152  1 assertTrue("_sd is an inner class of itself", _sd.isInnerClassOf(_sd, true));
 2153  1 assertTrue("outer1 is the outer class of _sd", _sd.isInnerClassOf(outer1, true));
 2154  1 assertTrue("outer2 is an outer class of _sd", _sd.isInnerClassOf(outer2, true));
 2155  1 assertTrue("outer2 is an outer class of itself", outer2.isInnerClassOf(outer2, true));
 2156  1 assertFalse("_sd is not related to notInChain", _sd.isInnerClassOf(notInChain, true));
 2157  1 assertFalse("_sd is not an outer class of outer1", outer1.isInnerClassOf(_sd, true));
 2158  1 assertFalse("outer3 cannot be seen from _sd if the static flag is true, because outer2 is static",
 2159    _sd.isInnerClassOf(outer3, true));
 2160  1 assertTrue("But, outer3 is an outer class of _sd", _sd.isInnerClassOf(outer3, false));
 2161    }
 2162   
 2163  1 public void testCreateUniqueMethodName() {
 2164  1 SymbolData george = new SymbolData("George");
 2165  1 VariableData[] noVars = new VariableData[0];
 2166  1 george.addMethod(new MethodData("getFriends", noVars));
 2167  1 george.addMethod(new MethodData("sayHello", noVars));
 2168   
 2169  1 SymbolData iAteGeorge = new SymbolData("IAteGeorge");
 2170  1 iAteGeorge.addMethod(new MethodData("sayHello", noVars));
 2171  1 iAteGeorge.addMethod(new MethodData("sayHello0", noVars));
 2172  1 iAteGeorge.addInnerClass(george);
 2173  1 george.setOuterData(iAteGeorge);
 2174   
 2175  1 SymbolData mrsGeorge = new SymbolData("MrsGeorge");
 2176  1 mrsGeorge.addMethod(new MethodData("sayHello1", noVars));
 2177  1 george.setSuperClass(mrsGeorge);
 2178   
 2179  1 SymbolData grandmaGeorge = new SymbolData("GrandmaGeorge");
 2180  1 grandmaGeorge.addMethod(new MethodData("sayHello2", noVars));
 2181  1 grandmaGeorge.addMethod(new MethodData("sayHello5", noVars));
 2182  1 george.addInterface(grandmaGeorge);
 2183   
 2184  1 SymbolData papaOfIAteGeorge = new SymbolData("PapaOfIAteGeorge");
 2185  1 papaOfIAteGeorge.addMethod(new MethodData("sayHello3", noVars));
 2186  1 iAteGeorge.setSuperClass(papaOfIAteGeorge);
 2187   
 2188  1 assertEquals("The generated name is correct when SymbolData has that method name",
 2189    "getFriends0", george.createUniqueMethodName("getFriends"));
 2190  1 assertEquals("The generated name is correct when SymbolData doesn't have a method of that name",
 2191    "eatDinner", george.createUniqueMethodName("eatDinner"));
 2192  1 assertEquals("The generated name is correct when a super class uses the name",
 2193    "sayHello10", george.createUniqueMethodName("sayHello1"));
 2194  1 assertEquals("The generated name is correct when an outer class uses the name",
 2195    "sayHello00", george.createUniqueMethodName("sayHello0"));
 2196  1 assertEquals("The generated name is correct when an interface uses the name",
 2197    "sayHello20", george.createUniqueMethodName("sayHello2"));
 2198  1 assertEquals("The generated name is correct when a super class of an outer class uses the name",
 2199    "sayHello30", george.createUniqueMethodName("sayHello3"));
 2200  1 assertEquals("The generated name is correct when a super class of an outer class uses the name",
 2201    "sayHello30", george.createUniqueMethodName("sayHello3"));
 2202  1 assertEquals("The generated name is correct when a lot of things use the name",
 2203    "sayHello4", george.createUniqueMethodName("sayHello"));
 2204   
 2205    }
 2206    }
 2207    }