### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java,v retrieving revision 1.124 diff -u -r1.124 BinaryTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 8 Sep 2010 12:55:49 -0000 1.124 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 27 Sep 2010 11:29:55 -0000 @@ -149,7 +149,12 @@ this.fPackage = packageBinding; this.fileName = binaryType.getFileName(); - char[] typeSignature = environment.globalOptions.originalSourceLevel >= ClassFileConstants.JDK1_5 ? binaryType.getGenericSignature() : null; + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we + must internalize type variables and observe any parameterization of super class + and/or super interfaces in order to be able to detect overriding in the presence + of generics. + */ + char[] typeSignature = binaryType.getGenericSignature(); this.typeVariables = typeSignature != null && typeSignature.length > 0 && typeSignature[0] == '<' ? null // is initialized in cachePartsFrom (called from LookupEnvironment.createBinaryTypeFrom())... must set to null so isGenericType() answers true : Binding.NO_TYPE_VARIABLES; @@ -261,11 +266,14 @@ } long sourceLevel = this.environment.globalOptions.originalSourceLevel; - char[] typeSignature = null; - if (sourceLevel >= ClassFileConstants.JDK1_5) { - typeSignature = binaryType.getGenericSignature(); - this.tagBits |= binaryType.getTagBits(); - } + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we + must internalize type variables and observe any parameterization of super class + and/or super interfaces in order to be able to detect overriding in the presence + of generics. + */ + char[] typeSignature = binaryType.getGenericSignature(); // use generic signature even in 1.4 + this.tagBits |= binaryType.getTagBits(); + char[][][] missingTypeNames = binaryType.getMissingTypeNames(); if (typeSignature == null) { char[] superclassName = binaryType.getSuperclassName(); @@ -412,7 +420,12 @@ TypeBinding returnType = null; final boolean use15specifics = sourceLevel >= ClassFileConstants.JDK1_5; - char[] methodSignature = use15specifics ? method.getGenericSignature() : null; + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, Since a 1.4 project can have a 1.5 + type as a super type and the 1.5 type could be generic, we must internalize usages of type + variables properly in order to be able to apply substitutions and thus be able to detect + overriding in the presence of generics. Seeing the erased form is not good enough. + */ + char[] methodSignature = method.getGenericSignature(); // always use generic signature, even in 1.4 if (methodSignature == null) { // no generics char[] methodDescriptor = method.getMethodDescriptor(); // of the form (I[Ljava/jang/String;)V int numOfParams = 0; @@ -476,7 +489,7 @@ } else { methodModifiers |= ExtraCompilerModifiers.AccGenericSignature; // MethodTypeSignature = ParameterPart(optional) '(' TypeSignatures ')' return_typeSignature ['^' TypeSignature (optional)] - SignatureWrapper wrapper = new SignatureWrapper(methodSignature); + SignatureWrapper wrapper = new SignatureWrapper(methodSignature, use15specifics); if (wrapper.signature[wrapper.start] == '<') { // (Ljava/lang/Class;)TA; // ParameterPart = '<' ParameterSignature(s) '>' Index: compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java,v retrieving revision 1.180 diff -u -r1.180 ClassScope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 26 Jul 2010 16:21:40 -0000 1.180 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java 27 Sep 2010 11:29:58 -0000 @@ -385,8 +385,7 @@ SourceTypeBinding sourceType = this.referenceContext.binding; TypeParameter[] typeParameters = this.referenceContext.typeParameters; - // do not construct type variables if source < 1.5 - if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) { + if (typeParameters == null || typeParameters.length == 0) { sourceType.typeVariables = Binding.NO_TYPE_VARIABLES; return; } Index: compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java,v retrieving revision 1.106 diff -u -r1.106 LookupEnvironment.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java 26 Jul 2010 16:21:40 -0000 1.106 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java 27 Sep 2010 11:30:02 -0000 @@ -1322,9 +1322,12 @@ } public MethodVerifier newMethodVerifier() { - return this.globalOptions.sourceLevel < ClassFileConstants.JDK1_5 - ? new MethodVerifier(this) - : new MethodVerifier15(this); // covariance only if sourceLevel is >= 1.5 + /* Always use MethodVerifier15. Even in a 1.4 project, we must internalize type variables and + observe any parameterization of super class and/or super interfaces in order to be able to + detect overriding in the presence of generics. + See https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 + */ + return new MethodVerifier15(this); } public void releaseClassFiles(org.eclipse.jdt.internal.compiler.ClassFile[] classFiles) { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java,v retrieving revision 1.115 diff -u -r1.115 MethodVerifier15.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java 26 Aug 2010 15:01:12 -0000 1.115 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/MethodVerifier15.java 27 Sep 2010 11:30:05 -0000 @@ -11,6 +11,7 @@ package org.eclipse.jdt.internal.compiler.lookup; import org.eclipse.jdt.internal.compiler.ast.TypeParameter; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.SimpleSet; @@ -80,7 +81,11 @@ } boolean areReturnTypesCompatible(MethodBinding one, MethodBinding two) { if (one.returnType == two.returnType) return true; - return areReturnTypesCompatible0(one, two); + if (this.type.scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) { + return areReturnTypesCompatible0(one, two); + } else { + return areTypesEqual(one.returnType.erasure(), two.returnType.erasure()); + } } boolean areTypesEqual(TypeBinding one, TypeBinding two) { if (one == two) return true; 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.373 diff -u -r1.373 Scope.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 19 Aug 2010 08:24:18 -0000 1.373 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java 27 Sep 2010 11:30:15 -0000 @@ -705,7 +705,7 @@ public TypeVariableBinding[] createTypeVariables(TypeParameter[] typeParameters, Binding declaringElement) { // do not construct type variables if source < 1.5 - if (typeParameters == null || compilerOptions().sourceLevel < ClassFileConstants.JDK1_5) + if (typeParameters == null || typeParameters.length == 0) return Binding.NO_TYPE_VARIABLES; PackageBinding unitPackage = compilationUnitScope().fPackage; Index: compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java,v retrieving revision 1.8 diff -u -r1.8 SignatureWrapper.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java 7 Mar 2009 01:08:09 -0000 1.8 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/SignatureWrapper.java 27 Sep 2010 11:30:15 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -17,11 +17,16 @@ public int start; public int end; public int bracket; + private boolean use15specifics; - public SignatureWrapper(char[] signature) { + public SignatureWrapper(char[] signature, boolean use15specifics) { this.signature = signature; this.start = 0; this.end = this.bracket = -1; + this.use15specifics = use15specifics; + } + public SignatureWrapper(char [] signature) { + this(signature, true); } public boolean atEnd() { return this.start < 0 || this.start >= this.signature.length; @@ -46,9 +51,33 @@ this.end = this.start; } - this.start = this.end + 1; // skip ';' + if (this.use15specifics || this.end != this.bracket) { + this.start = this.end + 1; // skip ';' + } else { + this.start = skipAngleContents(this.end) + 1; // skip <<>*>; + this.bracket = -1; + } return this.end; } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, do not expose generics if we shouldn't + public int skipAngleContents(int i) { + if (this.signature[i] != '<') { + return i; + } + int depth = 0, length = this.signature.length; + for (++i; i < length; i++) { + switch(this.signature[i]) { + case '<' : + depth++; + break; + case '>' : + if (--depth < 0) + return i + 1; + break; + } + } + return i; + } public char[] nextWord() { this.end = CharOperation.indexOf(';', this.signature, this.start); if (this.bracket <= this.start) // already know it if its > start Index: compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java,v retrieving revision 1.422 diff -u -r1.422 ProblemReporter.java --- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 21 Sep 2010 14:02:58 -0000 1.422 +++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 27 Sep 2010 11:30:28 -0000 @@ -7083,6 +7083,9 @@ } } public void unsafeReturnTypeOverride(MethodBinding currentMethod, MethodBinding inheritedMethod, SourceTypeBinding type) { + if (this.options.sourceLevel < ClassFileConstants.JDK1_5) { + return; + } int severity = computeSeverity(IProblem.UnsafeReturnTypeOverride); if (severity == ProblemSeverities.Ignore) return; int start = type.sourceStart(); Index: model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java,v retrieving revision 1.68 diff -u -r1.68 SourceTypeConverter.java --- model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java 8 Sep 2010 12:55:49 -0000 1.68 +++ model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java 27 Sep 2010 11:30:29 -0000 @@ -291,21 +291,22 @@ int start = methodInfo.getNameSourceStart(); int end = methodInfo.getNameSourceEnd(); - // convert 1.5 specific constructs only if compliance is 1.5 or above + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, Even when this type is being constructed + on behalf of a 1.4 project we must internalize type variables properly in order to be able to + recognize usages of them in the method signature, to apply substitutions and thus to be able to + detect overriding in the presence of generics. If we simply drop them, when the method signature + refers to the type parameter, we won't know it should be bound to the type parameter and perform + incorrect lookup and may mistakenly end up with missing types + */ TypeParameter[] typeParams = null; - // Digest type parameters if compliance level of current project or its prerequisite is >= 1.5 - // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 && https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259 - if (this.has1_5Compliance || this.problemReporter.options.complianceLevel >= ClassFileConstants.JDK1_5) { - /* convert type parameters */ - char[][] typeParameterNames = methodInfo.getTypeParameterNames(); - if (typeParameterNames != null) { - int parameterCount = typeParameterNames.length; - if (parameterCount > 0) { // method's type parameters must be null if no type parameter - char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds(); - typeParams = new TypeParameter[parameterCount]; - for (int i = 0; i < parameterCount; i++) { - typeParams[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end); - } + char[][] typeParameterNames = methodInfo.getTypeParameterNames(); + if (typeParameterNames != null) { + int parameterCount = typeParameterNames.length; + if (parameterCount > 0) { // method's type parameters must be null if no type parameter + char[][][] typeParameterBounds = methodInfo.getTypeParameterBounds(); + typeParams = new TypeParameter[parameterCount]; + for (int i = 0; i < parameterCount; i++) { + typeParams[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end); } } } @@ -465,24 +466,24 @@ /* convert annotations */ type.annotations = convertAnnotations(typeHandle); } - // Digest type parameters if compliance level of current project or its prerequisite is >= 1.5 - // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 && https://bugs.eclipse.org/bugs/show_bug.cgi?id=305259 - if (this.has1_5Compliance || this.problemReporter.options.complianceLevel >= ClassFileConstants.JDK1_5) { - /* convert type parameters */ - char[][] typeParameterNames = typeInfo.getTypeParameterNames(); - if (typeParameterNames.length > 0) { - int parameterCount = typeParameterNames.length; - char[][][] typeParameterBounds = typeInfo.getTypeParameterBounds(); - type.typeParameters = new TypeParameter[parameterCount]; - for (int i = 0; i < parameterCount; i++) { - type.typeParameters[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end); - } + /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850, even in a 1.4 project, we + must internalize type variables and observe any parameterization of super class + and/or super interfaces in order to be able to detect overriding in the presence + of generics. + */ + char[][] typeParameterNames = typeInfo.getTypeParameterNames(); + if (typeParameterNames.length > 0) { + int parameterCount = typeParameterNames.length; + char[][][] typeParameterBounds = typeInfo.getTypeParameterBounds(); + type.typeParameters = new TypeParameter[parameterCount]; + for (int i = 0; i < parameterCount; i++) { + type.typeParameters[i] = createTypeParameter(typeParameterNames[i], typeParameterBounds[i], start, end); } } /* set superclass and superinterfaces */ if (typeInfo.getSuperclassName() != null) { - type.superclass = createTypeReference(typeInfo.getSuperclassName(), start, end); + type.superclass = createTypeReference(typeInfo.getSuperclassName(), start, end, true /* include generics */); type.superclass.bits |= ASTNode.IsSuperType; } char[][] interfaceNames = typeInfo.getInterfaceNames(); @@ -490,7 +491,7 @@ if (interfaceCount > 0) { type.superInterfaces = new TypeReference[interfaceCount]; for (int i = 0; i < interfaceCount; i++) { - type.superInterfaces[i] = createTypeReference(interfaceNames[i], start, end); + type.superInterfaces[i] = createTypeReference(interfaceNames[i], start, end, true /* include generics */); type.superInterfaces[i].bits |= ASTNode.IsSuperType; } } Index: model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java,v retrieving revision 1.6 diff -u -r1.6 TypeConverter.java --- model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java 22 Sep 2010 04:06:21 -0000 1.6 +++ model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java 27 Sep 2010 11:30:30 -0000 @@ -107,11 +107,25 @@ protected TypeReference createTypeReference( char[] typeName, int start, + int end, + boolean includeGenericsAnyway) { + + int length = typeName.length; + this.namePos = 0; + return decodeType(typeName, length, start, end, true); + } + + /* + * Build a type reference from a readable name, e.g. java.lang.Object[][] + */ + protected TypeReference createTypeReference( + char[] typeName, + int start, int end) { int length = typeName.length; this.namePos = 0; - return decodeType(typeName, length, start, end); + return decodeType(typeName, length, start, end, false); } /* @@ -351,7 +365,7 @@ } } - private TypeReference decodeType(char[] typeName, int length, int start, int end) { + private TypeReference decodeType(char[] typeName, int length, int start, int end, boolean includeGenericsAnyway) { int identCount = 1; int dim = 0; int nameFragmentStart = this.namePos, nameFragmentEnd = -1; @@ -373,7 +387,7 @@ } this.namePos += max; Wildcard result = new Wildcard(Wildcard.SUPER); - result.bound = decodeType(typeName, length, start, end); + result.bound = decodeType(typeName, length, start, end, includeGenericsAnyway); result.sourceStart = start; result.sourceEnd = end; return result; @@ -389,7 +403,7 @@ } this.namePos += max; Wildcard result = new Wildcard(Wildcard.EXTENDS); - result.bound = decodeType(typeName, length, start, end); + result.bound = decodeType(typeName, length, start, end, includeGenericsAnyway); result.sourceStart = start; result.sourceEnd = end; return result; @@ -414,23 +428,27 @@ identCount ++; break; case '<' : - /* We need to convert and preserve 1.5 specific constructs only if compliance is 1.5 or above, - but in all cases, we must skip over them to see if there are any applicable type fragments - after the type parameters: i.e we just aren't done having seen a '<' in 1.4 mode. Because of - the way type signatures are encoded, TypeConverter.decodeType(String, int, int, int) is immune + /* We need to convert and preserve 1.5 specific constructs either if compliance is 1.5 or above, + or the caller has explicitly requested generics to be included. The parameter includeGenericsAnyway + should be used by the caller to signal that in the calling context generics information must be + internalized even when the requesting project is 1.4. But in all cases, we must skip over them to + see if there are any applicable type fragments after the type parameters: i.e we just aren't done + having seen a '<' in 1.4 mode. + + Because of the way type signatures are encoded, TypeConverter.decodeType(String, int, int, int) is immune to this problem. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=325633 */ - if (this.has1_5Compliance) { + if (this.has1_5Compliance || includeGenericsAnyway) { if (fragments == null) fragments = new ArrayList(2); } nameFragmentEnd = this.namePos-1; - if (this.has1_5Compliance) { + if (this.has1_5Compliance || includeGenericsAnyway) { char[][] identifiers = CharOperation.splitOn('.', typeName, nameFragmentStart, this.namePos); fragments.add(identifiers); } this.namePos++; // skip '<' - TypeReference[] arguments = decodeTypeArguments(typeName, length, start, end); // positionned on '>' at end - if (this.has1_5Compliance) { + TypeReference[] arguments = decodeTypeArguments(typeName, length, start, end, includeGenericsAnyway); // positionned on '>' at end + if (this.has1_5Compliance || includeGenericsAnyway) { fragments.add(arguments); identCount = 0; nameFragmentStart = -1; @@ -519,11 +537,11 @@ } } - private TypeReference[] decodeTypeArguments(char[] typeName, int length, int start, int end) { + private TypeReference[] decodeTypeArguments(char[] typeName, int length, int start, int end, boolean includeGenericsAnyway) { ArrayList argumentList = new ArrayList(1); int count = 0; argumentsLoop: while (this.namePos < length) { - TypeReference argument = decodeType(typeName, length, start, end); + TypeReference argument = decodeType(typeName, length, start, end, includeGenericsAnyway); count++; argumentList.add(argument); if (this.namePos >= length) break argumentsLoop; #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java,v retrieving revision 1.202 diff -u -r1.202 MethodVerifyTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java 9 Sep 2010 15:42:19 -0000 1.202 +++ src/org/eclipse/jdt/core/tests/compiler/regression/MethodVerifyTest.java 27 Sep 2010 11:31:12 -0000 @@ -11010,8 +11010,8 @@ "Name clash: The method foo(T) of type Interface has the same erasure as foo(T) of type Base but does not override it\n" + "----------\n"); } -//https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 -public void _test213() { +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 +public void test213() { Map compilerOptions15 = getCompilerOptions(); compilerOptions15.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); compilerOptions15.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); @@ -11061,4 +11061,55 @@ compilerOptions14, null); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 +public void test213a() { + Map compilerOptions15 = getCompilerOptions(); + compilerOptions15.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); + compilerOptions15.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); + compilerOptions15.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); + this.runConformTest( + new String[] { + "Y.java", + "public abstract class Y implements I {\n" + + " public final Y foo(Object o, J> j) {\n" + + " return null;\n" + + " }\n" + + " public final void bar(Object o, J j, Y y) {\n" + + " }\n" + + "}", + "I.java", + "public interface I {\n" + + " public S foo(Object o, J> j);\n" + + " public void bar(Object o, J j, S s);\n" + + "}", + "J.java", + "public interface J {}" + }, + "", + null, + true, + null, + compilerOptions15, + null); + + Map compilerOptions14 = getCompilerOptions(); + compilerOptions14.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_2); + compilerOptions14.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); + compilerOptions14.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3); + this.runConformTest( + new String[] { + "X.java", + "public class X {\n" + + " public Object foo() {\n" + + " return new Y() {};\n" + + " }\n" + + "}" + }, + "", + null, + false, + null, + compilerOptions14, + null); +} } Index: src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java,v retrieving revision 1.35 diff -u -r1.35 ProblemTypeAndMethodTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java 21 Sep 2010 14:02:56 -0000 1.35 +++ src/org/eclipse/jdt/core/tests/compiler/regression/ProblemTypeAndMethodTest.java 27 Sep 2010 11:32:18 -0000 @@ -3379,52 +3379,57 @@ " ^^^^\n" + "The method bar1() from the type X refers to the missing type Zork\n" + "----------\n" + - "2. ERROR in X.java (at line 6)\n" + + "2. ERROR in X.java (at line 5)\n" + + " bar2();\n" + + " ^^^^\n" + + "The method bar2() from the type X refers to the missing type Zork\n" + + "----------\n" + + "3. ERROR in X.java (at line 6)\n" + " bar3(null);\n" + " ^^^^\n" + "The method bar3(Zork) from the type X refers to the missing type Zork\n" + "----------\n" + - "3. ERROR in X.java (at line 7)\n" + + "4. ERROR in X.java (at line 7)\n" + " bar4(null,null);\n" + " ^^^^\n" + "The method bar4(Zork) from the type X refers to the missing type Zork\n" + "----------\n" + - "4. ERROR in X.java (at line 9)\n" + + "5. ERROR in X.java (at line 9)\n" + " Zork bar1() {}\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + "----------\n" + - "5. ERROR in X.java (at line 9)\n" + + "6. ERROR in X.java (at line 9)\n" + " Zork bar1() {}\n" + " ^^^^^^\n" + "Syntax error, parameterized types are only available if source level is 1.5\n" + "----------\n" + - "6. ERROR in X.java (at line 10)\n" + + "7. ERROR in X.java (at line 10)\n" + " List bar2() {}\n" + " ^^^^\n" + "Syntax error, parameterized types are only available if source level is 1.5\n" + "----------\n" + - "7. ERROR in X.java (at line 10)\n" + + "8. ERROR in X.java (at line 10)\n" + " List bar2() {}\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + "----------\n" + - "8. ERROR in X.java (at line 11)\n" + + "9. ERROR in X.java (at line 11)\n" + " void bar3(Zork z) {}\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + "----------\n" + - "9. ERROR in X.java (at line 11)\n" + + "10. ERROR in X.java (at line 11)\n" + " void bar3(Zork z) {}\n" + " ^^^^^^\n" + "Syntax error, parameterized types are only available if source level is 1.5\n" + "----------\n" + - "10. ERROR in X.java (at line 12)\n" + + "11. ERROR in X.java (at line 12)\n" + " void bar4(Zork z) {}\n" + " ^^^^\n" + "Zork cannot be resolved to a type\n" + "----------\n" + - "11. ERROR in X.java (at line 12)\n" + + "12. ERROR in X.java (at line 12)\n" + " void bar4(Zork z) {}\n" + " ^^^^^^^^^^^^^\n" + "Syntax error, parameterized types are only available if source level is 1.5\n" + #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java,v retrieving revision 1.156 diff -u -r1.156 ReconcilerTests.java --- src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java 22 Sep 2010 04:06:19 -0000 1.156 +++ src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java 27 Sep 2010 11:32:43 -0000 @@ -4876,4 +4876,79 @@ deleteProject(project15); } } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=324850 +public void testGenericAPIUsageFromA14Project6() throws CoreException { + IJavaProject project14 = null; + IJavaProject project15 = null; + try { + project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); + createFolder("/Reconciler15API/src/p2"); + createFile( + "/Reconciler15API/src/p2/Y.java", + "package p2;\n" + + "public abstract class Y implements I {\n" + + " public final Y foo(Object o, J j) {\n" + + " return null;\n" + + " }\n" + + " public final void bar(Object o, J j, Y y) {\n" + + " }\n" + + "}\n" + + "interface I {\n" + + " public S foo(Object o, J j);\n" + + " public void bar(Object o, J j, S s);\n" + + "}\n" + + "interface J {}\n" + ); + project15.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_5); + project15.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_5); + project15.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_5); + + project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin"); + project14.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); + project14.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_4); + project14.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4); + + IClasspathEntry[] oldClasspath = project14.getRawClasspath(); + int oldLength = oldClasspath.length; + IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; + System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); + newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler15API")); + project14.setRawClasspath(newClasspath, null); + + createFolder("/Reconciler1415/src/p1"); + String source = + "package p1;\n" + + "import p2.Y;\n" + + "public class X {\n" + + " private int unused = 0;\n" + + " public Object foo() {\n" + + " return new Y() {};\n" + + " }\n" + + "}"; + + createFile( + "/Reconciler1415/src/p1/X.java", + source + ); + + this.workingCopies = new ICompilationUnit[1]; + char[] sourceChars = source.toCharArray(); + this.problemRequestor.initialize(sourceChars); + this.workingCopies[0] = getCompilationUnit("/Reconciler1415/src/p1/X.java").getWorkingCopy(this.wcOwner, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "1. WARNING in /Reconciler1415/src/p1/X.java (at line 4)\n" + + " private int unused = 0;\n" + + " ^^^^^^\n" + + "The field X.unused is never read locally\n" + + "----------\n" + ); + } finally { + if (project14 != null) + deleteProject(project14); + if (project15 != null) + deleteProject(project15); + } +} }