|
121 | 121 | import org.eclipse.jdt.core.dom.TagElement; |
122 | 122 | import org.eclipse.jdt.core.dom.TextBlock; |
123 | 123 | import org.eclipse.jdt.core.dom.TextElement; |
| 124 | +import org.eclipse.jdt.core.dom.ThisExpression; |
124 | 125 | import org.eclipse.jdt.core.dom.Type; |
125 | 126 | import org.eclipse.jdt.core.dom.TypeDeclaration; |
126 | 127 | import org.eclipse.jdt.core.dom.TypePattern; |
@@ -181,6 +182,7 @@ public class DOMCompletionEngine implements ICompletionEngine { |
181 | 182 | private ExpectedTypes expectedTypes; |
182 | 183 | private String prefix; |
183 | 184 | private String qualifiedPrefix; |
| 185 | + private ITypeBinding qualifyingType; |
184 | 186 | private ASTNode toComplete; |
185 | 187 | private String textContent; |
186 | 188 |
|
@@ -543,6 +545,10 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour |
543 | 545 | } |
544 | 546 | this.qualifiedPrefix = packageName; |
545 | 547 | } |
| 548 | + } else if (this.toComplete instanceof ThisExpression thisExpression) { |
| 549 | + if (thisExpression.getQualifier() != null) { |
| 550 | + this.qualifiedPrefix = thisExpression.getQualifier().toString(); |
| 551 | + } |
546 | 552 | } |
547 | 553 | // some flags to controls different applicable completion search strategies |
548 | 554 | boolean suggestDefaultCompletions = true; |
@@ -1399,6 +1405,26 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour |
1399 | 1405 | } |
1400 | 1406 | suggestDefaultCompletions = false; |
1401 | 1407 | } |
| 1408 | + if (context instanceof ThisExpression thisExpression) { |
| 1409 | + if (thisExpression.getQualifier() != null) { |
| 1410 | + IBinding binding = thisExpression.getQualifier().resolveBinding(); |
| 1411 | + if (binding instanceof ITypeBinding typeBinding) { |
| 1412 | + this.qualifyingType = typeBinding; |
| 1413 | + Bindings typesMembers = new Bindings(); |
| 1414 | + processMembers(this.toComplete, typeBinding, typesMembers, true); |
| 1415 | + publishFromScope(typesMembers); |
| 1416 | + this.requestor.accept(createClassKeywordProposal(typeBinding, -1,-1)); |
| 1417 | + } |
| 1418 | + for (char[] keyword : List.of(Keywords.SUPER, Keywords.THIS)) { |
| 1419 | + if (!isFailedMatch(this.prefix.toCharArray(), keyword)) { |
| 1420 | + CompletionProposal res = createKeywordProposal(keyword, -1, -1); |
| 1421 | + res.setRelevance(res.getRelevance() + RelevanceConstants.R_NON_INHERITED); |
| 1422 | + this.requestor.accept(res); |
| 1423 | + } |
| 1424 | + } |
| 1425 | + suggestDefaultCompletions = false; |
| 1426 | + } |
| 1427 | + } |
1402 | 1428 | if (context != null && context.getLocationInParent() == QualifiedType.NAME_PROPERTY && context.getParent() instanceof QualifiedType qType) { |
1403 | 1429 | Type qualifier = qType.getQualifier(); |
1404 | 1430 | if (qualifier != null) { |
@@ -2652,6 +2678,7 @@ private CompletionProposal toProposal(IBinding binding, String completion) { |
2652 | 2678 | this.toComplete.getAST().resolveWellKnownType(Object.class.getName()), this.expectedTypes) + |
2653 | 2679 | (isInQualifiedName || res.getRequiredProposals() != null || inJavadoc ? 0 : RelevanceUtils.computeRelevanceForQualification(false, this.prefix, this.qualifiedPrefix)) + |
2654 | 2680 | RelevanceConstants.R_NON_RESTRICTED + |
| 2681 | + RelevanceUtils.computeRelevanceForInheritance(this.qualifyingType, binding) + |
2655 | 2682 | ((insideQualifiedReference() && !staticOnly() && !Modifier.isStatic(binding.getModifiers())) || (inJavadoc && !res.isConstructor()) ? RelevanceConstants.R_NON_STATIC : 0) + |
2656 | 2683 | (!staticOnly() || inheritedValue ? 0 : RelevanceConstants.R_NON_INHERITED) + // TODO: when is this active? |
2657 | 2684 | (binding instanceof IVariableBinding field && field.isEnumConstant() ? RelevanceConstants.R_ENUM + RelevanceConstants.R_ENUM_CONSTANT : 0) |
@@ -2756,6 +2783,10 @@ private CompletionProposal toProposal(IType type) { |
2756 | 2783 | res.setReplaceRange(this.offset, this.offset); |
2757 | 2784 | } else if (this.toComplete instanceof SimpleName) { |
2758 | 2785 | res.setReplaceRange(this.toComplete.getStartPosition(), this.toComplete.getStartPosition() + this.toComplete.getLength()); |
| 2786 | + } else if (this.toComplete instanceof ThisExpression thisExpression |
| 2787 | + && thisExpression.getQualifier() != null |
| 2788 | + && this.offset > (thisExpression.getQualifier().getStartPosition() + thisExpression.getQualifier().getLength())) { |
| 2789 | + setRange(res); |
2759 | 2790 | } else { |
2760 | 2791 | res.setReplaceRange(this.toComplete.getStartPosition(), this.offset); |
2761 | 2792 | } |
@@ -2792,6 +2823,7 @@ private CompletionProposal toProposal(IType type) { |
2792 | 2823 | + RelevanceConstants.R_RESOLVED |
2793 | 2824 | + RelevanceConstants.R_INTERESTING |
2794 | 2825 | + RelevanceConstants.R_NON_RESTRICTED |
| 2826 | + + RelevanceUtils.computeRelevanceForInheritance(this.qualifyingType, type) |
2795 | 2827 | + RelevanceUtils.computeRelevanceForQualification(!type.getFullyQualifiedName().startsWith("java.") && !nodeInImports && !fromCurrentCU && !inSamePackage && !typeIsImported, this.prefix, this.qualifiedPrefix) |
2796 | 2828 | + (type.getFullyQualifiedName().startsWith("java.") ? RelevanceConstants.R_JAVA_LIBRARY : 0) |
2797 | 2829 | + (expectedTypes.getExpectedTypes().stream().map(ITypeBinding::getQualifiedName).anyMatch(type.getFullyQualifiedName()::equals) ? RelevanceConstants.R_EXACT_EXPECTED_TYPE : |
@@ -3511,13 +3543,21 @@ private CompletionProposal createClassKeywordProposal(ITypeBinding typeBinding, |
3511 | 3543 | + RelevanceConstants.R_RESOLVED |
3512 | 3544 | + RelevanceConstants.R_INTERESTING |
3513 | 3545 | + RelevanceConstants.R_NON_RESTRICTED |
3514 | | - + RelevanceConstants.R_EXPECTED_TYPE; |
3515 | | - if (!isFailedMatch(this.prefix.toCharArray(), Keywords.CLASS)) { |
3516 | | - relevance += RelevanceConstants.R_SUBSTRING; |
3517 | | - } |
| 3546 | + + RelevanceConstants.R_NON_INHERITED |
| 3547 | + + RelevanceUtils.computeRelevanceForCaseMatching(this.prefix.toCharArray(), Keywords.CLASS, assistOptions) |
| 3548 | +// + RelevanceUtils.computeRelevanceForExpectingType(typeBinding, this.expectedTypes) |
| 3549 | + ; |
| 3550 | + |
3518 | 3551 | DOMInternalCompletionProposal keywordProposal = createProposal(CompletionProposal.FIELD_REF); |
3519 | 3552 | keywordProposal.setCompletion(Keywords.CLASS); |
3520 | | - keywordProposal.setReplaceRange(startPos, endPos); |
| 3553 | + |
| 3554 | + if (startPos == -1 && endPos == -1) { |
| 3555 | + setRange(keywordProposal); |
| 3556 | + } else { |
| 3557 | + keywordProposal.setReplaceRange(startPos, endPos); |
| 3558 | + keywordProposal.setTokenRange(startPos, endPos); |
| 3559 | + } |
| 3560 | + |
3521 | 3561 | keywordProposal.setRelevance(relevance); |
3522 | 3562 | keywordProposal.setPackageName(CharOperation.concatWith(TypeConstants.JAVA_LANG, '.')); |
3523 | 3563 | keywordProposal.setTypeName("Class".toCharArray()); //$NON-NLS-1$ |
|
0 commit comments