This commit is contained in:
CHEVALLIER Abel
2025-11-13 16:23:22 +01:00
parent de9c515a47
commit cb235644dc
34924 changed files with 3811102 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export * from './src/api';
export { aliasTransformFactory } from './src/alias';
export { ClassRecord, TraitCompiler } from './src/compilation';
export { declarationTransformFactory, DtsTransformRegistry, IvyDeclarationDtsTransform, } from './src/declaration';
export { AnalyzedTrait, PendingTrait, ResolvedTrait, SkippedTrait, Trait, TraitState, } from './src/trait';
export { ivyTransformFactory } from './src/transform';
export { signalMetadataTransform } from './src/implicit_signal_debug_name_transform';
+8
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.dev/license
*/
export { angularJitApplicationTransform, getDownlevelDecoratorsTransform, getInitializerApiJitTransform, } from './src/index';
@@ -0,0 +1,23 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import ts from 'typescript';
import { ReflectionHost } from '../../../reflection';
/**
* Gets a transformer for downleveling Angular constructor parameter and property decorators.
*
* Note that Angular class decorators are never processed as those rely on side effects that
* would otherwise no longer be executed. i.e. the creation of a component definition.
*
* @param typeChecker Reference to the program's type checker.
* @param host Reflection host that is used for determining decorators.
* @param diagnostics List which will be populated with diagnostics if any.
* @param isCore Whether the current TypeScript program is for the `@angular/core` package.
* @param isClosureCompilerEnabled Whether closure annotations need to be added where needed.
* @param shouldTransformClass Optional function to check if a given class should be transformed.
*/
export declare function getDownlevelDecoratorsTransform(typeChecker: ts.TypeChecker, host: ReflectionHost, diagnostics: ts.Diagnostic[], isCore: boolean, isClosureCompilerEnabled: boolean, shouldTransformClass?: (node: ts.ClassDeclaration) => boolean): ts.TransformerFactory<ts.SourceFile>;
+29
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.dev/license
*/
import ts from 'typescript';
export { getDownlevelDecoratorsTransform } from './downlevel_decorators_transform';
export { getInitializerApiJitTransform } from './initializer_api_transforms/transform';
/**
* JIT transform for Angular applications. Used by the Angular CLI for unit tests and
* explicit JIT applications.
*
* The transforms include:
*
* - A transform for downleveling Angular decorators and Angular-decorated class constructor
* parameters for dependency injection. This transform can be used by the CLI for JIT-mode
* compilation where constructor parameters and associated Angular decorators should be
* downleveled so that apps are not exposed to the ES2015 temporal dead zone limitation
* in TypeScript. See https://github.com/angular/angular-cli/pull/14473 for more details.
*
* - A transform for adding `@Input` to signal inputs. Signal inputs cannot be recognized
* at runtime using reflection. That is because the class would need to be instantiated-
* but is not possible before creation. To fix this for JIT, a decorator is automatically
* added that will declare the input as a signal input while also capturing the necessary
* metadata
*/
export declare function angularJitApplicationTransform(program: ts.Program, isCore?: boolean, shouldTransformClass?: (node: ts.ClassDeclaration) => boolean): ts.TransformerFactory<ts.SourceFile>;
@@ -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.dev/license
*/
import { PropertyTransform } from './transform_api';
/**
* Transform that will automatically add an `@Input` decorator for all signal
* inputs in Angular classes. The decorator will capture metadata of the signal
* input, derived from the `input()/input.required()` initializer.
*
* This transform is useful for JIT environments where signal inputs would like to be
* used. e.g. for Angular CLI unit testing. In such environments, signal inputs are not
* statically retrievable at runtime. JIT compilation needs to know about all possible inputs
* before instantiating directives. A decorator exposes this information to the class without
* the class needing to be instantiated.
*/
export declare const signalInputsTransform: PropertyTransform;
@@ -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.dev/license
*/
import { PropertyTransform } from './transform_api';
/**
* Transform that automatically adds `@Input` and `@Output` to members initialized as `model()`.
* It is useful for JIT environments where models can't be recognized based on the initializer.
*/
export declare const signalModelTransform: PropertyTransform;
@@ -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.dev/license
*/
import { PropertyTransform } from './transform_api';
/**
* Transform that will automatically add an `@Output` decorator for all initializer API
* outputs in Angular classes. The decorator will capture metadata of the output, such
* as the alias.
*
* This transform is useful for JIT environments. In such environments, such outputs are not
* statically retrievable at runtime. JIT compilation needs to know about all possible outputs
* before instantiating directives. A decorator exposes this information to the class without
* the class needing to be instantiated.
*/
export declare const initializerApiOutputTransform: PropertyTransform;
@@ -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.dev/license
*/
import { PropertyTransform } from './transform_api';
/**
* Transform that will automatically add query decorators for all signal-based
* queries in Angular classes. The decorator will capture metadata of the signal
* query, derived from the initializer-based API call.
*
* This transform is useful for JIT environments where signal queries would like to be
* used. e.g. for Angular CLI unit testing. In such environments, signal queries are not
* statically retrievable at runtime. JIT compilation needs to know about all possible queries
* before instantiating directives to construct the definition. A decorator exposes this
* information to the class without the class needing to be instantiated.
*/
export declare const queryFunctionsTransforms: PropertyTransform;
@@ -0,0 +1,23 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import ts from 'typescript';
import { ImportedSymbolsTracker } from '../../../../imports';
import { ReflectionHost } from '../../../../reflection';
/**
* Creates an AST transform that looks for Angular classes and transforms
* initializer-based declared members to work with JIT compilation.
*
* For example, an `input()` member may be transformed to add an `@Input`
* decorator for JIT.
*
* @param host Reflection host
* @param importTracker Import tracker for efficient import checking.
* @param isCore Whether this transforms runs against `@angular/core`.
* @param shouldTransformClass Optional function to check if a given class should be transformed.
*/
export declare function getInitializerApiJitTransform(host: ReflectionHost, importTracker: ImportedSymbolsTracker, isCore: boolean, shouldTransformClass?: (node: ts.ClassDeclaration) => boolean): ts.TransformerFactory<ts.SourceFile>;
@@ -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.dev/license
*/
import ts from 'typescript';
import { ImportedSymbolsTracker } from '../../../../imports';
import { ClassMember, Decorator, ReflectionHost } from '../../../../reflection';
import { ImportManager } from '../../../../translator';
/** Function that can be used to transform class properties. */
export type PropertyTransform = (member: Pick<ClassMember, 'name' | 'accessLevel' | 'value'> & {
node: ts.PropertyDeclaration;
}, sourceFile: ts.SourceFile, host: ReflectionHost, factory: ts.NodeFactory, importTracker: ImportedSymbolsTracker, importManager: ImportManager, classDecorator: Decorator, isCore: boolean) => ts.PropertyDeclaration;
/**
* Creates an import and access for a given Angular core import while
* ensuring the decorator symbol access can be traced back to an Angular core
* import in order to make the synthetic decorator compatible with the JIT
* decorator downlevel transform.
*/
export declare function createSyntheticAngularCoreDecoratorAccess(factory: ts.NodeFactory, importManager: ImportManager, ngClassDecorator: Decorator, sourceFile: ts.SourceFile, decoratorName: string): ts.PropertyAccessExpression;
/** Casts the given expression as `any`. */
export declare function castAsAny(factory: ts.NodeFactory, expr: ts.Expression): ts.Expression;
+9
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.dev/license
*/
import ts from 'typescript';
export declare function aliasTransformFactory(exportStatements: Map<string, Map<string, [string, string]>>): ts.TransformerFactory<ts.SourceFile>;
+225
View File
@@ -0,0 +1,225 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { ConstantPool, Expression, Statement, Type } from '@angular/compiler';
import ts from 'typescript';
import { Reexport, ReferenceEmitter } from '../../imports';
import { SemanticSymbol } from '../../incremental/semantic_graph';
import { IndexingContext } from '../../indexer';
import { ClassDeclaration, Decorator, ReflectionHost } from '../../reflection';
import { ImportManager } from '../../translator';
import { TypeCheckContext } from '../../typecheck/api';
import { ExtendedTemplateChecker } from '../../typecheck/extended/api';
import { TemplateSemanticsChecker } from '../../typecheck/template_semantics/api/api';
import { Xi18nContext } from '../../xi18n';
/**
* Specifies the compilation mode that is used for the compilation.
*/
export declare enum CompilationMode {
/**
* Generates fully AOT compiled code using Ivy instructions.
*/
FULL = 0,
/**
* Generates code using a stable, but intermediate format suitable to be published to NPM.
*/
PARTIAL = 1,
/**
* Generates code based on each individual source file without using its
* dependencies (suitable for local dev edit/refresh workflow).
*/
LOCAL = 2
}
export declare enum HandlerPrecedence {
/**
* Handler with PRIMARY precedence cannot overlap - there can only be one on a given class.
*
* If more than one PRIMARY handler matches a class, an error is produced.
*/
PRIMARY = 0,
/**
* Handlers with SHARED precedence can match any class, possibly in addition to a single PRIMARY
* handler.
*
* It is not an error for a class to have any number of SHARED handlers.
*/
SHARED = 1,
/**
* Handlers with WEAK precedence that match a class are ignored if any handlers with stronger
* precedence match a class.
*/
WEAK = 2
}
/**
* Provides the interface between a decorator compiler from @angular/compiler and the Typescript
* compiler/transform.
*
* The decorator compilers in @angular/compiler do not depend on Typescript. The handler is
* responsible for extracting the information required to perform compilation from the decorators
* and Typescript source, invoking the decorator compiler, and returning the result.
*
* @param `D` The type of decorator metadata produced by `detect`.
* @param `A` The type of analysis metadata produced by `analyze`.
* @param `R` The type of resolution metadata produced by `resolve`.
*/
export interface DecoratorHandler<D, A, S extends SemanticSymbol | null, R> {
readonly name: string;
/**
* The precedence of a handler controls how it interacts with other handlers that match the same
* class.
*
* See the descriptions on `HandlerPrecedence` for an explanation of the behaviors involved.
*/
readonly precedence: HandlerPrecedence;
/**
* Scan a set of reflected decorators and determine if this handler is responsible for compilation
* of one of them.
*/
detect(node: ClassDeclaration, decorators: Decorator[] | null): DetectResult<D> | undefined;
/**
* Asynchronously perform pre-analysis on the decorator/class combination.
*
* `preanalyze` is optional and is not guaranteed to be called through all compilation flows. It
* will only be called if asynchronicity is supported in the CompilerHost.
*/
preanalyze?(node: ClassDeclaration, metadata: Readonly<D>): Promise<void> | undefined;
/**
* Perform analysis on the decorator/class combination, extracting information from the class
* required for compilation.
*
* Returns analyzed metadata if successful, or an array of diagnostic messages if the analysis
* fails or the decorator isn't valid.
*
* Analysis should always be a "pure" operation, with no side effects. This is because the
* detect/analysis steps might be skipped for files which have not changed during incremental
* builds. Any side effects required for compilation (e.g. registration of metadata) should happen
* in the `register` phase, which is guaranteed to run even for incremental builds.
*/
analyze(node: ClassDeclaration, metadata: Readonly<D>): AnalysisOutput<A>;
/**
* React to a change in a resource file by updating the `analysis` or `resolution`, under the
* assumption that nothing in the TypeScript code has changed.
*/
updateResources?(node: ClassDeclaration, analysis: A, resolution: R): void;
/**
* Produces a `SemanticSymbol` that represents the class, which is registered into the semantic
* dependency graph. The symbol is used in incremental compilations to let the compiler determine
* how a change to the class affects prior emit results. See the `incremental` target's README for
* details on how this works.
*
* The symbol is passed in to `resolve`, where it can be extended with references into other parts
* of the compilation as needed.
*
* Only primary handlers are allowed to have symbols; handlers with `precedence` other than
* `HandlerPrecedence.PRIMARY` must return a `null` symbol.
*/
symbol(node: ClassDeclaration, analysis: Readonly<A>): S;
/**
* Post-process the analysis of a decorator/class combination and record any necessary information
* in the larger compilation.
*
* Registration always occurs for a given decorator/class, regardless of whether analysis was
* performed directly or whether the analysis results were reused from the previous program.
*/
register?(node: ClassDeclaration, analysis: A): void;
/**
* Registers information about the decorator for the indexing phase in a
* `IndexingContext`, which stores information about components discovered in the
* program.
*/
index?(context: IndexingContext, node: ClassDeclaration, analysis: Readonly<A>, resolution: Readonly<R>): void;
/**
* Perform resolution on the given decorator along with the result of analysis.
*
* The resolution phase happens after the entire `ts.Program` has been analyzed, and gives the
* `DecoratorHandler` a chance to leverage information from the whole compilation unit to enhance
* the `analysis` before the emit phase.
*/
resolve?(node: ClassDeclaration, analysis: Readonly<A>, symbol: S): ResolveResult<R>;
/**
* Extract i18n messages into the `Xi18nContext`, which is useful for generating various formats
* of message file outputs.
*/
xi18n?(bundle: Xi18nContext, node: ClassDeclaration, analysis: Readonly<A>): void;
typeCheck?(ctx: TypeCheckContext, node: ClassDeclaration, analysis: Readonly<A>, resolution: Readonly<R>): void;
extendedTemplateCheck?(component: ts.ClassDeclaration, extendedTemplateChecker: ExtendedTemplateChecker): ts.Diagnostic[];
templateSemanticsCheck?(component: ts.ClassDeclaration, templateSemanticsChecker: TemplateSemanticsChecker): ts.Diagnostic[];
/**
* Generate a description of the field which should be added to the class, including any
* initialization code to be generated.
*
* If the compilation mode is configured as other than full but an implementation of the
* corresponding method is not provided, then this method is called as a fallback.
*/
compileFull(node: ClassDeclaration, analysis: Readonly<A>, resolution: Readonly<R>, constantPool: ConstantPool): CompileResult | CompileResult[];
/**
* Generates code for the decorator using a stable, but intermediate format suitable to be
* published to NPM. This code is meant to be processed by the linker to achieve the final AOT
* compiled code.
*
* If present, this method is used if the compilation mode is configured as partial, otherwise
* `compileFull` is.
*/
compilePartial?(node: ClassDeclaration, analysis: Readonly<A>, resolution: Readonly<R>): CompileResult | CompileResult[];
/**
* Generates the function that will update a class' metadata at runtime during HMR.
*/
compileHmrUpdateDeclaration?(node: ClassDeclaration, analysis: Readonly<A>, resolution: Readonly<R>): ts.FunctionDeclaration | null;
/**
* Generates code based on each individual source file without using its
* dependencies (suitable for local dev edit/refresh workflow)
*/
compileLocal(node: ClassDeclaration, analysis: Readonly<A>, resolution: Readonly<Partial<R>>, constantPool: ConstantPool): CompileResult | CompileResult[];
}
/**
* The output of detecting a trait for a declaration as the result of the first phase of the
* compilation pipeline.
*/
export interface DetectResult<M> {
/**
* The node that triggered the match, which is typically a decorator.
*/
trigger: ts.Node | null;
/**
* Refers to the decorator that was recognized for this detection, if any. This can be a concrete
* decorator that is actually present in a file, or a synthetic decorator as inserted
* programmatically.
*/
decorator: Decorator | null;
/**
* An arbitrary object to carry over from the detection phase into the analysis phase.
*/
metadata: Readonly<M>;
}
/**
* The output of an analysis operation, consisting of possibly an arbitrary analysis object (used as
* the input to code generation) and potentially diagnostics if there were errors uncovered during
* analysis.
*/
export interface AnalysisOutput<A> {
analysis?: Readonly<A>;
diagnostics?: ts.Diagnostic[];
}
/**
* A description of the static field to add to a class, including an initialization expression
* and a type for the .d.ts file.
*/
export interface CompileResult {
name: string;
initializer: Expression | null;
statements: Statement[];
type: Type;
deferrableImports: Set<ts.ImportDeclaration> | null;
}
export interface ResolveResult<R> {
reexports?: Reexport[];
diagnostics?: ts.Diagnostic[];
data?: Readonly<R>;
}
export interface DtsTransform {
transformClass?(clazz: ts.ClassDeclaration, elements: ReadonlyArray<ts.ClassElement>, reflector: ReflectionHost, refEmitter: ReferenceEmitter, imports: ImportManager): ts.ClassDeclaration;
}
+122
View File
@@ -0,0 +1,122 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { ConstantPool } from '@angular/compiler';
import ts from 'typescript';
import { SourceFileTypeIdentifier } from '../../core/api';
import { IncrementalBuild } from '../../incremental/api';
import { SemanticDepGraphUpdater, SemanticSymbol } from '../../incremental/semantic_graph';
import { IndexingContext } from '../../indexer';
import { PerfRecorder } from '../../perf';
import { ClassDeclaration, DeclarationNode, Decorator, ReflectionHost } from '../../reflection';
import { ProgramTypeCheckAdapter, TypeCheckContext } from '../../typecheck/api';
import { Xi18nContext } from '../../xi18n';
import { CompilationMode, CompileResult, DecoratorHandler } from './api';
import { DtsTransformRegistry } from './declaration';
import { PendingTrait, Trait } from './trait';
/**
* Records information about a specific class that has matched traits.
*/
export interface ClassRecord {
/**
* The `ClassDeclaration` of the class which has Angular traits applied.
*/
node: ClassDeclaration;
/**
* All traits which matched on the class.
*/
traits: Trait<unknown, unknown, SemanticSymbol | null, unknown>[];
/**
* Meta-diagnostics about the class, which are usually related to whether certain combinations of
* Angular decorators are not permitted.
*/
metaDiagnostics: ts.Diagnostic[] | null;
/**
* Whether `traits` contains traits matched from `DecoratorHandler`s marked as `WEAK`.
*/
hasWeakHandlers: boolean;
/**
* Whether `traits` contains a trait from a `DecoratorHandler` matched as `PRIMARY`.
*/
hasPrimaryHandler: boolean;
}
/**
* The heart of Angular compilation.
*
* The `TraitCompiler` is responsible for processing all classes in the program. Any time a
* `DecoratorHandler` matches a class, a "trait" is created to represent that Angular aspect of the
* class (such as the class having a component definition).
*
* The `TraitCompiler` transitions each trait through the various phases of compilation, culminating
* in the production of `CompileResult`s instructing the compiler to apply various mutations to the
* class (like adding fields or type declarations).
*/
export declare class TraitCompiler implements ProgramTypeCheckAdapter {
private handlers;
private reflector;
private perf;
private incrementalBuild;
private compileNonExportedClasses;
private compilationMode;
private dtsTransforms;
private semanticDepGraphUpdater;
private sourceFileTypeIdentifier;
private emitDeclarationOnly;
/**
* Maps class declarations to their `ClassRecord`, which tracks the Ivy traits being applied to
* those classes.
*/
private classes;
/**
* Maps source files to any class declaration(s) within them which have been discovered to contain
* Ivy traits.
*/
private fileToClasses;
/**
* Tracks which source files have been analyzed but did not contain any traits. This set allows
* the compiler to skip analyzing these files in an incremental rebuild.
*/
private filesWithoutTraits;
private reexportMap;
private handlersByName;
constructor(handlers: DecoratorHandler<unknown, unknown, SemanticSymbol | null, unknown>[], reflector: ReflectionHost, perf: PerfRecorder, incrementalBuild: IncrementalBuild<ClassRecord, unknown>, compileNonExportedClasses: boolean, compilationMode: CompilationMode, dtsTransforms: DtsTransformRegistry, semanticDepGraphUpdater: SemanticDepGraphUpdater | null, sourceFileTypeIdentifier: SourceFileTypeIdentifier, emitDeclarationOnly: boolean);
analyzeSync(sf: ts.SourceFile): void;
analyzeAsync(sf: ts.SourceFile): Promise<void> | undefined;
private analyze;
recordFor(clazz: ClassDeclaration): ClassRecord | null;
getAnalyzedRecords(): Map<ts.SourceFile, ClassRecord[]>;
/**
* Import a `ClassRecord` from a previous compilation (only to be used in global compilation
* modes)
*
* Traits from the `ClassRecord` have accurate metadata, but the `handler` is from the old program
* and needs to be updated (matching is done by name). A new pending trait is created and then
* transitioned to analyzed using the previous analysis. If the trait is in the errored state,
* instead the errors are copied over.
*/
private adopt;
private scanClassForTraits;
protected detectTraits(clazz: ClassDeclaration, decorators: Decorator[] | null): PendingTrait<unknown, unknown, SemanticSymbol | null, unknown>[] | null;
private makeSymbolForTrait;
private analyzeClass;
private analyzeTrait;
resolve(): void;
/**
* Generate type-checking code into the `TypeCheckContext` for any components within the given
* `ts.SourceFile`.
*/
typeCheck(sf: ts.SourceFile, ctx: TypeCheckContext): void;
runAdditionalChecks(sf: ts.SourceFile, check: (clazz: ts.ClassDeclaration, handler: DecoratorHandler<unknown, unknown, SemanticSymbol | null, unknown>) => ts.Diagnostic[] | null): ts.Diagnostic[];
index(ctx: IndexingContext): void;
xi18n(bundle: Xi18nContext): void;
updateResources(clazz: DeclarationNode): void;
compile(clazz: DeclarationNode, constantPool: ConstantPool): CompileResult[] | null;
compileHmrUpdateCallback(clazz: DeclarationNode): ts.FunctionDeclaration | null;
decoratorsFor(node: ts.Declaration): ts.Decorator[];
get diagnostics(): ReadonlyArray<ts.Diagnostic>;
get exportStatements(): Map<string, Map<string, [string, string]>>;
}
+36
View File
@@ -0,0 +1,36 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { Type } from '@angular/compiler';
import ts from 'typescript';
import { ImportRewriter, ReferenceEmitter } from '../../imports';
import { ClassDeclaration, ReflectionHost } from '../../reflection';
import { ImportManager } from '../../translator';
import { DtsTransform } from './api';
/**
* Keeps track of `DtsTransform`s per source file, so that it is known which source files need to
* have their declaration file transformed.
*/
export declare class DtsTransformRegistry {
private ivyDeclarationTransforms;
getIvyDeclarationTransform(sf: ts.SourceFile): IvyDeclarationDtsTransform;
/**
* Gets the dts transforms to be applied for the given source file, or `null` if no transform is
* necessary.
*/
getAllTransforms(sf: ts.SourceFile): DtsTransform[] | null;
}
export declare function declarationTransformFactory(transformRegistry: DtsTransformRegistry, reflector: ReflectionHost, refEmitter: ReferenceEmitter, importRewriter: ImportRewriter): ts.TransformerFactory<ts.SourceFile>;
export interface IvyDeclarationField {
name: string;
type: Type;
}
export declare class IvyDeclarationDtsTransform implements DtsTransform {
private declarationFields;
addFields(decl: ClassDeclaration, fields: IvyDeclarationField[]): void;
transformClass(clazz: ts.ClassDeclaration, members: ReadonlyArray<ts.ClassElement>, reflector: ReflectionHost, refEmitter: ReferenceEmitter, imports: ImportManager): ts.ClassDeclaration;
}
@@ -0,0 +1,74 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import ts from 'typescript';
/**
*
* This transformer adds a debugName property to the config object of signal functions like
* signal, computed, effect, etc.
*
* The debugName property is added conditionally based on the value of ngDevMode. This is done
* to avoid adding the debugName property in production builds.
*
* Ex:
* ```ts
* import {signal} from '@angular/core';
* const mySignal = signal('Hello World');
* ```
*
* is transformed to:
* ```ts
* import {signal} from '@angular/core';
* const mySignal = signal('Hello World', ...(ngDevMode ? [{ debugName: "mySignal" }] : []));
* ```
*
* The transformer supports the following cases:
*
* # Variable declaration
* ```ts
* const mySignal = signal('Hello World');
* ```
*
* becomes
* ```
* const mySignal = signal('Hello World', ...(ngDevMode ? [{ debugName: "mySignal" }] : []));
* ```
*
* # Property assignment
* ```ts
* class MyClass {
* mySignal: Signal<string>;
* constructor() {
* this.mySignal = signal('Hello World');
* }
* }
* ```
* becomes
* ```ts
* class MyClass {
* mySignal: Signal<string>;
* constructor() {
* this.mySignal = signal(...(ngDevMode ? ['Hello World', { debugName: "mySignal" }] : ['Hello World']));
* }
* }
* ```
*
* # Property declaration
* ```ts
* class MyClass {
* mySignal = signal('Hello World');
* }
* ```
* becomes
* ```ts
* class MyClass {
* mySignal = signal(...(ngDevMode ? ['Hello World', { debugName: "mySignal" }] : ['Hello World']));
* }
* ```
*
*/
export declare function signalMetadataTransform(program: ts.Program): ts.TransformerFactory<ts.SourceFile>;
+151
View File
@@ -0,0 +1,151 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import ts from 'typescript';
import { SemanticSymbol } from '../../incremental/semantic_graph';
import { DecoratorHandler, DetectResult } from './api';
export declare enum TraitState {
/**
* Pending traits are freshly created and have never been analyzed.
*/
Pending = 0,
/**
* Analyzed traits have successfully been analyzed, but are pending resolution.
*/
Analyzed = 1,
/**
* Resolved traits have successfully been analyzed and resolved and are ready for compilation.
*/
Resolved = 2,
/**
* Skipped traits are no longer considered for compilation.
*/
Skipped = 3
}
/**
* An Ivy aspect added to a class (for example, the compilation of a component definition).
*
* Traits are created when a `DecoratorHandler` matches a class. Each trait begins in a pending
* state and undergoes transitions as compilation proceeds through the various steps.
*
* In practice, traits are instances of the private class `TraitImpl` declared below. Through the
* various interfaces included in this union type, the legal API of a trait in any given state is
* represented in the type system. This includes any possible transitions from one type to the next.
*
* This not only simplifies the implementation, but ensures traits are monomorphic objects as
* they're all just "views" in the type system of the same object (which never changes shape).
*/
export type Trait<D, A, S extends SemanticSymbol | null, R> = PendingTrait<D, A, S, R> | SkippedTrait<D, A, S, R> | AnalyzedTrait<D, A, S, R> | ResolvedTrait<D, A, S, R>;
/**
* The value side of `Trait` exposes a helper to create a `Trait` in a pending state (by delegating
* to `TraitImpl`).
*/
export declare const Trait: {
pending: <D, A, S extends SemanticSymbol | null, R>(handler: DecoratorHandler<D, A, S, R>, detected: DetectResult<D>) => PendingTrait<D, A, S, R>;
};
/**
* The part of the `Trait` interface that's common to all trait states.
*/
export interface TraitBase<D, A, S extends SemanticSymbol | null, R> {
/**
* Current state of the trait.
*
* This will be narrowed in the interfaces for each specific state.
*/
state: TraitState;
/**
* The `DecoratorHandler` which matched on the class to create this trait.
*/
handler: DecoratorHandler<D, A, S, R>;
/**
* The detection result (of `handler.detect`) which indicated that this trait applied to the
* class.
*
* This is mainly used to cache the detection between pre-analysis and analysis.
*/
detected: DetectResult<D>;
}
/**
* A trait in the pending state.
*
* Pending traits have yet to be analyzed in any way.
*/
export interface PendingTrait<D, A, S extends SemanticSymbol | null, R> extends TraitBase<D, A, S, R> {
state: TraitState.Pending;
/**
* This pending trait has been successfully analyzed, and should transition to the "analyzed"
* state.
*/
toAnalyzed(analysis: A | null, diagnostics: ts.Diagnostic[] | null, symbol: S): AnalyzedTrait<D, A, S, R>;
/**
* During analysis it was determined that this trait is not eligible for compilation after all,
* and should be transitioned to the "skipped" state.
*/
toSkipped(): SkippedTrait<D, A, S, R>;
}
/**
* A trait in the "skipped" state.
*
* Skipped traits aren't considered for compilation.
*
* This is a terminal state.
*/
export interface SkippedTrait<D, A, S extends SemanticSymbol | null, R> extends TraitBase<D, A, S, R> {
state: TraitState.Skipped;
}
/**
* A trait in the "analyzed" state.
*
* Analyzed traits have analysis results available, and are eligible for resolution.
*/
export interface AnalyzedTrait<D, A, S extends SemanticSymbol | null, R> extends TraitBase<D, A, S, R> {
state: TraitState.Analyzed;
symbol: S;
/**
* Analysis results of the given trait (if able to be produced), or `null` if analysis failed
* completely.
*/
analysis: Readonly<A> | null;
/**
* Any diagnostics that resulted from analysis, or `null` if none.
*/
analysisDiagnostics: ts.Diagnostic[] | null;
/**
* This analyzed trait has been successfully resolved, and should be transitioned to the
* "resolved" state.
*/
toResolved(resolution: R | null, diagnostics: ts.Diagnostic[] | null): ResolvedTrait<D, A, S, R>;
}
/**
* A trait in the "resolved" state.
*
* Resolved traits have been successfully analyzed and resolved, contain no errors, and are ready
* for the compilation phase.
*
* This is a terminal state.
*/
export interface ResolvedTrait<D, A, S extends SemanticSymbol | null, R> extends TraitBase<D, A, S, R> {
state: TraitState.Resolved;
symbol: S;
/**
* Resolved traits must have produced valid analysis results.
*/
analysis: Readonly<A>;
/**
* Analysis may have still resulted in diagnostics.
*/
analysisDiagnostics: ts.Diagnostic[] | null;
/**
* Diagnostics resulting from resolution are tracked separately from
*/
resolveDiagnostics: ts.Diagnostic[] | null;
/**
* The results returned by a successful resolution of the given class/`DecoratorHandler`
* combination.
*/
resolution: Readonly<R> | null;
}
+13
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.dev/license
*/
import ts from 'typescript';
import { DefaultImportTracker, ImportRewriter, LocalCompilationExtraImportsTracker } from '../../imports';
import { PerfRecorder } from '../../perf';
import { ReflectionHost } from '../../reflection';
import { TraitCompiler } from './compilation';
export declare function ivyTransformFactory(compilation: TraitCompiler, reflector: ReflectionHost, importRewriter: ImportRewriter, defaultImportTracker: DefaultImportTracker, localCompilationExtraImportsTracker: LocalCompilationExtraImportsTracker | null, perf: PerfRecorder, isCore: boolean, isClosureCompilerEnabled: boolean, emitDeclarationOnly: boolean): ts.TransformerFactory<ts.SourceFile>;