@angular-eslint/bundled-angular-compiler 18.0.2-alpha.0 → 18.0.2-alpha.10
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/dist/index.js +528 -77
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @license Angular v18.0.
|
|
4
|
+
* @license Angular v18.0.5
|
|
5
5
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
6
6
|
* License: MIT
|
|
7
7
|
*/
|
|
@@ -2886,6 +2886,9 @@ class Identifiers {
|
|
|
2886
2886
|
static { this.twoWayProperty = { name: 'ɵɵtwoWayProperty', moduleName: CORE }; }
|
|
2887
2887
|
static { this.twoWayBindingSet = { name: 'ɵɵtwoWayBindingSet', moduleName: CORE }; }
|
|
2888
2888
|
static { this.twoWayListener = { name: 'ɵɵtwoWayListener', moduleName: CORE }; }
|
|
2889
|
+
static { this.declareLet = { name: 'ɵɵdeclareLet', moduleName: CORE }; }
|
|
2890
|
+
static { this.storeLet = { name: 'ɵɵstoreLet', moduleName: CORE }; }
|
|
2891
|
+
static { this.readContextLet = { name: 'ɵɵreadContextLet', moduleName: CORE }; }
|
|
2889
2892
|
static { this.NgOnChangesFeature = { name: 'ɵɵNgOnChangesFeature', moduleName: CORE }; }
|
|
2890
2893
|
static { this.InheritDefinitionFeature = {
|
|
2891
2894
|
name: 'ɵɵInheritDefinitionFeature',
|
|
@@ -5053,6 +5056,18 @@ class UnknownBlock {
|
|
|
5053
5056
|
return visitor.visitUnknownBlock(this);
|
|
5054
5057
|
}
|
|
5055
5058
|
}
|
|
5059
|
+
class LetDeclaration$1 {
|
|
5060
|
+
constructor(name, value, sourceSpan, nameSpan, valueSpan) {
|
|
5061
|
+
this.name = name;
|
|
5062
|
+
this.value = value;
|
|
5063
|
+
this.sourceSpan = sourceSpan;
|
|
5064
|
+
this.nameSpan = nameSpan;
|
|
5065
|
+
this.valueSpan = valueSpan;
|
|
5066
|
+
}
|
|
5067
|
+
visit(visitor) {
|
|
5068
|
+
return visitor.visitLetDeclaration(this);
|
|
5069
|
+
}
|
|
5070
|
+
}
|
|
5056
5071
|
class Template {
|
|
5057
5072
|
constructor(
|
|
5058
5073
|
// tagName is the name of the container element, if applicable.
|
|
@@ -5188,6 +5203,7 @@ class RecursiveVisitor$1 {
|
|
|
5188
5203
|
visitIcu(icu) { }
|
|
5189
5204
|
visitDeferredTrigger(trigger) { }
|
|
5190
5205
|
visitUnknownBlock(block) { }
|
|
5206
|
+
visitLetDeclaration(decl) { }
|
|
5191
5207
|
}
|
|
5192
5208
|
function visitAll$1(visitor, nodes) {
|
|
5193
5209
|
const result = [];
|
|
@@ -8191,46 +8207,54 @@ var OpKind;
|
|
|
8191
8207
|
* An operation declaring the event side of a two-way binding.
|
|
8192
8208
|
*/
|
|
8193
8209
|
OpKind[OpKind["TwoWayListener"] = 37] = "TwoWayListener";
|
|
8210
|
+
/**
|
|
8211
|
+
* A creation-time operation that initializes the slot for a `@let` declaration.
|
|
8212
|
+
*/
|
|
8213
|
+
OpKind[OpKind["DeclareLet"] = 38] = "DeclareLet";
|
|
8214
|
+
/**
|
|
8215
|
+
* An update-time operation that stores the current value of a `@let` declaration.
|
|
8216
|
+
*/
|
|
8217
|
+
OpKind[OpKind["StoreLet"] = 39] = "StoreLet";
|
|
8194
8218
|
/**
|
|
8195
8219
|
* The start of an i18n block.
|
|
8196
8220
|
*/
|
|
8197
|
-
OpKind[OpKind["I18nStart"] =
|
|
8221
|
+
OpKind[OpKind["I18nStart"] = 40] = "I18nStart";
|
|
8198
8222
|
/**
|
|
8199
8223
|
* A self-closing i18n on a single element.
|
|
8200
8224
|
*/
|
|
8201
|
-
OpKind[OpKind["I18n"] =
|
|
8225
|
+
OpKind[OpKind["I18n"] = 41] = "I18n";
|
|
8202
8226
|
/**
|
|
8203
8227
|
* The end of an i18n block.
|
|
8204
8228
|
*/
|
|
8205
|
-
OpKind[OpKind["I18nEnd"] =
|
|
8229
|
+
OpKind[OpKind["I18nEnd"] = 42] = "I18nEnd";
|
|
8206
8230
|
/**
|
|
8207
8231
|
* An expression in an i18n message.
|
|
8208
8232
|
*/
|
|
8209
|
-
OpKind[OpKind["I18nExpression"] =
|
|
8233
|
+
OpKind[OpKind["I18nExpression"] = 43] = "I18nExpression";
|
|
8210
8234
|
/**
|
|
8211
8235
|
* An instruction that applies a set of i18n expressions.
|
|
8212
8236
|
*/
|
|
8213
|
-
OpKind[OpKind["I18nApply"] =
|
|
8237
|
+
OpKind[OpKind["I18nApply"] = 44] = "I18nApply";
|
|
8214
8238
|
/**
|
|
8215
8239
|
* An instruction to create an ICU expression.
|
|
8216
8240
|
*/
|
|
8217
|
-
OpKind[OpKind["IcuStart"] =
|
|
8241
|
+
OpKind[OpKind["IcuStart"] = 45] = "IcuStart";
|
|
8218
8242
|
/**
|
|
8219
8243
|
* An instruction to update an ICU expression.
|
|
8220
8244
|
*/
|
|
8221
|
-
OpKind[OpKind["IcuEnd"] =
|
|
8245
|
+
OpKind[OpKind["IcuEnd"] = 46] = "IcuEnd";
|
|
8222
8246
|
/**
|
|
8223
8247
|
* An instruction representing a placeholder in an ICU expression.
|
|
8224
8248
|
*/
|
|
8225
|
-
OpKind[OpKind["IcuPlaceholder"] =
|
|
8249
|
+
OpKind[OpKind["IcuPlaceholder"] = 47] = "IcuPlaceholder";
|
|
8226
8250
|
/**
|
|
8227
8251
|
* An i18n context containing information needed to generate an i18n message.
|
|
8228
8252
|
*/
|
|
8229
|
-
OpKind[OpKind["I18nContext"] =
|
|
8253
|
+
OpKind[OpKind["I18nContext"] = 48] = "I18nContext";
|
|
8230
8254
|
/**
|
|
8231
8255
|
* A creation op that corresponds to i18n attributes on an element.
|
|
8232
8256
|
*/
|
|
8233
|
-
OpKind[OpKind["I18nAttributes"] =
|
|
8257
|
+
OpKind[OpKind["I18nAttributes"] = 49] = "I18nAttributes";
|
|
8234
8258
|
})(OpKind || (OpKind = {}));
|
|
8235
8259
|
/**
|
|
8236
8260
|
* Distinguishes different kinds of IR expressions.
|
|
@@ -8261,78 +8285,86 @@ var ExpressionKind;
|
|
|
8261
8285
|
* Runtime operation to retrieve the value of a local reference.
|
|
8262
8286
|
*/
|
|
8263
8287
|
ExpressionKind[ExpressionKind["Reference"] = 5] = "Reference";
|
|
8288
|
+
/**
|
|
8289
|
+
* A call storing the value of a `@let` declaration.
|
|
8290
|
+
*/
|
|
8291
|
+
ExpressionKind[ExpressionKind["StoreLet"] = 6] = "StoreLet";
|
|
8292
|
+
/**
|
|
8293
|
+
* A reference to a `@let` declaration read from the context view.
|
|
8294
|
+
*/
|
|
8295
|
+
ExpressionKind[ExpressionKind["ContextLetReference"] = 7] = "ContextLetReference";
|
|
8264
8296
|
/**
|
|
8265
8297
|
* Runtime operation to snapshot the current view context.
|
|
8266
8298
|
*/
|
|
8267
|
-
ExpressionKind[ExpressionKind["GetCurrentView"] =
|
|
8299
|
+
ExpressionKind[ExpressionKind["GetCurrentView"] = 8] = "GetCurrentView";
|
|
8268
8300
|
/**
|
|
8269
8301
|
* Runtime operation to restore a snapshotted view.
|
|
8270
8302
|
*/
|
|
8271
|
-
ExpressionKind[ExpressionKind["RestoreView"] =
|
|
8303
|
+
ExpressionKind[ExpressionKind["RestoreView"] = 9] = "RestoreView";
|
|
8272
8304
|
/**
|
|
8273
8305
|
* Runtime operation to reset the current view context after `RestoreView`.
|
|
8274
8306
|
*/
|
|
8275
|
-
ExpressionKind[ExpressionKind["ResetView"] =
|
|
8307
|
+
ExpressionKind[ExpressionKind["ResetView"] = 10] = "ResetView";
|
|
8276
8308
|
/**
|
|
8277
8309
|
* Defines and calls a function with change-detected arguments.
|
|
8278
8310
|
*/
|
|
8279
|
-
ExpressionKind[ExpressionKind["PureFunctionExpr"] =
|
|
8311
|
+
ExpressionKind[ExpressionKind["PureFunctionExpr"] = 11] = "PureFunctionExpr";
|
|
8280
8312
|
/**
|
|
8281
8313
|
* Indicates a positional parameter to a pure function definition.
|
|
8282
8314
|
*/
|
|
8283
|
-
ExpressionKind[ExpressionKind["PureFunctionParameterExpr"] =
|
|
8315
|
+
ExpressionKind[ExpressionKind["PureFunctionParameterExpr"] = 12] = "PureFunctionParameterExpr";
|
|
8284
8316
|
/**
|
|
8285
8317
|
* Binding to a pipe transformation.
|
|
8286
8318
|
*/
|
|
8287
|
-
ExpressionKind[ExpressionKind["PipeBinding"] =
|
|
8319
|
+
ExpressionKind[ExpressionKind["PipeBinding"] = 13] = "PipeBinding";
|
|
8288
8320
|
/**
|
|
8289
8321
|
* Binding to a pipe transformation with a variable number of arguments.
|
|
8290
8322
|
*/
|
|
8291
|
-
ExpressionKind[ExpressionKind["PipeBindingVariadic"] =
|
|
8323
|
+
ExpressionKind[ExpressionKind["PipeBindingVariadic"] = 14] = "PipeBindingVariadic";
|
|
8292
8324
|
/*
|
|
8293
8325
|
* A safe property read requiring expansion into a null check.
|
|
8294
8326
|
*/
|
|
8295
|
-
ExpressionKind[ExpressionKind["SafePropertyRead"] =
|
|
8327
|
+
ExpressionKind[ExpressionKind["SafePropertyRead"] = 15] = "SafePropertyRead";
|
|
8296
8328
|
/**
|
|
8297
8329
|
* A safe keyed read requiring expansion into a null check.
|
|
8298
8330
|
*/
|
|
8299
|
-
ExpressionKind[ExpressionKind["SafeKeyedRead"] =
|
|
8331
|
+
ExpressionKind[ExpressionKind["SafeKeyedRead"] = 16] = "SafeKeyedRead";
|
|
8300
8332
|
/**
|
|
8301
8333
|
* A safe function call requiring expansion into a null check.
|
|
8302
8334
|
*/
|
|
8303
|
-
ExpressionKind[ExpressionKind["SafeInvokeFunction"] =
|
|
8335
|
+
ExpressionKind[ExpressionKind["SafeInvokeFunction"] = 17] = "SafeInvokeFunction";
|
|
8304
8336
|
/**
|
|
8305
8337
|
* An intermediate expression that will be expanded from a safe read into an explicit ternary.
|
|
8306
8338
|
*/
|
|
8307
|
-
ExpressionKind[ExpressionKind["SafeTernaryExpr"] =
|
|
8339
|
+
ExpressionKind[ExpressionKind["SafeTernaryExpr"] = 18] = "SafeTernaryExpr";
|
|
8308
8340
|
/**
|
|
8309
8341
|
* An empty expression that will be stipped before generating the final output.
|
|
8310
8342
|
*/
|
|
8311
|
-
ExpressionKind[ExpressionKind["EmptyExpr"] =
|
|
8343
|
+
ExpressionKind[ExpressionKind["EmptyExpr"] = 19] = "EmptyExpr";
|
|
8312
8344
|
/*
|
|
8313
8345
|
* An assignment to a temporary variable.
|
|
8314
8346
|
*/
|
|
8315
|
-
ExpressionKind[ExpressionKind["AssignTemporaryExpr"] =
|
|
8347
|
+
ExpressionKind[ExpressionKind["AssignTemporaryExpr"] = 20] = "AssignTemporaryExpr";
|
|
8316
8348
|
/**
|
|
8317
8349
|
* A reference to a temporary variable.
|
|
8318
8350
|
*/
|
|
8319
|
-
ExpressionKind[ExpressionKind["ReadTemporaryExpr"] =
|
|
8351
|
+
ExpressionKind[ExpressionKind["ReadTemporaryExpr"] = 21] = "ReadTemporaryExpr";
|
|
8320
8352
|
/**
|
|
8321
8353
|
* An expression that will cause a literal slot index to be emitted.
|
|
8322
8354
|
*/
|
|
8323
|
-
ExpressionKind[ExpressionKind["SlotLiteralExpr"] =
|
|
8355
|
+
ExpressionKind[ExpressionKind["SlotLiteralExpr"] = 22] = "SlotLiteralExpr";
|
|
8324
8356
|
/**
|
|
8325
8357
|
* A test expression for a conditional op.
|
|
8326
8358
|
*/
|
|
8327
|
-
ExpressionKind[ExpressionKind["ConditionalCase"] =
|
|
8359
|
+
ExpressionKind[ExpressionKind["ConditionalCase"] = 23] = "ConditionalCase";
|
|
8328
8360
|
/**
|
|
8329
8361
|
* An expression that will be automatically extracted to the component const array.
|
|
8330
8362
|
*/
|
|
8331
|
-
ExpressionKind[ExpressionKind["ConstCollected"] =
|
|
8363
|
+
ExpressionKind[ExpressionKind["ConstCollected"] = 24] = "ConstCollected";
|
|
8332
8364
|
/**
|
|
8333
8365
|
* Operation that sets the value of a two-way binding.
|
|
8334
8366
|
*/
|
|
8335
|
-
ExpressionKind[ExpressionKind["TwoWayBindingSet"] =
|
|
8367
|
+
ExpressionKind[ExpressionKind["TwoWayBindingSet"] = 25] = "TwoWayBindingSet";
|
|
8336
8368
|
})(ExpressionKind || (ExpressionKind = {}));
|
|
8337
8369
|
var VariableFlags;
|
|
8338
8370
|
(function (VariableFlags) {
|
|
@@ -8553,11 +8585,8 @@ const TRAIT_CONSUMES_VARS = {
|
|
|
8553
8585
|
function hasConsumesSlotTrait(op) {
|
|
8554
8586
|
return op[ConsumesSlot] === true;
|
|
8555
8587
|
}
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
*/
|
|
8559
|
-
function hasDependsOnSlotContextTrait(op) {
|
|
8560
|
-
return op[DependsOnSlotContext] === true;
|
|
8588
|
+
function hasDependsOnSlotContextTrait(value) {
|
|
8589
|
+
return value[DependsOnSlotContext] === true;
|
|
8561
8590
|
}
|
|
8562
8591
|
function hasConsumesVarsTrait(value) {
|
|
8563
8592
|
return value[ConsumesVarsTrait] === true;
|
|
@@ -8855,8 +8884,23 @@ function createI18nApplyOp(owner, handle, sourceSpan) {
|
|
|
8855
8884
|
...NEW_OP,
|
|
8856
8885
|
};
|
|
8857
8886
|
}
|
|
8887
|
+
/**
|
|
8888
|
+
* Creates a `StoreLetOp`.
|
|
8889
|
+
*/
|
|
8890
|
+
function createStoreLetOp(target, declaredName, value, sourceSpan) {
|
|
8891
|
+
return {
|
|
8892
|
+
kind: OpKind.StoreLet,
|
|
8893
|
+
target,
|
|
8894
|
+
declaredName,
|
|
8895
|
+
value,
|
|
8896
|
+
sourceSpan,
|
|
8897
|
+
...TRAIT_DEPENDS_ON_SLOT_CONTEXT,
|
|
8898
|
+
...TRAIT_CONSUMES_VARS,
|
|
8899
|
+
...NEW_OP,
|
|
8900
|
+
};
|
|
8901
|
+
}
|
|
8858
8902
|
|
|
8859
|
-
var _a, _b, _c, _d, _e, _f;
|
|
8903
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
8860
8904
|
/**
|
|
8861
8905
|
* Check whether a given `o.Expression` is a logical IR expression type.
|
|
8862
8906
|
*/
|
|
@@ -8918,6 +8962,50 @@ class ReferenceExpr extends ExpressionBase {
|
|
|
8918
8962
|
return new ReferenceExpr(this.target, this.targetSlot, this.offset);
|
|
8919
8963
|
}
|
|
8920
8964
|
}
|
|
8965
|
+
class StoreLetExpr extends ExpressionBase {
|
|
8966
|
+
static { _a = ConsumesVarsTrait, _b = DependsOnSlotContext; }
|
|
8967
|
+
constructor(target, value, sourceSpan) {
|
|
8968
|
+
super();
|
|
8969
|
+
this.target = target;
|
|
8970
|
+
this.value = value;
|
|
8971
|
+
this.sourceSpan = sourceSpan;
|
|
8972
|
+
this.kind = ExpressionKind.StoreLet;
|
|
8973
|
+
this[_a] = true;
|
|
8974
|
+
this[_b] = true;
|
|
8975
|
+
}
|
|
8976
|
+
visitExpression() { }
|
|
8977
|
+
isEquivalent(e) {
|
|
8978
|
+
return (e instanceof StoreLetExpr && e.target === this.target && e.value.isEquivalent(this.value));
|
|
8979
|
+
}
|
|
8980
|
+
isConstant() {
|
|
8981
|
+
return false;
|
|
8982
|
+
}
|
|
8983
|
+
transformInternalExpressions(transform, flags) {
|
|
8984
|
+
this.value = transformExpressionsInExpression(this.value, transform, flags);
|
|
8985
|
+
}
|
|
8986
|
+
clone() {
|
|
8987
|
+
return new StoreLetExpr(this.target, this.value, this.sourceSpan);
|
|
8988
|
+
}
|
|
8989
|
+
}
|
|
8990
|
+
class ContextLetReferenceExpr extends ExpressionBase {
|
|
8991
|
+
constructor(target, targetSlot) {
|
|
8992
|
+
super();
|
|
8993
|
+
this.target = target;
|
|
8994
|
+
this.targetSlot = targetSlot;
|
|
8995
|
+
this.kind = ExpressionKind.ContextLetReference;
|
|
8996
|
+
}
|
|
8997
|
+
visitExpression() { }
|
|
8998
|
+
isEquivalent(e) {
|
|
8999
|
+
return e instanceof ContextLetReferenceExpr && e.target === this.target;
|
|
9000
|
+
}
|
|
9001
|
+
isConstant() {
|
|
9002
|
+
return false;
|
|
9003
|
+
}
|
|
9004
|
+
transformInternalExpressions() { }
|
|
9005
|
+
clone() {
|
|
9006
|
+
return new ContextLetReferenceExpr(this.target, this.targetSlot);
|
|
9007
|
+
}
|
|
9008
|
+
}
|
|
8921
9009
|
/**
|
|
8922
9010
|
* A reference to the current view context (usually the `ctx` variable in a template function).
|
|
8923
9011
|
*/
|
|
@@ -9118,12 +9206,12 @@ class ReadVariableExpr extends ExpressionBase {
|
|
|
9118
9206
|
}
|
|
9119
9207
|
}
|
|
9120
9208
|
class PureFunctionExpr extends ExpressionBase {
|
|
9121
|
-
static {
|
|
9209
|
+
static { _c = ConsumesVarsTrait, _d = UsesVarOffset; }
|
|
9122
9210
|
constructor(expression, args) {
|
|
9123
9211
|
super();
|
|
9124
9212
|
this.kind = ExpressionKind.PureFunctionExpr;
|
|
9125
|
-
this[
|
|
9126
|
-
this[
|
|
9213
|
+
this[_c] = true;
|
|
9214
|
+
this[_d] = true;
|
|
9127
9215
|
this.varOffset = null;
|
|
9128
9216
|
/**
|
|
9129
9217
|
* Once extracted to the `ConstantPool`, a reference to the function which defines the computation
|
|
@@ -9189,7 +9277,7 @@ class PureFunctionParameterExpr extends ExpressionBase {
|
|
|
9189
9277
|
}
|
|
9190
9278
|
}
|
|
9191
9279
|
class PipeBindingExpr extends ExpressionBase {
|
|
9192
|
-
static {
|
|
9280
|
+
static { _e = ConsumesVarsTrait, _f = UsesVarOffset; }
|
|
9193
9281
|
constructor(target, targetSlot, name, args) {
|
|
9194
9282
|
super();
|
|
9195
9283
|
this.target = target;
|
|
@@ -9197,8 +9285,8 @@ class PipeBindingExpr extends ExpressionBase {
|
|
|
9197
9285
|
this.name = name;
|
|
9198
9286
|
this.args = args;
|
|
9199
9287
|
this.kind = ExpressionKind.PipeBinding;
|
|
9200
|
-
this[
|
|
9201
|
-
this[
|
|
9288
|
+
this[_e] = true;
|
|
9289
|
+
this[_f] = true;
|
|
9202
9290
|
this.varOffset = null;
|
|
9203
9291
|
}
|
|
9204
9292
|
visitExpression(visitor, context) {
|
|
@@ -9224,7 +9312,7 @@ class PipeBindingExpr extends ExpressionBase {
|
|
|
9224
9312
|
}
|
|
9225
9313
|
}
|
|
9226
9314
|
class PipeBindingVariadicExpr extends ExpressionBase {
|
|
9227
|
-
static {
|
|
9315
|
+
static { _g = ConsumesVarsTrait, _h = UsesVarOffset; }
|
|
9228
9316
|
constructor(target, targetSlot, name, args, numArgs) {
|
|
9229
9317
|
super();
|
|
9230
9318
|
this.target = target;
|
|
@@ -9233,8 +9321,8 @@ class PipeBindingVariadicExpr extends ExpressionBase {
|
|
|
9233
9321
|
this.args = args;
|
|
9234
9322
|
this.numArgs = numArgs;
|
|
9235
9323
|
this.kind = ExpressionKind.PipeBindingVariadic;
|
|
9236
|
-
this[
|
|
9237
|
-
this[
|
|
9324
|
+
this[_g] = true;
|
|
9325
|
+
this[_h] = true;
|
|
9238
9326
|
this.varOffset = null;
|
|
9239
9327
|
}
|
|
9240
9328
|
visitExpression(visitor, context) {
|
|
@@ -9628,6 +9716,9 @@ function transformExpressionsInOp(op, transform, flags) {
|
|
|
9628
9716
|
case OpKind.DeferWhen:
|
|
9629
9717
|
op.expr = transformExpressionsInExpression(op.expr, transform, flags);
|
|
9630
9718
|
break;
|
|
9719
|
+
case OpKind.StoreLet:
|
|
9720
|
+
op.value = transformExpressionsInExpression(op.value, transform, flags);
|
|
9721
|
+
break;
|
|
9631
9722
|
case OpKind.Advance:
|
|
9632
9723
|
case OpKind.Container:
|
|
9633
9724
|
case OpKind.ContainerEnd:
|
|
@@ -9653,6 +9744,7 @@ function transformExpressionsInOp(op, transform, flags) {
|
|
|
9653
9744
|
case OpKind.Text:
|
|
9654
9745
|
case OpKind.I18nAttributes:
|
|
9655
9746
|
case OpKind.IcuPlaceholder:
|
|
9747
|
+
case OpKind.DeclareLet:
|
|
9656
9748
|
// These operations contain no expressions.
|
|
9657
9749
|
break;
|
|
9658
9750
|
default:
|
|
@@ -10316,6 +10408,20 @@ function createDeferOnOp(defer, trigger, prefetch, sourceSpan) {
|
|
|
10316
10408
|
...NEW_OP,
|
|
10317
10409
|
};
|
|
10318
10410
|
}
|
|
10411
|
+
/**
|
|
10412
|
+
* Creates a `DeclareLetOp`.
|
|
10413
|
+
*/
|
|
10414
|
+
function createDeclareLetOp(xref, declaredName, sourceSpan) {
|
|
10415
|
+
return {
|
|
10416
|
+
kind: OpKind.DeclareLet,
|
|
10417
|
+
xref,
|
|
10418
|
+
declaredName,
|
|
10419
|
+
sourceSpan,
|
|
10420
|
+
handle: new SlotHandle(),
|
|
10421
|
+
...TRAIT_CONSUMES_SLOT,
|
|
10422
|
+
...NEW_OP,
|
|
10423
|
+
};
|
|
10424
|
+
}
|
|
10319
10425
|
/**
|
|
10320
10426
|
* Create an `ExtractedMessageOp`.
|
|
10321
10427
|
*/
|
|
@@ -11009,6 +11115,7 @@ const CHAINABLE = new Set([
|
|
|
11009
11115
|
Identifiers.templateCreate,
|
|
11010
11116
|
Identifiers.twoWayProperty,
|
|
11011
11117
|
Identifiers.twoWayListener,
|
|
11118
|
+
Identifiers.declareLet,
|
|
11012
11119
|
]);
|
|
11013
11120
|
/**
|
|
11014
11121
|
* Post-process a reified view compilation and convert sequential calls to chainable instructions
|
|
@@ -12174,16 +12281,26 @@ function generateAdvance(job) {
|
|
|
12174
12281
|
// To do that, we track what the runtime's slot counter will be through the update operations.
|
|
12175
12282
|
let slotContext = 0;
|
|
12176
12283
|
for (const op of unit.update) {
|
|
12177
|
-
|
|
12178
|
-
|
|
12284
|
+
let consumer = null;
|
|
12285
|
+
if (hasDependsOnSlotContextTrait(op)) {
|
|
12286
|
+
consumer = op;
|
|
12287
|
+
}
|
|
12288
|
+
else {
|
|
12289
|
+
visitExpressionsInOp(op, (expr) => {
|
|
12290
|
+
if (consumer === null && hasDependsOnSlotContextTrait(expr)) {
|
|
12291
|
+
consumer = expr;
|
|
12292
|
+
}
|
|
12293
|
+
});
|
|
12294
|
+
}
|
|
12295
|
+
if (consumer === null) {
|
|
12179
12296
|
continue;
|
|
12180
12297
|
}
|
|
12181
|
-
|
|
12298
|
+
if (!slotMap.has(consumer.target)) {
|
|
12182
12299
|
// We expect ops that _do_ depend on the slot counter to point at declarations that exist in
|
|
12183
12300
|
// the `slotMap`.
|
|
12184
|
-
throw new Error(`AssertionError: reference to unknown slot for target ${
|
|
12301
|
+
throw new Error(`AssertionError: reference to unknown slot for target ${consumer.target}`);
|
|
12185
12302
|
}
|
|
12186
|
-
const slot = slotMap.get(
|
|
12303
|
+
const slot = slotMap.get(consumer.target);
|
|
12187
12304
|
// Does the slot counter need to be adjusted?
|
|
12188
12305
|
if (slotContext !== slot) {
|
|
12189
12306
|
// If so, generate an `ir.AdvanceOp` to advance the counter.
|
|
@@ -12191,7 +12308,7 @@ function generateAdvance(job) {
|
|
|
12191
12308
|
if (delta < 0) {
|
|
12192
12309
|
throw new Error(`AssertionError: slot counter should never need to move backwards`);
|
|
12193
12310
|
}
|
|
12194
|
-
OpList.insertBefore(createAdvanceOp(delta,
|
|
12311
|
+
OpList.insertBefore(createAdvanceOp(delta, consumer.sourceSpan), op);
|
|
12195
12312
|
slotContext = slot;
|
|
12196
12313
|
}
|
|
12197
12314
|
}
|
|
@@ -12282,13 +12399,11 @@ function recursivelyProcessView(view, parentScope) {
|
|
|
12282
12399
|
case OpKind.Listener:
|
|
12283
12400
|
case OpKind.TwoWayListener:
|
|
12284
12401
|
// Prepend variables to listener handler functions.
|
|
12285
|
-
op.handlerOps.prepend(generateVariablesInScopeForView(view, scope));
|
|
12402
|
+
op.handlerOps.prepend(generateVariablesInScopeForView(view, scope, true));
|
|
12286
12403
|
break;
|
|
12287
12404
|
}
|
|
12288
12405
|
}
|
|
12289
|
-
|
|
12290
|
-
const preambleOps = generateVariablesInScopeForView(view, scope);
|
|
12291
|
-
view.update.prepend(preambleOps);
|
|
12406
|
+
view.update.prepend(generateVariablesInScopeForView(view, scope, false));
|
|
12292
12407
|
}
|
|
12293
12408
|
/**
|
|
12294
12409
|
* Process a view and generate a `Scope` representing the variables available for reference within
|
|
@@ -12305,6 +12420,7 @@ function getScopeForView(view, parent) {
|
|
|
12305
12420
|
contextVariables: new Map(),
|
|
12306
12421
|
aliases: view.aliases,
|
|
12307
12422
|
references: [],
|
|
12423
|
+
letDeclarations: [],
|
|
12308
12424
|
parent,
|
|
12309
12425
|
};
|
|
12310
12426
|
for (const identifier of view.contextVariables.keys()) {
|
|
@@ -12336,6 +12452,17 @@ function getScopeForView(view, parent) {
|
|
|
12336
12452
|
});
|
|
12337
12453
|
}
|
|
12338
12454
|
break;
|
|
12455
|
+
case OpKind.DeclareLet:
|
|
12456
|
+
scope.letDeclarations.push({
|
|
12457
|
+
targetId: op.xref,
|
|
12458
|
+
targetSlot: op.handle,
|
|
12459
|
+
variable: {
|
|
12460
|
+
kind: SemanticVariableKind.Identifier,
|
|
12461
|
+
name: null,
|
|
12462
|
+
identifier: op.declaredName,
|
|
12463
|
+
},
|
|
12464
|
+
});
|
|
12465
|
+
break;
|
|
12339
12466
|
}
|
|
12340
12467
|
}
|
|
12341
12468
|
return scope;
|
|
@@ -12346,7 +12473,7 @@ function getScopeForView(view, parent) {
|
|
|
12346
12473
|
* This is a recursive process, as views inherit variables available from their parent view, which
|
|
12347
12474
|
* itself may have inherited variables, etc.
|
|
12348
12475
|
*/
|
|
12349
|
-
function generateVariablesInScopeForView(view, scope) {
|
|
12476
|
+
function generateVariablesInScopeForView(view, scope, isListener) {
|
|
12350
12477
|
const newOps = [];
|
|
12351
12478
|
if (scope.view !== view.xref) {
|
|
12352
12479
|
// Before generating variables for a parent view, we need to switch to the context of the parent
|
|
@@ -12370,9 +12497,14 @@ function generateVariablesInScopeForView(view, scope) {
|
|
|
12370
12497
|
for (const ref of scope.references) {
|
|
12371
12498
|
newOps.push(createVariableOp(view.job.allocateXrefId(), ref.variable, new ReferenceExpr(ref.targetId, ref.targetSlot, ref.offset), VariableFlags.None));
|
|
12372
12499
|
}
|
|
12500
|
+
if (scope.view !== view.xref || isListener) {
|
|
12501
|
+
for (const decl of scope.letDeclarations) {
|
|
12502
|
+
newOps.push(createVariableOp(view.job.allocateXrefId(), decl.variable, new ContextLetReferenceExpr(decl.targetId, decl.targetSlot), VariableFlags.None));
|
|
12503
|
+
}
|
|
12504
|
+
}
|
|
12373
12505
|
if (scope.parent !== null) {
|
|
12374
12506
|
// Recursively add variables from the parent scope.
|
|
12375
|
-
newOps.push(...generateVariablesInScopeForView(view, scope.parent));
|
|
12507
|
+
newOps.push(...generateVariablesInScopeForView(view, scope.parent, false));
|
|
12376
12508
|
}
|
|
12377
12509
|
return newOps;
|
|
12378
12510
|
}
|
|
@@ -13730,7 +13862,8 @@ class _ParseAST {
|
|
|
13730
13862
|
const keyStart = this.inputIndex;
|
|
13731
13863
|
const quoted = this.next.isString();
|
|
13732
13864
|
const key = this.expectIdentifierOrKeywordOrString();
|
|
13733
|
-
|
|
13865
|
+
const literalMapKey = { key, quoted };
|
|
13866
|
+
keys.push(literalMapKey);
|
|
13734
13867
|
// Properties with quoted keys can't use the shorthand syntax.
|
|
13735
13868
|
if (quoted) {
|
|
13736
13869
|
this.expectCharacter($COLON);
|
|
@@ -13740,6 +13873,7 @@ class _ParseAST {
|
|
|
13740
13873
|
values.push(this.parsePipe());
|
|
13741
13874
|
}
|
|
13742
13875
|
else {
|
|
13876
|
+
literalMapKey.isShorthandInitialized = true;
|
|
13743
13877
|
const span = this.span(keyStart);
|
|
13744
13878
|
const sourceSpan = this.sourceSpan(keyStart);
|
|
13745
13879
|
values.push(new PropertyRead(span, sourceSpan, sourceSpan, new ImplicitReceiver(span, sourceSpan), key));
|
|
@@ -14229,6 +14363,18 @@ class BlockParameter {
|
|
|
14229
14363
|
return visitor.visitBlockParameter(this, context);
|
|
14230
14364
|
}
|
|
14231
14365
|
}
|
|
14366
|
+
class LetDeclaration {
|
|
14367
|
+
constructor(name, value, sourceSpan, nameSpan, valueSpan) {
|
|
14368
|
+
this.name = name;
|
|
14369
|
+
this.value = value;
|
|
14370
|
+
this.sourceSpan = sourceSpan;
|
|
14371
|
+
this.nameSpan = nameSpan;
|
|
14372
|
+
this.valueSpan = valueSpan;
|
|
14373
|
+
}
|
|
14374
|
+
visit(visitor, context) {
|
|
14375
|
+
return visitor.visitLetDeclaration(this, context);
|
|
14376
|
+
}
|
|
14377
|
+
}
|
|
14232
14378
|
function visitAll(visitor, nodes, context = null) {
|
|
14233
14379
|
const result = [];
|
|
14234
14380
|
const visit = visitor.visit
|
|
@@ -14266,6 +14412,7 @@ class RecursiveVisitor {
|
|
|
14266
14412
|
});
|
|
14267
14413
|
}
|
|
14268
14414
|
visitBlockParameter(ast, context) { }
|
|
14415
|
+
visitLetDeclaration(decl, context) { }
|
|
14269
14416
|
visitChildren(context, cb) {
|
|
14270
14417
|
let results = [];
|
|
14271
14418
|
let t = this;
|
|
@@ -15229,6 +15376,9 @@ class _I18nVisitor {
|
|
|
15229
15376
|
visitBlockParameter(_parameter, _context) {
|
|
15230
15377
|
throw new Error('Unreachable code');
|
|
15231
15378
|
}
|
|
15379
|
+
visitLetDeclaration(decl, context) {
|
|
15380
|
+
return null;
|
|
15381
|
+
}
|
|
15232
15382
|
/**
|
|
15233
15383
|
* Convert, text and interpolated tokens up into text and placeholder pieces.
|
|
15234
15384
|
*
|
|
@@ -17554,6 +17704,8 @@ class _Tokenizer {
|
|
|
17554
17704
|
this._preserveLineEndings = options.preserveLineEndings || false;
|
|
17555
17705
|
this._i18nNormalizeLineEndingsInICUs = options.i18nNormalizeLineEndingsInICUs || false;
|
|
17556
17706
|
this._tokenizeBlocks = options.tokenizeBlocks ?? true;
|
|
17707
|
+
// TODO(crisbeto): eventually set this to true.
|
|
17708
|
+
this._tokenizeLet = options.tokenizeLet || false;
|
|
17557
17709
|
try {
|
|
17558
17710
|
this._cursor.init();
|
|
17559
17711
|
}
|
|
@@ -17594,6 +17746,14 @@ class _Tokenizer {
|
|
|
17594
17746
|
this._consumeTagOpen(start);
|
|
17595
17747
|
}
|
|
17596
17748
|
}
|
|
17749
|
+
else if (this._tokenizeLet &&
|
|
17750
|
+
// Use `peek` instead of `attempCharCode` since we
|
|
17751
|
+
// don't want to advance in case it's not `@let`.
|
|
17752
|
+
this._cursor.peek() === $AT &&
|
|
17753
|
+
!this._inInterpolation &&
|
|
17754
|
+
this._attemptStr('@let')) {
|
|
17755
|
+
this._consumeLetDeclaration(start);
|
|
17756
|
+
}
|
|
17597
17757
|
else if (this._tokenizeBlocks && this._attemptCharCode($AT)) {
|
|
17598
17758
|
this._consumeBlockStart(start);
|
|
17599
17759
|
}
|
|
@@ -17614,7 +17774,7 @@ class _Tokenizer {
|
|
|
17614
17774
|
this.handleError(e);
|
|
17615
17775
|
}
|
|
17616
17776
|
}
|
|
17617
|
-
this._beginToken(
|
|
17777
|
+
this._beginToken(33 /* TokenType.EOF */);
|
|
17618
17778
|
this._endToken([]);
|
|
17619
17779
|
}
|
|
17620
17780
|
_getBlockName() {
|
|
@@ -17705,6 +17865,77 @@ class _Tokenizer {
|
|
|
17705
17865
|
this._attemptCharCodeUntilFn(isBlockParameterChar);
|
|
17706
17866
|
}
|
|
17707
17867
|
}
|
|
17868
|
+
_consumeLetDeclaration(start) {
|
|
17869
|
+
this._beginToken(29 /* TokenType.LET_START */, start);
|
|
17870
|
+
// Require at least one white space after the `@let`.
|
|
17871
|
+
if (isWhitespace(this._cursor.peek())) {
|
|
17872
|
+
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
17873
|
+
}
|
|
17874
|
+
else {
|
|
17875
|
+
const token = this._endToken([this._cursor.getChars(start)]);
|
|
17876
|
+
token.type = 32 /* TokenType.INCOMPLETE_LET */;
|
|
17877
|
+
return;
|
|
17878
|
+
}
|
|
17879
|
+
const startToken = this._endToken([this._getLetDeclarationName()]);
|
|
17880
|
+
// Skip over white space before the equals character.
|
|
17881
|
+
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
17882
|
+
// Expect an equals sign.
|
|
17883
|
+
if (!this._attemptCharCode($EQ)) {
|
|
17884
|
+
startToken.type = 32 /* TokenType.INCOMPLETE_LET */;
|
|
17885
|
+
return;
|
|
17886
|
+
}
|
|
17887
|
+
// Skip spaces after the equals.
|
|
17888
|
+
this._attemptCharCodeUntilFn((code) => isNotWhitespace(code) && !isNewLine(code));
|
|
17889
|
+
this._consumeLetDeclarationValue();
|
|
17890
|
+
// Terminate the `@let` with a semicolon.
|
|
17891
|
+
const endChar = this._cursor.peek();
|
|
17892
|
+
if (endChar === $SEMICOLON) {
|
|
17893
|
+
this._beginToken(31 /* TokenType.LET_END */);
|
|
17894
|
+
this._endToken([]);
|
|
17895
|
+
this._cursor.advance();
|
|
17896
|
+
}
|
|
17897
|
+
else {
|
|
17898
|
+
startToken.type = 32 /* TokenType.INCOMPLETE_LET */;
|
|
17899
|
+
startToken.sourceSpan = this._cursor.getSpan(start);
|
|
17900
|
+
}
|
|
17901
|
+
}
|
|
17902
|
+
_getLetDeclarationName() {
|
|
17903
|
+
const nameCursor = this._cursor.clone();
|
|
17904
|
+
let allowDigit = false;
|
|
17905
|
+
this._attemptCharCodeUntilFn((code) => {
|
|
17906
|
+
// `@let` names can't start with a digit, but digits are valid anywhere else in the name.
|
|
17907
|
+
if (isAsciiLetter(code) || code === $_ || (allowDigit && isDigit(code))) {
|
|
17908
|
+
allowDigit = true;
|
|
17909
|
+
return false;
|
|
17910
|
+
}
|
|
17911
|
+
return true;
|
|
17912
|
+
});
|
|
17913
|
+
return this._cursor.getChars(nameCursor).trim();
|
|
17914
|
+
}
|
|
17915
|
+
_consumeLetDeclarationValue() {
|
|
17916
|
+
const start = this._cursor.clone();
|
|
17917
|
+
this._beginToken(30 /* TokenType.LET_VALUE */, start);
|
|
17918
|
+
while (this._cursor.peek() !== $EOF) {
|
|
17919
|
+
const char = this._cursor.peek();
|
|
17920
|
+
// `@let` declarations terminate with a semicolon.
|
|
17921
|
+
if (char === $SEMICOLON) {
|
|
17922
|
+
break;
|
|
17923
|
+
}
|
|
17924
|
+
// If we hit a quote, skip over its content since we don't care what's inside.
|
|
17925
|
+
if (isQuote(char)) {
|
|
17926
|
+
this._cursor.advance();
|
|
17927
|
+
this._attemptCharCodeUntilFn((inner) => {
|
|
17928
|
+
if (inner === $BACKSLASH) {
|
|
17929
|
+
this._cursor.advance();
|
|
17930
|
+
return false;
|
|
17931
|
+
}
|
|
17932
|
+
return inner === char;
|
|
17933
|
+
});
|
|
17934
|
+
}
|
|
17935
|
+
this._cursor.advance();
|
|
17936
|
+
}
|
|
17937
|
+
this._endToken([this._cursor.getChars(start)]);
|
|
17938
|
+
}
|
|
17708
17939
|
/**
|
|
17709
17940
|
* @returns whether an ICU token has been created
|
|
17710
17941
|
* @internal
|
|
@@ -18635,7 +18866,7 @@ class _TreeBuilder {
|
|
|
18635
18866
|
this._advance();
|
|
18636
18867
|
}
|
|
18637
18868
|
build() {
|
|
18638
|
-
while (this._peek.type !==
|
|
18869
|
+
while (this._peek.type !== 33 /* TokenType.EOF */) {
|
|
18639
18870
|
if (this._peek.type === 0 /* TokenType.TAG_OPEN_START */ ||
|
|
18640
18871
|
this._peek.type === 4 /* TokenType.INCOMPLETE_TAG_OPEN */) {
|
|
18641
18872
|
this._consumeStartTag(this._advance());
|
|
@@ -18672,6 +18903,14 @@ class _TreeBuilder {
|
|
|
18672
18903
|
this._closeVoidElement();
|
|
18673
18904
|
this._consumeIncompleteBlock(this._advance());
|
|
18674
18905
|
}
|
|
18906
|
+
else if (this._peek.type === 29 /* TokenType.LET_START */) {
|
|
18907
|
+
this._closeVoidElement();
|
|
18908
|
+
this._consumeLet(this._advance());
|
|
18909
|
+
}
|
|
18910
|
+
else if (this._peek.type === 32 /* TokenType.INCOMPLETE_LET */) {
|
|
18911
|
+
this._closeVoidElement();
|
|
18912
|
+
this._consumeIncompleteLet(this._advance());
|
|
18913
|
+
}
|
|
18675
18914
|
else {
|
|
18676
18915
|
// Skip all other tokens...
|
|
18677
18916
|
this._advance();
|
|
@@ -18745,7 +18984,7 @@ class _TreeBuilder {
|
|
|
18745
18984
|
if (!exp)
|
|
18746
18985
|
return null;
|
|
18747
18986
|
const end = this._advance();
|
|
18748
|
-
exp.push({ type:
|
|
18987
|
+
exp.push({ type: 33 /* TokenType.EOF */, parts: [], sourceSpan: end.sourceSpan });
|
|
18749
18988
|
// parse everything in between { and }
|
|
18750
18989
|
const expansionCaseParser = new _TreeBuilder(exp, this.getTagDefinition);
|
|
18751
18990
|
expansionCaseParser.build();
|
|
@@ -18785,7 +19024,7 @@ class _TreeBuilder {
|
|
|
18785
19024
|
return null;
|
|
18786
19025
|
}
|
|
18787
19026
|
}
|
|
18788
|
-
if (this._peek.type ===
|
|
19027
|
+
if (this._peek.type === 33 /* TokenType.EOF */) {
|
|
18789
19028
|
this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
|
|
18790
19029
|
return null;
|
|
18791
19030
|
}
|
|
@@ -19015,6 +19254,51 @@ class _TreeBuilder {
|
|
|
19015
19254
|
this.errors.push(TreeError.create(token.parts[0], span, `Incomplete block "${token.parts[0]}". If you meant to write the @ character, ` +
|
|
19016
19255
|
`you should use the "@" HTML entity instead.`));
|
|
19017
19256
|
}
|
|
19257
|
+
_consumeLet(startToken) {
|
|
19258
|
+
const name = startToken.parts[0];
|
|
19259
|
+
let valueToken;
|
|
19260
|
+
let endToken;
|
|
19261
|
+
if (this._peek.type !== 30 /* TokenType.LET_VALUE */) {
|
|
19262
|
+
this.errors.push(TreeError.create(startToken.parts[0], startToken.sourceSpan, `Invalid @let declaration "${name}". Declaration must have a value.`));
|
|
19263
|
+
return;
|
|
19264
|
+
}
|
|
19265
|
+
else {
|
|
19266
|
+
valueToken = this._advance();
|
|
19267
|
+
}
|
|
19268
|
+
// Type cast is necessary here since TS narrowed the type of `peek` above.
|
|
19269
|
+
if (this._peek.type !== 31 /* TokenType.LET_END */) {
|
|
19270
|
+
this.errors.push(TreeError.create(startToken.parts[0], startToken.sourceSpan, `Unterminated @let declaration "${name}". Declaration must be terminated with a semicolon.`));
|
|
19271
|
+
return;
|
|
19272
|
+
}
|
|
19273
|
+
else {
|
|
19274
|
+
endToken = this._advance();
|
|
19275
|
+
}
|
|
19276
|
+
const end = endToken.sourceSpan.fullStart;
|
|
19277
|
+
const span = new ParseSourceSpan(startToken.sourceSpan.start, end, startToken.sourceSpan.fullStart);
|
|
19278
|
+
// The start token usually captures the `@let`. Construct a name span by
|
|
19279
|
+
// offsetting the start by the length of any text before the name.
|
|
19280
|
+
const startOffset = startToken.sourceSpan.toString().lastIndexOf(name);
|
|
19281
|
+
const nameStart = startToken.sourceSpan.start.moveBy(startOffset);
|
|
19282
|
+
const nameSpan = new ParseSourceSpan(nameStart, startToken.sourceSpan.end);
|
|
19283
|
+
const node = new LetDeclaration(name, valueToken.parts[0], span, nameSpan, valueToken.sourceSpan);
|
|
19284
|
+
this._addToParent(node);
|
|
19285
|
+
}
|
|
19286
|
+
_consumeIncompleteLet(token) {
|
|
19287
|
+
// Incomplete `@let` declaration may end up with an empty name.
|
|
19288
|
+
const name = token.parts[0] ?? '';
|
|
19289
|
+
const nameString = name ? ` "${name}"` : '';
|
|
19290
|
+
// If there's at least a name, we can salvage an AST node that can be used for completions.
|
|
19291
|
+
if (name.length > 0) {
|
|
19292
|
+
const startOffset = token.sourceSpan.toString().lastIndexOf(name);
|
|
19293
|
+
const nameStart = token.sourceSpan.start.moveBy(startOffset);
|
|
19294
|
+
const nameSpan = new ParseSourceSpan(nameStart, token.sourceSpan.end);
|
|
19295
|
+
const valueSpan = new ParseSourceSpan(token.sourceSpan.start, token.sourceSpan.start.moveBy(0));
|
|
19296
|
+
const node = new LetDeclaration(name, '', token.sourceSpan, nameSpan, valueSpan);
|
|
19297
|
+
this._addToParent(node);
|
|
19298
|
+
}
|
|
19299
|
+
this.errors.push(TreeError.create(token.parts[0], token.sourceSpan, `Incomplete @let declaration${nameString}. ` +
|
|
19300
|
+
`@let declarations must be written as \`@let <name> = <value>;\``));
|
|
19301
|
+
}
|
|
19018
19302
|
_getContainer() {
|
|
19019
19303
|
return this._containerStack.length > 0
|
|
19020
19304
|
? this._containerStack[this._containerStack.length - 1]
|
|
@@ -19243,6 +19527,9 @@ class I18nMetaVisitor {
|
|
|
19243
19527
|
visitBlockParameter(parameter, context) {
|
|
19244
19528
|
return parameter;
|
|
19245
19529
|
}
|
|
19530
|
+
visitLetDeclaration(decl, context) {
|
|
19531
|
+
return decl;
|
|
19532
|
+
}
|
|
19246
19533
|
/**
|
|
19247
19534
|
* Parse the general form `meta` passed into extract the explicit metadata needed to create a
|
|
19248
19535
|
* `Message`.
|
|
@@ -20351,6 +20638,7 @@ function mergeNextContextsInOps(ops) {
|
|
|
20351
20638
|
break;
|
|
20352
20639
|
case ExpressionKind.GetCurrentView:
|
|
20353
20640
|
case ExpressionKind.Reference:
|
|
20641
|
+
case ExpressionKind.ContextLetReference:
|
|
20354
20642
|
// Can't merge past a dependency on the context.
|
|
20355
20643
|
tryToMerge = false;
|
|
20356
20644
|
break;
|
|
@@ -21076,6 +21364,15 @@ function repeater(collection, sourceSpan) {
|
|
|
21076
21364
|
function deferWhen(prefetch, expr, sourceSpan) {
|
|
21077
21365
|
return call(prefetch ? Identifiers.deferPrefetchWhen : Identifiers.deferWhen, [expr], sourceSpan);
|
|
21078
21366
|
}
|
|
21367
|
+
function declareLet(slot, sourceSpan) {
|
|
21368
|
+
return call(Identifiers.declareLet, [literal(slot)], sourceSpan);
|
|
21369
|
+
}
|
|
21370
|
+
function storeLet(value, sourceSpan) {
|
|
21371
|
+
return importExpr(Identifiers.storeLet).callFn([value], sourceSpan);
|
|
21372
|
+
}
|
|
21373
|
+
function readContextLet(slot) {
|
|
21374
|
+
return importExpr(Identifiers.readContextLet).callFn([literal(slot)]);
|
|
21375
|
+
}
|
|
21079
21376
|
function i18n(slot, constIndex, subTemplateIndex, sourceSpan) {
|
|
21080
21377
|
const args = [literal(slot), literal(constIndex)];
|
|
21081
21378
|
if (subTemplateIndex) {
|
|
@@ -21487,6 +21784,9 @@ function reifyCreateOperations(unit, ops) {
|
|
|
21487
21784
|
case OpKind.Pipe:
|
|
21488
21785
|
OpList.replace(op, pipe(op.handle.slot, op.name));
|
|
21489
21786
|
break;
|
|
21787
|
+
case OpKind.DeclareLet:
|
|
21788
|
+
OpList.replace(op, declareLet(op.handle.slot, op.sourceSpan));
|
|
21789
|
+
break;
|
|
21490
21790
|
case OpKind.Listener:
|
|
21491
21791
|
const listenerFn = reifyListenerHandler(unit, op.handlerFnName, op.handlerOps, op.consumesDollarEvent);
|
|
21492
21792
|
const eventTargetResolver = op.eventTarget
|
|
@@ -21706,6 +22006,8 @@ function reifyUpdateOperations(_unit, ops) {
|
|
|
21706
22006
|
case OpKind.DeferWhen:
|
|
21707
22007
|
OpList.replace(op, deferWhen(op.prefetch, op.expr, op.sourceSpan));
|
|
21708
22008
|
break;
|
|
22009
|
+
case OpKind.StoreLet:
|
|
22010
|
+
throw new Error(`AssertionError: unexpected storeLet ${op.declaredName}`);
|
|
21709
22011
|
case OpKind.Statement:
|
|
21710
22012
|
// Pass statement operations directly through.
|
|
21711
22013
|
break;
|
|
@@ -21764,6 +22066,10 @@ function reifyIrExpression(expr) {
|
|
|
21764
22066
|
return pipeBindV(expr.targetSlot.slot, expr.varOffset, expr.args);
|
|
21765
22067
|
case ExpressionKind.SlotLiteralExpr:
|
|
21766
22068
|
return literal(expr.slot.slot);
|
|
22069
|
+
case ExpressionKind.ContextLetReference:
|
|
22070
|
+
return readContextLet(expr.targetSlot.slot);
|
|
22071
|
+
case ExpressionKind.StoreLet:
|
|
22072
|
+
return storeLet(expr.value, expr.sourceSpan);
|
|
21767
22073
|
default:
|
|
21768
22074
|
throw new Error(`AssertionError: Unsupported reification of ir.Expression kind: ${ExpressionKind[expr.kind]}`);
|
|
21769
22075
|
}
|
|
@@ -22522,7 +22828,7 @@ function saveAndRestoreView(job) {
|
|
|
22522
22828
|
if (!needsRestoreView) {
|
|
22523
22829
|
for (const handlerOp of op.handlerOps) {
|
|
22524
22830
|
visitExpressionsInOp(handlerOp, (expr) => {
|
|
22525
|
-
if (expr instanceof ReferenceExpr) {
|
|
22831
|
+
if (expr instanceof ReferenceExpr || expr instanceof ContextLetReferenceExpr) {
|
|
22526
22832
|
// Listeners that reference() a local ref need the save/restore view operation.
|
|
22527
22833
|
needsRestoreView = true;
|
|
22528
22834
|
}
|
|
@@ -22820,7 +23126,7 @@ function optimizeTrackFns(job) {
|
|
|
22820
23126
|
}
|
|
22821
23127
|
}
|
|
22822
23128
|
function isTrackByFunctionCall(rootView, expr) {
|
|
22823
|
-
if (!(expr instanceof InvokeFunctionExpr) || expr.args.length
|
|
23129
|
+
if (!(expr instanceof InvokeFunctionExpr) || expr.args.length === 0 || expr.args.length > 2) {
|
|
22824
23130
|
return false;
|
|
22825
23131
|
}
|
|
22826
23132
|
if (!(expr.receiver instanceof ReadPropExpr && expr.receiver.receiver instanceof ContextExpr) ||
|
|
@@ -22831,6 +23137,9 @@ function isTrackByFunctionCall(rootView, expr) {
|
|
|
22831
23137
|
if (!(arg0 instanceof ReadVarExpr) || arg0.name !== '$index') {
|
|
22832
23138
|
return false;
|
|
22833
23139
|
}
|
|
23140
|
+
else if (expr.args.length === 1) {
|
|
23141
|
+
return true;
|
|
23142
|
+
}
|
|
22834
23143
|
if (!(arg1 instanceof ReadVarExpr) || arg1.name !== '$item') {
|
|
22835
23144
|
return false;
|
|
22836
23145
|
}
|
|
@@ -22974,6 +23283,7 @@ function varsUsedByOp(op) {
|
|
|
22974
23283
|
case OpKind.I18nExpression:
|
|
22975
23284
|
case OpKind.Conditional:
|
|
22976
23285
|
case OpKind.DeferWhen:
|
|
23286
|
+
case OpKind.StoreLet:
|
|
22977
23287
|
return 1;
|
|
22978
23288
|
case OpKind.RepeaterCreate:
|
|
22979
23289
|
// Repeaters may require an extra variable binding slot, if they have an empty view, for the
|
|
@@ -22993,6 +23303,8 @@ function varsUsedByIrExpression(expr) {
|
|
|
22993
23303
|
return 1 + expr.args.length;
|
|
22994
23304
|
case ExpressionKind.PipeBindingVariadic:
|
|
22995
23305
|
return 1 + expr.numArgs;
|
|
23306
|
+
case ExpressionKind.StoreLet:
|
|
23307
|
+
return 1;
|
|
22996
23308
|
default:
|
|
22997
23309
|
throw new Error(`AssertionError: unhandled ConsumesVarsTrait expression ${expr.constructor.name}`);
|
|
22998
23310
|
}
|
|
@@ -23249,7 +23561,10 @@ function fencesForIrExpression(expr) {
|
|
|
23249
23561
|
return Fence.ViewContextRead | Fence.ViewContextWrite;
|
|
23250
23562
|
case ExpressionKind.RestoreView:
|
|
23251
23563
|
return Fence.ViewContextRead | Fence.ViewContextWrite | Fence.SideEffectful;
|
|
23564
|
+
case ExpressionKind.StoreLet:
|
|
23565
|
+
return Fence.SideEffectful;
|
|
23252
23566
|
case ExpressionKind.Reference:
|
|
23567
|
+
case ExpressionKind.ContextLetReference:
|
|
23253
23568
|
return Fence.ViewContextRead;
|
|
23254
23569
|
default:
|
|
23255
23570
|
return Fence.None;
|
|
@@ -23451,6 +23766,87 @@ function wrapI18nIcus(job) {
|
|
|
23451
23766
|
}
|
|
23452
23767
|
}
|
|
23453
23768
|
|
|
23769
|
+
/*!
|
|
23770
|
+
* @license
|
|
23771
|
+
* Copyright Google LLC All Rights Reserved.
|
|
23772
|
+
*
|
|
23773
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
23774
|
+
* found in the LICENSE file at https://angular.io/license
|
|
23775
|
+
*/
|
|
23776
|
+
/**
|
|
23777
|
+
* Removes any `storeLet` calls that aren't referenced outside of the current view.
|
|
23778
|
+
*/
|
|
23779
|
+
function optimizeStoreLet(job) {
|
|
23780
|
+
const letUsedExternally = new Set();
|
|
23781
|
+
// Since `@let` declarations can be referenced in child views, both in
|
|
23782
|
+
// the creation block (via listeners) and in the update block, we have
|
|
23783
|
+
// to look through all the ops to find the references.
|
|
23784
|
+
for (const unit of job.units) {
|
|
23785
|
+
for (const op of unit.ops()) {
|
|
23786
|
+
visitExpressionsInOp(op, (expr) => {
|
|
23787
|
+
if (expr instanceof ContextLetReferenceExpr) {
|
|
23788
|
+
letUsedExternally.add(expr.target);
|
|
23789
|
+
}
|
|
23790
|
+
});
|
|
23791
|
+
}
|
|
23792
|
+
}
|
|
23793
|
+
// TODO(crisbeto): potentially remove the unused calls completely, pending discussion.
|
|
23794
|
+
for (const unit of job.units) {
|
|
23795
|
+
for (const op of unit.update) {
|
|
23796
|
+
transformExpressionsInOp(op, (expression) => expression instanceof StoreLetExpr && !letUsedExternally.has(expression.target)
|
|
23797
|
+
? expression.value
|
|
23798
|
+
: expression, VisitorContextFlag.None);
|
|
23799
|
+
}
|
|
23800
|
+
}
|
|
23801
|
+
}
|
|
23802
|
+
|
|
23803
|
+
/**
|
|
23804
|
+
* It's not allowed to access a `@let` declaration before it has been defined. This is enforced
|
|
23805
|
+
* already via template type checking, however it can trip some of the assertions in the pipeline.
|
|
23806
|
+
* E.g. the naming phase can fail because we resolved the variable here, but the variable doesn't
|
|
23807
|
+
* exist anymore because the optimization phase removed it since it's invalid. To avoid surfacing
|
|
23808
|
+
* confusing errors to users in the case where template type checking isn't running (e.g. in JIT
|
|
23809
|
+
* mode) this phase detects illegal forward references and replaces them with `undefined`.
|
|
23810
|
+
* Eventually users will see the proper error from the template type checker.
|
|
23811
|
+
*/
|
|
23812
|
+
function removeIllegalLetReferences(job) {
|
|
23813
|
+
for (const unit of job.units) {
|
|
23814
|
+
for (const op of unit.update) {
|
|
23815
|
+
if (op.kind !== OpKind.Variable ||
|
|
23816
|
+
op.variable.kind !== SemanticVariableKind.Identifier ||
|
|
23817
|
+
!(op.initializer instanceof StoreLetExpr)) {
|
|
23818
|
+
continue;
|
|
23819
|
+
}
|
|
23820
|
+
const name = op.variable.identifier;
|
|
23821
|
+
let current = op;
|
|
23822
|
+
while (current && current.kind !== OpKind.ListEnd) {
|
|
23823
|
+
transformExpressionsInOp(current, (expr) => expr instanceof LexicalReadExpr && expr.name === name ? literal(undefined) : expr, VisitorContextFlag.None);
|
|
23824
|
+
current = current.prev;
|
|
23825
|
+
}
|
|
23826
|
+
}
|
|
23827
|
+
}
|
|
23828
|
+
}
|
|
23829
|
+
|
|
23830
|
+
/**
|
|
23831
|
+
* Replaces the `storeLet` ops with variables that can be
|
|
23832
|
+
* used to reference the value within the same view.
|
|
23833
|
+
*/
|
|
23834
|
+
function generateLocalLetReferences(job) {
|
|
23835
|
+
for (const unit of job.units) {
|
|
23836
|
+
for (const op of unit.update) {
|
|
23837
|
+
if (op.kind !== OpKind.StoreLet) {
|
|
23838
|
+
continue;
|
|
23839
|
+
}
|
|
23840
|
+
const variable = {
|
|
23841
|
+
kind: SemanticVariableKind.Identifier,
|
|
23842
|
+
name: null,
|
|
23843
|
+
identifier: op.declaredName,
|
|
23844
|
+
};
|
|
23845
|
+
OpList.replace(op, createVariableOp(job.allocateXrefId(), variable, new StoreLetExpr(op.target, op.value, op.sourceSpan), VariableFlags.None));
|
|
23846
|
+
}
|
|
23847
|
+
}
|
|
23848
|
+
}
|
|
23849
|
+
|
|
23454
23850
|
/**
|
|
23455
23851
|
*
|
|
23456
23852
|
* @license
|
|
@@ -23485,11 +23881,13 @@ const phases = [
|
|
|
23485
23881
|
{ kind: CompilationJobKind.Tmpl, fn: createVariadicPipes },
|
|
23486
23882
|
{ kind: CompilationJobKind.Both, fn: generatePureLiteralStructures },
|
|
23487
23883
|
{ kind: CompilationJobKind.Tmpl, fn: generateProjectionDefs },
|
|
23884
|
+
{ kind: CompilationJobKind.Tmpl, fn: generateLocalLetReferences },
|
|
23488
23885
|
{ kind: CompilationJobKind.Tmpl, fn: generateVariables },
|
|
23489
23886
|
{ kind: CompilationJobKind.Tmpl, fn: saveAndRestoreView },
|
|
23490
23887
|
{ kind: CompilationJobKind.Both, fn: deleteAnyCasts },
|
|
23491
23888
|
{ kind: CompilationJobKind.Both, fn: resolveDollarEvent },
|
|
23492
23889
|
{ kind: CompilationJobKind.Tmpl, fn: generateTrackVariables },
|
|
23890
|
+
{ kind: CompilationJobKind.Tmpl, fn: removeIllegalLetReferences },
|
|
23493
23891
|
{ kind: CompilationJobKind.Both, fn: resolveNames },
|
|
23494
23892
|
{ kind: CompilationJobKind.Tmpl, fn: resolveDeferTargetNames },
|
|
23495
23893
|
{ kind: CompilationJobKind.Tmpl, fn: transformTwoWayBindingSet },
|
|
@@ -23501,6 +23899,7 @@ const phases = [
|
|
|
23501
23899
|
{ kind: CompilationJobKind.Both, fn: expandSafeReads },
|
|
23502
23900
|
{ kind: CompilationJobKind.Both, fn: generateTemporaryVariables },
|
|
23503
23901
|
{ kind: CompilationJobKind.Both, fn: optimizeVariables },
|
|
23902
|
+
{ kind: CompilationJobKind.Both, fn: optimizeStoreLet },
|
|
23504
23903
|
{ kind: CompilationJobKind.Tmpl, fn: allocateSlots },
|
|
23505
23904
|
{ kind: CompilationJobKind.Tmpl, fn: resolveI18nElementPlaceholders },
|
|
23506
23905
|
{ kind: CompilationJobKind.Tmpl, fn: resolveI18nExpressionPlaceholders },
|
|
@@ -23737,6 +24136,9 @@ function ingestNodes(unit, template) {
|
|
|
23737
24136
|
else if (node instanceof ForLoopBlock) {
|
|
23738
24137
|
ingestForBlock(unit, node);
|
|
23739
24138
|
}
|
|
24139
|
+
else if (node instanceof LetDeclaration$1) {
|
|
24140
|
+
ingestLetDeclaration(unit, node);
|
|
24141
|
+
}
|
|
23740
24142
|
else {
|
|
23741
24143
|
throw new Error(`Unsupported template node: ${node.constructor.name}`);
|
|
23742
24144
|
}
|
|
@@ -24151,6 +24553,11 @@ function getComputedForLoopVariableExpression(variable, indexName, countName) {
|
|
|
24151
24553
|
throw new Error(`AssertionError: unknown @for loop variable ${variable.value}`);
|
|
24152
24554
|
}
|
|
24153
24555
|
}
|
|
24556
|
+
function ingestLetDeclaration(unit, node) {
|
|
24557
|
+
const target = unit.job.allocateXrefId();
|
|
24558
|
+
unit.create.push(createDeclareLetOp(target, node.name, node.sourceSpan));
|
|
24559
|
+
unit.update.push(createStoreLetOp(target, node.name, convertAst(node.value, unit.job, node.valueSpan), node.sourceSpan));
|
|
24560
|
+
}
|
|
24154
24561
|
/**
|
|
24155
24562
|
* Convert a template AST expression into an output AST expression.
|
|
24156
24563
|
*/
|
|
@@ -24176,7 +24583,7 @@ function convertAst(ast, job, baseSourceSpan) {
|
|
|
24176
24583
|
// The whole point of the explicit `this` was to access the class property, but TDB and the
|
|
24177
24584
|
// current TCB treat the read as implicit, and give you the context property instead!
|
|
24178
24585
|
//
|
|
24179
|
-
// For now, we emulate this old
|
|
24586
|
+
// For now, we emulate this old behavior by aggressively converting explicit reads to to
|
|
24180
24587
|
// implicit reads, except for the special cases that TDB and the current TCB protect. However,
|
|
24181
24588
|
// it would be an improvement to fix this.
|
|
24182
24589
|
//
|
|
@@ -24900,6 +25307,9 @@ class WhitespaceVisitor {
|
|
|
24900
25307
|
visitBlockParameter(parameter, context) {
|
|
24901
25308
|
return parameter;
|
|
24902
25309
|
}
|
|
25310
|
+
visitLetDeclaration(decl, context) {
|
|
25311
|
+
return decl;
|
|
25312
|
+
}
|
|
24903
25313
|
}
|
|
24904
25314
|
function createWhitespaceProcessedTextToken({ type, parts, sourceSpan }) {
|
|
24905
25315
|
return { type, parts: [processWhitespace(parts[0])], sourceSpan };
|
|
@@ -26555,6 +26965,13 @@ class HtmlAstToIvyAst {
|
|
|
26555
26965
|
}
|
|
26556
26966
|
return null;
|
|
26557
26967
|
}
|
|
26968
|
+
visitLetDeclaration(decl, context) {
|
|
26969
|
+
const value = this.bindingParser.parseBinding(decl.value, false, decl.valueSpan, decl.valueSpan.start.offset);
|
|
26970
|
+
if (value.errors.length === 0 && value.ast instanceof EmptyExpr$1) {
|
|
26971
|
+
this.reportError('@let declaration value cannot be empty', decl.valueSpan);
|
|
26972
|
+
}
|
|
26973
|
+
return new LetDeclaration$1(decl.name, value, decl.sourceSpan, decl.nameSpan, decl.valueSpan);
|
|
26974
|
+
}
|
|
26558
26975
|
visitBlockParameter() {
|
|
26559
26976
|
return null;
|
|
26560
26977
|
}
|
|
@@ -26833,6 +27250,9 @@ class NonBindableVisitor {
|
|
|
26833
27250
|
visitBlockParameter(parameter, context) {
|
|
26834
27251
|
return null;
|
|
26835
27252
|
}
|
|
27253
|
+
visitLetDeclaration(decl, context) {
|
|
27254
|
+
return new Text$3(`@let ${decl.name} = ${decl.value};`, decl.sourceSpan);
|
|
27255
|
+
}
|
|
26836
27256
|
}
|
|
26837
27257
|
const NON_BINDABLE_VISITOR = new NonBindableVisitor();
|
|
26838
27258
|
function normalizeAttributeName(attrName) {
|
|
@@ -26867,6 +27287,7 @@ function parseTemplate(template, templateUrl, options = {}) {
|
|
|
26867
27287
|
...options,
|
|
26868
27288
|
tokenizeExpansionForms: true,
|
|
26869
27289
|
tokenizeBlocks: options.enableBlockSyntax ?? true,
|
|
27290
|
+
tokenizeLet: options.enableLetSyntax ?? false,
|
|
26870
27291
|
});
|
|
26871
27292
|
if (!options.alwaysAttemptHtmlToR3AstConversion &&
|
|
26872
27293
|
parseResult.errors &&
|
|
@@ -27636,6 +28057,9 @@ class Scope {
|
|
|
27636
28057
|
visitContent(content) {
|
|
27637
28058
|
this.ingestScopedNode(content);
|
|
27638
28059
|
}
|
|
28060
|
+
visitLetDeclaration(decl) {
|
|
28061
|
+
this.maybeDeclare(decl);
|
|
28062
|
+
}
|
|
27639
28063
|
// Unused visitors.
|
|
27640
28064
|
visitBoundAttribute(attr) { }
|
|
27641
28065
|
visitBoundEvent(event) { }
|
|
@@ -27848,6 +28272,7 @@ class DirectiveBinder {
|
|
|
27848
28272
|
visitIcu(icu) { }
|
|
27849
28273
|
visitDeferredTrigger(trigger) { }
|
|
27850
28274
|
visitUnknownBlock(block) { }
|
|
28275
|
+
visitLetDeclaration(decl) { }
|
|
27851
28276
|
}
|
|
27852
28277
|
/**
|
|
27853
28278
|
* Processes a template and extract metadata about expressions and symbols within.
|
|
@@ -28044,6 +28469,12 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
28044
28469
|
visitBoundText(text) {
|
|
28045
28470
|
text.value.visit(this);
|
|
28046
28471
|
}
|
|
28472
|
+
visitLetDeclaration(decl) {
|
|
28473
|
+
decl.value.visit(this);
|
|
28474
|
+
if (this.rootNode !== null) {
|
|
28475
|
+
this.symbols.set(decl, this.rootNode);
|
|
28476
|
+
}
|
|
28477
|
+
}
|
|
28047
28478
|
visitPipe(ast, context) {
|
|
28048
28479
|
this.usedPipes.add(ast.name);
|
|
28049
28480
|
if (!this.scope.isDeferred) {
|
|
@@ -28078,7 +28509,13 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
28078
28509
|
}
|
|
28079
28510
|
// Check whether the name exists in the current scope. If so, map it. Otherwise, the name is
|
|
28080
28511
|
// probably a property on the top-level component context.
|
|
28081
|
-
|
|
28512
|
+
const target = this.scope.lookup(name);
|
|
28513
|
+
// It's not allowed to read template entities via `this`, however it previously worked by
|
|
28514
|
+
// accident (see #55115). Since `@let` declarations are new, we can fix it from the beginning,
|
|
28515
|
+
// whereas pre-existing template entities will be fixed in #55115.
|
|
28516
|
+
if (target instanceof LetDeclaration$1 && ast.receiver instanceof ThisReceiver) {
|
|
28517
|
+
return;
|
|
28518
|
+
}
|
|
28082
28519
|
if (target !== null) {
|
|
28083
28520
|
this.bindings.set(ast, target);
|
|
28084
28521
|
}
|
|
@@ -28276,6 +28713,7 @@ function extractScopedNodeEntities(rootScope) {
|
|
|
28276
28713
|
class ResourceLoader {
|
|
28277
28714
|
}
|
|
28278
28715
|
|
|
28716
|
+
let enableLetSyntax = false;
|
|
28279
28717
|
class CompilerFacadeImpl {
|
|
28280
28718
|
constructor(jitEvaluator = new JitEvaluator()) {
|
|
28281
28719
|
this.jitEvaluator = jitEvaluator;
|
|
@@ -28684,7 +29122,11 @@ function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespaces,
|
|
|
28684
29122
|
? InterpolationConfig.fromArray(interpolation)
|
|
28685
29123
|
: DEFAULT_INTERPOLATION_CONFIG;
|
|
28686
29124
|
// Parse the template and check for errors.
|
|
28687
|
-
const parsed = parseTemplate(template, sourceMapUrl, {
|
|
29125
|
+
const parsed = parseTemplate(template, sourceMapUrl, {
|
|
29126
|
+
preserveWhitespaces,
|
|
29127
|
+
interpolationConfig,
|
|
29128
|
+
enableLetSyntax,
|
|
29129
|
+
});
|
|
28688
29130
|
if (parsed.errors !== null) {
|
|
28689
29131
|
const errors = parsed.errors.map((err) => err.toString()).join(', ');
|
|
28690
29132
|
throw new Error(`Errors during JIT compilation of template for ${typeName}: ${errors}`);
|
|
@@ -28913,7 +29355,7 @@ function publishFacade(global) {
|
|
|
28913
29355
|
* @description
|
|
28914
29356
|
* Entry point for all public APIs of the compiler package.
|
|
28915
29357
|
*/
|
|
28916
|
-
const VERSION = new Version('18.0.
|
|
29358
|
+
const VERSION = new Version('18.0.5');
|
|
28917
29359
|
|
|
28918
29360
|
class CompilerConfig {
|
|
28919
29361
|
constructor({ defaultEncapsulation = exports.ViewEncapsulation.Emulated, preserveWhitespaces, strictInjectionParameters, } = {}) {
|
|
@@ -29138,6 +29580,7 @@ class _Visitor {
|
|
|
29138
29580
|
visitAll(this, block.children, context);
|
|
29139
29581
|
}
|
|
29140
29582
|
visitBlockParameter(parameter, context) { }
|
|
29583
|
+
visitLetDeclaration(decl, context) { }
|
|
29141
29584
|
_init(mode, interpolationConfig) {
|
|
29142
29585
|
this._mode = mode;
|
|
29143
29586
|
this._inI18nBlock = false;
|
|
@@ -29350,8 +29793,8 @@ class XmlParser extends Parser {
|
|
|
29350
29793
|
super(getXmlTagDefinition);
|
|
29351
29794
|
}
|
|
29352
29795
|
parse(source, url, options = {}) {
|
|
29353
|
-
// Blocks aren't supported in an XML context.
|
|
29354
|
-
return super.parse(source, url, { ...options, tokenizeBlocks: false });
|
|
29796
|
+
// Blocks and let declarations aren't supported in an XML context.
|
|
29797
|
+
return super.parse(source, url, { ...options, tokenizeBlocks: false, tokenizeLet: false });
|
|
29355
29798
|
}
|
|
29356
29799
|
}
|
|
29357
29800
|
|
|
@@ -29572,6 +30015,7 @@ class XliffParser {
|
|
|
29572
30015
|
visitExpansionCase(expansionCase, context) { }
|
|
29573
30016
|
visitBlock(block, context) { }
|
|
29574
30017
|
visitBlockParameter(parameter, context) { }
|
|
30018
|
+
visitLetDeclaration(decl, context) { }
|
|
29575
30019
|
_addError(node, message) {
|
|
29576
30020
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
29577
30021
|
}
|
|
@@ -29624,6 +30068,7 @@ class XmlToI18n$2 {
|
|
|
29624
30068
|
visitAttribute(attribute, context) { }
|
|
29625
30069
|
visitBlock(block, context) { }
|
|
29626
30070
|
visitBlockParameter(parameter, context) { }
|
|
30071
|
+
visitLetDeclaration(decl, context) { }
|
|
29627
30072
|
_addError(node, message) {
|
|
29628
30073
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
29629
30074
|
}
|
|
@@ -29883,6 +30328,7 @@ class Xliff2Parser {
|
|
|
29883
30328
|
visitExpansionCase(expansionCase, context) { }
|
|
29884
30329
|
visitBlock(block, context) { }
|
|
29885
30330
|
visitBlockParameter(parameter, context) { }
|
|
30331
|
+
visitLetDeclaration(decl, context) { }
|
|
29886
30332
|
_addError(node, message) {
|
|
29887
30333
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
29888
30334
|
}
|
|
@@ -29952,6 +30398,7 @@ class XmlToI18n$1 {
|
|
|
29952
30398
|
visitAttribute(attribute, context) { }
|
|
29953
30399
|
visitBlock(block, context) { }
|
|
29954
30400
|
visitBlockParameter(parameter, context) { }
|
|
30401
|
+
visitLetDeclaration(decl, context) { }
|
|
29955
30402
|
_addError(node, message) {
|
|
29956
30403
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
29957
30404
|
}
|
|
@@ -30088,6 +30535,7 @@ class XtbParser {
|
|
|
30088
30535
|
visitExpansionCase(expansionCase, context) { }
|
|
30089
30536
|
visitBlock(block, context) { }
|
|
30090
30537
|
visitBlockParameter(block, context) { }
|
|
30538
|
+
visitLetDeclaration(decl, context) { }
|
|
30091
30539
|
_addError(node, message) {
|
|
30092
30540
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
30093
30541
|
}
|
|
@@ -30138,6 +30586,7 @@ class XmlToI18n {
|
|
|
30138
30586
|
visitAttribute(attribute, context) { }
|
|
30139
30587
|
visitBlock(block, context) { }
|
|
30140
30588
|
visitBlockParameter(block, context) { }
|
|
30589
|
+
visitLetDeclaration(decl, context) { }
|
|
30141
30590
|
_addError(node, message) {
|
|
30142
30591
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
30143
30592
|
}
|
|
@@ -30544,7 +30993,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
|
|
|
30544
30993
|
function compileDeclareClassMetadata(metadata) {
|
|
30545
30994
|
const definitionMap = new DefinitionMap();
|
|
30546
30995
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
30547
|
-
definitionMap.set('version', literal('18.0.
|
|
30996
|
+
definitionMap.set('version', literal('18.0.5'));
|
|
30548
30997
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
30549
30998
|
definitionMap.set('type', metadata.type);
|
|
30550
30999
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -30562,7 +31011,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
|
|
|
30562
31011
|
callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? literal(null));
|
|
30563
31012
|
callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? literal(null));
|
|
30564
31013
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
|
|
30565
|
-
definitionMap.set('version', literal('18.0.
|
|
31014
|
+
definitionMap.set('version', literal('18.0.5'));
|
|
30566
31015
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
30567
31016
|
definitionMap.set('type', metadata.type);
|
|
30568
31017
|
definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
|
|
@@ -30657,7 +31106,7 @@ function createDirectiveDefinitionMap(meta) {
|
|
|
30657
31106
|
const definitionMap = new DefinitionMap();
|
|
30658
31107
|
const minVersion = getMinimumVersionForPartialOutput(meta);
|
|
30659
31108
|
definitionMap.set('minVersion', literal(minVersion));
|
|
30660
|
-
definitionMap.set('version', literal('18.0.
|
|
31109
|
+
definitionMap.set('version', literal('18.0.5'));
|
|
30661
31110
|
// e.g. `type: MyDirective`
|
|
30662
31111
|
definitionMap.set('type', meta.type.value);
|
|
30663
31112
|
if (meta.isStandalone) {
|
|
@@ -31076,7 +31525,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
|
|
|
31076
31525
|
function compileDeclareFactoryFunction(meta) {
|
|
31077
31526
|
const definitionMap = new DefinitionMap();
|
|
31078
31527
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
31079
|
-
definitionMap.set('version', literal('18.0.
|
|
31528
|
+
definitionMap.set('version', literal('18.0.5'));
|
|
31080
31529
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
31081
31530
|
definitionMap.set('type', meta.type.value);
|
|
31082
31531
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -31111,7 +31560,7 @@ function compileDeclareInjectableFromMetadata(meta) {
|
|
|
31111
31560
|
function createInjectableDefinitionMap(meta) {
|
|
31112
31561
|
const definitionMap = new DefinitionMap();
|
|
31113
31562
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
31114
|
-
definitionMap.set('version', literal('18.0.
|
|
31563
|
+
definitionMap.set('version', literal('18.0.5'));
|
|
31115
31564
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
31116
31565
|
definitionMap.set('type', meta.type.value);
|
|
31117
31566
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -31162,7 +31611,7 @@ function compileDeclareInjectorFromMetadata(meta) {
|
|
|
31162
31611
|
function createInjectorDefinitionMap(meta) {
|
|
31163
31612
|
const definitionMap = new DefinitionMap();
|
|
31164
31613
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
31165
|
-
definitionMap.set('version', literal('18.0.
|
|
31614
|
+
definitionMap.set('version', literal('18.0.5'));
|
|
31166
31615
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
31167
31616
|
definitionMap.set('type', meta.type.value);
|
|
31168
31617
|
definitionMap.set('providers', meta.providers);
|
|
@@ -31195,7 +31644,7 @@ function createNgModuleDefinitionMap(meta) {
|
|
|
31195
31644
|
throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
|
|
31196
31645
|
}
|
|
31197
31646
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
31198
|
-
definitionMap.set('version', literal('18.0.
|
|
31647
|
+
definitionMap.set('version', literal('18.0.5'));
|
|
31199
31648
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
31200
31649
|
definitionMap.set('type', meta.type.value);
|
|
31201
31650
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -31246,7 +31695,7 @@ function compileDeclarePipeFromMetadata(meta) {
|
|
|
31246
31695
|
function createPipeDefinitionMap(meta) {
|
|
31247
31696
|
const definitionMap = new DefinitionMap();
|
|
31248
31697
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
31249
|
-
definitionMap.set('version', literal('18.0.
|
|
31698
|
+
definitionMap.set('version', literal('18.0.5'));
|
|
31250
31699
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
31251
31700
|
// e.g. `type: MyPipe`
|
|
31252
31701
|
definitionMap.set('type', meta.type.value);
|
|
@@ -31328,6 +31777,7 @@ exports.JitEvaluator = JitEvaluator;
|
|
|
31328
31777
|
exports.KeyedRead = KeyedRead;
|
|
31329
31778
|
exports.KeyedWrite = KeyedWrite;
|
|
31330
31779
|
exports.LeadingComment = LeadingComment;
|
|
31780
|
+
exports.LetDeclaration = LetDeclaration;
|
|
31331
31781
|
exports.Lexer = Lexer;
|
|
31332
31782
|
exports.LiteralArray = LiteralArray;
|
|
31333
31783
|
exports.LiteralArrayExpr = LiteralArrayExpr;
|
|
@@ -31404,6 +31854,7 @@ exports.TmplAstIfBlock = IfBlock;
|
|
|
31404
31854
|
exports.TmplAstIfBlockBranch = IfBlockBranch;
|
|
31405
31855
|
exports.TmplAstImmediateDeferredTrigger = ImmediateDeferredTrigger;
|
|
31406
31856
|
exports.TmplAstInteractionDeferredTrigger = InteractionDeferredTrigger;
|
|
31857
|
+
exports.TmplAstLetDeclaration = LetDeclaration$1;
|
|
31407
31858
|
exports.TmplAstRecursiveVisitor = RecursiveVisitor$1;
|
|
31408
31859
|
exports.TmplAstReference = Reference;
|
|
31409
31860
|
exports.TmplAstSwitchBlock = SwitchBlock;
|