### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java,v retrieving revision 1.78 diff -u -r1.78 TestAll.java --- src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java 28 Apr 2009 17:17:32 -0000 1.78 +++ src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java 12 May 2009 18:57:19 -0000 @@ -91,6 +91,7 @@ since_1_5.add(BatchCompilerTest.class); since_1_5.add(ExternalizeStringLiterals15Test.class); since_1_5.add(Deprecated15Test.class); + since_1_5.add(InnerEmulationTest_1_5.class); // Tests to run when compliance is greater than 1.5 ArrayList since_1_6 = new ArrayList(); Index: src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest_1_5.java =================================================================== RCS file: src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest_1_5.java diff -N src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest_1_5.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest_1_5.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,292 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.compiler.regression; + +import java.io.File; + +import junit.framework.Test; + +public class InnerEmulationTest_1_5 extends AbstractRegressionTest { +static { +// TESTS_NAMES = new String[] { "Bug58069" }; +// TESTS_NUMBERS = new int[] { 13 }; +// TESTS_RANGE = new int[] { 144, -1 }; +} +public InnerEmulationTest_1_5(String name) { + super(name); +} +public static Test suite() { + return buildMinimalComplianceTestSuite(testClass(), F_1_5); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test1() throws Exception { + this.runConformTest(new String[] { + "X.java", + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "public class X {\n" + + " public void foo(Collection args) { /* dummy */ }\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #25 java/util/Map$Entry, outer class info: #27 java/util/Map\n" + + " inner name: #29 Entry, accessflags: 1545 public abstract static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test2() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "public class X {\n" + + " public void foo(Map.Entry args) { /* dummy */ }\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #21 java/util/Map$Entry, outer class info: #23 java/util/Map\n" + + " inner name: #25 Entry, accessflags: 1545 public abstract static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test3() throws Exception { + this.runConformTest(new String[] { + "X.java", + "import java.util.Map;\n" + + "import java.util.List;\n" + + "public class X {\n" + + " , T extends Map.Entry> X(List lu, T t) {\n" + + " }\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #27 java/util/Map$Entry, outer class info: #29 java/util/Map\n" + + " inner name: #31 Entry, accessflags: 1545 public abstract static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test4() throws Exception { + this.runConformTest(new String[] { + "X.java", + "import java.util.Map;\n" + + "import java.util.List;\n" + + "public class X> {}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #21 java/util/Map$Entry, outer class info: #23 java/util/Map\n" + + " inner name: #25 Entry, accessflags: 1545 public abstract static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test5() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "public class X {\n" + + " public void foo(Map.Entry args) { /* dummy */ }\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #25 java/util/Map$Entry, outer class info: #27 java/util/Map\n" + + " inner name: #29 Entry, accessflags: 1545 public abstract static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test6() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "public class X {\n" + + " Map.Entry f;\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #21 java/util/Map$Entry, outer class info: #23 java/util/Map\n" + + " inner name: #25 Entry, accessflags: 1545 public abstract static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test7() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "public class X> {\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #21 java/util/Map$Entry, outer class info: #23 java/util/Map\n" + + " inner name: #25 Entry, accessflags: 1545 public abstract static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test8() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "class A {\n" + + " static class B{}\n" + + "}\n" + + "public class X> {\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #21 java/util/Map$Entry, outer class info: #23 java/util/Map\n" + + " inner name: #25 Entry, accessflags: 1545 public abstract static],\n" + + " [inner class info: #26 p/A$B, outer class info: #28 p/A\n" + + " inner name: #30 B, accessflags: 8 static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test9() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "class A {\n" + + " static class B{}\n" + + "}\n" + + "public class X {\n" + + " > void foo(E e) {}\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #25 java/util/Map$Entry, outer class info: #27 java/util/Map\n" + + " inner name: #29 Entry, accessflags: 1545 public abstract static],\n" + + " [inner class info: #30 p/A$B, outer class info: #32 p/A\n" + + " inner name: #34 B, accessflags: 8 static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test10() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "class A {\n" + + " static interface B{}\n" + + "}\n" + + "class C {\n" + + " static class D{}\n" + + "}\n" + + "public class X {\n" + + " >> void foo(E e) {}\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #25 java/util/Map$Entry, outer class info: #27 java/util/Map\n" + + " inner name: #29 Entry, accessflags: 1545 public abstract static],\n" + + " [inner class info: #30 p/A$B, outer class info: #32 p/A\n" + + " inner name: #34 B, accessflags: 1544 abstract static],\n" + + " [inner class info: #35 p/C$D, outer class info: #37 p/C\n" + + " inner name: #39 D, accessflags: 8 static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test11() throws Exception { + this.runConformTest(new String[] { + "X.java", + "import java.util.*;\n" + + "\n" + + " public class X {\n" + + " \n" + + " static abstract class SelfType>{\n" + + " }\n" + + " \n" + + " static class SuperType extends SelfType{\n" + + " }\n" + + " \n" + + " static class SubType extends SuperType{}\n" + + " \n" + + " static > List makeSingletonList(T t){\n" + + " return Collections.singletonList(t);\n" + + " }\n" + + " \n" + + " static ,S extends T> List makeSingletonList2(S s){\n" + + " return Collections.singletonList((T)s); // #0\n" + + " }\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #35 X$SelfType, outer class info: #1 X\n" + + " inner name: #37 SelfType, accessflags: 1032 abstract static],\n" + + " [inner class info: #38 X$SubType, outer class info: #1 X\n" + + " inner name: #40 SubType, accessflags: 8 static],\n" + + " [inner class info: #41 X$SuperType, outer class info: #1 X\n" + + " inner name: #43 SuperType, accessflags: 8 static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test12() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "public class X {\n" + + " Collection field;\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #21 java/util/Map$Entry, outer class info: #23 java/util/Map\n" + + " inner name: #25 Entry, accessflags: 1545 public abstract static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=275381 +public void test13() throws Exception { + this.runConformTest(new String[] { + "p/X.java", + "package p;\n" + + "import java.util.Collection;\n" + + "import java.util.Map;\n" + + "class A {\n" + + " static interface B{}\n" + + "}\n" + + "class C {\n" + + " static class D{}\n" + + "}\n" + + "public class X extends C.D implements A.B {\n" + + "}" + }); + String expectedOutput = + " Inner classes:\n" + + " [inner class info: #5 p/A$B, outer class info: #19 p/A\n" + + " inner name: #21 B, accessflags: 1544 abstract static],\n" + + " [inner class info: #3 p/C$D, outer class info: #22 p/C\n" + + " inner name: #24 D, accessflags: 8 static]\n"; + checkDisassembledClassFile(OUTPUT_DIR + File.separator + "p" + File.separator + "X.class", "X", expectedOutput); +} +public static Class testClass() { + return InnerEmulationTest_1_5.class; +} +} #P org.eclipse.jdt.core.tests Index: Eclipse Java Tests Runner/org/eclipse/jdt/core/tests/RunAllDisassemblerTests.java =================================================================== RCS file: /home/cvs/numbat/org.eclipse.jdt.core.tests/Eclipse Java Tests Runner/org/eclipse/jdt/core/tests/RunAllDisassemblerTests.java,v retrieving revision 1.11 diff -u -r1.11 RunAllDisassemblerTests.java --- Eclipse Java Tests Runner/org/eclipse/jdt/core/tests/RunAllDisassemblerTests.java 27 Jun 2008 16:02:01 -0000 1.11 +++ Eclipse Java Tests Runner/org/eclipse/jdt/core/tests/RunAllDisassemblerTests.java 12 May 2009 18:57:20 -0000 @@ -69,6 +69,7 @@ tests_1_5.add(ForeachStatementTest.class); tests_1_5.add(GenericTypeTest.class); tests_1_5.add(MethodVerifyTest.class); + tests_1_5.add(InnerEmulationTest_1_5.class); all.addTest(AbstractCompilerTest.buildComplianceTestSuite(ClassFileConstants.JDK1_5, tests_1_5)); } if ((possibleComplianceLevels & AbstractCompilerTest.F_1_6) != 0) { #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java,v retrieving revision 1.112 diff -u -r1.112 ParameterizedTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java 8 Jan 2009 20:51:05 -0000 1.112 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ParameterizedTypeBinding.java 12 May 2009 18:57:21 -0000 @@ -673,10 +673,11 @@ this.tagBits |= TagBits.IsBoundParameterizedType; break; } - this.tagBits |= someArgument.tagBits & (TagBits.HasTypeVariable | TagBits.HasMissingType); + this.tagBits |= someArgument.tagBits & (TagBits.HasTypeVariable | TagBits.HasMissingType); + this.tagBits |= someArgument.tagBits & TagBits.ContainsNestedTypeReferences; } } - this.tagBits |= someType.tagBits & (TagBits.IsLocalType| TagBits.IsMemberType | TagBits.IsNestedType | TagBits.HasMissingType); + this.tagBits |= someType.tagBits & (TagBits.IsLocalType| TagBits.IsMemberType | TagBits.IsNestedType | TagBits.HasMissingType | TagBits.ContainsNestedTypeReferences); this.tagBits &= ~(TagBits.AreFieldsComplete|TagBits.AreMethodsComplete); } @@ -845,10 +846,14 @@ this.tagBits &= ~TagBits.HasUnresolvedTypeVariables; // can be recursive so only want to call once ReferenceBinding resolvedType = (ReferenceBinding) BinaryTypeBinding.resolveType(this.type, this.environment, false /* no raw conversion */); // still part of parameterized type ref + this.tagBits |= resolvedType.tagBits & TagBits.ContainsNestedTypeReferences; if (this.arguments != null) { int argLength = this.arguments.length; - for (int i = 0; i < argLength; i++) - this.arguments[i] = BinaryTypeBinding.resolveType(this.arguments[i], this.environment, true /* raw conversion */); + for (int i = 0; i < argLength; i++) { + TypeBinding resolveType = BinaryTypeBinding.resolveType(this.arguments[i], this.environment, true /* raw conversion */); + this.arguments[i] = resolveType; + this.tagBits |= resolvedType.tagBits & TagBits.ContainsNestedTypeReferences; + } // arity check TypeVariableBinding[] refTypeVariables = resolvedType.typeVariables(); if (refTypeVariables == Binding.NO_TYPE_VARIABLES) { // check generic Index: compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java,v retrieving revision 1.355 diff -u -r1.355 Scope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 6 May 2009 21:25:21 -0000 1.355 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 12 May 2009 18:57:21 -0000 @@ -621,6 +621,7 @@ } else { typeVariable.superInterfaces = new ReferenceBinding[] {superRefType}; } + typeVariable.tagBits |= superType.tagBits & TagBits.ContainsNestedTypeReferences; typeVariable.firstBound = superRefType; // first bound used to compute erasure } } @@ -635,6 +636,7 @@ typeVariable.tagBits |= TagBits.HierarchyHasProblems; continue nextBound; } else { + typeVariable.tagBits |= superType.tagBits & TagBits.ContainsNestedTypeReferences; boolean didAlreadyComplain = !typeRef.resolvedType.isValidBinding(); if (isFirstBoundTypeVariable && j == 0) { problemReporter().noAdditionalBoundAfterTypeVariable(typeRef); Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java,v retrieving revision 1.59 diff -u -r1.59 ArrayBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java 27 Jun 2008 16:04:02 -0000 1.59 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ArrayBinding.java 12 May 2009 18:57:21 -0000 @@ -35,7 +35,7 @@ if (type instanceof UnresolvedReferenceBinding) ((UnresolvedReferenceBinding) type).addWrapper(this, environment); else - this.tagBits |= type.tagBits & (TagBits.HasTypeVariable | TagBits.HasDirectWildcard | TagBits.HasMissingType); + this.tagBits |= type.tagBits & (TagBits.HasTypeVariable | TagBits.HasDirectWildcard | TagBits.HasMissingType | TagBits.ContainsNestedTypeReferences); } public TypeBinding closestMatch() { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java,v retrieving revision 1.72 diff -u -r1.72 TypeVariableBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 27 Feb 2009 16:58:42 -0000 1.72 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TypeVariableBinding.java 12 May 2009 18:57:21 -0000 @@ -398,14 +398,19 @@ return this; TypeBinding oldSuperclass = this.superclass, oldFirstInterface = null; - if (this.superclass != null) - this.superclass = (ReferenceBinding) BinaryTypeBinding.resolveType(this.superclass, this.environment, true /* raw conversion */); + if (this.superclass != null) { + ReferenceBinding resolveType = (ReferenceBinding) BinaryTypeBinding.resolveType(this.superclass, this.environment, true /* raw conversion */); + this.tagBits |= resolveType.tagBits & TagBits.ContainsNestedTypeReferences; + this.superclass = resolveType; + } ReferenceBinding[] interfaces = this.superInterfaces; int length; if ((length = interfaces.length) != 0) { oldFirstInterface = interfaces[0]; for (int i = length; --i >= 0;) { - interfaces[i] = (ReferenceBinding) BinaryTypeBinding.resolveType(interfaces[i], this.environment, true /* raw conversion */); + ReferenceBinding resolveType = (ReferenceBinding) BinaryTypeBinding.resolveType(interfaces[i], this.environment, true /* raw conversion */); + this.tagBits |= resolveType.tagBits & TagBits.ContainsNestedTypeReferences; + interfaces[i] = resolveType; } } // refresh the firstBound in case it changed Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java,v retrieving revision 1.117 diff -u -r1.117 MethodBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java 19 Mar 2009 17:39:40 -0000 1.117 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodBinding.java 12 May 2009 18:57:21 -0000 @@ -20,6 +20,7 @@ import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; +import org.eclipse.jdt.internal.compiler.util.Util; public class MethodBinding extends Binding { @@ -962,7 +963,7 @@ */ public final char[] signature(ClassFile classFile) { if (this.signature != null) { - if ((this.tagBits & TagBits.ContainsNestedTypesInSignature) != 0) { + if ((this.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { // we need to record inner classes references boolean isConstructor = isConstructor(); TypeBinding[] targetParameters = this.parameters; @@ -973,8 +974,8 @@ if (syntheticArgumentTypes != null) { for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) { ReferenceBinding syntheticArgumentType = syntheticArgumentTypes[i]; - if (syntheticArgumentType.isNestedType()) { - classFile.recordInnerClasses(syntheticArgumentType); + if ((syntheticArgumentType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, syntheticArgumentType); } } } @@ -984,11 +985,11 @@ } if (targetParameters != Binding.NO_PARAMETERS) { - for (int i = 0; i < targetParameters.length; i++) { + for (int i = 0, max = targetParameters.length; i < max; i++) { TypeBinding targetParameter = targetParameters[i]; TypeBinding leafTargetParameterType = targetParameter.leafComponentType(); - if (leafTargetParameterType.isNestedType()) { - classFile.recordInnerClasses(leafTargetParameterType); + if ((leafTargetParameterType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, leafTargetParameterType); } } } @@ -997,15 +998,15 @@ for (int i = targetParameters.length, extraLength = this.parameters.length; i < extraLength; i++) { TypeBinding parameter = this.parameters[i]; TypeBinding leafParameterType = parameter.leafComponentType(); - if (leafParameterType.isNestedType()) { - classFile.recordInnerClasses(leafParameterType); + if ((leafParameterType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, leafParameterType); } } } if (this.returnType != null) { TypeBinding ret = this.returnType.leafComponentType(); - if (ret.isNestedType()) { - classFile.recordInnerClasses(ret); + if ((ret.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, ret); } } } @@ -1028,9 +1029,9 @@ if (syntheticArgumentTypes != null) { for (int i = 0, count = syntheticArgumentTypes.length; i < count; i++) { ReferenceBinding syntheticArgumentType = syntheticArgumentTypes[i]; - if (syntheticArgumentType.isNestedType()) { - this.tagBits |= TagBits.ContainsNestedTypesInSignature; - classFile.recordInnerClasses(syntheticArgumentType); + if ((syntheticArgumentType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + this.tagBits |= TagBits.ContainsNestedTypeReferences; + Util.recordNestedType(classFile, syntheticArgumentType); } buffer.append(syntheticArgumentType.signature()); } @@ -1042,12 +1043,12 @@ } if (targetParameters != Binding.NO_PARAMETERS) { - for (int i = 0; i < targetParameters.length; i++) { + for (int i = 0, max = targetParameters.length; i < max; i++) { TypeBinding targetParameter = targetParameters[i]; TypeBinding leafTargetParameterType = targetParameter.leafComponentType(); - if (leafTargetParameterType.isNestedType()) { - this.tagBits |= TagBits.ContainsNestedTypesInSignature; - classFile.recordInnerClasses(leafTargetParameterType); + if ((leafTargetParameterType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + this.tagBits |= TagBits.ContainsNestedTypeReferences; + Util.recordNestedType(classFile, leafTargetParameterType); } buffer.append(targetParameter.signature()); } @@ -1062,9 +1063,9 @@ for (int i = targetParameters.length, extraLength = this.parameters.length; i < extraLength; i++) { TypeBinding parameter = this.parameters[i]; TypeBinding leafParameterType = parameter.leafComponentType(); - if (leafParameterType.isNestedType()) { - this.tagBits |= TagBits.ContainsNestedTypesInSignature; - classFile.recordInnerClasses(leafParameterType); + if ((leafParameterType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + this.tagBits |= TagBits.ContainsNestedTypeReferences; + Util.recordNestedType(classFile, leafParameterType); } buffer.append(parameter.signature()); } @@ -1072,9 +1073,9 @@ buffer.append(')'); if (this.returnType != null) { TypeBinding ret = this.returnType.leafComponentType(); - if (ret.isNestedType()) { - this.tagBits |= TagBits.ContainsNestedTypesInSignature; - classFile.recordInnerClasses(ret); + if ((ret.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + this.tagBits |= TagBits.ContainsNestedTypeReferences; + Util.recordNestedType(classFile, ret); } buffer.append(this.returnType.signature()); } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java,v retrieving revision 1.36 diff -u -r1.36 TagBits.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java 7 Mar 2009 00:59:02 -0000 1.36 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java 12 May 2009 18:57:21 -0000 @@ -19,11 +19,12 @@ long IsBaseType = ASTNode.Bit2; long IsNestedType = ASTNode.Bit3; long IsMemberType = ASTNode.Bit4; - long MemberTypeMask = IsNestedType | IsMemberType; + long ContainsNestedTypeReferences = ASTNode.Bit12; // method/parameterized type binding + long MemberTypeMask = IsNestedType | IsMemberType | ContainsNestedTypeReferences; long IsLocalType = ASTNode.Bit5; - long LocalTypeMask = IsNestedType | IsLocalType; + long LocalTypeMask = IsNestedType | IsLocalType | ContainsNestedTypeReferences; long IsAnonymousType = ASTNode.Bit6; - long AnonymousTypeMask = LocalTypeMask | IsAnonymousType; + long AnonymousTypeMask = LocalTypeMask | IsAnonymousType | ContainsNestedTypeReferences; long IsBinaryBinding = ASTNode.Bit7; // set for all bindings either represeting a missing type (type), or directly referencing a missing type (field/method/variable) @@ -35,9 +36,9 @@ // for the type cycle hierarchy check used by ClassScope long BeginHierarchyCheck = ASTNode.Bit9; // type long EndHierarchyCheck = ASTNode.Bit10; // type - long ContainsNestedTypesInSignature = ASTNode.Bit10; // method long HasParameterAnnotations = ASTNode.Bit11; // method + // test bit to see if default abstract methods were computed long KnowsDefaultAbstractMethods = ASTNode.Bit11; // type Index: compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java,v retrieving revision 1.23 diff -u -r1.23 NestedTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java 24 Sep 2008 16:05:23 -0000 1.23 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java 12 May 2009 18:57:21 -0000 @@ -21,7 +21,7 @@ public NestedTypeBinding(char[][] typeName, ClassScope scope, SourceTypeBinding enclosingType) { super(typeName, enclosingType.fPackage, scope); - this.tagBits |= TagBits.IsNestedType; + this.tagBits |= (TagBits.IsNestedType | TagBits.ContainsNestedTypeReferences); this.enclosingType = enclosingType; } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java,v retrieving revision 1.73 diff -u -r1.73 WildcardBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java 7 Mar 2009 00:59:02 -0000 1.73 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/WildcardBinding.java 12 May 2009 18:57:21 -0000 @@ -39,7 +39,7 @@ */ public WildcardBinding(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind, LookupEnvironment environment) { this.rank = rank; - this.boundKind = boundKind; + this.boundKind = boundKind; this.modifiers = ClassFileConstants.AccPublic | ExtraCompilerModifiers.AccGenericSignature; // treat wildcard as public this.environment = environment; initialize(genericType, bound, otherBounds); @@ -53,7 +53,7 @@ ((UnresolvedReferenceBinding) genericType).addWrapper(this, environment); if (bound instanceof UnresolvedReferenceBinding) ((UnresolvedReferenceBinding) bound).addWrapper(this, environment); - this.tagBits |= TagBits.HasUnresolvedTypeVariables; // cleared in resolve() + this.tagBits |= TagBits.HasUnresolvedTypeVariables; // cleared in resolve() } public int kind() { @@ -425,7 +425,13 @@ this.fPackage = someGenericType.getPackage(); } if (someBound != null) { - this.tagBits |= someBound.tagBits & (TagBits.HasTypeVariable | TagBits.HasMissingType); + this.tagBits |= someBound.tagBits & (TagBits.HasTypeVariable | TagBits.HasMissingType | TagBits.ContainsNestedTypeReferences); + } + if (someOtherBounds != null) { + for (int i = 0, max = someOtherBounds.length; i < max; i++) { + TypeBinding someOtherBound = someOtherBounds[i]; + this.tagBits |= someOtherBound.tagBits & TagBits.ContainsNestedTypeReferences; + } } } @@ -494,18 +500,30 @@ this.tagBits &= ~TagBits.HasUnresolvedTypeVariables; BinaryTypeBinding.resolveType(this.genericType, this.environment, false /* no raw conversion */); - switch(this.boundKind) { - case Wildcard.EXTENDS : - this.bound = BinaryTypeBinding.resolveType(this.bound, this.environment, true /* raw conversion */); - for (int i = 0, length = this.otherBounds == null ? 0 : this.otherBounds.length; i < length; i++) { - this.otherBounds[i]= BinaryTypeBinding.resolveType(this.bound, this.environment, true /* raw conversion */); - } + switch(this.boundKind) { + case Wildcard.EXTENDS : + TypeBinding resolveType = BinaryTypeBinding.resolveType(this.bound, this.environment, true /* raw conversion */); + this.bound = resolveType; + if (resolveType.isNestedType() || ((resolveType.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) { + this.tagBits |= TagBits.ContainsNestedTypeReferences; + } + for (int i = 0, length = this.otherBounds == null ? 0 : this.otherBounds.length; i < length; i++) { + resolveType = BinaryTypeBinding.resolveType(this.otherBounds[i], this.environment, true /* raw conversion */); + this.otherBounds[i]= resolveType; + if (resolveType.isNestedType() || ((resolveType.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) { + this.tagBits |= TagBits.ContainsNestedTypeReferences; + } + } break; - case Wildcard.SUPER : - this.bound = BinaryTypeBinding.resolveType(this.bound, this.environment, true /* raw conversion */); + case Wildcard.SUPER : + resolveType = BinaryTypeBinding.resolveType(this.bound, this.environment, true /* raw conversion */); + this.bound = resolveType; + if (resolveType.isNestedType() || ((resolveType.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) { + this.tagBits |= TagBits.ContainsNestedTypeReferences; + } break; case Wildcard.UNBOUND : - } + } return this; } Index: compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java,v retrieving revision 1.157 diff -u -r1.157 TypeDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 19 Mar 2009 23:20:16 -0000 1.157 +++ compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 12 May 2009 18:57:21 -0000 @@ -516,6 +516,13 @@ enclosingClassFile.recordInnerClasses(this.binding); classFile.recordInnerClasses(this.binding); } + TypeVariableBinding[] typeVariables = this.binding.typeVariables(); + for (int i = 0, max = typeVariables.length; i < max; i++) { + TypeVariableBinding typeVariableBinding = typeVariables[i]; + if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, typeVariableBinding); + } + } // generate all fiels classFile.addFieldInfos(); Index: compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java,v retrieving revision 1.85 diff -u -r1.85 CompilationUnitDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java 12 Jan 2009 18:37:16 -0000 1.85 +++ compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java 12 May 2009 18:57:21 -0000 @@ -146,6 +146,7 @@ classFile.referenceBinding = null; classFile.innerClassesBindings = null; classFile.missingTypes = null; + classFile.visitedTypes = null; } this.suppressWarningAnnotations = null; Index: compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java,v retrieving revision 1.171 diff -u -r1.171 CodeStream.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 1 Oct 2008 21:16:38 -0000 1.171 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 12 May 2009 18:57:21 -0000 @@ -1217,8 +1217,8 @@ public void fieldAccess(byte opcode, FieldBinding fieldBinding, TypeBinding declaringClass) { if (declaringClass == null) declaringClass = fieldBinding.declaringClass; - if (declaringClass.leafComponentType().isNestedType()) { - this.classFile.recordInnerClasses(declaringClass); + if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(this.classFile, declaringClass); } TypeBinding returnType = fieldBinding.type; int returnTypeSize; @@ -3835,52 +3835,52 @@ public void invoke(byte opcode, MethodBinding methodBinding, TypeBinding declaringClass) { if (declaringClass == null) declaringClass = methodBinding.declaringClass; - if (declaringClass.isNestedType()) { - this.classFile.recordInnerClasses(declaringClass); - } - // compute receiverAndArgsSize - int receiverAndArgsSize; - switch(opcode) { - case Opcodes.OPC_invokestatic : - receiverAndArgsSize = 0; // no receiver - break; - case Opcodes.OPC_invokeinterface : - case Opcodes.OPC_invokevirtual : - receiverAndArgsSize = 1; // receiver - break; - case Opcodes.OPC_invokespecial : - receiverAndArgsSize = 1; // receiver - if (methodBinding.isConstructor()) { - if (declaringClass.isNestedType()) { - ReferenceBinding nestedType = (ReferenceBinding) declaringClass; - // enclosing instances - receiverAndArgsSize += nestedType.getEnclosingInstancesSlotSize(); - // outer local variables - SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables(); - if (syntheticArguments != null) { - for (int i = 0, max = syntheticArguments.length; i < max; i++) { - switch (syntheticArguments[i].id) { - case TypeIds.T_double : - case TypeIds.T_long : - receiverAndArgsSize += 2; + if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(this.classFile, declaringClass); + } + // compute receiverAndArgsSize + int receiverAndArgsSize; + switch(opcode) { + case Opcodes.OPC_invokestatic : + receiverAndArgsSize = 0; // no receiver + break; + case Opcodes.OPC_invokeinterface : + case Opcodes.OPC_invokevirtual : + receiverAndArgsSize = 1; // receiver + break; + case Opcodes.OPC_invokespecial : + receiverAndArgsSize = 1; // receiver + if (methodBinding.isConstructor()) { + if (declaringClass.isNestedType()) { + ReferenceBinding nestedType = (ReferenceBinding) declaringClass; + // enclosing instances + receiverAndArgsSize += nestedType.getEnclosingInstancesSlotSize(); + // outer local variables + SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables(); + if (syntheticArguments != null) { + for (int i = 0, max = syntheticArguments.length; i < max; i++) { + switch (syntheticArguments[i].id) { + case TypeIds.T_double : + case TypeIds.T_long : + receiverAndArgsSize += 2; break; - default: - receiverAndArgsSize++; - break; - } - } - } - } - if (declaringClass.isEnum()) { - // adding String (name) and int (ordinal) - receiverAndArgsSize += 2; - } - } - break; - default : - return; // should not occur - - } + default: + receiverAndArgsSize++; + break; + } + } + } + } + if (declaringClass.isEnum()) { + // adding String (name) and int (ordinal) + receiverAndArgsSize += 2; + } + } + break; + default : + return; // should not occur + + } for (int i = methodBinding.parameters.length - 1; i >= 0; i--) { switch (methodBinding.parameters[i].id) { case TypeIds.T_double : @@ -3993,9 +3993,9 @@ public void invokeIterableIterator(TypeBinding iterableReceiverType) { // invokevirtual/interface: .iterator() - if (iterableReceiverType.isNestedType()) { - this.classFile.recordInnerClasses(iterableReceiverType); - } + if ((iterableReceiverType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(this.classFile, iterableReceiverType); + } invoke( iterableReceiverType.isInterface() ? Opcodes.OPC_invokeinterface : Opcodes.OPC_invokevirtual, 1, // receiverAndArgsSize Index: compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java,v retrieving revision 1.60 diff -u -r1.60 ConstantPool.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java 7 Mar 2009 00:58:59 -0000 1.60 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java 12 May 2009 18:57:21 -0000 @@ -13,10 +13,12 @@ import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.lookup.TagBits; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; +import org.eclipse.jdt.internal.compiler.util.Util; /** * This type is used to store all the constant pool entries. */ @@ -297,11 +299,11 @@ return index; } public int literalIndex(TypeBinding binding) { - TypeBinding typeBinding = binding.leafComponentType(); - if (typeBinding.isNestedType()) { - this.classFile.recordInnerClasses(typeBinding); - } - return literalIndex(binding.signature()); + TypeBinding typeBinding = binding.leafComponentType(); + if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(this.classFile, typeBinding); + } + return literalIndex(binding.signature()); } /** * This method returns the index into the constantPool corresponding to the type descriptor. @@ -647,11 +649,11 @@ * binding must not be an array type. */ public int literalIndexForType(final TypeBinding binding) { - TypeBinding typeBinding = binding.leafComponentType(); - if (typeBinding.isNestedType()) { - this.classFile.recordInnerClasses(typeBinding); - } - return this.literalIndexForType(binding.constantPoolName()); + TypeBinding typeBinding = binding.leafComponentType(); + if ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(this.classFile, typeBinding); + } + return this.literalIndexForType(binding.constantPoolName()); } public int literalIndexForMethod(char[] declaringClass, char[] selector, char[] signature, boolean isInterface) { int index; @@ -688,10 +690,10 @@ return index; } public int literalIndexForMethod(TypeBinding declaringClass, char[] selector, char[] signature, boolean isInterface) { - if (declaringClass.isNestedType()) { - this.classFile.recordInnerClasses(declaringClass); - } - return this.literalIndexForMethod(declaringClass.constantPoolName(), selector, signature, isInterface); + if ((declaringClass.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(this.classFile, declaringClass); + } + return this.literalIndexForMethod(declaringClass.constantPoolName(), selector, signature, isInterface); } public int literalIndexForNameAndType(char[] name, char[] signature) { int index; Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java,v retrieving revision 1.19 diff -u -r1.19 CodeSnippetTypeDeclaration.java --- eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java 7 Mar 2009 01:08:09 -0000 1.19 +++ eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java 12 May 2009 18:57:21 -0000 @@ -14,7 +14,10 @@ import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.lookup.TagBits; +import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; import org.eclipse.jdt.internal.compiler.problem.AbortType; +import org.eclipse.jdt.internal.compiler.util.Util; public class CodeSnippetTypeDeclaration extends TypeDeclaration { @@ -46,7 +49,13 @@ enclosingClassFile.recordInnerClasses(this.binding); classFile.recordInnerClasses(this.binding); } - + TypeVariableBinding[] typeVariables = this.binding.typeVariables(); + for (int i = 0, max = typeVariables.length; i < max; i++) { + TypeVariableBinding typeVariableBinding = typeVariables[i]; + if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, typeVariableBinding); + } + } if (this.memberTypes != null) { for (int i = 0, max = this.memberTypes.length; i < max; i++) { TypeDeclaration memberType = this.memberTypes[i]; Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java,v retrieving revision 1.49 diff -u -r1.49 CodeSnippetClassFile.java --- eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java 19 Mar 2009 23:20:17 -0000 1.49 +++ eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java 12 May 2009 18:57:21 -0000 @@ -24,6 +24,9 @@ import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.TagBits; +import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; +import org.eclipse.jdt.internal.compiler.util.Util; public class CodeSnippetClassFile extends ClassFile { /** @@ -144,6 +147,13 @@ if (typeBinding.isNestedType()) { classFile.recordInnerClasses(typeBinding); } + TypeVariableBinding[] typeVariables = typeBinding.typeVariables(); + for (int i = 0, max = typeVariables.length; i < max; i++) { + TypeVariableBinding typeVariableBinding = typeVariables[i]; + if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, typeVariableBinding); + } + } // add its fields FieldBinding[] fields = typeBinding.fields(); Index: compiler/org/eclipse/jdt/internal/compiler/util/Util.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java,v retrieving revision 1.73 diff -u -r1.73 Util.java --- compiler/org/eclipse/jdt/internal/compiler/util/Util.java 7 May 2009 13:14:51 -0000 1.73 +++ compiler/org/eclipse/jdt/internal/compiler/util/Util.java 12 May 2009 18:57:21 -0000 @@ -23,6 +23,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; +import java.util.HashSet; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -32,6 +33,12 @@ import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; +import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.TagBits; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; +import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding; public class Util implements SuffixConstants { @@ -810,4 +817,69 @@ output.close(); } } -} + public static void recordNestedType(ClassFile classFile, TypeBinding typeBinding) { + if (classFile.visitedTypes == null) { + classFile.visitedTypes = new HashSet(3); + } else if (classFile.visitedTypes.contains(typeBinding)) { + // type is already visited + return; + } + classFile.visitedTypes.add(typeBinding); + if (typeBinding.isParameterizedType() + && ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) { + ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) typeBinding; + ReferenceBinding genericType = parameterizedTypeBinding.genericType(); + if ((genericType.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + recordNestedType(classFile, genericType); + } + TypeBinding[] arguments = parameterizedTypeBinding.arguments; + if (arguments != null) { + for (int j = 0, max2 = arguments.length; j < max2; j++) { + TypeBinding argument = arguments[j]; + if (argument.isWildcard()) { + WildcardBinding wildcardBinding = (WildcardBinding) argument; + TypeBinding bound = wildcardBinding.bound; + if (bound != null + && ((bound.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) { + recordNestedType(classFile, bound); + } + ReferenceBinding superclass = wildcardBinding.superclass(); + if (superclass != null + && ((superclass.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) { + recordNestedType(classFile, superclass); + } + ReferenceBinding[] superInterfaces = wildcardBinding.superInterfaces(); + if (superInterfaces != null) { + for (int k = 0, max3 = superInterfaces.length; k < max3; k++) { + ReferenceBinding superInterface = superInterfaces[k]; + if ((superInterface.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + recordNestedType(classFile, superInterface); + } + } + } + } else if ((argument.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + recordNestedType(classFile, argument); + } + } + } + } else if (typeBinding.isTypeVariable() + && ((typeBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) { + TypeVariableBinding typeVariableBinding = (TypeVariableBinding) typeBinding; + TypeBinding upperBound = typeVariableBinding.upperBound(); + if (upperBound != null && ((upperBound.tagBits & TagBits.ContainsNestedTypeReferences) != 0)) { + recordNestedType(classFile, upperBound); + } + TypeBinding[] upperBounds = typeVariableBinding.otherUpperBounds(); + if (upperBounds != null) { + for (int k = 0, max3 = upperBounds.length; k < max3; k++) { + TypeBinding otherUpperBound = upperBounds[k]; + if ((otherUpperBound.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + recordNestedType(classFile, otherUpperBound); + } + } + } + } else if (typeBinding.isNestedType()) { + classFile.recordInnerClasses(typeBinding); + } + } +} \ No newline at end of file Index: compiler/org/eclipse/jdt/internal/compiler/ClassFile.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java,v retrieving revision 1.187 diff -u -r1.187 ClassFile.java --- compiler/org/eclipse/jdt/internal/compiler/ClassFile.java 27 Apr 2009 18:52:00 -0000 1.187 +++ compiler/org/eclipse/jdt/internal/compiler/ClassFile.java 12 May 2009 18:57:21 -0000 @@ -67,6 +67,7 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; +import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement; import org.eclipse.jdt.internal.compiler.util.Messages; @@ -123,6 +124,8 @@ public List missingTypes = null; + public Set visitedTypes; + public static final int INITIAL_CONTENTS_SIZE = 400; public static final int INITIAL_HEADER_SIZE = 1500; public static final int INNER_CLASSES_SIZE = 5; @@ -151,7 +154,13 @@ if (typeBinding.isNestedType()) { classFile.recordInnerClasses(typeBinding); } - + TypeVariableBinding[] typeVariables = typeBinding.typeVariables(); + for (int i = 0, max = typeVariables.length; i < max; i++) { + TypeVariableBinding typeVariableBinding = typeVariables[i]; + if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) { + Util.recordNestedType(classFile, typeVariableBinding); + } + } // add its fields FieldBinding[] fields = typeBinding.fields(); if ((fields != null) && (fields != Binding.NO_FIELDS)) { @@ -7182,6 +7191,7 @@ this.innerClassesBindings.clear(); } this.missingTypes = null; + this.visitedTypes = null; } /**