Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java152
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java5
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java76
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java3
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SearchableEnvironment.java54
6 files changed, 279 insertions, 25 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
index 1870433959..134963008e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests9.java
@@ -1214,4 +1214,156 @@ public void testBug528948_002() throws Exception {
deleteProject(project2);
}
}
+public void testBug517417_001() throws Exception {
+ IJavaProject project1 = createJavaProject("Completion9_1", new String[] {"src"}, new String[] {"JCL9_LIB"}, "bin", "9");
+ IJavaProject project2 = createJavaProject("Completion9_2", new String[] {"src"}, new String[] {"JCL9_LIB"}, "bin", "9");
+ IJavaProject project3 = createJavaProject("Completion9_3", new String[] {"src"}, new String[] {"JCL9_LIB"}, "bin", "9");
+ try {
+ project1.open(null);
+ createType("/Completion9_1/src/", "pack11", "X11");
+ createFile("/Completion9_1/src/module-info.java",
+ "module first {\n" +
+ " requires second;\n" +
+ "}\n");
+ String fileContent =
+ "package pack0;\n" +
+ "import pac\n" +
+ "public class Main {\n" +
+ "}\n";
+ String completeBehind = "import pac";
+ createFolder("/Completion9_1/src/pack0");
+ String filePath = "/Completion9_1/src/pack0/Main.java";
+ createFile(filePath, fileContent);
+ addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH")));
+
+ project2.open(null);
+ createType("/Completion9_2/src/", "pack21", "X21");
+ createType("/Completion9_2/src/", "pack2internal", "X22");
+
+ createFile("/Completion9_2/src/module-info.java",
+ "module second { \n" +
+ " requires transitive third;\n" +
+ " exports pack21 to first;\n" +
+ " exports pack2internal to my.test.mod;\n" +
+ "}\n");
+ addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH")));
+
+ project3.open(null);
+ createType("/Completion9_3/src/", "pack31", "X31");
+
+ createFile("/Completion9_3/src/module-info.java",
+ "module third { " +
+ " exports pack31;\n" +
+ "}\n");
+ addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH")));
+
+ project1.close(); // sync
+ project2.close();
+ project3.close();
+ project3.open(null);
+ project2.open(null);
+ project1.open(null);
+
+ int cursorLocation = fileContent.lastIndexOf(completeBehind) + completeBehind.length();
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+
+ ICompilationUnit unit = getCompilationUnit(filePath);
+ unit.codeComplete(cursorLocation, requestor);
+
+ String expected = "pack0[PACKAGE_REF]{pack0.*;, pack0, null, null, 49}\n" + // local
+ "pack11[PACKAGE_REF]{pack11.*;, pack11, null, null, 49}\n" + // local
+ "pack21[PACKAGE_REF]{pack21.*;, pack21, null, null, 49}\n" + // exported
+ "pack31[PACKAGE_REF]{pack31.*;, pack31, null, null, 49}"; // exported in transitively required third
+ // package pack2internal is exported only to another module
+ assertResults(expected, requestor.getResults());
+ } finally {
+ deleteProject(project1);
+ deleteProject(project2);
+ deleteProject(project3);
+ }
+}
+
+// testing only packages from transitive requires modules available for completion
+public void testBug517417_002() throws Exception {
+ IJavaProject project1 = createJavaProject("Completion9_1", new String[] {"src"}, new String[] {"JCL9_LIB"}, "bin", "9");
+ IJavaProject project2 = createJavaProject("Completion9_2", new String[] {"src"}, new String[] {"JCL9_LIB"}, "bin", "9");
+ IJavaProject project3 = createJavaProject("Completion9_3", new String[] {"src"}, new String[] {"JCL9_LIB"}, "bin", "9");
+ IJavaProject project4 = createJavaProject("Completion9_4", new String[] {"src"}, new String[] {"JCL9_LIB"}, "bin", "9");
+ try {
+ project1.open(null);
+ createType("/Completion9_1/src/", "pack11", "X11");
+ createFile("/Completion9_1/src/module-info.java",
+ "module first {\n" +
+ " requires second;\n" +
+ "}\n");
+ String fileContent =
+ "package pack0;\n" +
+ "import pac\n" +
+ "public class Main {\n" +
+ "}\n";
+ String completeBehind = "import pac";
+ createFolder("/Completion9_1/src/pack0");
+ String filePath = "/Completion9_1/src/pack0/Main.java";
+ createFile(filePath, fileContent);
+ addClasspathEntry(project1, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH")));
+
+ project2.open(null);
+ createType("/Completion9_2/src/", "pack21", "X21");
+ createType("/Completion9_2/src/", "pack2internal", "X22");
+
+ createFile("/Completion9_2/src/module-info.java",
+ "module second { \n" +
+ " requires transitive third;\n" +
+ " requires four;\n" +
+ " exports pack21 to first;\n" +
+ " exports pack2internal to my.test.mod;\n" +
+ "}\n");
+ addClasspathEntry(project2, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH")));
+
+ project3.open(null);
+ createType("/Completion9_3/src/", "pack31", "X31");
+
+ createFile("/Completion9_3/src/module-info.java",
+ "module third { " +
+ " exports pack31;\n" +
+ "}\n");
+ addClasspathEntry(project3, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH")));
+
+ project4.open(null);
+ createType("/Completion9_4/src/", "pack41", "X41");
+
+ createFile("/Completion9_4/src/module-info.java",
+ "module four { " +
+ " exports pack41;\n" +
+ "}\n");
+ addClasspathEntry(project4, JavaCore.newContainerEntry(new Path("org.eclipse.jdt.MODULE_PATH")));
+
+ project1.close(); // sync
+ project2.close();
+ project3.close();
+ project4.close();
+ project4.open(null);
+ project3.open(null);
+ project2.open(null);
+ project1.open(null);
+
+ int cursorLocation = fileContent.lastIndexOf(completeBehind) + completeBehind.length();
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+
+ ICompilationUnit unit = getCompilationUnit(filePath);
+ unit.codeComplete(cursorLocation, requestor);
+
+ String expected = "pack0[PACKAGE_REF]{pack0.*;, pack0, null, null, 49}\n" + // local
+ "pack11[PACKAGE_REF]{pack11.*;, pack11, null, null, 49}\n" + // local
+ "pack21[PACKAGE_REF]{pack21.*;, pack21, null, null, 49}\n" + // exported
+ "pack31[PACKAGE_REF]{pack31.*;, pack31, null, null, 49}"; // exported in transitively required third
+ // package pack2internal is exported only to another module
+ assertResults(expected, requestor.getResults());
+ } finally {
+ deleteProject(project1);
+ deleteProject(project2);
+ deleteProject(project3);
+ deleteProject(project4);
+ }
+}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index efda13aac7..2386d7df7d 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -8164,7 +8164,11 @@ public final class CompletionEngine
setSourceRange(
importReference.sourceStart,
importReference.declarationSourceEnd);
- this.nameEnvironment.findPackages(importName, this);
+ try {
+ this.nameEnvironment.findPackages(importName, this, this.javaProject.getAllPackageFragmentRoots(), true);
+ } catch (JavaModelException e) {
+ // silent
+ }
setSourceRange(
oldStart,
oldEnd - 1,
@@ -10732,7 +10736,7 @@ public final class CompletionEngine
private void findPackagesInCurrentModule() {
try {
IPackageFragmentRoot[] moduleRoots = SearchableEnvironment.getOwnedPackageFragmentRoots(this.javaProject);
- this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this, moduleRoots);
+ this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this, moduleRoots, false);
} catch (JavaModelException e) {
// silent
}
@@ -10744,7 +10748,11 @@ public final class CompletionEngine
setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
+ try {
+ this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this, this.javaProject.getAllPackageFragmentRoots(), true);
+ } catch (JavaModelException e) {
+ // silent
+ }
}
private void findParameterizedType(TypeReference ref, Scope scope) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java
index 14489de7e3..54d0a7a2d4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/AnnotatableTypeSystem.java
@@ -176,7 +176,8 @@ public class AnnotatableTypeSystem extends TypeSystem {
throw new IllegalStateException();
WildcardBinding nakedType = null;
- TypeBinding[] derivedTypes = getDerivedTypes(genericType);
+ boolean useDerivedTypesOfBound = bound instanceof TypeVariableBinding || bound instanceof ParameterizedTypeBinding;
+ TypeBinding[] derivedTypes = getDerivedTypes(useDerivedTypesOfBound ? bound : genericType);
for (int i = 0, length = derivedTypes.length; i < length; i++) {
TypeBinding derivedType = derivedTypes[i];
if (derivedType == null)
@@ -200,7 +201,7 @@ public class AnnotatableTypeSystem extends TypeSystem {
WildcardBinding wildcard = new WildcardBinding(genericType, rank, bound, otherBounds, boundKind, this.environment);
wildcard.id = nakedType.id;
wildcard.setTypeAnnotations(annotations, this.isAnnotationBasedNullAnalysisEnabled);
- return (WildcardBinding) cacheDerivedType(genericType, nakedType, wildcard);
+ return (WildcardBinding) cacheDerivedType(useDerivedTypesOfBound ? bound : genericType, nakedType, wildcard);
}
public WildcardBinding getWildcard(ReferenceBinding genericType, int rank, TypeBinding bound, TypeBinding[] otherBounds, int boundKind) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
index a50f0206c0..d63ca6673e 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TypeSystem.java
@@ -65,27 +65,67 @@ public class TypeSystem {
public final class HashedParameterizedTypes {
- private final class InternalParameterizedTypeBinding extends ParameterizedTypeBinding {
-
- public InternalParameterizedTypeBinding(ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBinding enclosingType, LookupEnvironment environment) {
- super(genericType, typeArguments, enclosingType, environment);
+ private final class PTBKey extends ReferenceBinding { // extends ReferenceBinding so it can be used as wrapper
+ protected ReferenceBinding type; // must ensure the type is resolved
+ public TypeBinding[] arguments;
+ private ReferenceBinding enclosingType;
+ public PTBKey(ReferenceBinding type, TypeBinding[] arguments, ReferenceBinding enclosingType, LookupEnvironment environment) {
+ this.type = type;
+ this.arguments = arguments;
+ this.enclosingType = enclosingType;
+
+ if(environment != null) {
+ // only add as wrapper when used in put()
+ if (type instanceof UnresolvedReferenceBinding)
+ ((UnresolvedReferenceBinding) type).addWrapper(this, environment);
+ if (arguments != null) {
+ for (int i = 0, l = arguments.length; i < l; i++) {
+ if (arguments[i] instanceof UnresolvedReferenceBinding)
+ ((UnresolvedReferenceBinding) arguments[i]).addWrapper(this, environment);
+ if (arguments[i].hasNullTypeAnnotations())
+ this.tagBits |= TagBits.HasNullTypeAnnotation;
+ }
+ }
+ }
+ }
+ @Override
+ public void swapUnresolved(UnresolvedReferenceBinding unresolvedType, ReferenceBinding resolvedType, LookupEnvironment env) {
+ if (this.type == unresolvedType) { //$IDENTITY-COMPARISON$
+ this.type = resolvedType; // cannot be raw since being parameterized below
+ ReferenceBinding enclosing = resolvedType.enclosingType();
+ if (enclosing != null) {
+ this.enclosingType = (ReferenceBinding) env.convertUnresolvedBinaryToRawType(enclosing); // needed when binding unresolved member type
+ }
+ }
+ if (this.arguments != null) {
+ for (int i = 0, l = this.arguments.length; i < l; i++) {
+ if (this.arguments[i] == unresolvedType) { //$IDENTITY-COMPARISON$
+ this.arguments[i] = env.convertUnresolvedBinaryToRawType(resolvedType);
+ }
+ }
+ }
}
-
public boolean equals(Object other) {
- ParameterizedTypeBinding that = (ParameterizedTypeBinding) other; // homogeneous container.
+ PTBKey that = (PTBKey) other; // homogeneous container.
return this.type == that.type && this.enclosingType == that.enclosingType && Util.effectivelyEqual(this.arguments, that.arguments); //$IDENTITY-COMPARISON$
}
-
+ final int hash(TypeBinding b) {
+ if(b instanceof WildcardBinding || b instanceof TypeVariableBinding) {
+ return System.identityHashCode(b);
+ }
+ return b.hashCode();
+ }
public int hashCode() {
- int hashCode = this.type.hashCode() + 13 * (this.enclosingType != null ? this.enclosingType.hashCode() : 0);
+ final int prime=31;
+ int hashCode = 1 + hash(this.type) + (this.enclosingType != null ? hash(this.enclosingType) : 0);
for (int i = 0, length = this.arguments == null ? 0 : this.arguments.length; i < length; i++) {
- hashCode += (i + 1) * this.arguments[i].hashCode();
+ hashCode = hashCode * prime + hash(this.arguments[i]);
}
return hashCode;
}
}
- HashMap<ParameterizedTypeBinding, ParameterizedTypeBinding []> hashedParameterizedTypes = new HashMap<ParameterizedTypeBinding, ParameterizedTypeBinding[]>(256);
+ HashMap<PTBKey, ParameterizedTypeBinding []> hashedParameterizedTypes = new HashMap<>(256);
ParameterizedTypeBinding get(ReferenceBinding genericType, TypeBinding[] typeArguments, ReferenceBinding enclosingType, AnnotationBinding[] annotations) {
@@ -97,7 +137,7 @@ public class TypeSystem {
}
ReferenceBinding unannotatedEnclosingType = enclosingType == null ? null : (ReferenceBinding) getUnannotatedType(enclosingType);
- ParameterizedTypeBinding typeParameterization = new InternalParameterizedTypeBinding(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, TypeSystem.this.environment);
+ PTBKey key = new PTBKey(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, null);
ReferenceBinding genericTypeToMatch = unannotatedGenericType, enclosingTypeToMatch = unannotatedEnclosingType;
TypeBinding [] typeArgumentsToMatch = unannotatedTypeArguments;
if (TypeSystem.this instanceof AnnotatableTypeSystem) {
@@ -105,7 +145,7 @@ public class TypeSystem {
enclosingTypeToMatch = enclosingType;
typeArgumentsToMatch = typeArguments;
}
- ParameterizedTypeBinding [] parameterizedTypeBindings = this.hashedParameterizedTypes.get(typeParameterization);
+ ParameterizedTypeBinding [] parameterizedTypeBindings = this.hashedParameterizedTypes.get(key);
for (int i = 0, length = parameterizedTypeBindings == null ? 0 : parameterizedTypeBindings.length; i < length; i++) {
ParameterizedTypeBinding parameterizedType = parameterizedTypeBindings[i];
if (parameterizedType.actualType() != genericTypeToMatch) { //$IDENTITY-COMPARISON$
@@ -130,9 +170,9 @@ public class TypeSystem {
}
ReferenceBinding unannotatedEnclosingType = enclosingType == null ? null : (ReferenceBinding) getUnannotatedType(enclosingType);
- ParameterizedTypeBinding typeParameterization = new InternalParameterizedTypeBinding(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, TypeSystem.this.environment);
+ PTBKey key = new PTBKey(unannotatedGenericType, unannotatedTypeArguments, unannotatedEnclosingType, TypeSystem.this.environment);
- ParameterizedTypeBinding [] parameterizedTypeBindings = this.hashedParameterizedTypes.get(typeParameterization);
+ ParameterizedTypeBinding [] parameterizedTypeBindings = this.hashedParameterizedTypes.get(key);
int slot;
if (parameterizedTypeBindings == null) {
slot = 0;
@@ -142,7 +182,7 @@ public class TypeSystem {
System.arraycopy(parameterizedTypeBindings, 0, parameterizedTypeBindings = new ParameterizedTypeBinding[slot + 1], 0, slot);
}
parameterizedTypeBindings[slot] = parameterizedType;
- this.hashedParameterizedTypes.put(typeParameterization, parameterizedTypeBindings);
+ this.hashedParameterizedTypes.put(key, parameterizedTypeBindings);
}
}
@@ -342,7 +382,9 @@ public class TypeSystem {
}
TypeBinding unannotatedBound = bound == null ? null : getUnannotatedType(bound);
- TypeBinding[] derivedTypes = this.types[unannotatedGenericType.id]; // by construction, cachedInfo != null now.
+ boolean useDerivedTypesOfBound = unannotatedBound instanceof TypeVariableBinding || unannotatedBound instanceof ParameterizedTypeBinding;
+ TypeBinding[] derivedTypes = this.types[useDerivedTypesOfBound ? unannotatedBound.id :unannotatedGenericType.id]; // by construction, cachedInfo != null now.
+
int i, length = derivedTypes.length;
for (i = 0; i < length; i++) {
TypeBinding derivedType = derivedTypes[i];
@@ -358,7 +400,7 @@ public class TypeSystem {
if (i == length) {
System.arraycopy(derivedTypes, 0, derivedTypes = new TypeBinding[length * 2], 0, length);
- this.types[unannotatedGenericType.id] = derivedTypes;
+ this.types[useDerivedTypesOfBound ? unannotatedBound.id :unannotatedGenericType.id] = derivedTypes;
}
TypeBinding wildcard = derivedTypes[i] = new WildcardBinding(unannotatedGenericType, rank, unannotatedBound, unannotatedOtherBounds, boundKind, this.environment);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
index 9695895d15..734cccbe04 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/NameLookup.java
@@ -1153,9 +1153,10 @@ public class NameLookup implements SuffixConstants {
private void seekModuleAwarePartialPackageFragments(String name, IJavaElementRequestor requestor, IPackageFragmentRoot[] moduleContext) {
boolean allPrefixMatch = CharOperation.equals(name.toCharArray(), CharOperation.ALL_PREFIX);
+ String lName = name.toLowerCase();
Arrays.stream(this.packageFragments.keyTable)
.filter(k -> k != null)
- .filter(k -> allPrefixMatch || Util.concatWith((String[])k, '.').startsWith(name))
+ .filter(k -> allPrefixMatch || Util.concatWith((String[])k, '.').toLowerCase().startsWith(lName))
.forEach(k -> {
checkModulePackages(requestor, moduleContext, this.packageFragments.getIndex(k));
});
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 2b30b8e7df..37446db8fb 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
@@ -14,9 +14,10 @@ package org.eclipse.jdt.internal.core;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
-
+import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
@@ -31,6 +32,8 @@ import org.eclipse.jdt.internal.compiler.env.AccessRestriction;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import org.eclipse.jdt.internal.compiler.env.IModule;
+import org.eclipse.jdt.internal.compiler.env.IModule.IModuleReference;
+import org.eclipse.jdt.internal.compiler.env.IModule.IPackageExport;
import org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment;
import org.eclipse.jdt.internal.compiler.env.ISourceType;
import org.eclipse.jdt.internal.compiler.env.IUpdatableModule;
@@ -233,12 +236,59 @@ public class SearchableEnvironment
* The packages found are passed to:
* ISearchRequestor.acceptPackage(char[][] packageName)
*/
- public void findPackages(char[] prefix, ISearchRequestor requestor, IPackageFragmentRoot[] moduleContext) {
+ public void findPackages(char[] prefix, ISearchRequestor requestor, IPackageFragmentRoot[] moduleContext, boolean followRequires) {
this.nameLookup.seekPackageFragments(
new String(prefix),
true,
new SearchableEnvironmentRequestor(requestor), moduleContext);
+ if (followRequires && this.knownModuleLocations != null) {
+ try {
+ boolean isMatchAllPrefix = CharOperation.equals(CharOperation.ALL_PREFIX, prefix);
+ Set<IModuleDescription> modDescs = new HashSet<>();
+ for (IPackageFragmentRoot root : moduleContext) {
+ IModuleDescription desc = root.getJavaProject().getModuleDescription();
+ if (desc instanceof AbstractModule)
+ modDescs.add(desc);
+ }
+ for (IModuleDescription md : modDescs) {
+ IModuleReference[] reqModules = ((AbstractModule) md).getRequiredModules();
+ char[] modName = md.getElementName().toCharArray();
+ for (IModuleReference moduleReference : reqModules) {
+ findPackagesFromRequires(prefix, isMatchAllPrefix, requestor, moduleReference, modName);
+ }
+ }
+ } catch (JavaModelException e) {
+ // silent
+ }
+ }
+}
+
+private void findPackagesFromRequires(char[] prefix, boolean isMatchAllPrefix, ISearchRequestor requestor, IModuleReference moduleReference, char[] clientModuleName) {
+ IPackageFragmentRoot[] fragmentRoots = findModuleContext(moduleReference.name());
+ if (fragmentRoots == null) return;
+ for (IPackageFragmentRoot root : fragmentRoots) {
+ IJavaProject requiredProject = root.getJavaProject();
+ try {
+ IModuleDescription module = requiredProject.getModuleDescription();
+ if (module instanceof AbstractModule) {
+ AbstractModule requiredModule = (AbstractModule) module;
+ for (IPackageExport packageExport : requiredModule.getExportedPackages()) {
+ if (!packageExport.isQualified() || CharOperation.containsEqual(packageExport.targets(), clientModuleName)) {
+ char[] exportName = packageExport.name();
+ if (isMatchAllPrefix || CharOperation.prefixEquals(prefix, exportName))
+ requestor.acceptPackage(exportName);
+ }
+ }
+ for (IModuleReference moduleRef2 : requiredModule.getRequiredModules()) {
+ if (moduleRef2.isTransitive())
+ findPackagesFromRequires(prefix, isMatchAllPrefix, requestor, moduleRef2, clientModuleName);
+ }
+ }
+ } catch (JavaModelException e) {
+ // silent
+ }
}
+}
/**
* Find the top-level types that are defined
* in the current environment and whose simple name matches the given name.

Back to the top