### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.builder Index: src/org/eclipse/jdt/core/tests/builder/TestingEnvironment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/TestingEnvironment.java,v retrieving revision 1.37 diff -u -r1.37 TestingEnvironment.java --- src/org/eclipse/jdt/core/tests/builder/TestingEnvironment.java 11 Jul 2005 14:46:03 -0000 1.37 +++ src/org/eclipse/jdt/core/tests/builder/TestingEnvironment.java 12 Dec 2005 09:20:55 -0000 @@ -133,6 +133,15 @@ * Returns the path of the added package fragment root. */ public IPath addPackageFragmentRoot(IPath projectPath, String sourceFolderName, IPath[] exclusionPatterns, String specificOutputLocation) throws JavaModelException { + return addPackageFragmentRoot(projectPath, sourceFolderName, exclusionPatterns, true/*exclusion patterns*/, specificOutputLocation); + } + + /** Adds a package fragment root to the workspace. If + * a package fragment root with the same name already + * exists, it is not replaced. A workspace must be open. + * Returns the path of the added package fragment root. + */ + public IPath addPackageFragmentRoot(IPath projectPath, String sourceFolderName, IPath[] patterns, boolean areExclusionPatterns, String specificOutputLocation) throws JavaModelException { checkAssertion("a workspace must be open", fIsOpen); //$NON-NLS-1$ IPath path = getPackageFragmentRootPath(projectPath, sourceFolderName); createFolder(path); @@ -141,7 +150,13 @@ outputPath = getPackageFragmentRootPath(projectPath, specificOutputLocation); createFolder(outputPath); } - IClasspathEntry entry = JavaCore.newSourceEntry(path, exclusionPatterns == null ? new Path[0] : exclusionPatterns, outputPath); + IClasspathEntry entry; + if (areExclusionPatterns) + // exclusion patterns + entry = JavaCore.newSourceEntry(path, patterns == null ? new Path[0] : patterns, outputPath); + else + // inclusion patterns + entry = JavaCore.newSourceEntry(path, patterns == null ? new Path[0] : patterns, new Path[0], outputPath); addEntry(projectPath, entry); return path; } Index: src/org/eclipse/jdt/core/tests/builder/MultiSourceFolderAndOutputFolderTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/MultiSourceFolderAndOutputFolderTests.java,v retrieving revision 1.14 diff -u -r1.14 MultiSourceFolderAndOutputFolderTests.java --- src/org/eclipse/jdt/core/tests/builder/MultiSourceFolderAndOutputFolderTests.java 23 Feb 2005 02:49:38 -0000 1.14 +++ src/org/eclipse/jdt/core/tests/builder/MultiSourceFolderAndOutputFolderTests.java 12 Dec 2005 09:20:55 -0000 @@ -282,4 +282,29 @@ expectingNoPresenceOf(projectPath.append("bin2").append("bin")); //$NON-NLS-1$ //$NON-NLS-2$ expectingNoPresenceOf(projectPath.append("bin").append("bin2")); //$NON-NLS-1$ //$NON-NLS-2$ } + + /* + * Regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161 + */ + public void test0012() throws JavaModelException { + IPath projectPath = env.addProject("P"); + env.removePackageFragmentRoot(projectPath, ""); + IPath src = env.addPackageFragmentRoot(projectPath, "", new IPath[] {new Path("p1/p2/p3/X.java"), new Path("Y.java")}, false/*inclusion*/, ""); + env.addExternalJars(projectPath, Util.getJavaClassLibs()); + + env.addClass(src, "p1.p2.p3", "X", + "package p1.p2.p3;\n" + + "public class X {}" + ); + fullBuild(); + expectingNoProblems(); + + env.addClass(src, "", "Y", + "import p1.p2.p3.X;\n" + + "public class Y extends X {}" + ); + incrementalBuild(); + expectingNoProblems(); + } + } #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/InclusionPatternsTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/InclusionPatternsTests.java,v retrieving revision 1.12 diff -u -r1.12 InclusionPatternsTests.java --- src/org/eclipse/jdt/core/tests/model/InclusionPatternsTests.java 18 Nov 2005 17:51:44 -0000 1.12 +++ src/org/eclipse/jdt/core/tests/model/InclusionPatternsTests.java 12 Dec 2005 09:20:58 -0000 @@ -11,14 +11,10 @@ package org.eclipse.jdt.core.tests.model; import org.eclipse.core.resources.*; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.*; -import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; @@ -32,7 +28,7 @@ } static { -// TESTS_NAMES = new String[] { "testSearchWithIncludedPackage2" }; +// TESTS_NAMES = new String[] { "testIncludeCUOnly02" }; } public static Test suite() { return buildTestSuite(InclusionPatternsTests.class); @@ -373,6 +369,74 @@ root.getNonJavaResources()); } /* + * Ensure that a type can be resolved if it is included but not its super packages. + * (regression test for bug 119161 classes in "deep" packages not fully recognized when using tight inclusion filters) + */ +public void testIncludeCUOnly01() throws CoreException { + setClasspath(new String[] {"/P/src", "p1/p2/*.java|q/*.java"}); + addLibraryEntry(getJavaProject("P"), getExternalJCLPathString(), false); + createFolder("/P/src/p1/p2"); + createFile( + "/P/src/p1/p2/X.java", + "package p1.p2;\n" + + "public class X {\n" + + "}" + ); + ICompilationUnit workingCopy = null; + try { + ProblemRequestor problemRequestor = new ProblemRequestor(); + workingCopy = getWorkingCopy( + "/P/src/Y.java", + "import p1.p2.X;\n" + + "public class Y extends X {\n" + + "}", + null/*primary owner*/, + problemRequestor); + assertProblems( + "Unepected problems", + "----------\n" + + "----------\n", + problemRequestor); + } finally { + if (workingCopy != null) + workingCopy.discardWorkingCopy(); + } +} +/* + * Ensure that a type can be resolved if it is included but not its super packages. + * (regression test for bug 119161 classes in "deep" packages not fully recognized when using tight inclusion filters) + */ +public void testIncludeCUOnly02() throws CoreException { + setClasspath(new String[] {"/P/src", "p1/p2/p3/*.java|q/*.java"}); + addLibraryEntry(getJavaProject("P"), getExternalJCLPathString(), false); + createFolder("/P/src/p1/p2/p3"); + createFile( + "/P/src/p1/p2/p3/X.java", + "package p1.p2.p3;\n" + + "public class X {\n" + + "}" + ); + ICompilationUnit workingCopy = null; + try { + ProblemRequestor problemRequestor = new ProblemRequestor(); + workingCopy = getWorkingCopy( + "/P/src/Y.java", + "import p1.p2.p3.X;\n" + + "public class Y extends X {\n" + + "}", + null/*primary owner*/, + problemRequestor); + assertProblems( + "Unepected problems", + "----------\n" + + "----------\n", + problemRequestor); + } finally { + if (workingCopy != null) + workingCopy.discardWorkingCopy(); + } +} +/* * Ensures that a cu that is not included is not on the classpath of the project. */ public void testIsOnClasspath1() throws CoreException { Index: src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java,v retrieving revision 1.154 diff -u -r1.154 AbstractJavaModelTests.java --- src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 5 Dec 2005 15:52:04 -0000 1.154 +++ src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 12 Dec 2005 09:20:58 -0000 @@ -1496,8 +1496,14 @@ return getWorkingCopy(path, source, owner, problemRequestor); } public ICompilationUnit getWorkingCopy(String path, String source, WorkingCopyOwner owner, IProblemRequestor problemRequestor) throws JavaModelException { - ICompilationUnit workingCopy = getCompilationUnit(path).getWorkingCopy(owner, problemRequestor, null/*no progress monitor*/); + ICompilationUnit workingCopy = getCompilationUnit(path); + if (owner != null) + workingCopy = workingCopy.getWorkingCopy(owner, problemRequestor, null/*no progress monitor*/); + else + workingCopy.becomeWorkingCopy(problemRequestor, null/*no progress monitor*/); workingCopy.getBuffer().setContents(source); + if (problemRequestor instanceof ProblemRequestor) + ((ProblemRequestor) problemRequestor).initialize(source.toCharArray()); workingCopy.makeConsistent(null/*no progress monitor*/); return workingCopy; } #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java,v retrieving revision 1.32 diff -u -r1.32 ClasspathDirectory.java --- model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java 7 Dec 2005 11:27:15 -0000 1.32 +++ model/org/eclipse/jdt/internal/core/builder/ClasspathDirectory.java 12 Dec 2005 09:21:01 -0000 @@ -49,7 +49,7 @@ try { IResource container = binaryFolder.findMember(qualifiedPackageName); // this is a case-sensitive check - if (container instanceof IContainer && !isExcluded(container)) { + if (container instanceof IContainer) { IResource[] members = ((IContainer) container).members(); dirList = new String[members.length]; int index = 0; Index: model/org/eclipse/jdt/internal/core/SearchableEnvironment.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java,v retrieving revision 1.61 diff -u -r1.61 SearchableEnvironment.java --- model/org/eclipse/jdt/internal/core/SearchableEnvironment.java 28 Oct 2005 11:52:04 -0000 1.61 +++ model/org/eclipse/jdt/internal/core/SearchableEnvironment.java 12 Dec 2005 09:21:01 -0000 @@ -341,22 +341,17 @@ * @see org.eclipse.jdt.internal.compiler.env.INameEnvironment#isPackage(char[][], char[]) */ public boolean isPackage(char[][] parentPackageName, char[] subPackageName) { - if (subPackageName == null || CharOperation.contains('.', subPackageName)) - return false; - if (parentPackageName == null || parentPackageName.length == 0) - return isTopLevelPackage(subPackageName); - for (int i = 0, length = parentPackageName.length; i < length; i++) - if (parentPackageName[i] == null || CharOperation.contains('.', parentPackageName[i])) - return false; - - String packageName = new String(CharOperation.concatWith(parentPackageName, subPackageName, '.')); - return this.nameLookup.findPackageFragments(packageName, false) != null; - } - - public boolean isTopLevelPackage(char[] packageName) { - return packageName != null && - !CharOperation.contains('.', packageName) && - this.nameLookup.findPackageFragments(new String(packageName), false) != null; + String[] pkgName; + if (parentPackageName == null) + pkgName = new String[] {new String(subPackageName)}; + else { + int length = parentPackageName.length; + pkgName = new String[length+1]; + for (int i = 0; i < length; i++) + pkgName[i] = new String(parentPackageName[i]); + pkgName[length] = new String(subPackageName); + } + return this.nameLookup.isPackage(pkgName); } /** Index: model/org/eclipse/jdt/internal/core/NameLookup.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java,v retrieving revision 1.95 diff -u -r1.95 NameLookup.java --- model/org/eclipse/jdt/internal/core/NameLookup.java 5 Dec 2005 15:52:20 -0000 1.95 +++ model/org/eclipse/jdt/internal/core/NameLookup.java 12 Dec 2005 09:21:00 -0000 @@ -99,6 +99,12 @@ * replaces the array. */ protected HashtableOfArrayToObject packageFragments; + + /* + * A set of names (String[]) that are not to be package names. + * Value is not null for known package. + */ + protected HashtableOfArrayToObject isPackageCache; /** * Reverse map from root path to corresponding resolved CP entry @@ -197,6 +203,21 @@ } } } + + // cache whether each package and its including packages (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=119161) + // are actual packages + this.isPackageCache = new HashtableOfArrayToObject(); + for (int i = 0, size = this.packageFragments.keyTable.length; i < size; i++) { + String[] pkgName = (String[]) this.packageFragments.keyTable[i]; + if (pkgName == null) continue; + this.isPackageCache.put(pkgName, pkgName); + int length = pkgName.length; + for (int j = length-1; j > 0; j--) { + String[] subPkgName = new String[j]; + System.arraycopy(pkgName, 0, subPkgName, 0, j); + this.isPackageCache.put(subPkgName, subPkgName); + } + } this.rootToResolvedEntries = rootToResolvedEntries; if (VERBOSE) { Util.verbose(" -> spent: " + (start - System.currentTimeMillis()) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -465,20 +486,19 @@ } else { String[] splittedName = Util.splitOn('.', name, 0, name.length()); Object value = this.packageFragments.get(splittedName); + if (value == null) + return null; if (value instanceof PackageFragmentRoot) { return new IPackageFragment[] {((PackageFragmentRoot) value).getPackageFragment(splittedName)}; } else { IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value; - if (roots != null) { - IPackageFragment[] result = new IPackageFragment[roots.length]; - for (int i= 0; i < roots.length; i++) { - result[i] = ((PackageFragmentRoot) roots[i]).getPackageFragment(splittedName); - } - return result; + IPackageFragment[] result = new IPackageFragment[roots.length]; + for (int i= 0; i < roots.length; i++) { + result[i] = ((PackageFragmentRoot) roots[i]).getPackageFragment(splittedName); } + return result; } } - return null; } /* @@ -629,6 +649,10 @@ } return type; } + + public boolean isPackage(String[] pkgName) { + return this.isPackageCache.get(pkgName) != null; + } /** * Returns true if the given element's name matches the