fix(language-service): fix autocomplete info display for some cases (#42472)

Before this commit, attribute completion display parts were retrieved
but not assigned. In addition, the switch case was non-exhaustive
because it did not include `StructuralDirectiveAttribute`.

PR Close #42472
This commit is contained in:
Andrew Scott 2021-06-03 15:15:16 -07:00 committed by Jessica Janiuk
parent f85a120b7b
commit a493ea9bcb
3 changed files with 20 additions and 6 deletions

View File

@ -579,6 +579,7 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
displayParts = info.displayParts;
documentation = info.documentation;
break;
case AttributeCompletionKind.StructuralDirectiveAttribute:
case AttributeCompletionKind.DirectiveInput:
case AttributeCompletionKind.DirectiveOutput:
const propertySymbol = getAttributeCompletionSymbol(completion, this.typeChecker);
@ -586,11 +587,17 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
return undefined;
}
let kind: DisplayInfoKind;
if (completion.kind === AttributeCompletionKind.DirectiveInput) {
kind = DisplayInfoKind.PROPERTY;
} else if (completion.kind === AttributeCompletionKind.DirectiveOutput) {
kind = DisplayInfoKind.EVENT;
} else {
kind = DisplayInfoKind.DIRECTIVE;
}
info = getTsSymbolDisplayInfo(
this.tsLS, this.typeChecker, propertySymbol,
completion.kind === AttributeCompletionKind.DirectiveInput ? DisplayInfoKind.PROPERTY :
DisplayInfoKind.EVENT,
completion.directive.tsSymbol.name);
this.tsLS, this.typeChecker, propertySymbol, kind, completion.directive.tsSymbol.name);
if (info === null) {
return undefined;
}
@ -602,7 +609,7 @@ export class CompletionBuilder<N extends TmplAstNode|AST> {
name: entryName,
kind: unsafeCastDisplayInfoKindToScriptElementKind(kind),
kindModifiers: ts.ScriptElementKindModifier.none,
displayParts: [],
displayParts,
documentation,
};
}

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {isNamedClassDeclaration} from '@angular/compiler-cli/src/ngtsc/reflection';
import {DirectiveInScope, ReferenceSymbol, ShimLocation, Symbol, SymbolKind, VariableSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
import * as ts from 'typescript';
@ -155,7 +156,9 @@ export function getTsSymbolDisplayInfo(
tsLS: ts.LanguageService, checker: ts.TypeChecker, symbol: ts.Symbol, kind: DisplayInfoKind,
ownerName: string|null): DisplayInfo|null {
const decl = symbol.valueDeclaration;
if (decl === undefined || (!ts.isPropertyDeclaration(decl) && !ts.isMethodDeclaration(decl)) ||
if (decl === undefined ||
(!ts.isPropertyDeclaration(decl) && !ts.isMethodDeclaration(decl) &&
!isNamedClassDeclaration(decl)) ||
!ts.isIdentifier(decl.name)) {
return null;
}

View File

@ -586,6 +586,10 @@ describe('completions', () => {
unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.DIRECTIVE),
['ngFor']);
expectReplacementText(completions, templateFile.contents, 'ng');
const details = templateFile.getCompletionEntryDetails(
'ngFor', /* formatOptions */ undefined,
/* preferences */ undefined)!;
expect(toText(details.displayParts)).toEqual('(directive) NgFor.NgFor: NgFor');
});
it('should return structural directive completions for just the structural marker', () => {