diff options
author | Sasikanth Bharadwaj | 2016-09-19 19:14:27 +0000 |
---|---|---|
committer | Sasikanth Bharadwaj | 2016-09-20 08:31:18 +0000 |
commit | 8a5070c9abb42a9122f8fad53b6c17d83c4418a2 (patch) | |
tree | 5b09c15581d3db114b8ee418d635d9a2f6f25cb2 | |
parent | 89a41f58374b17a9f3b995a949ab03d9a6da1636 (diff) | |
download | eclipse.jdt.core-8a5070c9abb42a9122f8fad53b6c17d83c4418a2.tar.gz eclipse.jdt.core-8a5070c9abb42a9122f8fad53b6c17d83c4418a2.tar.xz eclipse.jdt.core-8a5070c9abb42a9122f8fad53b6c17d83c4418a2.zip |
1. Make INameEnvironmentExtension module aware and provide necessary
implementations
2. More improvements to the lookup infrastructure
16 files changed, 134 insertions, 192 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PackageBindingTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PackageBindingTest.java index a071410d5d..42bead91b5 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PackageBindingTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PackageBindingTest.java @@ -12,6 +12,7 @@ package org.eclipse.jdt.core.tests.compiler.regression; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jdt.core.tests.util.AbstractCompilerTest; +import org.eclipse.jdt.internal.compiler.env.IModuleContext; import org.eclipse.jdt.internal.compiler.env.INameEnvironment; import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; @@ -147,7 +148,7 @@ public class PackageBindingTest extends AbstractCompilerTest } @Override - public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes) { + public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes, IModuleContext context) { this.isTypeSearchExecutedWithSearchWithSecondaryTypes = true; this.isTypeSearchWithSearchWithSecondaryTypes = searchWithSecondaryTypes; return null; diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJRT.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJRT.java index 901eb84672..15a2abf592 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJRT.java +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/ClasspathJRT.java @@ -370,13 +370,13 @@ public class ClasspathJRT extends ClasspathLocation implements IMultiModuleEntry @Override public TypeLookup typeLookup() { // - return servesModule(module.name()) ? ClasspathJRT.this.typeLookupForModule.apply(module.name()) : TypeLookup.nullTypeLookup; + return servesModule(module.name()) ? ClasspathJRT.this.typeLookupForModule.apply(module.name()) : TypeLookup.Dummy; } @Override public PackageLookup packageLookup() { // - return servesModule(module.name()) ? ClasspathJRT.this.pkgLookupForModule.apply(module.name()) : PackageLookup.nullPkgLookup; + return servesModule(module.name()) ? ClasspathJRT.this.pkgLookupForModule.apply(module.name()) : PackageLookup.Dummy; } }; } diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java index fc6c98445f..c0a6a7539c 100644 --- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java +++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/FileSystem.java @@ -33,7 +33,7 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; import org.eclipse.jdt.internal.compiler.env.IModulePathEntry; import org.eclipse.jdt.internal.compiler.env.IModule; -import org.eclipse.jdt.internal.compiler.env.IModuleEnvironment; +import org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment; import org.eclipse.jdt.internal.compiler.env.IModule.IPackageExport; import org.eclipse.jdt.internal.compiler.env.IModuleContext; import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; @@ -44,7 +44,7 @@ import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.compiler.util.Util; @SuppressWarnings({ "rawtypes", "unchecked" }) -public class FileSystem extends ModuleEnvironment implements SuffixConstants { +public class FileSystem implements IModuleAwareNameEnvironment, SuffixConstants { /** * A <code>Classpath<code>, even though an IModuleLocation, can represent a plain * classpath location too. The FileSystem tells the Classpath whether to behave as a module or regular class @@ -348,7 +348,7 @@ private static String convertPathSeparators(String path) { // return suggestedAnswer; //} private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName, boolean asBinaryOnly) { - return findClass(qualifiedTypeName, typeName, asBinaryOnly, ModuleEnvironment.UNNAMED_MODULE_CONTEXT); + return findClass(qualifiedTypeName, typeName, asBinaryOnly, IModuleContext.UNNAMED_MODULE_CONTEXT); } private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName, boolean asBinaryOnly, IModuleContext moduleContext) { NameEnvironmentAnswer answer = internalFindClass(qualifiedTypeName, typeName, asBinaryOnly, moduleContext); @@ -368,90 +368,6 @@ private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeNam } return answer; } -private NameEnvironmentAnswer internalFindClass(String qualifiedTypeName, char[] typeName, boolean asBinaryOnly, IModule[] modules){ - if (this.knownFileNames.contains(qualifiedTypeName)) return null; // looking for a file which we know was provided at the beginning of the compilation -// - String qualifiedBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class; - String qualifiedPackageName = - qualifiedTypeName.length() == typeName.length - ? Util.EMPTY_STRING - : qualifiedBinaryFileName.substring(0, qualifiedTypeName.length() - typeName.length - 1); -// String qp2 = File.separatorChar == '/' ? qualifiedPackageName : qualifiedPackageName.replace('/', File.separatorChar); -// NameEnvironmentAnswer suggestedAnswer = null; -// if (qualifiedPackageName == qp2) { -// for (int i = 0, length = this.classpaths.length; i < length; i++) { -// NameEnvironmentAnswer answer = null; -// for (IModule iModule : modules) { -// boolean isUnnamed = CharOperation.equals(iModule.name(), ModuleEnvironment.UNNAMED); -// if (!isUnnamed && !this.classpaths[i].servesModule(iModule.name())) continue; -// answer = isUnnamed ? this.classpaths[i].findClass(new String(typeName), qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly) : this.classpaths[i].findClass(new String(typeName), qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly, iModule.name()); -// if (answer != null) break; -// } -// if (answer != null) { -// if (!answer.ignoreIfBetter()) { -// if (answer.isBetter(suggestedAnswer)) -// return answer; -// } else if (answer.isBetter(suggestedAnswer)) -// // remember suggestion and keep looking -// suggestedAnswer = answer; -// } -// } -// } else { -// String qb2 = qualifiedBinaryFileName.replace('/', File.separatorChar); -// for (int i = 0, length = this.classpaths.length; i < length; i++) { -// Classpath p = this.classpaths[i]; -// NameEnvironmentAnswer answer = null; -// for (IModule iModule : modules) { -// boolean isUnnamed = CharOperation.equals(iModule.name(), ModuleEnvironment.UNNAMED); -// if (!isUnnamed && !p.servesModule(iModule.name())) continue; -// if (isUnnamed) { -// answer = (p instanceof ClasspathJar) -// ? p.findClass(new String(typeName), qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly) -// : p.findClass(new String(typeName), qp2, qb2, asBinaryOnly); -// } else { -// answer = (p instanceof ClasspathJar) -// ? p.findClass(new String(typeName), qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly) -// : p.findClass(new String(typeName), qp2, qb2, asBinaryOnly, iModule.name()); -// } -// if (answer != null) break; -// } -// if (answer != null) { -// if (!answer.ignoreIfBetter()) { -// if (answer.isBetter(suggestedAnswer)) -// return answer; -// } else if (answer.isBetter(suggestedAnswer)) -// // remember suggestion and keep looking -// suggestedAnswer = answer; -// } -// } -// } -// if (suggestedAnswer != null) -// // no better answer was found -// return suggestedAnswer; -// return null; - - return Stream.of(modules) - .map(m -> { - if (m == ModuleEnvironment.UNNAMED_MODULE) { - TypeLookup t = null; - for (int i = 0, length = this.classpaths.length; i < length; i++) { - Classpath p = this.classpaths[i]; - if (t == null) { - t = p::findClass; - } else { - t = t.chain(p :: findClass); - } - } - return t; - } - IModuleEnvironment env = m.getLookupEnvironment(); - return env == null ? null : m.getLookupEnvironment().typeLookup(); - }) - .filter(t -> t != null) - .reduce(TypeLookup::chain) - .map(lookup -> lookup.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName, asBinaryOnly)) - .orElse(null); -} public NameEnvironmentAnswer findType(char[][] compoundName) { if (compoundName != null) return findClass( @@ -576,7 +492,7 @@ public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, IMo } public boolean isPackage(char[][] compoundName, char[] packageName) { - return isPackage(compoundName, packageName, ModuleEnvironment.UNNAMED_MODULE_CONTEXT); + return isPackage(compoundName, packageName, IModuleContext.UNNAMED_MODULE_CONTEXT); } public boolean isPackage(char[][] compoundName, char[] packageName, IModuleContext moduleContext) { String qualifiedPackageName = new String(CharOperation.concatWith(compoundName, packageName, '/')); @@ -590,7 +506,7 @@ public boolean isPackage(char[][] compoundName, char[] packageName, IModuleConte // return true; // } // } else { - if (moduleContext == ModuleEnvironment.UNNAMED_MODULE_CONTEXT) { + if (moduleContext == IModuleContext.UNNAMED_MODULE_CONTEXT) { return Stream.of(this.classpaths).map(p -> p.getLookupEnvironment().packageLookup()).filter(l -> l.isPackage(qualifiedPackageName)).findAny().isPresent(); } else { return moduleContext.getEnvironment().map(e -> e.packageLookup()).filter(l -> l.isPackage(qualifiedPackageName)).findAny().isPresent(); @@ -646,21 +562,11 @@ private NameEnvironmentAnswer internalFindClass(String qualifiedTypeName, char[] ? Util.EMPTY_STRING : qualifiedBinaryFileName.substring(0, qualifiedTypeName.length() - typeName.length - 1); - if (ModuleEnvironment.UNNAMED_MODULE_CONTEXT == moduleContext) { - return Stream.of(this.classpaths).map(p -> { - return p.getLookupEnvironment().typeLookup(); - }) - .reduce(TypeLookup::chain).map(t -> t.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName)).orElse(null); -// TypeLookup t = null; -// for (int i = 0, length = this.classpaths.length; i < length; i++) { -// Classpath p = this.classpaths[i]; -// if (t == null) { -// t = p::findClass; -// } else { -// t = t.chain(p :: findClass); -// } -// } -// return t.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName); + if (IModuleContext.UNNAMED_MODULE_CONTEXT == moduleContext) { + return Stream.of(this.classpaths) + .map(p -> p.getLookupEnvironment().typeLookup()) + .reduce(TypeLookup::chain) + .map(t -> t.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName)).orElse(null); } return moduleContext.getEnvironment().map(env -> env.typeLookup()) .reduce(TypeLookup::chain) diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java index d9f3d87248..5a9f671b40 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleAwareNameEnvironment.java @@ -18,22 +18,19 @@ package org.eclipse.jdt.internal.compiler.env; * A module aware name environment * */ -public interface IModuleAwareNameEnvironment extends INameEnvironmentExtension { +public interface IModuleAwareNameEnvironment extends INameEnvironment { default NameEnvironmentAnswer findType(char[][] compoundTypeName) { - return findType(compoundTypeName, null); + return findType(compoundTypeName, IModuleContext.UNNAMED_MODULE_CONTEXT); } default NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { - return findType(typeName, packageName, null); + return findType(typeName, packageName, IModuleContext.UNNAMED_MODULE_CONTEXT); } default boolean isPackage(char[][] parentPackageName, char[] packageName) { - return isPackage(parentPackageName, packageName, null); - } - default NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes) { - return findType(typeName, packageName, searchWithSecondaryTypes, null); + return isPackage(parentPackageName, packageName, IModuleContext.UNNAMED_MODULE_CONTEXT); } + NameEnvironmentAnswer findType(char[][] compoundTypeName, IModuleContext moduleContext); NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, IModuleContext moduleContext); - NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes, IModuleContext moduleContext); boolean isPackage(char[][] parentPackageName, char[] packageName, IModuleContext moduleContext); IModule getModule(char[] moduleName); } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleContext.java index 64f56f18bb..0b5fe334e0 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleContext.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleContext.java @@ -24,8 +24,36 @@ import java.util.stream.Stream; */ public interface IModuleContext { /** + * A special context to represent the unnamed module context + * + */ + IModuleContext UNNAMED_MODULE_CONTEXT = () -> { + return Stream.empty(); + }; + /** * Return the environments that are included in this context * */ public Stream<IModuleEnvironment> getEnvironment(); + + /** + * Include the other module context in this context + * + * @param other + * + * @return A joint context that represents both the module contexts + */ + default IModuleContext include(IModuleContext other) { + return () -> Stream.concat(getEnvironment(), other.getEnvironment()); + } + /** + * Include all the other contexts in this context + * + * @param other + * + * @return A joint context that represents all the module contexts + */ + default IModuleContext includeAll(Stream<IModuleContext> other) { + return () -> Stream.concat(getEnvironment(), other.flatMap(c -> c.getEnvironment())); + } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleEnvironment.java index a5e367a778..63c3df2b3c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleEnvironment.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModuleEnvironment.java @@ -16,9 +16,9 @@ package org.eclipse.jdt.internal.compiler.env; /** * The module environment provides a callback API that the compiler - * can use to look up types, compilation units, and packages in a - * specific module. A lookup environment for a module can be obtained - * from the IModulePathEntry that contributes the module + * can use to look up types, compilation units, and packages in the + * context of one or modules. A lookup environment for a module can + * be obtained from the IModulePathEntry that contributes the module * * @see IModulePathEntry#getLookupEnvironmentFor(IModule) */ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModulePathEntry.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModulePathEntry.java index b4fd7d4837..4b85905473 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModulePathEntry.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IModulePathEntry.java @@ -55,6 +55,19 @@ public interface IModulePathEntry { default boolean servesModule(char[] name) { return getModule(name) != null; } + /** + * Return the look up environment for this entry. Should be used when one needs to + * look up types/packages in all the modules contributed by this entry + * + */ IModuleEnvironment getLookupEnvironment(); + /** + * Return the lookup environment for the given module + * + * @param module + * + * @return The look up environment for the module, or null if this entry + * does not know any such module + */ IModuleEnvironment getLookupEnvironmentFor(IModule module); }
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironmentExtension.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironmentExtension.java index 4dc4972d15..a77eb7bc2f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironmentExtension.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/INameEnvironmentExtension.java @@ -43,6 +43,10 @@ public interface INameEnvironmentExtension extends INameEnvironment { * @param searchWithSecondaryTypes flag to switch on/off the search for secondary types * @return {@link NameEnvironmentAnswer} */ - NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes); + NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes, IModuleContext moduleContext); + default NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes) { + return findType(typeName, packageName, searchWithSecondaryTypes, IModuleContext.UNNAMED_MODULE_CONTEXT); + } + } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/PackageLookup.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/PackageLookup.java index 5871a5e773..0a672f83fc 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/PackageLookup.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/PackageLookup.java @@ -19,7 +19,7 @@ package org.eclipse.jdt.internal.compiler.env; */ public interface PackageLookup { - PackageLookup nullPkgLookup = qualifiedPackageName -> false; + PackageLookup Dummy = qualifiedPackageName -> false; /** * Answer whether qualifiedPackageName is the name of a known package diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/TypeLookup.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/TypeLookup.java index f1dc5c61f3..87d4cd2e28 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/TypeLookup.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/TypeLookup.java @@ -22,7 +22,7 @@ import java.util.function.BiFunction; */ public interface TypeLookup { - TypeLookup nullTypeLookup = (typeName, qualifiedPackageName, qualifiedBinaryFileName,binaryOnly) -> null; + TypeLookup Dummy = (typeName, qualifiedPackageName, qualifiedBinaryFileName,binaryOnly) -> null; /** * Find the class named typeName with binary file name qualifiedBinaryFileName in the package whose full name is qualifiedPackageName diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java index 8e10c97d49..c02d764cbb 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/CompilationUnitScope.java @@ -482,8 +482,8 @@ private Binding findImport(char[][] compoundName, int length) { break foundNothingOrType; packageBinding = (PackageBinding) binding; -// if (!packageBinding.canBeSeenBy(module())) -// return new ProblemPackageBinding(CharOperation.subarray(compoundName, 0, i), ProblemReasons.NotVisible); + if (!packageBinding.canBeSeenBy(module())) + return new ProblemPackageBinding(CharOperation.subarray(compoundName, 0, i), ProblemReasons.NotVisible); } return packageBinding; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java index 9f2f4472b1..463086616d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java @@ -130,7 +130,7 @@ public class LookupEnvironment implements ProblemReasons, TypeConstants { static final ProblemPackageBinding TheNotFoundPackage = new ProblemPackageBinding(CharOperation.NO_CHAR, NotFound); static final ProblemReferenceBinding TheNotFoundType = new ProblemReferenceBinding(CharOperation.NO_CHAR_CHAR, null, NotFound); - final ModuleBinding UnNamedModule = new ModuleBinding(ModuleEnvironment.UNNAMED_MODULE, this); + final ModuleBinding UnNamedModule = new ModuleBinding.UnNamedModule(this); public LookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions globalOptions, ProblemReporter problemReporter, INameEnvironment nameEnvironment) { this.typeRequestor = typeRequestor; @@ -177,7 +177,7 @@ public ReferenceBinding askForType(char[][] compoundName, char[] mod) { NameEnvironmentAnswer answer = null; if (this.nameEnvironment instanceof IModuleAwareNameEnvironment) { ModuleBinding module = getModule(mod); - answer = ((IModuleAwareNameEnvironment)this.nameEnvironment).findType(compoundName, module.getDependencyLookupContext()); + answer = ((IModuleAwareNameEnvironment)this.nameEnvironment).findType(compoundName, module.getDependencyClosureContext()); } else { answer = this.nameEnvironment.findType(compoundName); } @@ -218,7 +218,7 @@ ReferenceBinding askForType(PackageBinding packageBinding, char[] name, char[] m NameEnvironmentAnswer answer = null; if (this.nameEnvironment instanceof IModuleAwareNameEnvironment) { ModuleBinding module = getModule(mod); - answer = ((IModuleAwareNameEnvironment)this.nameEnvironment).findType(name, packageBinding.compoundName, module.getDependencyLookupContext()); + answer = ((IModuleAwareNameEnvironment)this.nameEnvironment).findType(name, packageBinding.compoundName, module.getDependencyClosureContext()); } else { answer = this.nameEnvironment.findType(name, packageBinding.compoundName); } @@ -846,10 +846,11 @@ public PackageBinding createPackage(char[][] compoundName, char[] mod) { // since the package can be added after a set of source files have already been compiled, // we need to check whenever a package is created if(this.nameEnvironment instanceof INameEnvironmentExtension) { + ModuleBinding module = getModule(mod); //When the nameEnvironment is an instance of INameEnvironmentWithProgress, it can get avoided to search for secondaryTypes (see flag). // This is a performance optimization, because it is very expensive to search for secondary types and it isn't necessary to check when creating a package, // because package name can not collide with a secondary type name. - if (((INameEnvironmentExtension)this.nameEnvironment).findType(compoundName[i], parent.compoundName, false) != null) { + if (((INameEnvironmentExtension)this.nameEnvironment).findType(compoundName[i], parent.compoundName, false, module.getDependencyClosureContext()) != null) { return null; } } else { @@ -1753,7 +1754,7 @@ boolean isPackage(char[][] compoundName, char[] name, char[] mod) { boolean answer = false; if (this.nameEnvironment instanceof IModuleAwareNameEnvironment) { ModuleBinding module = getModule(mod); - answer = ((IModuleAwareNameEnvironment)this.nameEnvironment).isPackage(pkgName, name, module.getDependencyLookupContext()); + answer = ((IModuleAwareNameEnvironment)this.nameEnvironment).isPackage(pkgName, name, module.getDependencyClosureContext()); } else { answer = this.nameEnvironment.isPackage(pkgName, name); } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java index 1d782a3175..76d7800e66 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleBinding.java @@ -16,7 +16,6 @@ package org.eclipse.jdt.internal.compiler.lookup; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.function.Predicate; import java.util.function.Supplier; @@ -33,6 +32,28 @@ import org.eclipse.jdt.internal.compiler.util.JRTUtil; public class ModuleBinding extends Binding { + public static class UnNamedModule extends ModuleBinding { + + UnNamedModule(LookupEnvironment env) { + super(env); + } + public ModuleBinding[] getAllRequiredModules() { + return NO_REQUIRES; + } + public IModuleContext getModuleLookupContext() { + return IModuleContext.UNNAMED_MODULE_CONTEXT; + } + public IModuleContext getDependencyClosureContext() { + return IModuleContext.UNNAMED_MODULE_CONTEXT; + } + public IModuleContext getModuleGraphContext() { + return IModuleContext.UNNAMED_MODULE_CONTEXT; + } + public boolean canSee(PackageBinding pkg) { + //TODO - if the package is part of a named module, then we should check if the module exports the package + return true; + } + } public char[] moduleName; public IModuleReference[] requires; public IPackageExport[] exportedPackages; @@ -52,6 +73,8 @@ public class ModuleBinding extends Binding { ModuleBinding(LookupEnvironment env) { this.moduleName = ModuleEnvironment.UNNAMED; this.environment = env; + this.requires = NO_MODULE_REFS; + this.exportedPackages = NO_EXPORTS; } public ModuleBinding(IModule module, LookupEnvironment environment) { this.moduleName = module.name(); @@ -99,8 +122,6 @@ public class ModuleBinding extends Binding { * collection of implicit dependencies */ public Collection<ModuleBinding> getImplicitDependencies() { - if (this == this.environment.UnNamedModule) - return Collections.emptyList(); return implicitDependencyCollector().get(); } @@ -114,8 +135,6 @@ public class ModuleBinding extends Binding { * An array of all required modules */ public ModuleBinding[] getAllRequiredModules() { - if (this == this.environment.UnNamedModule) - return NO_REQUIRES; if (this.requiredModules != null) return this.requiredModules; @@ -158,10 +177,6 @@ public class ModuleBinding extends Binding { * @return True, if the package is visible to this module, false otherwise */ public boolean canSee(PackageBinding pkg) { - if (this == this.environment.UnNamedModule) { - //TODO - if the package is part of a named module, then we should check if the module exports the package - return true; - } return Stream.of(getAllRequiredModules()).filter(dep -> dep.isPackageExportedTo(pkg, this)).findFirst().isPresent(); } @@ -170,24 +185,20 @@ public class ModuleBinding extends Binding { return true; return Stream.of(getAllRequiredModules()).anyMatch(other::equals); } + // A context representing just this module public IModuleContext getModuleLookupContext() { - return this == this.environment.UnNamedModule ? ModuleEnvironment.UNNAMED_MODULE_CONTEXT : () -> Stream.of(this.moduleEnviroment); + return () -> this.moduleEnviroment == null ? Stream.empty() : Stream.of(this.moduleEnviroment); } - public IModuleContext getDependencyLookupContext() { + // A context including this module and all it's required modules + public IModuleContext getDependencyClosureContext() { ModuleBinding[] deps = getAllRequiredModules(); - return this == this.environment.UnNamedModule ? ModuleEnvironment.UNNAMED_MODULE_CONTEXT : () -> Stream.concat(getModuleLookupContext().getEnvironment(), Stream.of(deps).flatMap(m -> m.getDependencyLookupContext().getEnvironment())).filter(e -> e != null); - //return getModuleLookupContext().chain(Stream.of(deps).map(m -> m.moduleEnviroment.typeLookup()) -// .collect(Collectors.groupingBy(m -> { -// return m.moduleEnviroment; -// })) -// .entrySet().stream().map (e -> { -// IModuleEnvironment env = e.getKey(); -// if (root instanceof IMultiModuleEntry) { -// return ((IMultiModuleEntry)root).forModules(e.getValue().stream().map(ModuleBinding::name).collect(Collectors.toList())); -// } -// return env.typeLookup(); - //}) -// .reduce(TypeLookup::chain).orElse(null)); + return getModuleLookupContext().includeAll(Stream.of(deps).map(m -> m.getDependencyClosureContext())); + } + // A context that includes the entire module graph starting from this module + public IModuleContext getModuleGraphContext() { + Stream<ModuleBinding> reqs = getRequiredModules(false); + return this == this.environment.UnNamedModule ? IModuleContext.UNNAMED_MODULE_CONTEXT : + getModuleLookupContext().includeAll(reqs.map(m -> m.getModuleGraphContext())); } @Override public int kind() { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleEnvironment.java index 70b49e8fdf..de1be4f05b 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleEnvironment.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ModuleEnvironment.java @@ -17,7 +17,6 @@ package org.eclipse.jdt.internal.compiler.lookup; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Set; - import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.env.IModule; import org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment; @@ -62,11 +61,6 @@ public abstract class ModuleEnvironment implements IModuleAwareNameEnvironment { return new String(UNNAMED); } }; - // A special context to represent the unnamed module context. Subclasses should perform a whole - // world lookup when they see this context - public static final IModuleContext UNNAMED_MODULE_CONTEXT = () -> { - return null; - }; public static IModule[] UNNAMED_MODULE_ARRAY = new IModule[]{UNNAMED_MODULE}; private HashMap<String, IModule> modulesCache = null; private static HashMap<IModuleLocation, IModule> ModuleLocationMap = new HashMap<>(); @@ -75,22 +69,6 @@ public abstract class ModuleEnvironment implements IModuleAwareNameEnvironment { this.modulesCache = new HashMap<>(); } - private NameEnvironmentAnswer findTypeWorker(char[] typeName, char[][] packageName, boolean searchSecondaryTypes, IModuleContext context) { - NameEnvironmentAnswer answer = findType(typeName, packageName, context); -// char[] module = null; -// if(answer == null || (module = answer.moduleName()) == null || client == null || -// CharOperation.equals(module, JRTUtil.JAVA_BASE_CHAR)) { -// return answer; -// } -// return returnAnswerAfterValidation(packageName, answer, client); - return answer; - } - - //TODO this should be abstract - public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes, IModuleContext context) { - return findTypeWorker(typeName, packageName, searchWithSecondaryTypes, context); - } - protected NameEnvironmentAnswer returnAnswerAfterValidation(char[][] packageName, NameEnvironmentAnswer answer, char[] client) { if (isPackageVisible(CharOperation.concatWith(packageName, '.'), answer.moduleName(), client)) { return answer; @@ -98,7 +76,7 @@ public abstract class ModuleEnvironment implements IModuleAwareNameEnvironment { return null; } - // TODO: this should be abstract + // TODO: these should be abstract public NameEnvironmentAnswer findType(char[][] compoundTypeName, IModuleContext moduleContext) { return null; } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java index 8f6a1855c5..bb47654a31 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/NameEnvironmentWithProgress.java @@ -16,6 +16,7 @@ *******************************************************************************/ package org.eclipse.jdt.core.dom; +import java.util.function.Function; import java.util.stream.Stream; import org.eclipse.core.runtime.IProgressMonitor; @@ -26,7 +27,6 @@ import org.eclipse.jdt.internal.compiler.batch.FileSystem; import org.eclipse.jdt.internal.compiler.env.IModuleContext; import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; import org.eclipse.jdt.internal.compiler.env.TypeLookup; -import org.eclipse.jdt.internal.compiler.lookup.ModuleEnvironment; import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; import org.eclipse.jdt.internal.core.INameEnvironmentWithProgress; import org.eclipse.jdt.internal.core.NameLookup; @@ -51,9 +51,8 @@ class NameEnvironmentWithProgress extends FileSystem implements INameEnvironment } } public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, IModuleContext context) { - return super.findType(typeName, packageName, true, context); + return findType(typeName, packageName, true, context); } - public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchSecondaryTypes, IModuleContext context) { checkCanceled(); NameEnvironmentAnswer answer = super.findType(typeName, packageName, context); @@ -78,20 +77,23 @@ class NameEnvironmentWithProgress extends FileSystem implements INameEnvironment // } // } // } - if (ModuleEnvironment.UNNAMED_MODULE_CONTEXT == context) { - answer = Stream.of(this.classpaths).<TypeLookup>map(p -> { - return (t, qPackageName, qBinaryFileName,asBinaryOnly) -> { - return ((ClasspathDirectory)p).findSecondaryInClass(typeName, qualifiedPackageName, qualifiedBinaryFileName); - }; - }) - .reduce(TypeLookup::chain).map(t -> t.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName)).orElse(null); + Function<ClasspathDirectory, TypeLookup> secondaryTypesLookup = d -> { + return (t, qPackageName, qBinaryFileName,asBinaryOnly) -> { + return d.findSecondaryInClass(t, qPackageName, qBinaryFileName); + }; + }; + if (IModuleContext.UNNAMED_MODULE_CONTEXT == context) { + answer = Stream.of(this.classpaths) + .filter(env -> env instanceof ClasspathDirectory) + .map(p -> (ClasspathDirectory)p) + .map(secondaryTypesLookup) + .reduce(TypeLookup::chain) + .map(t -> t.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName)).orElse(null); } else { - answer = context.getEnvironment().filter(env -> env instanceof ClasspathDirectory) - .<TypeLookup>map(p -> { - return (t, qPackageName, qBinaryFileName,asBinaryOnly) -> { - return ((ClasspathDirectory)p).findSecondaryInClass(typeName, qualifiedPackageName, qualifiedBinaryFileName); - }; - }) + answer = context.getEnvironment() + .filter(env -> env instanceof ClasspathDirectory) + .map(p -> (ClasspathDirectory)p) + .map(secondaryTypesLookup) .reduce(TypeLookup::chain) .map(lookup -> lookup.findClass(typeName, qualifiedPackageName, qualifiedBinaryFileName)) .orElse(null); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java index d9b440f55d..9826cfdaad 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CancelableNameEnvironment.java @@ -19,6 +19,7 @@ import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.internal.codeassist.ISearchRequestor; +import org.eclipse.jdt.internal.compiler.env.IModuleContext; import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; @@ -53,7 +54,7 @@ public class CancelableNameEnvironment extends SearchableEnvironment implements checkCanceled(); return super.findType(compoundTypeName); } - public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes) { + public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, boolean searchWithSecondaryTypes, IModuleContext context) { return findType(typeName, packageName); } public void findTypes(char[] prefix, boolean findMembers, boolean camelCaseMatch, int searchFor, ISearchRequestor storage, IProgressMonitor progressMonitor) { |