|
30 | 30 | import org.eclipse.jdt.core.search.TypeNameMatchRequestor; |
31 | 31 | import org.eclipse.jdt.internal.codeassist.impl.AssistOptions; |
32 | 32 | import org.eclipse.jdt.internal.codeassist.impl.Keywords; |
| 33 | +import org.eclipse.jdt.internal.compiler.env.AccessRestriction; |
33 | 34 | import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; |
34 | 35 | import org.eclipse.jdt.internal.compiler.parser.RecoveryScanner; |
35 | 36 | import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; |
|
40 | 41 | import org.eclipse.jdt.internal.core.SearchableEnvironment; |
41 | 42 | import org.eclipse.jdt.internal.core.SourceType; |
42 | 43 | import org.eclipse.jdt.internal.core.util.Messages; |
| 44 | +import org.eclipse.jdt.internal.core.util.Util; |
43 | 45 |
|
44 | 46 | /** |
45 | 47 | * A completion engine using a DOM as input (as opposed to {@link CompletionEngine} which |
@@ -210,7 +212,6 @@ public void run() { |
210 | 212 | // var completionContext = new DOMCompletionContext(this.offset, completeAfter.toCharArray(), |
211 | 213 | // computeEnclosingElement(), defaultCompletionBindings::stream, expectedTypes, this.toComplete); |
212 | 214 | var completionContext = new DOMCompletionContext(this.unit, this.modelUnit, this.cuBuffer, this.offset, this.assistOptions, defaultCompletionBindings); |
213 | | - this.nestedEngine.completionToken = completionContext.getToken(); |
214 | 215 | this.requestor.acceptContext(completionContext); |
215 | 216 |
|
216 | 217 | this.expectedTypes = completionContext.expectedTypes; |
@@ -1078,9 +1079,6 @@ public void run() { |
1078 | 1079 | // currently, this is always run, even when not using the default completion, |
1079 | 1080 | // because method argument guessing uses it. |
1080 | 1081 | scrapeAccessibleBindings(defaultCompletionBindings); |
1081 | | - if (shouldSuggestPackages(toComplete)) { |
1082 | | - suggestPackages(toComplete); |
1083 | | - } |
1084 | 1082 | if (context instanceof SimpleName simple && !(simple.getParent() instanceof Name)) { |
1085 | 1083 | for (ImportDeclaration importDecl : (List<ImportDeclaration>)this.unit.imports()) { |
1086 | 1084 | if (importDecl.isStatic()) { |
@@ -1484,10 +1482,75 @@ private void suggestPackages(ASTNode context) { |
1484 | 1482 | } |
1485 | 1483 | String prefix = context instanceof Name name ? name.toString() : this.prefix; |
1486 | 1484 | if (prefix != null && !prefix.isBlank()) { |
1487 | | - this.nameEnvironment.findPackages(prefix.toCharArray(), this.nestedEngine); |
| 1485 | + Set<String> packageNames = new HashSet<>(); |
| 1486 | + this.nameEnvironment.findPackages(prefix.toCharArray(), new ISearchRequestor() { |
| 1487 | + |
| 1488 | + @Override |
| 1489 | + public void acceptConstructor(int modifiers, char[] simpleTypeName, int parameterCount, |
| 1490 | + char[] signature, char[][] parameterTypes, char[][] parameterNames, int typeModifiers, |
| 1491 | + char[] packageName, int extraFlags, String path, AccessRestriction access) { |
| 1492 | + // do nothing |
| 1493 | + } |
| 1494 | + |
| 1495 | + @Override |
| 1496 | + public void acceptType(char[] packageName, char[] typeName, char[][] enclosingTypeNames, int modifiers, |
| 1497 | + AccessRestriction accessRestriction) { |
| 1498 | + // do nothing |
| 1499 | + } |
| 1500 | + |
| 1501 | + @Override |
| 1502 | + public void acceptPackage(char[] packageName) { |
| 1503 | + String packageNameString = new String(packageName); |
| 1504 | + // TODO: CompletionEngine has a caching mechanism for this |
| 1505 | + if (isValidPackageName(packageNameString)) { |
| 1506 | + packageNames.add(new String(packageName)); |
| 1507 | + } |
| 1508 | + } |
| 1509 | + |
| 1510 | + @Override |
| 1511 | + public void acceptModule(char[] moduleName) { |
| 1512 | + // do nothing |
| 1513 | + } |
| 1514 | + |
| 1515 | + }); |
| 1516 | + for (String packageName : packageNames) { |
| 1517 | + this.requestor.accept(toPackageProposal(packageName, context)); |
| 1518 | + } |
1488 | 1519 | } |
1489 | 1520 | } |
1490 | 1521 |
|
| 1522 | + private boolean isValidPackageName(String packageName) { |
| 1523 | + String[] names = packageName.split("\\."); //$NON-NLS-1$ |
| 1524 | + for (String name : names) { |
| 1525 | + if (!Util.isValidFolderNameForPackage( |
| 1526 | + name, |
| 1527 | + this.modelUnit.getJavaProject().getOption(JavaCore.COMPILER_SOURCE, true), |
| 1528 | + this.modelUnit.getJavaProject().getOption(JavaCore.COMPILER_COMPLIANCE, true))) { |
| 1529 | + return false; |
| 1530 | + } |
| 1531 | + } |
| 1532 | + return true; |
| 1533 | + } |
| 1534 | + |
| 1535 | + private CompletionProposal toPackageProposal(String packageName, ASTNode completing) { |
| 1536 | + InternalCompletionProposal res = createProposal(CompletionProposal.PACKAGE_REF); |
| 1537 | + res.setCompletion(packageName.toCharArray()); |
| 1538 | + res.setDeclarationSignature(packageName.toCharArray()); |
| 1539 | + res.setPackageName(packageName.toCharArray()); |
| 1540 | + QualifiedName qualifiedName = (QualifiedName)DOMCompletionUtil.findParent(completing, new int[] {ASTNode.QUALIFIED_NAME}); |
| 1541 | + int relevance = RelevanceConstants.R_DEFAULT |
| 1542 | + + RelevanceConstants.R_RESOLVED |
| 1543 | + + RelevanceConstants.R_INTERESTING |
| 1544 | + + computeRelevanceForCaseMatching(this.qualifiedPrefix.toCharArray(), packageName.toCharArray(), this.assistOptions) |
| 1545 | + + computeRelevanceForQualification(true) |
| 1546 | + + RelevanceConstants.R_NON_RESTRICTED; |
| 1547 | + res.setRelevance(relevance); |
| 1548 | + if (qualifiedName != null) { |
| 1549 | + res.setReplaceRange(qualifiedName.getStartPosition(), this.offset); |
| 1550 | + } |
| 1551 | + return res; |
| 1552 | + } |
| 1553 | + |
1491 | 1554 | private void suggestTypesInPackage(String packageName) { |
1492 | 1555 | if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { |
1493 | 1556 | List<IType> foundTypes = findTypes(this.prefix, packageName).toList(); |
|
0 commit comments