diff options
author | Stephan Herrmann | 2017-09-09 23:10:35 +0000 |
---|---|---|
committer | Stephan Herrmann | 2017-09-09 23:10:35 +0000 |
commit | bc0e5b8ad19af75654b974dfc4cfc05b5b467507 (patch) | |
tree | ddbe8c28a74cbeda94eb7be30729e46f50442d13 | |
parent | 6f90d44d90811c036e9a1d93a1138bbc37f8d26b (diff) | |
download | eclipse.jdt.core-bc0e5b8ad19af75654b974dfc4cfc05b5b467507.tar.gz eclipse.jdt.core-bc0e5b8ad19af75654b974dfc4cfc05b5b467507.tar.xz eclipse.jdt.core-bc0e5b8ad19af75654b974dfc4cfc05b5b467507.zip |
Change-Id: I6f5eeedccdcb5a8ff809277aeaa645f5f0e4554c
4 files changed, 106 insertions, 6 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java index fa7c9ec897..36cff592b7 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java @@ -1307,10 +1307,13 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases { return createJava9Project(name, new String[]{"src"}); } protected IJavaProject createJava9Project(String name, String[] srcFolders) throws CoreException { + return createJava9ProjectWithJREAttributes(name, srcFolders, null); + } + protected IJavaProject createJava9ProjectWithJREAttributes(String name, String[] srcFolders, IClasspathAttribute[] attributes) throws CoreException { String javaHome = System.getProperty("java.home") + File.separator; Path bootModPath = new Path(javaHome +"/lib/jrt-fs.jar"); Path sourceAttachment = new Path(javaHome +"/lib/src.zip"); - IClasspathEntry jrtEntry = JavaCore.newLibraryEntry(bootModPath, sourceAttachment, null, null, null, false); + IClasspathEntry jrtEntry = JavaCore.newLibraryEntry(bootModPath, sourceAttachment, null, null, attributes, false); IJavaProject project = this.createJavaProject(name, srcFolders, new String[0], new String[0], "bin", "9"); IClasspathEntry[] old = project.getRawClasspath(); 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 1ddf31d165..d8b828066b 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 @@ -5328,6 +5328,44 @@ public class ModuleBuilderTests extends ModifyingResourceTests { this.deleteProject("org.astro.patch"); } } + + // patch can see unexported type from host - JRE + public void testPatch2() throws CoreException, IOException { + if (!isJRE9) return; + try { + IClasspathAttribute[] attributes = { + JavaCore.newClasspathAttribute(IClasspathAttribute.MODULE, "true"), + JavaCore.newClasspathAttribute(IClasspathAttribute.PATCH_MODULE, "java.base") + }; + IJavaProject patchProject = createJava9ProjectWithJREAttributes("org.astro.patch", new String[]{"src"}, attributes); + + String[] patchSources = { + "src/org/astro/Test2.java", + "package org.astro;\n" + + "class Test2 {\n" + + " int test(jdk.internal.misc.Unsafe unsafe) {\n" + + " return unsafe.addressSize();\n" + + " }\n" + + "}\n" + }; + createSourceFiles(patchProject, patchSources); + + getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); + assertNoErrors(); + + this.problemRequestor.reset(); + ICompilationUnit cu = getCompilationUnit("/org.astro.patch/src/org/astro/Test2.java"); + cu.getWorkingCopy(this.wcOwner, null); + assertProblems( + "Unexpected problems", + "----------\n" + + "----------\n", + this.problemRequestor); + + } finally { + this.deleteProject("org.astro.patch"); + } + } 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/builder/ModulePathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ModulePathEntry.java index 6924d0d8c0..161e01f64e 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ModulePathEntry.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/ModulePathEntry.java @@ -15,10 +15,16 @@ package org.eclipse.jdt.internal.core.builder; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.env.IModule; import org.eclipse.jdt.internal.compiler.env.IModulePathEntry; +import org.eclipse.jdt.internal.compiler.env.IMultiModuleEntry; /** * Represents a project on the module path. @@ -114,4 +120,49 @@ public class ModulePathEntry implements IModulePathEntry { } return false; } + + /** + * Combines an IMultiModuleEntry with further locations in order to support patch-module. + * Implemented by adding IMultiModuleEntry functionality to ModulePathEntry. + */ + static public class Multi extends ModulePathEntry implements IMultiModuleEntry { + + Multi(IPath path, IModule module, ClasspathLocation[] locations) { + super(path, module, locations); + } + + void addPatchLocation(ClasspathLocation location) { + this.locations = Arrays.copyOf(this.locations, this.locations.length+1); + this.locations[this.locations.length-1] = location; + location.setModule(this.module); + } + + @Override + public IModule getModule(char[] name) { + for (ClasspathLocation loc : this.locations) { + if (loc instanceof IMultiModuleEntry) { + IModule mod = ((IMultiModuleEntry) loc).getModule(name); + if (mod != null) + return mod; + } else { + IModule mod = loc.getModule(); + if (CharOperation.equals(mod.name(), name)) + return mod; + } + } + return null; + } + + @Override + public Collection<String> getModuleNames() { + Set<String> result = new HashSet<>(); + for (ClasspathLocation loc : this.locations) { + if (loc instanceof IMultiModuleEntry) + result.addAll(((IMultiModuleEntry) loc).getModuleNames()); + else + result.add(String.valueOf(loc.getModule().name())); + } + return result; + } + } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java index 0271be84eb..77b543980e 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/NameEnvironment.java @@ -278,10 +278,12 @@ private void computeClasspathLocations( sLocations.toArray(this.sourceLocations); if (moduleEntries != null && (mod = javaProject.getModuleDescription()) != null) { try { - SourceModule sourceModule = (SourceModule)mod; + AbstractModule sourceModule = (AbstractModule)mod; ModuleDescriptionInfo info = (ModuleDescriptionInfo) sourceModule.getElementInfo(); ModulePathEntry projectEntry = new ModulePathEntry(javaProject.getPath(), info, this.sourceLocations); - moduleEntries.put(sourceModule.getElementName(), projectEntry); + if (!moduleEntries.containsKey(sourceModule.getElementName())) { // can be registered already, if patching + moduleEntries.put(sourceModule.getElementName(), projectEntry); + } } catch (JavaModelException jme) { // do nothing, probably a non module project } @@ -371,15 +373,21 @@ void combineIntoModuleEntry(ClasspathLocation sourceLocation, IModule patchedMod String patchedModuleName = String.valueOf(patchedModule.name()); IModulePathEntry mainEntry = moduleEntries.get(patchedModuleName); ClasspathLocation[] combinedLocations = null; - if (mainEntry instanceof ModulePathEntry) { + if (mainEntry instanceof ModulePathEntry.Multi) { + ((ModulePathEntry.Multi) mainEntry).addPatchLocation(sourceLocation); + return; + } else if (mainEntry instanceof ClasspathJrt) { + combinedLocations = new ClasspathLocation[] { (ClasspathLocation) mainEntry, sourceLocation }; + moduleEntries.put(patchedModuleName, new ModulePathEntry.Multi(null, patchedModule, combinedLocations)); + return; + } else if (mainEntry instanceof ModulePathEntry) { ClasspathLocation[] mainLocs = ((ModulePathEntry) mainEntry).locations; combinedLocations = Arrays.copyOf(mainLocs, mainLocs.length+1); combinedLocations[combinedLocations.length-1] = sourceLocation; } else if (mainEntry instanceof ClasspathLocation) { combinedLocations = new ClasspathLocation[] { (ClasspathLocation) mainEntry, sourceLocation }; } else { - // FIXME: JrtPackageFragmentRoot, ProjectEntry ?? - System.err.println("ups!"); + throw new IllegalStateException("Cannot patch the module of classpath entry "+mainEntry); //$NON-NLS-1$ } moduleEntries.put(patchedModuleName, new ModulePathEntry(null, patchedModule, combinedLocations)); } |