@angular/compiler-cli
Version:
Angular - the compiler CLI for Node.js
1,330 lines (1,317 loc) • 562 kB
JavaScript
import {createRequire as __cjsCompatRequire} from 'module';
const require = __cjsCompatRequire(import.meta.url);
import {
AmbientImport,
ClassMemberAccessLevel,
ClassMemberKind,
CompletionKind,
DOC_PAGE_BASE_URL,
DynamicValue,
EnumValue,
Environment,
ErrorCode,
ExpressionIdentifier,
FatalDiagnosticError,
ImportFlags,
ImportManager,
ImportedSymbolsTracker,
MetaKind,
OptimizeFor,
PotentialImportKind,
PotentialImportMode,
Reference,
ReferenceEmitEnvironment,
ReferenceEmitKind,
RegistryDomSchemaChecker,
SymbolBuilder,
SymbolKind,
SyntheticValue,
TcbInliningRequirement,
TypeParameterEmitter,
TypeScriptReflectionHost,
assertSuccessfulReferenceEmit,
attachDefaultImportDeclaration,
classMemberAccessLevelToString,
describeResolvedType,
ensureTypeCheckFilePreparationImports,
entityNameToValue,
extractDirectiveTypeCheckMeta,
filterToMembersWithDecorator,
findAllMatchingNodes,
findFirstMatchingNode,
findTypeCheckBlock,
flattenInheritedDirectiveMetadata,
generateInlineTypeCtor,
generateTcbTypeParameters,
getDefaultImportDeclaration,
getProjectRelativePath,
getSourceFile,
getSourceFileOrNull,
getSourceMapping,
getTokenAtPosition,
getTypeCheckId,
hasInjectableFields,
identifierOfNode,
isAliasImportDeclaration,
isDirectiveDeclaration,
isDtsPath,
isFromDtsFile,
isHostDirectiveMetaForGlobalMode,
isNamedClassDeclaration,
isNonDeclarationTsPath,
isSymbolAliasOf,
isSymbolWithValueDeclaration,
loadIsReferencedAliasDeclarationPatch,
makeDiagnostic,
makeDiagnosticChain,
makeRelatedInformation,
makeTemplateDiagnostic,
ngErrorCode,
nodeNameForError,
presetImportManagerForceNamespaceImports,
reflectClassMember,
reflectObjectLiteral,
requiresInlineTypeCheckBlock,
requiresInlineTypeCtor,
tempPrint,
toUnredirectedSourceFile,
traceDynamicValue,
translateExpression,
translateStatement,
translateType,
typeNodeToValueExpr
} from "./chunk-QY6RCOQ6.js";
import {
absoluteFrom,
absoluteFromSourceFile,
getSourceFileOrError,
relative
} from "./chunk-UTWH365F.js";
// packages/compiler-cli/src/ngtsc/transform/jit/src/downlevel_decorators_transform.js
import ts from "typescript";
function isAngularDecorator(decorator, isCore) {
return isCore || decorator.import !== null && decorator.import.from === "@angular/core";
}
var DECORATOR_INVOCATION_JSDOC_TYPE = "!Array<{type: !Function, args: (undefined|!Array<?>)}>";
function extractMetadataFromSingleDecorator(decorator, diagnostics) {
const metadataProperties = [];
const expr = decorator.expression;
switch (expr.kind) {
case ts.SyntaxKind.Identifier:
metadataProperties.push(ts.factory.createPropertyAssignment("type", expr));
break;
case ts.SyntaxKind.CallExpression:
const call = expr;
metadataProperties.push(ts.factory.createPropertyAssignment("type", call.expression));
if (call.arguments.length) {
const args = [];
for (const arg of call.arguments) {
args.push(arg);
}
const argsArrayLiteral = ts.factory.createArrayLiteralExpression(ts.factory.createNodeArray(args, true));
metadataProperties.push(ts.factory.createPropertyAssignment("args", argsArrayLiteral));
}
break;
default:
diagnostics.push({
file: decorator.getSourceFile(),
start: decorator.getStart(),
length: decorator.getEnd() - decorator.getStart(),
messageText: `${ts.SyntaxKind[decorator.kind]} not implemented in gathering decorator metadata.`,
category: ts.DiagnosticCategory.Error,
code: 0
});
break;
}
return ts.factory.createObjectLiteralExpression(metadataProperties);
}
function createCtorParametersClassProperty(diagnostics, entityNameToExpression, ctorParameters, isClosureCompilerEnabled) {
const params = [];
for (const ctorParam of ctorParameters) {
if (!ctorParam.type && ctorParam.decorators.length === 0) {
params.push(ts.factory.createNull());
continue;
}
const paramType = ctorParam.type ? typeReferenceToExpression(entityNameToExpression, ctorParam.type) : void 0;
const members = [
ts.factory.createPropertyAssignment("type", paramType || ts.factory.createIdentifier("undefined"))
];
const decorators = [];
for (const deco of ctorParam.decorators) {
decorators.push(extractMetadataFromSingleDecorator(deco, diagnostics));
}
if (decorators.length) {
members.push(ts.factory.createPropertyAssignment("decorators", ts.factory.createArrayLiteralExpression(decorators)));
}
params.push(ts.factory.createObjectLiteralExpression(members));
}
const initializer = ts.factory.createArrowFunction(void 0, void 0, [], void 0, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createArrayLiteralExpression(params, true));
const ctorProp = ts.factory.createPropertyDeclaration([ts.factory.createToken(ts.SyntaxKind.StaticKeyword)], "ctorParameters", void 0, void 0, initializer);
if (isClosureCompilerEnabled) {
ts.setSyntheticLeadingComments(ctorProp, [
{
kind: ts.SyntaxKind.MultiLineCommentTrivia,
text: [
`*`,
` * @type {function(): !Array<(null|{`,
` * type: ?,`,
` * decorators: (undefined|${DECORATOR_INVOCATION_JSDOC_TYPE}),`,
` * })>}`,
` * @nocollapse`,
` `
].join("\n"),
pos: -1,
end: -1,
hasTrailingNewLine: true
}
]);
}
return ctorProp;
}
function typeReferenceToExpression(entityNameToExpression, node) {
let kind = node.kind;
if (ts.isLiteralTypeNode(node)) {
kind = node.literal.kind;
}
switch (kind) {
case ts.SyntaxKind.FunctionType:
case ts.SyntaxKind.ConstructorType:
return ts.factory.createIdentifier("Function");
case ts.SyntaxKind.ArrayType:
case ts.SyntaxKind.TupleType:
return ts.factory.createIdentifier("Array");
case ts.SyntaxKind.TypePredicate:
case ts.SyntaxKind.TrueKeyword:
case ts.SyntaxKind.FalseKeyword:
case ts.SyntaxKind.BooleanKeyword:
return ts.factory.createIdentifier("Boolean");
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.StringKeyword:
return ts.factory.createIdentifier("String");
case ts.SyntaxKind.ObjectKeyword:
return ts.factory.createIdentifier("Object");
case ts.SyntaxKind.NumberKeyword:
case ts.SyntaxKind.NumericLiteral:
return ts.factory.createIdentifier("Number");
case ts.SyntaxKind.TypeReference:
const typeRef = node;
return entityNameToExpression(typeRef.typeName);
case ts.SyntaxKind.UnionType:
const childTypeNodes = node.types.filter((t) => !(ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword));
return childTypeNodes.length === 1 ? typeReferenceToExpression(entityNameToExpression, childTypeNodes[0]) : void 0;
default:
return void 0;
}
}
function symbolIsRuntimeValue(typeChecker, symbol) {
if (symbol.flags & ts.SymbolFlags.Alias) {
symbol = typeChecker.getAliasedSymbol(symbol);
}
return (symbol.flags & ts.SymbolFlags.Value & ts.SymbolFlags.ConstEnumExcludes) !== 0;
}
function getDownlevelDecoratorsTransform(typeChecker, host, diagnostics, isCore, isClosureCompilerEnabled, shouldTransformClass) {
function addJSDocTypeAnnotation(node, jsdocType) {
if (!isClosureCompilerEnabled) {
return;
}
ts.setSyntheticLeadingComments(node, [
{
kind: ts.SyntaxKind.MultiLineCommentTrivia,
text: `* @type {${jsdocType}} `,
pos: -1,
end: -1,
hasTrailingNewLine: true
}
]);
}
function createPropDecoratorsClassProperty(diagnostics2, properties) {
const entries = [];
for (const [name, decorators] of properties.entries()) {
entries.push(ts.factory.createPropertyAssignment(name, ts.factory.createArrayLiteralExpression(decorators.map((deco) => extractMetadataFromSingleDecorator(deco, diagnostics2)))));
}
const initializer = ts.factory.createObjectLiteralExpression(entries, true);
const prop = ts.factory.createPropertyDeclaration([ts.factory.createToken(ts.SyntaxKind.StaticKeyword)], "propDecorators", void 0, void 0, initializer);
addJSDocTypeAnnotation(prop, `!Object<string, ${DECORATOR_INVOCATION_JSDOC_TYPE}>`);
return prop;
}
return (context) => {
const referencedParameterTypes = loadIsReferencedAliasDeclarationPatch(context);
function entityNameToExpression(name) {
const symbol = typeChecker.getSymbolAtLocation(name);
if (!symbol || !symbolIsRuntimeValue(typeChecker, symbol) || !symbol.declarations || symbol.declarations.length === 0) {
return void 0;
}
if (ts.isQualifiedName(name)) {
const containerExpr = entityNameToExpression(name.left);
if (containerExpr === void 0) {
return void 0;
}
return ts.factory.createPropertyAccessExpression(containerExpr, name.right);
}
const decl = symbol.declarations[0];
if (isAliasImportDeclaration(decl)) {
referencedParameterTypes?.add(decl);
if (decl.name !== void 0) {
return ts.setOriginalNode(ts.factory.createIdentifier(decl.name.text), decl.name);
}
}
return ts.setOriginalNode(ts.factory.createIdentifier(name.text), name);
}
function transformClassElement(element) {
element = ts.visitEachChild(element, decoratorDownlevelVisitor, context);
const decoratorsToKeep = [];
const toLower = [];
const decorators = host.getDecoratorsOfDeclaration(element) || [];
for (const decorator of decorators) {
const decoratorNode = decorator.node;
if (!isAngularDecorator(decorator, isCore)) {
decoratorsToKeep.push(decoratorNode);
continue;
}
toLower.push(decoratorNode);
}
if (!toLower.length)
return [void 0, element, []];
if (!element.name || !ts.isIdentifier(element.name)) {
diagnostics.push({
file: element.getSourceFile(),
start: element.getStart(),
length: element.getEnd() - element.getStart(),
messageText: `Cannot process decorators for class element with non-analyzable name.`,
category: ts.DiagnosticCategory.Error,
code: 0
});
return [void 0, element, []];
}
const elementModifiers = ts.canHaveModifiers(element) ? ts.getModifiers(element) : void 0;
let modifiers;
if (decoratorsToKeep.length || elementModifiers?.length) {
modifiers = ts.setTextRange(ts.factory.createNodeArray([...decoratorsToKeep, ...elementModifiers || []]), element.modifiers);
}
return [element.name.text, cloneClassElementWithModifiers(element, modifiers), toLower];
}
function transformConstructor(ctor) {
ctor = ts.visitEachChild(ctor, decoratorDownlevelVisitor, context);
const newParameters = [];
const oldParameters = ctor.parameters;
const parametersInfo = [];
for (const param of oldParameters) {
const decoratorsToKeep = [];
const paramInfo = { decorators: [], type: null };
const decorators = host.getDecoratorsOfDeclaration(param) || [];
for (const decorator of decorators) {
const decoratorNode = decorator.node;
if (!isAngularDecorator(decorator, isCore)) {
decoratorsToKeep.push(decoratorNode);
continue;
}
paramInfo.decorators.push(decoratorNode);
}
if (param.type) {
paramInfo.type = param.type;
}
parametersInfo.push(paramInfo);
let modifiers;
const paramModifiers = ts.getModifiers(param);
if (decoratorsToKeep.length || paramModifiers?.length) {
modifiers = [...decoratorsToKeep, ...paramModifiers || []];
}
const newParam = ts.factory.updateParameterDeclaration(param, modifiers, param.dotDotDotToken, param.name, param.questionToken, param.type, param.initializer);
newParameters.push(newParam);
}
const updated = ts.factory.updateConstructorDeclaration(ctor, ts.getModifiers(ctor), newParameters, ctor.body);
return [updated, parametersInfo];
}
function transformClassDeclaration(classDecl) {
const newMembers = [];
const decoratedProperties = /* @__PURE__ */ new Map();
let classParameters = null;
for (const member of classDecl.members) {
switch (member.kind) {
case ts.SyntaxKind.PropertyDeclaration:
case ts.SyntaxKind.GetAccessor:
case ts.SyntaxKind.SetAccessor:
case ts.SyntaxKind.MethodDeclaration: {
const [name, newMember, decorators] = transformClassElement(member);
newMembers.push(newMember);
if (name)
decoratedProperties.set(name, decorators);
continue;
}
case ts.SyntaxKind.Constructor: {
const ctor = member;
if (!ctor.body)
break;
const [newMember, parametersInfo] = transformConstructor(member);
classParameters = parametersInfo;
newMembers.push(newMember);
continue;
}
default:
break;
}
newMembers.push(ts.visitEachChild(member, decoratorDownlevelVisitor, context));
}
const possibleAngularDecorators = host.getDecoratorsOfDeclaration(classDecl) || [];
const hasAngularDecorator = possibleAngularDecorators.some((d) => isAngularDecorator(d, isCore));
if (classParameters) {
if (hasAngularDecorator || classParameters.some((p) => !!p.decorators.length)) {
newMembers.push(createCtorParametersClassProperty(diagnostics, entityNameToExpression, classParameters, isClosureCompilerEnabled));
}
}
if (decoratedProperties.size) {
newMembers.push(createPropDecoratorsClassProperty(diagnostics, decoratedProperties));
}
const members = ts.setTextRange(ts.factory.createNodeArray(newMembers, classDecl.members.hasTrailingComma), classDecl.members);
return ts.factory.updateClassDeclaration(classDecl, classDecl.modifiers, classDecl.name, classDecl.typeParameters, classDecl.heritageClauses, members);
}
function decoratorDownlevelVisitor(node) {
if (ts.isClassDeclaration(node) && (shouldTransformClass === void 0 || shouldTransformClass(node))) {
return transformClassDeclaration(node);
}
return ts.visitEachChild(node, decoratorDownlevelVisitor, context);
}
return (sf) => {
return ts.visitEachChild(sf, decoratorDownlevelVisitor, context);
};
};
}
function cloneClassElementWithModifiers(node, modifiers) {
let clone;
if (ts.isMethodDeclaration(node)) {
clone = ts.factory.createMethodDeclaration(modifiers, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body);
} else if (ts.isPropertyDeclaration(node)) {
clone = ts.factory.createPropertyDeclaration(modifiers, node.name, node.questionToken, node.type, node.initializer);
} else if (ts.isGetAccessor(node)) {
clone = ts.factory.createGetAccessorDeclaration(modifiers, node.name, node.parameters, node.type, node.body);
} else if (ts.isSetAccessor(node)) {
clone = ts.factory.createSetAccessorDeclaration(modifiers, node.name, node.parameters, node.body);
} else {
throw new Error(`Unsupported decorated member with kind ${ts.SyntaxKind[node.kind]}`);
}
return ts.setOriginalNode(clone, node);
}
// packages/compiler-cli/src/ngtsc/annotations/common/src/util.js
import { ExternalExpr, ParseLocation, ParseSourceFile, ParseSourceSpan, ReadPropExpr, WrappedNodeExpr } from "@angular/compiler";
import ts2 from "typescript";
var CORE_MODULE = "@angular/core";
function valueReferenceToExpression(valueRef) {
if (valueRef.kind === 2) {
return null;
} else if (valueRef.kind === 0) {
const expr = new WrappedNodeExpr(valueRef.expression);
if (valueRef.defaultImportStatement !== null) {
attachDefaultImportDeclaration(expr, valueRef.defaultImportStatement);
}
return expr;
} else {
let importExpr = new ExternalExpr({
moduleName: valueRef.moduleName,
name: valueRef.importedName
});
if (valueRef.nestedPath !== null) {
for (const property of valueRef.nestedPath) {
importExpr = new ReadPropExpr(importExpr, property);
}
}
return importExpr;
}
}
function toR3Reference(origin, ref, context, refEmitter) {
const emittedValueRef = refEmitter.emit(ref, context);
assertSuccessfulReferenceEmit(emittedValueRef, origin, "class");
const emittedTypeRef = refEmitter.emit(ref, context, ImportFlags.ForceNewImport | ImportFlags.AllowTypeImports);
assertSuccessfulReferenceEmit(emittedTypeRef, origin, "class");
return {
value: emittedValueRef.expression,
type: emittedTypeRef.expression
};
}
function isAngularCore(decorator) {
return decorator.import !== null && decorator.import.from === CORE_MODULE;
}
function isAngularCoreReferenceWithPotentialAliasing(reference, symbolName, isCore) {
return (reference.ownedByModuleGuess === CORE_MODULE || isCore) && reference.debugName?.replace(/\$\d+$/, "") === symbolName;
}
function findAngularDecorator(decorators, name, isCore) {
return decorators.find((decorator) => isAngularDecorator2(decorator, name, isCore));
}
function isAngularDecorator2(decorator, name, isCore) {
if (isCore) {
return decorator.name === name;
} else if (isAngularCore(decorator)) {
return decorator.import.name === name;
}
return false;
}
function getAngularDecorators(decorators, names, isCore) {
return decorators.filter((decorator) => {
const name = isCore ? decorator.name : decorator.import?.name;
if (name === void 0 || !names.includes(name)) {
return false;
}
return isCore || isAngularCore(decorator);
});
}
function unwrapExpression(node) {
while (ts2.isAsExpression(node) || ts2.isParenthesizedExpression(node)) {
node = node.expression;
}
return node;
}
function expandForwardRef(arg) {
arg = unwrapExpression(arg);
if (!ts2.isArrowFunction(arg) && !ts2.isFunctionExpression(arg)) {
return null;
}
const body = arg.body;
if (ts2.isBlock(body)) {
if (body.statements.length !== 1) {
return null;
}
const stmt = body.statements[0];
if (!ts2.isReturnStatement(stmt) || stmt.expression === void 0) {
return null;
}
return stmt.expression;
} else {
return body;
}
}
function tryUnwrapForwardRef(node, reflector) {
node = unwrapExpression(node);
if (!ts2.isCallExpression(node) || node.arguments.length !== 1) {
return null;
}
const fn = ts2.isPropertyAccessExpression(node.expression) ? node.expression.name : node.expression;
if (!ts2.isIdentifier(fn)) {
return null;
}
const expr = expandForwardRef(node.arguments[0]);
if (expr === null) {
return null;
}
const imp = reflector.getImportOfIdentifier(fn);
if (imp === null || imp.from !== "@angular/core" || imp.name !== "forwardRef") {
return null;
}
return expr;
}
function createForwardRefResolver(isCore) {
return (fn, callExpr, resolve, unresolvable) => {
if (!isAngularCoreReferenceWithPotentialAliasing(fn, "forwardRef", isCore) || callExpr.arguments.length !== 1) {
return unresolvable;
}
const expanded = expandForwardRef(callExpr.arguments[0]);
if (expanded !== null) {
return resolve(expanded);
} else {
return unresolvable;
}
};
}
function combineResolvers(resolvers) {
return (fn, callExpr, resolve, unresolvable) => {
for (const resolver of resolvers) {
const resolved = resolver(fn, callExpr, resolve, unresolvable);
if (resolved !== unresolvable) {
return resolved;
}
}
return unresolvable;
};
}
function isExpressionForwardReference(expr, context, contextSource) {
if (isWrappedTsNodeExpr(expr)) {
const node = ts2.getOriginalNode(expr.node);
return node.getSourceFile() === contextSource && context.pos < node.pos;
} else {
return false;
}
}
function isWrappedTsNodeExpr(expr) {
return expr instanceof WrappedNodeExpr;
}
function readBaseClass(node, reflector, evaluator) {
const baseExpression = reflector.getBaseClassExpression(node);
if (baseExpression !== null) {
const baseClass = evaluator.evaluate(baseExpression);
if (baseClass instanceof Reference && reflector.isClass(baseClass.node)) {
return baseClass;
} else {
return "dynamic";
}
}
return null;
}
var parensWrapperTransformerFactory = (context) => {
const visitor = (node) => {
const visited = ts2.visitEachChild(node, visitor, context);
if (ts2.isArrowFunction(visited) || ts2.isFunctionExpression(visited)) {
return ts2.factory.createParenthesizedExpression(visited);
}
return visited;
};
return (node) => ts2.visitEachChild(node, visitor, context);
};
function wrapFunctionExpressionsInParens(expression) {
return ts2.transform(expression, [parensWrapperTransformerFactory]).transformed[0];
}
function resolveProvidersRequiringFactory(rawProviders, reflector, evaluator) {
const providers = /* @__PURE__ */ new Set();
const resolvedProviders = evaluator.evaluate(rawProviders);
if (!Array.isArray(resolvedProviders)) {
return providers;
}
resolvedProviders.forEach(function processProviders(provider) {
let tokenClass = null;
if (Array.isArray(provider)) {
provider.forEach(processProviders);
} else if (provider instanceof Reference) {
tokenClass = provider;
} else if (provider instanceof Map && provider.has("useClass") && !provider.has("deps")) {
const useExisting = provider.get("useClass");
if (useExisting instanceof Reference) {
tokenClass = useExisting;
}
}
if (tokenClass !== null && !tokenClass.node.getSourceFile().isDeclarationFile && reflector.isClass(tokenClass.node)) {
const constructorParameters = reflector.getConstructorParameters(tokenClass.node);
if (constructorParameters !== null && constructorParameters.length > 0) {
providers.add(tokenClass);
}
}
});
return providers;
}
function wrapTypeReference(clazz) {
const value = new WrappedNodeExpr(clazz.name);
const type = value;
return { value, type };
}
function createSourceSpan(node) {
const sf = node.getSourceFile();
const [startOffset, endOffset] = [node.getStart(), node.getEnd()];
const { line: startLine, character: startCol } = sf.getLineAndCharacterOfPosition(startOffset);
const { line: endLine, character: endCol } = sf.getLineAndCharacterOfPosition(endOffset);
const parseSf = new ParseSourceFile(sf.getFullText(), sf.fileName);
return new ParseSourceSpan(new ParseLocation(parseSf, startOffset, startLine + 1, startCol + 1), new ParseLocation(parseSf, endOffset, endLine + 1, endCol + 1));
}
function compileResults(fac, def, metadataStmt, propName, additionalFields, deferrableImports, debugInfo = null, hmrInitializer = null) {
const statements = def.statements;
if (metadataStmt !== null) {
statements.push(metadataStmt);
}
if (debugInfo !== null) {
statements.push(debugInfo);
}
if (hmrInitializer !== null) {
statements.push(hmrInitializer);
}
const results = [
fac,
{
name: propName,
initializer: def.expression,
statements: def.statements,
type: def.type,
deferrableImports
}
];
if (additionalFields !== null) {
results.push(...additionalFields);
}
return results;
}
function toFactoryMetadata(meta, target) {
return {
name: meta.name,
type: meta.type,
typeArgumentCount: meta.typeArgumentCount,
deps: meta.deps,
target
};
}
function resolveImportedFile(moduleResolver, importedFile, expr, origin) {
if (importedFile !== "unknown") {
return importedFile;
}
if (!(expr instanceof ExternalExpr)) {
return null;
}
return moduleResolver.resolveModule(expr.value.moduleName, origin.fileName);
}
function getOriginNodeForDiagnostics(expr, container) {
const nodeSf = expr.getSourceFile();
const exprSf = container.getSourceFile();
if (nodeSf === exprSf && expr.pos >= container.pos && expr.end <= container.end) {
return expr;
} else {
return container;
}
}
function isAbstractClassDeclaration(clazz) {
return ts2.canHaveModifiers(clazz) && clazz.modifiers !== void 0 ? clazz.modifiers.some((mod) => mod.kind === ts2.SyntaxKind.AbstractKeyword) : false;
}
// packages/compiler-cli/src/ngtsc/transform/src/api.js
var CompilationMode;
(function(CompilationMode2) {
CompilationMode2[CompilationMode2["FULL"] = 0] = "FULL";
CompilationMode2[CompilationMode2["PARTIAL"] = 1] = "PARTIAL";
CompilationMode2[CompilationMode2["LOCAL"] = 2] = "LOCAL";
})(CompilationMode || (CompilationMode = {}));
var HandlerPrecedence;
(function(HandlerPrecedence2) {
HandlerPrecedence2[HandlerPrecedence2["PRIMARY"] = 0] = "PRIMARY";
HandlerPrecedence2[HandlerPrecedence2["SHARED"] = 1] = "SHARED";
HandlerPrecedence2[HandlerPrecedence2["WEAK"] = 2] = "WEAK";
})(HandlerPrecedence || (HandlerPrecedence = {}));
// packages/compiler-cli/src/ngtsc/perf/src/api.js
var PerfPhase;
(function(PerfPhase2) {
PerfPhase2[PerfPhase2["Unaccounted"] = 0] = "Unaccounted";
PerfPhase2[PerfPhase2["Setup"] = 1] = "Setup";
PerfPhase2[PerfPhase2["TypeScriptProgramCreate"] = 2] = "TypeScriptProgramCreate";
PerfPhase2[PerfPhase2["Reconciliation"] = 3] = "Reconciliation";
PerfPhase2[PerfPhase2["ResourceUpdate"] = 4] = "ResourceUpdate";
PerfPhase2[PerfPhase2["TypeScriptDiagnostics"] = 5] = "TypeScriptDiagnostics";
PerfPhase2[PerfPhase2["Analysis"] = 6] = "Analysis";
PerfPhase2[PerfPhase2["Resolve"] = 7] = "Resolve";
PerfPhase2[PerfPhase2["CycleDetection"] = 8] = "CycleDetection";
PerfPhase2[PerfPhase2["TcbGeneration"] = 9] = "TcbGeneration";
PerfPhase2[PerfPhase2["TcbUpdateProgram"] = 10] = "TcbUpdateProgram";
PerfPhase2[PerfPhase2["TypeScriptEmit"] = 11] = "TypeScriptEmit";
PerfPhase2[PerfPhase2["Compile"] = 12] = "Compile";
PerfPhase2[PerfPhase2["TtcAutocompletion"] = 13] = "TtcAutocompletion";
PerfPhase2[PerfPhase2["TtcDiagnostics"] = 14] = "TtcDiagnostics";
PerfPhase2[PerfPhase2["TtcSuggestionDiagnostics"] = 15] = "TtcSuggestionDiagnostics";
PerfPhase2[PerfPhase2["TtcSymbol"] = 16] = "TtcSymbol";
PerfPhase2[PerfPhase2["LsReferencesAndRenames"] = 17] = "LsReferencesAndRenames";
PerfPhase2[PerfPhase2["LsQuickInfo"] = 18] = "LsQuickInfo";
PerfPhase2[PerfPhase2["LsDefinition"] = 19] = "LsDefinition";
PerfPhase2[PerfPhase2["LsCompletions"] = 20] = "LsCompletions";
PerfPhase2[PerfPhase2["LsTcb"] = 21] = "LsTcb";
PerfPhase2[PerfPhase2["LsDiagnostics"] = 22] = "LsDiagnostics";
PerfPhase2[PerfPhase2["LsSuggestionDiagnostics"] = 23] = "LsSuggestionDiagnostics";
PerfPhase2[PerfPhase2["LsComponentLocations"] = 24] = "LsComponentLocations";
PerfPhase2[PerfPhase2["LsSignatureHelp"] = 25] = "LsSignatureHelp";
PerfPhase2[PerfPhase2["OutliningSpans"] = 26] = "OutliningSpans";
PerfPhase2[PerfPhase2["LsCodeFixes"] = 27] = "LsCodeFixes";
PerfPhase2[PerfPhase2["LsCodeFixesAll"] = 28] = "LsCodeFixesAll";
PerfPhase2[PerfPhase2["LSComputeApplicableRefactorings"] = 29] = "LSComputeApplicableRefactorings";
PerfPhase2[PerfPhase2["LSApplyRefactoring"] = 30] = "LSApplyRefactoring";
PerfPhase2[PerfPhase2["LSSemanticClassification"] = 31] = "LSSemanticClassification";
PerfPhase2[PerfPhase2["LAST"] = 32] = "LAST";
})(PerfPhase || (PerfPhase = {}));
var PerfEvent;
(function(PerfEvent2) {
PerfEvent2[PerfEvent2["InputDtsFile"] = 0] = "InputDtsFile";
PerfEvent2[PerfEvent2["InputTsFile"] = 1] = "InputTsFile";
PerfEvent2[PerfEvent2["AnalyzeComponent"] = 2] = "AnalyzeComponent";
PerfEvent2[PerfEvent2["AnalyzeDirective"] = 3] = "AnalyzeDirective";
PerfEvent2[PerfEvent2["AnalyzeInjectable"] = 4] = "AnalyzeInjectable";
PerfEvent2[PerfEvent2["AnalyzeNgModule"] = 5] = "AnalyzeNgModule";
PerfEvent2[PerfEvent2["AnalyzePipe"] = 6] = "AnalyzePipe";
PerfEvent2[PerfEvent2["AnalyzeService"] = 7] = "AnalyzeService";
PerfEvent2[PerfEvent2["TraitAnalyze"] = 8] = "TraitAnalyze";
PerfEvent2[PerfEvent2["TraitReuseAnalysis"] = 9] = "TraitReuseAnalysis";
PerfEvent2[PerfEvent2["SourceFilePhysicalChange"] = 10] = "SourceFilePhysicalChange";
PerfEvent2[PerfEvent2["SourceFileLogicalChange"] = 11] = "SourceFileLogicalChange";
PerfEvent2[PerfEvent2["SourceFileReuseAnalysis"] = 12] = "SourceFileReuseAnalysis";
PerfEvent2[PerfEvent2["GenerateTcb"] = 13] = "GenerateTcb";
PerfEvent2[PerfEvent2["SkipGenerateTcbNoInline"] = 14] = "SkipGenerateTcbNoInline";
PerfEvent2[PerfEvent2["ReuseTypeCheckFile"] = 15] = "ReuseTypeCheckFile";
PerfEvent2[PerfEvent2["UpdateTypeCheckProgram"] = 16] = "UpdateTypeCheckProgram";
PerfEvent2[PerfEvent2["EmitSkipSourceFile"] = 17] = "EmitSkipSourceFile";
PerfEvent2[PerfEvent2["EmitSourceFile"] = 18] = "EmitSourceFile";
PerfEvent2[PerfEvent2["LAST"] = 19] = "LAST";
})(PerfEvent || (PerfEvent = {}));
var PerfCheckpoint;
(function(PerfCheckpoint2) {
PerfCheckpoint2[PerfCheckpoint2["Initial"] = 0] = "Initial";
PerfCheckpoint2[PerfCheckpoint2["TypeScriptProgramCreate"] = 1] = "TypeScriptProgramCreate";
PerfCheckpoint2[PerfCheckpoint2["PreAnalysis"] = 2] = "PreAnalysis";
PerfCheckpoint2[PerfCheckpoint2["Analysis"] = 3] = "Analysis";
PerfCheckpoint2[PerfCheckpoint2["Resolve"] = 4] = "Resolve";
PerfCheckpoint2[PerfCheckpoint2["TtcGeneration"] = 5] = "TtcGeneration";
PerfCheckpoint2[PerfCheckpoint2["TtcUpdateProgram"] = 6] = "TtcUpdateProgram";
PerfCheckpoint2[PerfCheckpoint2["PreEmit"] = 7] = "PreEmit";
PerfCheckpoint2[PerfCheckpoint2["Emit"] = 8] = "Emit";
PerfCheckpoint2[PerfCheckpoint2["LAST"] = 9] = "LAST";
})(PerfCheckpoint || (PerfCheckpoint = {}));
// packages/compiler-cli/src/ngtsc/perf/src/noop.js
var NoopPerfRecorder = class {
eventCount() {
}
memory() {
}
phase() {
return PerfPhase.Unaccounted;
}
inPhase(phase, fn) {
return fn();
}
reset() {
}
};
var NOOP_PERF_RECORDER = new NoopPerfRecorder();
// packages/compiler-cli/src/ngtsc/perf/src/clock.js
function mark() {
return process.hrtime();
}
function timeSinceInMicros(mark2) {
const delta = process.hrtime(mark2);
return delta[0] * 1e6 + Math.floor(delta[1] / 1e3);
}
// packages/compiler-cli/src/ngtsc/perf/src/recorder.js
var ActivePerfRecorder = class _ActivePerfRecorder {
zeroTime;
counters;
phaseTime;
bytes;
currentPhase = PerfPhase.Unaccounted;
currentPhaseEntered;
/**
* Creates an `ActivePerfRecorder` with its zero point set to the current time.
*/
static zeroedToNow() {
return new _ActivePerfRecorder(mark());
}
constructor(zeroTime) {
this.zeroTime = zeroTime;
this.currentPhaseEntered = this.zeroTime;
this.counters = Array(PerfEvent.LAST).fill(0);
this.phaseTime = Array(PerfPhase.LAST).fill(0);
this.bytes = Array(PerfCheckpoint.LAST).fill(0);
this.memory(PerfCheckpoint.Initial);
}
reset() {
this.counters = Array(PerfEvent.LAST).fill(0);
this.phaseTime = Array(PerfPhase.LAST).fill(0);
this.bytes = Array(PerfCheckpoint.LAST).fill(0);
this.zeroTime = mark();
this.currentPhase = PerfPhase.Unaccounted;
this.currentPhaseEntered = this.zeroTime;
}
memory(after) {
this.bytes[after] = process.memoryUsage().heapUsed;
}
phase(phase) {
const previous = this.currentPhase;
this.phaseTime[this.currentPhase] += timeSinceInMicros(this.currentPhaseEntered);
this.currentPhase = phase;
this.currentPhaseEntered = mark();
return previous;
}
inPhase(phase, fn) {
const previousPhase = this.phase(phase);
try {
return fn();
} finally {
this.phase(previousPhase);
}
}
eventCount(counter, incrementBy = 1) {
this.counters[counter] += incrementBy;
}
/**
* Return the current performance metrics as a serializable object.
*/
finalize() {
this.phase(PerfPhase.Unaccounted);
const results = {
events: {},
phases: {},
memory: {}
};
for (let i = 0; i < this.phaseTime.length; i++) {
if (this.phaseTime[i] > 0) {
results.phases[PerfPhase[i]] = this.phaseTime[i];
}
}
for (let i = 0; i < this.phaseTime.length; i++) {
if (this.counters[i] > 0) {
results.events[PerfEvent[i]] = this.counters[i];
}
}
for (let i = 0; i < this.bytes.length; i++) {
if (this.bytes[i] > 0) {
results.memory[PerfCheckpoint[i]] = this.bytes[i];
}
}
return results;
}
};
var DelegatingPerfRecorder = class {
target;
constructor(target) {
this.target = target;
}
eventCount(counter, incrementBy) {
this.target.eventCount(counter, incrementBy);
}
phase(phase) {
return this.target.phase(phase);
}
inPhase(phase, fn) {
const previousPhase = this.target.phase(phase);
try {
return fn();
} finally {
this.target.phase(previousPhase);
}
}
memory(after) {
this.target.memory(after);
}
reset() {
this.target.reset();
}
};
// packages/compiler-cli/src/ngtsc/transform/src/alias.js
import ts3 from "typescript";
function aliasTransformFactory(exportStatements) {
return () => {
return (file) => {
if (ts3.isBundle(file) || !exportStatements.has(file.fileName)) {
return file;
}
const statements = [...file.statements];
exportStatements.get(file.fileName).forEach(([moduleName, symbolName], aliasName) => {
const stmt = ts3.factory.createExportDeclaration(
/* modifiers */
void 0,
/* isTypeOnly */
false,
/* exportClause */
ts3.factory.createNamedExports([
ts3.factory.createExportSpecifier(false, symbolName, aliasName)
]),
/* moduleSpecifier */
ts3.factory.createStringLiteral(moduleName)
);
statements.push(stmt);
});
return ts3.factory.updateSourceFile(file, statements);
};
};
}
// packages/compiler-cli/src/ngtsc/transform/src/compilation.js
import ts4 from "typescript";
// packages/compiler-cli/src/ngtsc/transform/src/trait.js
var TraitState;
(function(TraitState2) {
TraitState2[TraitState2["Pending"] = 0] = "Pending";
TraitState2[TraitState2["Analyzed"] = 1] = "Analyzed";
TraitState2[TraitState2["Resolved"] = 2] = "Resolved";
TraitState2[TraitState2["Skipped"] = 3] = "Skipped";
})(TraitState || (TraitState = {}));
var Trait = {
pending: (handler, detected) => TraitImpl.pending(handler, detected)
};
var TraitImpl = class _TraitImpl {
state = TraitState.Pending;
handler;
detected;
analysis = null;
symbol = null;
resolution = null;
analysisDiagnostics = null;
resolveDiagnostics = null;
typeCheckDiagnostics = null;
constructor(handler, detected) {
this.handler = handler;
this.detected = detected;
}
toAnalyzed(analysis, diagnostics, symbol) {
this.assertTransitionLegal(TraitState.Pending, TraitState.Analyzed);
this.analysis = analysis;
this.analysisDiagnostics = diagnostics;
this.symbol = symbol;
this.state = TraitState.Analyzed;
return this;
}
toResolved(resolution, diagnostics) {
this.assertTransitionLegal(TraitState.Analyzed, TraitState.Resolved);
if (this.analysis === null) {
throw new Error(`Cannot transition an Analyzed trait with a null analysis to Resolved`);
}
this.resolution = resolution;
this.state = TraitState.Resolved;
this.resolveDiagnostics = diagnostics;
this.typeCheckDiagnostics = null;
return this;
}
toSkipped() {
this.assertTransitionLegal(TraitState.Pending, TraitState.Skipped);
this.state = TraitState.Skipped;
return this;
}
/**
* Verifies that the trait is currently in one of the `allowedState`s.
*
* If correctly used, the `Trait` type and transition methods prevent illegal transitions from
* occurring. However, if a reference to the `TraitImpl` instance typed with the previous
* interface is retained after calling one of its transition methods, it will allow for illegal
* transitions to take place. Hence, this assertion provides a little extra runtime protection.
*/
assertTransitionLegal(allowedState, transitionTo) {
if (!(this.state === allowedState)) {
throw new Error(`Assertion failure: cannot transition from ${TraitState[this.state]} to ${TraitState[transitionTo]}.`);
}
}
/**
* Construct a new `TraitImpl` in the pending state.
*/
static pending(handler, detected) {
return new _TraitImpl(handler, detected);
}
};
// packages/compiler-cli/src/ngtsc/transform/src/compilation.js
var TraitCompiler = class {
handlers;
reflector;
perf;
incrementalBuild;
compileNonExportedClasses;
compilationMode;
dtsTransforms;
semanticDepGraphUpdater;
sourceFileTypeIdentifier;
emitDeclarationOnly;
emitIntermediateTs;
/**
* Maps class declarations to their `ClassRecord`, which tracks the Ivy traits being applied to
* those classes.
*/
classes = /* @__PURE__ */ new Map();
/**
* Maps source files to any class declaration(s) within them which have been discovered to contain
* Ivy traits.
*/
fileToClasses = /* @__PURE__ */ new Map();
/**
* 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.
*/
filesWithoutTraits = /* @__PURE__ */ new Set();
reexportMap = /* @__PURE__ */ new Map();
handlersByName = /* @__PURE__ */ new Map();
constructor(handlers, reflector, perf, incrementalBuild, compileNonExportedClasses, compilationMode, dtsTransforms, semanticDepGraphUpdater, sourceFileTypeIdentifier, emitDeclarationOnly, emitIntermediateTs) {
this.handlers = handlers;
this.reflector = reflector;
this.perf = perf;
this.incrementalBuild = incrementalBuild;
this.compileNonExportedClasses = compileNonExportedClasses;
this.compilationMode = compilationMode;
this.dtsTransforms = dtsTransforms;
this.semanticDepGraphUpdater = semanticDepGraphUpdater;
this.sourceFileTypeIdentifier = sourceFileTypeIdentifier;
this.emitDeclarationOnly = emitDeclarationOnly;
this.emitIntermediateTs = emitIntermediateTs;
for (const handler of handlers) {
this.handlersByName.set(handler.name, handler);
}
}
analyzeSync(sf) {
this.analyze(sf, false);
}
analyzeAsync(sf) {
return this.analyze(sf, true);
}
analyze(sf, preanalyze) {
if (sf.isDeclarationFile || this.sourceFileTypeIdentifier.isShim(sf) || this.sourceFileTypeIdentifier.isResource(sf)) {
return void 0;
}
const promises = [];
const priorWork = this.compilationMode !== CompilationMode.LOCAL ? this.incrementalBuild.priorAnalysisFor(sf) : null;
if (priorWork !== null) {
this.perf.eventCount(PerfEvent.SourceFileReuseAnalysis);
if (priorWork.length > 0) {
for (const priorRecord of priorWork) {
this.adopt(priorRecord);
}
this.perf.eventCount(PerfEvent.TraitReuseAnalysis, priorWork.length);
} else {
this.filesWithoutTraits.add(sf);
}
return;
}
const visit2 = (node) => {
if (this.reflector.isClass(node)) {
this.analyzeClass(node, preanalyze ? promises : null);
}
ts4.forEachChild(node, visit2);
};
visit2(sf);
if (!this.fileToClasses.has(sf)) {
this.filesWithoutTraits.add(sf);
}
if (preanalyze && promises.length > 0) {
return Promise.all(promises).then(() => void 0);
} else {
return void 0;
}
}
recordFor(clazz) {
if (this.classes.has(clazz)) {
return this.classes.get(clazz);
} else {
return null;
}
}
getAnalyzedRecords() {
const result = /* @__PURE__ */ new Map();
for (const [sf, classes] of this.fileToClasses) {
const records = [];
for (const clazz of classes) {
records.push(this.classes.get(clazz));
}
result.set(sf, records);
}
for (const sf of this.filesWithoutTraits) {
result.set(sf, []);
}
return result;
}
/**
* 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.
*/
adopt(priorRecord) {
const record = {
hasPrimaryHandler: priorRecord.hasPrimaryHandler,
hasWeakHandlers: priorRecord.hasWeakHandlers,
metaDiagnostics: priorRecord.metaDiagnostics,
node: priorRecord.node,
traits: []
};
for (const priorTrait of priorRecord.traits) {
const handler = this.handlersByName.get(priorTrait.handler.name);
let trait = Trait.pending(handler, priorTrait.detected);
if (priorTrait.state === TraitState.Analyzed || priorTrait.state === TraitState.Resolved) {
const symbol = this.makeSymbolForTrait(handler, record.node, priorTrait.analysis);
trait = trait.toAnalyzed(priorTrait.analysis, priorTrait.analysisDiagnostics, symbol);
if (trait.analysis !== null && trait.handler.register !== void 0) {
trait.handler.register(record.node, trait.analysis);
}
} else if (priorTrait.state === TraitState.Skipped) {
trait = trait.toSkipped();
}
record.traits.push(trait);
}
this.classes.set(record.node, record);
const sf = record.node.getSourceFile();
if (!this.fileToClasses.has(sf)) {
this.fileToClasses.set(sf, /* @__PURE__ */ new Set());
}
this.fileToClasses.get(sf).add(record.node);
}
scanClassForTraits(clazz) {
if (!this.compileNonExportedClasses && !this.reflector.isStaticallyExported(clazz)) {
return null;
}
const decorators = this.reflector.getDecoratorsOfDeclaration(clazz);
return this.detectTraits(clazz, decorators);
}
detectTraits(clazz, decorators) {
let record = this.recordFor(clazz);
let foundTraits = [];
const nonNgDecoratorsInLocalMode = this.compilationMode === CompilationMode.LOCAL ? new Set(decorators) : null;
for (const handler of this.handlers) {
const result = handler.detect(clazz, decorators);
if (result === void 0) {
continue;
}
if (nonNgDecoratorsInLocalMode !== null && result.decorator !== null) {
nonNgDecoratorsInLocalMode.delete(result.decorator);
}
const isPrimaryHandler = handler.precedence === HandlerPrecedence.PRIMARY;
const isWeakHandler = handler.precedence === HandlerPrecedence.WEAK;
const trait = Trait.pending(handler, result);
foundTraits.push(trait);
if (record === null) {
record = {
node: clazz,
traits: [trait],
metaDiagnostics: null,
hasPrimaryHandler: isPrimaryHandler,
hasWeakHandlers: isWeakHandler
};
this.classes.set(clazz, record);
const sf = clazz.getSourceFile();
if (!this.fileToClasses.has(sf)) {
this.fileToClasses.set(sf, /* @__PURE__ */ new Set());
}
this.fileToClasses.get(sf).add(clazz);
} else {
if (!isWeakHandler && record.hasWeakHandlers) {
record.traits = record.traits.filter((field) => field.handler.precedence !== HandlerPrecedence.WEAK);
record.hasWeakHandlers = false;
} else if (isWeakHandler && !record.hasWeakHandlers) {
continue;
}
if (isPrimaryHandler && record.hasPrimaryHandler) {
record.metaDiagnostics = [
{
category: ts4.DiagnosticCategory.Error,
code: Number("-99" + ErrorCode.DECORATOR_COLLISION),
file: getSourceFile(clazz),
start: clazz.getStart(void 0, false),
length: clazz.getWidth(),
messageText: "Two incompatible decorators on class"
}
];
record.traits = foundTraits = [];
break;
}
record.traits.push(trait);
record.hasPrimaryHandler = record.hasPrimaryHandler || isPrimaryHandler;
}
}
if (nonNgDecoratorsInLocalMode !== null && nonNgDecoratorsInLocalMode.size > 0 && record !== null && record.metaDiagnostics === null) {
const compilationModeName = this.emitDeclarationOnly ? "experimental declaration-only emission" : "local compilation";
record.metaDiagnostics = [...nonNgDecoratorsInLocalMode].map((decorator) => ({
category: ts4.DiagnosticCategory.Error,
code: Number("-99" + ErrorCode.DECORATOR_UNEXPECTED),
file: getSourceFile(clazz),
start: decorator.node.getStart(),
length: decorator.node.getWidth(),
messageText: `In ${compilationModeName} mode, Angular does not support custom decorators. Ensure all class decorators are from Angular.`
}));
record.traits = foundTraits = [];
}
return foundTraits.length > 0 ? foundTraits : null;
}
makeSymbolForTrait(handler, decl, analysis) {
if (analysis === null) {
return null;
}
const symbol = handler.symbol(decl, analysis);
if (symbol !== null && this.semanticDepGraphUpdater !== null) {
const isPrimary = handler.precedence === HandlerPrecedence.PRIMARY;
if (!isPrimary) {
throw new Error(`AssertionError: ${handler.name} returned a symbol but is not a primary handler.`);
}
this.semanticDepGraphUpdater.registerSymbol(symbol);
}
return symbol;
}
analyzeClass(clazz, preanalyzeQueue) {
const traits = this.scanClassForTraits(clazz);
if (traits === null) {
return;
}
for (const trait of traits) {
const analyze = () => this.analyzeTrait(clazz, trait);
let preanalysis = null;
if (preanalyzeQueue !== null && trait.handler.preanalyze !== void 0) {
try {
preanalysis = trait.handler.preanalyze(clazz, trait.detected.metadata) || null;
} catch (err) {
if (err instanceof FatalDiagnosticError) {
trait.toAnalyzed(null, [err.toDiagnostic()], null);
return;
} else {
throw err;
}
}
}
if (preanalysis !== null) {
preanalyzeQueue.push(preanalysis.then(analyze));
} else {
analyze();
}
}
}
analyzeTrait(clazz, trait) {
if (trait.state !== TraitState.Pending) {
throw new Error(`Attempt to analyze trait of ${clazz.name.text} in state ${TraitState[trait.state]} (expected DETECTED)`);
}
this.perf.eventCount(PerfEvent.TraitAnalyze);
let result;
try {
result = trait.handler.analyze(clazz, trait.detected.metadata);
} catch (err) {
if (err instanceof FatalDiagnosticError) {
trait.toAnalyzed(null, [err.toDiagnostic()], null);
return;
} else {
throw err;
}
}
const symbol = this.makeSymbolForTrait(trait.handler, clazz, result.analysis ?? null);
if (result.analysis !== void 0 && trait.handler.register !== void 0) {
trait.handler.register(clazz, result.analysis);
}
trait = trait.toAnalyzed(result.analysis ?? null, result.diagnostics ?? null, symbol);
}
resolve() {
const classes = this.classes.keys();
for (const clazz of classes) {
const record = this.classes.get(clazz);
for (let trait of record.traits) {
const handler = trait.handler;
switch (trait.state) {
case TraitState.Skipped:
continue;
case TraitState.Pending:
throw new Error(`Resolving a trait that hasn't been analyzed: ${clazz.name.text} / ${trait.handler.name}`);
case TraitState.Resolved:
throw new Error(`Resolving an already resolved trait`);
}
if (trait.analysis === null) {
continue;
}
if (handler.resolve === void 0) {
trait = trait.toResolved(null, null);
continue;
}
let result;
try {
result = handler.resolve(clazz, trait.analysis, trait.symbol);
} catch (err) {
if (err instanceof FatalDiagnosticError) {
trait = trait.toResolved(null, [err.toDiagnostic()]);
continue;
} else {
throw err;
}
}
trait = trait.toResolved(result.data ?? null, result.diagnostics ?? null);
if (result.reexports !== void 0) {
const fileName = clazz.getSourceFile().fileName;
if (!this.reexportMap.has(fileName)) {
this.reexportMap.set(fileName, /* @__PURE__ */ new Map());
}
const fileReexports = this.reexportMap.get(fileName);
for (const reexport of result.reexports) {
fileReexports.set(reexport.asAlias, [reexport.fromModule, reexport.symbolName]);
}
}
}
}
}
/**
* Generate type-checking code into the `TypeCheckContext` for any components within the given
* `ts.SourceFile`.
*/
typeCheck(sf, ctx) {
if (!this.fileToClasses.has(sf) || this.compilationMode === CompilationMode.LOCAL) {
return;
}
for (const clazz of this.fileToClasses.get(sf)) {
const record = this.classes.get(clazz);
for (const trait of record.traits) {
if (trait.state !== TraitState.Resolved) {
continue;
} else if (trait.handler.typeCheck === void 0) {
continue;
}
if (trait.resolution !== null) {
trait.handler.type