fix(language-service): only visit directives (#34564)

PR Close #34564
This commit is contained in:
ivanwonder 2020-01-04 22:20:46 +08:00 committed by atscott
parent c8c6fd7153
commit 6f916c1240

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {AST, Attribute, BoundDirectivePropertyAst, BoundEventAst, CompileTypeSummary, CssSelector, DirectiveAst, ElementAst, RecursiveTemplateAstVisitor, SelectorMatcher, TemplateAst, TemplateAstPath, templateVisitAll, tokenReference} from '@angular/compiler'; import {AST, Attribute, BoundDirectivePropertyAst, BoundEventAst, CompileTypeSummary, CssSelector, DirectiveAst, ElementAst, EmbeddedTemplateAst, RecursiveTemplateAstVisitor, SelectorMatcher, TemplateAst, TemplateAstPath, templateVisitAll, tokenReference} from '@angular/compiler';
import {AstResult} from './common'; import {AstResult} from './common';
import {getExpressionScope} from './expression_diagnostics'; import {getExpressionScope} from './expression_diagnostics';
@ -130,7 +130,7 @@ export function locateSymbol(info: AstResult, position: number): SymbolInfo|unde
}, },
visitDirectiveProperty(ast) { visitDirectiveProperty(ast) {
if (!attributeValueSymbol(ast.value)) { if (!attributeValueSymbol(ast.value)) {
symbol = findInputBinding(info, path, ast); symbol = findInputBinding(info, templatePosition, ast);
span = spanOf(ast); span = spanOf(ast);
} }
} }
@ -148,13 +148,37 @@ function findAttribute(info: AstResult, position: number): Attribute|undefined {
return path.first(Attribute); return path.first(Attribute);
} }
function findParentOfBinding(ast: TemplateAst[], binding: BoundDirectivePropertyAst) { function findParentOfBinding(
ast: TemplateAst[], binding: BoundDirectivePropertyAst, position: number) {
let res: DirectiveAst|undefined; let res: DirectiveAst|undefined;
const visitor = new class extends RecursiveTemplateAstVisitor { const visitor = new class extends RecursiveTemplateAstVisitor {
visit(ast: TemplateAst): any {
let span = spanOf(ast);
if (!inSpan(position, span)) {
// Returning a value here will result in the children being skipped.
return true;
}
}
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any {
return this.visitChildren(context, visit => {
visit(ast.directives);
visit(ast.children);
});
}
visitElement(ast: ElementAst, context: any): any {
return this.visitChildren(context, visit => {
visit(ast.directives);
visit(ast.children);
});
}
visitDirective(ast: DirectiveAst) { visitDirective(ast: DirectiveAst) {
const result = this.visitChildren(ast, visit => { visit(ast.inputs); }); const result = this.visitChildren(ast, visit => { visit(ast.inputs); });
return result; return result;
} }
visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: DirectiveAst) { visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: DirectiveAst) {
if (ast === binding) { if (ast === binding) {
res = context; res = context;
@ -166,8 +190,8 @@ function findParentOfBinding(ast: TemplateAst[], binding: BoundDirectiveProperty
} }
function findInputBinding( function findInputBinding(
info: AstResult, path: TemplateAstPath, binding: BoundDirectivePropertyAst): Symbol|undefined { info: AstResult, position: number, binding: BoundDirectivePropertyAst): Symbol|undefined {
const directiveAst = findParentOfBinding(info.templateAst, binding); const directiveAst = findParentOfBinding(info.templateAst, binding, position);
if (directiveAst) { if (directiveAst) {
const invertedInput = invertMap(directiveAst.directive.inputs); const invertedInput = invertMap(directiveAst.directive.inputs);
const fieldName = invertedInput[binding.templateName]; const fieldName = invertedInput[binding.templateName];