@angular/compiler-cli
Version:
Angular - the compiler CLI for Node.js
219 lines (218 loc) • 11 kB
TypeScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { AST, LiteralPrimitive, ParseSourceSpan, PropertyRead, SafePropertyRead, TemplateEntity, TmplAstElement, TmplAstNode, TmplAstTemplate, TmplAstTextAttribute } from '@angular/compiler';
import ts from 'typescript';
import { AbsoluteFsPath } from '../../../../src/ngtsc/file_system';
import { ErrorCode } from '../../diagnostics';
import { Reference } from '../../imports';
import { NgModuleMeta, PipeMeta } from '../../metadata';
import { ClassDeclaration } from '../../reflection';
import { FullSourceMapping, NgTemplateDiagnostic, TypeCheckableDirectiveMeta } from './api';
import { GlobalCompletion } from './completion';
import { PotentialDirective, PotentialImport, PotentialImportMode, PotentialPipe } from './scope';
import { ElementSymbol, Symbol, TcbLocation, TemplateSymbol } from './symbols';
/**
* Interface to the Angular Template Type Checker to extract diagnostics and intelligence from the
* compiler's understanding of component templates.
*
* This interface is analogous to TypeScript's own `ts.TypeChecker` API.
*
* In general, this interface supports two kinds of operations:
* - updating Type Check Blocks (TCB)s that capture the template in the form of TypeScript code
* - querying information about available TCBs, including diagnostics
*
* Once a TCB is available, information about it can be queried. If no TCB is available to answer a
* query, depending on the method either `null` will be returned or an error will be thrown.
*/
export interface TemplateTypeChecker {
/**
* Retrieve the template in use for the given component.
*/
getTemplate(component: ts.ClassDeclaration, optimizeFor?: OptimizeFor): TmplAstNode[] | null;
/**
* Get all `ts.Diagnostic`s currently available for the given `ts.SourceFile`.
*
* This method will fail (throw) if there are components within the `ts.SourceFile` that do not
* have TCBs available.
*
* Generating a template type-checking program is expensive, and in some workflows (e.g. checking
* an entire program before emit), it should ideally only be done once. The `optimizeFor` flag
* allows the caller to hint to `getDiagnosticsForFile` (which internally will create a template
* type-checking program if needed) whether the caller is interested in just the results of the
* single file, or whether they plan to query about other files in the program. Based on this
* flag, `getDiagnosticsForFile` will determine how much of the user's program to prepare for
* checking as part of the template type-checking program it creates.
*/
getDiagnosticsForFile(sf: ts.SourceFile, optimizeFor: OptimizeFor): ts.Diagnostic[];
/**
* Given a `shim` and position within the file, returns information for mapping back to a source
* location.
*/
getSourceMappingAtTcbLocation(tcbLocation: TcbLocation): FullSourceMapping | null;
/**
* Get all `ts.Diagnostic`s currently available that pertain to the given component.
*
* This method always runs in `OptimizeFor.SingleFile` mode.
*/
getDiagnosticsForComponent(component: ts.ClassDeclaration): ts.Diagnostic[];
/**
* Ensures shims for the whole program are generated. This type of operation would be required by
* operations like "find references" and "refactor/rename" because references may appear in type
* check blocks generated from templates anywhere in the program.
*/
generateAllTypeCheckBlocks(): void;
/**
* Returns `true` if the given file is in the record of known shims generated by the compiler,
* `false` if we cannot find the file in the shim records.
*/
isTrackedTypeCheckFile(filePath: AbsoluteFsPath): boolean;
/**
* Retrieve the top-level node representing the TCB for the given component.
*
* This can return `null` if there is no TCB available for the component.
*
* This method always runs in `OptimizeFor.SingleFile` mode.
*/
getTypeCheckBlock(component: ts.ClassDeclaration): ts.Node | null;
/**
* Retrieves a `Symbol` for the node in a component's template.
*
* This method can return `null` if a valid `Symbol` cannot be determined for the node.
*
* @see Symbol
*/
getSymbolOfNode(node: TmplAstElement, component: ts.ClassDeclaration): ElementSymbol | null;
getSymbolOfNode(node: TmplAstTemplate, component: ts.ClassDeclaration): TemplateSymbol | null;
getSymbolOfNode(node: AST | TmplAstNode, component: ts.ClassDeclaration): Symbol | null;
/**
* Get "global" `Completion`s in the given context.
*
* Global completions are completions in the global context, as opposed to completions within an
* existing expression. For example, completing inside a new interpolation expression (`{{|}}`) or
* inside a new property binding `[input]="|" should retrieve global completions, which will
* include completions from the template's context component, as well as any local references or
* template variables which are in scope for that expression.
*/
getGlobalCompletions(context: TmplAstTemplate | null, component: ts.ClassDeclaration, node: AST | TmplAstNode): GlobalCompletion | null;
/**
* 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): TcbLocation | null;
/**
* For the given node represents a `LiteralPrimitive`(the `TextAttribute` represents a string
* 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): TcbLocation | null;
/**
* Get basic metadata on the directives which are in scope or can be imported for the given
* component.
*/
getPotentialTemplateDirectives(component: ts.ClassDeclaration): PotentialDirective[];
/**
* Get basic metadata on the pipes which are in scope or can be imported for the given component.
*/
getPotentialPipes(component: ts.ClassDeclaration): PotentialPipe[];
/**
* Retrieve a `Map` of potential template element tags, to either the `PotentialDirective` that
* declares them (if the tag is from a directive/component), or `null` if the tag originates from
* the DOM schema.
*/
getPotentialElementTags(component: ts.ClassDeclaration): Map<string, PotentialDirective | null>;
/**
* In the context of an Angular trait, generate potential imports for a directive.
*/
getPotentialImportsFor(toImport: Reference<ClassDeclaration>, inContext: ts.Node, importMode: PotentialImportMode): ReadonlyArray<PotentialImport>;
/**
* Get the primary decorator for an Angular class (such as @Component). This does not work for
* `@Injectable`.
*/
getPrimaryAngularDecorator(target: ts.ClassDeclaration): ts.Decorator | null;
/**
* Get the class of the NgModule that owns this Angular trait. If the result is `null`, that
* probably means the provided component is standalone.
*/
getOwningNgModule(component: ts.ClassDeclaration): ts.ClassDeclaration | null;
/**
* Retrieve any potential DOM bindings for the given element.
*
* This returns an array of objects which list both the attribute and property names of each
* binding, which are usually identical but can vary if the HTML attribute name is for example a
* reserved keyword in JS, like the `for` attribute which corresponds to the `htmlFor` property.
*/
getPotentialDomBindings(tagName: string): {
attribute: string;
property: string;
}[];
/**
* Retrieve any potential DOM events.
*/
getPotentialDomEvents(tagName: string): string[];
/**
* Retrieve the type checking engine's metadata for the given directive class, if available.
*/
getDirectiveMetadata(dir: ts.ClassDeclaration): TypeCheckableDirectiveMeta | null;
/**
* Retrieve the type checking engine's metadata for the given NgModule class, if available.
*/
getNgModuleMetadata(module: ts.ClassDeclaration): NgModuleMeta | null;
/**
* Retrieve the type checking engine's metadata for the given pipe class, if available.
*/
getPipeMetadata(pipe: ts.ClassDeclaration): PipeMeta | null;
/**
* Gets the directives that have been used in a component's template.
*/
getUsedDirectives(component: ts.ClassDeclaration): TypeCheckableDirectiveMeta[] | null;
/**
* Gets the pipes that have been used in a component's template.
*/
getUsedPipes(component: ts.ClassDeclaration): string[] | null;
/**
* Reset the `TemplateTypeChecker`'s state for the given class, so that it will be recomputed on
* the next request.
*/
invalidateClass(clazz: ts.ClassDeclaration): void;
/**
* Gets the target of a template expression, if possible.
* See `BoundTarget.getExpressionTarget` for more information.
*/
getExpressionTarget(expression: AST, clazz: ts.ClassDeclaration): TemplateEntity | null;
/**
* Constructs a `ts.Diagnostic` for a given `ParseSourceSpan` within a template.
*/
makeTemplateDiagnostic<T extends ErrorCode>(clazz: ts.ClassDeclaration, sourceSpan: ParseSourceSpan, category: ts.DiagnosticCategory, errorCode: T, message: string, relatedInformation?: {
text: string;
start: number;
end: number;
sourceFile: ts.SourceFile;
}[]): NgTemplateDiagnostic<T>;
}
/**
* Describes the scope of the caller's interest in template type-checking results.
*/
export declare enum OptimizeFor {
/**
* Indicates that a consumer of a `TemplateTypeChecker` is only interested in results for a
* given file, and wants them as fast as possible.
*
* Calling `TemplateTypeChecker` methods successively for multiple files while specifying
* `OptimizeFor.SingleFile` can result in significant unnecessary overhead overall.
*/
SingleFile = 0,
/**
* Indicates that a consumer of a `TemplateTypeChecker` intends to query for results pertaining
* to the entire user program, and so the type-checker should internally optimize for this case.
*
* Initial calls to retrieve type-checking information may take longer, but repeated calls to
* gather information for the whole user program will be significantly faster with this mode of
* optimization.
*/
WholeProgram = 1
}