Skip to content

Commit b40f1e5

Browse files
dylhunnpkozlowski-opensource
authored andcommitted
refactor(compiler): Remove deep imports in the language service (#54695)
Previously, the language service relied on deep imports such as `@angular/compiler/render3/...`. This is bad form, because that creates a dependency on the package's internal structure. Additionally, this is not compatible with google3. In this PR, I replace all the deep imports with shallow imports, in some cases adding the missing symbol to the `compiler.ts` exports. PR Close #54695
1 parent 33a6fab commit b40f1e5

File tree

10 files changed

+161
-163
lines changed

10 files changed

+161
-163
lines changed

packages/compiler/src/compiler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export {SourceMap} from './output/source_map';
6363
export * from './injectable_compiler_2';
6464
export * from './render3/partial/api';
6565
export * from './render3/view/api';
66-
export {BoundAttribute as TmplAstBoundAttribute, BoundEvent as TmplAstBoundEvent, BoundText as TmplAstBoundText, Content as TmplAstContent, Element as TmplAstElement, Icu as TmplAstIcu, Node as TmplAstNode, RecursiveVisitor as TmplAstRecursiveVisitor, Reference as TmplAstReference, Template as TmplAstTemplate, Text as TmplAstText, TextAttribute as TmplAstTextAttribute, Variable as TmplAstVariable, DeferredBlock as TmplAstDeferredBlock, DeferredBlockPlaceholder as TmplAstDeferredBlockPlaceholder, DeferredBlockLoading as TmplAstDeferredBlockLoading, DeferredBlockError as TmplAstDeferredBlockError, DeferredTrigger as TmplAstDeferredTrigger, BoundDeferredTrigger as TmplAstBoundDeferredTrigger, IdleDeferredTrigger as TmplAstIdleDeferredTrigger, ImmediateDeferredTrigger as TmplAstImmediateDeferredTrigger, HoverDeferredTrigger as TmplAstHoverDeferredTrigger, TimerDeferredTrigger as TmplAstTimerDeferredTrigger, InteractionDeferredTrigger as TmplAstInteractionDeferredTrigger, ViewportDeferredTrigger as TmplAstViewportDeferredTrigger, SwitchBlock as TmplAstSwitchBlock, SwitchBlockCase as TmplAstSwitchBlockCase, ForLoopBlock as TmplAstForLoopBlock, ForLoopBlockEmpty as TmplAstForLoopBlockEmpty, IfBlock as TmplAstIfBlock, IfBlockBranch as TmplAstIfBlockBranch, DeferredBlockTriggers as TmplAstDeferredBlockTriggers, UnknownBlock as TmplAstUnknownBlock} from './render3/r3_ast';
66+
export {visitAll as tmplAstVisitAll, BlockNode as TmplAstBlockNode, BoundAttribute as TmplAstBoundAttribute, BoundEvent as TmplAstBoundEvent, BoundText as TmplAstBoundText, Content as TmplAstContent, Element as TmplAstElement, Icu as TmplAstIcu, Node as TmplAstNode, Visitor as TmplAstVisitor, RecursiveVisitor as TmplAstRecursiveVisitor, Reference as TmplAstReference, Template as TmplAstTemplate, Text as TmplAstText, TextAttribute as TmplAstTextAttribute, Variable as TmplAstVariable, DeferredBlock as TmplAstDeferredBlock, DeferredBlockPlaceholder as TmplAstDeferredBlockPlaceholder, DeferredBlockLoading as TmplAstDeferredBlockLoading, DeferredBlockError as TmplAstDeferredBlockError, DeferredTrigger as TmplAstDeferredTrigger, BoundDeferredTrigger as TmplAstBoundDeferredTrigger, IdleDeferredTrigger as TmplAstIdleDeferredTrigger, ImmediateDeferredTrigger as TmplAstImmediateDeferredTrigger, HoverDeferredTrigger as TmplAstHoverDeferredTrigger, TimerDeferredTrigger as TmplAstTimerDeferredTrigger, InteractionDeferredTrigger as TmplAstInteractionDeferredTrigger, ViewportDeferredTrigger as TmplAstViewportDeferredTrigger, SwitchBlock as TmplAstSwitchBlock, SwitchBlockCase as TmplAstSwitchBlockCase, ForLoopBlock as TmplAstForLoopBlock, ForLoopBlockEmpty as TmplAstForLoopBlockEmpty, IfBlock as TmplAstIfBlock, IfBlockBranch as TmplAstIfBlockBranch, DeferredBlockTriggers as TmplAstDeferredBlockTriggers, UnknownBlock as TmplAstUnknownBlock} from './render3/r3_ast';
6767
export * from './render3/view/t2_api';
6868
export * from './render3/view/t2_binder';
6969
export {createCssSelectorFromNode} from './render3/view/util';

packages/language-service/src/codefixes/fix_invalid_banana_in_box.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {TmplAstBoundEvent} from '@angular/compiler';
910
import {ErrorCode, ngErrorCode} from '@angular/compiler-cli/src/ngtsc/diagnostics';
10-
import {BoundEvent} from '@angular/compiler/src/render3/r3_ast';
1111
import tss from 'typescript/lib/tsserverlibrary';
1212

1313
import {getTargetAtPosition, TargetNodeKind} from '../template_target';
@@ -85,7 +85,8 @@ export const fixInvalidBananaInBoxMeta: CodeActionMeta = {
8585
},
8686
};
8787

88-
function getTheBoundEventAtPosition(templateInfo: TemplateInfo, start: number): BoundEvent|null {
88+
function getTheBoundEventAtPosition(templateInfo: TemplateInfo, start: number): TmplAstBoundEvent|
89+
null {
8990
// It's safe to get the bound event at the position `start + 1` because the `start` is at the
9091
// start of the diagnostic, and the node outside the attribute key and value spans are skipped by
9192
// the function `getTargetAtPosition`.
@@ -97,7 +98,7 @@ function getTheBoundEventAtPosition(templateInfo: TemplateInfo, start: number):
9798
}
9899

99100
if (positionDetail.context.kind !== TargetNodeKind.AttributeInKeyContext ||
100-
!(positionDetail.context.node instanceof BoundEvent)) {
101+
!(positionDetail.context.node instanceof TmplAstBoundEvent)) {
101102
return null;
102103
}
103104

@@ -107,7 +108,7 @@ function getTheBoundEventAtPosition(templateInfo: TemplateInfo, start: number):
107108
/**
108109
* Flip the invalid "box in a banana" `([thing])` to the correct "banana in a box" `[(thing)]`.
109110
*/
110-
function convertBoundEventToTsTextChange(node: BoundEvent): readonly tss.TextChange[] {
111+
function convertBoundEventToTsTextChange(node: TmplAstBoundEvent): readonly tss.TextChange[] {
111112
const name = node.name;
112113
const boundSyntax = node.sourceSpan.toString();
113114
const expectedBoundSyntax = boundSyntax.replace(`(${name})`, `[(${name.slice(1, -1)})]`);

packages/language-service/src/codefixes/fix_missing_import.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ASTWithName} from '@angular/compiler';
9+
import {ASTWithName, TmplAstElement} from '@angular/compiler';
1010
import {ErrorCode as NgCompilerErrorCode, ngErrorCode} from '@angular/compiler-cli/src/ngtsc/diagnostics/index';
1111
import {PotentialDirective, PotentialImportMode, PotentialPipe} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
12-
import * as t from '@angular/compiler/src/render3/r3_ast'; // t for template AST
1312
import ts from 'typescript';
1413

1514
import {getTargetAtPosition, TargetNodeKind} from '../template_target';
@@ -52,7 +51,7 @@ function getCodeActions(
5251

5352
let matches: Set<PotentialDirective>|Set<PotentialPipe>;
5453
if (target.context.kind === TargetNodeKind.ElementInTagContext &&
55-
target.context.node instanceof t.Element) {
54+
target.context.node instanceof TmplAstElement) {
5655
const allPossibleDirectives = checker.getPotentialTemplateDirectives(templateInfo.component);
5756
matches = getDirectiveMatchesForElementTag(target.context.node, allPossibleDirectives);
5857
} else if (

packages/language-service/src/codefixes/fix_missing_member.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {findFirstMatchingNode} from '@angular/compiler-cli/src/ngtsc/typecheck/src/comments';
10-
import * as e from '@angular/compiler/src/expression_parser/ast'; // e for expression AST
119
import ts from 'typescript';
1210
import tss from 'typescript/lib/tsserverlibrary';
1311

packages/language-service/src/completions.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {AST, ASTWithSource, BindingPipe, BindingType, Call, EmptyExpr, ImplicitReceiver, LiteralPrimitive, ParsedEventType, ParseSourceSpan, PropertyRead, PropertyWrite, SafePropertyRead, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstElement, TmplAstNode, TmplAstReference, TmplAstTemplate, TmplAstText, TmplAstTextAttribute, TmplAstVariable} from '@angular/compiler';
9+
import {AST, ASTWithSource, BindingPipe, BindingType, Call, EmptyExpr, ImplicitReceiver, LiteralPrimitive, ParsedEventType, ParseSourceSpan, PropertyRead, PropertyWrite, SafePropertyRead, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstBoundEvent as BoundEvent, TmplAstElement, TmplAstNode, TmplAstReference, TmplAstSwitchBlock as SwitchBlock, TmplAstTemplate, TmplAstText, TmplAstTextAttribute, TmplAstTextAttribute as TextAttribute, TmplAstUnknownBlock as UnknownBlock, TmplAstVariable} from '@angular/compiler';
1010
import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core';
1111
import {CompletionKind, PotentialDirective, SymbolKind, TemplateDeclarationSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
12-
import {BoundEvent, DeferredBlock, SwitchBlock, TextAttribute, UnknownBlock} from '@angular/compiler/src/render3/r3_ast';
1312
import ts from 'typescript';
1413

1514
import {addAttributeCompletionEntries, AsciiSortPriority, AttributeCompletionKind, buildAnimationCompletionEntries, buildAttributeCompletionTable, getAttributeCompletionSymbol} from './attribute_completions';

packages/language-service/src/outlining_spans.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ParseLocation, ParseSourceSpan} from '@angular/compiler';
9+
import {ParseLocation, ParseSourceSpan, TmplAstBlockNode, TmplAstDeferredBlock, TmplAstForLoopBlock, TmplAstIfBlock, TmplAstNode, TmplAstRecursiveVisitor, tmplAstVisitAll} from '@angular/compiler';
1010
import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core';
1111
import {isExternalResource} from '@angular/compiler-cli/src/ngtsc/metadata';
1212
import {isNamedClassDeclaration} from '@angular/compiler-cli/src/ngtsc/reflection';
13-
import * as t from '@angular/compiler/src/render3/r3_ast'; // t for template AST
1413
import ts from 'typescript';
1514

1615
import {getFirstComponentForTemplateFile, isTypeScriptFile, toTextSpan} from './utils';
@@ -22,7 +21,7 @@ export function getOutliningSpans(compiler: NgCompiler, fileName: string): ts.Ou
2221
return [];
2322
}
2423

25-
const templatesInFile: Array<t.Node[]> = [];
24+
const templatesInFile: Array<TmplAstNode[]> = [];
2625
for (const stmt of sf.statements) {
2726
if (isNamedClassDeclaration(stmt)) {
2827
const resources = compiler.getComponentResources(stmt);
@@ -47,19 +46,19 @@ export function getOutliningSpans(compiler: NgCompiler, fileName: string): ts.Ou
4746
}
4847
}
4948

50-
class BlockVisitor extends t.RecursiveVisitor {
51-
readonly blocks = [] as Array<t.BlockNode>;
49+
class BlockVisitor extends TmplAstRecursiveVisitor {
50+
readonly blocks = [] as Array<TmplAstBlockNode>;
5251

53-
static getBlockSpans(templateNodes: t.Node[]): ts.OutliningSpan[] {
52+
static getBlockSpans(templateNodes: TmplAstNode[]): ts.OutliningSpan[] {
5453
const visitor = new BlockVisitor();
55-
t.visitAll(visitor, templateNodes);
54+
tmplAstVisitAll(visitor, templateNodes);
5655
const {blocks} = visitor;
5756
return blocks.map(block => {
5857
let mainBlockSpan = block.sourceSpan;
5958
// The source span of for loops and deferred blocks contain all parts (ForLoopBlockEmpty,
6059
// DeferredBlockLoading, etc.). The folding range should only include the main block span for
6160
// these.
62-
if (block instanceof t.ForLoopBlock || block instanceof t.DeferredBlock) {
61+
if (block instanceof TmplAstForLoopBlock || block instanceof TmplAstDeferredBlock) {
6362
mainBlockSpan = block.mainBlockSpan;
6463
}
6564
return {
@@ -75,10 +74,10 @@ class BlockVisitor extends t.RecursiveVisitor {
7574
});
7675
}
7776

78-
visit(node: t.Node) {
79-
if (node instanceof t.BlockNode
77+
visit(node: TmplAstNode) {
78+
if (node instanceof TmplAstBlockNode
8079
// Omit `IfBlock` because we include the branches individually
81-
&& !(node instanceof t.IfBlock)) {
80+
&& !(node instanceof TmplAstIfBlock)) {
8281
this.blocks.push(node);
8382
}
8483
}

packages/language-service/src/quick_info.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {AST, TmplAstBoundAttribute, TmplAstNode, TmplAstTextAttribute} from '@angular/compiler';
8+
import {AST, TmplAstBlockNode, TmplAstBoundAttribute, TmplAstDeferredTrigger, TmplAstNode, TmplAstTextAttribute} from '@angular/compiler';
99
import {NgCompiler} from '@angular/compiler-cli/src/ngtsc/core';
1010
import {DirectiveSymbol, DomBindingSymbol, ElementSymbol, InputBindingSymbol, OutputBindingSymbol, PipeSymbol, ReferenceSymbol, Symbol, SymbolKind, TcbLocation, VariableSymbol} from '@angular/compiler-cli/src/ngtsc/typecheck/api';
11-
import {BlockNode, DeferredTrigger} from '@angular/compiler/src/render3/r3_ast';
1211
import ts from 'typescript';
1312

1413
import {DisplayInfoKind, SYMBOL_PUNC, SYMBOL_SPACE, SYMBOL_TEXT} from './display_parts';
@@ -26,7 +25,7 @@ export class QuickInfoBuilder {
2625
private readonly positionDetails: TemplateTarget) {}
2726

2827
get(): ts.QuickInfo|undefined {
29-
if (this.node instanceof DeferredTrigger || this.node instanceof BlockNode) {
28+
if (this.node instanceof TmplAstDeferredTrigger || this.node instanceof TmplAstBlockNode) {
3029
return createQuickInfoForBuiltIn(this.node, this.positionDetails.position);
3130
}
3231

packages/language-service/src/quick_info_built_ins.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {AST, Call, ImplicitReceiver, ParseSourceSpan, PropertyRead, ThisReceiver, TmplAstDeferredBlock, TmplAstDeferredBlockError, TmplAstDeferredBlockLoading, TmplAstDeferredBlockPlaceholder, TmplAstNode} from '@angular/compiler';
9-
import {BlockNode, DeferredTrigger, ForLoopBlock, ForLoopBlockEmpty} from '@angular/compiler/src/render3/r3_ast';
8+
import {AST, Call, ImplicitReceiver, ParseSourceSpan, PropertyRead, ThisReceiver, TmplAstBlockNode, TmplAstDeferredBlock, TmplAstDeferredBlockError, TmplAstDeferredBlockLoading, TmplAstDeferredBlockPlaceholder, TmplAstDeferredTrigger, TmplAstForLoopBlock, TmplAstForLoopBlockEmpty, TmplAstNode} from '@angular/compiler';
109
import ts from 'typescript';
1110

1211
import {DisplayInfoKind, SYMBOL_TEXT} from './display_parts';
@@ -50,9 +49,10 @@ export function createNgTemplateQuickInfo(node: TmplAstNode|AST): ts.QuickInfo {
5049
}
5150

5251
export function createQuickInfoForBuiltIn(
53-
node: DeferredTrigger|BlockNode, cursorPositionInTemplate: number): ts.QuickInfo|undefined {
52+
node: TmplAstDeferredTrigger|TmplAstBlockNode, cursorPositionInTemplate: number): ts.QuickInfo|
53+
undefined {
5454
let partSpan: ParseSourceSpan;
55-
if (node instanceof DeferredTrigger) {
55+
if (node instanceof TmplAstDeferredTrigger) {
5656
if (node.prefetchSpan !== null && isWithin(cursorPositionInTemplate, node.prefetchSpan)) {
5757
partSpan = node.prefetchSpan;
5858
} else if (
@@ -68,10 +68,12 @@ export function createQuickInfoForBuiltIn(
6868
if (node instanceof TmplAstDeferredBlock || node instanceof TmplAstDeferredBlockError ||
6969
node instanceof TmplAstDeferredBlockLoading ||
7070
node instanceof TmplAstDeferredBlockPlaceholder ||
71-
node instanceof ForLoopBlockEmpty && isWithin(cursorPositionInTemplate, node.nameSpan)) {
71+
node instanceof TmplAstForLoopBlockEmpty &&
72+
isWithin(cursorPositionInTemplate, node.nameSpan)) {
7273
partSpan = node.nameSpan;
7374
} else if (
74-
node instanceof ForLoopBlock && isWithin(cursorPositionInTemplate, node.trackKeywordSpan)) {
75+
node instanceof TmplAstForLoopBlock &&
76+
isWithin(cursorPositionInTemplate, node.trackKeywordSpan)) {
7577
partSpan = node.trackKeywordSpan;
7678
} else {
7779
return undefined;

0 commit comments

Comments
 (0)