message: fix(language-service): only visit directives
  PR Close
diff: * 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 {getExpressionScope} from './expression_diagnostics';
  @@ -130,7 +130,7 @@ export function locateSymbol(info: AstResult, position: number): SymbolInfo|unde
  },
  visitDirectiveProperty(ast) {
  if (!attributeValueSymbol(ast.value)) {
  - symbol = findInputBinding(info, path, ast);
  + symbol = findInputBinding(info, templatePosition, ast);
  span = spanOf(ast);
  }
  }
  @@ -148,13 +148,37 @@ function findAttribute(info: AstResult, position: number): Attribute|undefined {
  return path.first(Attribute);
  }
  -function findParentOfBinding(ast: TemplateAst[], binding: BoundDirectivePropertyAst) {
  +function findParentOfBinding(
  + ast: TemplateAst[], binding: BoundDirectivePropertyAst, position: number) {
  let res: DirectiveAst|undefined;
  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) {
  const result = this.visitChildren(ast, visit => { visit(ast.inputs); });
  return result;
  }
  +
  visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: DirectiveAst) {
  if (ast === binding) {
  res = context;
  @@ -166,8 +190,8 @@ function findParentOfBinding(ast: TemplateAst[], binding: BoundDirectiveProperty
  }
  function findInputBinding(
  - info: AstResult, path: TemplateAstPath, binding: BoundDirectivePropertyAst): Symbol|undefined {
  - const directiveAst = findParentOfBinding(info.templateAst, binding);
  + info: AstResult, position: number, binding: BoundDirectivePropertyAst): Symbol|undefined {
  + const directiveAst = findParentOfBinding(info.templateAst, binding, position);
  if (directiveAst) {
  const invertedInput = invertMap(directiveAst.directive.inputs);
  const fieldName = invertedInput[binding.templateName];
  