diff options
author | Stephan Herrmann | 2017-09-19 16:34:10 +0000 |
---|---|---|
committer | Stephan Herrmann | 2017-09-19 20:33:31 +0000 |
commit | 59ce6fa5675e86bef14c55671e48e2adc2ceaf5f (patch) | |
tree | 8fae8ce5bb0545ce59303558a2055668cf32de18 | |
parent | 5bdd0835d3458337d75635aa505492c8b3e25a87 (diff) | |
download | eclipse.jdt.core-59ce6fa5675e86bef14c55671e48e2adc2ceaf5f.tar.gz eclipse.jdt.core-59ce6fa5675e86bef14c55671e48e2adc2ceaf5f.tar.xz eclipse.jdt.core-59ce6fa5675e86bef14c55671e48e2adc2ceaf5f.zip |
Bug 522503: [9] SearchableEnvironment mis-interprets classfolders from aY20170920-1000P20170920-0255
different project
Change-Id: Ibfc10a3d0bcc9abab68d338f1009a58fd8dd6b40
2 files changed, 86 insertions, 0 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java index fa0519c82c..c43096f308 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ModuleBuilderTests.java @@ -5718,6 +5718,46 @@ public class ModuleBuilderTests extends ModifyingResourceTests { deleteProject("nonmodular2"); } } + + public void testBug522503() throws Exception { + IJavaProject p1 = setupModuleProject("mod.one", + new String[] { + "src/module-info.java", + "module mod.one {\n" + + " exports p1;\n" + + "}\n", + "src/p1/API.java", + "package p1;\n" + + "public class API {}\n" + }); + IClasspathAttribute[] attr = { JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true") }; + IClasspathEntry[] deps = { JavaCore.newLibraryEntry(p1.getOutputLocation(), null, null, null, attr, false) }; + String[] sources2 = new String[] { + "src/module-info.java", + "module mod.two {\n" + + " requires mod.one;\n" + + "}\n", + "src/client/Client.java", + "package client;\n" + + "import p1.API;\n" + + "public class Client {\n" + + " API api;\n" + + "}\n" + }; + IJavaProject p2 = setupModuleProject("mod.two", sources2, deps); + p2.getProject().getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); + assertNoErrors(); + + this.problemRequestor.reset(); + ICompilationUnit cu = getCompilationUnit("/mod.two/src/client/Client.java"); + cu.getWorkingCopy(this.wcOwner, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "----------\n", + this.problemRequestor); + } + protected void assertNoErrors() throws CoreException { for (IProject p : getWorkspace().getRoot().getProjects()) { int maxSeverity = p.findMaxProblemSeverity(null, true, IResource.DEPTH_INFINITE); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java index 411f6373d7..5ad549b241 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java @@ -15,11 +15,14 @@ *******************************************************************************/ package org.eclipse.jdt.internal.core; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.function.Function; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -911,6 +914,7 @@ public class SearchableEnvironment if (moduleContext == null) { Answer moduleAnswer = this.nameLookup.findModule(moduleName); if (moduleAnswer != null) { + IProject currentProject = moduleAnswer.module.getJavaProject().getProject(); IJavaElement current = moduleAnswer.module.getParent(); while (moduleContext == null && current != null) { switch (current.getElementType()) { @@ -931,6 +935,22 @@ public class SearchableEnvironment break; default: current = current.getParent(); + if (current != null) { + try { + // detect when an element refers to a resource owned by another project: + IResource resource = current.getUnderlyingResource(); + if (resource != null) { + IProject otherProject = resource.getProject(); + if (otherProject != null && !otherProject.equals(currentProject)) { + IJavaProject otherJavaProject = JavaCore.create(otherProject); + if (otherJavaProject.exists()) + moduleContext = getRootsForOutputLocation(otherJavaProject, resource); + } + } + } catch (JavaModelException e) { + Util.log(e, "Failed to find package fragment root for " + current); //$NON-NLS-1$ + } + } } } this.knownModuleLocations.put(String.valueOf(moduleName), moduleContext); @@ -984,6 +1004,32 @@ public class SearchableEnvironment this.moduleUpdater.applyModuleUpdates(module, kind); } + private IPackageFragmentRoot[] getRootsForOutputLocation(IJavaProject otherJavaProject, IResource outputLocation) throws JavaModelException { + IPath outputPath = outputLocation.getFullPath(); + List<IPackageFragmentRoot> result = new ArrayList<>(); + if (outputPath.equals(otherJavaProject.getOutputLocation())) { + // collect roots reporting to the default output location: + for (IClasspathEntry classpathEntry : otherJavaProject.getRawClasspath()) { + if (classpathEntry.getOutputLocation() == null) { + for (IPackageFragmentRoot root : otherJavaProject.findPackageFragmentRoots(classpathEntry)) { + IResource rootResource = root.getResource(); + if (rootResource == null || !rootResource.getProject().equals(otherJavaProject.getProject())) + continue; // outside this project + result.add(root); + } + } + } + } + if (!result.isEmpty()) + return result.toArray(new IPackageFragmentRoot[result.size()]); + // search an entry that specifically (and exclusively) reports to the output location: + for (IClasspathEntry classpathEntry : otherJavaProject.getRawClasspath()) { + if (outputPath.equals(classpathEntry.getOutputLocation())) + return otherJavaProject.findPackageFragmentRoots(classpathEntry); + } + return null; + } + public static IPackageFragmentRoot[] getOwnedPackageFragmentRoots(IJavaProject javaProject) throws JavaModelException { IPackageFragmentRoot[] allRoots = javaProject.getPackageFragmentRoots(); IPackageFragmentRoot[] sourceRoots = Arrays.copyOf(allRoots, allRoots.length); |