001 /*BEGIN_COPYRIGHT_BLOCK
002 * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu). All rights reserved.
003 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
004 * following conditions are met:
005 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
006 * disclaimer.
007 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
008 * following disclaimer in the documentation and/or other materials provided with the distribution.
009 * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the names of its contributors may be used
010 * to endorse or promote products derived from this software without specific prior written permission.
011 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
012 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
013 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
014 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
015 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
016 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
017 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
018 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
019 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
020 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
021 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
022 *
023 * This software is Open Source Initiative approved Open Source Software.
024 * Open Source Initative Approved is a trademark of the Open Source Initiative.
025 *
026 * This file is part of DrJava. Download the current version of this project
027 * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
028 *
029 * END_COPYRIGHT_BLOCK*/
030
031 package edu.rice.cs.javalanglevels;
032
033 import edu.rice.cs.javalanglevels.tree.*;
034 import edu.rice.cs.javalanglevels.parser.*;
035 import edu.rice.cs.javalanglevels.util.Utilities;
036
037 import edu.rice.cs.plt.reflect.JavaVersion;
038 import edu.rice.cs.plt.iter.IterUtil;
039 import java.util.*;
040 import java.io.*;
041
042 import junit.framework.TestCase;
043
044 /** Language Level Visitor class that implements the FullJava Language Level. Enforces constraints during the first
045 * walk of the AST (checking for langauge specific errors and building the symbol table). This class enforces some
046 * constraints imposed on an interface body at the FullJava Language Level.
047 */
048 public class InterfaceBodyFullJavaVisitor extends FullJavaVisitor {
049
050 /**The SymbolData corresponding to this interface, which encloses the body of the interface. */
051 private SymbolData _enclosing;
052
053 /** Old constructor for InterfaceBodyFullJavaVisitor.
054 * @param sd The SymbolData that encloses the context we are visiting.
055 * @param file The source file this came from.
056 * @param packageName The package the source file is in
057 * @importedFiles A list of classes that were specifically imported
058 * @param importedPackages A list of package names that were specifically imported
059 * @param classesInThisFile A list of the classes that are yet to be defined in this source file
060 * @param continuations A hashtable corresponding to the continuations (unresolved Symbol Datas) that will need to
061 * be resolved
062 */
063 public InterfaceBodyFullJavaVisitor(SymbolData sd,
064 File file,
065 String packageName,
066 LinkedList<String> importedFiles,
067 LinkedList<String> importedPackages,
068 HashSet<String> classesInThisFile,
069 Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>> continuations,
070 LinkedList<Command> fixUps) {
071 super(file, packageName, sd.getName(), importedFiles, importedPackages, classesInThisFile, continuations, fixUps);
072 _enclosing = sd;
073 // if (_enclosingClassName != sd.getName()) Utilities.show("enclosingClassName does not equal sd.getName(). Trace follows.\n" +
074 // Utilities.getStackTrace());
075 }
076
077 /** Preferred constructor for InterfaceBodyFullJavaVisitor.
078 * @param sd The SymbolData that encloses the context we are visiting.
079 * @param file The source file this came from.
080 * @param packageName The package the source file is in
081 * @importedFiles A list of classes that were specifically imported
082 * @param importedPackages A list of package names that were specifically imported
083 * @param classesInThisFile A list of the classes that are yet to be defined in this source file
084 * @param continuations A hashtable corresponding to the continuations (unresolved Symbol Datas) that will need to
085 * be resolved
086 * @param genericTypes A HashMap mapping in scope generic type names to their bounds (SymbolDatas).
087 */
088 public InterfaceBodyFullJavaVisitor(SymbolData sd,
089 File file,
090 String packageName,
091 LinkedList<String> importedFiles,
092 LinkedList<String> importedPackages,
093 HashSet<String> classesInThisFile,
094 Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>> continuations,
095 LinkedList<Command> fixUps,
096 HashMap<String, SymbolData> genericTypes) {
097 super(file, packageName, sd.getName(), importedFiles, importedPackages, classesInThisFile, continuations, fixUps,
098 genericTypes);
099 _enclosing = sd;
100 // if (_enclosingClassName != sd.getName()) Utilities.show("enclosingClassName does not equal sd.getName(). Trace follows.\n" +
101 // Utilities.getStackTrace());
102 }
103
104 /** Ignore Statement. */
105 public Void forStatementDoFirst(Statement that) { return null; }
106
107 /*Throw an appropriate error*/
108 public Void forConcreteMethodDefDoFirst(ConcreteMethodDef that) {
109 _addError("You cannot have concrete methods definitions in interfaces", that);
110 return null;
111 }
112
113
114 /**Throw an appropriate error*/
115 public Void forInstanceInitializerDoFirst(InstanceInitializer that) {
116 _addError("This open brace must mark the beginning of an interface body", that);
117 return null;
118 }
119
120 /** Ignore VariableDeclaration. */
121 public Void forVariableDeclarationOnly(VariableDeclaration that) { return null; }
122
123 /**No This literal in interfaces--give an appropriate error*/
124 public Void forThisReferenceDoFirst(ThisReference that) {
125 _addAndIgnoreError("The field 'this' does not exist in interfaces. Only classes have a 'this' field.", that);
126 return null;
127 }
128
129 /** No super references for interfaces--give an appropriate error.*/
130 public Void forSuperReferenceDoFirst(SuperReference that) {
131 _addAndIgnoreError("The field 'super' does not exist in interfaces. Only classes have a 'super' field", that);
132 return null;
133 }
134
135 public Void forAbstractMethodDef(AbstractMethodDef that) {
136 forAbstractMethodDefDoFirst(that);
137 if (_checkError()) return null;
138
139 assert _enclosing != null;
140
141 // Process type parameters
142 TypeParameter[] tps = that.getTypeParams();
143
144 // TODO !!! pass genericTypes as a parameter to createMethod and critical submethods. The scope of the
145 // new generic types table includes all of createMethodData processing, notably processing the return type.
146 // Passing an extended generic types table to BodyBodyFullJavaVisitor is insufficient
147
148 // Save a snapshot of _genericTypes
149 HashMap<String, SymbolData> oldGenericTypes = _genericTypes;
150
151 // Rebind _genericTypes to a shallow copy of itself for use in processing this method. The temporary variable copy
152 // gets around a bug in javac in processing the SuppressWarnings statement.
153 @SuppressWarnings("unchecked")
154 HashMap<String, SymbolData> copy = (HashMap<String, SymbolData>)_genericTypes.clone();
155 _genericTypes = copy;
156
157 if (tps != null) { // extend genericTypes by new type variable bindings
158 for (TypeParameter tp: tps) {
159 final String typeName = tp.getVariable().getName();
160 final String boundName = tp.getBound().getName();
161 SymbolData boundSD = _identifyType(boundName, that.getSourceInfo(), _enclosingClassName);
162 if (boundSD == null) { // create a dummy SymbolData
163 boundSD = symbolTable.get("java.lang.Object"); // TODO: could create a separate unbound type variable singleton class?
164 // System.err.println("Creating dummy SymbolData for bounding type " + typeName + " in inner class " + name);
165 // TODO! !!!!! Create an appropriate fixUp mechanism
166 }
167 // System.err.println("In method " + _enclosing + "." + that.getName().getText() + ", type " + typeName
168 // + " is bound to " + boundSD);
169 _genericTypes.put(typeName, boundSD);
170 }
171 }
172
173 MethodData md = createMethodData(that, _enclosing);
174
175 //All interface methods are considered public by default: enforce this.
176 if (md.hasModifier("private")) {
177 _addAndIgnoreError("Interface methods cannot be private. They must be public.", that.getMav());
178 }
179 if (md.hasModifier("protected")) {
180 _addAndIgnoreError("Interface methods cannot be protected. They must be public.", that.getMav());
181 }
182
183 // All interface methods are considered public by default.
184 md.addModifier("public");
185 md.addModifier("abstract"); // and all interface methods are abstract.
186 String className = getUnqualifiedClassName(_enclosing.getName());
187 if (className.equals(md.getName())) {
188 _addAndIgnoreError("Only constructors can have the same name as the class they appear in, " +
189 "and constructors cannot appear in interfaces.", that);
190 }
191 else _enclosing.addMethod(md);
192
193 _genericTypes = oldGenericTypes;
194 return null;
195 }
196
197 /** Call the method in FullJavaVisitor since it's common to this ClassBodyFullJavaVisitor. */
198 public Void forInnerInterfaceDef(InnerInterfaceDef that) {
199 String relName = that.getName().getText();
200 handleInnerInterfaceDef(that, _enclosing, relName, getQualifiedClassName(_enclosing.getName()) + '.' + relName);
201 return null;
202 }
203
204 /**Call the method in FullJavaVisitor; it's common to this ClassBodyAdvancedVisitor.*/
205 public Void forInnerClassDef(InnerClassDef that) {
206 String relName = that.getName().getText();
207 handleInnerClassDef(that, _enclosing, relName, getQualifiedClassName(_enclosing.getName()) + '.' + relName);
208 return null;
209 }
210
211 /** Throw an error: Interfaces cannot have constructors */
212 public Void forConstructorDefDoFirst(ConstructorDef that) {
213 _addAndIgnoreError("Constructor definitions cannot appear in interfaces", that);
214 return null;
215 }
216
217 /** Processes a static field declaration within an interface. Calls the super method to convert the VariableDeclaration
218 * to a VariableData array, then makes sure that each VariableData is final and static, as required in an
219 * interface.
220 * @param enclosingData The Data immediately enclosing the variables
221 */
222 protected VariableData[] _variableDeclaration2VariableData(VariableDeclaration vd, Data enclosingData) {
223 VariableData[] vds = super._variableDeclaration2VariableData(vd, enclosingData);
224 for (int i = 0; i < vds.length; i++) {
225 vds[i].setFinalAndStatic();
226 }
227 return vds;
228 }
229
230 /** Delegate to method in LLV */
231 public Void forComplexAnonymousClassInstantiation(ComplexAnonymousClassInstantiation that) {
232 complexAnonymousClassInstantiationHelper(that, _enclosing); // TODO: the wrong enclosing context?
233 return null;
234 }
235
236 /** Delegate to method in LLV*/
237 public Void forSimpleAnonymousClassInstantiation(SimpleAnonymousClassInstantiation that) {
238 // System.err.println("Calling simpleAnonymousClassInstantiation Helper from InterfaceBody " + that.getSourceInfo());
239 simpleAnonymousClassInstantiationHelper(that, _enclosing);
240 return null;
241 }
242
243 /** Test the methods in the above class. */
244 public static class InterfaceBodyFullJavaVisitorTest extends TestCase {
245
246 private InterfaceBodyFullJavaVisitor _ibfv;
247
248 private SymbolData _sd1;
249 private SymbolData _objectSD;
250
251 private ModifiersAndVisibility _publicMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"public"});
252 private ModifiersAndVisibility _protectedMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"protected"});
253 private ModifiersAndVisibility _privateMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"private"});
254 private ModifiersAndVisibility _packageMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[0]);
255 private ModifiersAndVisibility _abstractMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"abstract"});
256 private ModifiersAndVisibility _finalMav = new ModifiersAndVisibility(SourceInfo.NONE, new String[] {"final"});
257
258 public InterfaceBodyFullJavaVisitorTest() { this(""); }
259 public InterfaceBodyFullJavaVisitorTest(String name) { super(name); }
260
261 public void setUp() {
262 errors = new LinkedList<Pair<String, JExpressionIF>>();
263 LanguageLevelConverter.symbolTable.clear();
264 LanguageLevelConverter._newSDs.clear();
265 LanguageLevelConverter.OPT = new Options(JavaVersion.JAVA_5, IterUtil.make(new File("lib/buildlib/junit.jar")));
266 visitedFiles = new LinkedList<Pair<LanguageLevelVisitor, edu.rice.cs.javalanglevels.tree.SourceFile>>();
267
268
269 _sd1 = new SymbolData("MyInterface");
270 _sd1.setIsContinuation(false);
271 _sd1.setInterface(true);
272 _sd1.setPackage("");
273 _sd1.setTypeParameters(new TypeParameter[0]);
274 _sd1.setInterfaces(new ArrayList<SymbolData>());
275
276 // NOTE: the following ensures that the symbolTable includes essential types
277 _ibfv = new InterfaceBodyFullJavaVisitor(_sd1,
278 new File(""),
279 "",
280 new LinkedList<String>(),
281 new LinkedList<String>(),
282 new HashSet<String>(),
283 new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>(),
284 new LinkedList<Command>());
285 _ibfv._classesInThisFile = new HashSet<String>();
286 _ibfv.continuations = new Hashtable<String, Triple<SourceInfo, LanguageLevelVisitor, SymbolData>>();
287 _ibfv._importedPackages.addFirst("java.lang");
288 _ibfv._enclosingClassName = "MyInterface";
289
290 _objectSD = LanguageLevelConverter.symbolTable.get("java.lang.Object");
291 _sd1.setSuperClass(_objectSD);
292
293 LanguageLevelConverter.symbolTable.put("MyInterface", _sd1);
294
295 _errorAdded = false;
296 }
297
298 public void testForConcreteMethodDefDoFirst() {
299 // Check that an error is thrown
300 ConcreteMethodDef cmd = new ConcreteMethodDef(SourceInfo.NONE,
301 _publicMav,
302 new TypeParameter[0],
303 new PrimitiveType(SourceInfo.NONE, "int"),
304 new Word(SourceInfo.NONE, "methodName"),
305 new FormalParameter[0],
306 new ReferenceType[0],
307 new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
308 cmd.visit(_ibfv);
309 assertEquals("There should not be 1 error", 1, errors.size());
310 assertEquals("The error message should be correct", "You cannot have concrete methods definitions in interfaces",
311 errors.getLast().getFirst());
312
313 }
314
315 public void testForAbstractMethodDefDoFirst() {
316 // Check one that works
317 _ibfv._enclosing.setMav(_abstractMav);
318 AbstractMethodDef amd2 = new AbstractMethodDef(SourceInfo.NONE,
319 _abstractMav,
320 new TypeParameter[0],
321 new PrimitiveType(SourceInfo.NONE, "double"),
322 new Word(SourceInfo.NONE, "methodName"),
323 new FormalParameter[0],
324 new ReferenceType[0]);
325 amd2.visit(_ibfv);
326 assertEquals("There should be no errors", 0, errors.size());
327 assertTrue("The method def should be public",
328 _ibfv._enclosing.getMethods().get(0).hasModifier("public"));
329
330 }
331
332 public void testForInstanceInitializerDoFirst() {
333 InstanceInitializer ii =
334 new InstanceInitializer(SourceInfo.NONE,
335 new Block(SourceInfo.NONE,
336 new BracedBody(SourceInfo.NONE, new BodyItemI[0])));
337 ii.visit(_ibfv);
338 assertEquals("There should be one error.", 1, errors.size());
339 assertEquals("The error message should be correct.",
340 "This open brace must mark the beginning of an interface body",
341 errors.get(0).getFirst());
342 }
343
344 public void testForSimpleThisReferenceDoFirst() {
345 SimpleThisReference tl = new SimpleThisReference(SourceInfo.NONE);
346 tl.visit(_ibfv);
347 assertEquals("There should be one error", 1, errors.size());
348 assertEquals("The error message should be correct",
349 "The field 'this' does not exist in interfaces. Only classes have a 'this' field.",
350 errors.get(0).getFirst());
351 }
352
353 public void testForComplexThisReferenceDoFirst() {
354 ComplexThisReference tl = new ComplexThisReference(SourceInfo.NONE,
355 new NullLiteral(SourceInfo.NONE));
356 tl.visit(_ibfv);
357 assertEquals("There should be one error", 1, errors.size());
358 assertEquals("The error message should be correct",
359 "The field 'this' does not exist in interfaces. Only classes have a 'this' field.",
360 errors.get(0).getFirst());
361
362 }
363
364 public void testForSimpleSuperReferenceDoFirst() {
365 SimpleSuperReference sr = new SimpleSuperReference(SourceInfo.NONE);
366 sr.visit(_ibfv);
367 assertEquals("There should be one error", 1, errors.size());
368 assertEquals("The error message should be correct",
369 "The field 'super' does not exist in interfaces. Only classes have a 'super' field",
370 errors.get(0).getFirst());
371 }
372
373 public void testForComplexSuperReferenceDoFirst() {
374 ComplexSuperReference cr = new ComplexSuperReference(SourceInfo.NONE,
375 new NullLiteral(SourceInfo.NONE));
376 cr.visit(_ibfv);
377 assertEquals("There should be one error", 1, errors.size());
378 assertEquals("The error message should be correct",
379 "The field 'super' does not exist in interfaces. Only classes have a 'super' field",
380 errors.get(0).getFirst());
381 }
382
383 public void xtestForVariableDeclarationDoFirst() {
384 //Check that if a field is initialized, no error is thrown
385 VariableDeclaration vdecl0 = new VariableDeclaration(SourceInfo.NONE,
386 _packageMav,
387 new VariableDeclarator[] {
388 new InitializedVariableDeclarator(SourceInfo.NONE,
389 new PrimitiveType(SourceInfo.NONE, "double"),
390 new Word (SourceInfo.NONE, "field0"),
391 new DoubleLiteral(SourceInfo.NONE, 2.345))});
392
393 vdecl0.visit(_ibfv);
394 assertEquals("There should be no errors", 0, errors.size());
395
396
397 // Check that an error is thrown if the fields are not initialized
398 VariableDeclaration vdecl = new VariableDeclaration(SourceInfo.NONE,
399 _packageMav,
400 new VariableDeclarator[] {
401 new InitializedVariableDeclarator(SourceInfo.NONE,
402 new PrimitiveType(SourceInfo.NONE, "double"),
403 new Word (SourceInfo.NONE, "field1"),
404 new DoubleLiteral(SourceInfo.NONE, 2.45)),
405 new UninitializedVariableDeclarator(SourceInfo.NONE,
406 new PrimitiveType(SourceInfo.NONE, "boolean"),
407 new Word (SourceInfo.NONE, "field2"))});
408 vdecl.visit(_ibfv);
409 assertEquals("There should be one error", 1, errors.size());
410 assertEquals("The error message should be correct",
411 "All fields in interfaces must be assigned a value when they are declared",
412 errors.getLast().getFirst());
413 }
414
415 public void testForAbstractMethodDef() {
416 // Test one that works.
417 MethodDef mdef = new AbstractMethodDef(SourceInfo.NONE,
418 _abstractMav,
419 new TypeParameter[0],
420 new PrimitiveType(SourceInfo.NONE, "int"),
421 new Word(SourceInfo.NONE, "methodName"),
422 new FormalParameter[0],
423 new ReferenceType[0]);
424 _ibfv._enclosing.setMav(_abstractMav);
425 mdef.visit(_ibfv);
426 assertEquals("There should not be any errors.", 0, errors.size());
427
428 // Test one that doesn't work.
429 mdef = new AbstractMethodDef(SourceInfo.NONE,
430 _abstractMav,
431 new TypeParameter[0],
432 new PrimitiveType(SourceInfo.NONE, "int"),
433 new Word(SourceInfo.NONE, "MyInterface"),
434 new FormalParameter[0],
435 new ReferenceType[0]);
436 mdef.visit(_ibfv);
437 assertEquals("There should be one error.", 1, errors.size());
438 assertEquals("The error message should be correct.",
439 "Only constructors can have the same name as the class they appear in, and constructors cannot "
440 + "appear in interfaces.",
441 errors.get(0).getFirst());
442
443 //It's okay for the method to be public
444 AbstractMethodDef amd3 = new AbstractMethodDef(SourceInfo.NONE,
445 _publicMav,
446 new TypeParameter[0],
447 new PrimitiveType(SourceInfo.NONE, "double"),
448 new Word(SourceInfo.NONE, "methodName2"),
449 new FormalParameter[0],
450 new ReferenceType[0]);
451 amd3.visit(_ibfv);
452 assertEquals("There should still be one error", 1, errors.size());
453 assertTrue("The method def should be public", _ibfv._enclosing.getMethods().get(1).hasModifier("public"));
454
455 //What if the method is called private? Should throw error
456 AbstractMethodDef amd4 = new AbstractMethodDef(SourceInfo.NONE,
457 _privateMav,
458 new TypeParameter[0],
459 new PrimitiveType(SourceInfo.NONE, "double"),
460 new Word(SourceInfo.NONE, "methodName3"),
461 new FormalParameter[0],
462 new ReferenceType[0]);
463 amd4.visit(_ibfv);
464 assertEquals("There should be two errors", 2, errors.size());
465 assertEquals("The error message should be correct",
466 "Interface methods cannot be private. They must be public." ,
467 errors.get(1).getFirst());
468
469 //What if the method is protected: Should throw error
470 AbstractMethodDef amd5 = new AbstractMethodDef(SourceInfo.NONE,
471 _protectedMav,
472 new TypeParameter[0],
473 new PrimitiveType(SourceInfo.NONE, "double"),
474 new Word(SourceInfo.NONE, "methodName4"),
475 new FormalParameter[0],
476 new ReferenceType[0]);
477 amd5.visit(_ibfv);
478 assertEquals("There should be three errors", 3, errors.size());
479 assertEquals("The error message should be correct",
480 "Interface methods cannot be protected. They must be public." ,
481 errors.get(2).getFirst());
482 }
483
484
485 public void testForInnerClassDef() {
486 _ibfv._enclosing = new SymbolData("MyInterface");
487 _ibfv._enclosing.setInterface(true);
488
489 // SymbolData obj = new SymbolData("java.lang.Object");
490 LanguageLevelConverter._newSDs.clear();
491 // LanguageLevelConverter.symbolTable.put("java.lang.Object", obj);
492
493 InnerClassDef cd1 =
494 new InnerClassDef(SourceInfo.NONE,
495 _packageMav,
496 new Word(SourceInfo.NONE, "Bart"),
497 new TypeParameter[0],
498 new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]),
499 new ReferenceType[0],
500 new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
501 InnerClassDef cd0 =
502 new InnerClassDef(SourceInfo.NONE,
503 _packageMav,
504 new Word(SourceInfo.NONE, "Lisa"),
505 new TypeParameter[0],
506 new ClassOrInterfaceType(SourceInfo.NONE, "java.lang.Object", new Type[0]),
507 new ReferenceType[0],
508 new BracedBody(SourceInfo.NONE, new BodyItemI[] {cd1}));
509
510 // SymbolData sd0 = new SymbolData(_ibfv._enclosing.getName() + "$Lisa", _packageMav, new TypeParameter[0], obj,
511 // new ArrayList<SymbolData>(), null);
512 // SymbolData sd1 =
513 // new SymbolData(_ibfv._enclosing.getName() + "$Lisa$Bart", _packageMav, new TypeParameter[0], obj,
514 // new ArrayList<SymbolData>(), null);
515
516 // _ibfv._enclosing.addInnerClass(sd0);
517 // sd0.setOuterData(_ibfv._enclosing);
518
519 // sd0.addInnerClass(sd1);
520 // sd1.setOuterData(sd0);
521 //
522 // sd0.setIsContinuation(true);
523 // sd1.setIsContinuation(true);
524 // LanguageLevelConverter._newSDs.clear();
525 // LanguageLevelConverter.symbolTable.put(_ibfv._enclosing.getName() + "$Lisa", sd0);
526
527 cd0.visit(_ibfv);
528
529 SymbolData sd0 = _ibfv._enclosing.getInnerClassOrInterface("Lisa");
530 assertNotNull("Inner class Lisa exists", sd0);
531
532 assertEquals("Lisa should have the correct outer data", _ibfv._enclosing, sd0.getOuterData());
533 assertTrue("_sd1 should be an interface", _sd1.isInterface());
534 assertFalse("sd0 should be a class", sd0.isInterface());
535 assertEquals("Lisa should have 0 methods", 0, sd0.getMethods().size());
536
537 SymbolData sd1 = sd0.getInnerClassOrInterface("Bart");
538 assertNotNull("Inner class Bart exists", sd1);
539
540 assertEquals("Bart should have the correct outer data", sd0, sd1.getOuterData());
541 assertFalse("sd1 should be a class", sd1.isInterface());
542 assertEquals("Bart should have 0 methods", 0, sd1.getMethods().size());
543 }
544
545 public void testForInnerInterfaceDef() {
546
547 InnerInterfaceDef cd1 =
548 new InnerInterfaceDef(SourceInfo.NONE, _packageMav, new Word(SourceInfo.NONE, "Bart"),
549 new TypeParameter[0], new ReferenceType[0],
550 new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
551
552 InnerInterfaceDef cd0 =
553 new InnerInterfaceDef(SourceInfo.NONE, _packageMav, new Word(SourceInfo.NONE, "Lisa"),
554 new TypeParameter[0], new ReferenceType[0],
555 new BracedBody(SourceInfo.NONE, new BodyItemI[] {cd1}));
556
557 // SymbolData sd0 = new SymbolData(_ibfv._enclosing.getName() + "$Lisa", _packageMav, new TypeParameter[0],
558 // new ArrayList<SymbolData>(), null);
559 // SymbolData sd1 = new SymbolData(_ibfv._enclosing.getName() + "$Lisa$Bart", _packageMav, new TypeParameter[0],
560 // new ArrayList<SymbolData>(), null);
561 // sd0.addInnerInterface(sd1);
562 //
563 //
564 // _ibfv._enclosing.addInnerInterface(sd0);
565 // sd0.setOuterData(_ibfv._enclosing);
566 //
567 // sd0.addInnerInterface(sd1);
568 // sd1.setOuterData(sd0);
569 //
570 //
571 // sd0.setIsContinuation(true);
572 // sd1.setIsContinuation(true);
573 // LanguageLevelConverter._newSDs.clear();
574 // LanguageLevelConverter.symbolTable.put(_ibfv._enclosing.getName() + "$Lisa", sd0);
575 // LanguageLevelConverter._newSDs.clear();
576 // LanguageLevelConverter.symbolTable.put(_ibfv._enclosing.getName() + "$Lisa$Bart", sd1);
577
578 cd0.visit(_ibfv);
579
580 SymbolData sd0 = _ibfv._enclosing.getInnerClassOrInterface("Lisa");
581 assertNotNull("Inner interfacae Lisa exists", sd0);
582
583 assertEquals("Lisa should have the correct outer data", _ibfv._enclosing, sd0.getOuterData());
584 assertTrue("_sd1 should be an interface", _sd1.isInterface());
585 assertTrue("sd0 should be a interface", sd0.isInterface());
586 assertEquals("Lisa should have 0 methods", 0, sd0.getMethods().size());
587
588 SymbolData sd1 = sd0.getInnerClassOrInterface("Bart");
589 assertNotNull("Inner interface Bart exists", sd1);
590
591 assertEquals("Bart should have the correct outer data", sd0, sd1.getOuterData());
592 assertTrue("sd1 should be an interface", sd1.isInterface());
593 assertEquals("Bart should have 0 methods", 0, sd1.getMethods().size());
594 }
595
596 public void testForConstructorDef() {
597 ///this is a ConstructorDef with no formal paramaters and no throws
598 ConstructorDef cd =
599 new ConstructorDef(SourceInfo.NONE, new Word(SourceInfo.NONE, "MyClass"),
600 _publicMav, new FormalParameter[0], new ReferenceType[0],
601 new BracedBody(SourceInfo.NONE, new BodyItemI[0]));
602
603 // Check that the appropriate error is thrown.
604 cd.visit(_ibfv);
605 assertEquals("There should now be one error", 1, errors.size());
606 assertEquals("The error message should be correct", "Constructor definitions cannot appear in interfaces",
607 errors.get(0).getFirst());
608
609 }
610 public void testDummy() { }
611 }
612 }