@angular/compiler-cli 21.0.0-next.9 → 21.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/{chunk-SIOKS4LN.js → chunk-5UJIUEKT.js} +285 -799
- package/bundles/chunk-DBAV4W4V.js +644 -0
- package/bundles/chunk-DT6FD4OE.js +1 -1
- package/bundles/{chunk-3UF7UI6H.js → chunk-VBBJY6IR.js} +17827 -17100
- package/bundles/{chunk-IE2YQNTQ.js → chunk-YVYYMXOI.js} +1 -1
- package/bundles/index.js +18 -18
- package/bundles/private/migrations.js +49 -5
- package/bundles/private/testing.js +526 -0
- package/bundles/private/tooling.js +1 -2
- package/bundles/src/bin/ng_xi18n.js +4 -4
- package/bundles/src/bin/ngc.js +4 -4
- package/index.d.ts +1 -1
- package/linker/src/file_linker/partial_linkers/util.d.ts +1 -1
- package/package.json +5 -13
- package/private/migrations.d.ts +11 -5
- package/private/testing.d.ts +11 -0
- package/src/ngtsc/annotations/index.d.ts +3 -2
- package/src/ngtsc/core/index.d.ts +1 -0
- package/src/ngtsc/diagnostics/src/error_code.d.ts +2 -0
- package/src/ngtsc/docs/src/entities.d.ts +7 -1
- package/src/ngtsc/docs/src/extractor.d.ts +6 -0
- package/src/ngtsc/docs/src/namespace_extractor.d.ts +15 -0
- package/src/ngtsc/docs/src/variable_extractor.d.ts +16 -0
- package/src/ngtsc/file_system/testing/index.d.ts +12 -0
- package/src/ngtsc/file_system/testing/src/mock_file_system.d.ts +71 -0
- package/src/ngtsc/file_system/testing/src/mock_file_system_native.d.ts +15 -0
- package/src/ngtsc/file_system/testing/src/mock_file_system_posix.d.ts +12 -0
- package/src/ngtsc/file_system/testing/src/mock_file_system_windows.d.ts +12 -0
- package/src/ngtsc/file_system/testing/src/test_helper.d.ts +16 -0
- package/src/ngtsc/translator/src/translator.d.ts +1 -1
- package/src/ngtsc/typecheck/src/oob.d.ts +5 -0
- package/bundles/chunk-HRLHX4UA.js +0 -548
|
@@ -1,548 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import {createRequire as __cjsCompatRequire} from 'module';
|
|
3
|
-
const require = __cjsCompatRequire(import.meta.url);
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
ImportManager,
|
|
7
|
-
ImportedSymbolsTracker,
|
|
8
|
-
TypeScriptReflectionHost,
|
|
9
|
-
getAngularDecorators,
|
|
10
|
-
isAliasImportDeclaration,
|
|
11
|
-
isAngularDecorator,
|
|
12
|
-
loadIsReferencedAliasDeclarationPatch,
|
|
13
|
-
queryDecoratorNames,
|
|
14
|
-
reflectClassMember,
|
|
15
|
-
tryParseInitializerBasedOutput,
|
|
16
|
-
tryParseSignalInputMapping,
|
|
17
|
-
tryParseSignalModelMapping,
|
|
18
|
-
tryParseSignalQueryFromInitializer
|
|
19
|
-
} from "./chunk-3UF7UI6H.js";
|
|
20
|
-
|
|
21
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/downlevel_decorators_transform.js
|
|
22
|
-
import ts from "typescript";
|
|
23
|
-
function isAngularDecorator2(decorator, isCore) {
|
|
24
|
-
return isCore || decorator.import !== null && decorator.import.from === "@angular/core";
|
|
25
|
-
}
|
|
26
|
-
var DECORATOR_INVOCATION_JSDOC_TYPE = "!Array<{type: !Function, args: (undefined|!Array<?>)}>";
|
|
27
|
-
function extractMetadataFromSingleDecorator(decorator, diagnostics) {
|
|
28
|
-
const metadataProperties = [];
|
|
29
|
-
const expr = decorator.expression;
|
|
30
|
-
switch (expr.kind) {
|
|
31
|
-
case ts.SyntaxKind.Identifier:
|
|
32
|
-
metadataProperties.push(ts.factory.createPropertyAssignment("type", expr));
|
|
33
|
-
break;
|
|
34
|
-
case ts.SyntaxKind.CallExpression:
|
|
35
|
-
const call = expr;
|
|
36
|
-
metadataProperties.push(ts.factory.createPropertyAssignment("type", call.expression));
|
|
37
|
-
if (call.arguments.length) {
|
|
38
|
-
const args = [];
|
|
39
|
-
for (const arg of call.arguments) {
|
|
40
|
-
args.push(arg);
|
|
41
|
-
}
|
|
42
|
-
const argsArrayLiteral = ts.factory.createArrayLiteralExpression(ts.factory.createNodeArray(args, true));
|
|
43
|
-
metadataProperties.push(ts.factory.createPropertyAssignment("args", argsArrayLiteral));
|
|
44
|
-
}
|
|
45
|
-
break;
|
|
46
|
-
default:
|
|
47
|
-
diagnostics.push({
|
|
48
|
-
file: decorator.getSourceFile(),
|
|
49
|
-
start: decorator.getStart(),
|
|
50
|
-
length: decorator.getEnd() - decorator.getStart(),
|
|
51
|
-
messageText: `${ts.SyntaxKind[decorator.kind]} not implemented in gathering decorator metadata.`,
|
|
52
|
-
category: ts.DiagnosticCategory.Error,
|
|
53
|
-
code: 0
|
|
54
|
-
});
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
return ts.factory.createObjectLiteralExpression(metadataProperties);
|
|
58
|
-
}
|
|
59
|
-
function createCtorParametersClassProperty(diagnostics, entityNameToExpression, ctorParameters, isClosureCompilerEnabled) {
|
|
60
|
-
const params = [];
|
|
61
|
-
for (const ctorParam of ctorParameters) {
|
|
62
|
-
if (!ctorParam.type && ctorParam.decorators.length === 0) {
|
|
63
|
-
params.push(ts.factory.createNull());
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
const paramType = ctorParam.type ? typeReferenceToExpression(entityNameToExpression, ctorParam.type) : void 0;
|
|
67
|
-
const members = [
|
|
68
|
-
ts.factory.createPropertyAssignment("type", paramType || ts.factory.createIdentifier("undefined"))
|
|
69
|
-
];
|
|
70
|
-
const decorators = [];
|
|
71
|
-
for (const deco of ctorParam.decorators) {
|
|
72
|
-
decorators.push(extractMetadataFromSingleDecorator(deco, diagnostics));
|
|
73
|
-
}
|
|
74
|
-
if (decorators.length) {
|
|
75
|
-
members.push(ts.factory.createPropertyAssignment("decorators", ts.factory.createArrayLiteralExpression(decorators)));
|
|
76
|
-
}
|
|
77
|
-
params.push(ts.factory.createObjectLiteralExpression(members));
|
|
78
|
-
}
|
|
79
|
-
const initializer = ts.factory.createArrowFunction(void 0, void 0, [], void 0, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createArrayLiteralExpression(params, true));
|
|
80
|
-
const ctorProp = ts.factory.createPropertyDeclaration([ts.factory.createToken(ts.SyntaxKind.StaticKeyword)], "ctorParameters", void 0, void 0, initializer);
|
|
81
|
-
if (isClosureCompilerEnabled) {
|
|
82
|
-
ts.setSyntheticLeadingComments(ctorProp, [
|
|
83
|
-
{
|
|
84
|
-
kind: ts.SyntaxKind.MultiLineCommentTrivia,
|
|
85
|
-
text: [
|
|
86
|
-
`*`,
|
|
87
|
-
` * @type {function(): !Array<(null|{`,
|
|
88
|
-
` * type: ?,`,
|
|
89
|
-
` * decorators: (undefined|${DECORATOR_INVOCATION_JSDOC_TYPE}),`,
|
|
90
|
-
` * })>}`,
|
|
91
|
-
` * @nocollapse`,
|
|
92
|
-
` `
|
|
93
|
-
].join("\n"),
|
|
94
|
-
pos: -1,
|
|
95
|
-
end: -1,
|
|
96
|
-
hasTrailingNewLine: true
|
|
97
|
-
}
|
|
98
|
-
]);
|
|
99
|
-
}
|
|
100
|
-
return ctorProp;
|
|
101
|
-
}
|
|
102
|
-
function typeReferenceToExpression(entityNameToExpression, node) {
|
|
103
|
-
let kind = node.kind;
|
|
104
|
-
if (ts.isLiteralTypeNode(node)) {
|
|
105
|
-
kind = node.literal.kind;
|
|
106
|
-
}
|
|
107
|
-
switch (kind) {
|
|
108
|
-
case ts.SyntaxKind.FunctionType:
|
|
109
|
-
case ts.SyntaxKind.ConstructorType:
|
|
110
|
-
return ts.factory.createIdentifier("Function");
|
|
111
|
-
case ts.SyntaxKind.ArrayType:
|
|
112
|
-
case ts.SyntaxKind.TupleType:
|
|
113
|
-
return ts.factory.createIdentifier("Array");
|
|
114
|
-
case ts.SyntaxKind.TypePredicate:
|
|
115
|
-
case ts.SyntaxKind.TrueKeyword:
|
|
116
|
-
case ts.SyntaxKind.FalseKeyword:
|
|
117
|
-
case ts.SyntaxKind.BooleanKeyword:
|
|
118
|
-
return ts.factory.createIdentifier("Boolean");
|
|
119
|
-
case ts.SyntaxKind.StringLiteral:
|
|
120
|
-
case ts.SyntaxKind.StringKeyword:
|
|
121
|
-
return ts.factory.createIdentifier("String");
|
|
122
|
-
case ts.SyntaxKind.ObjectKeyword:
|
|
123
|
-
return ts.factory.createIdentifier("Object");
|
|
124
|
-
case ts.SyntaxKind.NumberKeyword:
|
|
125
|
-
case ts.SyntaxKind.NumericLiteral:
|
|
126
|
-
return ts.factory.createIdentifier("Number");
|
|
127
|
-
case ts.SyntaxKind.TypeReference:
|
|
128
|
-
const typeRef = node;
|
|
129
|
-
return entityNameToExpression(typeRef.typeName);
|
|
130
|
-
case ts.SyntaxKind.UnionType:
|
|
131
|
-
const childTypeNodes = node.types.filter((t) => !(ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword));
|
|
132
|
-
return childTypeNodes.length === 1 ? typeReferenceToExpression(entityNameToExpression, childTypeNodes[0]) : void 0;
|
|
133
|
-
default:
|
|
134
|
-
return void 0;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
function symbolIsRuntimeValue(typeChecker, symbol) {
|
|
138
|
-
if (symbol.flags & ts.SymbolFlags.Alias) {
|
|
139
|
-
symbol = typeChecker.getAliasedSymbol(symbol);
|
|
140
|
-
}
|
|
141
|
-
return (symbol.flags & ts.SymbolFlags.Value & ts.SymbolFlags.ConstEnumExcludes) !== 0;
|
|
142
|
-
}
|
|
143
|
-
function getDownlevelDecoratorsTransform(typeChecker, host, diagnostics, isCore, isClosureCompilerEnabled, shouldTransformClass) {
|
|
144
|
-
function addJSDocTypeAnnotation(node, jsdocType) {
|
|
145
|
-
if (!isClosureCompilerEnabled) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
ts.setSyntheticLeadingComments(node, [
|
|
149
|
-
{
|
|
150
|
-
kind: ts.SyntaxKind.MultiLineCommentTrivia,
|
|
151
|
-
text: `* @type {${jsdocType}} `,
|
|
152
|
-
pos: -1,
|
|
153
|
-
end: -1,
|
|
154
|
-
hasTrailingNewLine: true
|
|
155
|
-
}
|
|
156
|
-
]);
|
|
157
|
-
}
|
|
158
|
-
function createPropDecoratorsClassProperty(diagnostics2, properties) {
|
|
159
|
-
const entries = [];
|
|
160
|
-
for (const [name, decorators] of properties.entries()) {
|
|
161
|
-
entries.push(ts.factory.createPropertyAssignment(name, ts.factory.createArrayLiteralExpression(decorators.map((deco) => extractMetadataFromSingleDecorator(deco, diagnostics2)))));
|
|
162
|
-
}
|
|
163
|
-
const initializer = ts.factory.createObjectLiteralExpression(entries, true);
|
|
164
|
-
const prop = ts.factory.createPropertyDeclaration([ts.factory.createToken(ts.SyntaxKind.StaticKeyword)], "propDecorators", void 0, void 0, initializer);
|
|
165
|
-
addJSDocTypeAnnotation(prop, `!Object<string, ${DECORATOR_INVOCATION_JSDOC_TYPE}>`);
|
|
166
|
-
return prop;
|
|
167
|
-
}
|
|
168
|
-
return (context) => {
|
|
169
|
-
const referencedParameterTypes = loadIsReferencedAliasDeclarationPatch(context);
|
|
170
|
-
function entityNameToExpression(name) {
|
|
171
|
-
const symbol = typeChecker.getSymbolAtLocation(name);
|
|
172
|
-
if (!symbol || !symbolIsRuntimeValue(typeChecker, symbol) || !symbol.declarations || symbol.declarations.length === 0) {
|
|
173
|
-
return void 0;
|
|
174
|
-
}
|
|
175
|
-
if (ts.isQualifiedName(name)) {
|
|
176
|
-
const containerExpr = entityNameToExpression(name.left);
|
|
177
|
-
if (containerExpr === void 0) {
|
|
178
|
-
return void 0;
|
|
179
|
-
}
|
|
180
|
-
return ts.factory.createPropertyAccessExpression(containerExpr, name.right);
|
|
181
|
-
}
|
|
182
|
-
const decl = symbol.declarations[0];
|
|
183
|
-
if (isAliasImportDeclaration(decl)) {
|
|
184
|
-
referencedParameterTypes?.add(decl);
|
|
185
|
-
if (decl.name !== void 0) {
|
|
186
|
-
return ts.setOriginalNode(ts.factory.createIdentifier(decl.name.text), decl.name);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return ts.setOriginalNode(ts.factory.createIdentifier(name.text), name);
|
|
190
|
-
}
|
|
191
|
-
function transformClassElement(element) {
|
|
192
|
-
element = ts.visitEachChild(element, decoratorDownlevelVisitor, context);
|
|
193
|
-
const decoratorsToKeep = [];
|
|
194
|
-
const toLower = [];
|
|
195
|
-
const decorators = host.getDecoratorsOfDeclaration(element) || [];
|
|
196
|
-
for (const decorator of decorators) {
|
|
197
|
-
const decoratorNode = decorator.node;
|
|
198
|
-
if (!isAngularDecorator2(decorator, isCore)) {
|
|
199
|
-
decoratorsToKeep.push(decoratorNode);
|
|
200
|
-
continue;
|
|
201
|
-
}
|
|
202
|
-
toLower.push(decoratorNode);
|
|
203
|
-
}
|
|
204
|
-
if (!toLower.length)
|
|
205
|
-
return [void 0, element, []];
|
|
206
|
-
if (!element.name || !ts.isIdentifier(element.name)) {
|
|
207
|
-
diagnostics.push({
|
|
208
|
-
file: element.getSourceFile(),
|
|
209
|
-
start: element.getStart(),
|
|
210
|
-
length: element.getEnd() - element.getStart(),
|
|
211
|
-
messageText: `Cannot process decorators for class element with non-analyzable name.`,
|
|
212
|
-
category: ts.DiagnosticCategory.Error,
|
|
213
|
-
code: 0
|
|
214
|
-
});
|
|
215
|
-
return [void 0, element, []];
|
|
216
|
-
}
|
|
217
|
-
const elementModifiers = ts.canHaveModifiers(element) ? ts.getModifiers(element) : void 0;
|
|
218
|
-
let modifiers;
|
|
219
|
-
if (decoratorsToKeep.length || elementModifiers?.length) {
|
|
220
|
-
modifiers = ts.setTextRange(ts.factory.createNodeArray([...decoratorsToKeep, ...elementModifiers || []]), element.modifiers);
|
|
221
|
-
}
|
|
222
|
-
return [element.name.text, cloneClassElementWithModifiers(element, modifiers), toLower];
|
|
223
|
-
}
|
|
224
|
-
function transformConstructor(ctor) {
|
|
225
|
-
ctor = ts.visitEachChild(ctor, decoratorDownlevelVisitor, context);
|
|
226
|
-
const newParameters = [];
|
|
227
|
-
const oldParameters = ctor.parameters;
|
|
228
|
-
const parametersInfo = [];
|
|
229
|
-
for (const param of oldParameters) {
|
|
230
|
-
const decoratorsToKeep = [];
|
|
231
|
-
const paramInfo = { decorators: [], type: null };
|
|
232
|
-
const decorators = host.getDecoratorsOfDeclaration(param) || [];
|
|
233
|
-
for (const decorator of decorators) {
|
|
234
|
-
const decoratorNode = decorator.node;
|
|
235
|
-
if (!isAngularDecorator2(decorator, isCore)) {
|
|
236
|
-
decoratorsToKeep.push(decoratorNode);
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
paramInfo.decorators.push(decoratorNode);
|
|
240
|
-
}
|
|
241
|
-
if (param.type) {
|
|
242
|
-
paramInfo.type = param.type;
|
|
243
|
-
}
|
|
244
|
-
parametersInfo.push(paramInfo);
|
|
245
|
-
let modifiers;
|
|
246
|
-
const paramModifiers = ts.getModifiers(param);
|
|
247
|
-
if (decoratorsToKeep.length || paramModifiers?.length) {
|
|
248
|
-
modifiers = [...decoratorsToKeep, ...paramModifiers || []];
|
|
249
|
-
}
|
|
250
|
-
const newParam = ts.factory.updateParameterDeclaration(param, modifiers, param.dotDotDotToken, param.name, param.questionToken, param.type, param.initializer);
|
|
251
|
-
newParameters.push(newParam);
|
|
252
|
-
}
|
|
253
|
-
const updated = ts.factory.updateConstructorDeclaration(ctor, ts.getModifiers(ctor), newParameters, ctor.body);
|
|
254
|
-
return [updated, parametersInfo];
|
|
255
|
-
}
|
|
256
|
-
function transformClassDeclaration(classDecl) {
|
|
257
|
-
const newMembers = [];
|
|
258
|
-
const decoratedProperties = /* @__PURE__ */ new Map();
|
|
259
|
-
let classParameters = null;
|
|
260
|
-
for (const member of classDecl.members) {
|
|
261
|
-
switch (member.kind) {
|
|
262
|
-
case ts.SyntaxKind.PropertyDeclaration:
|
|
263
|
-
case ts.SyntaxKind.GetAccessor:
|
|
264
|
-
case ts.SyntaxKind.SetAccessor:
|
|
265
|
-
case ts.SyntaxKind.MethodDeclaration: {
|
|
266
|
-
const [name, newMember, decorators] = transformClassElement(member);
|
|
267
|
-
newMembers.push(newMember);
|
|
268
|
-
if (name)
|
|
269
|
-
decoratedProperties.set(name, decorators);
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
case ts.SyntaxKind.Constructor: {
|
|
273
|
-
const ctor = member;
|
|
274
|
-
if (!ctor.body)
|
|
275
|
-
break;
|
|
276
|
-
const [newMember, parametersInfo] = transformConstructor(member);
|
|
277
|
-
classParameters = parametersInfo;
|
|
278
|
-
newMembers.push(newMember);
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
281
|
-
default:
|
|
282
|
-
break;
|
|
283
|
-
}
|
|
284
|
-
newMembers.push(ts.visitEachChild(member, decoratorDownlevelVisitor, context));
|
|
285
|
-
}
|
|
286
|
-
const possibleAngularDecorators = host.getDecoratorsOfDeclaration(classDecl) || [];
|
|
287
|
-
const hasAngularDecorator = possibleAngularDecorators.some((d) => isAngularDecorator2(d, isCore));
|
|
288
|
-
if (classParameters) {
|
|
289
|
-
if (hasAngularDecorator || classParameters.some((p) => !!p.decorators.length)) {
|
|
290
|
-
newMembers.push(createCtorParametersClassProperty(diagnostics, entityNameToExpression, classParameters, isClosureCompilerEnabled));
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
if (decoratedProperties.size) {
|
|
294
|
-
newMembers.push(createPropDecoratorsClassProperty(diagnostics, decoratedProperties));
|
|
295
|
-
}
|
|
296
|
-
const members = ts.setTextRange(ts.factory.createNodeArray(newMembers, classDecl.members.hasTrailingComma), classDecl.members);
|
|
297
|
-
return ts.factory.updateClassDeclaration(classDecl, classDecl.modifiers, classDecl.name, classDecl.typeParameters, classDecl.heritageClauses, members);
|
|
298
|
-
}
|
|
299
|
-
function decoratorDownlevelVisitor(node) {
|
|
300
|
-
if (ts.isClassDeclaration(node) && (shouldTransformClass === void 0 || shouldTransformClass(node))) {
|
|
301
|
-
return transformClassDeclaration(node);
|
|
302
|
-
}
|
|
303
|
-
return ts.visitEachChild(node, decoratorDownlevelVisitor, context);
|
|
304
|
-
}
|
|
305
|
-
return (sf) => {
|
|
306
|
-
return ts.visitEachChild(sf, decoratorDownlevelVisitor, context);
|
|
307
|
-
};
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
function cloneClassElementWithModifiers(node, modifiers) {
|
|
311
|
-
let clone;
|
|
312
|
-
if (ts.isMethodDeclaration(node)) {
|
|
313
|
-
clone = ts.factory.createMethodDeclaration(modifiers, node.asteriskToken, node.name, node.questionToken, node.typeParameters, node.parameters, node.type, node.body);
|
|
314
|
-
} else if (ts.isPropertyDeclaration(node)) {
|
|
315
|
-
clone = ts.factory.createPropertyDeclaration(modifiers, node.name, node.questionToken, node.type, node.initializer);
|
|
316
|
-
} else if (ts.isGetAccessor(node)) {
|
|
317
|
-
clone = ts.factory.createGetAccessorDeclaration(modifiers, node.name, node.parameters, node.type, node.body);
|
|
318
|
-
} else if (ts.isSetAccessor(node)) {
|
|
319
|
-
clone = ts.factory.createSetAccessorDeclaration(modifiers, node.name, node.parameters, node.body);
|
|
320
|
-
} else {
|
|
321
|
-
throw new Error(`Unsupported decorated member with kind ${ts.SyntaxKind[node.kind]}`);
|
|
322
|
-
}
|
|
323
|
-
return ts.setOriginalNode(clone, node);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/initializer_api_transforms/transform.js
|
|
327
|
-
import ts4 from "typescript";
|
|
328
|
-
|
|
329
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/initializer_api_transforms/transform_api.js
|
|
330
|
-
import ts2 from "typescript";
|
|
331
|
-
function createSyntheticAngularCoreDecoratorAccess(factory, importManager, ngClassDecorator, sourceFile, decoratorName) {
|
|
332
|
-
const classDecoratorIdentifier = ts2.isIdentifier(ngClassDecorator.identifier) ? ngClassDecorator.identifier : ngClassDecorator.identifier.expression;
|
|
333
|
-
return factory.createPropertyAccessExpression(
|
|
334
|
-
importManager.addImport({
|
|
335
|
-
exportModuleSpecifier: "@angular/core",
|
|
336
|
-
exportSymbolName: null,
|
|
337
|
-
requestedFile: sourceFile
|
|
338
|
-
}),
|
|
339
|
-
// The synthetic identifier may be checked later by the downlevel decorators
|
|
340
|
-
// transform to resolve to an Angular import using `getSymbolAtLocation`. We trick
|
|
341
|
-
// the transform to think it's not synthetic and comes from Angular core.
|
|
342
|
-
ts2.setOriginalNode(factory.createIdentifier(decoratorName), classDecoratorIdentifier)
|
|
343
|
-
);
|
|
344
|
-
}
|
|
345
|
-
function castAsAny(factory, expr) {
|
|
346
|
-
return factory.createAsExpression(expr, factory.createKeywordTypeNode(ts2.SyntaxKind.AnyKeyword));
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/initializer_api_transforms/input_function.js
|
|
350
|
-
var signalInputsTransform = (member, sourceFile, host, factory, importTracker, importManager, classDecorator, isCore) => {
|
|
351
|
-
if (host.getDecoratorsOfDeclaration(member.node)?.some((d) => isAngularDecorator(d, "Input", isCore))) {
|
|
352
|
-
return member.node;
|
|
353
|
-
}
|
|
354
|
-
const inputMapping = tryParseSignalInputMapping(member, host, importTracker);
|
|
355
|
-
if (inputMapping === null) {
|
|
356
|
-
return member.node;
|
|
357
|
-
}
|
|
358
|
-
const fields = {
|
|
359
|
-
"isSignal": factory.createTrue(),
|
|
360
|
-
"alias": factory.createStringLiteral(inputMapping.bindingPropertyName),
|
|
361
|
-
"required": inputMapping.required ? factory.createTrue() : factory.createFalse(),
|
|
362
|
-
// For signal inputs, transforms are captured by the input signal. The runtime will
|
|
363
|
-
// determine whether a transform needs to be run via the input signal, so the `transform`
|
|
364
|
-
// option is always `undefined`.
|
|
365
|
-
"transform": factory.createIdentifier("undefined")
|
|
366
|
-
};
|
|
367
|
-
const newDecorator = factory.createDecorator(factory.createCallExpression(createSyntheticAngularCoreDecoratorAccess(factory, importManager, classDecorator, sourceFile, "Input"), void 0, [
|
|
368
|
-
// Cast to `any` because `isSignal` will be private, and in case this
|
|
369
|
-
// transform is used directly as a pre-compilation step, the decorator should
|
|
370
|
-
// not fail. It is already validated now due to us parsing the input metadata.
|
|
371
|
-
castAsAny(factory, factory.createObjectLiteralExpression(Object.entries(fields).map(([name, value]) => factory.createPropertyAssignment(name, value))))
|
|
372
|
-
]));
|
|
373
|
-
return factory.updatePropertyDeclaration(member.node, [newDecorator, ...member.node.modifiers ?? []], member.name, member.node.questionToken, member.node.type, member.node.initializer);
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/initializer_api_transforms/model_function.js
|
|
377
|
-
import ts3 from "typescript";
|
|
378
|
-
var signalModelTransform = (member, sourceFile, host, factory, importTracker, importManager, classDecorator, isCore) => {
|
|
379
|
-
if (host.getDecoratorsOfDeclaration(member.node)?.some((d) => {
|
|
380
|
-
return isAngularDecorator(d, "Input", isCore) || isAngularDecorator(d, "Output", isCore);
|
|
381
|
-
})) {
|
|
382
|
-
return member.node;
|
|
383
|
-
}
|
|
384
|
-
const modelMapping = tryParseSignalModelMapping(member, host, importTracker);
|
|
385
|
-
if (modelMapping === null) {
|
|
386
|
-
return member.node;
|
|
387
|
-
}
|
|
388
|
-
const inputConfig = factory.createObjectLiteralExpression([
|
|
389
|
-
factory.createPropertyAssignment("isSignal", modelMapping.input.isSignal ? factory.createTrue() : factory.createFalse()),
|
|
390
|
-
factory.createPropertyAssignment("alias", factory.createStringLiteral(modelMapping.input.bindingPropertyName)),
|
|
391
|
-
factory.createPropertyAssignment("required", modelMapping.input.required ? factory.createTrue() : factory.createFalse())
|
|
392
|
-
]);
|
|
393
|
-
const inputDecorator = createDecorator(
|
|
394
|
-
"Input",
|
|
395
|
-
// Config is cast to `any` because `isSignal` will be private, and in case this
|
|
396
|
-
// transform is used directly as a pre-compilation step, the decorator should
|
|
397
|
-
// not fail. It is already validated now due to us parsing the input metadata.
|
|
398
|
-
factory.createAsExpression(inputConfig, factory.createKeywordTypeNode(ts3.SyntaxKind.AnyKeyword)),
|
|
399
|
-
classDecorator,
|
|
400
|
-
factory,
|
|
401
|
-
sourceFile,
|
|
402
|
-
importManager
|
|
403
|
-
);
|
|
404
|
-
const outputDecorator = createDecorator("Output", factory.createStringLiteral(modelMapping.output.bindingPropertyName), classDecorator, factory, sourceFile, importManager);
|
|
405
|
-
return factory.updatePropertyDeclaration(member.node, [inputDecorator, outputDecorator, ...member.node.modifiers ?? []], member.node.name, member.node.questionToken, member.node.type, member.node.initializer);
|
|
406
|
-
};
|
|
407
|
-
function createDecorator(name, config, classDecorator, factory, sourceFile, importManager) {
|
|
408
|
-
const callTarget = createSyntheticAngularCoreDecoratorAccess(factory, importManager, classDecorator, sourceFile, name);
|
|
409
|
-
return factory.createDecorator(factory.createCallExpression(callTarget, void 0, [config]));
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/initializer_api_transforms/output_function.js
|
|
413
|
-
var initializerApiOutputTransform = (member, sourceFile, host, factory, importTracker, importManager, classDecorator, isCore) => {
|
|
414
|
-
if (host.getDecoratorsOfDeclaration(member.node)?.some((d) => isAngularDecorator(d, "Output", isCore))) {
|
|
415
|
-
return member.node;
|
|
416
|
-
}
|
|
417
|
-
const output = tryParseInitializerBasedOutput(member, host, importTracker);
|
|
418
|
-
if (output === null) {
|
|
419
|
-
return member.node;
|
|
420
|
-
}
|
|
421
|
-
const newDecorator = factory.createDecorator(factory.createCallExpression(createSyntheticAngularCoreDecoratorAccess(factory, importManager, classDecorator, sourceFile, "Output"), void 0, [factory.createStringLiteral(output.metadata.bindingPropertyName)]));
|
|
422
|
-
return factory.updatePropertyDeclaration(member.node, [newDecorator, ...member.node.modifiers ?? []], member.node.name, member.node.questionToken, member.node.type, member.node.initializer);
|
|
423
|
-
};
|
|
424
|
-
|
|
425
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/initializer_api_transforms/query_functions.js
|
|
426
|
-
var queryFunctionToDecorator = {
|
|
427
|
-
"viewChild": "ViewChild",
|
|
428
|
-
"viewChildren": "ViewChildren",
|
|
429
|
-
"contentChild": "ContentChild",
|
|
430
|
-
"contentChildren": "ContentChildren"
|
|
431
|
-
};
|
|
432
|
-
var queryFunctionsTransforms = (member, sourceFile, host, factory, importTracker, importManager, classDecorator, isCore) => {
|
|
433
|
-
const decorators = host.getDecoratorsOfDeclaration(member.node);
|
|
434
|
-
const queryDecorators = decorators && getAngularDecorators(decorators, queryDecoratorNames, isCore);
|
|
435
|
-
if (queryDecorators !== null && queryDecorators.length > 0) {
|
|
436
|
-
return member.node;
|
|
437
|
-
}
|
|
438
|
-
const queryDefinition = tryParseSignalQueryFromInitializer(member, host, importTracker);
|
|
439
|
-
if (queryDefinition === null) {
|
|
440
|
-
return member.node;
|
|
441
|
-
}
|
|
442
|
-
const callArgs = queryDefinition.call.arguments;
|
|
443
|
-
const newDecorator = factory.createDecorator(factory.createCallExpression(
|
|
444
|
-
createSyntheticAngularCoreDecoratorAccess(factory, importManager, classDecorator, sourceFile, queryFunctionToDecorator[queryDefinition.name]),
|
|
445
|
-
void 0,
|
|
446
|
-
// All positional arguments of the query functions can be mostly re-used as is
|
|
447
|
-
// for the decorator. i.e. predicate is always first argument. Options are second.
|
|
448
|
-
[
|
|
449
|
-
queryDefinition.call.arguments[0],
|
|
450
|
-
// Note: Casting as `any` because `isSignal` is not publicly exposed and this
|
|
451
|
-
// transform might pre-transform TS sources.
|
|
452
|
-
castAsAny(factory, factory.createObjectLiteralExpression([
|
|
453
|
-
...callArgs.length > 1 ? [factory.createSpreadAssignment(callArgs[1])] : [],
|
|
454
|
-
factory.createPropertyAssignment("isSignal", factory.createTrue())
|
|
455
|
-
]))
|
|
456
|
-
]
|
|
457
|
-
));
|
|
458
|
-
return factory.updatePropertyDeclaration(member.node, [newDecorator, ...member.node.modifiers ?? []], member.node.name, member.node.questionToken, member.node.type, member.node.initializer);
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/initializer_api_transforms/transform.js
|
|
462
|
-
var decoratorsWithInputs = ["Directive", "Component"];
|
|
463
|
-
var propertyTransforms = [
|
|
464
|
-
signalInputsTransform,
|
|
465
|
-
initializerApiOutputTransform,
|
|
466
|
-
queryFunctionsTransforms,
|
|
467
|
-
signalModelTransform
|
|
468
|
-
];
|
|
469
|
-
function getInitializerApiJitTransform(host, importTracker, isCore, shouldTransformClass) {
|
|
470
|
-
return (ctx) => {
|
|
471
|
-
return (sourceFile) => {
|
|
472
|
-
const importManager = new ImportManager();
|
|
473
|
-
sourceFile = ts4.visitNode(sourceFile, createTransformVisitor(ctx, host, importManager, importTracker, isCore, shouldTransformClass), ts4.isSourceFile);
|
|
474
|
-
return importManager.transformTsFile(ctx, sourceFile);
|
|
475
|
-
};
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
function createTransformVisitor(ctx, host, importManager, importTracker, isCore, shouldTransformClass) {
|
|
479
|
-
const visitor = (node) => {
|
|
480
|
-
if (ts4.isClassDeclaration(node) && node.name !== void 0) {
|
|
481
|
-
const originalNode = ts4.getOriginalNode(node, ts4.isClassDeclaration);
|
|
482
|
-
const angularDecorator = host.getDecoratorsOfDeclaration(originalNode)?.find((d) => decoratorsWithInputs.some((name) => isAngularDecorator(d, name, isCore)));
|
|
483
|
-
if (angularDecorator !== void 0 && (shouldTransformClass === void 0 || shouldTransformClass(node))) {
|
|
484
|
-
let hasChanged = false;
|
|
485
|
-
const sourceFile = originalNode.getSourceFile();
|
|
486
|
-
const members = node.members.map((memberNode) => {
|
|
487
|
-
if (!ts4.isPropertyDeclaration(memberNode)) {
|
|
488
|
-
return memberNode;
|
|
489
|
-
}
|
|
490
|
-
const member = reflectClassMember(memberNode);
|
|
491
|
-
if (member === null) {
|
|
492
|
-
return memberNode;
|
|
493
|
-
}
|
|
494
|
-
for (const transform of propertyTransforms) {
|
|
495
|
-
const newNode = transform({ ...member, node: memberNode }, sourceFile, host, ctx.factory, importTracker, importManager, angularDecorator, isCore);
|
|
496
|
-
if (newNode !== member.node) {
|
|
497
|
-
hasChanged = true;
|
|
498
|
-
return newNode;
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
return memberNode;
|
|
502
|
-
});
|
|
503
|
-
if (hasChanged) {
|
|
504
|
-
return ctx.factory.updateClassDeclaration(node, node.modifiers, node.name, node.typeParameters, node.heritageClauses, members);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
return ts4.visitEachChild(node, visitor, ctx);
|
|
509
|
-
};
|
|
510
|
-
return visitor;
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// packages/compiler-cli/src/ngtsc/transform/jit/src/index.js
|
|
514
|
-
function angularJitApplicationTransform(program, isCore = false, shouldTransformClass) {
|
|
515
|
-
const typeChecker = program.getTypeChecker();
|
|
516
|
-
const reflectionHost = new TypeScriptReflectionHost(typeChecker);
|
|
517
|
-
const importTracker = new ImportedSymbolsTracker();
|
|
518
|
-
const downlevelDecoratorTransform = getDownlevelDecoratorsTransform(
|
|
519
|
-
typeChecker,
|
|
520
|
-
reflectionHost,
|
|
521
|
-
[],
|
|
522
|
-
isCore,
|
|
523
|
-
/* enableClosureCompiler */
|
|
524
|
-
false,
|
|
525
|
-
shouldTransformClass
|
|
526
|
-
);
|
|
527
|
-
const initializerApisJitTransform = getInitializerApiJitTransform(reflectionHost, importTracker, isCore, shouldTransformClass);
|
|
528
|
-
return (ctx) => {
|
|
529
|
-
return (sourceFile) => {
|
|
530
|
-
sourceFile = initializerApisJitTransform(ctx)(sourceFile);
|
|
531
|
-
sourceFile = downlevelDecoratorTransform(ctx)(sourceFile);
|
|
532
|
-
return sourceFile;
|
|
533
|
-
};
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
export {
|
|
538
|
-
getDownlevelDecoratorsTransform,
|
|
539
|
-
getInitializerApiJitTransform,
|
|
540
|
-
angularJitApplicationTransform
|
|
541
|
-
};
|
|
542
|
-
/**
|
|
543
|
-
* @license
|
|
544
|
-
* Copyright Google LLC All Rights Reserved.
|
|
545
|
-
*
|
|
546
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
547
|
-
* found in the LICENSE file at https://angular.dev/license
|
|
548
|
-
*/
|