6262import org .eclipse .jdt .core .dom .AST ;
6363import org .eclipse .jdt .core .dom .ASTNode ;
6464import org .eclipse .jdt .core .dom .ASTParser ;
65+ import org .eclipse .jdt .core .dom .ASTVisitor ;
6566import org .eclipse .jdt .core .dom .AbstractTypeDeclaration ;
6667import org .eclipse .jdt .core .dom .Annotation ;
6768import org .eclipse .jdt .core .dom .AnnotationTypeMemberDeclaration ;
@@ -996,7 +997,7 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
996997 }
997998 } else if (qualifiedNameBinding instanceof IVariableBinding variableBinding ) {
998999 ITypeBinding typeBinding = variableBinding .getType ();
999- if (typeBinding == null && unit .findDeclaringNode (variableBinding ) instanceof VariableDeclaration decl ) {
1000+ if (( typeBinding == null || typeBinding . isRecovered ()) && unit .findDeclaringNode (variableBinding ) instanceof VariableDeclaration decl ) {
10001001 Type type = null ;
10011002 if (decl instanceof SingleVariableDeclaration single ) {
10021003 type = single .getType ();
@@ -1577,24 +1578,66 @@ private boolean isTypeInVariableDeclaration(ASTNode context) {
15771578 }
15781579
15791580 private void completeMissingType (Type type ) throws JavaModelException {
1580- if (type instanceof ParameterizedType parameterized ) {
1581- type = parameterized .getType ();
1582- }
1583- final Type finalType = type ;
1581+ Type simpleType = type instanceof ParameterizedType parameterized ?
1582+ parameterized .getType () : type ;
15841583 var scope = SearchEngine .createJavaSearchScope (new IJavaElement [] { this .javaProject });
1585- new SearchEngine (this .workingCopyOwner ).searchAllTypeNames (null , SearchPattern .R_PREFIX_MATCH , type .toString ().toCharArray (), SearchPattern .R_EXACT_MATCH , IJavaSearchConstants .TYPE , scope , new TypeNameMatchRequestor () {
1584+ SearchEngine searchEngine = new SearchEngine (this .workingCopyOwner );
1585+ List <IType > types = new ArrayList <>();
1586+ searchEngine .searchAllTypeNames (null , SearchPattern .R_PREFIX_MATCH , simpleType .toString ().toCharArray (), SearchPattern .R_EXACT_MATCH , IJavaSearchConstants .TYPE , scope , new TypeNameMatchRequestor () {
15861587 @ Override
15871588 public void acceptTypeNameMatch (TypeNameMatch match ) {
1588- processMembers (match .getType ()).stream ()
1589- .map (member -> {
1590- CompletionProposal typeProposal = toProposal (match .getType ());
1591- typeProposal .setReplaceRange (finalType .getStartPosition (), finalType .getStartPosition () + finalType .getLength ());
1592- typeProposal .setRelevance (member .getRelevance ());
1593- member .setRequiredProposals (new CompletionProposal [] { typeProposal });
1594- return member ;
1595- }).forEach (DOMCompletionEngine .this .requestor ::accept );
1589+ types .add (match .getType ());
15961590 }
15971591 }, IJavaSearchConstants .WAIT_UNTIL_READY_TO_SEARCH , monitor );
1592+ StringBuilder builder = new StringBuilder ();
1593+ if (type instanceof ParameterizedType parameterized ) {
1594+ builder .append (Signature .C_GENERIC_START );
1595+ for (Type typeParam : (List <Type >)parameterized .typeArguments ()) {
1596+ builder .append (SignatureUtils .createSignature (typeParam , searchEngine , scope , monitor ));
1597+ }
1598+ builder .append (Signature .C_GENERIC_END );
1599+ }
1600+ for (IType matchedType : types ) {
1601+ processMembers (matchedType )
1602+ .map (member -> {
1603+ StringBuilder declaringSignature = new StringBuilder ();
1604+ declaringSignature .append (member .getDeclarationSignature ());
1605+ declaringSignature .deleteCharAt (declaringSignature .length () - 1 ); // `;`
1606+ declaringSignature .append (builder );
1607+ declaringSignature .append (';' );
1608+ member .setDeclarationSignature (declaringSignature .toString ().toCharArray ());
1609+ CompletionProposal typeProposal = toProposal (matchedType );
1610+ typeProposal .setReplaceRange (simpleType .getStartPosition (), simpleType .getStartPosition () + simpleType .getLength ());
1611+ typeProposal .setRelevance (member .getRelevance ());
1612+ type .accept (new ASTVisitor () {
1613+ @ Override
1614+ public boolean visit (SimpleType simpleType ) {
1615+ ITypeBinding binding = simpleType .resolveBinding ();
1616+ if (binding == null || binding .isRecovered ()) {
1617+ List <IType > matchingITypes = new ArrayList <>();
1618+ try {
1619+ searchEngine .searchAllTypeNames (null , SearchPattern .R_PREFIX_MATCH , simpleType .toString ().toCharArray (), SearchPattern .R_EXACT_MATCH , IJavaSearchConstants .TYPE , scope , new TypeNameMatchRequestor () {
1620+ @ Override
1621+ public void acceptTypeNameMatch (TypeNameMatch match ) {
1622+ matchingITypes .add (match .getType ());
1623+ }
1624+ }, IJavaSearchConstants .WAIT_UNTIL_READY_TO_SEARCH , monitor );
1625+ } catch (JavaModelException ex ) {
1626+ ILog .get ().error (ex .getMessage (), ex );
1627+ }
1628+ if (matchingITypes .size () == 1 ) {
1629+ CompletionProposal typeProposal = toProposal (matchingITypes .get (0 ));
1630+ typeProposal .setReplaceRange (simpleType .getStartPosition (), simpleType .getStartPosition () + simpleType .getLength ());
1631+ typeProposal .setRelevance (member .getRelevance ());
1632+ }
1633+ }
1634+ return true ;
1635+ }
1636+ });
1637+ member .setRequiredProposals (new CompletionProposal [] { typeProposal });
1638+ return member ;
1639+ }).forEach (DOMCompletionEngine .this .requestor ::accept );
1640+ }
15981641 }
15991642
16001643 private void suggestSuperConstructors () {
@@ -2493,7 +2536,7 @@ private void processMembers(ITypeBinding typeBinding, Bindings scope,
24932536 }
24942537 }
24952538
2496- private List <CompletionProposal > processMembers (IType type ) {
2539+ private Stream <CompletionProposal > processMembers (IType type ) {
24972540 IJavaElement [] children ;
24982541 try {
24992542 children = type .getChildren ();
@@ -2504,8 +2547,7 @@ private List<CompletionProposal> processMembers(IType type) {
25042547 return Arrays .stream (children )
25052548 .filter (element -> element .getElementType () == IJavaElement .FIELD || element .getElementType () == IJavaElement .METHOD )
25062549 .filter (this ::isVisible )
2507- .map (this ::toProposal )
2508- .toList ();
2550+ .map (this ::toProposal );
25092551 }
25102552
25112553 private String getSignature (IMethodBinding method ) {
0 commit comments