1 | /**
|
2 | * @license
|
3 | * Copyright Google LLC All Rights Reserved.
|
4 | *
|
5 | * Use of this source code is governed by an MIT-style license that can be
|
6 | * found in the LICENSE file at https://angular.dev/license
|
7 | */
|
8 | import { AST, LiteralPrimitive, ParseSourceSpan, PropertyRead, SafePropertyRead, TemplateEntity, TmplAstElement, TmplAstNode, TmplAstTemplate, TmplAstTextAttribute } from '@angular/compiler';
|
9 | import ts from 'typescript';
|
10 | import { AbsoluteFsPath } from '../../../../src/ngtsc/file_system';
|
11 | import { ErrorCode } from '../../diagnostics';
|
12 | import { Reference } from '../../imports';
|
13 | import { NgModuleMeta, PipeMeta } from '../../metadata';
|
14 | import { ClassDeclaration } from '../../reflection';
|
15 | import { FullTemplateMapping, NgTemplateDiagnostic, TypeCheckableDirectiveMeta } from './api';
|
16 | import { GlobalCompletion } from './completion';
|
17 | import { PotentialDirective, PotentialImport, PotentialImportMode, PotentialPipe } from './scope';
|
18 | import { ElementSymbol, Symbol, TcbLocation, TemplateSymbol } from './symbols';
|
19 | /**
|
20 | * Interface to the Angular Template Type Checker to extract diagnostics and intelligence from the
|
21 | * compiler's understanding of component templates.
|
22 | *
|
23 | * This interface is analogous to TypeScript's own `ts.TypeChecker` API.
|
24 | *
|
25 | * In general, this interface supports two kinds of operations:
|
26 | * - updating Type Check Blocks (TCB)s that capture the template in the form of TypeScript code
|
27 | * - querying information about available TCBs, including diagnostics
|
28 | *
|
29 | * Once a TCB is available, information about it can be queried. If no TCB is available to answer a
|
30 | * query, depending on the method either `null` will be returned or an error will be thrown.
|
31 | */
|
32 | export interface TemplateTypeChecker {
|
33 | /**
|
34 | * Retrieve the template in use for the given component.
|
35 | */
|
36 | getTemplate(component: ts.ClassDeclaration): TmplAstNode[] | null;
|
37 | /**
|
38 | * Get all `ts.Diagnostic`s currently available for the given `ts.SourceFile`.
|
39 | *
|
40 | * This method will fail (throw) if there are components within the `ts.SourceFile` that do not
|
41 | * have TCBs available.
|
42 | *
|
43 | * Generating a template type-checking program is expensive, and in some workflows (e.g. checking
|
44 | * an entire program before emit), it should ideally only be done once. The `optimizeFor` flag
|
45 | * allows the caller to hint to `getDiagnosticsForFile` (which internally will create a template
|
46 | * type-checking program if needed) whether the caller is interested in just the results of the
|
47 | * single file, or whether they plan to query about other files in the program. Based on this
|
48 | * flag, `getDiagnosticsForFile` will determine how much of the user's program to prepare for
|
49 | * checking as part of the template type-checking program it creates.
|
50 | */
|
51 | getDiagnosticsForFile(sf: ts.SourceFile, optimizeFor: OptimizeFor): ts.Diagnostic[];
|
52 | /**
|
53 | * Given a `shim` and position within the file, returns information for mapping back to a template
|
54 | * location.
|
55 | */
|
56 | getTemplateMappingAtTcbLocation(tcbLocation: TcbLocation): FullTemplateMapping | null;
|
57 | /**
|
58 | * Get all `ts.Diagnostic`s currently available that pertain to the given component.
|
59 | *
|
60 | * This method always runs in `OptimizeFor.SingleFile` mode.
|
61 | */
|
62 | getDiagnosticsForComponent(component: ts.ClassDeclaration): ts.Diagnostic[];
|
63 | /**
|
64 | * Ensures shims for the whole program are generated. This type of operation would be required by
|
65 | * operations like "find references" and "refactor/rename" because references may appear in type
|
66 | * check blocks generated from templates anywhere in the program.
|
67 | */
|
68 | generateAllTypeCheckBlocks(): void;
|
69 | /**
|
70 | * Returns `true` if the given file is in the record of known shims generated by the compiler,
|
71 | * `false` if we cannot find the file in the shim records.
|
72 | */
|
73 | isTrackedTypeCheckFile(filePath: AbsoluteFsPath): boolean;
|
74 | /**
|
75 | * Retrieve the top-level node representing the TCB for the given component.
|
76 | *
|
77 | * This can return `null` if there is no TCB available for the component.
|
78 | *
|
79 | * This method always runs in `OptimizeFor.SingleFile` mode.
|
80 | */
|
81 | getTypeCheckBlock(component: ts.ClassDeclaration): ts.Node | null;
|
82 | /**
|
83 | * Retrieves a `Symbol` for the node in a component's template.
|
84 | *
|
85 | * This method can return `null` if a valid `Symbol` cannot be determined for the node.
|
86 | *
|
87 | * @see Symbol
|
88 | */
|
89 | getSymbolOfNode(node: TmplAstElement, component: ts.ClassDeclaration): ElementSymbol | null;
|
90 | getSymbolOfNode(node: TmplAstTemplate, component: ts.ClassDeclaration): TemplateSymbol | null;
|
91 | getSymbolOfNode(node: AST | TmplAstNode, component: ts.ClassDeclaration): Symbol | null;
|
92 | /**
|
93 | * Get "global" `Completion`s in the given context.
|
94 | *
|
95 | * Global completions are completions in the global context, as opposed to completions within an
|
96 | * existing expression. For example, completing inside a new interpolation expression (`{{|}}`) or
|
97 | * inside a new property binding `[input]="|" should retrieve global completions, which will
|
98 | * include completions from the template's context component, as well as any local references or
|
99 | * template variables which are in scope for that expression.
|
100 | */
|
101 | getGlobalCompletions(context: TmplAstTemplate | null, component: ts.ClassDeclaration, node: AST | TmplAstNode): GlobalCompletion | null;
|
102 | /**
|
103 | * For the given expression node, retrieve a `TcbLocation` that can be used to perform
|
104 | * autocompletion at that point in the expression, if such a location exists.
|
105 | */
|
106 | getExpressionCompletionLocation(expr: PropertyRead | SafePropertyRead, component: ts.ClassDeclaration): TcbLocation | null;
|
107 | /**
|
108 | * For the given node represents a `LiteralPrimitive`(the `TextAttribute` represents a string
|
109 | * literal), retrieve a `TcbLocation` that can be used to perform autocompletion at that point in
|
110 | * the node, if such a location exists.
|
111 | */
|
112 | getLiteralCompletionLocation(strNode: LiteralPrimitive | TmplAstTextAttribute, component: ts.ClassDeclaration): TcbLocation | null;
|
113 | /**
|
114 | * Get basic metadata on the directives which are in scope or can be imported for the given
|
115 | * component.
|
116 | */
|
117 | getPotentialTemplateDirectives(component: ts.ClassDeclaration): PotentialDirective[];
|
118 | /**
|
119 | * Get basic metadata on the pipes which are in scope or can be imported for the given component.
|
120 | */
|
121 | getPotentialPipes(component: ts.ClassDeclaration): PotentialPipe[];
|
122 | /**
|
123 | * Retrieve a `Map` of potential template element tags, to either the `PotentialDirective` that
|
124 | * declares them (if the tag is from a directive/component), or `null` if the tag originates from
|
125 | * the DOM schema.
|
126 | */
|
127 | getPotentialElementTags(component: ts.ClassDeclaration): Map<string, PotentialDirective | null>;
|
128 | /**
|
129 | * In the context of an Angular trait, generate potential imports for a directive.
|
130 | */
|
131 | getPotentialImportsFor(toImport: Reference<ClassDeclaration>, inComponent: ts.ClassDeclaration, importMode: PotentialImportMode): ReadonlyArray<PotentialImport>;
|
132 | /**
|
133 | * Get the primary decorator for an Angular class (such as @Component). This does not work for
|
134 | * `@Injectable`.
|
135 | */
|
136 | getPrimaryAngularDecorator(target: ts.ClassDeclaration): ts.Decorator | null;
|
137 | /**
|
138 | * Get the class of the NgModule that owns this Angular trait. If the result is `null`, that
|
139 | * probably means the provided component is standalone.
|
140 | */
|
141 | getOwningNgModule(component: ts.ClassDeclaration): ts.ClassDeclaration | null;
|
142 | /**
|
143 | * Retrieve any potential DOM bindings for the given element.
|
144 | *
|
145 | * This returns an array of objects which list both the attribute and property names of each
|
146 | * binding, which are usually identical but can vary if the HTML attribute name is for example a
|
147 | * reserved keyword in JS, like the `for` attribute which corresponds to the `htmlFor` property.
|
148 | */
|
149 | getPotentialDomBindings(tagName: string): {
|
150 | attribute: string;
|
151 | property: string;
|
152 | }[];
|
153 | /**
|
154 | * Retrieve any potential DOM events.
|
155 | */
|
156 | getPotentialDomEvents(tagName: string): string[];
|
157 | /**
|
158 | * Retrieve the type checking engine's metadata for the given directive class, if available.
|
159 | */
|
160 | getDirectiveMetadata(dir: ts.ClassDeclaration): TypeCheckableDirectiveMeta | null;
|
161 | /**
|
162 | * Retrieve the type checking engine's metadata for the given NgModule class, if available.
|
163 | */
|
164 | getNgModuleMetadata(module: ts.ClassDeclaration): NgModuleMeta | null;
|
165 | /**
|
166 | * Retrieve the type checking engine's metadata for the given pipe class, if available.
|
167 | */
|
168 | getPipeMetadata(pipe: ts.ClassDeclaration): PipeMeta | null;
|
169 | /**
|
170 | * Gets the directives that have been used in a component's template.
|
171 | */
|
172 | getUsedDirectives(component: ts.ClassDeclaration): TypeCheckableDirectiveMeta[] | null;
|
173 | /**
|
174 | * Gets the pipes that have been used in a component's template.
|
175 | */
|
176 | getUsedPipes(component: ts.ClassDeclaration): string[] | null;
|
177 | /**
|
178 | * Reset the `TemplateTypeChecker`'s state for the given class, so that it will be recomputed on
|
179 | * the next request.
|
180 | */
|
181 | invalidateClass(clazz: ts.ClassDeclaration): void;
|
182 | /**
|
183 | * Gets the target of a template expression, if possible.
|
184 | * See `BoundTarget.getExpressionTarget` for more information.
|
185 | */
|
186 | getExpressionTarget(expression: AST, clazz: ts.ClassDeclaration): TemplateEntity | null;
|
187 | /**
|
188 | * Constructs a `ts.Diagnostic` for a given `ParseSourceSpan` within a template.
|
189 | */
|
190 | makeTemplateDiagnostic<T extends ErrorCode>(clazz: ts.ClassDeclaration, sourceSpan: ParseSourceSpan, category: ts.DiagnosticCategory, errorCode: T, message: string, relatedInformation?: {
|
191 | text: string;
|
192 | start: number;
|
193 | end: number;
|
194 | sourceFile: ts.SourceFile;
|
195 | }[]): NgTemplateDiagnostic<T>;
|
196 | }
|
197 | /**
|
198 | * Describes the scope of the caller's interest in template type-checking results.
|
199 | */
|
200 | export declare enum OptimizeFor {
|
201 | /**
|
202 | * Indicates that a consumer of a `TemplateTypeChecker` is only interested in results for a
|
203 | * given file, and wants them as fast as possible.
|
204 | *
|
205 | * Calling `TemplateTypeChecker` methods successively for multiple files while specifying
|
206 | * `OptimizeFor.SingleFile` can result in significant unnecessary overhead overall.
|
207 | */
|
208 | SingleFile = 0,
|
209 | /**
|
210 | * Indicates that a consumer of a `TemplateTypeChecker` intends to query for results pertaining
|
211 | * to the entire user program, and so the type-checker should internally optimize for this case.
|
212 | *
|
213 | * Initial calls to retrieve type-checking information may take longer, but repeated calls to
|
214 | * gather information for the whole user program will be significantly faster with this mode of
|
215 | * optimization.
|
216 | */
|
217 | WholeProgram = 1
|
218 | }
|