### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java,v retrieving revision 1.230 diff -u -r1.230 CompilerOptions.java --- compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 25 Feb 2010 19:17:04 -0000 1.230 +++ compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java 7 Sep 2010 05:21:21 -0000 @@ -256,10 +256,20 @@ /** Classfile debug information, may contain source file name, line numbers, local variable tables, etc... */ public int produceDebugAttributes; - /** Compliance level for the compiler, refers to a JDK version, e.g. {link {@link ClassFileConstants#JDK1_4} */ + /** Compliance level for the compiler, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4} */ public long complianceLevel; - /** Java source level, refers to a JDK version, e.g. {link {@link ClassFileConstants#JDK1_4} */ + /** Original compliance level for the compiler, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4}, + * Usually same as the field complianceLevel, though the latter could deviate to create temporary sandbox + * modes during reconcile operations. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 + */ + public long originalComplianceLevel; + /** Java source level, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4} */ public long sourceLevel; + /** Original Java source level, refers to a JDK version, e.g. {@link ClassFileConstants#JDK1_4} + * Usually same as the field sourceLevel, though the latter could deviate to create temporary sandbox + * modes during reconcile operations. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 + * */ + public long originalSourceLevel; /** VM target level, refers to a JDK version, e.g. {link {@link ClassFileConstants#JDK1_4} */ public long targetJDK; /** Source encoding format */ @@ -953,8 +963,8 @@ // by default only lines and source attributes are generated. this.produceDebugAttributes = ClassFileConstants.ATTR_SOURCE | ClassFileConstants.ATTR_LINES; - this.complianceLevel = ClassFileConstants.JDK1_4; // by default be compliant with 1.4 - this.sourceLevel = ClassFileConstants.JDK1_3; //1.3 source behavior by default + this.complianceLevel = this.originalComplianceLevel = ClassFileConstants.JDK1_4; // by default be compliant with 1.4 + this.sourceLevel = this.originalSourceLevel = ClassFileConstants.JDK1_3; //1.3 source behavior by default this.targetJDK = ClassFileConstants.JDK1_2; // default generates for JVM1.2 this.defaultEncoding = null; // will use the platform default encoding @@ -1117,11 +1127,11 @@ } if ((optionValue = optionsMap.get(OPTION_Compliance)) != null) { long level = versionToJdkLevel(optionValue); - if (level != 0) this.complianceLevel = level; + if (level != 0) this.complianceLevel = this.originalComplianceLevel = level; } if ((optionValue = optionsMap.get(OPTION_Source)) != null) { long level = versionToJdkLevel(optionValue); - if (level != 0) this.sourceLevel = level; + if (level != 0) this.sourceLevel = this.originalSourceLevel = level; } if ((optionValue = optionsMap.get(OPTION_TargetPlatform)) != null) { long level = versionToJdkLevel(optionValue); 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.123 diff -u -r1.123 BinaryTypeBinding.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 21 Sep 2009 23:37:04 -0000 1.123 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java 7 Sep 2010 05:21:22 -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 @@ -149,7 +149,7 @@ this.fPackage = packageBinding; this.fileName = binaryType.getFileName(); - char[] typeSignature = environment.globalOptions.sourceLevel >= ClassFileConstants.JDK1_5 ? binaryType.getGenericSignature() : null; + char[] typeSignature = environment.globalOptions.originalSourceLevel >= ClassFileConstants.JDK1_5 ? binaryType.getGenericSignature() : null; 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; @@ -260,7 +260,7 @@ } } - long sourceLevel = this.environment.globalOptions.sourceLevel; + long sourceLevel = this.environment.globalOptions.originalSourceLevel; char[] typeSignature = null; if (sourceLevel >= ClassFileConstants.JDK1_5) { typeSignature = binaryType.getGenericSignature(); @@ -558,7 +558,7 @@ if (iMethods != null) { total = initialTotal = iMethods.length; boolean keepBridgeMethods = sourceLevel < ClassFileConstants.JDK1_5 - && this.environment.globalOptions.complianceLevel >= ClassFileConstants.JDK1_5; + && this.environment.globalOptions.originalComplianceLevel >= ClassFileConstants.JDK1_5; for (int i = total; --i >= 0;) { IBinaryMethod method = iMethods[i]; if ((method.getModifiers() & ClassFileConstants.AccSynthetic) != 0) { 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.67 diff -u -r1.67 SourceTypeConverter.java --- model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java 29 Jul 2010 09:15:19 -0000 1.67 +++ model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java 7 Sep 2010 05:21:22 -0000 @@ -293,7 +293,9 @@ // convert 1.5 specific constructs only if compliance is 1.5 or above TypeParameter[] typeParams = null; - if (this.has1_5Compliance) { + // 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) { @@ -462,7 +464,10 @@ if (this.has1_5Compliance) { /* 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) { 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.4 diff -u -r1.4 TypeConverter.java --- model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java 9 Sep 2008 14:53:17 -0000 1.4 +++ model/org/eclipse/jdt/internal/compiler/parser/TypeConverter.java 7 Sep 2010 05:21:22 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008 IBM Corporation and others. + * Copyright (c) 2008, 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 @@ -40,7 +40,7 @@ protected TypeConverter(ProblemReporter problemReporter, char memberTypeSeparator) { this.problemReporter = problemReporter; - this.has1_5Compliance = problemReporter.options.complianceLevel >= ClassFileConstants.JDK1_5; + this.has1_5Compliance = problemReporter.options.originalComplianceLevel >= ClassFileConstants.JDK1_5; this.memberTypeSeparator = memberTypeSeparator; } #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.154 diff -u -r1.154 ReconcilerTests.java --- src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java 19 Aug 2010 08:20:16 -0000 1.154 +++ src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java 7 Sep 2010 05:21:27 -0000 @@ -4632,4 +4632,179 @@ deleteProject(project15); } } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 +public void testGenericAPIUsageFromA14Project3() 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/X.java", + "package p2;\n" + + "import java.util.Collection;\n" + + "import java.util.Iterator;\n" + + "public class X implements Collection{\n" + + " public static X getX() {\n" + + " return new X();\n" + + " }\n" + + " public int size() {\n" + + " return 0;\n" + + " }\n" + + " public boolean isEmpty() {\n" + + " return false;\n" + + " }\n" + + " public boolean contains(Object o) {\n" + + " return false;\n" + + " }\n" + + " public Iterator iterator() {\n" + + " return null;\n" + + " }\n" + + " public Object[] toArray() {\n" + + " return null;\n" + + " }\n" + + " public T[] toArray(T[] a) {\n" + + " return null;\n" + + " }\n" + + " public boolean add(E e) {\n" + + " return false;\n" + + " }\n" + + " public boolean remove(Object o) {\n" + + " return false;\n" + + " }\n" + + " public boolean containsAll(Collection c) {\n" + + " return false;\n" + + " }\n" + + " public boolean addAll(Collection c) {\n" + + " return false;\n" + + " }\n" + + " public boolean removeAll(Collection c) {\n" + + " return false;\n" + + " }\n" + + " public boolean retainAll(Collection c) {\n" + + " return false;\n" + + " }\n" + + " public void clear() {\n" + + " }\n" + + "}\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[] {"JCL15_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 java.util.Collection;\n" + + "public class X {\n" + + " public static void main(String string) {\n" + + " Collection c = p2.X.getX(); \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 5)\n" + + " Collection c = p2.X.getX(); \n" + + " ^\n" + + "The local variable c is never read\n" + + "----------\n" + ); + } finally { + if (project14 != null) + deleteProject(project14); + if (project15 != null) + deleteProject(project15); + } +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=323633 (variation: 15 uses 14) +public void testGenericAPIUsageFromA14Project4() throws CoreException { + IJavaProject project14 = null; + IJavaProject project15 = null; + try { + project14 = createJavaProject("Reconciler1415", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); + createFolder("/Reconciler1415/src/p1"); + String source = + "package p1;\n" + + "import java.lang.Comparable;\n" + + "public class X implements Comparable {\n" + + " public static X getX() {\n" + + " return new X();\n" + + " }\n" + + "}"; + + createFile( + "/Reconciler1415/src/p1/X.java", + source + ); + + 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); + + project15 = createJavaProject("Reconciler15API", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin"); + createFolder("/Reconciler15API/src/p2"); + String otherSource = "package p2;\n" + + "public class X { \n" + + " private p1.X x = p1.X.getX();\n" + + " Comparable y = null;\n" + + "}\n"; + + createFile( + "/Reconciler15API/src/p2/X.java", + otherSource + ); + 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); + + IClasspathEntry[] oldClasspath = project15.getRawClasspath(); + int oldLength = oldClasspath.length; + IClasspathEntry[] newClasspath = new IClasspathEntry[oldLength+1]; + System.arraycopy(oldClasspath, 0, newClasspath, 0, oldLength); + newClasspath[oldLength] = JavaCore.newProjectEntry(new Path("/Reconciler1415")); + project15.setRawClasspath(newClasspath, null); + + this.workingCopies = new ICompilationUnit[1]; + char[] sourceChars = otherSource.toCharArray(); + this.problemRequestor.initialize(sourceChars); + this.workingCopies[0] = getCompilationUnit("/Reconciler15API/src/p2/X.java").getWorkingCopy(this.wcOwner, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "1. WARNING in /Reconciler15API/src/p2/X.java (at line 3)\n" + + " private p1.X x = p1.X.getX();\n" + + " ^\n" + + "The field X.x is never read locally\n" + + "----------\n" + ); + } finally { + if (project14 != null) + deleteProject(project14); + if (project15 != null) + deleteProject(project15); + } +} }