fix(language-service): Diagnostic span should point to class name (#34932)

Right now, if an Angular diagnostic is generated for a TypeScript node,
the span points to the decorator Identifier, i.e. the Identifier node
like `@NgModule`, `@Component`, etc.
This is weird. It should point to the class name instead.
Note, we do not have a more fine-grained breakdown of the span when
diagnostics are emitted, this work remains to be done.

PR Close #34932
This commit is contained in:
Keen Yee Liau
2020-01-23 12:02:47 -08:00
committed by Andrew Kushnir
parent b50ed5c22c
commit 0223aa6121
4 changed files with 18 additions and 24 deletions

View File

@ -288,9 +288,9 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
const visit = (child: tss.Node) => {
const candidate = getDirectiveClassLike(child);
if (candidate) {
const {decoratorId, classDecl} = candidate;
const declarationSpan = spanOf(decoratorId);
const className = classDecl.name !.text;
const {classId} = candidate;
const declarationSpan = spanOf(classId);
const className = classId.getText();
const classSymbol = this.reflector.getStaticSymbol(sourceFile.fileName, className);
// Ask the resolver to check if candidate is actually Angular directive
if (!this.resolver.isDirective(classSymbol)) {

View File

@ -164,8 +164,8 @@ export function findTightestNode(node: ts.Node, position: number): ts.Node|undef
}
interface DirectiveClassLike {
decoratorId: ts.Identifier; // decorator identifier
classDecl: ts.ClassDeclaration;
decoratorId: ts.Identifier; // decorator identifier, like @Component
classId: ts.Identifier;
}
/**
@ -178,11 +178,11 @@ interface DirectiveClassLike {
*
* For example,
* v---------- `decoratorId`
* @NgModule({
* declarations: [],
* })
* class AppModule {}
* ^----- `classDecl`
* @NgModule({ <
* declarations: [], < classDecl
* }) <
* class AppModule {} <
* ^----- `classId`
*
* @param node Potential node that represents an Angular directive.
*/
@ -200,7 +200,7 @@ export function getDirectiveClassLike(node: ts.Node): DirectiveClassLike|undefin
if (ts.isObjectLiteralExpression(arg)) {
return {
decoratorId: expr.expression,
classDecl: node,
classId: node.name,
};
}
}