first commit

This commit is contained in:
2024-01-19 11:09:11 +01:00
commit b18af7a943
29473 changed files with 4500547 additions and 0 deletions

9
node_modules/@angular/compiler-cli/src/bin/ng_xi18n.d.ts generated vendored Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/env node
/**
* @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.io/license
*/
import 'reflect-metadata';

9
node_modules/@angular/compiler-cli/src/bin/ngc.d.ts generated vendored Executable file
View File

@@ -0,0 +1,9 @@
#!/usr/bin/env node
/**
* @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.io/license
*/
import 'reflect-metadata';

8
node_modules/@angular/compiler-cli/src/extract_i18n.d.ts generated vendored Executable file
View File

@@ -0,0 +1,8 @@
/**
* @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.io/license
*/
export declare function mainXi18n(args: string[], consoleError?: (msg: string) => void): number;

29
node_modules/@angular/compiler-cli/src/main.d.ts generated vendored Executable file
View File

@@ -0,0 +1,29 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { ParsedConfiguration } from './perform_compile';
import * as api from './transformers/api';
export declare function main(args: string[], consoleError?: (s: string) => void, config?: NgcParsedConfiguration, customTransformers?: api.CustomTransformers, programReuse?: {
program: api.Program | undefined;
}, modifiedResourceFiles?: Set<string> | null): number;
export declare function mainDiagnosticsForTest(args: string[], config?: NgcParsedConfiguration, programReuse?: {
program: api.Program | undefined;
}, modifiedResourceFiles?: Set<string> | null): {
exitCode: number;
diagnostics: ReadonlyArray<ts.Diagnostic>;
};
export interface NgcParsedConfiguration extends ParsedConfiguration {
watch?: boolean;
}
export declare function readNgcCommandLineAndConfiguration(args: string[]): NgcParsedConfiguration;
export declare function readCommandLineAndConfiguration(args: string[], existingOptions?: api.CompilerOptions, ngCmdLineOptions?: string[]): ParsedConfiguration;
export declare function watchMode(project: string, options: api.CompilerOptions, consoleError: (s: string) => void): {
close: () => void;
ready: (cb: () => void) => void;
firstCompileResult: readonly ts.Diagnostic[];
};

View File

@@ -0,0 +1,19 @@
/**
* @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.io/license
*/
export * from './src/api';
export * from './src/di';
export * from './src/diagnostics';
export * from './src/evaluation';
export * from './src/factory';
export * from './src/injectable_registry';
export * from './src/metadata';
export * from './src/debug_info';
export * from './src/references_registry';
export * from './src/schema';
export * from './src/util';
export * from './src/input_transforms';

View File

@@ -0,0 +1,82 @@
/**
* @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.io/license
*/
/**
* Resolves and loads resource files that are referenced in Angular metadata.
*
* Note that `preload()` and `load()` take a `resolvedUrl`, which can be found
* by calling `resolve()`. These two steps are separated because sometimes the
* resolved URL to the resource is needed as well as its contents.
*/
export interface ResourceLoader {
/**
* True if this resource loader can preload resources.
*
* Sometimes a `ResourceLoader` is not able to do asynchronous pre-loading of resources.
*/
canPreload: boolean;
/**
* If true, the resource loader is able to preprocess inline resources.
*/
canPreprocess: boolean;
/**
* Resolve the url of a resource relative to the file that contains the reference to it.
* The return value of this method can be used in the `load()` and `preload()` methods.
*
* @param url The, possibly relative, url of the resource.
* @param fromFile The path to the file that contains the URL of the resource.
* @returns A resolved url of resource.
* @throws An error if the resource cannot be resolved.
*/
resolve(file: string, basePath: string): string;
/**
* Preload the specified resource, asynchronously. Once the resource is loaded, its value
* should be cached so it can be accessed synchronously via the `load()` method.
*
* @param resolvedUrl The url (resolved by a call to `resolve()`) of the resource to preload.
* @param context Information regarding the resource such as the type and containing file.
* @returns A Promise that is resolved once the resource has been loaded or `undefined`
* if the file has already been loaded.
* @throws An Error if pre-loading is not available.
*/
preload(resolvedUrl: string, context: ResourceLoaderContext): Promise<void> | undefined;
/**
* Preprocess the content data of an inline resource, asynchronously.
*
* @param data The existing content data from the inline resource.
* @param context Information regarding the resource such as the type and containing file.
* @returns A Promise that resolves to the processed data. If no processing occurs, the
* same data string that was passed to the function will be resolved.
*/
preprocessInline(data: string, context: ResourceLoaderContext): Promise<string>;
/**
* Load the resource at the given url, synchronously.
*
* The contents of the resource may have been cached by a previous call to `preload()`.
*
* @param resolvedUrl The url (resolved by a call to `resolve()`) of the resource to load.
* @returns The contents of the resource.
*/
load(resolvedUrl: string): string;
}
/**
* Contextual information used by members of the ResourceLoader interface.
*/
export interface ResourceLoaderContext {
/**
* The type of the component resource.
* * Resources referenced via a component's `styles` or `styleUrls` properties are of
* type `style`.
* * Resources referenced via a component's `template` or `templateUrl` properties are of type
* `template`.
*/
type: 'style' | 'template';
/**
* The absolute path to the file that contains the resource or reference to the resource.
*/
containingFile: string;
}

View File

@@ -0,0 +1,10 @@
/**
* @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.io/license
*/
import { R3ClassDebugInfo } from '@angular/compiler';
import { DeclarationNode, ReflectionHost } from '../../../reflection';
export declare function extractClassDebugInfo(clazz: DeclarationNode, reflection: ReflectionHost, rootDirs: ReadonlyArray<string>, forbidOrphanRendering: boolean): R3ClassDebugInfo | null;

View File

@@ -0,0 +1,38 @@
/**
* @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.io/license
*/
import { R3DependencyMetadata } from '@angular/compiler';
import { ClassDeclaration, CtorParameter, ReflectionHost, UnavailableValue } from '../../../reflection';
import { CompilationMode } from '../../../transform';
export type ConstructorDeps = {
deps: R3DependencyMetadata[];
} | {
deps: null;
errors: ConstructorDepError[];
};
export interface ConstructorDepError {
index: number;
param: CtorParameter;
reason: UnavailableValue;
}
export declare function getConstructorDependencies(clazz: ClassDeclaration, reflector: ReflectionHost, isCore: boolean, compilationMode: CompilationMode): ConstructorDeps | null;
/**
* Convert `ConstructorDeps` into the `R3DependencyMetadata` array for those deps if they're valid,
* or into an `'invalid'` signal if they're not.
*
* This is a companion function to `validateConstructorDependencies` which accepts invalid deps.
*/
export declare function unwrapConstructorDependencies(deps: ConstructorDeps | null): R3DependencyMetadata[] | 'invalid' | null;
export declare function getValidConstructorDependencies(clazz: ClassDeclaration, reflector: ReflectionHost, isCore: boolean, compilationMode: CompilationMode): R3DependencyMetadata[] | null;
/**
* Validate that `ConstructorDeps` does not have any invalid dependencies and convert them into the
* `R3DependencyMetadata` array if so, or raise a diagnostic if some deps are invalid.
*
* This is a companion function to `unwrapConstructorDependencies` which does not accept invalid
* deps.
*/
export declare function validateConstructorDependencies(clazz: ClassDeclaration, deps: ConstructorDeps | null): R3DependencyMetadata[] | null;

View File

@@ -0,0 +1,52 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { FatalDiagnosticError } from '../../../diagnostics';
import { Reference } from '../../../imports';
import { HostDirectiveMeta, MetadataReader } from '../../../metadata';
import { PartialEvaluator, ResolvedValue } from '../../../partial_evaluator';
import { ClassDeclaration, ReflectionHost } from '../../../reflection';
import { DeclarationData, LocalModuleScopeRegistry } from '../../../scope';
import { InjectableClassRegistry } from './injectable_registry';
/**
* Create a `ts.Diagnostic` which indicates the given class is part of the declarations of two or
* more NgModules.
*
* The resulting `ts.Diagnostic` will have a context entry for each NgModule showing the point where
* the directive/pipe exists in its `declarations` (if possible).
*/
export declare function makeDuplicateDeclarationError(node: ClassDeclaration, data: DeclarationData[], kind: string): ts.Diagnostic;
/**
* Creates a `FatalDiagnosticError` for a node that did not evaluate to the expected type. The
* diagnostic that is created will include details on why the value is incorrect, i.e. it includes
* a representation of the actual type that was unsupported, or in the case of a dynamic value the
* trace to the node where the dynamic value originated.
*
* @param node The node for which the diagnostic should be produced.
* @param value The evaluated value that has the wrong type.
* @param messageText The message text of the error.
*/
export declare function createValueHasWrongTypeError(node: ts.Node, value: ResolvedValue, messageText: string): FatalDiagnosticError;
/**
* Gets the diagnostics for a set of provider classes.
* @param providerClasses Classes that should be checked.
* @param providersDeclaration Node that declares the providers array.
* @param registry Registry that keeps track of the registered injectable classes.
*/
export declare function getProviderDiagnostics(providerClasses: Set<Reference<ClassDeclaration>>, providersDeclaration: ts.Expression, registry: InjectableClassRegistry): ts.Diagnostic[];
export declare function getDirectiveDiagnostics(node: ClassDeclaration, injectableRegistry: InjectableClassRegistry, evaluator: PartialEvaluator, reflector: ReflectionHost, scopeRegistry: LocalModuleScopeRegistry, strictInjectionParameters: boolean, kind: 'Directive' | 'Component'): ts.Diagnostic[] | null;
export declare function validateHostDirectives(origin: ts.Expression, hostDirectives: HostDirectiveMeta[], metaReader: MetadataReader): ts.DiagnosticWithLocation[];
export declare function getUndecoratedClassWithAngularFeaturesDiagnostic(node: ClassDeclaration): ts.Diagnostic;
export declare function checkInheritanceOfInjectable(node: ClassDeclaration, injectableRegistry: InjectableClassRegistry, reflector: ReflectionHost, evaluator: PartialEvaluator, strictInjectionParameters: boolean, kind: 'Directive' | 'Component' | 'Pipe' | 'Injectable'): ts.Diagnostic | null;
interface ClassWithCtor {
ref: Reference<ClassDeclaration>;
isCtorValid: boolean;
isDecorated: boolean;
}
export declare function findInheritedCtor(node: ClassDeclaration, injectableRegistry: InjectableClassRegistry, reflector: ReflectionHost, evaluator: PartialEvaluator): ClassWithCtor | null;
export {};

View File

@@ -0,0 +1,25 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { Reference } from '../../../imports';
import { PartialEvaluator, ResolvedValue } from '../../../partial_evaluator';
import { ClassDeclaration, Decorator } from '../../../reflection';
export declare function resolveEnumValue(evaluator: PartialEvaluator, metadata: Map<string, ts.Expression>, field: string, enumSymbolName: string): number | null;
/**
* Resolves a EncapsulationEnum expression locally on best effort without having to calculate the
* reference. This suites local compilation mode where each file is compiled individually.
*
* The static analysis is still needed in local compilation mode since the value of this enum will
* be used later to decide the generated code for styles.
*/
export declare function resolveEncapsulationEnumValueLocally(expr?: ts.Expression): number | null;
/** Determines if the result of an evaluation is a string array. */
export declare function isStringArray(resolvedValue: ResolvedValue): resolvedValue is string[];
export declare function isClassReferenceArray(resolvedValue: ResolvedValue): resolvedValue is Reference<ClassDeclaration>[];
export declare function isArray(value: ResolvedValue): value is Array<ResolvedValue>;
export declare function resolveLiteral(decorator: Decorator, literalCache: Map<Decorator, ts.ObjectLiteralExpression>): ts.ObjectLiteralExpression;

View File

@@ -0,0 +1,12 @@
/**
* @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.io/license
*/
import { R3FactoryMetadata } from '@angular/compiler';
import { CompileResult } from '../../../transform';
export type CompileFactoryFn = (metadata: R3FactoryMetadata) => CompileResult;
export declare function compileNgFactoryDefField(metadata: R3FactoryMetadata): CompileResult;
export declare function compileDeclareFactory(metadata: R3FactoryMetadata): CompileResult;

View File

@@ -0,0 +1,24 @@
/**
* @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.io/license
*/
import { R3DependencyMetadata } from '@angular/compiler';
import { ClassDeclaration, ReflectionHost } from '../../../reflection';
export interface InjectableMeta {
ctorDeps: R3DependencyMetadata[] | 'invalid' | null;
}
/**
* Registry that keeps track of classes that can be constructed via dependency injection (e.g.
* injectables, directives, pipes).
*/
export declare class InjectableClassRegistry {
private host;
private isCore;
private classes;
constructor(host: ReflectionHost, isCore: boolean);
registerInjectable(declaration: ClassDeclaration, meta: InjectableMeta): void;
getInjectableMeta(declaration: ClassDeclaration): InjectableMeta | null;
}

View File

@@ -0,0 +1,11 @@
/*!
* @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.io/license
*/
import { ClassPropertyMapping, InputMapping } from '../../../metadata';
import { CompileResult } from '../../../transform';
/** Generates additional fields to be added to a class that has inputs with transform functions. */
export declare function compileInputTransformFields(inputs: ClassPropertyMapping<InputMapping>): CompileResult[];

View File

@@ -0,0 +1,25 @@
/**
* @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.io/license
*/
import { R3ClassMetadata } from '@angular/compiler';
import ts from 'typescript';
import { DeclarationNode, Decorator, ReflectionHost } from '../../../reflection';
/**
* Given a class declaration, generate a call to `setClassMetadata` with the Angular metadata
* present on the class or its member fields. An ngDevMode guard is used to allow the call to be
* tree-shaken away, as the `setClassMetadata` invocation is only needed for testing purposes.
*
* If no such metadata is present, this function returns `null`. Otherwise, the call is returned
* as a `Statement` for inclusion along with the class.
*/
export declare function extractClassMetadata(clazz: DeclarationNode, reflection: ReflectionHost, isCore: boolean, annotateForClosureCompiler?: boolean, angularDecoratorTransform?: (dec: Decorator) => Decorator): R3ClassMetadata | null;
/**
* Recursively recreates all of the `Identifier` descendant nodes with a particular name inside
* of an AST node, thus removing any references to them. Useful if a particular node has to be
* taken from one place any emitted to another one exactly as it has been written.
*/
export declare function removeIdentifierReferences<T extends ts.Node>(node: T, names: string | Set<string>): T;

View File

@@ -0,0 +1,26 @@
/**
* @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.io/license
*/
import { Reference } from '../../../imports';
import { DeclarationNode } from '../../../reflection';
/**
* Implement this interface if you want DecoratorHandlers to register
* references that they find in their analysis of the code.
*/
export interface ReferencesRegistry {
/**
* Register one or more references in the registry.
* @param references A collection of references to register.
*/
add(source: DeclarationNode, ...references: Reference<DeclarationNode>[]): void;
}
/**
* This registry does nothing.
*/
export declare class NoopReferencesRegistry implements ReferencesRegistry {
add(source: DeclarationNode, ...references: Reference<DeclarationNode>[]): void;
}

View File

@@ -0,0 +1,11 @@
/**
* @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.io/license
*/
import { SchemaMetadata } from '@angular/compiler';
import ts from 'typescript';
import { PartialEvaluator } from '../../../partial_evaluator';
export declare function extractSchemas(rawExpr: ts.Expression, evaluator: PartialEvaluator, context: string): SchemaMetadata[];

View File

@@ -0,0 +1,102 @@
/**
* @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.io/license
*/
import { Expression, FactoryTarget, ParseSourceSpan, R3CompiledExpression, R3FactoryMetadata, R3Reference, Statement, WrappedNodeExpr } from '@angular/compiler';
import ts from 'typescript';
import { ImportedFile, ModuleResolver, Reference, ReferenceEmitter } from '../../../imports';
import { ForeignFunctionResolver, PartialEvaluator } from '../../../partial_evaluator';
import { ClassDeclaration, Decorator, Import, ImportedTypeValueReference, LocalTypeValueReference, ReflectionHost, TypeValueReference } from '../../../reflection';
import { CompileResult } from '../../../transform';
/**
* Convert a `TypeValueReference` to an `Expression` which refers to the type as a value.
*
* Local references are converted to a `WrappedNodeExpr` of the TypeScript expression, and non-local
* references are converted to an `ExternalExpr`. Note that this is only valid in the context of the
* file in which the `TypeValueReference` originated.
*/
export declare function valueReferenceToExpression(valueRef: LocalTypeValueReference | ImportedTypeValueReference): Expression;
export declare function valueReferenceToExpression(valueRef: TypeValueReference): Expression | null;
export declare function toR3Reference(origin: ts.Node, ref: Reference, context: ts.SourceFile, refEmitter: ReferenceEmitter): R3Reference;
export declare function isAngularCore(decorator: Decorator): decorator is Decorator & {
import: Import;
};
export declare function isAngularCoreReference(reference: Reference, symbolName: string): boolean;
export declare function findAngularDecorator(decorators: Decorator[], name: string, isCore: boolean): Decorator | undefined;
export declare function isAngularDecorator(decorator: Decorator, name: string, isCore: boolean): boolean;
/**
* Unwrap a `ts.Expression`, removing outer type-casts or parentheses until the expression is in its
* lowest level form.
*
* For example, the expression "(foo as Type)" unwraps to "foo".
*/
export declare function unwrapExpression(node: ts.Expression): ts.Expression;
/**
* If the given `node` is a forwardRef() expression then resolve its inner value, otherwise return
* `null`.
*
* @param node the forwardRef() expression to resolve
* @param reflector a ReflectionHost
* @returns the resolved expression, if the original expression was a forwardRef(), or `null`
* otherwise.
*/
export declare function tryUnwrapForwardRef(node: ts.Expression, reflector: ReflectionHost): ts.Expression | null;
/**
* A foreign function resolver for `staticallyResolve` which unwraps forwardRef() expressions.
*
* @param ref a Reference to the declaration of the function being called (which might be
* forwardRef)
* @param args the arguments to the invocation of the forwardRef expression
* @returns an unwrapped argument if `ref` pointed to forwardRef, or null otherwise
*/
export declare const forwardRefResolver: ForeignFunctionResolver;
/**
* Combines an array of resolver functions into a one.
* @param resolvers Resolvers to be combined.
*/
export declare function combineResolvers(resolvers: ForeignFunctionResolver[]): ForeignFunctionResolver;
export declare function isExpressionForwardReference(expr: Expression, context: ts.Node, contextSource: ts.SourceFile): boolean;
export declare function isWrappedTsNodeExpr(expr: Expression): expr is WrappedNodeExpr<ts.Node>;
export declare function readBaseClass(node: ClassDeclaration, reflector: ReflectionHost, evaluator: PartialEvaluator): Reference<ClassDeclaration> | 'dynamic' | null;
/**
* Wraps all functions in a given expression in parentheses. This is needed to avoid problems
* where Tsickle annotations added between analyse and transform phases in Angular may trigger
* automatic semicolon insertion, e.g. if a function is the expression in a `return` statement.
* More
* info can be found in Tsickle source code here:
* https://github.com/angular/tsickle/blob/d7974262571c8a17d684e5ba07680e1b1993afdd/src/jsdoc_transformer.ts#L1021
*
* @param expression Expression where functions should be wrapped in parentheses
*/
export declare function wrapFunctionExpressionsInParens(expression: ts.Expression): ts.Expression;
/**
* Resolves the given `rawProviders` into `ClassDeclarations` and returns
* a set containing those that are known to require a factory definition.
* @param rawProviders Expression that declared the providers array in the source.
*/
export declare function resolveProvidersRequiringFactory(rawProviders: ts.Expression, reflector: ReflectionHost, evaluator: PartialEvaluator): Set<Reference<ClassDeclaration>>;
/**
* Create an R3Reference for a class.
*
* The `value` is the exported declaration of the class from its source file.
* The `type` is an expression that would be used in the typings (.d.ts) files.
*/
export declare function wrapTypeReference(reflector: ReflectionHost, clazz: ClassDeclaration): R3Reference;
/** Creates a ParseSourceSpan for a TypeScript node. */
export declare function createSourceSpan(node: ts.Node): ParseSourceSpan;
/**
* Collate the factory and definition compiled results into an array of CompileResult objects.
*/
export declare function compileResults(fac: CompileResult, def: R3CompiledExpression, metadataStmt: Statement | null, propName: string, additionalFields: CompileResult[] | null, deferrableImports: Set<ts.ImportDeclaration> | null, debugInfo?: Statement | null): CompileResult[];
export declare function toFactoryMetadata(meta: Omit<R3FactoryMetadata, 'target'>, target: FactoryTarget): R3FactoryMetadata;
export declare function resolveImportedFile(moduleResolver: ModuleResolver, importedFile: ImportedFile, expr: Expression, origin: ts.SourceFile): ts.SourceFile | null;
/**
* Determines the most appropriate expression for diagnostic reporting purposes. If `expr` is
* contained within `container` then `expr` is used as origin node, otherwise `container` itself is
* used.
*/
export declare function getOriginNodeForDiagnostics(expr: ts.Expression, container: ts.Expression): ts.Expression;
export declare function isAbstractClassDeclaration(clazz: ClassDeclaration): boolean;

View File

@@ -0,0 +1,8 @@
/**
* @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.io/license
*/
export { ComponentDecoratorHandler } from './src/handler';

View File

@@ -0,0 +1,19 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { Cycle } from '../../../cycles';
import { Reference } from '../../../imports';
/**
* Generate a diagnostic related information object that describes a potential cyclic import path.
*/
export declare function makeCyclicImportInfo(ref: Reference, type: string, cycle: Cycle): ts.DiagnosticRelatedInformation;
/**
* Checks whether a selector is a valid custom element tag name.
* Based loosely on https://github.com/sindresorhus/validate-element-name.
*/
export declare function checkCustomElementSelectorForErrors(selector: string): string | null;

View File

@@ -0,0 +1,107 @@
/**
* @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.io/license
*/
import { ConstantPool } from '@angular/compiler';
import ts from 'typescript';
import { CycleAnalyzer, CycleHandlingStrategy } from '../../../cycles';
import { DeferredSymbolTracker, ModuleResolver, ReferenceEmitter } from '../../../imports';
import { DependencyTracker } from '../../../incremental/api';
import { SemanticDepGraphUpdater } from '../../../incremental/semantic_graph';
import { IndexingContext } from '../../../indexer';
import { HostDirectivesResolver, MetadataReader, MetadataRegistry, ResourceRegistry } from '../../../metadata';
import { PartialEvaluator } from '../../../partial_evaluator';
import { PerfRecorder } from '../../../perf';
import { ClassDeclaration, Decorator, ReflectionHost } from '../../../reflection';
import { ComponentScopeReader, DtsModuleScopeResolver, LocalModuleScopeRegistry, TypeCheckScopeRegistry } from '../../../scope';
import { AnalysisOutput, CompilationMode, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence, ResolveResult } from '../../../transform';
import { TypeCheckContext } from '../../../typecheck/api';
import { ExtendedTemplateChecker } from '../../../typecheck/extended/api';
import { Xi18nContext } from '../../../xi18n';
import { InjectableClassRegistry, ReferencesRegistry, ResourceLoader } from '../../common';
import { ComponentAnalysisData, ComponentResolutionData } from './metadata';
import { ComponentSymbol } from './symbol';
/**
* `DecoratorHandler` which handles the `@Component` annotation.
*/
export declare class ComponentDecoratorHandler implements DecoratorHandler<Decorator, ComponentAnalysisData, ComponentSymbol, ComponentResolutionData> {
private reflector;
private evaluator;
private metaRegistry;
private metaReader;
private scopeReader;
private dtsScopeReader;
private scopeRegistry;
private typeCheckScopeRegistry;
private resourceRegistry;
private isCore;
private strictCtorDeps;
private resourceLoader;
private rootDirs;
private defaultPreserveWhitespaces;
private i18nUseExternalIds;
private enableI18nLegacyMessageIdFormat;
private usePoisonedData;
private i18nNormalizeLineEndingsInICUs;
private moduleResolver;
private cycleAnalyzer;
private cycleHandlingStrategy;
private refEmitter;
private referencesRegistry;
private depTracker;
private injectableRegistry;
private semanticDepGraphUpdater;
private annotateForClosureCompiler;
private perf;
private hostDirectivesResolver;
private includeClassMetadata;
private readonly compilationMode;
private readonly deferredSymbolTracker;
private readonly forbidOrphanRendering;
private readonly enableBlockSyntax;
constructor(reflector: ReflectionHost, evaluator: PartialEvaluator, metaRegistry: MetadataRegistry, metaReader: MetadataReader, scopeReader: ComponentScopeReader, dtsScopeReader: DtsModuleScopeResolver, scopeRegistry: LocalModuleScopeRegistry, typeCheckScopeRegistry: TypeCheckScopeRegistry, resourceRegistry: ResourceRegistry, isCore: boolean, strictCtorDeps: boolean, resourceLoader: ResourceLoader, rootDirs: ReadonlyArray<string>, defaultPreserveWhitespaces: boolean, i18nUseExternalIds: boolean, enableI18nLegacyMessageIdFormat: boolean, usePoisonedData: boolean, i18nNormalizeLineEndingsInICUs: boolean, moduleResolver: ModuleResolver, cycleAnalyzer: CycleAnalyzer, cycleHandlingStrategy: CycleHandlingStrategy, refEmitter: ReferenceEmitter, referencesRegistry: ReferencesRegistry, depTracker: DependencyTracker | null, injectableRegistry: InjectableClassRegistry, semanticDepGraphUpdater: SemanticDepGraphUpdater | null, annotateForClosureCompiler: boolean, perf: PerfRecorder, hostDirectivesResolver: HostDirectivesResolver, includeClassMetadata: boolean, compilationMode: CompilationMode, deferredSymbolTracker: DeferredSymbolTracker, forbidOrphanRendering: boolean, enableBlockSyntax: boolean);
private literalCache;
private elementSchemaRegistry;
/**
* During the asynchronous preanalyze phase, it's necessary to parse the template to extract
* any potential <link> tags which might need to be loaded. This cache ensures that work is not
* thrown away, and the parsed template is reused during the analyze phase.
*/
private preanalyzeTemplateCache;
private preanalyzeStylesCache;
private extractTemplateOptions;
readonly precedence = HandlerPrecedence.PRIMARY;
readonly name = "ComponentDecoratorHandler";
detect(node: ClassDeclaration, decorators: Decorator[] | null): DetectResult<Decorator> | undefined;
preanalyze(node: ClassDeclaration, decorator: Readonly<Decorator>): Promise<void> | undefined;
analyze(node: ClassDeclaration, decorator: Readonly<Decorator>): AnalysisOutput<ComponentAnalysisData>;
symbol(node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>): ComponentSymbol;
register(node: ClassDeclaration, analysis: ComponentAnalysisData): void;
index(context: IndexingContext, node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>): null;
typeCheck(ctx: TypeCheckContext, node: ClassDeclaration, meta: Readonly<ComponentAnalysisData>): void;
extendedTemplateCheck(component: ts.ClassDeclaration, extendedTemplateChecker: ExtendedTemplateChecker): ts.Diagnostic[];
resolve(node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>, symbol: ComponentSymbol): ResolveResult<ComponentResolutionData>;
xi18n(ctx: Xi18nContext, node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>): void;
updateResources(node: ClassDeclaration, analysis: ComponentAnalysisData): void;
compileFull(node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>, resolution: Readonly<ComponentResolutionData>, pool: ConstantPool): CompileResult[];
compilePartial(node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>, resolution: Readonly<ComponentResolutionData>): CompileResult[];
compileLocal(node: ClassDeclaration, analysis: Readonly<ComponentAnalysisData>, pool: ConstantPool): CompileResult[];
/**
* Check whether adding an import from `origin` to the source-file corresponding to `expr` would
* create a cyclic import.
*
* @returns a `Cycle` object if a cycle would be created, otherwise `null`.
*/
private _checkForCyclicImport;
private maybeRecordSyntheticImport;
/**
* Resolves information about defer blocks dependencies to make it
* available for the final `compile` step.
*/
private resolveDeferBlocks;
/** Resolves the triggers of the defer block to the elements that they're pointing to. */
private resolveDeferTriggers;
}

View File

@@ -0,0 +1,65 @@
/**
* @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.io/license
*/
import { AnimationTriggerNames, R3ClassDebugInfo, R3ClassMetadata, R3ComponentMetadata, R3TemplateDependencyMetadata, SchemaMetadata } from '@angular/compiler';
import ts from 'typescript';
import { Reference } from '../../../imports';
import { ClassPropertyMapping, ComponentResources, DirectiveTypeCheckMeta, HostDirectiveMeta, InputMapping } from '../../../metadata';
import { ClassDeclaration } from '../../../reflection';
import { SubsetOfKeys } from '../../../util/src/typescript';
import { ParsedTemplateWithSource, StyleUrlMeta } from './resources';
/**
* These fields of `R3ComponentMetadata` are updated in the `resolve` phase.
*
* The `keyof R3ComponentMetadata &` condition ensures that only fields of `R3ComponentMetadata` can
* be included here.
*/
export type ComponentMetadataResolvedFields = SubsetOfKeys<R3ComponentMetadata<R3TemplateDependencyMetadata>, 'declarations' | 'declarationListEmitMode' | 'deferBlocks' | 'deferrableDeclToImportDecl'>;
export interface ComponentAnalysisData {
/**
* `meta` includes those fields of `R3ComponentMetadata` which are calculated at `analyze` time
* (not during resolve).
*/
meta: Omit<R3ComponentMetadata<R3TemplateDependencyMetadata>, ComponentMetadataResolvedFields>;
baseClass: Reference<ClassDeclaration> | 'dynamic' | null;
typeCheckMeta: DirectiveTypeCheckMeta;
template: ParsedTemplateWithSource;
classMetadata: R3ClassMetadata | null;
classDebugInfo: R3ClassDebugInfo | null;
inputs: ClassPropertyMapping<InputMapping>;
outputs: ClassPropertyMapping;
/**
* Providers extracted from the `providers` field of the component annotation which will require
* an Angular factory definition at runtime.
*/
providersRequiringFactory: Set<Reference<ClassDeclaration>> | null;
/**
* Providers extracted from the `viewProviders` field of the component annotation which will
* require an Angular factory definition at runtime.
*/
viewProvidersRequiringFactory: Set<Reference<ClassDeclaration>> | null;
resources: ComponentResources;
/**
* `styleUrls` extracted from the decorator, if present.
*/
styleUrls: StyleUrlMeta[] | null;
/**
* Inline stylesheets extracted from the decorator, if present.
*/
inlineStyles: string[] | null;
isPoisoned: boolean;
animationTriggerNames: AnimationTriggerNames | null;
rawImports: ts.Expression | null;
resolvedImports: Reference<ClassDeclaration>[] | null;
schemas: SchemaMetadata[] | null;
decorator: ts.Decorator | null;
/** Additional directives applied to the component host. */
hostDirectives: HostDirectiveMeta[] | null;
/** Raw expression that defined the host directives array. Used for diagnostics. */
rawHostDirectives: ts.Expression | null;
}
export type ComponentResolutionData = Pick<R3ComponentMetadata<R3TemplateDependencyMetadata>, ComponentMetadataResolvedFields>;

View File

@@ -0,0 +1,124 @@
/**
* @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.io/license
*/
import { InterpolationConfig, ParsedTemplate, ParseSourceFile, TmplAstNode } from '@angular/compiler';
import ts from 'typescript';
import { FatalDiagnosticError } from '../../../diagnostics';
import { DependencyTracker } from '../../../incremental/api';
import { Resource } from '../../../metadata';
import { PartialEvaluator } from '../../../partial_evaluator';
import { ClassDeclaration, DeclarationNode, Decorator } from '../../../reflection';
import { CompilationMode } from '../../../transform';
import { TemplateSourceMapping } from '../../../typecheck/api';
import { ResourceLoader } from '../../common';
/**
* The literal style url extracted from the decorator, along with metadata for diagnostics.
*/
export interface StyleUrlMeta {
url: string;
nodeForError: ts.Node;
source: ResourceTypeForDiagnostics.StylesheetFromTemplate | ResourceTypeForDiagnostics.StylesheetFromDecorator;
}
/**
* Information about the origin of a resource in the application code. This is used for creating
* diagnostics, so we can point to the root cause of an error in the application code.
*
* A template resource comes from the `templateUrl` property on the component decorator.
*
* Stylesheets resources can come from either the `styleUrls` property on the component decorator,
* or from inline `style` tags and style links on the external template.
*/
export declare const enum ResourceTypeForDiagnostics {
Template = 0,
StylesheetFromTemplate = 1,
StylesheetFromDecorator = 2
}
/**
* Information about the template which was extracted during parsing.
*
* This contains the actual parsed template as well as any metadata collected during its parsing,
* some of which might be useful for re-parsing the template with different options.
*/
export interface ParsedComponentTemplate extends ParsedTemplate {
/**
* The template AST, parsed in a manner which preserves source map information for diagnostics.
*
* Not useful for emit.
*/
diagNodes: TmplAstNode[];
/**
* The `ParseSourceFile` for the template.
*/
file: ParseSourceFile;
}
export interface ParsedTemplateWithSource extends ParsedComponentTemplate {
/** The string contents of the template. */
content: string;
sourceMapping: TemplateSourceMapping;
declaration: TemplateDeclaration;
}
/**
* Common fields extracted from the declaration of a template.
*/
interface CommonTemplateDeclaration {
preserveWhitespaces: boolean;
interpolationConfig: InterpolationConfig;
templateUrl: string;
resolvedTemplateUrl: string;
}
/**
* Information extracted from the declaration of an inline template.
*/
export interface InlineTemplateDeclaration extends CommonTemplateDeclaration {
isInline: true;
expression: ts.Expression;
}
/**
* Information extracted from the declaration of an external template.
*/
export interface ExternalTemplateDeclaration extends CommonTemplateDeclaration {
isInline: false;
templateUrlExpression: ts.Expression;
}
/**
* The declaration of a template extracted from a component decorator.
*
* This data is extracted and stored separately to facilitate re-interpreting the template
* declaration whenever the compiler is notified of a change to a template file. With this
* information, `ComponentDecoratorHandler` is able to re-read the template and update the component
* record without needing to parse the original decorator again.
*/
export type TemplateDeclaration = InlineTemplateDeclaration | ExternalTemplateDeclaration;
/** Determines the node to use for debugging purposes for the given TemplateDeclaration. */
export declare function getTemplateDeclarationNodeForError(declaration: TemplateDeclaration): ts.Node;
export interface ExtractTemplateOptions {
usePoisonedData: boolean;
enableI18nLegacyMessageIdFormat: boolean;
i18nNormalizeLineEndingsInICUs: boolean;
enableBlockSyntax: boolean;
}
export declare function extractTemplate(node: ClassDeclaration, template: TemplateDeclaration, evaluator: PartialEvaluator, depTracker: DependencyTracker | null, resourceLoader: ResourceLoader, options: ExtractTemplateOptions, compilationMode: CompilationMode): ParsedTemplateWithSource;
export declare function parseTemplateDeclaration(node: ClassDeclaration, decorator: Decorator, component: Map<string, ts.Expression>, containingFile: string, evaluator: PartialEvaluator, depTracker: DependencyTracker | null, resourceLoader: ResourceLoader, defaultPreserveWhitespaces: boolean): TemplateDeclaration;
export declare function preloadAndParseTemplate(evaluator: PartialEvaluator, resourceLoader: ResourceLoader, depTracker: DependencyTracker | null, preanalyzeTemplateCache: Map<DeclarationNode, ParsedTemplateWithSource>, node: ClassDeclaration, decorator: Decorator, component: Map<string, ts.Expression>, containingFile: string, defaultPreserveWhitespaces: boolean, options: ExtractTemplateOptions, compilationMode: CompilationMode): Promise<ParsedTemplateWithSource | null>;
export declare function makeResourceNotFoundError(file: string, nodeForError: ts.Node, resourceType: ResourceTypeForDiagnostics): FatalDiagnosticError;
/**
* Transforms the given decorator to inline external resources. i.e. if the decorator
* resolves to `@Component`, the `templateUrl` and `styleUrls` metadata fields will be
* transformed to their semantically-equivalent inline variants.
*
* This method is used for serializing decorators into the class metadata. The emitted
* class metadata should not refer to external resources as this would be inconsistent
* with the component definitions/declarations which already inline external resources.
*
* Additionally, the references to external resources would require libraries to ship
* external resources exclusively for the class metadata.
*/
export declare function transformDecoratorResources(dec: Decorator, component: Map<string, ts.Expression>, styles: string[], template: ParsedTemplateWithSource): Decorator;
export declare function extractComponentStyleUrls(evaluator: PartialEvaluator, component: Map<string, ts.Expression>): StyleUrlMeta[];
export declare function extractStyleResources(resourceLoader: ResourceLoader, component: Map<string, ts.Expression>, containingFile: string): ReadonlySet<Resource>;
export declare function _extractTemplateStyleUrls(template: ParsedTemplateWithSource): StyleUrlMeta[];
export {};

View File

@@ -0,0 +1,19 @@
/**
* @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.io/license
*/
import { SemanticReference, SemanticSymbol } from '../../../incremental/semantic_graph';
import { DirectiveSymbol } from '../../directive';
/**
* Represents an Angular component.
*/
export declare class ComponentSymbol extends DirectiveSymbol {
usedDirectives: SemanticReference[];
usedPipes: SemanticReference[];
isRemotelyScoped: boolean;
isEmitAffected(previousSymbol: SemanticSymbol, publicApiAffected: Set<SemanticSymbol>): boolean;
isTypeCheckBlockAffected(previousSymbol: SemanticSymbol, typeCheckApiAffected: Set<SemanticSymbol>): boolean;
}

View File

@@ -0,0 +1,25 @@
/**
* @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.io/license
*/
import { AnimationTriggerNames } from '@angular/compiler';
import ts from 'typescript';
import { Reference } from '../../../imports';
import { ForeignFunctionResolver, ResolvedValue } from '../../../partial_evaluator';
import { ClassDeclaration } from '../../../reflection';
/**
* Collect the animation names from the static evaluation result.
* @param value the static evaluation result of the animations
* @param animationTriggerNames the animation names collected and whether some names could not be
* statically evaluated.
*/
export declare function collectAnimationNames(value: ResolvedValue, animationTriggerNames: AnimationTriggerNames): void;
export declare function isAngularAnimationsReference(reference: Reference, symbolName: string): boolean;
export declare const animationTriggerResolver: ForeignFunctionResolver;
export declare function validateAndFlattenComponentImports(imports: ResolvedValue, expr: ts.Expression): {
imports: Reference<ClassDeclaration>[];
diagnostics: ts.Diagnostic[];
};

View File

@@ -0,0 +1,10 @@
/**
* @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.io/license
*/
export { DirectiveDecoratorHandler } from './src/handler';
export { DirectiveSymbol } from './src/symbol';
export * from './src/shared';

View File

@@ -0,0 +1,68 @@
/**
* @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.io/license
*/
import { ConstantPool, R3ClassMetadata, R3DirectiveMetadata } from '@angular/compiler';
import ts from 'typescript';
import { Reference, ReferenceEmitter } from '../../../imports';
import { SemanticDepGraphUpdater } from '../../../incremental/semantic_graph';
import { ClassPropertyMapping, DirectiveTypeCheckMeta, HostDirectiveMeta, InputMapping, MetadataReader, MetadataRegistry } from '../../../metadata';
import { PartialEvaluator } from '../../../partial_evaluator';
import { PerfRecorder } from '../../../perf';
import { ClassDeclaration, Decorator, ReflectionHost } from '../../../reflection';
import { LocalModuleScopeRegistry } from '../../../scope';
import { AnalysisOutput, CompilationMode, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence, ResolveResult } from '../../../transform';
import { InjectableClassRegistry, ReferencesRegistry } from '../../common';
import { DirectiveSymbol } from './symbol';
export interface DirectiveHandlerData {
baseClass: Reference<ClassDeclaration> | 'dynamic' | null;
typeCheckMeta: DirectiveTypeCheckMeta;
meta: R3DirectiveMetadata;
classMetadata: R3ClassMetadata | null;
providersRequiringFactory: Set<Reference<ClassDeclaration>> | null;
inputs: ClassPropertyMapping<InputMapping>;
outputs: ClassPropertyMapping;
isPoisoned: boolean;
isStructural: boolean;
decorator: ts.Decorator | null;
hostDirectives: HostDirectiveMeta[] | null;
rawHostDirectives: ts.Expression | null;
}
export declare class DirectiveDecoratorHandler implements DecoratorHandler<Decorator | null, DirectiveHandlerData, DirectiveSymbol, unknown> {
private reflector;
private evaluator;
private metaRegistry;
private scopeRegistry;
private metaReader;
private injectableRegistry;
private refEmitter;
private referencesRegistry;
private isCore;
private strictCtorDeps;
private semanticDepGraphUpdater;
private annotateForClosureCompiler;
private perf;
private includeClassMetadata;
private readonly compilationMode;
constructor(reflector: ReflectionHost, evaluator: PartialEvaluator, metaRegistry: MetadataRegistry, scopeRegistry: LocalModuleScopeRegistry, metaReader: MetadataReader, injectableRegistry: InjectableClassRegistry, refEmitter: ReferenceEmitter, referencesRegistry: ReferencesRegistry, isCore: boolean, strictCtorDeps: boolean, semanticDepGraphUpdater: SemanticDepGraphUpdater | null, annotateForClosureCompiler: boolean, perf: PerfRecorder, includeClassMetadata: boolean, compilationMode: CompilationMode);
readonly precedence = HandlerPrecedence.PRIMARY;
readonly name = "DirectiveDecoratorHandler";
detect(node: ClassDeclaration, decorators: Decorator[] | null): DetectResult<Decorator | null> | undefined;
analyze(node: ClassDeclaration, decorator: Readonly<Decorator | null>): AnalysisOutput<DirectiveHandlerData>;
symbol(node: ClassDeclaration, analysis: Readonly<DirectiveHandlerData>): DirectiveSymbol;
register(node: ClassDeclaration, analysis: Readonly<DirectiveHandlerData>): void;
resolve(node: ClassDeclaration, analysis: DirectiveHandlerData, symbol: DirectiveSymbol): ResolveResult<unknown>;
compileFull(node: ClassDeclaration, analysis: Readonly<DirectiveHandlerData>, resolution: Readonly<unknown>, pool: ConstantPool): CompileResult[];
compilePartial(node: ClassDeclaration, analysis: Readonly<DirectiveHandlerData>, resolution: Readonly<unknown>): CompileResult[];
compileLocal(node: ClassDeclaration, analysis: Readonly<DirectiveHandlerData>, pool: ConstantPool): CompileResult[];
/**
* Checks if a given class uses Angular features and returns the TypeScript node
* that indicated the usage. Classes are considered using Angular features if they
* contain class members that are either decorated with a known Angular decorator,
* or if they correspond to a known Angular lifecycle hook.
*/
private findClassFieldWithAngularFeatures;
}

View File

@@ -0,0 +1,34 @@
/**
* @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.io/license
*/
import { ParsedHostBindings, R3DirectiveMetadata, R3QueryMetadata } from '@angular/compiler';
import ts from 'typescript';
import { ReferenceEmitter } from '../../../imports';
import { ClassPropertyMapping, HostDirectiveMeta, InputMapping } from '../../../metadata';
import { PartialEvaluator } from '../../../partial_evaluator';
import { ClassDeclaration, ClassMember, Decorator, ReflectionHost } from '../../../reflection';
import { CompilationMode } from '../../../transform';
import { ReferencesRegistry } from '../../common';
/**
* Helper function to extract metadata from a `Directive` or `Component`. `Directive`s without a
* selector are allowed to be used for abstract base classes. These abstract directives should not
* appear in the declarations of an `NgModule` and additional verification is done when processing
* the module.
*/
export declare function extractDirectiveMetadata(clazz: ClassDeclaration, decorator: Readonly<Decorator | null>, reflector: ReflectionHost, evaluator: PartialEvaluator, refEmitter: ReferenceEmitter, referencesRegistry: ReferencesRegistry, isCore: boolean, annotateForClosureCompiler: boolean, compilationMode: CompilationMode, defaultSelector?: string | null): {
decorator: Map<string, ts.Expression>;
metadata: R3DirectiveMetadata;
inputs: ClassPropertyMapping<InputMapping>;
outputs: ClassPropertyMapping;
isStructural: boolean;
hostDirectives: HostDirectiveMeta[] | null;
rawHostDirectives: ts.Expression | null;
} | undefined;
export declare function extractQueryMetadata(exprNode: ts.Node, name: string, args: ReadonlyArray<ts.Expression>, propertyName: string, reflector: ReflectionHost, evaluator: PartialEvaluator): R3QueryMetadata;
export declare function extractHostBindings(members: ClassMember[], evaluator: PartialEvaluator, coreModule: string | undefined, metadata?: Map<string, ts.Expression>): ParsedHostBindings;
export declare function parseDirectiveStyles(directive: Map<string, ts.Expression>, evaluator: PartialEvaluator, compilationMode: CompilationMode): null | string[];
export declare function parseFieldStringArrayValue(directive: Map<string, ts.Expression>, field: string, evaluator: PartialEvaluator): null | string[];

View File

@@ -0,0 +1,26 @@
/**
* @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.io/license
*/
import { SemanticSymbol, SemanticTypeParameter } from '../../../incremental/semantic_graph';
import { ClassPropertyMapping, DirectiveTypeCheckMeta, InputMapping } from '../../../metadata';
import { ClassDeclaration } from '../../../reflection';
/**
* Represents an Angular directive. Components are represented by `ComponentSymbol`, which inherits
* from this symbol.
*/
export declare class DirectiveSymbol extends SemanticSymbol {
readonly selector: string | null;
readonly inputs: ClassPropertyMapping<InputMapping>;
readonly outputs: ClassPropertyMapping;
readonly exportAs: string[] | null;
readonly typeCheckMeta: DirectiveTypeCheckMeta;
readonly typeParameters: SemanticTypeParameter[] | null;
baseClass: SemanticSymbol | null;
constructor(decl: ClassDeclaration, selector: string | null, inputs: ClassPropertyMapping<InputMapping>, outputs: ClassPropertyMapping, exportAs: string[] | null, typeCheckMeta: DirectiveTypeCheckMeta, typeParameters: SemanticTypeParameter[] | null);
isPublicApiAffected(previousSymbol: SemanticSymbol): boolean;
isTypeCheckApiAffected(previousSymbol: SemanticSymbol): boolean;
}

View File

@@ -0,0 +1,13 @@
/**
* @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.io/license
*/
export { forwardRefResolver, NoopReferencesRegistry, ReferencesRegistry, ResourceLoader, ResourceLoaderContext } from './common';
export { ComponentDecoratorHandler } from './component';
export { DirectiveDecoratorHandler } from './directive';
export { NgModuleDecoratorHandler } from './ng_module';
export { InjectableDecoratorHandler } from './src/injectable';
export { PipeDecoratorHandler } from './src/pipe';

View File

@@ -0,0 +1,9 @@
/**
* @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.io/license
*/
export { NgModuleDecoratorHandler, NgModuleSymbol } from './src/handler';
export { createModuleWithProvidersResolver, isResolvedModuleWithProviders, ResolvedModuleWithProviders } from './src/module_with_providers';

View File

@@ -0,0 +1,117 @@
/**
* @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.io/license
*/
import { Expression, R3ClassMetadata, R3FactoryMetadata, R3InjectorMetadata, R3NgModuleMetadata, SchemaMetadata } from '@angular/compiler';
import ts from 'typescript';
import { Reference, ReferenceEmitter } from '../../../imports';
import { SemanticDepGraphUpdater, SemanticReference, SemanticSymbol } from '../../../incremental/semantic_graph';
import { ExportedProviderStatusResolver, MetadataReader, MetadataRegistry } from '../../../metadata';
import { PartialEvaluator } from '../../../partial_evaluator';
import { PerfRecorder } from '../../../perf';
import { ClassDeclaration, Decorator, ReflectionHost } from '../../../reflection';
import { LocalModuleScopeRegistry } from '../../../scope';
import { AnalysisOutput, CompilationMode, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence, ResolveResult } from '../../../transform';
import { InjectableClassRegistry, ReferencesRegistry } from '../../common';
export interface NgModuleAnalysis {
mod: R3NgModuleMetadata;
inj: R3InjectorMetadata;
fac: R3FactoryMetadata;
classMetadata: R3ClassMetadata | null;
declarations: Reference<ClassDeclaration>[];
rawDeclarations: ts.Expression | null;
schemas: SchemaMetadata[];
imports: TopLevelImportedExpression[];
importRefs: Reference<ClassDeclaration>[];
rawImports: ts.Expression | null;
exports: Reference<ClassDeclaration>[];
rawExports: ts.Expression | null;
id: Expression | null;
factorySymbolName: string;
providersRequiringFactory: Set<Reference<ClassDeclaration>> | null;
providers: ts.Expression | null;
remoteScopesMayRequireCycleProtection: boolean;
decorator: ts.Decorator | null;
}
export interface NgModuleResolution {
injectorImports: Expression[];
}
/**
* Represents an Angular NgModule.
*/
export declare class NgModuleSymbol extends SemanticSymbol {
readonly hasProviders: boolean;
private remotelyScopedComponents;
/**
* `SemanticSymbol`s of the transitive imports of this NgModule which came from imported
* standalone components.
*
* Standalone components are excluded/included in the `InjectorDef` emit output of the NgModule
* based on whether the compiler can prove that their transitive imports may contain exported
* providers, so a change in this set of symbols may affect the compilation output of this
* NgModule.
*/
private transitiveImportsFromStandaloneComponents;
constructor(decl: ClassDeclaration, hasProviders: boolean);
isPublicApiAffected(previousSymbol: SemanticSymbol): boolean;
isEmitAffected(previousSymbol: SemanticSymbol): boolean;
isTypeCheckApiAffected(previousSymbol: SemanticSymbol): boolean;
addRemotelyScopedComponent(component: SemanticSymbol, usedDirectives: SemanticReference[], usedPipes: SemanticReference[]): void;
addTransitiveImportFromStandaloneComponent(importedSymbol: SemanticSymbol): void;
}
/**
* Compiles @NgModule annotations to ngModuleDef fields.
*/
export declare class NgModuleDecoratorHandler implements DecoratorHandler<Decorator, NgModuleAnalysis, NgModuleSymbol, NgModuleResolution> {
private reflector;
private evaluator;
private metaReader;
private metaRegistry;
private scopeRegistry;
private referencesRegistry;
private exportedProviderStatusResolver;
private semanticDepGraphUpdater;
private isCore;
private refEmitter;
private annotateForClosureCompiler;
private onlyPublishPublicTypings;
private injectableRegistry;
private perf;
private includeClassMetadata;
private includeSelectorScope;
private readonly compilationMode;
constructor(reflector: ReflectionHost, evaluator: PartialEvaluator, metaReader: MetadataReader, metaRegistry: MetadataRegistry, scopeRegistry: LocalModuleScopeRegistry, referencesRegistry: ReferencesRegistry, exportedProviderStatusResolver: ExportedProviderStatusResolver, semanticDepGraphUpdater: SemanticDepGraphUpdater | null, isCore: boolean, refEmitter: ReferenceEmitter, annotateForClosureCompiler: boolean, onlyPublishPublicTypings: boolean, injectableRegistry: InjectableClassRegistry, perf: PerfRecorder, includeClassMetadata: boolean, includeSelectorScope: boolean, compilationMode: CompilationMode);
readonly precedence = HandlerPrecedence.PRIMARY;
readonly name = "NgModuleDecoratorHandler";
detect(node: ClassDeclaration, decorators: Decorator[] | null): DetectResult<Decorator> | undefined;
analyze(node: ClassDeclaration, decorator: Readonly<Decorator>): AnalysisOutput<NgModuleAnalysis>;
symbol(node: ClassDeclaration, analysis: NgModuleAnalysis): NgModuleSymbol;
register(node: ClassDeclaration, analysis: NgModuleAnalysis): void;
resolve(node: ClassDeclaration, analysis: Readonly<NgModuleAnalysis>): ResolveResult<NgModuleResolution>;
compileFull(node: ClassDeclaration, { inj, mod, fac, classMetadata, declarations, remoteScopesMayRequireCycleProtection }: Readonly<NgModuleAnalysis>, { injectorImports }: Readonly<NgModuleResolution>): CompileResult[];
compilePartial(node: ClassDeclaration, { inj, fac, mod, classMetadata }: Readonly<NgModuleAnalysis>, { injectorImports }: Readonly<NgModuleResolution>): CompileResult[];
compileLocal(node: ClassDeclaration, { inj, mod, fac, classMetadata, declarations, remoteScopesMayRequireCycleProtection }: Readonly<NgModuleAnalysis>): CompileResult[];
/**
* Add class metadata statements, if provided, to the `ngModuleStatements`.
*/
private insertMetadataStatement;
/**
* Add remote scoping statements, as needed, to the `ngModuleStatements`.
*/
private appendRemoteScopingStatements;
private compileNgModule;
private _toR3Reference;
private isClassDeclarationReference;
/**
* Compute a list of `Reference`s from a resolved metadata value.
*/
private resolveTypeList;
}
export interface TopLevelImportedExpression {
expression: ts.Expression;
resolvedReferences: Array<Reference<ClassDeclaration>>;
hasModuleWithProviders: boolean;
}

View File

@@ -0,0 +1,25 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { Reference } from '../../../imports';
import { ForeignFunctionResolver, SyntheticValue } from '../../../partial_evaluator';
import { ClassDeclaration, ReflectionHost } from '../../../reflection';
/**
* Creates a foreign function resolver to detect a `ModuleWithProviders<T>` type in a return type
* position of a function or method declaration. A `SyntheticValue` is produced if such a return
* type is recognized.
*
* @param reflector The reflection host to use for analyzing the syntax.
* @param isCore Whether the @angular/core package is being compiled.
*/
export declare function createModuleWithProvidersResolver(reflector: ReflectionHost, isCore: boolean): ForeignFunctionResolver;
export interface ResolvedModuleWithProviders {
ngModule: Reference<ClassDeclaration>;
mwpCall: ts.CallExpression;
}
export declare function isResolvedModuleWithProviders(sv: SyntheticValue<unknown>): sv is SyntheticValue<ResolvedModuleWithProviders>;

View File

@@ -0,0 +1,58 @@
/**
* @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.io/license
*/
import { R3ClassMetadata, R3DependencyMetadata, R3InjectableMetadata } from '@angular/compiler';
import { InjectableClassRegistry } from '../../annotations/common';
import { PartialEvaluator } from '../../partial_evaluator';
import { PerfRecorder } from '../../perf';
import { ClassDeclaration, Decorator, ReflectionHost } from '../../reflection';
import { AnalysisOutput, CompilationMode, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence, ResolveResult } from '../../transform';
export interface InjectableHandlerData {
meta: R3InjectableMetadata;
classMetadata: R3ClassMetadata | null;
ctorDeps: R3DependencyMetadata[] | 'invalid' | null;
needsFactory: boolean;
}
/**
* Adapts the `compileInjectable` compiler for `@Injectable` decorators to the Ivy compiler.
*/
export declare class InjectableDecoratorHandler implements DecoratorHandler<Decorator, InjectableHandlerData, null, unknown> {
private reflector;
private evaluator;
private isCore;
private strictCtorDeps;
private injectableRegistry;
private perf;
private includeClassMetadata;
private readonly compilationMode;
/**
* What to do if the injectable already contains a ɵprov property.
*
* If true then an error diagnostic is reported.
* If false then there is no error and a new ɵprov property is not added.
*/
private errorOnDuplicateProv;
constructor(reflector: ReflectionHost, evaluator: PartialEvaluator, isCore: boolean, strictCtorDeps: boolean, injectableRegistry: InjectableClassRegistry, perf: PerfRecorder, includeClassMetadata: boolean, compilationMode: CompilationMode,
/**
* What to do if the injectable already contains a ɵprov property.
*
* If true then an error diagnostic is reported.
* If false then there is no error and a new ɵprov property is not added.
*/
errorOnDuplicateProv?: boolean);
readonly precedence = HandlerPrecedence.SHARED;
readonly name = "InjectableDecoratorHandler";
detect(node: ClassDeclaration, decorators: Decorator[] | null): DetectResult<Decorator> | undefined;
analyze(node: ClassDeclaration, decorator: Readonly<Decorator>): AnalysisOutput<InjectableHandlerData>;
symbol(): null;
register(node: ClassDeclaration, analysis: InjectableHandlerData): void;
resolve(node: ClassDeclaration, analysis: Readonly<InjectableHandlerData>, symbol: null): ResolveResult<unknown>;
compileFull(node: ClassDeclaration, analysis: Readonly<InjectableHandlerData>): CompileResult[];
compilePartial(node: ClassDeclaration, analysis: Readonly<InjectableHandlerData>): CompileResult[];
compileLocal(node: ClassDeclaration, analysis: Readonly<InjectableHandlerData>): CompileResult[];
private compile;
}

View File

@@ -0,0 +1,54 @@
/**
* @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.io/license
*/
import { R3ClassMetadata, R3PipeMetadata } from '@angular/compiler';
import ts from 'typescript';
import { SemanticSymbol } from '../../incremental/semantic_graph';
import { MetadataRegistry } from '../../metadata';
import { PartialEvaluator } from '../../partial_evaluator';
import { PerfRecorder } from '../../perf';
import { ClassDeclaration, Decorator, ReflectionHost } from '../../reflection';
import { LocalModuleScopeRegistry } from '../../scope';
import { AnalysisOutput, CompilationMode, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence, ResolveResult } from '../../transform';
import { InjectableClassRegistry } from '../common';
export interface PipeHandlerData {
meta: R3PipeMetadata;
classMetadata: R3ClassMetadata | null;
pipeNameExpr: ts.Expression;
decorator: ts.Decorator | null;
}
/**
* Represents an Angular pipe.
*/
export declare class PipeSymbol extends SemanticSymbol {
readonly name: string;
constructor(decl: ClassDeclaration, name: string);
isPublicApiAffected(previousSymbol: SemanticSymbol): boolean;
isTypeCheckApiAffected(previousSymbol: SemanticSymbol): boolean;
}
export declare class PipeDecoratorHandler implements DecoratorHandler<Decorator, PipeHandlerData, PipeSymbol, unknown> {
private reflector;
private evaluator;
private metaRegistry;
private scopeRegistry;
private injectableRegistry;
private isCore;
private perf;
private includeClassMetadata;
private readonly compilationMode;
constructor(reflector: ReflectionHost, evaluator: PartialEvaluator, metaRegistry: MetadataRegistry, scopeRegistry: LocalModuleScopeRegistry, injectableRegistry: InjectableClassRegistry, isCore: boolean, perf: PerfRecorder, includeClassMetadata: boolean, compilationMode: CompilationMode);
readonly precedence = HandlerPrecedence.PRIMARY;
readonly name = "PipeDecoratorHandler";
detect(node: ClassDeclaration, decorators: Decorator[] | null): DetectResult<Decorator> | undefined;
analyze(clazz: ClassDeclaration, decorator: Readonly<Decorator>): AnalysisOutput<PipeHandlerData>;
symbol(node: ClassDeclaration, analysis: Readonly<PipeHandlerData>): PipeSymbol;
register(node: ClassDeclaration, analysis: Readonly<PipeHandlerData>): void;
resolve(node: ClassDeclaration): ResolveResult<unknown>;
compileFull(node: ClassDeclaration, analysis: Readonly<PipeHandlerData>): CompileResult[];
compilePartial(node: ClassDeclaration, analysis: Readonly<PipeHandlerData>): CompileResult[];
compileLocal(node: ClassDeclaration, analysis: Readonly<PipeHandlerData>): CompileResult[];
}

View File

@@ -0,0 +1,11 @@
/**
* @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.io/license
*/
export * from './src/adapter';
export * from './src/interfaces';
export * from './src/options';
export * from './src/public_options';

View File

@@ -0,0 +1,76 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath } from '../../../file_system';
import { ExtendedTsCompilerHost, UnifiedModulesHost } from './interfaces';
/**
* Names of methods from `ExtendedTsCompilerHost` that need to be provided by the
* `NgCompilerAdapter`.
*/
export type ExtendedCompilerHostMethods = 'getCanonicalFileName' | 'resolveModuleNames' | 'getCurrentDirectory' | 'getModifiedResourceFiles' | 'readResource' | 'resourceNameToFileName' | 'transformResource';
/**
* Adapter for `NgCompiler` that allows it to be used in various circumstances, such as
* command-line `ngc`, as a plugin to `ts_library` in Bazel, or from the Language Service.
*
* `NgCompilerAdapter` is a subset of the `NgCompilerHost` implementation of `ts.CompilerHost`
* which is relied upon by `NgCompiler`. A consumer of `NgCompiler` can therefore use the
* `NgCompilerHost` or implement `NgCompilerAdapter` itself.
*/
export interface NgCompilerAdapter extends Omit<ts.ModuleResolutionHost, 'getCurrentDirectory'>, Pick<ExtendedTsCompilerHost, 'getCurrentDirectory' | ExtendedCompilerHostMethods>, SourceFileTypeIdentifier {
/**
* A path to a single file which represents the entrypoint of an Angular Package Format library,
* if the current program is one.
*
* This is used to emit a flat module index if requested, and can be left `null` if that is not
* required.
*/
readonly entryPoint: AbsoluteFsPath | null;
/**
* An array of `ts.Diagnostic`s that occurred during construction of the `ts.Program`.
*/
readonly constructionDiagnostics: ts.Diagnostic[];
/**
* A `Set` of `ts.SourceFile`s which are internal to the program and should not be emitted as JS
* files.
*
* Often these are shim files such as `ngtypecheck` shims used for template type-checking in
* command-line ngc.
*/
readonly ignoreForEmit: Set<ts.SourceFile>;
/**
* A specialized interface provided in some environments (such as Bazel) which overrides how
* import specifiers are generated.
*
* If not required, this can be `null`.
*/
readonly unifiedModulesHost: UnifiedModulesHost | null;
/**
* Resolved list of root directories explicitly set in, or inferred from, the tsconfig.
*/
readonly rootDirs: ReadonlyArray<AbsoluteFsPath>;
}
export interface SourceFileTypeIdentifier {
/**
* Distinguishes between shim files added by Angular to the compilation process (both those
* intended for output, like ngfactory files, as well as internal shims like ngtypecheck files)
* and original files in the user's program.
*
* This is mostly used to limit type-checking operations to only user files. It should return
* `true` if a file was written by the user, and `false` if a file was added by the compiler.
*/
isShim(sf: ts.SourceFile): boolean;
/**
* Distinguishes between resource files added by Angular to the project and original files in the
* user's program.
*
* This is necessary only for the language service because it adds resource files as root files
* when they are read. This is done to indicate to TS Server that these resources are part of the
* project and ensures that projects are retained properly when navigating around the workspace.
*/
isResource(sf: ts.SourceFile): boolean;
}

View File

@@ -0,0 +1,98 @@
/**
* @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.io/license
*/
import ts from 'typescript';
/**
* A host backed by a build system which has a unified view of the module namespace.
*
* Such a build system supports the `fileNameToModuleName` method provided by certain build system
* integrations (such as the integration with Bazel). See the docs on `fileNameToModuleName` for
* more details.
*/
export interface UnifiedModulesHost {
/**
* Converts a file path to a module name that can be used as an `import ...`.
*
* For example, such a host might determine that `/absolute/path/to/monorepo/lib/importedFile.ts`
* should be imported using a module specifier of `monorepo/lib/importedFile`.
*/
fileNameToModuleName(importedFilePath: string, containingFilePath: string): string;
}
/**
* A host which additionally tracks and produces "resources" (HTML templates, CSS
* files, etc).
*/
export interface ResourceHost {
/**
* Converts a file path for a resource that is used in a source file or another resource
* into a filepath.
*
* The optional `fallbackResolve` method can be used as a way to attempt a fallback resolution if
* the implementation's `resourceNameToFileName` resolution fails.
*/
resourceNameToFileName(resourceName: string, containingFilePath: string, fallbackResolve?: (url: string, fromFile: string) => string | null): string | null;
/**
* Load a referenced resource either statically or asynchronously. If the host returns a
* `Promise<string>` it is assumed the user of the corresponding `Program` will call
* `loadNgStructureAsync()`. Returning `Promise<string>` outside `loadNgStructureAsync()` will
* cause a diagnostics error or an exception to be thrown.
*/
readResource(fileName: string): Promise<string> | string;
/**
* Get the absolute paths to the changed files that triggered the current compilation
* or `undefined` if this is not an incremental build.
*/
getModifiedResourceFiles?(): Set<string> | undefined;
/**
* Transform an inline or external resource asynchronously.
* It is assumed the consumer of the corresponding `Program` will call
* `loadNgStructureAsync()`. Using outside `loadNgStructureAsync()` will
* cause a diagnostics error or an exception to be thrown.
* Only style resources are currently supported.
*
* @param data The resource data to transform.
* @param context Information regarding the resource such as the type and containing file.
* @returns A promise of either the transformed resource data or null if no transformation occurs.
*/
transformResource?(data: string, context: ResourceHostContext): Promise<TransformResourceResult | null>;
}
/**
* Contextual information used by members of the ResourceHost interface.
*/
export interface ResourceHostContext {
/**
* The type of the component resource. Templates are not yet supported.
* * Resources referenced via a component's `styles` or `styleUrls` properties are of
* type `style`.
*/
readonly type: 'style';
/**
* The absolute path to the resource file. If the resource is inline, the value will be null.
*/
readonly resourceFile: string | null;
/**
* The absolute path to the file that contains the resource or reference to the resource.
*/
readonly containingFile: string;
}
/**
* The successful transformation result of the `ResourceHost.transformResource` function.
* This interface may be expanded in the future to include diagnostic information and source mapping
* support.
*/
export interface TransformResourceResult {
/**
* The content generated by the transformation.
*/
content: string;
}
/**
* A `ts.CompilerHost` interface which supports some number of optional methods in addition to the
* core interface.
*/
export interface ExtendedTsCompilerHost extends ts.CompilerHost, Partial<ResourceHost>, Partial<UnifiedModulesHost> {
}

View File

@@ -0,0 +1,41 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { BazelAndG3Options, DiagnosticOptions, I18nOptions, LegacyNgcOptions, MiscOptions, StrictTemplateOptions, TargetOptions } from './public_options';
/**
* Non-public options which are useful during testing of the compiler.
*/
export interface TestOnlyOptions {
/**
* Enable the Language Service APIs for template type-checking for tests.
*/
_enableTemplateTypeChecker?: boolean;
/**
* An option to enable ngtsc's internal performance tracing.
*
* This should be a path to a JSON file where trace information will be written. This is sensitive
* to the compiler's working directory, and should likely be an absolute path.
*
* This is currently not exposed to users as the trace format is still unstable.
*/
tracePerformance?: string;
}
/**
* Internal only options for compiler.
*/
export interface InternalOptions {
}
/**
* A merged interface of all of the various Angular compiler options, as well as the standard
* `ts.CompilerOptions`.
*
* Also includes a few miscellaneous options.
*/
export interface NgCompilerOptions extends ts.CompilerOptions, LegacyNgcOptions, BazelAndG3Options, DiagnosticOptions, StrictTemplateOptions, TestOnlyOptions, I18nOptions, TargetOptions, InternalOptions, MiscOptions {
[prop: string]: any;
}

View File

@@ -0,0 +1,386 @@
/**
* @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.io/license
*/
import { ExtendedTemplateDiagnosticName } from '../../../../ngtsc/diagnostics';
/**
* Options supported by the legacy View Engine compiler, which are still consumed by the Angular Ivy
* compiler for backwards compatibility.
*
* These are expected to be removed at some point in the future.
*
* @publicApi
*/
export interface LegacyNgcOptions {
/**
* generate all possible generated files
* @deprecated This option is not used anymore.
*/
allowEmptyCodegenFiles?: boolean;
/**
* Whether to type check the entire template.
*
* This flag currently controls a couple aspects of template type-checking, including
* whether embedded views are checked.
*
* For maximum type-checking, set this to `true`, and set `strictTemplates` to `true`.
*
* It is an error for this flag to be `false`, while `strictTemplates` is set to `true`.
*
* @deprecated The `fullTemplateTypeCheck` option has been superseded by the more granular
* `strictTemplates` family of compiler options. Usage of `fullTemplateTypeCheck` is therefore
* deprecated, `strictTemplates` and its related options should be used instead.
*/
fullTemplateTypeCheck?: boolean;
/**
* Whether to generate a flat module index of the given name and the corresponding
* flat module metadata. This option is intended to be used when creating flat
* modules similar to how `@angular/core` and `@angular/common` are packaged.
* When this option is used the `package.json` for the library should refer to the
* generated flat module index instead of the library index file. When using this
* option only one .metadata.json file is produced that contains all the metadata
* necessary for symbols exported from the library index.
* In the generated .ngfactory.ts files flat module index is used to import symbols
* including both the public API from the library index as well as shrouded internal
* symbols.
* By default the .ts file supplied in the `files` field is assumed to be the
* library index. If more than one is specified, uses `libraryIndex` to select the
* file to use. If more than one .ts file is supplied and no `libraryIndex` is supplied
* an error is produced.
* A flat module index .d.ts and .js will be created with the given `flatModuleOutFile`
* name in the same location as the library index .d.ts file is emitted.
* For example, if a library uses `public_api.ts` file as the library index of the
* module the `tsconfig.json` `files` field would be `["public_api.ts"]`. The
* `flatModuleOutFile` options could then be set to, for example `"index.js"`, which
* produces `index.d.ts` and `index.metadata.json` files. The library's
* `package.json`'s `module` field would be `"index.js"` and the `typings` field would
* be `"index.d.ts"`.
*/
flatModuleOutFile?: string;
/**
* Preferred module id to use for importing flat module. References generated by `ngc`
* will use this module name when importing symbols from the flat module. This is only
* meaningful when `flatModuleOutFile` is also supplied. It is otherwise ignored.
*/
flatModuleId?: string;
/**
* Always report errors a parameter is supplied whose injection type cannot
* be determined. When this value option is not provided or is `false`, constructor
* parameters of classes marked with `@Injectable` whose type cannot be resolved will
* produce a warning. With this option `true`, they produce an error. When this option is
* not provided is treated as if it were `false`.
*/
strictInjectionParameters?: boolean;
/**
* Whether to remove blank text nodes from compiled templates. It is `false` by default starting
* from Angular 6.
*/
preserveWhitespaces?: boolean;
}
/**
* Options related to template type-checking and its strictness.
*
* @publicApi
*/
export interface StrictTemplateOptions {
/**
* If `true`, implies all template strictness flags below (unless individually disabled).
*
* This flag is a superset of the deprecated `fullTemplateTypeCheck` option.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is `true`.
*/
strictTemplates?: boolean;
/**
* Whether to check the type of a binding to a directive/component input against the type of the
* field on the directive/component.
*
* For example, if this is `false` then the expression `[input]="expr"` will have `expr` type-
* checked, but not the assignment of the resulting type to the `input` property of whichever
* directive or component is receiving the binding. If set to `true`, both sides of the assignment
* are checked.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is set.
*/
strictInputTypes?: boolean;
/**
* Whether to check if the input binding attempts to assign to a restricted field (readonly,
* private, or protected) on the directive/component.
*
* Defaults to `false`, even if "fullTemplateTypeCheck", "strictTemplates" and/or
* "strictInputTypes" is set. Note that if `strictInputTypes` is not set, or set to `false`, this
* flag has no effect.
*
* Tracking issue for enabling this by default: https://github.com/angular/angular/issues/38400
*/
strictInputAccessModifiers?: boolean;
/**
* Whether to use strict null types for input bindings for directives.
*
* If this is `true`, applications that are compiled with TypeScript's `strictNullChecks` enabled
* will produce type errors for bindings which can evaluate to `undefined` or `null` where the
* inputs's type does not include `undefined` or `null` in its type. If set to `false`, all
* binding expressions are wrapped in a non-null assertion operator to effectively disable strict
* null checks.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is set. Note that if `strictInputTypes` is
* not set, or set to `false`, this flag has no effect.
*/
strictNullInputTypes?: boolean;
/**
* Whether to check text attributes that happen to be consumed by a directive or component.
*
* For example, in a template containing `<input matInput disabled>` the `disabled` attribute ends
* up being consumed as an input with type `boolean` by the `matInput` directive. At runtime, the
* input will be set to the attribute's string value, which is an empty string for attributes
* without a value, so with this flag set to `true`, an error would be reported. If set to
* `false`, text attributes will never report an error.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is set. Note that if `strictInputTypes` is
* not set, or set to `false`, this flag has no effect.
*/
strictAttributeTypes?: boolean;
/**
* Whether to use a strict type for null-safe navigation operations.
*
* If this is `false`, then the return type of `a?.b` or `a?()` will be `any`. If set to `true`,
* then the return type of `a?.b` for example will be the same as the type of the ternary
* expression `a != null ? a.b : a`.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is set.
*/
strictSafeNavigationTypes?: boolean;
/**
* Whether to infer the type of local references.
*
* If this is `true`, the type of a `#ref` variable on a DOM node in the template will be
* determined by the type of `document.createElement` for the given DOM node. If set to `false`,
* the type of `ref` for DOM nodes will be `any`.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is set.
*/
strictDomLocalRefTypes?: boolean;
/**
* Whether to infer the type of the `$event` variable in event bindings for directive outputs or
* animation events.
*
* If this is `true`, the type of `$event` will be inferred based on the generic type of
* `EventEmitter`/`Subject` of the output. If set to `false`, the `$event` variable will be of
* type `any`.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is set.
*/
strictOutputEventTypes?: boolean;
/**
* Whether to infer the type of the `$event` variable in event bindings to DOM events.
*
* If this is `true`, the type of `$event` will be inferred based on TypeScript's
* `HTMLElementEventMap`, with a fallback to the native `Event` type. If set to `false`, the
* `$event` variable will be of type `any`.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is set.
*/
strictDomEventTypes?: boolean;
/**
* Whether to include the generic type of components when type-checking the template.
*
* If no component has generic type parameters, this setting has no effect.
*
* If a component has generic type parameters and this setting is `true`, those generic parameters
* will be included in the context type for the template. If `false`, any generic parameters will
* be set to `any` in the template context type.
*
* Defaults to `false`, even if "fullTemplateTypeCheck" is set.
*/
strictContextGenerics?: boolean;
/**
* Whether object or array literals defined in templates use their inferred type, or are
* interpreted as `any`.
*
* Defaults to `false` unless `fullTemplateTypeCheck` or `strictTemplates` are set.
*/
strictLiteralTypes?: boolean;
}
/**
* A label referring to a `ts.DiagnosticCategory` or `'suppress'`, meaning the associated diagnostic
* should not be displayed at all.
*
* @publicApi
*/
export declare enum DiagnosticCategoryLabel {
/** Treat the diagnostic as a warning, don't fail the compilation. */
Warning = "warning",
/** Treat the diagnostic as a hard error, fail the compilation. */
Error = "error",
/** Ignore the diagnostic altogether. */
Suppress = "suppress"
}
/**
* Options which control how diagnostics are emitted from the compiler.
*
* @publicApi
*/
export interface DiagnosticOptions {
/** Options which control how diagnostics are emitted from the compiler. */
extendedDiagnostics?: {
/**
* The category to use for configurable diagnostics which are not overridden by `checks`. Uses
* `warning` by default.
*/
defaultCategory?: DiagnosticCategoryLabel;
/**
* A map of each extended template diagnostic's name to its category. This can be expanded in
* the future with more information for each check or for additional diagnostics not part of the
* extended template diagnostics system.
*/
checks?: {
[Name in ExtendedTemplateDiagnosticName]?: DiagnosticCategoryLabel;
};
};
}
/**
* Options which control behavior useful for "monorepo" build cases using Bazel (such as the
* internal Google monorepo, g3).
*
* @publicApi
*/
export interface BazelAndG3Options {
/**
* Enables the generation of alias re-exports of directives/pipes that are visible from an
* NgModule from that NgModule's file.
*
* This option should be disabled for application builds or for Angular Package Format libraries
* (where NgModules along with their directives/pipes are exported via a single entrypoint).
*
* For other library compilations which are intended to be path-mapped into an application build
* (or another library), enabling this option enables the resulting deep imports to work
* correctly.
*
* A consumer of such a path-mapped library will write an import like:
*
* ```typescript
* import {LibModule} from 'lib/deep/path/to/module';
* ```
*
* The compiler will attempt to generate imports of directives/pipes from that same module
* specifier (the compiler does not rewrite the user's given import path, unlike View Engine).
*
* ```typescript
* import {LibDir, LibCmp, LibPipe} from 'lib/deep/path/to/module';
* ```
*
* It would be burdensome for users to have to re-export all directives/pipes alongside each
* NgModule to support this import model. Enabling this option tells the compiler to generate
* private re-exports alongside the NgModule of all the directives/pipes it makes available, to
* support these future imports.
*/
generateDeepReexports?: boolean;
/**
* The `.d.ts` file for NgModules contain type pointers to their declarations, imports, and
* exports. Without this flag, the generated type definition will include
* components/directives/pipes/NgModules that are declared or imported locally in the NgModule and
* not necessarily exported to consumers.
*
* With this flag set, the type definition generated in the `.d.ts` for an NgModule will be
* filtered to only list those types which are publicly exported by the NgModule.
*/
onlyPublishPublicTypingsForNgModules?: boolean;
/**
* Insert JSDoc type annotations needed by Closure Compiler
*/
annotateForClosureCompiler?: boolean;
}
/**
* Options related to i18n compilation support.
*
* @publicApi
*/
export interface I18nOptions {
/**
* Locale of the imported translations
*/
i18nInLocale?: string;
/**
* Export format (xlf, xlf2 or xmb) when the xi18n operation is requested.
*/
i18nOutFormat?: string;
/**
* Path to the extracted message file to emit when the xi18n operation is requested.
*/
i18nOutFile?: string;
/**
* Locale of the application (used when xi18n is requested).
*/
i18nOutLocale?: string;
/**
* Render `$localize` messages with legacy format ids.
*
* The default value for now is `true`.
*
* Use this option when use are using the `$localize` based localization messages but
* have not migrated the translation files to use the new `$localize` message id format.
*/
enableI18nLegacyMessageIdFormat?: boolean;
/**
* Whether translation variable name should contain external message id
* (used by Closure Compiler's output of `goog.getMsg` for transition period)
*/
i18nUseExternalIds?: boolean;
/**
* If templates are stored in external files (e.g. via `templateUrl`) then we need to decide
* whether or not to normalize the line-endings (from `\r\n` to `\n`) when processing ICU
* expressions.
*
* Ideally we would always normalize, but for backward compatibility this flag allows the template
* parser to avoid normalizing line endings in ICU expressions.
*
* If `true` then we will normalize ICU expression line endings.
* The default is `false`, but this will be switched in a future major release.
*/
i18nNormalizeLineEndingsInICUs?: boolean;
}
/**
* Options that specify compilation target.
*
* @publicApi
*/
export interface TargetOptions {
/**
* Specifies the compilation mode to use. The following modes are available:
* - 'full': generates fully AOT compiled code using Ivy instructions.
* - 'partial': generates code in a stable, but intermediate form suitable for publication to NPM.
* - 'experimental-local': generates code based on each individual source file without using its
* dependencies. This mode is suitable only for fast edit/refresh during development. It will be
* eventually replaced by the value `local` once the feature is ready to be public.
*
* The default value is 'full'.
*/
compilationMode?: 'full' | 'partial' | 'experimental-local';
}
/**
* Miscellaneous options that don't fall into any other category
*
* @publicApi
*/
export interface MiscOptions {
/**
* Whether the compiler should avoid generating code for classes that haven't been exported.
* Defaults to `true`.
*/
compileNonExportedClasses?: boolean;
/**
* Disable TypeScript Version Check.
*/
disableTypeScriptVersionCheck?: boolean;
/**
* Enables the runtime check to guard against rendering a component without first loading its
* NgModule.
*
* This check is only applied to the current compilation unit, i.e., a component imported from
* another library without option set will not issue error if rendered in orphan way.
*/
forbidOrphanComponents?: boolean;
}

View File

@@ -0,0 +1,9 @@
/**
* @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.io/license
*/
export * from './src/compiler';
export { NgCompilerHost } from './src/host';

View File

@@ -0,0 +1,267 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { DocEntry } from '../../docs';
import { AbsoluteFsPath } from '../../file_system';
import { IncrementalBuildStrategy, IncrementalCompilation, IncrementalState } from '../../incremental';
import { IndexedComponent } from '../../indexer';
import { ComponentResources, DirectiveMeta, PipeMeta } from '../../metadata';
import { ActivePerfRecorder } from '../../perf';
import { ProgramDriver } from '../../program_driver';
import { DeclarationNode } from '../../reflection';
import { OptimizeFor, TemplateTypeChecker } from '../../typecheck/api';
import { Xi18nContext } from '../../xi18n';
import { NgCompilerAdapter, NgCompilerOptions } from '../api';
/**
* Discriminant type for a `CompilationTicket`.
*/
export declare enum CompilationTicketKind {
Fresh = 0,
IncrementalTypeScript = 1,
IncrementalResource = 2
}
/**
* Begin an Angular compilation operation from scratch.
*/
export interface FreshCompilationTicket {
kind: CompilationTicketKind.Fresh;
options: NgCompilerOptions;
incrementalBuildStrategy: IncrementalBuildStrategy;
programDriver: ProgramDriver;
enableTemplateTypeChecker: boolean;
usePoisonedData: boolean;
tsProgram: ts.Program;
perfRecorder: ActivePerfRecorder;
}
/**
* Begin an Angular compilation operation that incorporates changes to TypeScript code.
*/
export interface IncrementalTypeScriptCompilationTicket {
kind: CompilationTicketKind.IncrementalTypeScript;
options: NgCompilerOptions;
newProgram: ts.Program;
incrementalBuildStrategy: IncrementalBuildStrategy;
incrementalCompilation: IncrementalCompilation;
programDriver: ProgramDriver;
enableTemplateTypeChecker: boolean;
usePoisonedData: boolean;
perfRecorder: ActivePerfRecorder;
}
export interface IncrementalResourceCompilationTicket {
kind: CompilationTicketKind.IncrementalResource;
compiler: NgCompiler;
modifiedResourceFiles: Set<string>;
perfRecorder: ActivePerfRecorder;
}
/**
* A request to begin Angular compilation, either starting from scratch or from a known prior state.
*
* `CompilationTicket`s are used to initialize (or update) an `NgCompiler` instance, the core of the
* Angular compiler. They abstract the starting state of compilation and allow `NgCompiler` to be
* managed independently of any incremental compilation lifecycle.
*/
export type CompilationTicket = FreshCompilationTicket | IncrementalTypeScriptCompilationTicket | IncrementalResourceCompilationTicket;
/**
* Create a `CompilationTicket` for a brand new compilation, using no prior state.
*/
export declare function freshCompilationTicket(tsProgram: ts.Program, options: NgCompilerOptions, incrementalBuildStrategy: IncrementalBuildStrategy, programDriver: ProgramDriver, perfRecorder: ActivePerfRecorder | null, enableTemplateTypeChecker: boolean, usePoisonedData: boolean): CompilationTicket;
/**
* Create a `CompilationTicket` as efficiently as possible, based on a previous `NgCompiler`
* instance and a new `ts.Program`.
*/
export declare function incrementalFromCompilerTicket(oldCompiler: NgCompiler, newProgram: ts.Program, incrementalBuildStrategy: IncrementalBuildStrategy, programDriver: ProgramDriver, modifiedResourceFiles: Set<AbsoluteFsPath>, perfRecorder: ActivePerfRecorder | null): CompilationTicket;
/**
* Create a `CompilationTicket` directly from an old `ts.Program` and associated Angular compilation
* state, along with a new `ts.Program`.
*/
export declare function incrementalFromStateTicket(oldProgram: ts.Program, oldState: IncrementalState, newProgram: ts.Program, options: NgCompilerOptions, incrementalBuildStrategy: IncrementalBuildStrategy, programDriver: ProgramDriver, modifiedResourceFiles: Set<AbsoluteFsPath>, perfRecorder: ActivePerfRecorder | null, enableTemplateTypeChecker: boolean, usePoisonedData: boolean): CompilationTicket;
export declare function resourceChangeTicket(compiler: NgCompiler, modifiedResourceFiles: Set<string>): IncrementalResourceCompilationTicket;
/**
* The heart of the Angular Ivy compiler.
*
* The `NgCompiler` provides an API for performing Angular compilation within a custom TypeScript
* compiler. Each instance of `NgCompiler` supports a single compilation, which might be
* incremental.
*
* `NgCompiler` is lazy, and does not perform any of the work of the compilation until one of its
* output methods (e.g. `getDiagnostics`) is called.
*
* See the README.md for more information.
*/
export declare class NgCompiler {
private adapter;
readonly options: NgCompilerOptions;
private inputProgram;
readonly programDriver: ProgramDriver;
readonly incrementalStrategy: IncrementalBuildStrategy;
readonly incrementalCompilation: IncrementalCompilation;
readonly usePoisonedData: boolean;
private livePerfRecorder;
/**
* Lazily evaluated state of the compilation.
*
* This is created on demand by calling `ensureAnalyzed`.
*/
private compilation;
/**
* Any diagnostics related to the construction of the compilation.
*
* These are diagnostics which arose during setup of the host and/or program.
*/
private constructionDiagnostics;
/**
* Non-template diagnostics related to the program itself. Does not include template
* diagnostics because the template type checker memoizes them itself.
*
* This is set by (and memoizes) `getNonTemplateDiagnostics`.
*/
private nonTemplateDiagnostics;
private closureCompilerEnabled;
private currentProgram;
private entryPoint;
private moduleResolver;
private resourceManager;
private cycleAnalyzer;
readonly ignoreForDiagnostics: Set<ts.SourceFile>;
readonly ignoreForEmit: Set<ts.SourceFile>;
readonly enableTemplateTypeChecker: boolean;
private readonly enableBlockSyntax;
/**
* `NgCompiler` can be reused for multiple compilations (for resource-only changes), and each
* new compilation uses a fresh `PerfRecorder`. Thus, classes created with a lifespan of the
* `NgCompiler` use a `DelegatingPerfRecorder` so the `PerfRecorder` they write to can be updated
* with each fresh compilation.
*/
private delegatingPerfRecorder;
/**
* Convert a `CompilationTicket` into an `NgCompiler` instance for the requested compilation.
*
* Depending on the nature of the compilation request, the `NgCompiler` instance may be reused
* from a previous compilation and updated with any changes, it may be a new instance which
* incrementally reuses state from a previous compilation, or it may represent a fresh
* compilation entirely.
*/
static fromTicket(ticket: CompilationTicket, adapter: NgCompilerAdapter): NgCompiler;
private constructor();
get perfRecorder(): ActivePerfRecorder;
private updateWithChangedResources;
/**
* Get the resource dependencies of a file.
*
* If the file is not part of the compilation, an empty array will be returned.
*/
getResourceDependencies(file: ts.SourceFile): string[];
/**
* Get all Angular-related diagnostics for this compilation.
*/
getDiagnostics(): ts.Diagnostic[];
/**
* Get all Angular-related diagnostics for this compilation.
*
* If a `ts.SourceFile` is passed, only diagnostics related to that file are returned.
*/
getDiagnosticsForFile(file: ts.SourceFile, optimizeFor: OptimizeFor): ts.Diagnostic[];
/**
* Get all `ts.Diagnostic`s currently available that pertain to the given component.
*/
getDiagnosticsForComponent(component: ts.ClassDeclaration): ts.Diagnostic[];
/**
* Add Angular.io error guide links to diagnostics for this compilation.
*/
private addMessageTextDetails;
/**
* Get all setup-related diagnostics for this compilation.
*/
getOptionDiagnostics(): ts.Diagnostic[];
/**
* Get the current `ts.Program` known to this `NgCompiler`.
*
* Compilation begins with an input `ts.Program`, and during template type-checking operations new
* `ts.Program`s may be produced using the `ProgramDriver`. The most recent such `ts.Program` to
* be produced is available here.
*
* This `ts.Program` serves two key purposes:
*
* * As an incremental starting point for creating the next `ts.Program` based on files that the
* user has changed (for clients using the TS compiler program APIs).
*
* * As the "before" point for an incremental compilation invocation, to determine what's changed
* between the old and new programs (for all compilations).
*/
getCurrentProgram(): ts.Program;
getTemplateTypeChecker(): TemplateTypeChecker;
/**
* Retrieves the `ts.Declaration`s for any component(s) which use the given template file.
*/
getComponentsWithTemplateFile(templateFilePath: string): ReadonlySet<DeclarationNode>;
/**
* Retrieves the `ts.Declaration`s for any component(s) which use the given template file.
*/
getComponentsWithStyleFile(styleFilePath: string): ReadonlySet<DeclarationNode>;
/**
* Retrieves external resources for the given component.
*/
getComponentResources(classDecl: DeclarationNode): ComponentResources | null;
getMeta(classDecl: DeclarationNode): PipeMeta | DirectiveMeta | null;
/**
* Perform Angular's analysis step (as a precursor to `getDiagnostics` or `prepareEmit`)
* asynchronously.
*
* Normally, this operation happens lazily whenever `getDiagnostics` or `prepareEmit` are called.
* However, certain consumers may wish to allow for an asynchronous phase of analysis, where
* resources such as `styleUrls` are resolved asynchronously. In these cases `analyzeAsync` must
* be called first, and its `Promise` awaited prior to calling any other APIs of `NgCompiler`.
*/
analyzeAsync(): Promise<void>;
/**
* Fetch transformers and other information which is necessary for a consumer to `emit` the
* program with Angular-added definitions.
*/
prepareEmit(): {
transformers: ts.CustomTransformers;
};
/**
* Run the indexing process and return a `Map` of all indexed components.
*
* See the `indexing` package for more details.
*/
getIndexedComponents(): Map<DeclarationNode, IndexedComponent>;
/**
* Gets information for the current program that may be used to generate API
* reference documentation. This includes Angular-specific information, such
* as component inputs and outputs.
*
* @param entryPoint Path to the entry point for the package for which API
* docs should be extracted.
*/
getApiDocumentation(entryPoint: string): DocEntry[];
/**
* Collect i18n messages into the `Xi18nContext`.
*/
xi18n(ctx: Xi18nContext): void;
private ensureAnalyzed;
private analyzeSync;
private resolveCompilation;
private get fullTemplateTypeCheck();
private getTypeCheckingConfig;
private getTemplateDiagnostics;
private getTemplateDiagnosticsForFile;
private getNonTemplateDiagnostics;
/**
* Calls the `extendedTemplateCheck` phase of the trait compiler
* @param sf optional parameter to get diagnostics for a certain file
* or all files in the program if `sf` is undefined
* @returns generated extended template diagnostics
*/
private getExtendedTemplateDiagnostics;
private makeCompilation;
}
/**
* Determine if the given `Program` is @angular/core.
*/
export declare function isAngularCorePackage(program: ts.Program): boolean;

View File

@@ -0,0 +1,111 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath } from '../../file_system';
import { ShimAdapter, ShimReferenceTagger } from '../../shims';
import { RequiredDelegations } from '../../util/src/typescript';
import { ExtendedTsCompilerHost, NgCompilerAdapter, NgCompilerOptions, UnifiedModulesHost } from '../api';
/**
* Delegates all methods of `ExtendedTsCompilerHost` to a delegate, with the exception of
* `getSourceFile` and `fileExists` which are implemented in `NgCompilerHost`.
*
* If a new method is added to `ts.CompilerHost` which is not delegated, a type error will be
* generated for this class.
*/
export declare class DelegatingCompilerHost implements Omit<RequiredDelegations<ExtendedTsCompilerHost>, 'getSourceFile' | 'fileExists'> {
protected delegate: ExtendedTsCompilerHost;
createHash: ((data: string) => string) | undefined;
directoryExists: ((directoryName: string) => boolean) | undefined;
fileNameToModuleName: ((importedFilePath: string, containingFilePath: string) => string) | undefined;
getCancellationToken: (() => ts.CancellationToken) | undefined;
getCanonicalFileName: (fileName: string) => string;
getCurrentDirectory: () => string;
getDefaultLibFileName: (options: ts.CompilerOptions) => string;
getDefaultLibLocation: (() => string) | undefined;
getDirectories: ((path: string) => string[]) | undefined;
getEnvironmentVariable: ((name: string) => string | undefined) | undefined;
getModifiedResourceFiles: (() => Set<string> | undefined) | undefined;
getNewLine: () => string;
getParsedCommandLine: ((fileName: string) => ts.ParsedCommandLine | undefined) | undefined;
getSourceFileByPath: ((fileName: string, path: ts.Path, languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined) => ts.SourceFile | undefined) | undefined;
readDirectory: ((rootDir: string, extensions: readonly string[], excludes: readonly string[] | undefined, includes: readonly string[], depth?: number | undefined) => string[]) | undefined;
readFile: (fileName: string) => string | undefined;
readResource: ((fileName: string) => string | Promise<string>) | undefined;
transformResource: ((data: string, context: import("../api").ResourceHostContext) => Promise<import("../api").TransformResourceResult | null>) | undefined;
realpath: ((path: string) => string) | undefined;
resolveModuleNames: ((moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference: ts.ResolvedProjectReference | undefined, options: ts.CompilerOptions, containingSourceFile?: ts.SourceFile | undefined) => (ts.ResolvedModule | undefined)[]) | undefined;
resolveTypeReferenceDirectives: ((typeReferenceDirectiveNames: string[] | readonly ts.FileReference[], containingFile: string, redirectedReference: ts.ResolvedProjectReference | undefined, options: ts.CompilerOptions, containingFileMode?: ts.ResolutionMode) => (ts.ResolvedTypeReferenceDirective | undefined)[]) | undefined;
resourceNameToFileName: ((resourceName: string, containingFilePath: string, fallbackResolve?: ((url: string, fromFile: string) => string | null) | undefined) => string | null) | undefined;
trace: ((s: string) => void) | undefined;
useCaseSensitiveFileNames: () => boolean;
writeFile: ts.WriteFileCallback;
getModuleResolutionCache: (() => ts.ModuleResolutionCache | undefined) | undefined;
hasInvalidatedResolutions: ((filePath: ts.Path) => boolean) | undefined;
resolveModuleNameLiterals: ((moduleLiterals: readonly ts.StringLiteralLike[], containingFile: string, redirectedReference: ts.ResolvedProjectReference | undefined, options: ts.CompilerOptions, containingSourceFile: ts.SourceFile, reusedNames: readonly ts.StringLiteralLike[] | undefined) => readonly ts.ResolvedModuleWithFailedLookupLocations[]) | undefined;
resolveTypeReferenceDirectiveReferences: (<T extends string | ts.FileReference>(typeDirectiveReferences: readonly T[], containingFile: string, redirectedReference: ts.ResolvedProjectReference | undefined, options: ts.CompilerOptions, containingSourceFile: ts.SourceFile | undefined, reusedNames: readonly T[] | undefined) => readonly ts.ResolvedTypeReferenceDirectiveWithFailedLookupLocations[]) | undefined;
constructor(delegate: ExtendedTsCompilerHost);
private delegateMethod;
}
/**
* A wrapper around `ts.CompilerHost` (plus any extension methods from `ExtendedTsCompilerHost`).
*
* In order for a consumer to include Angular compilation in their TypeScript compiler, the
* `ts.Program` must be created with a host that adds Angular-specific files (e.g.
* the template type-checking file, etc) to the compilation. `NgCompilerHost` is the
* host implementation which supports this.
*
* The interface implementations here ensure that `NgCompilerHost` fully delegates to
* `ExtendedTsCompilerHost` methods whenever present.
*/
export declare class NgCompilerHost extends DelegatingCompilerHost implements RequiredDelegations<ExtendedTsCompilerHost>, ExtendedTsCompilerHost, NgCompilerAdapter {
private shimAdapter;
private shimTagger;
readonly entryPoint: AbsoluteFsPath | null;
readonly constructionDiagnostics: ts.Diagnostic[];
readonly inputFiles: ReadonlyArray<string>;
readonly rootDirs: ReadonlyArray<AbsoluteFsPath>;
constructor(delegate: ExtendedTsCompilerHost, inputFiles: ReadonlyArray<string>, rootDirs: ReadonlyArray<AbsoluteFsPath>, shimAdapter: ShimAdapter, shimTagger: ShimReferenceTagger, entryPoint: AbsoluteFsPath | null, diagnostics: ts.Diagnostic[]);
/**
* Retrieves a set of `ts.SourceFile`s which should not be emitted as JS files.
*
* Available after this host is used to create a `ts.Program` (which causes all the files in the
* program to be enumerated).
*/
get ignoreForEmit(): Set<ts.SourceFile>;
/**
* Retrieve the array of shim extension prefixes for which shims were created for each original
* file.
*/
get shimExtensionPrefixes(): string[];
/**
* Performs cleanup that needs to happen after a `ts.Program` has been created using this host.
*/
postProgramCreationCleanup(): void;
/**
* Create an `NgCompilerHost` from a delegate host, an array of input filenames, and the full set
* of TypeScript and Angular compiler options.
*/
static wrap(delegate: ts.CompilerHost, inputFiles: ReadonlyArray<string>, options: NgCompilerOptions, oldProgram: ts.Program | null): NgCompilerHost;
/**
* Check whether the given `ts.SourceFile` is a shim file.
*
* If this returns false, the file is user-provided.
*/
isShim(sf: ts.SourceFile): boolean;
/**
* Check whether the given `ts.SourceFile` is a resource file.
*
* This simply returns `false` for the compiler-cli since resource files are not added as root
* files to the project.
*/
isResource(sf: ts.SourceFile): boolean;
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined): ts.SourceFile | undefined;
fileExists(fileName: string): boolean;
get unifiedModulesHost(): UnifiedModulesHost | null;
private createCachedResolveModuleNamesFunction;
}

View File

@@ -0,0 +1,9 @@
/**
* @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.io/license
*/
export { Cycle, CycleAnalyzer, CycleHandlingStrategy } from './src/analyzer';
export { ImportGraph } from './src/imports';

View File

@@ -0,0 +1,66 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { ImportGraph } from './imports';
/**
* Analyzes a `ts.Program` for cycles.
*/
export declare class CycleAnalyzer {
private importGraph;
/**
* Cycle detection is requested with the same `from` source file for all used directives and pipes
* within a component, which makes it beneficial to cache the results as long as the `from` source
* file has not changed. This avoids visiting the import graph that is reachable from multiple
* directives/pipes more than once.
*/
private cachedResults;
constructor(importGraph: ImportGraph);
/**
* Check for a cycle to be created in the `ts.Program` by adding an import between `from` and
* `to`.
*
* @returns a `Cycle` object if an import between `from` and `to` would create a cycle; `null`
* otherwise.
*/
wouldCreateCycle(from: ts.SourceFile, to: ts.SourceFile): Cycle | null;
/**
* Record a synthetic import from `from` to `to`.
*
* This is an import that doesn't exist in the `ts.Program` but will be considered as part of the
* import graph for cycle creation.
*/
recordSyntheticImport(from: ts.SourceFile, to: ts.SourceFile): void;
}
/**
* Represents an import cycle between `from` and `to` in the program.
*
* This class allows us to do the work to compute the cyclic path between `from` and `to` only if
* needed.
*/
export declare class Cycle {
private importGraph;
readonly from: ts.SourceFile;
readonly to: ts.SourceFile;
constructor(importGraph: ImportGraph, from: ts.SourceFile, to: ts.SourceFile);
/**
* Compute an array of source-files that illustrates the cyclic path between `from` and `to`.
*
* Note that a `Cycle` will not be created unless a path is available between `to` and `from`,
* so `findPath()` will never return `null`.
*/
getPath(): ts.SourceFile[];
}
/**
* What to do if a cycle is detected.
*/
export declare const enum CycleHandlingStrategy {
/** Add "remote scoping" code to avoid creating a cycle. */
UseRemoteScoping = 0,
/** Fail the compilation with an error. */
Error = 1
}

View File

@@ -0,0 +1,45 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { PerfRecorder } from '../../perf';
/**
* A cached graph of imports in the `ts.Program`.
*
* The `ImportGraph` keeps track of dependencies (imports) of individual `ts.SourceFile`s. Only
* dependencies within the same program are tracked; imports into packages on NPM are not.
*/
export declare class ImportGraph {
private checker;
private perf;
private imports;
constructor(checker: ts.TypeChecker, perf: PerfRecorder);
/**
* List the direct (not transitive) imports of a given `ts.SourceFile`.
*
* This operation is cached.
*/
importsOf(sf: ts.SourceFile): Set<ts.SourceFile>;
/**
* Find an import path from the `start` SourceFile to the `end` SourceFile.
*
* This function implements a breadth first search that results in finding the
* shortest path between the `start` and `end` points.
*
* @param start the starting point of the path.
* @param end the ending point of the path.
* @returns an array of source files that connect the `start` and `end` source files, or `null` if
* no path could be found.
*/
findPath(start: ts.SourceFile, end: ts.SourceFile): ts.SourceFile[] | null;
/**
* Add a record of an import from `sf` to `imported`, that's not present in the original
* `ts.Program` but will be remembered by the `ImportGraph`.
*/
addSyntheticImport(sf: ts.SourceFile, imported: ts.SourceFile): void;
private scanImports;
}

View File

@@ -0,0 +1,13 @@
/**
* @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.io/license
*/
export { COMPILER_ERRORS_WITH_GUIDES } from './src/docs';
export { addDiagnosticChain, FatalDiagnosticError, isFatalDiagnosticError, makeDiagnostic, makeDiagnosticChain, makeRelatedInformation } from './src/error';
export { ErrorCode } from './src/error_code';
export { ERROR_DETAILS_PAGE_BASE_URL } from './src/error_details_base_url';
export { ExtendedTemplateDiagnosticName } from './src/extended_template_diagnostic_name';
export { ngErrorCode, replaceTsWithNgInErrors } from './src/util';

View File

@@ -0,0 +1,13 @@
/**
* @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.io/license
*/
import { ErrorCode } from './error_code';
/**
* Contains a set of error messages that have detailed guides at angular.io.
* Full list of available error guides can be found at https://angular.io/errors
*/
export declare const COMPILER_ERRORS_WITH_GUIDES: Set<ErrorCode>;

View File

@@ -0,0 +1,22 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { ErrorCode } from './error_code';
export declare class FatalDiagnosticError {
readonly code: ErrorCode;
readonly node: ts.Node;
readonly message: string | ts.DiagnosticMessageChain;
readonly relatedInformation?: ts.DiagnosticRelatedInformation[] | undefined;
constructor(code: ErrorCode, node: ts.Node, message: string | ts.DiagnosticMessageChain, relatedInformation?: ts.DiagnosticRelatedInformation[] | undefined);
toDiagnostic(): ts.DiagnosticWithLocation;
}
export declare function makeDiagnostic(code: ErrorCode, node: ts.Node, messageText: string | ts.DiagnosticMessageChain, relatedInformation?: ts.DiagnosticRelatedInformation[]): ts.DiagnosticWithLocation;
export declare function makeDiagnosticChain(messageText: string, next?: ts.DiagnosticMessageChain[]): ts.DiagnosticMessageChain;
export declare function makeRelatedInformation(node: ts.Node, messageText: string): ts.DiagnosticRelatedInformation;
export declare function addDiagnosticChain(messageText: string | ts.DiagnosticMessageChain, add: ts.DiagnosticMessageChain[]): ts.DiagnosticMessageChain;
export declare function isFatalDiagnosticError(err: any): err is FatalDiagnosticError;

View File

@@ -0,0 +1,382 @@
/**
* @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.io/license
*/
/**
* @publicApi
*/
export declare enum ErrorCode {
DECORATOR_ARG_NOT_LITERAL = 1001,
DECORATOR_ARITY_WRONG = 1002,
DECORATOR_NOT_CALLED = 1003,
DECORATOR_UNEXPECTED = 1005,
/**
* This error code indicates that there are incompatible decorators on a type or a class field.
*/
DECORATOR_COLLISION = 1006,
VALUE_HAS_WRONG_TYPE = 1010,
VALUE_NOT_LITERAL = 1011,
COMPONENT_MISSING_TEMPLATE = 2001,
PIPE_MISSING_NAME = 2002,
PARAM_MISSING_TOKEN = 2003,
DIRECTIVE_MISSING_SELECTOR = 2004,
/** Raised when an undecorated class is passed in as a provider to a module or a directive. */
UNDECORATED_PROVIDER = 2005,
/**
* Raised when a Directive inherits its constructor from a base class without an Angular
* decorator.
*/
DIRECTIVE_INHERITS_UNDECORATED_CTOR = 2006,
/**
* Raised when an undecorated class that is using Angular features
* has been discovered.
*/
UNDECORATED_CLASS_USING_ANGULAR_FEATURES = 2007,
/**
* Raised when an component cannot resolve an external resource, such as a template or a style
* sheet.
*/
COMPONENT_RESOURCE_NOT_FOUND = 2008,
/**
* Raised when a component uses `ShadowDom` view encapsulation, but its selector
* does not match the shadow DOM tag name requirements.
*/
COMPONENT_INVALID_SHADOW_DOM_SELECTOR = 2009,
/**
* Raised when a component has `imports` but is not marked as `standalone: true`.
*/
COMPONENT_NOT_STANDALONE = 2010,
/**
* Raised when a type in the `imports` of a component is a directive or pipe, but is not
* standalone.
*/
COMPONENT_IMPORT_NOT_STANDALONE = 2011,
/**
* Raised when a type in the `imports` of a component is not a directive, pipe, or NgModule.
*/
COMPONENT_UNKNOWN_IMPORT = 2012,
/**
* Raised when the compiler wasn't able to resolve the metadata of a host directive.
*/
HOST_DIRECTIVE_INVALID = 2013,
/**
* Raised when a host directive isn't standalone.
*/
HOST_DIRECTIVE_NOT_STANDALONE = 2014,
/**
* Raised when a host directive is a component.
*/
HOST_DIRECTIVE_COMPONENT = 2015,
/**
* Raised when a type with Angular decorator inherits its constructor from a base class
* which has a constructor that is incompatible with Angular DI.
*/
INJECTABLE_INHERITS_INVALID_CONSTRUCTOR = 2016,
/** Raised when a host tries to alias a host directive binding that does not exist. */
HOST_DIRECTIVE_UNDEFINED_BINDING = 2017,
/**
* Raised when a host tries to alias a host directive
* binding to a pre-existing binding's public name.
*/
HOST_DIRECTIVE_CONFLICTING_ALIAS = 2018,
/**
* Raised when a host directive definition doesn't expose a
* required binding from the host directive.
*/
HOST_DIRECTIVE_MISSING_REQUIRED_BINDING = 2019,
/**
* Raised when a component specifies both a `transform` function on an input
* and has a corresponding `ngAcceptInputType_` member for the same input.
*/
CONFLICTING_INPUT_TRANSFORM = 2020,
/** Raised when a component has both `styleUrls` and `styleUrl`. */
COMPONENT_INVALID_STYLE_URLS = 2021,
SYMBOL_NOT_EXPORTED = 3001,
/**
* Raised when a relationship between directives and/or pipes would cause a cyclic import to be
* created that cannot be handled, such as in partial compilation mode.
*/
IMPORT_CYCLE_DETECTED = 3003,
/**
* Raised when the compiler is unable to generate an import statement for a reference.
*/
IMPORT_GENERATION_FAILURE = 3004,
CONFIG_FLAT_MODULE_NO_INDEX = 4001,
CONFIG_STRICT_TEMPLATES_IMPLIES_FULL_TEMPLATE_TYPECHECK = 4002,
CONFIG_EXTENDED_DIAGNOSTICS_IMPLIES_STRICT_TEMPLATES = 4003,
CONFIG_EXTENDED_DIAGNOSTICS_UNKNOWN_CATEGORY_LABEL = 4004,
CONFIG_EXTENDED_DIAGNOSTICS_UNKNOWN_CHECK = 4005,
/**
* Raised when a host expression has a parse error, such as a host listener or host binding
* expression containing a pipe.
*/
HOST_BINDING_PARSE_ERROR = 5001,
/**
* Raised when the compiler cannot parse a component's template.
*/
TEMPLATE_PARSE_ERROR = 5002,
/**
* Raised when an NgModule contains an invalid reference in `declarations`.
*/
NGMODULE_INVALID_DECLARATION = 6001,
/**
* Raised when an NgModule contains an invalid type in `imports`.
*/
NGMODULE_INVALID_IMPORT = 6002,
/**
* Raised when an NgModule contains an invalid type in `exports`.
*/
NGMODULE_INVALID_EXPORT = 6003,
/**
* Raised when an NgModule contains a type in `exports` which is neither in `declarations` nor
* otherwise imported.
*/
NGMODULE_INVALID_REEXPORT = 6004,
/**
* Raised when a `ModuleWithProviders` with a missing
* generic type argument is passed into an `NgModule`.
*/
NGMODULE_MODULE_WITH_PROVIDERS_MISSING_GENERIC = 6005,
/**
* Raised when an NgModule exports multiple directives/pipes of the same name and the compiler
* attempts to generate private re-exports within the NgModule file.
*/
NGMODULE_REEXPORT_NAME_COLLISION = 6006,
/**
* Raised when a directive/pipe is part of the declarations of two or more NgModules.
*/
NGMODULE_DECLARATION_NOT_UNIQUE = 6007,
/**
* Raised when a standalone directive/pipe is part of the declarations of an NgModule.
*/
NGMODULE_DECLARATION_IS_STANDALONE = 6008,
/**
* Raised when a standalone component is part of the bootstrap list of an NgModule.
*/
NGMODULE_BOOTSTRAP_IS_STANDALONE = 6009,
/**
* Indicates that an NgModule is declared with `id: module.id`. This is an anti-pattern that is
* disabled explicitly in the compiler, that was originally based on a misunderstanding of
* `NgModule.id`.
*/
WARN_NGMODULE_ID_UNNECESSARY = 6100,
/**
* 6999 was previously assigned to NGMODULE_VE_DEPENDENCY_ON_IVY_LIB
* To prevent any confusion, let's not reassign it.
*/
/**
* An element name failed validation against the DOM schema.
*/
SCHEMA_INVALID_ELEMENT = 8001,
/**
* An element's attribute name failed validation against the DOM schema.
*/
SCHEMA_INVALID_ATTRIBUTE = 8002,
/**
* No matching directive was found for a `#ref="target"` expression.
*/
MISSING_REFERENCE_TARGET = 8003,
/**
* No matching pipe was found for a
*/
MISSING_PIPE = 8004,
/**
* The left-hand side of an assignment expression was a template variable. Effectively, the
* template looked like:
*
* ```
* <ng-template let-something>
* <button (click)="something = ...">...</button>
* </ng-template>
* ```
*
* Template variables are read-only.
*/
WRITE_TO_READ_ONLY_VARIABLE = 8005,
/**
* A template variable was declared twice. For example:
*
* ```html
* <div *ngFor="let i of items; let i = index">
* </div>
* ```
*/
DUPLICATE_VARIABLE_DECLARATION = 8006,
/**
* A template has a two way binding (two bindings created by a single syntactical element)
* in which the input and output are going to different places.
*/
SPLIT_TWO_WAY_BINDING = 8007,
/**
* A directive usage isn't binding to one or more required inputs.
*/
MISSING_REQUIRED_INPUTS = 8008,
/**
* The tracking expression of a `for` loop block is accessing a variable that is unavailable,
* for example:
*
* ```
* <ng-template let-ref>
* @for (item of items; track ref) {}
* </ng-template>
* ```
*/
ILLEGAL_FOR_LOOP_TRACK_ACCESS = 8009,
/**
* The trigger of a `defer` block cannot access its trigger element,
* either because it doesn't exist or it's in a different view.
*
* ```
* @defer (on interaction(trigger)) {...}
*
* <ng-template>
* <button #trigger></button>
* </ng-template>
* ```
*/
INACCESSIBLE_DEFERRED_TRIGGER_ELEMENT = 8010,
/**
* A control flow node is projected at the root of a component and is preventing its direct
* descendants from being projected, because it has more than one root node.
*
* ```
* <comp>
* @if (expr) {
* <div projectsIntoSlot></div>
* Text preventing the div from being projected
* }
* </comp>
* ```
*/
CONTROL_FLOW_PREVENTING_CONTENT_PROJECTION = 8011,
/**
* A two way binding in a template has an incorrect syntax,
* parentheses outside brackets. For example:
*
* ```
* <div ([foo])="bar" />
* ```
*/
INVALID_BANANA_IN_BOX = 8101,
/**
* The left side of a nullish coalescing operation is not nullable.
*
* ```
* {{ foo ?? bar }}
* ```
* When the type of foo doesn't include `null` or `undefined`.
*/
NULLISH_COALESCING_NOT_NULLABLE = 8102,
/**
* A known control flow directive (e.g. `*ngIf`) is used in a template,
* but the `CommonModule` is not imported.
*/
MISSING_CONTROL_FLOW_DIRECTIVE = 8103,
/**
* A text attribute is not interpreted as a binding but likely intended to be.
*
* For example:
* ```
* <div
* attr.x="value"
* class.blue="true"
* style.margin-right.px="5">
* </div>
* ```
*
* All of the above attributes will just be static text attributes and will not be interpreted as
* bindings by the compiler.
*/
TEXT_ATTRIBUTE_NOT_BINDING = 8104,
/**
* NgForOf is used in a template, but the user forgot to include let
* in their statement.
*
* For example:
* ```
* <ul><li *ngFor="item of items">{{item["name"]}};</li></ul>
* ```
*/
MISSING_NGFOROF_LET = 8105,
/**
* Indicates that the binding suffix is not supported
*
* Style bindings support suffixes like `style.width.px`, `.em`, and `.%`.
* These suffixes are _not_ supported for attribute bindings.
*
* For example `[attr.width.px]="5"` becomes `width.px="5"` when bound.
* This is almost certainly unintentional and this error is meant to
* surface this mistake to the developer.
*/
SUFFIX_NOT_SUPPORTED = 8106,
/**
* The left side of an optional chain operation is not nullable.
*
* ```
* {{ foo?.bar }}
* {{ foo?.['bar'] }}
* {{ foo?.() }}
* ```
* When the type of foo doesn't include `null` or `undefined`.
*/
OPTIONAL_CHAIN_NOT_NULLABLE = 8107,
/**
* `ngSkipHydration` should not be a binding (it should be a static attribute).
*
* For example:
* ```
* <my-cmp [ngSkipHydration]="someTruthyVar" />
* ```
*
* `ngSkipHydration` cannot be a binding and can not have values other than "true" or an empty
* value
*/
SKIP_HYDRATION_NOT_STATIC = 8108,
/**
* Signal functions should be invoked when interpolated in templates.
*
* For example:
* ```
* {{ mySignal() }}
* ```
*/
INTERPOLATED_SIGNAL_NOT_INVOKED = 8109,
/**
* The template type-checking engine would need to generate an inline type check block for a
* component, but the current type-checking environment doesn't support it.
*/
INLINE_TCB_REQUIRED = 8900,
/**
* The template type-checking engine would need to generate an inline type constructor for a
* directive or component, but the current type-checking environment doesn't support it.
*/
INLINE_TYPE_CTOR_REQUIRED = 8901,
/**
* An injectable already has a `ɵprov` property.
*/
INJECTABLE_DUPLICATE_PROV = 9001,
/**
* Suggest users to enable `strictTemplates` to make use of full capabilities
* provided by Angular language service.
*/
SUGGEST_STRICT_TEMPLATES = 10001,
/**
* Indicates that a particular structural directive provides advanced type narrowing
* functionality, but the current template type-checking configuration does not allow its usage in
* type inference.
*/
SUGGEST_SUBOPTIMAL_TYPE_INFERENCE = 10002,
/**
* A string is imported from another file to be used as template string for a component in local
* compilation mode.
*/
LOCAL_COMPILATION_IMPORTED_TEMPLATE_STRING = 11001,
/**
* A string is imported from another file to be used as styles string for a component in local
* compilation mode.
*/
LOCAL_COMPILATION_IMPORTED_STYLES_STRING = 11002
}

View File

@@ -0,0 +1,15 @@
/**
* @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.io/license
*/
/**
* Base URL for the error details page.
*
* Keep the files below in full sync:
* - packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.ts
* - packages/core/src/error_details_base_url.ts
*/
export declare const ERROR_DETAILS_PAGE_BASE_URL = "https://angular.io/errors";

View File

@@ -0,0 +1,28 @@
/**
* @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.io/license
*/
/**
* Enum holding the name of each extended template diagnostic. The name is used as a user-meaningful
* value for configuring the diagnostic in the project's options.
*
* See the corresponding `ErrorCode` for documentation about each specific error.
* packages/compiler-cli/src/ngtsc/diagnostics/src/error_code.ts
*
* @publicApi
*/
export declare enum ExtendedTemplateDiagnosticName {
INVALID_BANANA_IN_BOX = "invalidBananaInBox",
NULLISH_COALESCING_NOT_NULLABLE = "nullishCoalescingNotNullable",
OPTIONAL_CHAIN_NOT_NULLABLE = "optionalChainNotNullable",
MISSING_CONTROL_FLOW_DIRECTIVE = "missingControlFlowDirective",
TEXT_ATTRIBUTE_NOT_BINDING = "textAttributeNotBinding",
MISSING_NGFOROF_LET = "missingNgForOfLet",
SUFFIX_NOT_SUPPORTED = "suffixNotSupported",
SKIP_HYDRATION_NOT_STATIC = "skipHydrationNotStatic",
INTERPOLATED_SIGNAL_NOT_INVOKED = "interpolatedSignalNotInvoked",
CONTROL_FLOW_PREVENTING_CONTENT_PROJECTION = "controlFlowPreventingContentProjection"
}

View File

@@ -0,0 +1,19 @@
/**
* @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.io/license
*/
import { ErrorCode } from './error_code';
/**
* During formatting of `ts.Diagnostic`s, the numeric code of each diagnostic is prefixed with the
* hard-coded "TS" prefix. For Angular's own error codes, a prefix of "NG" is desirable. To achieve
* this, all Angular error codes start with "-99" so that the sequence "TS-99" can be assumed to
* correspond with an Angular specific error code. This function replaces those occurrences with
* just "NG".
*
* @param errors The formatted diagnostics
*/
export declare function replaceTsWithNgInErrors(errors: string): string;
export declare function ngErrorCode(code: ErrorCode): number;

View File

@@ -0,0 +1,9 @@
/**
* @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.io/license
*/
export { DocEntry } from './src/entities';
export { DocsExtractor } from './src/extractor';

View File

@@ -0,0 +1,15 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { MetadataReader } from '../../metadata';
import { ClassDeclaration } from '../../reflection';
import { ClassEntry, InterfaceEntry } from './entities';
/** Extracts documentation info for a class, potentially including Angular-specific info. */
export declare function extractClass(classDeclaration: ClassDeclaration & ts.ClassDeclaration, metadataReader: MetadataReader, typeChecker: ts.TypeChecker): ClassEntry;
/** Extracts documentation info for an interface. */
export declare function extractInterface(declaration: ts.InterfaceDeclaration, typeChecker: ts.TypeChecker): InterfaceEntry;

View File

@@ -0,0 +1,13 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { ConstantEntry } from './entities';
/** Extracts documentation entry for a constant. */
export declare function extractConstant(declaration: ts.VariableDeclaration, typeChecker: ts.TypeChecker): ConstantEntry;
/** Gets whether a given constant is an Angular-added const that should be ignored for docs. */
export declare function isSyntheticAngularConstant(declaration: ts.VariableDeclaration): boolean;

View File

@@ -0,0 +1,15 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { DecoratorEntry } from './entities';
/** Extracts an API documentation entry for an Angular decorator. */
export declare function extractorDecorator(declaration: ts.VariableDeclaration, typeChecker: ts.TypeChecker): DecoratorEntry;
/** Gets whether the given variable declaration is an Angular decorator declaration. */
export declare function isDecoratorDeclaration(declaration: ts.VariableDeclaration): boolean;
/** Gets whether an interface is the options interface for a decorator in the same file. */
export declare function isDecoratorOptionsInterface(declaration: ts.InterfaceDeclaration): boolean;

View File

@@ -0,0 +1,134 @@
/**
* @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.io/license
*/
/** Type of top-level documentation entry. */
export declare enum EntryType {
Block = "block",
Component = "component",
Constant = "constant",
Decorator = "decorator",
Directive = "directive",
Element = "element",
Enum = "enum",
Function = "function",
Interface = "interface",
NgModule = "ng_module",
Pipe = "pipe",
TypeAlias = "type_alias",
UndecoratedClass = "undecorated_class"
}
/** Types of class members */
export declare enum MemberType {
Property = "property",
Method = "method",
Getter = "getter",
Setter = "setter",
EnumItem = "enum_item"
}
export declare enum DecoratorType {
Class = "class",
Member = "member",
Parameter = "parameter"
}
/** Informational tags applicable to class members. */
export declare enum MemberTags {
Abstract = "abstract",
Static = "static",
Readonly = "readonly",
Protected = "protected",
Optional = "optional",
Input = "input",
Output = "output",
Inherited = "override"
}
/** Documentation entity for single JsDoc tag. */
export interface JsDocTagEntry {
name: string;
comment: string;
}
/** Documentation entity for single generic parameter. */
export interface GenericEntry {
name: string;
constraint: string | undefined;
default: string | undefined;
}
/** Base type for all documentation entities. */
export interface DocEntry {
entryType: EntryType;
name: string;
description: string;
rawComment: string;
jsdocTags: JsDocTagEntry[];
}
/** Documentation entity for a constant. */
export interface ConstantEntry extends DocEntry {
type: string;
}
/** Documentation entity for a type alias. */
export type TypeAliasEntry = ConstantEntry;
/** Documentation entity for a TypeScript class. */
export interface ClassEntry extends DocEntry {
isAbstract: boolean;
members: MemberEntry[];
generics: GenericEntry[];
}
/** Documentation entity for a TypeScript interface. */
export type InterfaceEntry = ClassEntry;
/** Documentation entity for a TypeScript enum. */
export interface EnumEntry extends DocEntry {
members: EnumMemberEntry[];
}
/** Documentation entity for an Angular decorator. */
export interface DecoratorEntry extends DocEntry {
decoratorType: DecoratorType;
members: PropertyEntry[];
}
/** Documentation entity for an Angular directives and components. */
export interface DirectiveEntry extends ClassEntry {
selector: string;
exportAs: string[];
isStandalone: boolean;
}
export interface PipeEntry extends ClassEntry {
pipeName: string;
isStandalone: boolean;
}
export interface FunctionEntry extends DocEntry {
params: ParameterEntry[];
returnType: string;
generics: GenericEntry[];
}
/** Sub-entry for a single class or enum member. */
export interface MemberEntry {
name: string;
memberType: MemberType;
memberTags: MemberTags[];
description: string;
jsdocTags: JsDocTagEntry[];
}
/** Sub-entry for an enum member. */
export interface EnumMemberEntry extends MemberEntry {
type: string;
value: string;
}
/** Sub-entry for a class property. */
export interface PropertyEntry extends MemberEntry {
type: string;
inputAlias?: string;
outputAlias?: string;
isRequiredInput?: boolean;
}
/** Sub-entry for a class method. */
export type MethodEntry = MemberEntry & FunctionEntry;
/** Sub-entry for a single function parameter. */
export interface ParameterEntry {
name: string;
description: string;
type: string;
isOptional: boolean;
isRestParam: boolean;
}

View File

@@ -0,0 +1,11 @@
/**
* @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.io/license
*/
import { EnumEntry } from '@angular/compiler-cli/src/ngtsc/docs/src/entities';
import ts from 'typescript';
/** Extracts documentation entry for an enum. */
export declare function extractEnum(declaration: ts.EnumDeclaration, typeChecker: ts.TypeChecker): EnumEntry;

View File

@@ -0,0 +1,30 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { MetadataReader } from '../../metadata';
import { DocEntry } from './entities';
/**
* Extracts all information from a source file that may be relevant for generating
* public API documentation.
*/
export declare class DocsExtractor {
private typeChecker;
private metadataReader;
constructor(typeChecker: ts.TypeChecker, metadataReader: MetadataReader);
/**
* Gets the set of all documentable entries from a source file, including
* declarations that are re-exported from this file as an entry-point.
*
* @param sourceFile The file from which to extract documentable entries.
*/
extractAll(sourceFile: ts.SourceFile): DocEntry[];
/** Extract the doc entry for a single declaration. */
private extractDeclaration;
/** Gets the list of exported declarations for doc extraction. */
private getExportedDeclarations;
}

View File

@@ -0,0 +1,9 @@
/**
* @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.io/license
*/
/** Gets whether a symbol's name indicates it is an Angular-private API. */
export declare function isAngularPrivateName(name: string): boolean;

View File

@@ -0,0 +1,20 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { FunctionEntry } from './entities';
export type FunctionLike = ts.FunctionDeclaration | ts.MethodDeclaration | ts.MethodSignature;
export declare class FunctionExtractor {
private declaration;
private typeChecker;
constructor(declaration: FunctionLike, typeChecker: ts.TypeChecker);
extract(): FunctionEntry;
private extractAllParams;
/** Gets all overloads for the function (excluding this extractor's FunctionDeclaration). */
getOverloads(): ts.FunctionDeclaration[];
private getSymbol;
}

View File

@@ -0,0 +1,15 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { GenericEntry } from './entities';
type DeclarationWithTypeParams = {
typeParameters?: ts.NodeArray<ts.TypeParameterDeclaration> | undefined;
};
/** Gets a list of all the generic type parameters for a declaration. */
export declare function extractGenerics(declaration: DeclarationWithTypeParams): GenericEntry[];
export {};

View File

@@ -0,0 +1,21 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { JsDocTagEntry } from './entities';
/** Gets the set of JsDoc tags applied to a node. */
export declare function extractJsDocTags(node: ts.HasJSDoc): JsDocTagEntry[];
/**
* Gets the JsDoc description for a node. If the node does not have
* a description, returns the empty string.
*/
export declare function extractJsDocDescription(node: ts.HasJSDoc): string;
/**
* Gets the raw JsDoc applied to a node.
* If the node does not have a JsDoc block, returns the empty string.
*/
export declare function extractRawJsDoc(node: ts.HasJSDoc): string;

View File

@@ -0,0 +1,18 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { EntryType } from './entities';
/** Extract the documentation entry for a type alias. */
export declare function extractTypeAlias(declaration: ts.TypeAliasDeclaration): {
name: string;
type: string;
entryType: EntryType;
rawComment: string;
description: string;
jsdocTags: import("./entities").JsDocTagEntry[];
};

View File

@@ -0,0 +1,10 @@
/**
* @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.io/license
*/
import ts from 'typescript';
/** Gets the string representation of a node's resolved type. */
export declare function extractResolvedTypeString(node: ts.Node, checker: ts.TypeChecker): string;

View File

@@ -0,0 +1,11 @@
/**
* @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.io/license
*/
export { FlatIndexGenerator } from './src/generator';
export { findFlatIndexEntryPoint } from './src/logic';
export { checkForPrivateExports } from './src/private_export_checker';
export { ReferenceGraph } from './src/reference_graph';

View File

@@ -0,0 +1,18 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath } from '../../file_system';
import { TopLevelShimGenerator } from '../../shims/api';
export declare class FlatIndexGenerator implements TopLevelShimGenerator {
readonly entryPoint: AbsoluteFsPath;
readonly moduleName: string | null;
readonly flatIndexPath: string;
readonly shouldEmit = true;
constructor(entryPoint: AbsoluteFsPath, relativeFlatIndexPath: string, moduleName: string | null);
makeTopLevelShim(): ts.SourceFile;
}

View File

@@ -0,0 +1,9 @@
/**
* @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.io/license
*/
import { AbsoluteFsPath } from '../../file_system';
export declare function findFlatIndexEntryPoint(rootFiles: ReadonlyArray<AbsoluteFsPath>): AbsoluteFsPath | null;

View File

@@ -0,0 +1,32 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { ReferenceGraph } from './reference_graph';
/**
* Produce `ts.Diagnostic`s for classes that are visible from exported types (e.g. directives
* exposed by exported `NgModule`s) that are not themselves exported.
*
* This function reconciles two concepts:
*
* A class is Exported if it's exported from the main library `entryPoint` file.
* A class is Visible if, via Angular semantics, a downstream consumer can import an Exported class
* and be affected by the class in question. For example, an Exported NgModule may expose a
* directive class to its consumers. Consumers that import the NgModule may have the directive
* applied to elements in their templates. In this case, the directive is considered Visible.
*
* `checkForPrivateExports` attempts to verify that all Visible classes are Exported, and report
* `ts.Diagnostic`s for those that aren't.
*
* @param entryPoint `ts.SourceFile` of the library's entrypoint, which should export the library's
* public API.
* @param checker `ts.TypeChecker` for the current program.
* @param refGraph `ReferenceGraph` tracking the visibility of Angular types.
* @returns an array of `ts.Diagnostic`s representing errors when visible classes are not exported
* properly.
*/
export declare function checkForPrivateExports(entryPoint: ts.SourceFile, checker: ts.TypeChecker, refGraph: ReferenceGraph): ts.Diagnostic[];

View File

@@ -0,0 +1,16 @@
/**
* @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.io/license
*/
import { DeclarationNode } from '../../reflection';
export declare class ReferenceGraph<T = DeclarationNode> {
private references;
add(from: T, to: T): void;
transitiveReferencesOf(target: T): Set<T>;
pathFrom(source: T, target: T): T[] | null;
private collectPathFrom;
private collectTransitiveReferences;
}

View File

@@ -0,0 +1,13 @@
/**
* @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.io/license
*/
export { NgtscCompilerHost } from './src/compiler_host';
export { absoluteFrom, absoluteFromSourceFile, basename, dirname, getFileSystem, isLocalRelativePath, isRoot, isRooted, join, relative, relativeFrom, resolve, setFileSystem, toRelativeImport } from './src/helpers';
export { LogicalFileSystem, LogicalProjectPath } from './src/logical';
export { NodeJSFileSystem } from './src/node_js_file_system';
export { AbsoluteFsPath, FileStats, FileSystem, PathManipulation, PathSegment, PathString, ReadonlyFileSystem } from './src/types';
export { getSourceFileOrError } from './src/util';

View File

@@ -0,0 +1,25 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { FileSystem } from './types';
export declare class NgtscCompilerHost implements ts.CompilerHost {
protected fs: FileSystem;
protected options: ts.CompilerOptions;
constructor(fs: FileSystem, options?: ts.CompilerOptions);
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget): ts.SourceFile | undefined;
getDefaultLibFileName(options: ts.CompilerOptions): string;
getDefaultLibLocation(): string;
writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError: ((message: string) => void) | undefined, sourceFiles?: ReadonlyArray<ts.SourceFile>): void;
getCurrentDirectory(): string;
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
fileExists(fileName: string): boolean;
readFile(fileName: string): string | undefined;
realpath(path: string): string;
}

View File

@@ -0,0 +1,56 @@
import { AbsoluteFsPath, FileSystem, PathSegment, PathString } from './types';
export declare function getFileSystem(): FileSystem;
export declare function setFileSystem(fileSystem: FileSystem): void;
/**
* Convert the path `path` to an `AbsoluteFsPath`, throwing an error if it's not an absolute path.
*/
export declare function absoluteFrom(path: string): AbsoluteFsPath;
/**
* Extract an `AbsoluteFsPath` from a `ts.SourceFile`-like object.
*/
export declare function absoluteFromSourceFile(sf: {
fileName: string;
}): AbsoluteFsPath;
/**
* Convert the path `path` to a `PathSegment`, throwing an error if it's not a relative path.
*/
export declare function relativeFrom(path: string): PathSegment;
/**
* Static access to `dirname`.
*/
export declare function dirname<T extends PathString>(file: T): T;
/**
* Static access to `join`.
*/
export declare function join<T extends PathString>(basePath: T, ...paths: string[]): T;
/**
* Static access to `resolve`s.
*/
export declare function resolve(basePath: string, ...paths: string[]): AbsoluteFsPath;
/** Returns true when the path provided is the root path. */
export declare function isRoot(path: AbsoluteFsPath): boolean;
/**
* Static access to `isRooted`.
*/
export declare function isRooted(path: string): boolean;
/**
* Static access to `relative`.
*/
export declare function relative<T extends PathString>(from: T, to: T): PathSegment | AbsoluteFsPath;
/**
* Static access to `basename`.
*/
export declare function basename(filePath: PathString, extension?: string): PathSegment;
/**
* Returns true if the given path is locally relative.
*
* This is used to work out if the given path is relative (i.e. not absolute) but also is not
* escaping the current directory.
*/
export declare function isLocalRelativePath(relativePath: string): boolean;
/**
* Converts a path to a form suitable for use as a relative module import specifier.
*
* In other words it adds the `./` to the path if it is locally relative.
*/
export declare function toRelativeImport(relativePath: PathSegment | AbsoluteFsPath): PathSegment | AbsoluteFsPath;

View File

@@ -0,0 +1,45 @@
/**
* @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.io/license
*/
import { AbsoluteFsPath, FileStats, FileSystem, PathSegment, PathString } from './types';
/**
* The default `FileSystem` that will always fail.
*
* This is a way of ensuring that the developer consciously chooses and
* configures the `FileSystem` before using it; particularly important when
* considering static functions like `absoluteFrom()` which rely on
* the `FileSystem` under the hood.
*/
export declare class InvalidFileSystem implements FileSystem {
exists(path: AbsoluteFsPath): boolean;
readFile(path: AbsoluteFsPath): string;
readFileBuffer(path: AbsoluteFsPath): Uint8Array;
writeFile(path: AbsoluteFsPath, data: string | Uint8Array, exclusive?: boolean): void;
removeFile(path: AbsoluteFsPath): void;
symlink(target: AbsoluteFsPath, path: AbsoluteFsPath): void;
readdir(path: AbsoluteFsPath): PathSegment[];
lstat(path: AbsoluteFsPath): FileStats;
stat(path: AbsoluteFsPath): FileStats;
pwd(): AbsoluteFsPath;
chdir(path: AbsoluteFsPath): void;
extname(path: AbsoluteFsPath | PathSegment): string;
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
ensureDir(path: AbsoluteFsPath): void;
removeDeep(path: AbsoluteFsPath): void;
isCaseSensitive(): boolean;
resolve(...paths: string[]): AbsoluteFsPath;
dirname<T extends PathString>(file: T): T;
join<T extends PathString>(basePath: T, ...paths: string[]): T;
isRoot(path: AbsoluteFsPath): boolean;
isRooted(path: string): boolean;
relative<T extends PathString>(from: T, to: T): PathSegment | AbsoluteFsPath;
basename(filePath: string, extension?: string): PathSegment;
realpath(filePath: AbsoluteFsPath): AbsoluteFsPath;
getDefaultLibLocation(): AbsoluteFsPath;
normalize<T extends PathString>(path: T): T;
}

View File

@@ -0,0 +1,62 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath, BrandedPath, PathSegment } from './types';
/**
* A path that's relative to the logical root of a TypeScript project (one of the project's
* rootDirs).
*
* Paths in the type system use POSIX format.
*/
export type LogicalProjectPath = BrandedPath<'LogicalProjectPath'>;
export declare const LogicalProjectPath: {
/**
* Get the relative path between two `LogicalProjectPath`s.
*
* This will return a `PathSegment` which would be a valid module specifier to use in `from` when
* importing from `to`.
*/
relativePathBetween: (from: LogicalProjectPath, to: LogicalProjectPath) => PathSegment;
};
/**
* A utility class which can translate absolute paths to source files into logical paths in
* TypeScript's logical file system, based on the root directories of the project.
*/
export declare class LogicalFileSystem {
private compilerHost;
/**
* The root directories of the project, sorted with the longest path first.
*/
private rootDirs;
/**
* The same root directories as `rootDirs` but with each one converted to its
* canonical form for matching in case-insensitive file-systems.
*/
private canonicalRootDirs;
/**
* A cache of file paths to project paths, because computation of these paths is slightly
* expensive.
*/
private cache;
constructor(rootDirs: AbsoluteFsPath[], compilerHost: Pick<ts.CompilerHost, 'getCanonicalFileName'>);
/**
* Get the logical path in the project of a `ts.SourceFile`.
*
* This method is provided as a convenient alternative to calling
* `logicalPathOfFile(absoluteFromSourceFile(sf))`.
*/
logicalPathOfSf(sf: ts.SourceFile): LogicalProjectPath | null;
/**
* Get the logical path in the project of a source file.
*
* @returns A `LogicalProjectPath` to the source file, or `null` if the source file is not in any
* of the TS project's root directories.
*/
logicalPathOfFile(physicalFile: AbsoluteFsPath): LogicalProjectPath | null;
private createLogicalProjectPath;
}

View File

@@ -0,0 +1,44 @@
import { AbsoluteFsPath, FileStats, FileSystem, PathManipulation, PathSegment, PathString, ReadonlyFileSystem } from './types';
/**
* A wrapper around the Node.js file-system that supports path manipulation.
*/
export declare class NodeJSPathManipulation implements PathManipulation {
pwd(): AbsoluteFsPath;
chdir(dir: AbsoluteFsPath): void;
resolve(...paths: string[]): AbsoluteFsPath;
dirname<T extends string>(file: T): T;
join<T extends string>(basePath: T, ...paths: string[]): T;
isRoot(path: AbsoluteFsPath): boolean;
isRooted(path: string): boolean;
relative<T extends PathString>(from: T, to: T): PathSegment | AbsoluteFsPath;
basename(filePath: string, extension?: string): PathSegment;
extname(path: AbsoluteFsPath | PathSegment): string;
normalize<T extends string>(path: T): T;
}
/**
* A wrapper around the Node.js file-system that supports readonly operations and path manipulation.
*/
export declare class NodeJSReadonlyFileSystem extends NodeJSPathManipulation implements ReadonlyFileSystem {
private _caseSensitive;
isCaseSensitive(): boolean;
exists(path: AbsoluteFsPath): boolean;
readFile(path: AbsoluteFsPath): string;
readFileBuffer(path: AbsoluteFsPath): Uint8Array;
readdir(path: AbsoluteFsPath): PathSegment[];
lstat(path: AbsoluteFsPath): FileStats;
stat(path: AbsoluteFsPath): FileStats;
realpath(path: AbsoluteFsPath): AbsoluteFsPath;
getDefaultLibLocation(): AbsoluteFsPath;
}
/**
* A wrapper around the Node.js file-system (i.e. the `fs` package).
*/
export declare class NodeJSFileSystem extends NodeJSReadonlyFileSystem implements FileSystem {
writeFile(path: AbsoluteFsPath, data: string | Uint8Array, exclusive?: boolean): void;
removeFile(path: AbsoluteFsPath): void;
symlink(target: AbsoluteFsPath, path: AbsoluteFsPath): void;
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
ensureDir(path: AbsoluteFsPath): void;
removeDeep(path: AbsoluteFsPath): void;
}

View File

@@ -0,0 +1,89 @@
/**
* @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.io/license
*/
/**
* A `string` representing a specific type of path, with a particular brand `B`.
*
* A `string` is not assignable to a `BrandedPath`, but a `BrandedPath` is assignable to a `string`.
* Two `BrandedPath`s with different brands are not mutually assignable.
*/
export type BrandedPath<B extends string> = string & {
_brand: B;
};
/**
* A fully qualified path in the file system, in POSIX form.
*/
export type AbsoluteFsPath = BrandedPath<'AbsoluteFsPath'>;
/**
* A path that's relative to another (unspecified) root.
*
* This does not necessarily have to refer to a physical file.
*/
export type PathSegment = BrandedPath<'PathSegment'>;
/**
* An abstraction over the path manipulation aspects of a file-system.
*/
export interface PathManipulation {
extname(path: AbsoluteFsPath | PathSegment): string;
isRoot(path: AbsoluteFsPath): boolean;
isRooted(path: string): boolean;
dirname<T extends PathString>(file: T): T;
extname(path: AbsoluteFsPath | PathSegment): string;
join<T extends PathString>(basePath: T, ...paths: string[]): T;
/**
* Compute the relative path between `from` and `to`.
*
* In file-systems that can have multiple file trees the returned path may not actually be
* "relative" (i.e. `PathSegment`). For example, Windows can have multiple drives :
* `relative('c:/a/b', 'd:/a/c')` would be `d:/a/c'.
*/
relative<T extends PathString>(from: T, to: T): PathSegment | AbsoluteFsPath;
basename(filePath: string, extension?: string): PathSegment;
normalize<T extends PathString>(path: T): T;
resolve(...paths: string[]): AbsoluteFsPath;
pwd(): AbsoluteFsPath;
chdir(path: AbsoluteFsPath): void;
}
/**
* An abstraction over the read-only aspects of a file-system.
*/
export interface ReadonlyFileSystem extends PathManipulation {
isCaseSensitive(): boolean;
exists(path: AbsoluteFsPath): boolean;
readFile(path: AbsoluteFsPath): string;
readFileBuffer(path: AbsoluteFsPath): Uint8Array;
readdir(path: AbsoluteFsPath): PathSegment[];
lstat(path: AbsoluteFsPath): FileStats;
stat(path: AbsoluteFsPath): FileStats;
realpath(filePath: AbsoluteFsPath): AbsoluteFsPath;
getDefaultLibLocation(): AbsoluteFsPath;
}
/**
* A basic interface to abstract the underlying file-system.
*
* This makes it easier to provide mock file-systems in unit tests,
* but also to create clever file-systems that have features such as caching.
*/
export interface FileSystem extends ReadonlyFileSystem {
writeFile(path: AbsoluteFsPath, data: string | Uint8Array, exclusive?: boolean): void;
removeFile(path: AbsoluteFsPath): void;
symlink(target: AbsoluteFsPath, path: AbsoluteFsPath): void;
copyFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
moveFile(from: AbsoluteFsPath, to: AbsoluteFsPath): void;
ensureDir(path: AbsoluteFsPath): void;
removeDeep(path: AbsoluteFsPath): void;
}
export type PathString = string | AbsoluteFsPath | PathSegment;
/**
* Information about an object in the FileSystem.
* This is analogous to the `fs.Stats` class in Node.js.
*/
export interface FileStats {
isFile(): boolean;
isDirectory(): boolean;
isSymbolicLink(): boolean;
}

View File

@@ -0,0 +1,18 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath, PathString } from './types';
/**
* Convert Windows-style separators to POSIX separators.
*/
export declare function normalizeSeparators(path: string): string;
/**
* Remove a .ts, .d.ts, or .js extension from a file name.
*/
export declare function stripExtension<T extends PathString>(path: T): T;
export declare function getSourceFileOrError(program: ts.Program, fileName: AbsoluteFsPath): ts.SourceFile;

View File

@@ -0,0 +1,16 @@
/**
* @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.io/license
*/
export { AliasingHost, AliasStrategy, PrivateExportAliasingHost, UnifiedModulesAliasingHost } from './src/alias';
export { ImportRewriter, NoopImportRewriter, R3SymbolsImportRewriter, validateAndRewriteCoreSymbol } from './src/core';
export { DefaultImportTracker } from './src/default';
export { DeferredSymbolTracker } from './src/deferred_symbol_tracker';
export { AbsoluteModuleStrategy, assertSuccessfulReferenceEmit, EmittedReference, FailedEmitResult, ImportedFile, ImportFlags, LocalIdentifierStrategy, LogicalProjectStrategy, ReferenceEmitKind, ReferenceEmitResult, ReferenceEmitStrategy, ReferenceEmitter, RelativePathStrategy, UnifiedModulesStrategy } from './src/emitter';
export { isAliasImportDeclaration, loadIsReferencedAliasDeclarationPatch } from './src/patch_alias_reference_resolution';
export { Reexport } from './src/reexport';
export { OwningModule, Reference } from './src/references';
export { ModuleResolver } from './src/resolver';

View File

@@ -0,0 +1,139 @@
/**
* @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.io/license
*/
import { Expression } from '@angular/compiler';
import ts from 'typescript';
import { UnifiedModulesHost } from '../../core/api';
import { ClassDeclaration, ReflectionHost } from '../../reflection';
import { EmittedReference, ImportFlags, ReferenceEmitStrategy } from './emitter';
import { Reference } from './references';
/**
* A host for the aliasing system, which allows for alternative exports/imports of directives/pipes.
*
* Given an import of an NgModule (e.g. `CommonModule`), the compiler must generate imports to the
* directives and pipes exported by this module (e.g. `NgIf`) when they're used in a particular
* template. In its default configuration, if the compiler is not directly able to import the
* component from another file within the same project, it will attempt to import the component
* from the same (absolute) path by which the module was imported. So in the above example if
* `CommonModule` was imported from '@angular/common', the compiler will attempt to import `NgIf`
* from '@angular/common' as well.
*
* The aliasing system interacts with the above logic in two distinct ways.
*
* 1) It can be used to create "alias" re-exports from different files, which can be used when the
* user hasn't exported the directive(s) from the ES module containing the NgModule. These re-
* exports can also be helpful when using a `UnifiedModulesHost`, which overrides the import
* logic described above.
*
* 2) It can be used to get an alternative import expression for a directive or pipe, instead of
* the import that the normal logic would apply. The alias used depends on the provenance of the
* `Reference` which was obtained for the directive/pipe, which is usually a property of how it
* came to be in a template's scope (e.g. by which NgModule).
*
* See the README.md for more information on how aliasing works within the compiler.
*/
export interface AliasingHost {
/**
* Controls whether any alias re-exports are rendered into .d.ts files.
*
* This is not always necessary for aliasing to function correctly, so this flag allows an
* `AliasingHost` to avoid cluttering the .d.ts files if exports are not strictly needed.
*/
readonly aliasExportsInDts: boolean;
/**
* Determine a name by which `decl` should be re-exported from `context`, depending on the
* particular set of aliasing rules in place.
*
* `maybeAliasSymbolAs` can return `null`, in which case no alias export should be generated.
*
* @param ref a `Reference` to the directive/pipe to consider for aliasing.
* @param context the `ts.SourceFile` in which the alias re-export might need to be generated.
* @param ngModuleName the declared name of the `NgModule` within `context` for which the alias
* would be generated.
* @param isReExport whether the directive/pipe under consideration is re-exported from another
* NgModule (as opposed to being declared by it directly).
*/
maybeAliasSymbolAs(ref: Reference<ClassDeclaration>, context: ts.SourceFile, ngModuleName: string, isReExport: boolean): string | null;
/**
* Determine an `Expression` by which `decl` should be imported from `via` using an alias export
* (which should have been previously created when compiling `via`).
*
* `getAliasIn` can return `null`, in which case no alias is needed to import `decl` from `via`
* (and the normal import rules should be used).
*
* @param decl the declaration of the directive/pipe which is being imported, and which might be
* aliased.
* @param via the `ts.SourceFile` which might contain an alias to the
*/
getAliasIn(decl: ClassDeclaration, via: ts.SourceFile, isReExport: boolean): Expression | null;
}
/**
* An `AliasingHost` which generates and consumes alias re-exports when module names for each file
* are determined by a `UnifiedModulesHost`.
*
* When using a `UnifiedModulesHost`, aliasing prevents issues with transitive dependencies. See the
* README.md for more details.
*/
export declare class UnifiedModulesAliasingHost implements AliasingHost {
private unifiedModulesHost;
constructor(unifiedModulesHost: UnifiedModulesHost);
/**
* With a `UnifiedModulesHost`, aliases are chosen automatically without the need to look through
* the exports present in a .d.ts file, so we can avoid cluttering the .d.ts files.
*/
readonly aliasExportsInDts = false;
maybeAliasSymbolAs(ref: Reference<ClassDeclaration>, context: ts.SourceFile, ngModuleName: string, isReExport: boolean): string | null;
/**
* Generates an `Expression` to import `decl` from `via`, assuming an export was added when `via`
* was compiled per `maybeAliasSymbolAs` above.
*/
getAliasIn(decl: ClassDeclaration, via: ts.SourceFile, isReExport: boolean): Expression | null;
/**
* Generates an alias name based on the full module name of the file which declares the aliased
* directive/pipe.
*/
private aliasName;
}
/**
* An `AliasingHost` which exports directives from any file containing an NgModule in which they're
* declared/exported, under a private symbol name.
*
* These exports support cases where an NgModule is imported deeply from an absolute module path
* (that is, it's not part of an Angular Package Format entrypoint), and the compiler needs to
* import any matched directives/pipes from the same path (to the NgModule file). See README.md for
* more details.
*/
export declare class PrivateExportAliasingHost implements AliasingHost {
private host;
constructor(host: ReflectionHost);
/**
* Under private export aliasing, the `AbsoluteModuleStrategy` used for emitting references will
* will select aliased exports that it finds in the .d.ts file for an NgModule's file. Thus,
* emitting these exports in .d.ts is a requirement for the `PrivateExportAliasingHost` to
* function correctly.
*/
readonly aliasExportsInDts = true;
maybeAliasSymbolAs(ref: Reference<ClassDeclaration>, context: ts.SourceFile, ngModuleName: string): string | null;
/**
* A `PrivateExportAliasingHost` only generates re-exports and does not direct the compiler to
* directly consume the aliases it creates.
*
* Instead, they're consumed indirectly: `AbsoluteModuleStrategy` `ReferenceEmitterStrategy` will
* select these alias exports automatically when looking for an export of the directive/pipe from
* the same path as the NgModule was imported.
*
* Thus, `getAliasIn` always returns `null`.
*/
getAliasIn(): null;
}
/**
* A `ReferenceEmitStrategy` which will consume the alias attached to a particular `Reference` to a
* directive or pipe, if it exists.
*/
export declare class AliasStrategy implements ReferenceEmitStrategy {
emit(ref: Reference, context: ts.SourceFile, importMode: ImportFlags): EmittedReference | null;
}

View File

@@ -0,0 +1,48 @@
/**
* @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.io/license
*/
/**
* Rewrites imports of symbols being written into generated code.
*/
export interface ImportRewriter {
/**
* Should the given symbol be imported at all?
*
* If `true`, the symbol should be imported from the given specifier. If `false`, the symbol
* should be referenced directly, without an import.
*/
shouldImportSymbol(symbol: string, specifier: string): boolean;
/**
* Optionally rewrite a reference to an imported symbol, changing either the binding prefix or the
* symbol name itself.
*/
rewriteSymbol(symbol: string, specifier: string): string;
/**
* Optionally rewrite the given module specifier in the context of a given file.
*/
rewriteSpecifier(specifier: string, inContextOfFile: string): string;
}
/**
* `ImportRewriter` that does no rewriting.
*/
export declare class NoopImportRewriter implements ImportRewriter {
shouldImportSymbol(symbol: string, specifier: string): boolean;
rewriteSymbol(symbol: string, specifier: string): string;
rewriteSpecifier(specifier: string, inContextOfFile: string): string;
}
/**
* `ImportRewriter` that rewrites imports from '@angular/core' to be imported from the r3_symbols.ts
* file instead.
*/
export declare class R3SymbolsImportRewriter implements ImportRewriter {
private r3SymbolsPath;
constructor(r3SymbolsPath: string);
shouldImportSymbol(symbol: string, specifier: string): boolean;
rewriteSymbol(symbol: string, specifier: string): string;
rewriteSpecifier(specifier: string, inContextOfFile: string): string;
}
export declare function validateAndRewriteCoreSymbol(name: string): string;

View File

@@ -0,0 +1,64 @@
/**
* @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.io/license
*/
import { WrappedNodeExpr } from '@angular/compiler';
import ts from 'typescript';
/**
* Attaches a default import declaration to `expr` to indicate the dependency of `expr` on the
* default import.
*/
export declare function attachDefaultImportDeclaration(expr: WrappedNodeExpr<unknown>, importDecl: ts.ImportDeclaration): void;
/**
* Obtains the default import declaration that `expr` depends on, or `null` if there is no such
* dependency.
*/
export declare function getDefaultImportDeclaration(expr: WrappedNodeExpr<unknown>): ts.ImportDeclaration | null;
/**
* TypeScript has trouble with generating default imports inside of transformers for some module
* formats. The issue is that for the statement:
*
* import X from 'some/module';
* console.log(X);
*
* TypeScript will not use the "X" name in generated code. For normal user code, this is fine
* because references to X will also be renamed. However, if both the import and any references are
* added in a transformer, TypeScript does not associate the two, and will leave the "X" references
* dangling while renaming the import variable. The generated code looks something like:
*
* const module_1 = require('some/module');
* console.log(X); // now X is a dangling reference.
*
* Therefore, we cannot synthetically add default imports, and must reuse the imports that users
* include. Doing this poses a challenge for imports that are only consumed in the type position in
* the user's code. If Angular reuses the imported symbol in a value position (for example, we
* see a constructor parameter of type Foo and try to write "inject(Foo)") we will also end up with
* a dangling reference, as TS will elide the import because it was only used in the type position
* originally.
*
* To avoid this, the compiler must patch the emit resolver, and should only do this for imports
* which are actually consumed. The `DefaultImportTracker` keeps track of these imports as they're
* encountered and emitted, and implements a transform which can correctly flag the imports as
* required.
*
* This problem does not exist for non-default imports as the compiler can easily insert
* "import * as X" style imports for those, and the "X" identifier survives transformation.
*/
export declare class DefaultImportTracker {
/**
* A `Map` which tracks the `Set` of `ts.ImportClause`s for default imports that were used in
* a given file name.
*/
private sourceFileToUsedImports;
recordUsedImport(importDecl: ts.ImportDeclaration): void;
/**
* Get a `ts.TransformerFactory` which will preserve default imports that were previously marked
* as used.
*
* This transformer must run after any other transformers which call `recordUsedImport`.
*/
importPreservingTransformer(): ts.TransformerFactory<ts.SourceFile>;
}

View File

@@ -0,0 +1,47 @@
/**
* @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.io/license
*/
import ts from 'typescript';
/**
* Allows to register a symbol as deferrable and keep track of its usage.
*
* This information is later used to determine whether it's safe to drop
* a regular import of this symbol (actually the entire import declaration)
* in favor of using a dynamic import for cases when defer blocks are used.
*/
export declare class DeferredSymbolTracker {
private readonly typeChecker;
private readonly imports;
constructor(typeChecker: ts.TypeChecker);
/**
* Given an import declaration node, extract the names of all imported symbols
* and return them as a map where each symbol is a key and `AssumeEager` is a value.
*
* The logic recognizes the following import shapes:
*
* Case 1: `import {a, b as B} from 'a'`
* Case 2: `import X from 'a'`
* Case 3: `import * as x from 'a'`
*/
private extractImportedSymbols;
/**
* Marks a given identifier and an associated import declaration as a candidate
* for defer loading.
*/
markAsDeferrableCandidate(identifier: ts.Identifier, importDecl: ts.ImportDeclaration): void;
/**
* Whether all symbols from a given import declaration have no references
* in a source file, thus it's safe to use dynamic imports.
*/
canDefer(importDecl: ts.ImportDeclaration): boolean;
/**
* Returns a set of import declarations that is safe to remove
* from the current source file and generate dynamic imports instead.
*/
getDeferrableImportDecls(): Set<ts.ImportDeclaration>;
private lookupIdentifiersInSourceFile;
}

View File

@@ -0,0 +1,235 @@
/**
* @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.io/license
*/
import { Expression } from '@angular/compiler';
import ts from 'typescript';
import { UnifiedModulesHost } from '../../core/api';
import { LogicalFileSystem } from '../../file_system';
import { DeclarationNode, ReflectionHost } from '../../reflection';
import { Reference } from './references';
import { ModuleResolver } from './resolver';
/**
* Flags which alter the imports generated by the `ReferenceEmitter`.
*/
export declare enum ImportFlags {
None = 0,
/**
* Force the generation of a new import when generating a reference, even if an identifier already
* exists in the target file which could be used instead.
*
* This is sometimes required if there's a risk TypeScript might remove imports during emit.
*/
ForceNewImport = 1,
/**
* Don't make use of any aliasing information when emitting a reference.
*
* This is sometimes required if emitting into a context where generated references will be fed
* into TypeScript and type-checked (such as in template type-checking).
*/
NoAliasing = 2,
/**
* Indicates that an import to a type-only declaration is allowed.
*
* For references that occur in type-positions, the referred declaration may be a type-only
* declaration that is not retained during emit. Including this flag allows to emit references to
* type-only declarations as used in e.g. template type-checking.
*/
AllowTypeImports = 4,
/**
* Indicates that importing from a declaration file using a relative import path is allowed.
*
* The generated imports should normally use module specifiers that are valid for use in
* production code, where arbitrary relative imports into e.g. node_modules are not allowed. For
* template type-checking code it is however acceptable to use relative imports, as such files are
* never emitted to JS code.
*
* Non-declaration files have to be contained within a configured `rootDir` so using relative
* paths may not be possible for those, hence this flag only applies when importing from a
* declaration file.
*/
AllowRelativeDtsImports = 8,
/**
* Indicates that references coming from ambient imports are allowed.
*/
AllowAmbientReferences = 16
}
/**
* An emitter strategy has the ability to indicate which `ts.SourceFile` is being imported by the
* expression that it has generated. This information is useful for consumers of the emitted
* reference that would otherwise have to perform a relatively expensive module resolution step,
* e.g. for cyclic import analysis. In cases the emitter is unable to definitively determine the
* imported source file or a computation would be required to actually determine the imported
* source file, then `'unknown'` should be returned. If the generated expression does not represent
* an import then `null` should be used.
*/
export type ImportedFile = ts.SourceFile | 'unknown' | null;
export declare const enum ReferenceEmitKind {
Success = 0,
Failed = 1
}
/**
* Represents the emitted expression of a `Reference` that is valid in the source file it was
* emitted from.
*/
export interface EmittedReference {
kind: ReferenceEmitKind.Success;
/**
* The expression that refers to `Reference`.
*/
expression: Expression;
/**
* The `ts.SourceFile` that is imported by `expression`. This is not necessarily the source file
* of the `Reference`'s declaration node, as the reference may have been rewritten through an
* alias export. It could also be `null` if `expression` is a local identifier, or `'unknown'` if
* the exact source file that is being imported is not known to the emitter.
*/
importedFile: ImportedFile;
}
/**
* Represents a failure to emit a `Reference` into a different source file.
*/
export interface FailedEmitResult {
kind: ReferenceEmitKind.Failed;
/**
* The reference that could not be emitted.
*/
ref: Reference;
/**
* The source file into which the reference was requested to be emitted.
*/
context: ts.SourceFile;
/**
* Describes why the reference could not be emitted. This may be shown in a diagnostic.
*/
reason: string;
}
export type ReferenceEmitResult = EmittedReference | FailedEmitResult;
/**
* Verifies that a reference was emitted successfully, or raises a `FatalDiagnosticError` otherwise.
* @param result The emit result that should have been successful.
* @param origin The node that is used to report the failure diagnostic.
* @param typeKind The kind of the symbol that the reference represents, e.g. 'component' or
* 'class'.
*/
export declare function assertSuccessfulReferenceEmit(result: ReferenceEmitResult, origin: ts.Node, typeKind: string): asserts result is EmittedReference;
/**
* A particular strategy for generating an expression which refers to a `Reference`.
*
* There are many potential ways a given `Reference` could be referred to in the context of a given
* file. A local declaration could be available, the `Reference` could be importable via a relative
* import within the project, or an absolute import into `node_modules` might be necessary.
*
* Different `ReferenceEmitStrategy` implementations implement specific logic for generating such
* references. A single strategy (such as using a local declaration) may not always be able to
* generate an expression for every `Reference` (for example, if no local identifier is available),
* and may return `null` in such a case.
*/
export interface ReferenceEmitStrategy {
/**
* Emit an `Expression` which refers to the given `Reference` in the context of a particular
* source file, if possible.
*
* @param ref the `Reference` for which to generate an expression
* @param context the source file in which the `Expression` must be valid
* @param importFlags a flag which controls whether imports should be generated or not
* @returns an `EmittedReference` which refers to the `Reference`, or `null` if none can be
* generated
*/
emit(ref: Reference, context: ts.SourceFile, importFlags: ImportFlags): ReferenceEmitResult | null;
}
/**
* Generates `Expression`s which refer to `Reference`s in a given context.
*
* A `ReferenceEmitter` uses one or more `ReferenceEmitStrategy` implementations to produce an
* `Expression` which refers to a `Reference` in the context of a particular file.
*/
export declare class ReferenceEmitter {
private strategies;
constructor(strategies: ReferenceEmitStrategy[]);
emit(ref: Reference, context: ts.SourceFile, importFlags?: ImportFlags): ReferenceEmitResult;
}
/**
* A `ReferenceEmitStrategy` which will refer to declarations by any local `ts.Identifier`s, if
* such identifiers are available.
*/
export declare class LocalIdentifierStrategy implements ReferenceEmitStrategy {
emit(ref: Reference, context: ts.SourceFile, importFlags: ImportFlags): EmittedReference | null;
}
/**
* Represents the exported declarations from a module source file.
*/
interface ModuleExports {
/**
* The source file of the module.
*/
module: ts.SourceFile | null;
/**
* The map of declarations to their exported name.
*/
exportMap: Map<DeclarationNode, string> | null;
}
/**
* A `ReferenceEmitStrategy` which will refer to declarations that come from `node_modules` using
* an absolute import.
*
* Part of this strategy involves looking at the target entry point and identifying the exported
* name of the targeted declaration, as it might be different from the declared name (e.g. a
* directive might be declared as FooDirImpl, but exported as FooDir). If no export can be found
* which maps back to the original directive, an error is thrown.
*/
export declare class AbsoluteModuleStrategy implements ReferenceEmitStrategy {
protected program: ts.Program;
protected checker: ts.TypeChecker;
protected moduleResolver: ModuleResolver;
private reflectionHost;
/**
* A cache of the exports of specific modules, because resolving a module to its exports is a
* costly operation.
*/
private moduleExportsCache;
constructor(program: ts.Program, checker: ts.TypeChecker, moduleResolver: ModuleResolver, reflectionHost: ReflectionHost);
emit(ref: Reference, context: ts.SourceFile, importFlags: ImportFlags): ReferenceEmitResult | null;
private getExportsOfModule;
protected enumerateExportsOfModule(specifier: string, fromFile: string): ModuleExports;
}
/**
* A `ReferenceEmitStrategy` which will refer to declarations via relative paths, provided they're
* both in the logical project "space" of paths.
*
* This is trickier than it sounds, as the two files may be in different root directories in the
* project. Simply calculating a file system relative path between the two is not sufficient.
* Instead, `LogicalProjectPath`s are used.
*/
export declare class LogicalProjectStrategy implements ReferenceEmitStrategy {
private reflector;
private logicalFs;
private relativePathStrategy;
constructor(reflector: ReflectionHost, logicalFs: LogicalFileSystem);
emit(ref: Reference, context: ts.SourceFile, importFlags: ImportFlags): ReferenceEmitResult | null;
}
/**
* A `ReferenceEmitStrategy` which constructs relatives paths between `ts.SourceFile`s.
*
* This strategy can be used if there is no `rootDir`/`rootDirs` structure for the project which
* necessitates the stronger logic of `LogicalProjectStrategy`.
*/
export declare class RelativePathStrategy implements ReferenceEmitStrategy {
private reflector;
constructor(reflector: ReflectionHost);
emit(ref: Reference, context: ts.SourceFile): ReferenceEmitResult | null;
}
/**
* A `ReferenceEmitStrategy` which uses a `UnifiedModulesHost` to generate absolute import
* references.
*/
export declare class UnifiedModulesStrategy implements ReferenceEmitStrategy {
private reflector;
private unifiedModulesHost;
constructor(reflector: ReflectionHost, unifiedModulesHost: UnifiedModulesHost);
emit(ref: Reference, context: ts.SourceFile): EmittedReference | null;
}
export {};

View File

@@ -0,0 +1,13 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { ReflectionHost } from '../../reflection';
/**
* Find the name, if any, by which a node is exported from a given file.
*/
export declare function findExportedNameOfNode(target: ts.Node, file: ts.SourceFile, reflector: ReflectionHost): string | null;

View File

@@ -0,0 +1,61 @@
/**
* @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.io/license
*/
import ts from 'typescript';
/**
* Patches the alias declaration reference resolution for a given transformation context
* so that TypeScript knows about the specified alias declarations being referenced.
*
* This exists because TypeScript performs analysis of import usage before transformers
* run and doesn't refresh its state after transformations. This means that imports
* for symbols used as constructor types are elided due to their original type-only usage.
*
* In reality though, since we downlevel decorators and constructor parameters, we want
* these symbols to be retained in the JavaScript output as they will be used as values
* at runtime. We can instruct TypeScript to preserve imports for such identifiers by
* creating a mutable clone of a given import specifier/clause or namespace, but that
* has the downside of preserving the full import in the JS output. See:
* https://github.com/microsoft/TypeScript/blob/3eaa7c65f6f076a08a5f7f1946fd0df7c7430259/src/compiler/transformers/ts.ts#L242-L250.
*
* This is a trick the CLI used in the past for constructor parameter downleveling in JIT:
* https://github.com/angular/angular-cli/blob/b3f84cc5184337666ce61c07b7b9df418030106f/packages/ngtools/webpack/src/transformers/ctor-parameters.ts#L323-L325
* The trick is not ideal though as it preserves the full import (as outlined before), and it
* results in a slow-down due to the type checker being involved multiple times. The CLI worked
* around this import preserving issue by having another complex post-process step that detects and
* elides unused imports. Note that these unused imports could cause unused chunks being generated
* by Webpack if the application or library is not marked as side-effect free.
*
* This is not ideal though, as we basically re-implement the complex import usage resolution
* from TypeScript. We can do better by letting TypeScript do the import eliding, but providing
* information about the alias declarations (e.g. import specifiers) that should not be elided
* because they are actually referenced (as they will now appear in static properties).
*
* More information about these limitations with transformers can be found in:
* 1. https://github.com/Microsoft/TypeScript/issues/17552.
* 2. https://github.com/microsoft/TypeScript/issues/17516.
* 3. https://github.com/angular/tsickle/issues/635.
*
* The patch we apply to tell TypeScript about actual referenced aliases (i.e. imported symbols),
* matches conceptually with the logic that runs internally in TypeScript when the
* `emitDecoratorMetadata` flag is enabled. TypeScript basically surfaces the same problem and
* solves it conceptually the same way, but obviously doesn't need to access an internal API.
*
* The set that is returned by this function is meant to be filled with import declaration nodes
* that have been referenced in a value-position by the transform, such the installed patch can
* ensure that those import declarations are not elided.
*
* See below. Note that this uses sourcegraph as the TypeScript checker file doesn't display on
* Github.
* https://sourcegraph.com/github.com/microsoft/TypeScript@3eaa7c65f6f076a08a5f7f1946fd0df7c7430259/-/blob/src/compiler/checker.ts#L31219-31257
*/
export declare function loadIsReferencedAliasDeclarationPatch(context: ts.TransformationContext): Set<ts.Declaration>;
/**
* Gets whether a given node corresponds to an import alias declaration. Alias
* declarations can be import specifiers, namespace imports or import clauses
* as these do not declare an actual symbol but just point to a target declaration.
*/
export declare function isAliasImportDeclaration(node: ts.Node): node is ts.ImportSpecifier | ts.NamespaceImport | ts.ImportClause;

View File

@@ -0,0 +1,12 @@
/**
* @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.io/license
*/
export interface Reexport {
symbolName: string;
asAlias: string;
fromModule: string;
}

View File

@@ -0,0 +1,109 @@
/**
* @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.io/license
*/
import { Expression } from '@angular/compiler';
import ts from 'typescript';
import { AmbientImport } from '../../reflection';
export interface OwningModule {
specifier: string;
resolutionContext: string;
}
/**
* A `ts.Node` plus the context in which it was discovered.
*
* A `Reference` is a pointer to a `ts.Node` that was extracted from the program somehow. It
* contains not only the node itself, but the information regarding how the node was located. In
* particular, it might track different identifiers by which the node is exposed, as well as
* potentially a module specifier which might expose the node.
*
* The Angular compiler uses `Reference`s instead of `ts.Node`s when tracking classes or generating
* imports.
*/
export declare class Reference<T extends ts.Node = ts.Node> {
readonly node: T;
/**
* The compiler's best guess at an absolute module specifier which owns this `Reference`.
*
* This is usually determined by tracking the import statements which led the compiler to a given
* node. If any of these imports are absolute, it's an indication that the node being imported
* might come from that module.
*
* It is not _guaranteed_ that the node in question is exported from its `bestGuessOwningModule` -
* that is mostly a convention that applies in certain package formats.
*
* If `bestGuessOwningModule` is `null`, then it's likely the node came from the current program.
*/
readonly bestGuessOwningModule: OwningModule | null;
private identifiers;
/**
* Indicates that the Reference was created synthetically, not as a result of natural value
* resolution.
*
* This is used to avoid misinterpreting the Reference in certain contexts.
*/
synthetic: boolean;
private _alias;
readonly isAmbient: boolean;
constructor(node: T, bestGuessOwningModule?: OwningModule | AmbientImport | null);
/**
* The best guess at which module specifier owns this particular reference, or `null` if there
* isn't one.
*/
get ownedByModuleGuess(): string | null;
/**
* Whether this reference has a potential owning module or not.
*
* See `bestGuessOwningModule`.
*/
get hasOwningModuleGuess(): boolean;
/**
* A name for the node, if one is available.
*
* This is only suited for debugging. Any actual references to this node should be made with
* `ts.Identifier`s (see `getIdentityIn`).
*/
get debugName(): string | null;
get alias(): Expression | null;
/**
* Record a `ts.Identifier` by which it's valid to refer to this node, within the context of this
* `Reference`.
*/
addIdentifier(identifier: ts.Identifier): void;
/**
* Get a `ts.Identifier` within this `Reference` that can be used to refer within the context of a
* given `ts.SourceFile`, if any.
*/
getIdentityIn(context: ts.SourceFile): ts.Identifier | null;
/**
* Get a `ts.Identifier` for this `Reference` that exists within the given expression.
*
* This is very useful for producing `ts.Diagnostic`s that reference `Reference`s that were
* extracted from some larger expression, as it can be used to pinpoint the `ts.Identifier` within
* the expression from which the `Reference` originated.
*/
getIdentityInExpression(expr: ts.Expression): ts.Identifier | null;
/**
* Given the 'container' expression from which this `Reference` was extracted, produce a
* `ts.Expression` to use in a diagnostic which best indicates the position within the container
* expression that generated the `Reference`.
*
* For example, given a `Reference` to the class 'Bar' and the containing expression:
* `[Foo, Bar, Baz]`, this function would attempt to return the `ts.Identifier` for `Bar` within
* the array. This could be used to produce a nice diagnostic context:
*
* ```text
* [Foo, Bar, Baz]
* ~~~
* ```
*
* If no specific node can be found, then the `fallback` expression is used, which defaults to the
* entire containing expression.
*/
getOriginForDiagnostics(container: ts.Expression, fallback?: ts.Expression): ts.Expression;
cloneWithAlias(alias: Expression): Reference<T>;
cloneWithNoIdentifiers(): Reference<T>;
}

View File

@@ -0,0 +1,22 @@
/**
* @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.io/license
*/
import ts from 'typescript';
/**
* Used by `RouterEntryPointManager` and `NgModuleRouteAnalyzer` (which is in turn is used by
* `NgModuleDecoratorHandler`) for resolving the module source-files references in lazy-loaded
* routes (relative to the source-file containing the `NgModule` that provides the route
* definitions).
*/
export declare class ModuleResolver {
private program;
private compilerOptions;
private host;
private moduleResolutionCache;
constructor(program: ts.Program, compilerOptions: ts.CompilerOptions, host: ts.ModuleResolutionHost & Pick<ts.CompilerHost, 'resolveModuleNames'>, moduleResolutionCache: ts.ModuleResolutionCache | null);
resolveModule(moduleName: string, containingFile: string): ts.SourceFile | null;
}

View File

@@ -0,0 +1,54 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath } from '../file_system';
/**
* Interface of the incremental build engine.
*
* `AnalysisT` is a generic type representing a unit of work. This is generic to avoid a cyclic
* dependency between the incremental engine API definition and its consumer(s).
* `FileTypeCheckDataT` is a generic type representing template type-checking data for a particular
* input file, which is generic for the same reason.
*/
export interface IncrementalBuild<AnalysisT, FileTypeCheckDataT> {
/**
* Retrieve the prior analysis work, if any, done for the given source file.
*/
priorAnalysisFor(sf: ts.SourceFile): AnalysisT[] | null;
/**
* Retrieve the prior type-checking work, if any, that's been done for the given source file.
*/
priorTypeCheckingResultsFor(fileSf: ts.SourceFile): FileTypeCheckDataT | null;
/**
* Reports that template type-checking has completed successfully, with a map of type-checking
* data for each user file which can be reused in a future incremental iteration.
*/
recordSuccessfulTypeCheck(results: Map<AbsoluteFsPath, FileTypeCheckDataT>): void;
}
/**
* Tracks dependencies between source files or resources in the application.
*/
export interface DependencyTracker<T extends {
fileName: string;
} = ts.SourceFile> {
/**
* Record that the file `from` depends on the file `on`.
*/
addDependency(from: T, on: T): void;
/**
* Record that the file `from` depends on the resource file `on`.
*/
addResourceDependency(from: T, on: AbsoluteFsPath): void;
/**
* Record that the given file contains unresolvable dependencies.
*
* In practice, this means that the dependency graph cannot provide insight into the effects of
* future changes on that file.
*/
recordDependencyAnalysisFailure(file: T): void;
}

View File

@@ -0,0 +1,11 @@
/**
* @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.io/license
*/
export { IncrementalCompilation } from './src/incremental';
export { NOOP_INCREMENTAL_BUILD } from './src/noop';
export { AnalyzedIncrementalState, DeltaIncrementalState, FreshIncrementalState, IncrementalState, IncrementalStateKind } from './src/state';
export * from './src/strategy';

View File

@@ -0,0 +1,11 @@
/**
* @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.io/license
*/
export { SemanticReference, SemanticSymbol } from './src/api';
export { SemanticDepGraph, SemanticDepGraphUpdater } from './src/graph';
export { areTypeParametersEqual, extractSemanticTypeParameters, SemanticTypeParameter } from './src/type_parameters';
export { isArrayEqual, isReferenceEqual, isSetEqual, isSymbolEqual } from './src/util';

View File

@@ -0,0 +1,97 @@
import { AbsoluteFsPath } from '../../../file_system';
import { ClassDeclaration } from '../../../reflection';
/**
* Represents a symbol that is recognizable across incremental rebuilds, which enables the captured
* metadata to be compared to the prior compilation. This allows for semantic understanding of
* the changes that have been made in a rebuild, which potentially enables more reuse of work
* from the prior compilation.
*/
export declare abstract class SemanticSymbol {
/**
* The declaration for this symbol.
*/
readonly decl: ClassDeclaration;
/**
* The path of the file that declares this symbol.
*/
readonly path: AbsoluteFsPath;
/**
* The identifier of this symbol, or null if no identifier could be determined. It should
* uniquely identify the symbol relative to `file`. This is typically just the name of a
* top-level class declaration, as that uniquely identifies the class within the file.
*
* If the identifier is null, then this symbol cannot be recognized across rebuilds. In that
* case, the symbol is always assumed to have semantically changed to guarantee a proper
* rebuild.
*/
readonly identifier: string | null;
constructor(
/**
* The declaration for this symbol.
*/
decl: ClassDeclaration);
/**
* Allows the symbol to be compared to the equivalent symbol in the previous compilation. The
* return value indicates whether the symbol has been changed in a way such that its public API
* is affected.
*
* This method determines whether a change to _this_ symbol require the symbols that
* use to this symbol to be re-emitted.
*
* Note: `previousSymbol` is obtained from the most recently succeeded compilation. Symbols of
* failed compilations are never provided.
*
* @param previousSymbol The symbol from a prior compilation.
*/
abstract isPublicApiAffected(previousSymbol: SemanticSymbol): boolean;
/**
* Allows the symbol to determine whether its emit is affected. The equivalent symbol from a prior
* build is given, in addition to the set of symbols of which the public API has changed.
*
* This method determines whether a change to _other_ symbols, i.e. those present in
* `publicApiAffected`, should cause _this_ symbol to be re-emitted.
*
* @param previousSymbol The equivalent symbol from a prior compilation. Note that it may be a
* different type of symbol, if e.g. a Component was changed into a Directive with the same name.
* @param publicApiAffected The set of symbols of which the public API has changed.
*/
isEmitAffected?(previousSymbol: SemanticSymbol, publicApiAffected: Set<SemanticSymbol>): boolean;
/**
* Similar to `isPublicApiAffected`, but here equivalent symbol from a prior compilation needs
* to be compared to see if the type-check block of components that use this symbol is affected.
*
* This method determines whether a change to _this_ symbol require the symbols that
* use to this symbol to have their type-check block regenerated.
*
* Note: `previousSymbol` is obtained from the most recently succeeded compilation. Symbols of
* failed compilations are never provided.
*
* @param previousSymbol The symbol from a prior compilation.
*/
abstract isTypeCheckApiAffected(previousSymbol: SemanticSymbol): boolean;
/**
* Similar to `isEmitAffected`, but focused on the type-check block of this symbol. This method
* determines whether a change to _other_ symbols, i.e. those present in `typeCheckApiAffected`,
* should cause _this_ symbol's type-check block to be regenerated.
*
* @param previousSymbol The equivalent symbol from a prior compilation. Note that it may be a
* different type of symbol, if e.g. a Component was changed into a Directive with the same name.
* @param typeCheckApiAffected The set of symbols of which the type-check API has changed.
*/
isTypeCheckBlockAffected?(previousSymbol: SemanticSymbol, typeCheckApiAffected: Set<SemanticSymbol>): boolean;
}
/**
* Represents a reference to a semantic symbol that has been emitted into a source file. The
* reference may refer to the symbol using a different name than the semantic symbol's declared
* name, e.g. in case a re-export under a different name was chosen by a reference emitter.
* Consequently, to know that an emitted reference is still valid not only requires that the
* semantic symbol is still valid, but also that the path by which the symbol is imported has not
* changed.
*/
export interface SemanticReference {
symbol: SemanticSymbol;
/**
* The path by which the symbol has been referenced.
*/
importPath: string | null;
}

View File

@@ -0,0 +1,104 @@
/**
* @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.io/license
*/
import { Expression } from '@angular/compiler';
import { AbsoluteFsPath } from '../../../file_system';
import { ClassDeclaration } from '../../../reflection';
import { SemanticReference, SemanticSymbol } from './api';
export interface SemanticDependencyResult {
/**
* The files that need to be re-emitted.
*/
needsEmit: Set<AbsoluteFsPath>;
/**
* The files for which the type-check block should be regenerated.
*/
needsTypeCheckEmit: Set<AbsoluteFsPath>;
/**
* The newly built graph that represents the current compilation.
*/
newGraph: SemanticDepGraph;
}
/**
* The semantic dependency graph of a single compilation.
*/
export declare class SemanticDepGraph {
readonly files: Map<AbsoluteFsPath, Map<string, SemanticSymbol>>;
readonly symbolByDecl: Map<ClassDeclaration, SemanticSymbol>;
/**
* Registers a symbol in the graph. The symbol is given a unique identifier if possible, such that
* its equivalent symbol can be obtained from a prior graph even if its declaration node has
* changed across rebuilds. Symbols without an identifier are only able to find themselves in a
* prior graph if their declaration node is identical.
*/
registerSymbol(symbol: SemanticSymbol): void;
/**
* Attempts to resolve a symbol in this graph that represents the given symbol from another graph.
* If no matching symbol could be found, null is returned.
*
* @param symbol The symbol from another graph for which its equivalent in this graph should be
* found.
*/
getEquivalentSymbol(symbol: SemanticSymbol): SemanticSymbol | null;
/**
* Attempts to find the symbol by its identifier.
*/
private getSymbolByName;
/**
* Attempts to resolve the declaration to its semantic symbol.
*/
getSymbolByDecl(decl: ClassDeclaration): SemanticSymbol | null;
}
/**
* Implements the logic to go from a previous dependency graph to a new one, along with information
* on which files have been affected.
*/
export declare class SemanticDepGraphUpdater {
/**
* The semantic dependency graph of the most recently succeeded compilation, or null if this
* is the initial build.
*/
private priorGraph;
private readonly newGraph;
/**
* Contains opaque symbols that were created for declarations for which there was no symbol
* registered, which happens for e.g. external declarations.
*/
private readonly opaqueSymbols;
constructor(
/**
* The semantic dependency graph of the most recently succeeded compilation, or null if this
* is the initial build.
*/
priorGraph: SemanticDepGraph | null);
/**
* Registers the symbol in the new graph that is being created.
*/
registerSymbol(symbol: SemanticSymbol): void;
/**
* Takes all facts that have been gathered to create a new semantic dependency graph. In this
* process, the semantic impact of the changes is determined which results in a set of files that
* need to be emitted and/or type-checked.
*/
finalize(): SemanticDependencyResult;
private determineInvalidatedFiles;
private determineInvalidatedTypeCheckFiles;
/**
* Creates a `SemanticReference` for the reference to `decl` using the expression `expr`. See
* the documentation of `SemanticReference` for details.
*/
getSemanticReference(decl: ClassDeclaration, expr: Expression): SemanticReference;
/**
* Gets the `SemanticSymbol` that was registered for `decl` during the current compilation, or
* returns an opaque symbol that represents `decl`.
*/
getSymbol(decl: ClassDeclaration): SemanticSymbol;
/**
* Gets or creates an `OpaqueSymbol` for the provided class declaration.
*/
private getOpaqueSymbol;
}

View File

@@ -0,0 +1,29 @@
import { ClassDeclaration } from '../../../reflection';
/**
* Describes a generic type parameter of a semantic symbol. A class declaration with type parameters
* needs special consideration in certain contexts. For example, template type-check blocks may
* contain type constructors of used directives which include the type parameters of the directive.
* As a consequence, if a change is made that affects the type parameters of said directive, any
* template type-check blocks that use the directive need to be regenerated.
*
* This type represents a single generic type parameter. It currently only tracks whether the
* type parameter has a constraint, i.e. has an `extends` clause. When a constraint is present, we
* currently assume that the type parameter is affected in each incremental rebuild; proving that
* a type parameter with constraint is not affected is non-trivial as it requires full semantic
* understanding of the type constraint.
*/
export interface SemanticTypeParameter {
/**
* Whether a type constraint, i.e. an `extends` clause is present on the type parameter.
*/
hasGenericTypeBound: boolean;
}
/**
* Converts the type parameters of the given class into their semantic representation. If the class
* does not have any type parameters, then `null` is returned.
*/
export declare function extractSemanticTypeParameters(node: ClassDeclaration): SemanticTypeParameter[] | null;
/**
* Compares the list of type parameters to determine if they can be considered equal.
*/
export declare function areTypeParametersEqual(current: SemanticTypeParameter[] | null, previous: SemanticTypeParameter[] | null): boolean;

View File

@@ -0,0 +1,28 @@
/**
* @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.io/license
*/
import { SemanticReference, SemanticSymbol } from './api';
/**
* Determines whether the provided symbols represent the same declaration.
*/
export declare function isSymbolEqual(a: SemanticSymbol, b: SemanticSymbol): boolean;
/**
* Determines whether the provided references to a semantic symbol are still equal, i.e. represent
* the same symbol and are imported by the same path.
*/
export declare function isReferenceEqual(a: SemanticReference, b: SemanticReference): boolean;
export declare function referenceEquality<T>(a: T, b: T): boolean;
/**
* Determines if the provided arrays are equal to each other, using the provided equality tester
* that is called for all entries in the array.
*/
export declare function isArrayEqual<T>(a: readonly T[] | null, b: readonly T[] | null, equalityTester?: (a: T, b: T) => boolean): boolean;
/**
* Determines if the provided sets are equal to each other, using the provided equality tester.
* Sets that only differ in ordering are considered equal.
*/
export declare function isSetEqual<T>(a: ReadonlySet<T> | null, b: ReadonlySet<T> | null, equalityTester?: (a: T, b: T) => boolean): boolean;

View File

@@ -0,0 +1,54 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath } from '../../file_system';
import { DependencyTracker } from '../api';
/**
* An implementation of the `DependencyTracker` dependency graph API.
*
* The `FileDependencyGraph`'s primary job is to determine whether a given file has "logically"
* changed, given the set of physical changes (direct changes to files on disk).
*
* A file is logically changed if at least one of three conditions is met:
*
* 1. The file itself has physically changed.
* 2. One of its dependencies has physically changed.
* 3. One of its resource dependencies has physically changed.
*/
export declare class FileDependencyGraph<T extends {
fileName: string;
} = ts.SourceFile> implements DependencyTracker<T> {
private nodes;
addDependency(from: T, on: T): void;
addResourceDependency(from: T, resource: AbsoluteFsPath): void;
recordDependencyAnalysisFailure(file: T): void;
getResourceDependencies(from: T): AbsoluteFsPath[];
/**
* Update the current dependency graph from a previous one, incorporating a set of physical
* changes.
*
* This method performs two tasks:
*
* 1. For files which have not logically changed, their dependencies from `previous` are added to
* `this` graph.
* 2. For files which have logically changed, they're added to a set of logically changed files
* which is eventually returned.
*
* In essence, for build `n`, this method performs:
*
* G(n) + L(n) = G(n - 1) + P(n)
*
* where:
*
* G(n) = the dependency graph of build `n`
* L(n) = the logically changed files from build n - 1 to build n.
* P(n) = the physically changed files from build n - 1 to build n.
*/
updateWithPhysicalChanges(previous: FileDependencyGraph<T>, changedTsPaths: Set<AbsoluteFsPath>, deletedTsPaths: Set<AbsoluteFsPath>, changedResources: Set<AbsoluteFsPath>): Set<AbsoluteFsPath>;
private nodeFor;
}

View File

@@ -0,0 +1,48 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath } from '../../file_system';
import { PerfRecorder } from '../../perf';
import { ClassRecord, TraitCompiler } from '../../transform';
import { FileTypeCheckingData } from '../../typecheck';
import { IncrementalBuild } from '../api';
import { SemanticDepGraphUpdater } from '../semantic_graph';
import { FileDependencyGraph } from './dependency_tracking';
import { IncrementalState } from './state';
/**
* Manages the incremental portion of an Angular compilation, allowing for reuse of a prior
* compilation if available, and producing an output state for reuse of the current compilation in a
* future one.
*/
export declare class IncrementalCompilation implements IncrementalBuild<ClassRecord, FileTypeCheckingData> {
readonly depGraph: FileDependencyGraph;
private versions;
private step;
private phase;
/**
* `IncrementalState` of this compilation if it were to be reused in a subsequent incremental
* compilation at the current moment.
*
* Exposed via the `state` read-only getter.
*/
private _state;
private constructor();
/**
* Begin a fresh `IncrementalCompilation`.
*/
static fresh(program: ts.Program, versions: Map<AbsoluteFsPath, string> | null): IncrementalCompilation;
static incremental(program: ts.Program, newVersions: Map<AbsoluteFsPath, string> | null, oldProgram: ts.Program, oldState: IncrementalState, modifiedResourceFiles: Set<AbsoluteFsPath> | null, perf: PerfRecorder): IncrementalCompilation;
get state(): IncrementalState;
get semanticDepGraphUpdater(): SemanticDepGraphUpdater;
recordSuccessfulAnalysis(traitCompiler: TraitCompiler): void;
recordSuccessfulTypeCheck(results: Map<AbsoluteFsPath, FileTypeCheckingData>): void;
recordSuccessfulEmit(sf: ts.SourceFile): void;
priorAnalysisFor(sf: ts.SourceFile): ClassRecord[] | null;
priorTypeCheckingResultsFor(sf: ts.SourceFile): FileTypeCheckingData | null;
safeToSkipEmit(sf: ts.SourceFile): boolean;
}

View File

@@ -0,0 +1,9 @@
/**
* @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.io/license
*/
import { IncrementalBuild } from '../api';
export declare const NOOP_INCREMENTAL_BUILD: IncrementalBuild<any, any>;

View File

@@ -0,0 +1,97 @@
/**
* @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.io/license
*/
import ts from 'typescript';
import { AbsoluteFsPath } from '../../file_system';
import { ClassRecord } from '../../transform';
import { FileTypeCheckingData } from '../../typecheck/src/checker';
import { SemanticDepGraph } from '../semantic_graph';
import { FileDependencyGraph } from './dependency_tracking';
/**
* Discriminant of the `IncrementalState` union.
*/
export declare enum IncrementalStateKind {
Fresh = 0,
Delta = 1,
Analyzed = 2
}
/**
* Placeholder state for a fresh compilation that has never been successfully analyzed.
*/
export interface FreshIncrementalState {
kind: IncrementalStateKind.Fresh;
}
/**
* State captured from a compilation that completed analysis successfully, that can serve as a
* starting point for a future incremental build.
*/
export interface AnalyzedIncrementalState {
kind: IncrementalStateKind.Analyzed;
/**
* Dependency graph extracted from the build, to be used to determine the logical impact of
* physical file changes.
*/
depGraph: FileDependencyGraph;
/**
* The semantic dependency graph from the build.
*
* This is used to perform in-depth comparison of Angular decorated classes, to determine
* which files have to be re-emitted and/or re-type-checked.
*/
semanticDepGraph: SemanticDepGraph;
/**
* The analysis data from a prior compilation. This stores the trait information for all source
* files that was present in a prior compilation.
*/
priorAnalysis: Map<ts.SourceFile, ClassRecord[]>;
/**
* All generated template type-checking files produced as part of this compilation, or `null` if
* type-checking was not (yet) performed.
*/
typeCheckResults: Map<AbsoluteFsPath, FileTypeCheckingData> | null;
/**
* Cumulative set of source file paths which were definitively emitted by this compilation or
* carried forward from a prior one.
*/
emitted: Set<AbsoluteFsPath>;
/**
* Map of source file paths to the version of this file as seen in the compilation.
*/
versions: Map<AbsoluteFsPath, string> | null;
}
/**
* Incremental state for a compilation that has not been successfully analyzed, but that can be
* based on a previous compilation which was.
*
* This is the state produced by an incremental compilation until its own analysis succeeds. If
* analysis fails, this state carries forward information about which files have changed since the
* last successful build (the `lastAnalyzedState`), so that the next incremental build can consider
* the total delta between the `lastAnalyzedState` and the current program in its incremental
* analysis.
*/
export interface DeltaIncrementalState {
kind: IncrementalStateKind.Delta;
/**
* If available, the `AnalyzedIncrementalState` for the most recent ancestor of the current
* program which was successfully analyzed.
*/
lastAnalyzedState: AnalyzedIncrementalState;
/**
* Set of file paths which have changed since the `lastAnalyzedState` compilation.
*/
physicallyChangedTsFiles: Set<AbsoluteFsPath>;
/**
* Set of resource file paths which have changed since the `lastAnalyzedState` compilation.
*/
changedResourceFiles: Set<AbsoluteFsPath>;
}
/**
* State produced by a compilation that's usable as the starting point for a subsequent compilation.
*
* Discriminated by the `IncrementalStateKind` enum.
*/
export type IncrementalState = AnalyzedIncrementalState | DeltaIncrementalState | FreshIncrementalState;

Some files were not shown because too many files have changed in this diff Show More