diff options
author | Szymon Ptaszkiewicz | 2014-01-20 23:05:14 +0000 |
---|---|---|
committer | Jayaprakash Arthanareeswaran | 2014-03-20 13:50:20 +0000 |
commit | af0e906d1e23ee06421f529bad569f551824b30a (patch) | |
tree | 331ff452927665d49a1fbef1ae1001deba42ac45 | |
parent | fdf1e11c6109326de5ebf367239556032171f749 (diff) | |
download | eclipse.jdt.core-af0e906d1e23ee06421f529bad569f551824b30a.tar.gz eclipse.jdt.core-af0e906d1e23ee06421f529bad569f551824b30a.tar.xz eclipse.jdt.core-af0e906d1e23ee06421f529bad569f551824b30a.zip |
Bug 410207 - Compiler incorrectly reports error message "X cannot be
resolved. It is indirectly referenced from required .class files"
Signed-off-by: Szymon Ptaszkiewicz <szymon.ptaszkiewicz@pl.ibm.com>
8 files changed, 536 insertions, 41 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java index 2f8c3af55b..13a459e61f 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -25,6 +25,7 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -5981,4 +5982,226 @@ public void testBug373409() throws Exception { deleteProject("P"); } } +/** + * Project's compliance: source: 1.5, compiler: 1.5 + * Jar's compliance: source: 1.3, compiler: 1.3 + * Jar contains a class with "enum" package and is located inside the project. + * The test verifies that class from the "enum" package is not proposed. + */ +public void testBug410207a() throws Exception { + try { + IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5"); + Util.createJar(new String[] { + "a/enum/b/NonCompliant.java", + "package a.enum.b;\n" + + "public class NonCompliant {\n" + + "}", + "lib/External.java", + "package lib;\n" + + "import a.enum.b.NonCompliant;\n" + + "public class External {\n" + + " public NonCompliant setNonCompliant(NonCompliant x) {\n" + + " return null;\n" + + " }\n" + + "}" + }, + p.getProject().getLocation().append("lib.jar").toOSString(), + "1.3"); + refresh(p); + createFolder("/P/src/p/"); + createFile( + "/P/src/p/Main.java", + "package p;\n" + + "import lib.External;\n" + + "public class Main {\n" + + " public void m() {\n" + + " External external = new External();\n" + + " external.setNonCompliant(new );\n" + + " };\n" + + "}" + ); + waitUntilIndexesReady(); + ICompilationUnit cu = getCompilationUnit("P", "src", "p", "Main.java"); + String source = cu.getSource(); + String completeBehind = "external.setNonCompliant(new "; + int cursorLocation = source.lastIndexOf(completeBehind) + completeBehind.length(); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true); + cu.codeComplete(cursorLocation, requestor); + assertResults( + "Main[TYPE_REF]{Main, p, Lp.Main;, null, null, 27}", + requestor.getResults()); + } finally { + deleteProject("P"); + } +} +/** + * Project's compliance: source: 1.5, compiler: 1.5 + * Jar's compliance: source: 1.4, compiler: 1.6 + * Jar contains a class with "enum" package and is located inside the project. + * The test verifies that class from the "enum" package is not proposed. It verifies also that + * compiler compliance of the jar is not used as source compliance. + */ +public void testBug410207b() throws Exception { + try { + IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5"); + Map options = new HashMap(); + options.put(CompilerOptions.OPTION_Source, "1.4"); + Util.createJar(new String[] { + "a/enum/b/NonCompliant.java", + "package a.enum.b;\n" + + "public class NonCompliant {\n" + + "}", + "lib/External.java", + "package lib;\n" + + "import a.enum.b.NonCompliant;\n" + + "public class External {\n" + + " public NonCompliant setNonCompliant(NonCompliant x) {\n" + + " return null;\n" + + " }\n" + + "}" + }, + null,/*extraPathsAndContents*/ + p.getProject().getLocation().append("lib.jar").toOSString(), + null,/*classpath*/ + "1.6", + options); + refresh(p); + createFolder("/P/src/p/"); + createFile( + "/P/src/p/Main.java", + "package p;\n" + + "import lib.External;\n" + + "public class Main {\n" + + " public void m() {\n" + + " External external = new External();\n" + + " external.setNonCompliant(new );\n" + + " };\n" + + "}" + ); + waitUntilIndexesReady(); + ICompilationUnit cu = getCompilationUnit("P", "src", "p", "Main.java"); + String source = cu.getSource(); + String completeBehind = "external.setNonCompliant(new "; + int cursorLocation = source.lastIndexOf(completeBehind) + completeBehind.length(); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true); + cu.codeComplete(cursorLocation, requestor); + assertResults( + "Main[TYPE_REF]{Main, p, Lp.Main;, null, null, 27}", + requestor.getResults()); + } finally { + deleteProject("P"); + } +} +/** + * Two projects: + * Lib: source: 1.4, compiler: 1.4 + * P: source: 1.5, compiler: 1.5 + * Lib contains a class with "enum" package and is required by P (dependency on the bin folder). + * The test verifies that class from the "enum" package is not proposed for P. + */ +public void testBug410207c() throws Exception { + try { + createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4"); + createFolder("/Lib/src/a/enum/b"); + createFile( + "/Lib/src/a/enum/b/NonCompliant.java", + "package a.enum.b;\n" + + "public class NonCompliant {\n" + + "}" + ); + createFolder("/Lib/src/lib"); + createFile( + "/Lib/src/lib/External.java", + "package lib;\n" + + "import a.enum.b.NonCompliant;\n" + + "public class External {\n" + + " public NonCompliant setNonCompliant(NonCompliant x) {\n" + + " return null;\n" + + " }\n" + + "}" + ); + getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null); + createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/Lib/bin"}, "bin", "1.5"); + createFolder("/P/src/p"); + createFile( + "/P/src/p/Main.java", + "package p;\n" + + "import lib.External;\n" + + "public class Main {\n" + + " public void m() {\n" + + " External external = new External();\n" + + " external.setNonCompliant(new );\n" + + " };\n" + + "}" + ); + waitUntilIndexesReady(); + ICompilationUnit cu = getCompilationUnit("P", "src", "p", "Main.java"); + String source = cu.getSource(); + String completeBehind = "external.setNonCompliant(new "; + int cursorLocation = source.lastIndexOf(completeBehind) + completeBehind.length(); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true); + cu.codeComplete(cursorLocation, requestor); + assertResults( + "Main[TYPE_REF]{Main, p, Lp.Main;, null, null, 27}", + requestor.getResults()); + } finally { + deleteProjects(new String[] { "Lib", "P" }); + } +} +/** + * Two projects: + * Lib: source: 1.4, compiler: 1.4 + * P: source: 1.5, compiler: 1.5 + * Lib contains a class with "enum" package and is required by P (dependency on the whole project). + * The test verifies that class from the "enum" package is not proposed for P. + */ +public void testBug410207d() throws Exception { + try { + createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4"); + createFolder("/Lib/src/a/enum/b"); + createFile( + "/Lib/src/a/enum/b/NonCompliant.java", + "package a.enum.b;\n" + + "public class NonCompliant {\n" + + "}" + ); + createFolder("/Lib/src/lib"); + createFile( + "/Lib/src/lib/External.java", + "package lib;\n" + + "import a.enum.b.NonCompliant;\n" + + "public class External {\n" + + " public NonCompliant setNonCompliant(NonCompliant x) {\n" + + " return null;\n" + + " }\n" + + "}" + ); + getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null); + createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, new String[] {"/Lib"}, "bin", "1.5"); + createFolder("/P/src/p"); + createFile( + "/P/src/p/Main.java", + "package p;\n" + + "import lib.External;\n" + + "public class Main {\n" + + " public void m() {\n" + + " External external = new External();\n" + + " external.setNonCompliant(new );\n" + + " };\n" + + "}" + ); + waitUntilIndexesReady(); + ICompilationUnit cu = getCompilationUnit("P", "src", "p", "Main.java"); + String source = cu.getSource(); + String completeBehind = "external.setNonCompliant(new "; + int cursorLocation = source.lastIndexOf(completeBehind) + completeBehind.length(); + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, false, false, true, true); + cu.codeComplete(cursorLocation, requestor); + assertResults( + "Main[TYPE_REF]{Main, p, Lp.Main;, null, null, 27}", + requestor.getResults()); + } finally { + deleteProjects(new String[] { "Lib", "P" }); + } +} } diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java index 52a693fed2..848d910808 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -13,7 +13,9 @@ package org.eclipse.jdt.core.tests.model; import java.io.File; import java.io.IOException; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; import junit.framework.Test; @@ -34,6 +36,7 @@ import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.compiler.ReconcileContext; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.tests.util.Util; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.core.CompilationUnit; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.search.indexing.IndexManager; @@ -5398,4 +5401,209 @@ public void testBug374176b() throws CoreException, IOException, InterruptedExcep deleteProject(project15); } } +/** + * Project's compliance: source: 1.5, compiler: 1.5 + * Jar's compliance: source: 1.3, compiler: 1.3 + * Jar contains a class with "enum" package and is located inside the project. + * The test verifies that class from the "enum" package is correctly reconciled. + */ +public void testBug410207a() throws Exception { + try { + IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5"); + Util.createJar(new String[] { + "a/enum/b/NonCompliant.java", + "package a.enum.b;\n" + + "public class NonCompliant {\n" + + "}", + "lib/External.java", + "package lib;\n" + + "import a.enum.b.NonCompliant;\n" + + "public class External {\n" + + " public NonCompliant setNonCompliant(NonCompliant x) {\n" + + " return null;\n" + + " }\n" + + "}" + }, + p.getProject().getLocation().append("lib.jar").toOSString(), + "1.3"); + refresh(p); + setUpWorkingCopy( + "/P/src/p/Main.java", + "package p;\n" + + "import lib.External;\n" + + "public class Main {\n" + + " public void m() {\n" + + " External external = new External();\n" + + " external.setNonCompliant(null);\n" + + " };\n" + + "}" + ); + this.problemRequestor.reset(); + this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "----------\n" + ); + } finally { + deleteProject("P"); + } +} +/** + * Project's compliance: source: 1.5, compiler: 1.5 + * Jar's compliance: source: 1.4, compiler: 1.6 + * Jar contains a class with "enum" package and is located inside the project. + * The test verifies that class from the "enum" package is correctly reconciled. + */ +public void testBug410207b() throws Exception { + try { + IJavaProject p = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/P/lib.jar"}, "bin", "1.5"); + Map options = new HashMap(); + options.put(CompilerOptions.OPTION_Source, "1.4"); + Util.createJar(new String[] { + "a/enum/b/NonCompliant.java", + "package a.enum.b;\n" + + "public class NonCompliant {\n" + + "}", + "lib/External.java", + "package lib;\n" + + "import a.enum.b.NonCompliant;\n" + + "public class External {\n" + + " public NonCompliant setNonCompliant(NonCompliant x) {\n" + + " return null;\n" + + " }\n" + + "}" + }, + null,/*extraPathsAndContents*/ + p.getProject().getLocation().append("lib.jar").toOSString(), + null,/*classpath*/ + "1.6", + options); + refresh(p); + setUpWorkingCopy( + "/P/src/p/Main.java", + "package p;\n" + + "import lib.External;\n" + + "public class Main {\n" + + " public void m() {\n" + + " External external = new External();\n" + + " external.setNonCompliant(null);\n" + + " };\n" + + "}" + ); + this.problemRequestor.reset(); + this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "----------\n" + ); + } finally { + deleteProject("P"); + } +} +/** + * Two projects: + * Lib: source: 1.4, compiler: 1.4 + * P: source: 1.5, compiler: 1.5 + * Lib contains a class with "enum" package and is required by P (dependency on the bin folder). + * The test verifies that class from the "enum" package is correctly reconciled for P. + */ +public void testBug410207c() throws Exception { + try { + createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4"); + createFolder("/Lib/src/a/enum/b"); + createFile( + "/Lib/src/a/enum/b/NonCompliant.java", + "package a.enum.b;\n" + + "public class NonCompliant {\n" + + "}" + ); + createFolder("/Lib/src/lib"); + createFile( + "/Lib/src/lib/External.java", + "package lib;\n" + + "import a.enum.b.NonCompliant;\n" + + "public class External {\n" + + " public NonCompliant setNonCompliant(NonCompliant x) {\n" + + " return null;\n" + + " }\n" + + "}" + ); + getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null); + createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB", "/Lib/bin"}, "bin", "1.5"); + setUpWorkingCopy( + "/P/src/p/Main.java", + "package p;\n" + + "import lib.External;\n" + + "public class Main {\n" + + " public void m() {\n" + + " External external = new External();\n" + + " external.setNonCompliant(null);\n" + + " };\n" + + "}" + ); + this.problemRequestor.reset(); + this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "----------\n" + ); + } finally { + deleteProjects(new String[] { "Lib", "P" }); + } +} +/** + * Two projects: + * Lib: source: 1.4, compiler: 1.4 + * P: source: 1.5, compiler: 1.5 + * Lib contains a class with "enum" package and is required by P (dependency on the whole project). + * The test verifies that class from the "enum" package is correctly reconciled for P. + */ +public void testBug410207d() throws Exception { + try { + createJavaProject("Lib", new String[] {"src"}, new String[] {"JCL_LIB"}, "bin", "1.4"); + createFolder("/Lib/src/a/enum/b"); + createFile( + "/Lib/src/a/enum/b/NonCompliant.java", + "package a.enum.b;\n" + + "public class NonCompliant {\n" + + "}" + ); + createFolder("/Lib/src/lib"); + createFile( + "/Lib/src/lib/External.java", + "package lib;\n" + + "import a.enum.b.NonCompliant;\n" + + "public class External {\n" + + " public NonCompliant setNonCompliant(NonCompliant x) {\n" + + " return null;\n" + + " }\n" + + "}" + ); + getProject("Lib").build(IncrementalProjectBuilder.FULL_BUILD, null); + createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, new String[] {"/Lib"}, "bin", "1.5"); + setUpWorkingCopy( + "/P/src/p/Main.java", + "package p;\n" + + "import lib.External;\n" + + "public class Main {\n" + + " public void m() {\n" + + " External external = new External();\n" + + " external.setNonCompliant(null);\n" + + " };\n" + + "}" + ); + this.problemRequestor.reset(); + this.workingCopy.reconcile(ICompilationUnit.NO_AST, true/*force problem detection*/, null, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "----------\n" + ); + } finally { + deleteProjects(new String[] { "Lib", "P" }); + } +} } diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java index ded8ad2d84..7aa95933c7 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -26,6 +26,7 @@ import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeRoot; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.WorkingCopyOwner; @@ -54,6 +55,7 @@ import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; +import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray; import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.ObjectVector; @@ -69,6 +71,7 @@ import org.eclipse.jdt.internal.core.SearchableEnvironment; import org.eclipse.jdt.internal.core.SourceTypeElementInfo; import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment; import org.eclipse.jdt.internal.core.util.Messages; +import org.eclipse.jdt.internal.core.util.Util; /** * This class is the entry point for source completions. @@ -498,8 +501,6 @@ public final class CompletionEngine private final static int SUPERTYPE = 1; private final static int SUBTYPE = 2; - private final static char[] DOT_ENUM = ".enum".toCharArray(); //$NON-NLS-1$ - int expectedTypesPtr = -1; TypeBinding[] expectedTypes = new TypeBinding[1]; int expectedTypesFilter; @@ -551,6 +552,10 @@ public final class CompletionEngine int startPosition, actualCompletionPosition, endPosition, offset; int tokenStart, tokenEnd; int javadocTagPosition; // Position of previous tag while completing in javadoc + String sourceLevel; + String complianceLevel; + SimpleSetOfCharArray validPackageNames = new SimpleSetOfCharArray(10); + SimpleSetOfCharArray invalidPackageNames = new SimpleSetOfCharArray(1); HashtableOfObject knownPkgs = new HashtableOfObject(10); HashtableOfObject knownTypes = new HashtableOfObject(10); @@ -657,6 +662,8 @@ public final class CompletionEngine this.nameEnvironment = nameEnvironment; this.typeCache = new HashtableOfObject(5); this.openedBinaryTypes = 0; + this.sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); + this.complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); this.problemFactory = new CompletionProblemFactory(Locale.getDefault()); this.problemReporter = new ProblemReporter( @@ -1107,6 +1114,8 @@ public final class CompletionEngine if (this.knownPkgs.containsKey(packageName)) return; + if (!isValidPackageName(packageName)) return; + this.knownPkgs.put(packageName, this); char[] completion; @@ -1194,7 +1203,7 @@ public final class CompletionEngine } } - if (isForbiddenType(packageName, simpleTypeName, enclosingTypeNames)) { + if (isForbidden(packageName, simpleTypeName, enclosingTypeNames)) { return; } @@ -11991,16 +12000,19 @@ public final class CompletionEngine private boolean isAllowingLongComputationProposals() { return this.monitor != null; } - private boolean isForbidden(Binding binding) { + private boolean isForbidden(ReferenceBinding binding) { for (int i = 0; i <= this.forbbidenBindingsPtr; i++) { if(this.forbbidenBindings[i] == binding) { return true; } } + if (!isValidPackageName(binding.qualifiedPackageName())) { + return true; + } return false; } - private boolean isForbiddenType(char[] givenPkgName, char[] givenTypeName, char[][] enclosingTypeNames) { + private boolean isForbidden(char[] givenPkgName, char[] givenTypeName, char[][] enclosingTypeNames) { // CharOperation.concatWith() handles the cases where input args are null/empty char[] fullTypeName = CharOperation.concatWith(enclosingTypeNames, givenTypeName, '.'); for (int i = 0; i <= this.forbbidenBindingsPtr; i++) { @@ -12016,11 +12028,8 @@ public final class CompletionEngine } } - // filter packages ending with enum for projects above 1.5 - // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=317264 - if (this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_5 && - CharOperation.endsWith(givenPkgName, DOT_ENUM)) { //note: it should be .enum and not just enum - return true; + if (!isValidPackageName(givenPkgName)) { + return true; } return false; @@ -12038,6 +12047,28 @@ public final class CompletionEngine return this.requestor.isIgnored(kind) || !this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind); } + + private boolean isValidPackageName(char[] packageName) { + if (this.validPackageNames.includes(packageName)) { + return true; + } + + if (this.invalidPackageNames.includes(packageName)) { + return false; + } + + char[][] names = CharOperation.splitOn('.', packageName); + for (int i = 0, length = names.length; i < length; i++) { + if (!Util.isValidFolderNameForPackage(new String(names[i]), this.sourceLevel, this.complianceLevel)) { + this.invalidPackageNames.add(packageName); + return false; + } + } + + this.validPackageNames.add(packageName); + return true; + } + private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){ if(parent instanceof ParameterizedSingleTypeReference) { @@ -12705,6 +12736,8 @@ public final class CompletionEngine protected void reset() { super.reset(false); + this.validPackageNames = new SimpleSetOfCharArray(10); + this.invalidPackageNames = new SimpleSetOfCharArray(1); this.knownPkgs = new HashtableOfObject(10); this.knownTypes = new HashtableOfObject(10); if (this.noCacheNameEnvironment != null) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java index ca43b547cb..8fd2f5568a 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragment.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -196,6 +196,9 @@ public Object[] getNonJavaResources() throws JavaModelException { return storedNonJavaResources(); } } +protected boolean internalIsValidPackageName() { + return true; +} /** * Jars and jar entries are all read only */ diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java index 0ca7ac6b3c..a013ce642f 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject; import org.eclipse.jdt.internal.core.util.Util; @@ -40,6 +41,11 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot { private final static ArrayList EMPTY_LIST = new ArrayList(); /** + * Compiler compliance level that was used to produce the jar. + */ + protected final String complianceLevel; + + /** * The path to the jar file * (a workspace relative path if the jar is internal, * or an OS path if the jar is external) @@ -54,6 +60,9 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot { protected JarPackageFragmentRoot(IPath externalJarPath, JavaProject project) { super(null, project); this.jarPath = externalJarPath; + Object file = JavaModel.getTarget(getPath(), true); + long level = Util.getJdkLevel(file); + this.complianceLevel = CompilerOptions.versionFromJdkLevel(level); } /** * Constructs a package fragment root which is the root of the Java package directory hierarchy @@ -62,6 +71,9 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot { protected JarPackageFragmentRoot(IResource resource, JavaProject project) { super(resource, project); this.jarPath = resource.getFullPath(); + Object file = JavaModel.getTarget(getPath(), true); + long level = Util.getJdkLevel(file); + this.complianceLevel = CompilerOptions.versionFromJdkLevel(level); } /** @@ -74,9 +86,6 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot { IJavaElement[] children; ZipFile jar = null; try { - IJavaProject project = getJavaProject(); - String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true); - String compliance = project.getOption(JavaCore.COMPILER_COMPLIANCE, true); jar = getJar(); // always create the default package @@ -84,7 +93,7 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot { for (Enumeration e= jar.entries(); e.hasMoreElements();) { ZipEntry member= (ZipEntry) e.nextElement(); - initRawPackageInfo(rawPackageInfo, member.getName(), member.isDirectory(), sourceLevel, compliance); + initRawPackageInfo(rawPackageInfo, member.getName(), member.isDirectory()); } // loop through all of referenced packages, creating package fragments if necessary @@ -211,7 +220,7 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot { public int hashCode() { return this.jarPath.hashCode(); } - private void initRawPackageInfo(HashtableOfArrayToObject rawPackageInfo, String entryName, boolean isDirectory, String sourceLevel, String compliance) { + private void initRawPackageInfo(HashtableOfArrayToObject rawPackageInfo, String entryName, boolean isDirectory) { int lastSeparator = isDirectory ? entryName.length()-1 : entryName.lastIndexOf('/'); String[] pkgName = Util.splitOn('/', entryName, 0, lastSeparator); String[] existing = null; @@ -224,7 +233,9 @@ public class JarPackageFragmentRoot extends PackageFragmentRoot { } JavaModelManager manager = JavaModelManager.getJavaModelManager(); for (int i = existingLength; i < length; i++) { - if (Util.isValidFolderNameForPackage(pkgName[i], sourceLevel, compliance)) { + // sourceLevel must be null because we know nothing about it based on a jar file + // complianceLevel can be retrieved from a jar file + if (Util.isValidFolderNameForPackage(pkgName[i], null, this.complianceLevel)) { System.arraycopy(existing, 0, existing = new String[i+1], 0, i); existing[i] = manager.intern(pkgName[i]); rawPackageInfo.put(existing, new ArrayList[] { EMPTY_LIST, EMPTY_LIST }); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java index 35fb34be92..02b6f7a5d1 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragment.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -57,9 +57,12 @@ public class PackageFragment extends Openable implements IPackageFragment, Suffi public String[] names; + private boolean isValidPackageName; + protected PackageFragment(PackageFragmentRoot root, String[] names) { super(root); this.names = names; + this.isValidPackageName = internalIsValidPackageName(); } /** * @see Openable @@ -384,14 +387,11 @@ public boolean hasSubpackages() throws JavaModelException { } return false; } -/** - * @see IPackageFragment#isDefaultPackage() - */ -public boolean isDefaultPackage() { - return this.names.length == 0; -} -private boolean isValidPackageName() { - JavaProject javaProject = (JavaProject) getJavaProject(); +protected boolean internalIsValidPackageName() { + // if package fragment refers to folder in another IProject, then + // resource().getProject() is different than getJavaProject().getProject() + // use the other java project's options to verify the name + IJavaProject javaProject = JavaCore.create(resource().getProject()); String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); for (int i = 0, length = this.names.length; i < length; i++) { @@ -401,6 +401,15 @@ private boolean isValidPackageName() { return true; } /** + * @see IPackageFragment#isDefaultPackage() + */ +public boolean isDefaultPackage() { + return this.names.length == 0; +} +protected final boolean isValidPackageName() { + return this.isValidPackageName; +} +/** * @see ISourceManipulation#move(IJavaElement, IJavaElement, String, boolean, IProgressMonitor) */ public void move(IJavaElement container, IJavaElement sibling, String rename, boolean force, IProgressMonitor monitor) throws JavaModelException { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java index a2be2233de..c544b35032 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -220,14 +220,18 @@ protected void computeFolderChildren(IContainer folder, boolean isIncluded, Stri vChildren.add(pkg); } try { - JavaProject javaProject = (JavaProject)getJavaProject(); - JavaModelManager manager = JavaModelManager.getJavaModelManager(); IResource[] members = folder.members(); boolean hasIncluded = isIncluded; int length = members.length; - if (length >0) { - String sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); - String complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); + if (length > 0) { + // if package fragment root refers to folder in another IProject, then + // folder.getProject() is different than getJavaProject().getProject() + // use the other java project's options to verify the name + IJavaProject otherJavaProject = JavaCore.create(folder.getProject()); + String sourceLevel = otherJavaProject.getOption(JavaCore.COMPILER_SOURCE, true); + String complianceLevel = otherJavaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); + JavaProject javaProject = (JavaProject) getJavaProject(); + JavaModelManager manager = JavaModelManager.getJavaModelManager(); for (int i = 0; i < length; i++) { IResource member = members[i]; String memberName = member.getName(); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java index 431b9c70cc..c523f1b682 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/PackageFragmentRootInfo.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2014 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 @@ -60,14 +60,18 @@ public PackageFragmentRootInfo() { static Object[] computeFolderNonJavaResources(IPackageFragmentRoot root, IContainer folder, char[][] inclusionPatterns, char[][] exclusionPatterns) throws JavaModelException { IResource[] nonJavaResources = new IResource[5]; int nonJavaResourcesCounter = 0; - JavaProject project = (JavaProject) root.getJavaProject(); try { - IClasspathEntry[] classpath = project.getResolvedClasspath(); IResource[] members = folder.members(); int length = members.length; if (length > 0) { - String sourceLevel = project.getOption(JavaCore.COMPILER_SOURCE, true); - String complianceLevel = project.getOption(JavaCore.COMPILER_COMPLIANCE, true); + // if package fragment root refers to folder in another IProject, then + // folder.getProject() is different than root.getJavaProject().getProject() + // use the other java project's options to verify the name + IJavaProject otherJavaProject = JavaCore.create(folder.getProject()); + String sourceLevel = otherJavaProject.getOption(JavaCore.COMPILER_SOURCE, true); + String complianceLevel = otherJavaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); + JavaProject javaProject = (JavaProject) root.getJavaProject(); + IClasspathEntry[] classpath = javaProject.getResolvedClasspath(); nextResource: for (int i = 0; i < length; i++) { IResource member = members[i]; switch (member.getType()) { |