From b2758d781b30fbfbb37dba27a21202c0920626b4 Mon Sep 17 00:00:00 2001 From: JoostK Date: Sat, 26 Mar 2022 22:10:33 +0100 Subject: [PATCH] refactor(compiler-cli): rename `ShimLocation` to `TcbLocation` (#45454) Inline type check blocks (TCBs) are emitted into the original source file, but node positions would still be represented as a `ShimLocation` with a `shimPath` corresponding with the type-checking shim file. This results in inconsistencies, as the `positionInShimFile` field of `ShimLocation` would not correspond with the `shimPath` of that `ShimLocation`. This commit is a precursor to letting `ShimLocation` also represent the correct location for inline type check blocks, by renaming the interface to `TcbLocation`. A followup commit addresses the actual inconsistency. PR Close #45454 --- .../src/ngtsc/typecheck/api/checker.ts | 12 +++--- .../src/ngtsc/typecheck/api/completion.ts | 6 +-- .../src/ngtsc/typecheck/api/symbols.ts | 35 ++++++++-------- .../nullish_coalescing_not_nullable/index.ts | 3 +- .../src/ngtsc/typecheck/src/checker.ts | 16 ++++---- .../src/ngtsc/typecheck/src/completion.ts | 38 +++++++++--------- .../typecheck/src/template_symbol_builder.ts | 30 +++++++------- .../test/type_checker__completion_spec.ts | 8 ++-- ...ecker__get_symbol_of_template_node_spec.ts | 8 ++-- packages/language-service/src/completions.ts | 18 ++++----- packages/language-service/src/definitions.ts | 40 +++++++++---------- .../language-service/src/display_parts.ts | 6 +-- packages/language-service/src/quick_info.ts | 23 +++++------ .../src/references_and_rename_utils.ts | 16 ++++---- .../language-service/src/signature_help.ts | 9 ++--- packages/language-service/src/utils.ts | 6 +-- 16 files changed, 137 insertions(+), 137 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts b/packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts index 7ca1dddbb26b9..ef2c9e516c8fd 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/api/checker.ts @@ -15,7 +15,7 @@ import {ErrorCode} from '../../diagnostics'; import {FullTemplateMapping, NgTemplateDiagnostic, TypeCheckableDirectiveMeta} from './api'; import {GlobalCompletion} from './completion'; import {DirectiveInScope, PipeInScope} from './scope'; -import {ElementSymbol, ShimLocation, Symbol, TemplateSymbol} from './symbols'; +import {ElementSymbol, Symbol, TcbLocation, TemplateSymbol} from './symbols'; /** * Interface to the Angular Template Type Checker to extract diagnostics and intelligence from the @@ -56,7 +56,7 @@ export interface TemplateTypeChecker { * Given a `shim` and position within the file, returns information for mapping back to a template * location. */ - getTemplateMappingAtShimLocation(shimLocation: ShimLocation): FullTemplateMapping|null; + getTemplateMappingAtTcbLocation(tcbLocation: TcbLocation): FullTemplateMapping|null; /** * Get all `ts.Diagnostic`s currently available that pertain to the given component. @@ -113,19 +113,19 @@ export interface TemplateTypeChecker { /** - * For the given expression node, retrieve a `ShimLocation` that can be used to perform + * For the given expression node, retrieve a `TcbLocation` that can be used to perform * autocompletion at that point in the expression, if such a location exists. */ getExpressionCompletionLocation( - expr: PropertyRead|SafePropertyRead, component: ts.ClassDeclaration): ShimLocation|null; + expr: PropertyRead|SafePropertyRead, component: ts.ClassDeclaration): TcbLocation|null; /** * For the given node represents a `LiteralPrimitive`(the `TextAttribute` represents a string - * literal), retrieve a `ShimLocation` that can be used to perform autocompletion at that point in + * literal), retrieve a `TcbLocation` that can be used to perform autocompletion at that point in * the node, if such a location exists. */ getLiteralCompletionLocation( - strNode: LiteralPrimitive|TmplAstTextAttribute, component: ts.ClassDeclaration): ShimLocation + strNode: LiteralPrimitive|TmplAstTextAttribute, component: ts.ClassDeclaration): TcbLocation |null; /** diff --git a/packages/compiler-cli/src/ngtsc/typecheck/api/completion.ts b/packages/compiler-cli/src/ngtsc/typecheck/api/completion.ts index 47d09ddb2651c..65e4e5332044e 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/api/completion.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/api/completion.ts @@ -8,7 +8,7 @@ import {TmplAstReference, TmplAstVariable} from '@angular/compiler'; -import {ShimLocation} from './symbols'; +import {TcbLocation} from './symbols'; /** * An autocompletion source of any kind. @@ -60,7 +60,7 @@ export interface GlobalCompletion { * A location within the type-checking shim where TypeScript's completion APIs can be used to * access completions for the template's component context (component class members). */ - componentContext: ShimLocation; + componentContext: TcbLocation; /** * `Map` of local references and variables that are visible at the requested level of the @@ -76,5 +76,5 @@ export interface GlobalCompletion { * A location within the type-checking shim where TypeScript's completion APIs can be used to * access completions for the AST node of the cursor position (primitive constants). */ - nodeContext: ShimLocation|null; + nodeContext: TcbLocation|null; } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/api/symbols.ts b/packages/compiler-cli/src/ngtsc/typecheck/api/symbols.ts index bb1bb186e8f2c..3c52f7d87cd06 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/api/symbols.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/api/symbols.ts @@ -39,16 +39,19 @@ export type Symbol = InputBindingSymbol|OutputBindingSymbol|ElementSymbol|Refere */ export type TemplateDeclarationSymbol = ReferenceSymbol|VariableSymbol; -/** Information about where a `ts.Node` can be found in the type check block shim file. */ -export interface ShimLocation { +/** + * Information about where a `ts.Node` can be found in the type check file. This can either be + * a type-checking shim file, or an original source file for inline type check blocks. + */ +export interface TcbLocation { /** * The fully qualified path of the file which contains the generated TypeScript type check * code for the component's template. */ - shimPath: AbsoluteFsPath; + tcbPath: AbsoluteFsPath; - /** The location in the shim file where node appears. */ - positionInShimFile: number; + /** The location in the file where node appears. */ + positionInFile: number; } /** @@ -62,7 +65,7 @@ export interface TsNodeSymbolInfo { tsSymbol: ts.Symbol|null; /** The position of the most relevant part of the template node. */ - shimLocation: ShimLocation; + tcbLocation: TcbLocation; } /** @@ -81,7 +84,7 @@ export interface ExpressionSymbol { tsSymbol: ts.Symbol|null; /** The position of the most relevant part of the expression. */ - shimLocation: ShimLocation; + tcbLocation: TcbLocation; } /** Represents either an input or output binding in a template. */ @@ -101,7 +104,7 @@ export interface BindingSymbol { target: DirectiveSymbol|ElementSymbol|TemplateSymbol; /** The location in the shim file where the field access for the binding appears. */ - shimLocation: ShimLocation; + tcbLocation: TcbLocation; } /** @@ -171,7 +174,7 @@ export interface ReferenceSymbol { * ``` * This `targetLocation` is `[_t1 variable declaration].getStart()`. */ - targetLocation: ShimLocation; + targetLocation: TcbLocation; /** * The location in the TCB for the identifier node in the reference variable declaration. @@ -179,7 +182,7 @@ export interface ReferenceSymbol { * `var _t2 = _t1`, this location is `[_t2 node].getStart()`. This location can * be used to find references to the variable within the template. */ - referenceVarLocation: ShimLocation; + referenceVarLocation: TcbLocation; } /** @@ -211,13 +214,13 @@ export interface VariableSymbol { /** * The location in the shim file for the identifier that was declared for the template variable. */ - localVarLocation: ShimLocation; + localVarLocation: TcbLocation; /** * The location in the shim file for the initializer node of the variable that represents the * template variable. */ - initializerLocation: ShimLocation; + initializerLocation: TcbLocation; } /** @@ -236,7 +239,7 @@ export interface ElementSymbol { directives: DirectiveSymbol[]; /** The location in the shim file for the variable that holds the type of the element. */ - shimLocation: ShimLocation; + tcbLocation: TcbLocation; templateNode: TmplAstElement; } @@ -261,7 +264,7 @@ export interface DirectiveSymbol extends DirectiveInScope { tsType: ts.Type; /** The location in the shim file for the variable that holds the type of the directive. */ - shimLocation: ShimLocation; + tcbLocation: TcbLocation; } /** @@ -292,7 +295,7 @@ export interface PipeSymbol { tsSymbol: ts.Symbol|null; /** The position of the transform call in the template. */ - shimLocation: ShimLocation; + tcbLocation: TcbLocation; /** The symbol for the pipe class as an instance that appears in the TCB. */ classSymbol: ClassSymbol; @@ -307,5 +310,5 @@ export interface ClassSymbol { tsSymbol: SymbolWithValueDeclaration; /** The position for the variable declaration for the class instance. */ - shimLocation: ShimLocation; + tcbLocation: TcbLocation; } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/extended/checks/nullish_coalescing_not_nullable/index.ts b/packages/compiler-cli/src/ngtsc/typecheck/extended/checks/nullish_coalescing_not_nullable/index.ts index 21cf739b0ffbd..de157ea82f4df 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/extended/checks/nullish_coalescing_not_nullable/index.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/extended/checks/nullish_coalescing_not_nullable/index.ts @@ -50,8 +50,7 @@ class NullishCoalescingNotNullableCheck extends if (symbol.kind !== SymbolKind.Expression) { return []; } - const span = - ctx.templateTypeChecker.getTemplateMappingAtShimLocation(symbol.shimLocation)!.span; + const span = ctx.templateTypeChecker.getTemplateMappingAtTcbLocation(symbol.tcbLocation)!.span; const diagnostic = ctx.makeTemplateDiagnostic( span, `The left side of this nullish coalescing operation does not include 'null' or 'undefined' in its type, therefore the '??' operator can be safely removed.`); diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts index 09ef4b55d6332..2a819cd01aa71 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/checker.ts @@ -19,7 +19,7 @@ import {ClassDeclaration, isNamedClassDeclaration, ReflectionHost} from '../../r import {ComponentScopeReader, TypeCheckScopeRegistry} from '../../scope'; import {isShim} from '../../shims'; import {getSourceFileOrNull, isSymbolWithValueDeclaration} from '../../util/src/typescript'; -import {DirectiveInScope, ElementSymbol, FullTemplateMapping, GlobalCompletion, NgTemplateDiagnostic, OptimizeFor, PipeInScope, ProgramTypeCheckAdapter, ShimLocation, Symbol, TemplateDiagnostic, TemplateId, TemplateSymbol, TemplateTypeChecker, TypeCheckableDirectiveMeta, TypeCheckingConfig} from '../api'; +import {DirectiveInScope, ElementSymbol, FullTemplateMapping, GlobalCompletion, NgTemplateDiagnostic, OptimizeFor, PipeInScope, ProgramTypeCheckAdapter, Symbol, TcbLocation, TemplateDiagnostic, TemplateId, TemplateSymbol, TemplateTypeChecker, TypeCheckableDirectiveMeta, TypeCheckingConfig} from '../api'; import {makeTemplateDiagnostic} from '../diagnostics'; import {CompletionEngine} from './completion'; @@ -151,20 +151,20 @@ export class TemplateTypeCheckerImpl implements TemplateTypeChecker { return null; } - getTemplateMappingAtShimLocation({shimPath, positionInShimFile}: ShimLocation): - FullTemplateMapping|null { - const records = this.getFileAndShimRecordsForPath(absoluteFrom(shimPath)); + getTemplateMappingAtTcbLocation({tcbPath, positionInFile}: TcbLocation): FullTemplateMapping + |null { + const records = this.getFileAndShimRecordsForPath(absoluteFrom(tcbPath)); if (records === null) { return null; } const {fileRecord} = records; - const shimSf = this.programDriver.getProgram().getSourceFile(absoluteFrom(shimPath)); + const shimSf = this.programDriver.getProgram().getSourceFile(absoluteFrom(tcbPath)); if (shimSf === undefined) { return null; } return getTemplateMapping( - shimSf, positionInShimFile, fileRecord.sourceManager, /*isDiagnosticsRequest*/ false); + shimSf, positionInFile, fileRecord.sourceManager, /*isDiagnosticsRequest*/ false); } generateAllTypeCheckBlocks() { @@ -270,7 +270,7 @@ export class TemplateTypeCheckerImpl implements TemplateTypeChecker { } getExpressionCompletionLocation( - ast: PropertyRead|SafePropertyRead, component: ts.ClassDeclaration): ShimLocation|null { + ast: PropertyRead|SafePropertyRead, component: ts.ClassDeclaration): TcbLocation|null { const engine = this.getOrCreateCompletionEngine(component); if (engine === null) { return null; @@ -280,7 +280,7 @@ export class TemplateTypeCheckerImpl implements TemplateTypeChecker { } getLiteralCompletionLocation( - node: LiteralPrimitive|TmplAstTextAttribute, component: ts.ClassDeclaration): ShimLocation + node: LiteralPrimitive|TmplAstTextAttribute, component: ts.ClassDeclaration): TcbLocation |null { const engine = this.getOrCreateCompletionEngine(component); if (engine === null) { diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/completion.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/completion.ts index 976511ac84899..2b1c97192f4a0 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/completion.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/completion.ts @@ -10,7 +10,7 @@ import {AST, EmptyExpr, ImplicitReceiver, LiteralPrimitive, PropertyRead, Proper import ts from 'typescript'; import {AbsoluteFsPath} from '../../file_system'; -import {CompletionKind, GlobalCompletion, ReferenceCompletion, ShimLocation, VariableCompletion} from '../api'; +import {CompletionKind, GlobalCompletion, ReferenceCompletion, TcbLocation, VariableCompletion} from '../api'; import {ExpressionIdentifier, findFirstMatchingNode} from './comments'; import {TemplateData} from './context'; @@ -22,7 +22,7 @@ import {TemplateData} from './context'; * surrounding TS program have changed. */ export class CompletionEngine { - private componentContext: ShimLocation|null; + private componentContext: TcbLocation|null; /** * Cache of completions for various levels of the template, including the root template (`null`). @@ -32,10 +32,10 @@ export class CompletionEngine { new Map>(); private expressionCompletionCache = - new Map(); + new Map(); - constructor(private tcb: ts.Node, private data: TemplateData, private shimPath: AbsoluteFsPath) { + constructor(private tcb: ts.Node, private data: TemplateData, private tcbPath: AbsoluteFsPath) { // Find the component completion expression within the TCB. This looks like: `ctx. /* ... */;` const globalRead = findFirstMatchingNode(this.tcb, { filter: ts.isPropertyAccessExpression, @@ -44,11 +44,11 @@ export class CompletionEngine { if (globalRead !== null) { this.componentContext = { - shimPath: this.shimPath, + tcbPath: this.tcbPath, // `globalRead.name` is an empty `ts.Identifier`, so its start position immediately follows // the `.` in `ctx.`. TS autocompletion APIs can then be used to access completion results // for the component context. - positionInShimFile: globalRead.name.getStart(), + positionInFile: globalRead.name.getStart(), }; } else { this.componentContext = null; @@ -74,7 +74,7 @@ export class CompletionEngine { return null; } - let nodeContext: ShimLocation|null = null; + let nodeContext: TcbLocation|null = null; if (node instanceof EmptyExpr) { const nodeLocation = findFirstMatchingNode(this.tcb, { filter: ts.isIdentifier, @@ -82,8 +82,8 @@ export class CompletionEngine { }); if (nodeLocation !== null) { nodeContext = { - shimPath: this.shimPath, - positionInShimFile: nodeLocation.getStart(), + tcbPath: this.tcbPath, + positionInFile: nodeLocation.getStart(), }; } } @@ -95,8 +95,8 @@ export class CompletionEngine { }); if (nodeLocation) { nodeContext = { - shimPath: this.shimPath, - positionInShimFile: nodeLocation.getStart(), + tcbPath: this.tcbPath, + positionInFile: nodeLocation.getStart(), }; } } @@ -108,7 +108,7 @@ export class CompletionEngine { }; } - getExpressionCompletionLocation(expr: PropertyRead|PropertyWrite|SafePropertyRead): ShimLocation + getExpressionCompletionLocation(expr: PropertyRead|PropertyWrite|SafePropertyRead): TcbLocation |null { if (this.expressionCompletionCache.has(expr)) { return this.expressionCompletionCache.get(expr)!; @@ -146,15 +146,15 @@ export class CompletionEngine { return null; } - const res: ShimLocation = { - shimPath: this.shimPath, - positionInShimFile: tsExpr.name.getEnd(), + const res: TcbLocation = { + tcbPath: this.tcbPath, + positionInFile: tsExpr.name.getEnd(), }; this.expressionCompletionCache.set(expr, res); return res; } - getLiteralCompletionLocation(expr: LiteralPrimitive|TmplAstTextAttribute): ShimLocation|null { + getLiteralCompletionLocation(expr: LiteralPrimitive|TmplAstTextAttribute): TcbLocation|null { if (this.expressionCompletionCache.has(expr)) { return this.expressionCompletionCache.get(expr)!; } @@ -186,9 +186,9 @@ export class CompletionEngine { // In the shimFile, if `tsExpr` is a string, the position should be in the quotes. positionInShimFile -= 1; } - const res: ShimLocation = { - shimPath: this.shimPath, - positionInShimFile, + const res: TcbLocation = { + tcbPath: this.tcbPath, + positionInFile: positionInShimFile, }; this.expressionCompletionCache.set(expr, res); return res; diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/template_symbol_builder.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/template_symbol_builder.ts index 5c0b763a72d4b..c005a6364ab0c 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/template_symbol_builder.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/template_symbol_builder.ts @@ -13,7 +13,7 @@ import {AbsoluteFsPath} from '../../file_system'; import {ClassDeclaration} from '../../reflection'; import {ComponentScopeReader} from '../../scope'; import {isAssignment, isSymbolWithValueDeclaration} from '../../util/src/typescript'; -import {BindingSymbol, DirectiveSymbol, DomBindingSymbol, ElementSymbol, ExpressionSymbol, InputBindingSymbol, OutputBindingSymbol, PipeSymbol, ReferenceSymbol, ShimLocation, Symbol, SymbolKind, TemplateSymbol, TsNodeSymbolInfo, TypeCheckableDirectiveMeta, VariableSymbol} from '../api'; +import {BindingSymbol, DirectiveSymbol, DomBindingSymbol, ElementSymbol, ExpressionSymbol, InputBindingSymbol, OutputBindingSymbol, PipeSymbol, ReferenceSymbol, Symbol, SymbolKind, TcbLocation, TemplateSymbol, TsNodeSymbolInfo, TypeCheckableDirectiveMeta, VariableSymbol} from '../api'; import {ExpressionIdentifier, findAllMatchingNodes, findFirstMatchingNode, hasExpressionIdentifier} from './comments'; import {TemplateData} from './context'; @@ -245,7 +245,7 @@ export class SymbolBuilder { tsSymbol, tsType, target, - shimLocation: {shimPath: this.shimPath, positionInShimFile}, + tcbLocation: {tcbPath: this.shimPath, positionInFile: positionInShimFile}, }); } else { if (!ts.isElementAccessExpression(outputFieldAccess)) { @@ -270,7 +270,7 @@ export class SymbolBuilder { tsSymbol, tsType, target, - shimLocation: {shimPath: this.shimPath, positionInShimFile}, + tcbLocation: {tcbPath: this.shimPath, positionInFile: positionInShimFile}, }); } } @@ -356,7 +356,7 @@ export class SymbolBuilder { kind: SymbolKind.Directive, tsSymbol: symbol.tsSymbol, tsType: symbol.tsType, - shimLocation: symbol.shimLocation, + tcbLocation: symbol.tcbLocation, isComponent, isStructural, selector, @@ -379,12 +379,12 @@ export class SymbolBuilder { return { tsType: expressionSymbol.tsType, tsSymbol: expressionSymbol.tsSymbol, - initializerLocation: expressionSymbol.shimLocation, + initializerLocation: expressionSymbol.tcbLocation, kind: SymbolKind.Variable, declaration: variable, localVarLocation: { - shimPath: this.shimPath, - positionInShimFile: this.getShimPositionForNode(node.name), + tcbPath: this.shimPath, + positionInFile: this.getShimPositionForNode(node.name), } }; } @@ -414,9 +414,9 @@ export class SymbolBuilder { return null; } - const referenceVarShimLocation: ShimLocation = { - shimPath: this.shimPath, - positionInShimFile: this.getShimPositionForNode(node), + const referenceVarTcbLocation: TcbLocation = { + tcbPath: this.shimPath, + positionInFile: this.getShimPositionForNode(node), }; if (target instanceof TmplAstTemplate || target instanceof TmplAstElement) { return { @@ -425,8 +425,8 @@ export class SymbolBuilder { tsType: symbol.tsType, target, declaration: ref, - targetLocation: symbol.shimLocation, - referenceVarLocation: referenceVarShimLocation, + targetLocation: symbol.tcbLocation, + referenceVarLocation: referenceVarTcbLocation, }; } else { if (!ts.isClassDeclaration(target.directive.ref.node)) { @@ -439,8 +439,8 @@ export class SymbolBuilder { tsType: symbol.tsType, declaration: ref, target: target.directive.ref.node, - targetLocation: symbol.shimLocation, - referenceVarLocation: referenceVarShimLocation, + targetLocation: symbol.tcbLocation, + referenceVarLocation: referenceVarTcbLocation, }; } } @@ -569,7 +569,7 @@ export class SymbolBuilder { // Examples of this would be literals and `document.createElement('div')`. tsSymbol: tsSymbol ?? type.symbol ?? null, tsType: type, - shimLocation: {shimPath: this.shimPath, positionInShimFile}, + tcbLocation: {tcbPath: this.shimPath, positionInFile: positionInShimFile}, }; } diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__completion_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__completion_spec.ts index df8dabee05460..b34d6c3bfc38d 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__completion_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__completion_spec.ts @@ -20,15 +20,15 @@ runInEachFileSystem(() => { it('should return a completion point in the TCB for the component context', () => { const {completions, program} = setupCompletions(`No special template needed`); expect(completions.templateContext.size).toBe(0); - const {shimPath, positionInShimFile} = completions.componentContext; - const tcbSf = getSourceFileOrError(program, shimPath); - const node = getTokenAtPosition(tcbSf, positionInShimFile).parent; + const {tcbPath, positionInFile} = completions.componentContext; + const tcbSf = getSourceFileOrError(program, tcbPath); + const node = getTokenAtPosition(tcbSf, positionInFile).parent; if (!ts.isExpressionStatement(node)) { return fail(`Expected a ts.ExpressionStatement`); } expect(node.expression.getText()).toEqual('ctx.'); // The position should be between the '.' and a following space. - expect(tcbSf.text.slice(positionInShimFile - 1, positionInShimFile + 1)).toEqual('. '); + expect(tcbSf.text.slice(positionInFile - 1, positionInFile + 1)).toEqual('. '); }); it('should return additional completions for references and variables when available', () => { diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__get_symbol_of_template_node_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__get_symbol_of_template_node_spec.ts index 3f331c940f48c..56d67f930e8f2 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__get_symbol_of_template_node_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/type_checker__get_symbol_of_template_node_spec.ts @@ -79,7 +79,7 @@ runInEachFileSystem(() => { // Ensure we can go back to the original location using the shim location const mapping = - templateTypeChecker.getTemplateMappingAtShimLocation(symbol.bindings[0].shimLocation)!; + templateTypeChecker.getTemplateMappingAtTcbLocation(symbol.bindings[0].tcbLocation)!; expect(mapping.span.toString()).toEqual('name'); }); @@ -153,10 +153,10 @@ runInEachFileSystem(() => { // Ensure we can map the shim locations back to the template const initializerMapping = - templateTypeChecker.getTemplateMappingAtShimLocation(symbol.initializerLocation)!; + templateTypeChecker.getTemplateMappingAtTcbLocation(symbol.initializerLocation)!; expect(initializerMapping.span.toString()).toEqual('bar'); const localVarMapping = - templateTypeChecker.getTemplateMappingAtShimLocation(symbol.localVarLocation)!; + templateTypeChecker.getTemplateMappingAtTcbLocation(symbol.localVarLocation)!; expect(localVarMapping.span.toString()).toEqual('contextFoo'); }); @@ -176,7 +176,7 @@ runInEachFileSystem(() => { // Ensure we can map the var shim location back to the template const localVarMapping = - templateTypeChecker.getTemplateMappingAtShimLocation(symbol.referenceVarLocation); + templateTypeChecker.getTemplateMappingAtTcbLocation(symbol.referenceVarLocation); expect(localVarMapping!.span.toString()).toEqual('ref1'); }); diff --git a/packages/language-service/src/completions.ts b/packages/language-service/src/completions.ts index 81350caafec48..435e1021a9575 100644 --- a/packages/language-service/src/completions.ts +++ b/packages/language-service/src/completions.ts @@ -103,7 +103,7 @@ export class CompletionBuilder { return undefined; } const tsResults = - this.tsLS.getCompletionsAtPosition(location.shimPath, location.positionInShimFile, options); + this.tsLS.getCompletionsAtPosition(location.tcbPath, location.positionInFile, options); if (tsResults === undefined) { return undefined; } @@ -209,8 +209,8 @@ export class CompletionBuilder { if (location === null) { return undefined; } - const tsResults = this.tsLS.getCompletionsAtPosition( - location.shimPath, location.positionInShimFile, options); + const tsResults = + this.tsLS.getCompletionsAtPosition(location.tcbPath, location.positionInFile, options); if (tsResults === undefined) { return undefined; } @@ -268,7 +268,7 @@ export class CompletionBuilder { return undefined; } details = this.tsLS.getCompletionEntryDetails( - location.shimPath, location.positionInShimFile, entryName, formatOptions, + location.tcbPath, location.positionInFile, entryName, formatOptions, /* source */ undefined, preferences, data); } if (details !== undefined) { @@ -292,7 +292,7 @@ export class CompletionBuilder { return undefined; } return this.tsLS.getCompletionEntrySymbol( - location.shimPath, location.positionInShimFile, name, /* source */ undefined); + location.tcbPath, location.positionInFile, name, /* source */ undefined); } } @@ -316,7 +316,7 @@ export class CompletionBuilder { // Merge TS completion results with results from the template scope. let entries: ts.CompletionEntry[] = []; const componentCompletions = this.tsLS.getCompletionsAtPosition( - componentContext.shimPath, componentContext.positionInShimFile, options); + componentContext.tcbPath, componentContext.positionInFile, options); if (componentCompletions !== undefined) { for (const tsCompletion of componentCompletions.entries) { // Skip completions that are shadowed by a template entity definition. @@ -335,7 +335,7 @@ export class CompletionBuilder { // Merge TS completion results with results from the ast context. if (astContext !== null) { const nodeCompletions = this.tsLS.getCompletionsAtPosition( - astContext.shimPath, astContext.positionInShimFile, options); + astContext.tcbPath, astContext.positionInFile, options); if (nodeCompletions !== undefined) { for (const tsCompletion of nodeCompletions.entries) { if (this.isValidNodeContextCompletion(tsCompletion)) { @@ -411,7 +411,7 @@ export class CompletionBuilder { }; } else { return this.tsLS.getCompletionEntryDetails( - componentContext.shimPath, componentContext.positionInShimFile, entryName, formatOptions, + componentContext.tcbPath, componentContext.positionInFile, entryName, formatOptions, /* source */ undefined, preferences, data); } } @@ -440,7 +440,7 @@ export class CompletionBuilder { return symbol.tsSymbol; } else { return this.tsLS.getCompletionEntrySymbol( - componentContext.shimPath, componentContext.positionInShimFile, entryName, + componentContext.tcbPath, componentContext.positionInFile, entryName, /* source */ undefined); } } diff --git a/packages/language-service/src/definitions.ts b/packages/language-service/src/definitions.ts index d263f08796ecc..ab3696cc0c0c3 100644 --- a/packages/language-service/src/definitions.ts +++ b/packages/language-service/src/definitions.ts @@ -11,13 +11,13 @@ import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core'; import {absoluteFrom} from '@angular/compiler-cli/src/ngtsc/file_system'; import {isExternalResource} from '@angular/compiler-cli/src/ngtsc/metadata'; import {ProgramDriver} from '@angular/compiler-cli/src/ngtsc/program_driver'; -import {DirectiveSymbol, DomBindingSymbol, ElementSymbol, ShimLocation, Symbol, SymbolKind, TemplateSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; +import {DirectiveSymbol, DomBindingSymbol, ElementSymbol, Symbol, SymbolKind, TcbLocation, TemplateSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; import ts from 'typescript'; import {convertToTemplateDocumentSpan} from './references_and_rename_utils'; import {getTargetAtPosition, TargetNodeKind} from './template_target'; import {findTightestNode, getParentClassDeclaration} from './ts_utils'; -import {flatMap, getDirectiveMatchesForAttribute, getDirectiveMatchesForElementTag, getTemplateInfoAtPosition, getTemplateLocationFromShimLocation, getTextSpanOfNode, isDollarEvent, isTypeScriptFile, TemplateInfo, toTextSpan} from './utils'; +import {flatMap, getDirectiveMatchesForAttribute, getDirectiveMatchesForElementTag, getTemplateInfoAtPosition, getTemplateLocationFromTcbLocation, getTextSpanOfNode, isDollarEvent, isTypeScriptFile, TemplateInfo, toTextSpan} from './utils'; interface DefinitionMeta { node: AST|TmplAstNode; @@ -25,8 +25,8 @@ interface DefinitionMeta { symbol: Symbol; } -interface HasShimLocation { - shimLocation: ShimLocation; +interface HasTcbLocation { + tcbLocation: TcbLocation; } export class DefinitionBuilder { @@ -107,11 +107,11 @@ export class DefinitionBuilder { case SymbolKind.Reference: { const definitions: ts.DefinitionInfo[] = []; if (symbol.declaration !== node) { - const shimLocation = symbol.kind === SymbolKind.Variable ? symbol.localVarLocation : - symbol.referenceVarLocation; - const mapping = getTemplateLocationFromShimLocation( - this.compiler.getTemplateTypeChecker(), shimLocation.shimPath, - shimLocation.positionInShimFile); + const tcbLocation = symbol.kind === SymbolKind.Variable ? symbol.localVarLocation : + symbol.referenceVarLocation; + const mapping = getTemplateLocationFromTcbLocation( + this.compiler.getTemplateTypeChecker(), tcbLocation.tcbPath, + tcbLocation.positionInFile); if (mapping !== null) { definitions.push({ name: symbol.declaration.name, @@ -126,7 +126,7 @@ export class DefinitionBuilder { } if (symbol.kind === SymbolKind.Variable) { definitions.push( - ...this.getDefinitionsForSymbols({shimLocation: symbol.initializerLocation})); + ...this.getDefinitionsForSymbols({tcbLocation: symbol.initializerLocation})); } return definitions; } @@ -136,10 +136,10 @@ export class DefinitionBuilder { } } - private getDefinitionsForSymbols(...symbols: HasShimLocation[]): ts.DefinitionInfo[] { - return flatMap(symbols, ({shimLocation}) => { - const {shimPath, positionInShimFile} = shimLocation; - const definitionInfos = this.tsLS.getDefinitionAtPosition(shimPath, positionInShimFile); + private getDefinitionsForSymbols(...symbols: HasTcbLocation[]): ts.DefinitionInfo[] { + return flatMap(symbols, ({tcbLocation}) => { + const {tcbPath, positionInFile} = tcbLocation; + const definitionInfos = this.tsLS.getDefinitionAtPosition(tcbPath, positionInFile); if (definitionInfos === undefined) { return []; } @@ -212,14 +212,14 @@ export class DefinitionBuilder { } case SymbolKind.Reference: definitions.push( - ...this.getTypeDefinitionsForSymbols({shimLocation: symbol.targetLocation})); + ...this.getTypeDefinitionsForSymbols({tcbLocation: symbol.targetLocation})); break; case SymbolKind.Expression: definitions.push(...this.getTypeDefinitionsForSymbols(symbol)); break; case SymbolKind.Variable: { definitions.push( - ...this.getTypeDefinitionsForSymbols({shimLocation: symbol.initializerLocation})); + ...this.getTypeDefinitionsForSymbols({tcbLocation: symbol.initializerLocation})); break; } } @@ -278,10 +278,10 @@ export class DefinitionBuilder { return this.getTypeDefinitionsForSymbols(...dirs); } - private getTypeDefinitionsForSymbols(...symbols: HasShimLocation[]): ts.DefinitionInfo[] { - return flatMap(symbols, ({shimLocation}) => { - const {shimPath, positionInShimFile} = shimLocation; - return this.tsLS.getTypeDefinitionAtPosition(shimPath, positionInShimFile) ?? []; + private getTypeDefinitionsForSymbols(...symbols: HasTcbLocation[]): ts.DefinitionInfo[] { + return flatMap(symbols, ({tcbLocation}) => { + const {tcbPath, positionInFile} = tcbLocation; + return this.tsLS.getTypeDefinitionAtPosition(tcbPath, positionInFile) ?? []; }); } diff --git a/packages/language-service/src/display_parts.ts b/packages/language-service/src/display_parts.ts index a45d8b3a28576..6d12d2dd4dc7a 100644 --- a/packages/language-service/src/display_parts.ts +++ b/packages/language-service/src/display_parts.ts @@ -7,7 +7,7 @@ */ 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 {DirectiveInScope, ReferenceSymbol, Symbol, SymbolKind, TcbLocation, VariableSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; import ts from 'typescript'; @@ -119,9 +119,9 @@ export function unsafeCastDisplayInfoKindToScriptElementKind(kind: DisplayInfoKi } function getDocumentationFromTypeDefAtLocation( - tsLS: ts.LanguageService, shimLocation: ShimLocation): ts.SymbolDisplayPart[]|undefined { + tsLS: ts.LanguageService, tcbLocation: TcbLocation): ts.SymbolDisplayPart[]|undefined { const typeDefs = - tsLS.getTypeDefinitionAtPosition(shimLocation.shimPath, shimLocation.positionInShimFile); + tsLS.getTypeDefinitionAtPosition(tcbLocation.tcbPath, tcbLocation.positionInFile); if (typeDefs === undefined || typeDefs.length === 0) { return undefined; } diff --git a/packages/language-service/src/quick_info.ts b/packages/language-service/src/quick_info.ts index 8370d4f6389c9..b92063c74b27a 100644 --- a/packages/language-service/src/quick_info.ts +++ b/packages/language-service/src/quick_info.ts @@ -7,7 +7,7 @@ */ import {AST, Call, ImplicitReceiver, PropertyRead, ThisReceiver, TmplAstBoundAttribute, TmplAstNode, TmplAstTextAttribute} from '@angular/compiler'; import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core'; -import {DirectiveSymbol, DomBindingSymbol, ElementSymbol, InputBindingSymbol, OutputBindingSymbol, PipeSymbol, ReferenceSymbol, ShimLocation, Symbol, SymbolKind, VariableSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; +import {DirectiveSymbol, DomBindingSymbol, ElementSymbol, InputBindingSymbol, OutputBindingSymbol, PipeSymbol, ReferenceSymbol, Symbol, SymbolKind, TcbLocation, VariableSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; import ts from 'typescript'; import {createDisplayParts, DisplayInfoKind, SYMBOL_PUNC, SYMBOL_SPACE, SYMBOL_TEXT, unsafeCastDisplayInfoKindToScriptElementKind} from './display_parts'; @@ -55,11 +55,11 @@ export class QuickInfoBuilder { case SymbolKind.DomBinding: return this.getQuickInfoForDomBinding(symbol); case SymbolKind.Directive: - return this.getQuickInfoAtShimLocation(symbol.shimLocation); + return this.getQuickInfoAtTcbLocation(symbol.tcbLocation); case SymbolKind.Pipe: return this.getQuickInfoForPipeSymbol(symbol); case SymbolKind.Expression: - return this.getQuickInfoAtShimLocation(symbol.shimLocation); + return this.getQuickInfoAtTcbLocation(symbol.tcbLocation); } } @@ -72,7 +72,7 @@ export class QuickInfoBuilder { const kind = symbol.kind === SymbolKind.Input ? DisplayInfoKind.PROPERTY : DisplayInfoKind.EVENT; - const quickInfo = this.getQuickInfoAtShimLocation(symbol.bindings[0].shimLocation); + const quickInfo = this.getQuickInfoAtTcbLocation(symbol.bindings[0].tcbLocation); return quickInfo === undefined ? undefined : updateQuickInfoKind(quickInfo, kind); } @@ -104,7 +104,7 @@ export class QuickInfoBuilder { private getQuickInfoForPipeSymbol(symbol: PipeSymbol): ts.QuickInfo|undefined { if (symbol.tsSymbol !== null) { - const quickInfo = this.getQuickInfoAtShimLocation(symbol.shimLocation); + const quickInfo = this.getQuickInfoAtTcbLocation(symbol.tcbLocation); return quickInfo === undefined ? undefined : updateQuickInfoKind(quickInfo, DisplayInfoKind.PIPE); } else { @@ -131,7 +131,7 @@ export class QuickInfoBuilder { private getQuickInfoForDirectiveSymbol(dir: DirectiveSymbol, node: TmplAstNode|AST = this.node): ts.QuickInfo { const kind = dir.isComponent ? DisplayInfoKind.COMPONENT : DisplayInfoKind.DIRECTIVE; - const documentation = this.getDocumentationFromTypeDefAtLocation(dir.shimLocation); + const documentation = this.getDocumentationFromTypeDefAtLocation(dir.tcbLocation); let containerName: string|undefined; if (ts.isClassDeclaration(dir.tsSymbol.valueDeclaration) && dir.ngModule !== null) { containerName = dir.ngModule.name.getText(); @@ -142,10 +142,10 @@ export class QuickInfoBuilder { containerName, undefined, documentation); } - private getDocumentationFromTypeDefAtLocation(shimLocation: ShimLocation): + private getDocumentationFromTypeDefAtLocation(tcbLocation: TcbLocation): ts.SymbolDisplayPart[]|undefined { - const typeDefs = this.tsLS.getTypeDefinitionAtPosition( - shimLocation.shimPath, shimLocation.positionInShimFile); + const typeDefs = + this.tsLS.getTypeDefinitionAtPosition(tcbLocation.tcbPath, tcbLocation.positionInFile); if (typeDefs === undefined || typeDefs.length === 0) { return undefined; } @@ -153,9 +153,8 @@ export class QuickInfoBuilder { ?.documentation; } - private getQuickInfoAtShimLocation(location: ShimLocation): ts.QuickInfo|undefined { - const quickInfo = - this.tsLS.getQuickInfoAtPosition(location.shimPath, location.positionInShimFile); + private getQuickInfoAtTcbLocation(location: TcbLocation): ts.QuickInfo|undefined { + const quickInfo = this.tsLS.getQuickInfoAtPosition(location.tcbPath, location.positionInFile); if (quickInfo === undefined || quickInfo.displayParts === undefined) { return quickInfo; } diff --git a/packages/language-service/src/references_and_rename_utils.ts b/packages/language-service/src/references_and_rename_utils.ts index 1b99ef8387f2b..bdbde823225de 100644 --- a/packages/language-service/src/references_and_rename_utils.ts +++ b/packages/language-service/src/references_and_rename_utils.ts @@ -9,13 +9,13 @@ import {AST, BindingPipe, LiteralPrimitive, PropertyRead, PropertyWrite, SafePro import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core'; import {absoluteFrom} from '@angular/compiler-cli/src/ngtsc/file_system'; import {DirectiveMeta, PipeMeta} from '@angular/compiler-cli/src/ngtsc/metadata'; -import {DirectiveSymbol, ShimLocation, Symbol, SymbolKind, TemplateTypeChecker} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; +import {DirectiveSymbol, Symbol, SymbolKind, TcbLocation, TemplateTypeChecker} from '@angular/compiler-cli/src/ngtsc/typecheck/api'; import {ExpressionIdentifier, hasExpressionIdentifier} from '@angular/compiler-cli/src/ngtsc/typecheck/src/comments'; import ts from 'typescript'; import {getTargetAtPosition, TargetNodeKind} from './template_target'; import {findTightestNode, getParentClassDeclaration} from './ts_utils'; -import {getDirectiveMatchesForAttribute, getDirectiveMatchesForElementTag, getTemplateLocationFromShimLocation, isWithin, TemplateInfo, toTextSpan} from './utils'; +import {getDirectiveMatchesForAttribute, getDirectiveMatchesForElementTag, getTemplateLocationFromTcbLocation, isWithin, TemplateInfo, toTextSpan} from './utils'; /** Represents a location in a file. */ export interface FilePosition { @@ -24,10 +24,10 @@ export interface FilePosition { } /** - * Converts a `ShimLocation` to a more genericly named `FilePosition`. + * Converts a `TcbLocation` to a more genericly named `FilePosition`. */ -function toFilePosition(shimLocation: ShimLocation): FilePosition { - return {fileName: shimLocation.shimPath, position: shimLocation.positionInShimFile}; +function toFilePosition(tcbLocation: TcbLocation): FilePosition { + return {fileName: tcbLocation.tcbPath, position: tcbLocation.positionInFile}; } export interface TemplateLocationDetails { /** @@ -147,7 +147,7 @@ export function getTargetDetailsAtTemplatePosition( case SymbolKind.Input: case SymbolKind.Output: { details.push({ - typescriptLocations: symbol.bindings.map(binding => toFilePosition(binding.shimLocation)), + typescriptLocations: symbol.bindings.map(binding => toFilePosition(binding.tcbLocation)), templateTarget, symbol, }); @@ -156,7 +156,7 @@ export function getTargetDetailsAtTemplatePosition( case SymbolKind.Pipe: case SymbolKind.Expression: { details.push({ - typescriptLocations: [toFilePosition(symbol.shimLocation)], + typescriptLocations: [toFilePosition(symbol.tcbLocation)], templateTarget, symbol, }); @@ -221,7 +221,7 @@ export function convertToTemplateDocumentSpan( // TODO(atscott): Determine how to consistently resolve paths. i.e. with the project // serverHost or LSParseConfigHost in the adapter. We should have a better defined way to // normalize paths. - const mapping = getTemplateLocationFromShimLocation( + const mapping = getTemplateLocationFromTcbLocation( templateTypeChecker, absoluteFrom(shimDocumentSpan.fileName), shimDocumentSpan.textSpan.start); if (mapping === null) { diff --git a/packages/language-service/src/signature_help.ts b/packages/language-service/src/signature_help.ts index b2352c5bbfb45..fc1b86775e215 100644 --- a/packages/language-service/src/signature_help.ts +++ b/packages/language-service/src/signature_help.ts @@ -52,7 +52,7 @@ export function getSignatureHelp( switch (targetInfo.context.kind) { case TargetNodeKind.RawExpression: // For normal expressions, just use the primary TCB position of the expression. - shimPosition = symbol.shimLocation.positionInShimFile; + shimPosition = symbol.tcbLocation.positionInFile; // Walk up the parents of this expression and try to find a // `Call` for which signature information is being fetched. @@ -87,10 +87,9 @@ export function getSignatureHelp( // from it directly. // // First, use `findTightestNode` to locate the `ts.Node` at `symbol`'s location. - const shimSf = - getSourceFileOrError(compiler.getCurrentProgram(), symbol.shimLocation.shimPath); + const shimSf = getSourceFileOrError(compiler.getCurrentProgram(), symbol.tcbLocation.tcbPath); let shimNode: ts.Node|null = - findTightestNode(shimSf, symbol.shimLocation.positionInShimFile) ?? null; + findTightestNode(shimSf, symbol.tcbLocation.positionInFile) ?? null; // This node should be somewhere inside a `ts.CallExpression`. Walk up the AST to find it. while (shimNode !== null) { @@ -115,7 +114,7 @@ export function getSignatureHelp( break; } - const res = tsLS.getSignatureHelpItems(symbol.shimLocation.shimPath, shimPosition, options); + const res = tsLS.getSignatureHelpItems(symbol.tcbLocation.tcbPath, shimPosition, options); if (res === undefined) { return undefined; } diff --git a/packages/language-service/src/utils.ts b/packages/language-service/src/utils.ts index 4c16ecbb25918..457aacccdf7c5 100644 --- a/packages/language-service/src/utils.ts +++ b/packages/language-service/src/utils.ts @@ -362,11 +362,11 @@ export function isWithin(position: number, span: AbsoluteSourceSpan|ParseSourceS * For a given location in a shim file, retrieves the corresponding file url for the template and * the span in the template. */ -export function getTemplateLocationFromShimLocation( +export function getTemplateLocationFromTcbLocation( templateTypeChecker: TemplateTypeChecker, shimPath: AbsoluteFsPath, positionInShimFile: number): {templateUrl: AbsoluteFsPath, span: ParseSourceSpan}|null { - const mapping = - templateTypeChecker.getTemplateMappingAtShimLocation({shimPath, positionInShimFile}); + const mapping = templateTypeChecker.getTemplateMappingAtTcbLocation( + {tcbPath: shimPath, positionInFile: positionInShimFile}); if (mapping === null) { return null; }