### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core 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.117 diff -u -r1.117 NameLookup.java --- model/org/eclipse/jdt/internal/core/NameLookup.java 14 Aug 2007 08:27:09 -0000 1.117 +++ model/org/eclipse/jdt/internal/core/NameLookup.java 14 Aug 2007 10:00:57 -0000 @@ -32,6 +32,7 @@ import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; import org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; +import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt; import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject; import org.eclipse.jdt.internal.core.util.Messages; @@ -164,14 +165,16 @@ // ignore (implementation of HashtableOfArrayToObject supports cloning) } this.typesInWorkingCopies = new HashMap(); - HashSet rootsSet = new HashSet(); + HashtableOfObjectToInt rootPositions = new HashtableOfObjectToInt(); for (int i = 0, length = packageFragmentRoots.length; i < length; i++) { - rootsSet.add(packageFragmentRoots[i]); + rootPositions.put(packageFragmentRoots[i], i); } for (int i = 0, length = workingCopies.length; i < length; i++) { ICompilationUnit workingCopy = workingCopies[i]; PackageFragment pkg = (PackageFragment) workingCopy.getParent(); - if (!rootsSet.contains(pkg.getParent())) + IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent(); + int rootPosition = rootPositions.get(root); + if (rootPosition == -1) continue; // working copy is not visible from this project (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=169970) HashMap typeMap = (HashMap) this.typesInWorkingCopies.get(pkg); if (typeMap == null) { @@ -207,7 +210,6 @@ } // add root of package fragment to cache - IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent(); String[] pkgName = pkg.names; Object existing = this.packageFragments.get(pkgName); if (existing == null || existing == JavaProjectElementInfo.NO_ROOTS) { @@ -217,22 +219,39 @@ JavaProjectElementInfo.addSuperPackageNames(pkgName, this.packageFragments); } else { if (existing instanceof PackageFragmentRoot) { - if (!existing.equals(root)) - this.packageFragments.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root}); + int exisitingPosition = rootPositions.get(existing); + if (rootPosition != exisitingPosition) { // if not equal + this.packageFragments.put( + pkgName, + exisitingPosition < rootPosition ? + new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root} : + new IPackageFragmentRoot[] {root, (PackageFragmentRoot) existing}); + } } else { + // insert root in the existing list IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing; int rootLength = roots.length; - boolean containsRoot = false; + int insertionIndex = 0; for (int j = 0; j < rootLength; j++) { - if (roots[j].equals(root)) { - containsRoot = true; + int existingPosition = rootPositions.get(roots[j]); + if (rootPosition > existingPosition) { + // root is after this index + insertionIndex = j; + } else if (rootPosition == existingPosition) { + // root already in the existing list + insertionIndex = -1; + break; + } else if (rootPosition < existingPosition) { + // root is before this index (thus it is at the insertion index) break; } } - if (containsRoot) { - System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength); - roots[rootLength] = root; - this.packageFragments.put(pkgName, roots); + if (insertionIndex != -1) { + IPackageFragmentRoot[] newRoots = new IPackageFragmentRoot[rootLength+1]; + System.arraycopy(roots, 0, newRoots, 0, insertionIndex); + newRoots[insertionIndex] = root; + System.arraycopy(roots, insertionIndex, newRoots, insertionIndex+1, rootLength-insertionIndex); + this.packageFragments.put(pkgName, newRoots); } } } #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/model/ResolveTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests.java,v retrieving revision 1.78 diff -u -r1.78 ResolveTests.java --- src/org/eclipse/jdt/core/tests/model/ResolveTests.java 8 Aug 2007 15:28:12 -0000 1.78 +++ src/org/eclipse/jdt/core/tests/model/ResolveTests.java 14 Aug 2007 10:00:59 -0000 @@ -1933,15 +1933,10 @@ int length = "Type".length(); IJavaElement[] elements = this.workingCopies[0].codeSelect(start, length, this.wcOwner); - - // The result should be "Type [in Type.class [in test.p [in src [in Resolve]]]]" but it is - // currently "Type [in Type.class [in test.p [in bug119434.jar [in Resolve]]]]". - // This is caused by the bug 194432 - // This test must be updated once bug 194432 will be fixed assertElementsEqual( - "Unexpected elements", - "Type [in Type.class [in test.p [in bug119434.jar [in Resolve]]]]", - elements + "Unexpected elements", + "Type [in [Working copy] Type.java [in test.p [in src [in Resolve]]]]", + elements ); } finally { removeClasspathEntry(this.currentProject, new Path(jarName)); @@ -2222,4 +2217,30 @@ elements ); } + +/* + * Ensures that the first type is found when defined in 2 different roots by working copies. + * (regression test for 194399 IJavaProject.findType(String, String, WorkingCopyOwner) doesn't return the same element with different VMs.) + */ +public void testWorkingCopyOrder1() throws JavaModelException { + this.workingCopies = new ICompilationUnit[2]; + this.workingCopies[0] = getWorkingCopy( + "/Resolve/src/test/p/Type.java", + "package test.p;\n" + + "public class Type {\n" + + "}\n" + ); + this.workingCopies[1] = getWorkingCopy( + "/Resolve/src2/test/p/Type.java", + "package test.p;\n" + + "public class Type {\n" + + "}\n" + ); + IJavaProject javaProject = getJavaProject("Resolve"); + IType foundType = javaProject.findType("test.p", "Type", this.wcOwner); + assertElementEquals( + "Unexpected type", + "Type [in [Working copy] Type.java [in test.p [in src [in Resolve]]]]", + foundType); +} }