@angular/compiler 17.2.0-next.0 → 17.2.0-next.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/esm2022/src/expression_parser/ast.mjs +2 -1
- package/esm2022/src/jit_compiler_facade.mjs +9 -2
- package/esm2022/src/render3/partial/class_metadata.mjs +1 -1
- package/esm2022/src/render3/partial/directive.mjs +1 -1
- package/esm2022/src/render3/partial/factory.mjs +1 -1
- package/esm2022/src/render3/partial/injectable.mjs +1 -1
- package/esm2022/src/render3/partial/injector.mjs +1 -1
- package/esm2022/src/render3/partial/ng_module.mjs +1 -1
- package/esm2022/src/render3/partial/pipe.mjs +1 -1
- package/esm2022/src/render3/r3_control_flow.mjs +39 -7
- package/esm2022/src/render3/r3_template_transform.mjs +5 -5
- package/esm2022/src/render3/view/api.mjs +1 -1
- package/esm2022/src/render3/view/compiler.mjs +10 -10
- package/esm2022/src/render3/view/template.mjs +4 -3
- package/esm2022/src/render3/view/util.mjs +2 -2
- package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +3 -3
- package/esm2022/src/template/pipeline/src/compilation.mjs +3 -2
- package/esm2022/src/template/pipeline/src/emit.mjs +2 -2
- package/esm2022/src/template/pipeline/src/ingest.mjs +9 -7
- package/esm2022/src/template/pipeline/src/phases/create_defer_deps_fns.mjs +6 -2
- package/esm2022/src/template_parser/binding_parser.mjs +11 -10
- package/esm2022/src/version.mjs +1 -1
- package/fesm2022/compiler.mjs +101 -52
- package/fesm2022/compiler.mjs.map +1 -1
- package/index.d.ts +10 -5
- package/package.json +2 -2
package/fesm2022/compiler.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v17.2.0-next.
|
|
2
|
+
* @license Angular v17.2.0-next.1
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -5138,7 +5138,7 @@ function getAttrsForDirectiveMatching(elOrTpl) {
|
|
|
5138
5138
|
}
|
|
5139
5139
|
});
|
|
5140
5140
|
elOrTpl.inputs.forEach(i => {
|
|
5141
|
-
if (i.type === 0 /* BindingType.Property */) {
|
|
5141
|
+
if (i.type === 0 /* BindingType.Property */ || i.type === 5 /* BindingType.TwoWay */) {
|
|
5142
5142
|
attributesMap[i.name] = '';
|
|
5143
5143
|
}
|
|
5144
5144
|
});
|
|
@@ -6930,6 +6930,7 @@ var ParsedPropertyType;
|
|
|
6930
6930
|
ParsedPropertyType[ParsedPropertyType["DEFAULT"] = 0] = "DEFAULT";
|
|
6931
6931
|
ParsedPropertyType[ParsedPropertyType["LITERAL_ATTR"] = 1] = "LITERAL_ATTR";
|
|
6932
6932
|
ParsedPropertyType[ParsedPropertyType["ANIMATION"] = 2] = "ANIMATION";
|
|
6933
|
+
ParsedPropertyType[ParsedPropertyType["TWO_WAY"] = 3] = "TWO_WAY";
|
|
6933
6934
|
})(ParsedPropertyType || (ParsedPropertyType = {}));
|
|
6934
6935
|
class ParsedEvent {
|
|
6935
6936
|
// Regular events have a target
|
|
@@ -11024,7 +11025,7 @@ function createExtractedAttributeOp(target, bindingKind, namespace, name, expres
|
|
|
11024
11025
|
...NEW_OP,
|
|
11025
11026
|
};
|
|
11026
11027
|
}
|
|
11027
|
-
function createDeferOp(xref, main, mainSlot, metadata, sourceSpan) {
|
|
11028
|
+
function createDeferOp(xref, main, mainSlot, metadata, resolverFn, sourceSpan) {
|
|
11028
11029
|
return {
|
|
11029
11030
|
kind: OpKind.Defer,
|
|
11030
11031
|
xref,
|
|
@@ -11043,7 +11044,7 @@ function createDeferOp(xref, main, mainSlot, metadata, sourceSpan) {
|
|
|
11043
11044
|
errorView: null,
|
|
11044
11045
|
errorSlot: null,
|
|
11045
11046
|
metadata,
|
|
11046
|
-
resolverFn
|
|
11047
|
+
resolverFn,
|
|
11047
11048
|
sourceSpan,
|
|
11048
11049
|
...NEW_OP,
|
|
11049
11050
|
...TRAIT_CONSUMES_SLOT,
|
|
@@ -11232,11 +11233,12 @@ class CompilationJob {
|
|
|
11232
11233
|
* embedded views or host bindings.
|
|
11233
11234
|
*/
|
|
11234
11235
|
class ComponentCompilationJob extends CompilationJob {
|
|
11235
|
-
constructor(componentName, pool, compatibility, relativeContextFilePath, i18nUseExternalIds, deferBlocksMeta) {
|
|
11236
|
+
constructor(componentName, pool, compatibility, relativeContextFilePath, i18nUseExternalIds, deferBlocksMeta, allDeferrableDepsFn) {
|
|
11236
11237
|
super(componentName, pool, compatibility);
|
|
11237
11238
|
this.relativeContextFilePath = relativeContextFilePath;
|
|
11238
11239
|
this.i18nUseExternalIds = i18nUseExternalIds;
|
|
11239
11240
|
this.deferBlocksMeta = deferBlocksMeta;
|
|
11241
|
+
this.allDeferrableDepsFn = allDeferrableDepsFn;
|
|
11240
11242
|
this.kind = CompilationJobKind.Tmpl;
|
|
11241
11243
|
this.fnSuffix = 'Template';
|
|
11242
11244
|
this.views = new Map();
|
|
@@ -12159,6 +12161,9 @@ function createDeferDepsFns(job) {
|
|
|
12159
12161
|
if (op.metadata.deps.length === 0) {
|
|
12160
12162
|
continue;
|
|
12161
12163
|
}
|
|
12164
|
+
if (op.resolverFn !== null) {
|
|
12165
|
+
continue;
|
|
12166
|
+
}
|
|
12162
12167
|
const dependencies = [];
|
|
12163
12168
|
for (const dep of op.metadata.deps) {
|
|
12164
12169
|
if (dep.isDeferrable) {
|
|
@@ -12177,7 +12182,8 @@ function createDeferDepsFns(job) {
|
|
|
12177
12182
|
if (op.handle.slot === null) {
|
|
12178
12183
|
throw new Error('AssertionError: slot must be assigned bfore extracting defer deps functions');
|
|
12179
12184
|
}
|
|
12180
|
-
|
|
12185
|
+
const fullPathName = unit.fnName?.replace(`_Template`, ``);
|
|
12186
|
+
op.resolverFn = job.pool.getSharedFunctionReference(depsFnExpr, `${fullPathName}_Defer_${op.handle.slot}_DepsFn`,
|
|
12181
12187
|
/* Don't use unique names for TDB compatibility */ false);
|
|
12182
12188
|
}
|
|
12183
12189
|
}
|
|
@@ -23937,7 +23943,6 @@ const phases = [
|
|
|
23937
23943
|
{ kind: CompilationJobKind.Both, fn: expandSafeReads },
|
|
23938
23944
|
{ kind: CompilationJobKind.Both, fn: generateTemporaryVariables },
|
|
23939
23945
|
{ kind: CompilationJobKind.Tmpl, fn: allocateSlots },
|
|
23940
|
-
{ kind: CompilationJobKind.Tmpl, fn: createDeferDepsFns },
|
|
23941
23946
|
{ kind: CompilationJobKind.Tmpl, fn: resolveI18nElementPlaceholders },
|
|
23942
23947
|
{ kind: CompilationJobKind.Tmpl, fn: resolveI18nExpressionPlaceholders },
|
|
23943
23948
|
{ kind: CompilationJobKind.Tmpl, fn: extractI18nMessages },
|
|
@@ -23950,6 +23955,7 @@ const phases = [
|
|
|
23950
23955
|
{ kind: CompilationJobKind.Tmpl, fn: generateAdvance },
|
|
23951
23956
|
{ kind: CompilationJobKind.Both, fn: optimizeVariables },
|
|
23952
23957
|
{ kind: CompilationJobKind.Both, fn: nameFunctionsAndVariables },
|
|
23958
|
+
{ kind: CompilationJobKind.Tmpl, fn: createDeferDepsFns },
|
|
23953
23959
|
{ kind: CompilationJobKind.Tmpl, fn: mergeNextContextExpressions },
|
|
23954
23960
|
{ kind: CompilationJobKind.Tmpl, fn: generateNgContainerOps },
|
|
23955
23961
|
{ kind: CompilationJobKind.Tmpl, fn: collapseEmptyInstructions },
|
|
@@ -24075,8 +24081,8 @@ const NG_TEMPLATE_TAG_NAME$1 = 'ng-template';
|
|
|
24075
24081
|
* representation.
|
|
24076
24082
|
* TODO: Refactor more of the ingestion code into phases.
|
|
24077
24083
|
*/
|
|
24078
|
-
function ingestComponent(componentName, template, constantPool, relativeContextFilePath, i18nUseExternalIds, deferBlocksMeta) {
|
|
24079
|
-
const job = new ComponentCompilationJob(componentName, constantPool, compatibilityMode, relativeContextFilePath, i18nUseExternalIds, deferBlocksMeta);
|
|
24084
|
+
function ingestComponent(componentName, template, constantPool, relativeContextFilePath, i18nUseExternalIds, deferBlocksMeta, allDeferrableDepsFn) {
|
|
24085
|
+
const job = new ComponentCompilationJob(componentName, constantPool, compatibilityMode, relativeContextFilePath, i18nUseExternalIds, deferBlocksMeta, allDeferrableDepsFn);
|
|
24080
24086
|
ingestNodes(job.root, template);
|
|
24081
24087
|
return job;
|
|
24082
24088
|
}
|
|
@@ -24134,7 +24140,7 @@ function ingestHostAttribute(job, name, value, securityContexts) {
|
|
|
24134
24140
|
job.root.update.push(attrBinding);
|
|
24135
24141
|
}
|
|
24136
24142
|
function ingestHostEvent(job, event) {
|
|
24137
|
-
const [phase, target] = event.type
|
|
24143
|
+
const [phase, target] = event.type !== 1 /* e.ParsedEventType.Animation */ ? [null, event.targetOrPhase] :
|
|
24138
24144
|
[event.targetOrPhase, null];
|
|
24139
24145
|
const eventBinding = createListenerOp(job.root.xref, new SlotHandle(), event.name, null, makeListenerHandlerOps(job.root, event.handler, event.handlerSpan), phase, target, true, event.sourceSpan);
|
|
24140
24146
|
job.root.create.push(eventBinding);
|
|
@@ -24400,7 +24406,7 @@ function ingestDeferBlock(unit, deferBlock) {
|
|
|
24400
24406
|
const error = ingestDeferView(unit, 'Error', deferBlock.error?.i18n, deferBlock.error?.children, deferBlock.error?.sourceSpan);
|
|
24401
24407
|
// Create the main defer op, and ops for all secondary views.
|
|
24402
24408
|
const deferXref = unit.job.allocateXrefId();
|
|
24403
|
-
const deferOp = createDeferOp(deferXref, main.xref, main.handle, blockMeta, deferBlock.sourceSpan);
|
|
24409
|
+
const deferOp = createDeferOp(deferXref, main.xref, main.handle, blockMeta, unit.job.allDeferrableDepsFn, deferBlock.sourceSpan);
|
|
24404
24410
|
deferOp.placeholderView = placeholder?.xref ?? null;
|
|
24405
24411
|
deferOp.placeholderSlot = placeholder?.handle ?? null;
|
|
24406
24412
|
deferOp.loadingSlot = loading?.handle ?? null;
|
|
@@ -24725,6 +24731,8 @@ function convertAstWithInterpolation(job, value, i18nMeta, sourceSpan) {
|
|
|
24725
24731
|
// TODO: Can we populate Template binding kinds in ingest?
|
|
24726
24732
|
const BINDING_KINDS = new Map([
|
|
24727
24733
|
[0 /* e.BindingType.Property */, BindingKind.Property],
|
|
24734
|
+
// TODO(crisbeto): we'll need a different BindingKind for two-way bindings.
|
|
24735
|
+
[5 /* e.BindingType.TwoWay */, BindingKind.Property],
|
|
24728
24736
|
[1 /* e.BindingType.Attribute */, BindingKind.Attribute],
|
|
24729
24737
|
[2 /* e.BindingType.Class */, BindingKind.ClassName],
|
|
24730
24738
|
[3 /* e.BindingType.Style */, BindingKind.StyleProperty],
|
|
@@ -24870,8 +24878,8 @@ function createTemplateBinding(view, xref, type, name, value, unit, securityCont
|
|
|
24870
24878
|
// update instruction.
|
|
24871
24879
|
if (templateKind === TemplateKind.Structural) {
|
|
24872
24880
|
if (!isStructuralTemplateAttribute &&
|
|
24873
|
-
(type === 0 /* e.BindingType.Property */ || type ===
|
|
24874
|
-
type === 3 /* e.BindingType.Style */)) {
|
|
24881
|
+
(type === 0 /* e.BindingType.Property */ || type === 5 /* e.BindingType.TwoWay */ ||
|
|
24882
|
+
type === 2 /* e.BindingType.Class */ || type === 3 /* e.BindingType.Style */)) {
|
|
24875
24883
|
// Because this binding doesn't really target the ng-template, it must be a binding on an
|
|
24876
24884
|
// inner node of a structural template. We can't skip it entirely, because we still need it on
|
|
24877
24885
|
// the ng-template's consts (e.g. for the purposes of directive matching). However, we should
|
|
@@ -25153,7 +25161,7 @@ class BindingParser {
|
|
|
25153
25161
|
for (const propName of Object.keys(properties)) {
|
|
25154
25162
|
const expression = properties[propName];
|
|
25155
25163
|
if (typeof expression === 'string') {
|
|
25156
|
-
this.parsePropertyBinding(propName, expression, true, sourceSpan, sourceSpan.start.offset, undefined, [],
|
|
25164
|
+
this.parsePropertyBinding(propName, expression, true, false, sourceSpan, sourceSpan.start.offset, undefined, [],
|
|
25157
25165
|
// Use the `sourceSpan` for `keySpan`. This isn't really accurate, but neither is the
|
|
25158
25166
|
// sourceSpan, as it represents the sourceSpan of the host itself rather than the
|
|
25159
25167
|
// source of the host binding (which doesn't exist in the template). Regardless,
|
|
@@ -25249,7 +25257,7 @@ class BindingParser {
|
|
|
25249
25257
|
else if (binding.value) {
|
|
25250
25258
|
const srcSpan = isIvyAst ? bindingSpan : sourceSpan;
|
|
25251
25259
|
const valueSpan = moveParseSourceSpan(sourceSpan, binding.value.ast.sourceSpan);
|
|
25252
|
-
this._parsePropertyAst(key, binding.value, srcSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25260
|
+
this._parsePropertyAst(key, binding.value, false, srcSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25253
25261
|
}
|
|
25254
25262
|
else {
|
|
25255
25263
|
targetMatchableAttrs.push([key, '' /* value */]);
|
|
@@ -25302,7 +25310,7 @@ class BindingParser {
|
|
|
25302
25310
|
targetProps.push(new ParsedProperty(name, this._exprParser.wrapLiteralPrimitive(value, '', absoluteOffset), ParsedPropertyType.LITERAL_ATTR, sourceSpan, keySpan, valueSpan));
|
|
25303
25311
|
}
|
|
25304
25312
|
}
|
|
25305
|
-
parsePropertyBinding(name, expression, isHost, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, targetProps, keySpan) {
|
|
25313
|
+
parsePropertyBinding(name, expression, isHost, isPartOfAssignmentBinding, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs, targetProps, keySpan) {
|
|
25306
25314
|
if (name.length === 0) {
|
|
25307
25315
|
this._reportError(`Property name is missing in binding`, sourceSpan);
|
|
25308
25316
|
}
|
|
@@ -25325,20 +25333,20 @@ class BindingParser {
|
|
|
25325
25333
|
this._parseAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25326
25334
|
}
|
|
25327
25335
|
else {
|
|
25328
|
-
this._parsePropertyAst(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25336
|
+
this._parsePropertyAst(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), isPartOfAssignmentBinding, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25329
25337
|
}
|
|
25330
25338
|
}
|
|
25331
25339
|
parsePropertyInterpolation(name, value, sourceSpan, valueSpan, targetMatchableAttrs, targetProps, keySpan, interpolatedTokens) {
|
|
25332
25340
|
const expr = this.parseInterpolation(value, valueSpan || sourceSpan, interpolatedTokens);
|
|
25333
25341
|
if (expr) {
|
|
25334
|
-
this._parsePropertyAst(name, expr, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25342
|
+
this._parsePropertyAst(name, expr, false, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
25335
25343
|
return true;
|
|
25336
25344
|
}
|
|
25337
25345
|
return false;
|
|
25338
25346
|
}
|
|
25339
|
-
_parsePropertyAst(name, ast, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
25347
|
+
_parsePropertyAst(name, ast, isPartOfAssignmentBinding, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
25340
25348
|
targetMatchableAttrs.push([name, ast.source]);
|
|
25341
|
-
targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan));
|
|
25349
|
+
targetProps.push(new ParsedProperty(name, ast, isPartOfAssignmentBinding ? ParsedPropertyType.TWO_WAY : ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan));
|
|
25342
25350
|
}
|
|
25343
25351
|
_parseAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
25344
25352
|
if (name.length === 0) {
|
|
@@ -25408,7 +25416,8 @@ class BindingParser {
|
|
|
25408
25416
|
const mappedPropName = this._schemaRegistry.getMappedPropName(boundProp.name);
|
|
25409
25417
|
boundPropertyName = mapPropertyName ? mappedPropName : boundProp.name;
|
|
25410
25418
|
securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, mappedPropName, false);
|
|
25411
|
-
bindingType =
|
|
25419
|
+
bindingType =
|
|
25420
|
+
boundProp.type === ParsedPropertyType.TWO_WAY ? 5 /* BindingType.TwoWay */ : 0 /* BindingType.Property */;
|
|
25412
25421
|
if (!skipValidation) {
|
|
25413
25422
|
this._validatePropertyOrAttributeName(mappedPropName, boundProp.sourceSpan, false);
|
|
25414
25423
|
}
|
|
@@ -25458,7 +25467,7 @@ class BindingParser {
|
|
|
25458
25467
|
const [target, eventName] = splitAtColon(name, [null, name]);
|
|
25459
25468
|
const ast = this._parseAction(expression, isAssignmentEvent, handlerSpan);
|
|
25460
25469
|
targetMatchableAttrs.push([name, ast.source]);
|
|
25461
|
-
targetEvents.push(new ParsedEvent(eventName, target, 0 /* ParsedEventType.Regular */, ast, sourceSpan, handlerSpan, keySpan));
|
|
25470
|
+
targetEvents.push(new ParsedEvent(eventName, target, isAssignmentEvent ? 2 /* ParsedEventType.TwoWay */ : 0 /* ParsedEventType.Regular */, ast, sourceSpan, handlerSpan, keySpan));
|
|
25462
25471
|
// Don't detect directives for event names for now,
|
|
25463
25472
|
// so don't add the event name to the matchableAttrs
|
|
25464
25473
|
}
|
|
@@ -25633,11 +25642,16 @@ const FOR_LOOP_EXPRESSION_PATTERN = /^\s*([0-9A-Za-z_$]*)\s+of\s+([\S\s]*)/;
|
|
|
25633
25642
|
/** Pattern for the tracking expression in a for loop block. */
|
|
25634
25643
|
const FOR_LOOP_TRACK_PATTERN = /^track\s+([\S\s]*)/;
|
|
25635
25644
|
/** Pattern for the `as` expression in a conditional block. */
|
|
25636
|
-
const CONDITIONAL_ALIAS_PATTERN = /^as\s+(.*)/;
|
|
25645
|
+
const CONDITIONAL_ALIAS_PATTERN = /^(as\s)+(.*)/;
|
|
25637
25646
|
/** Pattern used to identify an `else if` block. */
|
|
25638
25647
|
const ELSE_IF_PATTERN = /^else[^\S\r\n]+if/;
|
|
25639
25648
|
/** Pattern used to identify a `let` parameter. */
|
|
25640
25649
|
const FOR_LOOP_LET_PATTERN = /^let\s+([\S\s]*)/;
|
|
25650
|
+
/**
|
|
25651
|
+
* Pattern to group a string into leading whitespace, non whitespace, and trailing whitespace.
|
|
25652
|
+
* Useful for getting the variable name span when a span can contain leading and trailing space.
|
|
25653
|
+
*/
|
|
25654
|
+
const CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN = /(\s*)(\S+)(\s*)/;
|
|
25641
25655
|
/** Names of variables that are allowed to be used in the `let` expression of a `for` loop. */
|
|
25642
25656
|
const ALLOWED_FOR_LOOP_LET_VARIABLES = new Set(['$index', '$first', '$last', '$even', '$odd', '$count']);
|
|
25643
25657
|
/**
|
|
@@ -25777,8 +25791,13 @@ function parseForLoopParameters(block, errors, bindingParser) {
|
|
|
25777
25791
|
return null;
|
|
25778
25792
|
}
|
|
25779
25793
|
const [, itemName, rawExpression] = match;
|
|
25794
|
+
// `expressionParam.expression` contains the variable declaration and the expression of the
|
|
25795
|
+
// for...of statement, i.e. 'user of users' The variable of a ForOfStatement is _only_ the "const
|
|
25796
|
+
// user" part and does not include "of x".
|
|
25797
|
+
const variableName = expressionParam.expression.split(' ')[0];
|
|
25798
|
+
const variableSpan = new ParseSourceSpan(expressionParam.sourceSpan.start, expressionParam.sourceSpan.start.moveBy(variableName.length));
|
|
25780
25799
|
const result = {
|
|
25781
|
-
itemName: new Variable(itemName, '$implicit',
|
|
25800
|
+
itemName: new Variable(itemName, '$implicit', variableSpan, variableSpan),
|
|
25782
25801
|
trackBy: null,
|
|
25783
25802
|
expression: parseBlockParameterToBinding(expressionParam, bindingParser, rawExpression),
|
|
25784
25803
|
context: {},
|
|
@@ -25786,7 +25805,8 @@ function parseForLoopParameters(block, errors, bindingParser) {
|
|
|
25786
25805
|
for (const param of secondaryParams) {
|
|
25787
25806
|
const letMatch = param.expression.match(FOR_LOOP_LET_PATTERN);
|
|
25788
25807
|
if (letMatch !== null) {
|
|
25789
|
-
|
|
25808
|
+
const variablesSpan = new ParseSourceSpan(param.sourceSpan.start.moveBy(letMatch[0].length - letMatch[1].length), param.sourceSpan.end);
|
|
25809
|
+
parseLetParameter(param.sourceSpan, letMatch[1], variablesSpan, result.context, errors);
|
|
25790
25810
|
continue;
|
|
25791
25811
|
}
|
|
25792
25812
|
const trackMatch = param.expression.match(FOR_LOOP_TRACK_PATTERN);
|
|
@@ -25817,6 +25837,7 @@ function parseForLoopParameters(block, errors, bindingParser) {
|
|
|
25817
25837
|
/** Parses the `let` parameter of a `for` loop block. */
|
|
25818
25838
|
function parseLetParameter(sourceSpan, expression, span, context, errors) {
|
|
25819
25839
|
const parts = expression.split(',');
|
|
25840
|
+
let startSpan = span.start;
|
|
25820
25841
|
for (const part of parts) {
|
|
25821
25842
|
const expressionParts = part.split('=');
|
|
25822
25843
|
const name = expressionParts.length === 2 ? expressionParts[0].trim() : '';
|
|
@@ -25831,8 +25852,26 @@ function parseLetParameter(sourceSpan, expression, span, context, errors) {
|
|
|
25831
25852
|
errors.push(new ParseError(sourceSpan, `Duplicate "let" parameter variable "${variableName}"`));
|
|
25832
25853
|
}
|
|
25833
25854
|
else {
|
|
25834
|
-
|
|
25855
|
+
const [, keyLeadingWhitespace, keyName] = expressionParts[0].match(CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN) ?? [];
|
|
25856
|
+
const keySpan = keyLeadingWhitespace !== undefined && expressionParts.length === 2 ?
|
|
25857
|
+
new ParseSourceSpan(
|
|
25858
|
+
/* strip leading spaces */
|
|
25859
|
+
startSpan.moveBy(keyLeadingWhitespace.length),
|
|
25860
|
+
/* advance to end of the variable name */
|
|
25861
|
+
startSpan.moveBy(keyLeadingWhitespace.length + keyName.length)) :
|
|
25862
|
+
span;
|
|
25863
|
+
let valueSpan = undefined;
|
|
25864
|
+
if (expressionParts.length === 2) {
|
|
25865
|
+
const [, valueLeadingWhitespace, implicit] = expressionParts[1].match(CHARACTERS_IN_SURROUNDING_WHITESPACE_PATTERN) ?? [];
|
|
25866
|
+
valueSpan = valueLeadingWhitespace !== undefined ?
|
|
25867
|
+
new ParseSourceSpan(startSpan.moveBy(expressionParts[0].length + 1 + valueLeadingWhitespace.length), startSpan.moveBy(expressionParts[0].length + 1 + valueLeadingWhitespace.length +
|
|
25868
|
+
implicit.length)) :
|
|
25869
|
+
undefined;
|
|
25870
|
+
}
|
|
25871
|
+
const sourceSpan = new ParseSourceSpan(keySpan.start, valueSpan?.end ?? keySpan.end);
|
|
25872
|
+
context[variableName] = new Variable(name, variableName, sourceSpan, keySpan, valueSpan);
|
|
25835
25873
|
}
|
|
25874
|
+
startSpan = startSpan.moveBy(part.length + 1 /* add 1 to move past the comma */);
|
|
25836
25875
|
}
|
|
25837
25876
|
}
|
|
25838
25877
|
/**
|
|
@@ -25944,8 +25983,10 @@ function parseConditionalBlockParameters(block, errors, bindingParser) {
|
|
|
25944
25983
|
errors.push(new ParseError(param.sourceSpan, 'Conditional can only have one "as" expression'));
|
|
25945
25984
|
}
|
|
25946
25985
|
else {
|
|
25947
|
-
const name = aliasMatch[
|
|
25948
|
-
|
|
25986
|
+
const name = aliasMatch[2].trim();
|
|
25987
|
+
const variableStart = param.sourceSpan.start.moveBy(aliasMatch[1].length);
|
|
25988
|
+
const variableSpan = new ParseSourceSpan(variableStart, variableStart.moveBy(name.length));
|
|
25989
|
+
expressionAlias = new Variable(name, name, variableSpan, variableSpan);
|
|
25949
25990
|
}
|
|
25950
25991
|
}
|
|
25951
25992
|
return { expression, expressionAlias };
|
|
@@ -26806,7 +26847,7 @@ class HtmlAstToIvyAst {
|
|
|
26806
26847
|
if (bindParts[KW_BIND_IDX] != null) {
|
|
26807
26848
|
const identifier = bindParts[IDENT_KW_IDX];
|
|
26808
26849
|
const keySpan = createKeySpan(srcSpan, bindParts[KW_BIND_IDX], identifier);
|
|
26809
|
-
this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
26850
|
+
this.bindingParser.parsePropertyBinding(identifier, value, false, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
26810
26851
|
}
|
|
26811
26852
|
else if (bindParts[KW_LET_IDX]) {
|
|
26812
26853
|
if (isTemplateElement) {
|
|
@@ -26833,7 +26874,7 @@ class HtmlAstToIvyAst {
|
|
|
26833
26874
|
else if (bindParts[KW_BINDON_IDX]) {
|
|
26834
26875
|
const identifier = bindParts[IDENT_KW_IDX];
|
|
26835
26876
|
const keySpan = createKeySpan(srcSpan, bindParts[KW_BINDON_IDX], identifier);
|
|
26836
|
-
this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
26877
|
+
this.bindingParser.parsePropertyBinding(identifier, value, false, true, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
26837
26878
|
this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan);
|
|
26838
26879
|
}
|
|
26839
26880
|
else if (bindParts[KW_AT_IDX]) {
|
|
@@ -26863,11 +26904,11 @@ class HtmlAstToIvyAst {
|
|
|
26863
26904
|
const identifier = name.substring(delims.start.length, name.length - delims.end.length);
|
|
26864
26905
|
const keySpan = createKeySpan(srcSpan, delims.start, identifier);
|
|
26865
26906
|
if (delims.start === BINDING_DELIMS.BANANA_BOX.start) {
|
|
26866
|
-
this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
26907
|
+
this.bindingParser.parsePropertyBinding(identifier, value, false, true, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
26867
26908
|
this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan);
|
|
26868
26909
|
}
|
|
26869
26910
|
else if (delims.start === BINDING_DELIMS.PROPERTY.start) {
|
|
26870
|
-
this.bindingParser.parsePropertyBinding(identifier, value, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
26911
|
+
this.bindingParser.parsePropertyBinding(identifier, value, false, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
26871
26912
|
}
|
|
26872
26913
|
else {
|
|
26873
26914
|
const events = [];
|
|
@@ -28265,7 +28306,8 @@ class TemplateDefinitionBuilder {
|
|
|
28265
28306
|
element.inputs.forEach(input => {
|
|
28266
28307
|
const stylingInputWasSet = stylingBuilder.registerBoundInput(input);
|
|
28267
28308
|
if (!stylingInputWasSet) {
|
|
28268
|
-
if (input.type === 0 /* BindingType.Property */
|
|
28309
|
+
if ((input.type === 0 /* BindingType.Property */ || input.type === 5 /* BindingType.TwoWay */) &&
|
|
28310
|
+
input.i18n) {
|
|
28269
28311
|
boundI18nAttrs.push(input);
|
|
28270
28312
|
}
|
|
28271
28313
|
else {
|
|
@@ -28391,7 +28433,7 @@ class TemplateDefinitionBuilder {
|
|
|
28391
28433
|
}
|
|
28392
28434
|
}
|
|
28393
28435
|
this.allocateBindingSlots(value);
|
|
28394
|
-
if (inputType === 0 /* BindingType.Property */) {
|
|
28436
|
+
if (inputType === 0 /* BindingType.Property */ || inputType === 5 /* BindingType.TwoWay */) {
|
|
28395
28437
|
if (value instanceof Interpolation$1) {
|
|
28396
28438
|
// prop="{{value}}" and friends
|
|
28397
28439
|
this.interpolatedUpdateInstruction(getPropertyInterpolationExpression(value), elementIndex, attrName, input, value, params);
|
|
@@ -30321,16 +30363,16 @@ function compileComponentFromMetadata(meta, constantPool, bindingParser) {
|
|
|
30321
30363
|
// e.g. `template: function MyComponent_Template(_ctx, _cm) {...}`
|
|
30322
30364
|
const templateTypeName = meta.name;
|
|
30323
30365
|
const templateName = templateTypeName ? `${templateTypeName}_Template` : null;
|
|
30366
|
+
let allDeferrableDepsFn = null;
|
|
30367
|
+
if (meta.deferBlocks.size > 0 && meta.deferrableTypes.size > 0 &&
|
|
30368
|
+
meta.deferBlockDepsEmitMode === 1 /* DeferBlockDepsEmitMode.PerComponent */) {
|
|
30369
|
+
const fnName = `${templateTypeName}_DeferFn`;
|
|
30370
|
+
allDeferrableDepsFn = createDeferredDepsFunction(constantPool, fnName, meta.deferrableTypes);
|
|
30371
|
+
}
|
|
30324
30372
|
// Template compilation is currently conditional as we're in the process of rewriting it.
|
|
30325
|
-
if (!USE_TEMPLATE_PIPELINE) {
|
|
30373
|
+
if (!USE_TEMPLATE_PIPELINE && !meta.useTemplatePipeline) {
|
|
30326
30374
|
// This is the main path currently used in compilation, which compiles the template with the
|
|
30327
30375
|
// legacy `TemplateDefinitionBuilder`.
|
|
30328
|
-
let allDeferrableDepsFn = null;
|
|
30329
|
-
if (meta.deferBlocks.size > 0 && meta.deferrableTypes.size > 0 &&
|
|
30330
|
-
meta.deferBlockDepsEmitMode === 1 /* DeferBlockDepsEmitMode.PerComponent */) {
|
|
30331
|
-
const fnName = `${templateTypeName}_DeferFn`;
|
|
30332
|
-
allDeferrableDepsFn = createDeferredDepsFunction(constantPool, fnName, meta.deferrableTypes);
|
|
30333
|
-
}
|
|
30334
30376
|
const template = meta.template;
|
|
30335
30377
|
const templateBuilder = new TemplateDefinitionBuilder(constantPool, BindingScope.createRootScope(), 0, templateTypeName, null, null, templateName, Identifiers.namespaceHTML, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.deferBlocks, new Map(), allDeferrableDepsFn);
|
|
30336
30378
|
const templateFunctionExpression = templateBuilder.buildTemplateFunction(template.nodes, []);
|
|
@@ -30367,7 +30409,7 @@ function compileComponentFromMetadata(meta, constantPool, bindingParser) {
|
|
|
30367
30409
|
else {
|
|
30368
30410
|
// This path compiles the template using the prototype template pipeline. First the template is
|
|
30369
30411
|
// ingested into IR:
|
|
30370
|
-
const tpl = ingestComponent(meta.name, meta.template.nodes, constantPool, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.deferBlocks);
|
|
30412
|
+
const tpl = ingestComponent(meta.name, meta.template.nodes, constantPool, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.deferBlocks, allDeferrableDepsFn);
|
|
30371
30413
|
// Then the IR is transformed to prepare it for cod egeneration.
|
|
30372
30414
|
transform(tpl, CompilationJobKind.Tmpl);
|
|
30373
30415
|
// Finally we emit the template function:
|
|
@@ -30562,7 +30604,7 @@ function createHostBindingsFunction(hostBindingsMetadata, typeSourceSpan, bindin
|
|
|
30562
30604
|
const bindings = bindingParser.createBoundHostProperties(hostBindingsMetadata.properties, typeSourceSpan);
|
|
30563
30605
|
// Calculate host event bindings
|
|
30564
30606
|
const eventBindings = bindingParser.createDirectiveHostEventAsts(hostBindingsMetadata.listeners, typeSourceSpan);
|
|
30565
|
-
if (USE_TEMPLATE_PIPELINE) {
|
|
30607
|
+
if (USE_TEMPLATE_PIPELINE || hostBindingsMetadata.useTemplatePipeline) {
|
|
30566
30608
|
// The parser for host bindings treats class and style attributes specially -- they are
|
|
30567
30609
|
// extracted into these separate fields. This is not the case for templates, so the compiler can
|
|
30568
30610
|
// actually already handle these special attributes internally. Therefore, we just drop them
|
|
@@ -31746,6 +31788,7 @@ function extractScopedNodeEntities(rootScope) {
|
|
|
31746
31788
|
class ResourceLoader {
|
|
31747
31789
|
}
|
|
31748
31790
|
|
|
31791
|
+
const SHOULD_USE_TEMPLATE_PIPELINE_FOR_JIT = false;
|
|
31749
31792
|
class CompilerFacadeImpl {
|
|
31750
31793
|
constructor(jitEvaluator = new JitEvaluator()) {
|
|
31751
31794
|
this.jitEvaluator = jitEvaluator;
|
|
@@ -31879,6 +31922,7 @@ class CompilerFacadeImpl {
|
|
|
31879
31922
|
null,
|
|
31880
31923
|
relativeContextFilePath: '',
|
|
31881
31924
|
i18nUseExternalIds: true,
|
|
31925
|
+
useTemplatePipeline: SHOULD_USE_TEMPLATE_PIPELINE_FOR_JIT,
|
|
31882
31926
|
};
|
|
31883
31927
|
const jitExpressionSourceMap = `ng:///${facade.name}.js`;
|
|
31884
31928
|
return this.compileComponentFromMeta(angularCoreEnv, jitExpressionSourceMap, meta);
|
|
@@ -32001,7 +32045,10 @@ function convertDirectiveFacadeToMetadata(facade) {
|
|
|
32001
32045
|
typeSourceSpan: facade.typeSourceSpan,
|
|
32002
32046
|
type: wrapReference(facade.type),
|
|
32003
32047
|
deps: null,
|
|
32004
|
-
host:
|
|
32048
|
+
host: {
|
|
32049
|
+
...extractHostBindings(facade.propMetadata, facade.typeSourceSpan, facade.host),
|
|
32050
|
+
useTemplatePipeline: SHOULD_USE_TEMPLATE_PIPELINE_FOR_JIT,
|
|
32051
|
+
},
|
|
32005
32052
|
inputs: { ...inputsFromMetadata, ...inputsFromType },
|
|
32006
32053
|
outputs: { ...outputsFromMetadata, ...outputsFromType },
|
|
32007
32054
|
queries: facade.queries.map(convertToR3QueryMetadata),
|
|
@@ -32044,6 +32091,7 @@ function convertHostDeclarationToMetadata(host = {}) {
|
|
|
32044
32091
|
classAttr: host.classAttribute,
|
|
32045
32092
|
styleAttr: host.styleAttribute,
|
|
32046
32093
|
},
|
|
32094
|
+
useTemplatePipeline: SHOULD_USE_TEMPLATE_PIPELINE_FOR_JIT,
|
|
32047
32095
|
};
|
|
32048
32096
|
}
|
|
32049
32097
|
function convertHostDirectivesToMetadata(metadata) {
|
|
@@ -32116,6 +32164,7 @@ function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMap
|
|
|
32116
32164
|
declarationListEmitMode: 2 /* DeclarationListEmitMode.ClosureResolved */,
|
|
32117
32165
|
relativeContextFilePath: '',
|
|
32118
32166
|
i18nUseExternalIds: true,
|
|
32167
|
+
useTemplatePipeline: SHOULD_USE_TEMPLATE_PIPELINE_FOR_JIT,
|
|
32119
32168
|
};
|
|
32120
32169
|
}
|
|
32121
32170
|
function convertDeclarationFacadeToMetadata(declaration) {
|
|
@@ -32397,7 +32446,7 @@ function publishFacade(global) {
|
|
|
32397
32446
|
* @description
|
|
32398
32447
|
* Entry point for all public APIs of the compiler package.
|
|
32399
32448
|
*/
|
|
32400
|
-
const VERSION = new Version('17.2.0-next.
|
|
32449
|
+
const VERSION = new Version('17.2.0-next.1');
|
|
32401
32450
|
|
|
32402
32451
|
class CompilerConfig {
|
|
32403
32452
|
constructor({ defaultEncapsulation = ViewEncapsulation.Emulated, preserveWhitespaces, strictInjectionParameters } = {}) {
|
|
@@ -33963,7 +34012,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$5 = '12.0.0';
|
|
|
33963
34012
|
function compileDeclareClassMetadata(metadata) {
|
|
33964
34013
|
const definitionMap = new DefinitionMap();
|
|
33965
34014
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
33966
|
-
definitionMap.set('version', literal('17.2.0-next.
|
|
34015
|
+
definitionMap.set('version', literal('17.2.0-next.1'));
|
|
33967
34016
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
33968
34017
|
definitionMap.set('type', metadata.type);
|
|
33969
34018
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -34059,7 +34108,7 @@ function createDirectiveDefinitionMap(meta) {
|
|
|
34059
34108
|
const definitionMap = new DefinitionMap();
|
|
34060
34109
|
const minVersion = getMinimumVersionForPartialOutput(meta);
|
|
34061
34110
|
definitionMap.set('minVersion', literal(minVersion));
|
|
34062
|
-
definitionMap.set('version', literal('17.2.0-next.
|
|
34111
|
+
definitionMap.set('version', literal('17.2.0-next.1'));
|
|
34063
34112
|
// e.g. `type: MyDirective`
|
|
34064
34113
|
definitionMap.set('type', meta.type.value);
|
|
34065
34114
|
if (meta.isStandalone) {
|
|
@@ -34451,7 +34500,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
|
|
|
34451
34500
|
function compileDeclareFactoryFunction(meta) {
|
|
34452
34501
|
const definitionMap = new DefinitionMap();
|
|
34453
34502
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
34454
|
-
definitionMap.set('version', literal('17.2.0-next.
|
|
34503
|
+
definitionMap.set('version', literal('17.2.0-next.1'));
|
|
34455
34504
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
34456
34505
|
definitionMap.set('type', meta.type.value);
|
|
34457
34506
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -34486,7 +34535,7 @@ function compileDeclareInjectableFromMetadata(meta) {
|
|
|
34486
34535
|
function createInjectableDefinitionMap(meta) {
|
|
34487
34536
|
const definitionMap = new DefinitionMap();
|
|
34488
34537
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
34489
|
-
definitionMap.set('version', literal('17.2.0-next.
|
|
34538
|
+
definitionMap.set('version', literal('17.2.0-next.1'));
|
|
34490
34539
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
34491
34540
|
definitionMap.set('type', meta.type.value);
|
|
34492
34541
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -34537,7 +34586,7 @@ function compileDeclareInjectorFromMetadata(meta) {
|
|
|
34537
34586
|
function createInjectorDefinitionMap(meta) {
|
|
34538
34587
|
const definitionMap = new DefinitionMap();
|
|
34539
34588
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
34540
|
-
definitionMap.set('version', literal('17.2.0-next.
|
|
34589
|
+
definitionMap.set('version', literal('17.2.0-next.1'));
|
|
34541
34590
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
34542
34591
|
definitionMap.set('type', meta.type.value);
|
|
34543
34592
|
definitionMap.set('providers', meta.providers);
|
|
@@ -34570,7 +34619,7 @@ function createNgModuleDefinitionMap(meta) {
|
|
|
34570
34619
|
throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
|
|
34571
34620
|
}
|
|
34572
34621
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
34573
|
-
definitionMap.set('version', literal('17.2.0-next.
|
|
34622
|
+
definitionMap.set('version', literal('17.2.0-next.1'));
|
|
34574
34623
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
34575
34624
|
definitionMap.set('type', meta.type.value);
|
|
34576
34625
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -34621,7 +34670,7 @@ function compileDeclarePipeFromMetadata(meta) {
|
|
|
34621
34670
|
function createPipeDefinitionMap(meta) {
|
|
34622
34671
|
const definitionMap = new DefinitionMap();
|
|
34623
34672
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
34624
|
-
definitionMap.set('version', literal('17.2.0-next.
|
|
34673
|
+
definitionMap.set('version', literal('17.2.0-next.1'));
|
|
34625
34674
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
34626
34675
|
// e.g. `type: MyPipe`
|
|
34627
34676
|
definitionMap.set('type', meta.type.value);
|