@angular/compiler 16.2.0-next.1 → 16.2.0-next.2
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/compiler.mjs +2 -2
- package/esm2022/src/expression_parser/ast.mjs +1 -1
- package/esm2022/src/i18n/extractor_merger.mjs +8 -1
- package/esm2022/src/i18n/i18n_parser.mjs +12 -1
- package/esm2022/src/i18n/serializers/xliff.mjs +7 -1
- package/esm2022/src/i18n/serializers/xliff2.mjs +7 -1
- package/esm2022/src/i18n/serializers/xtb.mjs +7 -1
- package/esm2022/src/jit_compiler_facade.mjs +3 -2
- package/esm2022/src/ml_parser/ast.mjs +46 -1
- package/esm2022/src/ml_parser/html_whitespaces.mjs +10 -1
- package/esm2022/src/ml_parser/icu_ast_expander.mjs +10 -1
- package/esm2022/src/ml_parser/lexer.mjs +93 -4
- package/esm2022/src/ml_parser/parser.mjs +129 -32
- package/esm2022/src/ml_parser/tokens.mjs +1 -1
- package/esm2022/src/ml_parser/xml_parser.mjs +4 -3
- package/esm2022/src/output/output_ast.mjs +9 -1
- 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 +6 -3
- package/esm2022/src/render3/partial/pipe.mjs +1 -1
- package/esm2022/src/render3/r3_module_compiler.mjs +69 -27
- package/esm2022/src/render3/r3_template_transform.mjs +19 -1
- package/esm2022/src/render3/view/i18n/meta.mjs +12 -1
- package/esm2022/src/shadow_css.mjs +2 -2
- package/esm2022/src/template/pipeline/ir/src/enums.mjs +13 -1
- package/esm2022/src/template/pipeline/ir/src/expression.mjs +80 -6
- package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +16 -1
- package/esm2022/src/template/pipeline/src/emit.mjs +4 -2
- package/esm2022/src/template/pipeline/src/ingest.mjs +18 -1
- package/esm2022/src/template/pipeline/src/instruction.mjs +31 -1
- package/esm2022/src/template/pipeline/src/phases/chaining.mjs +2 -1
- package/esm2022/src/template/pipeline/src/phases/expand_safe_reads.mjs +102 -10
- package/esm2022/src/template/pipeline/src/phases/generate_variables.mjs +1 -6
- package/esm2022/src/template/pipeline/src/phases/nullish_coalescing.mjs +6 -5
- package/esm2022/src/template/pipeline/src/phases/reify.mjs +17 -1
- package/esm2022/src/template/pipeline/src/phases/resolve_names.mjs +8 -1
- package/esm2022/src/template/pipeline/src/phases/save_restore_view.mjs +32 -19
- package/esm2022/src/template/pipeline/src/phases/temporary_variables.mjs +53 -0
- package/esm2022/src/template/pipeline/src/phases/var_counting.mjs +7 -1
- package/esm2022/src/version.mjs +1 -1
- package/fesm2022/compiler.mjs +799 -115
- package/fesm2022/compiler.mjs.map +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/index.d.ts +113 -15
- package/package.json +2 -2
- package/testing/index.d.ts +1 -1
package/fesm2022/compiler.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v16.2.0-next.
|
|
2
|
+
* @license Angular v16.2.0-next.2
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -1339,6 +1339,10 @@ class InvokeFunctionExpr extends Expression {
|
|
|
1339
1339
|
this.args = args;
|
|
1340
1340
|
this.pure = pure;
|
|
1341
1341
|
}
|
|
1342
|
+
// An alias for fn, which allows other logic to handle calls and property reads together.
|
|
1343
|
+
get receiver() {
|
|
1344
|
+
return this.fn;
|
|
1345
|
+
}
|
|
1342
1346
|
isEquivalent(e) {
|
|
1343
1347
|
return e instanceof InvokeFunctionExpr && this.fn.isEquivalent(e.fn) &&
|
|
1344
1348
|
areAllEquivalent(this.args, e.args) && this.pure === e.pure;
|
|
@@ -1721,6 +1725,10 @@ class ReadPropExpr extends Expression {
|
|
|
1721
1725
|
this.receiver = receiver;
|
|
1722
1726
|
this.name = name;
|
|
1723
1727
|
}
|
|
1728
|
+
// An alias for name, which allows other logic to handle property reads and keyed reads together.
|
|
1729
|
+
get index() {
|
|
1730
|
+
return this.name;
|
|
1731
|
+
}
|
|
1724
1732
|
isEquivalent(e) {
|
|
1725
1733
|
return e instanceof ReadPropExpr && this.receiver.isEquivalent(e.receiver) &&
|
|
1726
1734
|
this.name === e.name;
|
|
@@ -5717,31 +5725,49 @@ var R3SelectorScopeMode;
|
|
|
5717
5725
|
*/
|
|
5718
5726
|
R3SelectorScopeMode[R3SelectorScopeMode["Omit"] = 2] = "Omit";
|
|
5719
5727
|
})(R3SelectorScopeMode || (R3SelectorScopeMode = {}));
|
|
5728
|
+
/**
|
|
5729
|
+
* The type of the NgModule meta data.
|
|
5730
|
+
* - Global: Used for full and partial compilation modes which mainly includes R3References.
|
|
5731
|
+
* - Local: Used for the local compilation mode which mainly includes the raw expressions as appears
|
|
5732
|
+
* in the NgModule decorator.
|
|
5733
|
+
*/
|
|
5734
|
+
var R3NgModuleMetadataKind;
|
|
5735
|
+
(function (R3NgModuleMetadataKind) {
|
|
5736
|
+
R3NgModuleMetadataKind[R3NgModuleMetadataKind["Global"] = 0] = "Global";
|
|
5737
|
+
R3NgModuleMetadataKind[R3NgModuleMetadataKind["Local"] = 1] = "Local";
|
|
5738
|
+
})(R3NgModuleMetadataKind || (R3NgModuleMetadataKind = {}));
|
|
5720
5739
|
/**
|
|
5721
5740
|
* Construct an `R3NgModuleDef` for the given `R3NgModuleMetadata`.
|
|
5722
5741
|
*/
|
|
5723
5742
|
function compileNgModule(meta) {
|
|
5724
|
-
const { type: moduleType, bootstrap, declarations, imports, exports, schemas, containsForwardDecls, selectorScopeMode, id } = meta;
|
|
5725
5743
|
const statements = [];
|
|
5726
5744
|
const definitionMap = new DefinitionMap();
|
|
5727
|
-
definitionMap.set('type',
|
|
5728
|
-
|
|
5729
|
-
|
|
5745
|
+
definitionMap.set('type', meta.type.value);
|
|
5746
|
+
// Assign bootstrap definition
|
|
5747
|
+
if (meta.kind === R3NgModuleMetadataKind.Global) {
|
|
5748
|
+
if (meta.bootstrap.length > 0) {
|
|
5749
|
+
definitionMap.set('bootstrap', refsToArray(meta.bootstrap, meta.containsForwardDecls));
|
|
5750
|
+
}
|
|
5730
5751
|
}
|
|
5731
|
-
|
|
5752
|
+
else {
|
|
5753
|
+
if (meta.bootstrapExpression) {
|
|
5754
|
+
definitionMap.set('bootstrap', meta.bootstrapExpression);
|
|
5755
|
+
}
|
|
5756
|
+
}
|
|
5757
|
+
if (meta.selectorScopeMode === R3SelectorScopeMode.Inline) {
|
|
5732
5758
|
// If requested to emit scope information inline, pass the `declarations`, `imports` and
|
|
5733
5759
|
// `exports` to the `ɵɵdefineNgModule()` call directly.
|
|
5734
|
-
if (declarations.length > 0) {
|
|
5735
|
-
definitionMap.set('declarations', refsToArray(declarations, containsForwardDecls));
|
|
5760
|
+
if (meta.declarations.length > 0) {
|
|
5761
|
+
definitionMap.set('declarations', refsToArray(meta.declarations, meta.containsForwardDecls));
|
|
5736
5762
|
}
|
|
5737
|
-
if (imports.length > 0) {
|
|
5738
|
-
definitionMap.set('imports', refsToArray(imports, containsForwardDecls));
|
|
5763
|
+
if (meta.imports.length > 0) {
|
|
5764
|
+
definitionMap.set('imports', refsToArray(meta.imports, meta.containsForwardDecls));
|
|
5739
5765
|
}
|
|
5740
|
-
if (exports.length > 0) {
|
|
5741
|
-
definitionMap.set('exports', refsToArray(exports, containsForwardDecls));
|
|
5766
|
+
if (meta.exports.length > 0) {
|
|
5767
|
+
definitionMap.set('exports', refsToArray(meta.exports, meta.containsForwardDecls));
|
|
5742
5768
|
}
|
|
5743
5769
|
}
|
|
5744
|
-
else if (selectorScopeMode === R3SelectorScopeMode.SideEffect) {
|
|
5770
|
+
else if (meta.selectorScopeMode === R3SelectorScopeMode.SideEffect) {
|
|
5745
5771
|
// In this mode, scope information is not passed into `ɵɵdefineNgModule` as it
|
|
5746
5772
|
// would prevent tree-shaking of the declarations, imports and exports references. Instead, it's
|
|
5747
5773
|
// patched onto the NgModule definition with a `ɵɵsetNgModuleScope` call that's guarded by the
|
|
@@ -5754,14 +5780,14 @@ function compileNgModule(meta) {
|
|
|
5754
5780
|
else {
|
|
5755
5781
|
// Selector scope emit was not requested, so skip it.
|
|
5756
5782
|
}
|
|
5757
|
-
if (schemas !== null && schemas.length > 0) {
|
|
5758
|
-
definitionMap.set('schemas', literalArr(schemas.map(ref => ref.value)));
|
|
5783
|
+
if (meta.schemas !== null && meta.schemas.length > 0) {
|
|
5784
|
+
definitionMap.set('schemas', literalArr(meta.schemas.map(ref => ref.value)));
|
|
5759
5785
|
}
|
|
5760
|
-
if (id !== null) {
|
|
5761
|
-
definitionMap.set('id', id);
|
|
5786
|
+
if (meta.id !== null) {
|
|
5787
|
+
definitionMap.set('id', meta.id);
|
|
5762
5788
|
// Generate a side-effectful call to register this NgModule by its id, as per the semantics of
|
|
5763
5789
|
// NgModule ids.
|
|
5764
|
-
statements.push(importExpr(Identifiers.registerNgModuleType).callFn([
|
|
5790
|
+
statements.push(importExpr(Identifiers.registerNgModuleType).callFn([meta.type.value, meta.id]).toStmt());
|
|
5765
5791
|
}
|
|
5766
5792
|
const expression = importExpr(Identifiers.defineNgModule).callFn([definitionMap.toLiteralMap()], undefined, true);
|
|
5767
5793
|
const type = createNgModuleType(meta);
|
|
@@ -5794,7 +5820,11 @@ function compileNgModuleDeclarationExpression(meta) {
|
|
|
5794
5820
|
}
|
|
5795
5821
|
return importExpr(Identifiers.defineNgModule).callFn([definitionMap.toLiteralMap()]);
|
|
5796
5822
|
}
|
|
5797
|
-
function createNgModuleType(
|
|
5823
|
+
function createNgModuleType(meta) {
|
|
5824
|
+
if (meta.kind === R3NgModuleMetadataKind.Local) {
|
|
5825
|
+
return new ExpressionType(meta.type.value);
|
|
5826
|
+
}
|
|
5827
|
+
const { type: moduleType, declarations, exports, imports, includeImportTypes, publicDeclarationTypes } = meta;
|
|
5798
5828
|
return new ExpressionType(importExpr(Identifiers.NgModuleDeclaration, [
|
|
5799
5829
|
new ExpressionType(moduleType.type),
|
|
5800
5830
|
publicDeclarationTypes === null ? tupleTypeOf(declarations) :
|
|
@@ -5810,16 +5840,36 @@ function createNgModuleType({ type: moduleType, declarations, exports, imports,
|
|
|
5810
5840
|
* symbols to become tree-shakeable.
|
|
5811
5841
|
*/
|
|
5812
5842
|
function generateSetNgModuleScopeCall(meta) {
|
|
5813
|
-
const { type: moduleType, declarations, imports, exports, containsForwardDecls } = meta;
|
|
5814
5843
|
const scopeMap = new DefinitionMap();
|
|
5815
|
-
if (
|
|
5816
|
-
|
|
5844
|
+
if (meta.kind === R3NgModuleMetadataKind.Global) {
|
|
5845
|
+
if (meta.declarations.length > 0) {
|
|
5846
|
+
scopeMap.set('declarations', refsToArray(meta.declarations, meta.containsForwardDecls));
|
|
5847
|
+
}
|
|
5848
|
+
}
|
|
5849
|
+
else {
|
|
5850
|
+
if (meta.declarationsExpression) {
|
|
5851
|
+
scopeMap.set('declarations', meta.declarationsExpression);
|
|
5852
|
+
}
|
|
5853
|
+
}
|
|
5854
|
+
if (meta.kind === R3NgModuleMetadataKind.Global) {
|
|
5855
|
+
if (meta.imports.length > 0) {
|
|
5856
|
+
scopeMap.set('imports', refsToArray(meta.imports, meta.containsForwardDecls));
|
|
5857
|
+
}
|
|
5817
5858
|
}
|
|
5818
|
-
|
|
5819
|
-
|
|
5859
|
+
else {
|
|
5860
|
+
if (meta.importsExpression) {
|
|
5861
|
+
scopeMap.set('imports', meta.importsExpression);
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
if (meta.kind === R3NgModuleMetadataKind.Global) {
|
|
5865
|
+
if (meta.exports.length > 0) {
|
|
5866
|
+
scopeMap.set('exports', refsToArray(meta.exports, meta.containsForwardDecls));
|
|
5867
|
+
}
|
|
5820
5868
|
}
|
|
5821
|
-
|
|
5822
|
-
|
|
5869
|
+
else {
|
|
5870
|
+
if (meta.exportsExpression) {
|
|
5871
|
+
scopeMap.set('exports', meta.exportsExpression);
|
|
5872
|
+
}
|
|
5823
5873
|
}
|
|
5824
5874
|
if (Object.keys(scopeMap.values).length === 0) {
|
|
5825
5875
|
return null;
|
|
@@ -5827,7 +5877,7 @@ function generateSetNgModuleScopeCall(meta) {
|
|
|
5827
5877
|
// setNgModuleScope(...)
|
|
5828
5878
|
const fnCall = new InvokeFunctionExpr(
|
|
5829
5879
|
/* fn */ importExpr(Identifiers.setNgModuleScope),
|
|
5830
|
-
/* args */ [
|
|
5880
|
+
/* args */ [meta.type.value, scopeMap.toLiteralMap()]);
|
|
5831
5881
|
// (ngJitMode guard) && setNgModuleScope(...)
|
|
5832
5882
|
const guardedCall = jitOnlyGuardedExpression(fnCall);
|
|
5833
5883
|
// function() { (ngJitMode guard) && setNgModuleScope(...); }
|
|
@@ -7946,7 +7996,7 @@ class ShadowCss {
|
|
|
7946
7996
|
}
|
|
7947
7997
|
else if (rule.selector.startsWith('@media') || rule.selector.startsWith('@supports') ||
|
|
7948
7998
|
rule.selector.startsWith('@document') || rule.selector.startsWith('@layer') ||
|
|
7949
|
-
rule.selector.startsWith('@container')) {
|
|
7999
|
+
rule.selector.startsWith('@container') || rule.selector.startsWith('@scope')) {
|
|
7950
8000
|
content = this._scopeSelectors(rule.content, scopeSelector, hostSelector);
|
|
7951
8001
|
}
|
|
7952
8002
|
else if (rule.selector.startsWith('@font-face') || rule.selector.startsWith('@page')) {
|
|
@@ -8663,6 +8713,10 @@ var OpKind;
|
|
|
8663
8713
|
* An operation to associate an attribute with an element.
|
|
8664
8714
|
*/
|
|
8665
8715
|
OpKind[OpKind["Attribute"] = 21] = "Attribute";
|
|
8716
|
+
/**
|
|
8717
|
+
* An operation to interpolate text into an attribute binding.
|
|
8718
|
+
*/
|
|
8719
|
+
OpKind[OpKind["InterpolateAttribute"] = 22] = "InterpolateAttribute";
|
|
8666
8720
|
})(OpKind || (OpKind = {}));
|
|
8667
8721
|
/**
|
|
8668
8722
|
* Distinguishes different kinds of IR expressions.
|
|
@@ -8737,6 +8791,14 @@ var ExpressionKind;
|
|
|
8737
8791
|
* An empty expression that will be stipped before generating the final output.
|
|
8738
8792
|
*/
|
|
8739
8793
|
ExpressionKind[ExpressionKind["EmptyExpr"] = 16] = "EmptyExpr";
|
|
8794
|
+
/*
|
|
8795
|
+
* An assignment to a temporary variable.
|
|
8796
|
+
*/
|
|
8797
|
+
ExpressionKind[ExpressionKind["AssignTemporaryExpr"] = 17] = "AssignTemporaryExpr";
|
|
8798
|
+
/**
|
|
8799
|
+
* A reference to a temporary variable.
|
|
8800
|
+
*/
|
|
8801
|
+
ExpressionKind[ExpressionKind["ReadTemporaryExpr"] = 18] = "ReadTemporaryExpr";
|
|
8740
8802
|
})(ExpressionKind || (ExpressionKind = {}));
|
|
8741
8803
|
/**
|
|
8742
8804
|
* Distinguishes between different kinds of `SemanticVariable`s.
|
|
@@ -9204,7 +9266,13 @@ class SafePropertyReadExpr extends ExpressionBase {
|
|
|
9204
9266
|
this.name = name;
|
|
9205
9267
|
this.kind = ExpressionKind.SafePropertyRead;
|
|
9206
9268
|
}
|
|
9207
|
-
|
|
9269
|
+
// An alias for name, which allows other logic to handle property reads and keyed reads together.
|
|
9270
|
+
get index() {
|
|
9271
|
+
return this.name;
|
|
9272
|
+
}
|
|
9273
|
+
visitExpression(visitor, context) {
|
|
9274
|
+
this.receiver.visitExpression(visitor, context);
|
|
9275
|
+
}
|
|
9208
9276
|
isEquivalent() {
|
|
9209
9277
|
return false;
|
|
9210
9278
|
}
|
|
@@ -9225,7 +9293,10 @@ class SafeKeyedReadExpr extends ExpressionBase {
|
|
|
9225
9293
|
this.index = index;
|
|
9226
9294
|
this.kind = ExpressionKind.SafeKeyedRead;
|
|
9227
9295
|
}
|
|
9228
|
-
visitExpression(visitor, context) {
|
|
9296
|
+
visitExpression(visitor, context) {
|
|
9297
|
+
this.receiver.visitExpression(visitor, context);
|
|
9298
|
+
this.index.visitExpression(visitor, context);
|
|
9299
|
+
}
|
|
9229
9300
|
isEquivalent() {
|
|
9230
9301
|
return false;
|
|
9231
9302
|
}
|
|
@@ -9247,7 +9318,12 @@ class SafeInvokeFunctionExpr extends ExpressionBase {
|
|
|
9247
9318
|
this.args = args;
|
|
9248
9319
|
this.kind = ExpressionKind.SafeInvokeFunction;
|
|
9249
9320
|
}
|
|
9250
|
-
visitExpression(visitor, context) {
|
|
9321
|
+
visitExpression(visitor, context) {
|
|
9322
|
+
this.receiver.visitExpression(visitor, context);
|
|
9323
|
+
for (const a of this.args) {
|
|
9324
|
+
a.visitExpression(visitor, context);
|
|
9325
|
+
}
|
|
9326
|
+
}
|
|
9251
9327
|
isEquivalent() {
|
|
9252
9328
|
return false;
|
|
9253
9329
|
}
|
|
@@ -9271,7 +9347,10 @@ class SafeTernaryExpr extends ExpressionBase {
|
|
|
9271
9347
|
this.expr = expr;
|
|
9272
9348
|
this.kind = ExpressionKind.SafeTernaryExpr;
|
|
9273
9349
|
}
|
|
9274
|
-
visitExpression(visitor, context) {
|
|
9350
|
+
visitExpression(visitor, context) {
|
|
9351
|
+
this.guard.visitExpression(visitor, context);
|
|
9352
|
+
this.expr.visitExpression(visitor, context);
|
|
9353
|
+
}
|
|
9275
9354
|
isEquivalent() {
|
|
9276
9355
|
return false;
|
|
9277
9356
|
}
|
|
@@ -9303,6 +9382,53 @@ class EmptyExpr extends ExpressionBase {
|
|
|
9303
9382
|
}
|
|
9304
9383
|
transformInternalExpressions() { }
|
|
9305
9384
|
}
|
|
9385
|
+
class AssignTemporaryExpr extends ExpressionBase {
|
|
9386
|
+
constructor(expr, xref) {
|
|
9387
|
+
super();
|
|
9388
|
+
this.expr = expr;
|
|
9389
|
+
this.xref = xref;
|
|
9390
|
+
this.kind = ExpressionKind.AssignTemporaryExpr;
|
|
9391
|
+
this.name = null;
|
|
9392
|
+
}
|
|
9393
|
+
visitExpression(visitor, context) {
|
|
9394
|
+
this.expr.visitExpression(visitor, context);
|
|
9395
|
+
}
|
|
9396
|
+
isEquivalent() {
|
|
9397
|
+
return false;
|
|
9398
|
+
}
|
|
9399
|
+
isConstant() {
|
|
9400
|
+
return false;
|
|
9401
|
+
}
|
|
9402
|
+
transformInternalExpressions(transform, flags) {
|
|
9403
|
+
this.expr = transformExpressionsInExpression(this.expr, transform, flags);
|
|
9404
|
+
}
|
|
9405
|
+
clone() {
|
|
9406
|
+
const a = new AssignTemporaryExpr(this.expr, this.xref);
|
|
9407
|
+
a.name = this.name;
|
|
9408
|
+
return a;
|
|
9409
|
+
}
|
|
9410
|
+
}
|
|
9411
|
+
class ReadTemporaryExpr extends ExpressionBase {
|
|
9412
|
+
constructor(xref) {
|
|
9413
|
+
super();
|
|
9414
|
+
this.xref = xref;
|
|
9415
|
+
this.kind = ExpressionKind.ReadTemporaryExpr;
|
|
9416
|
+
this.name = null;
|
|
9417
|
+
}
|
|
9418
|
+
visitExpression(visitor, context) { }
|
|
9419
|
+
isEquivalent() {
|
|
9420
|
+
return this.xref === this.xref;
|
|
9421
|
+
}
|
|
9422
|
+
isConstant() {
|
|
9423
|
+
return false;
|
|
9424
|
+
}
|
|
9425
|
+
transformInternalExpressions(transform, flags) { }
|
|
9426
|
+
clone() {
|
|
9427
|
+
const r = new ReadTemporaryExpr(this.xref);
|
|
9428
|
+
r.name = this.name;
|
|
9429
|
+
return r;
|
|
9430
|
+
}
|
|
9431
|
+
}
|
|
9306
9432
|
/**
|
|
9307
9433
|
* Visits all `Expression`s in the AST of `op` with the `visitor` function.
|
|
9308
9434
|
*/
|
|
@@ -9343,7 +9469,12 @@ function transformExpressionsInOp(op, transform, flags) {
|
|
|
9343
9469
|
break;
|
|
9344
9470
|
case OpKind.Attribute:
|
|
9345
9471
|
if (op.value) {
|
|
9346
|
-
transformExpressionsInExpression(op.value, transform, flags);
|
|
9472
|
+
op.value = transformExpressionsInExpression(op.value, transform, flags);
|
|
9473
|
+
}
|
|
9474
|
+
break;
|
|
9475
|
+
case OpKind.InterpolateAttribute:
|
|
9476
|
+
for (let i = 0; i < op.expressions.length; i++) {
|
|
9477
|
+
op.expressions[i] = transformExpressionsInExpression(op.expressions[i], transform, flags);
|
|
9347
9478
|
}
|
|
9348
9479
|
break;
|
|
9349
9480
|
case OpKind.Variable:
|
|
@@ -9446,6 +9577,11 @@ function transformExpressionsInStatement(stmt, transform, flags) {
|
|
|
9446
9577
|
else if (stmt instanceof ReturnStatement) {
|
|
9447
9578
|
stmt.value = transformExpressionsInExpression(stmt.value, transform, flags);
|
|
9448
9579
|
}
|
|
9580
|
+
else if (stmt instanceof DeclareVarStmt) {
|
|
9581
|
+
if (stmt.value !== undefined) {
|
|
9582
|
+
stmt.value = transformExpressionsInExpression(stmt.value, transform, flags);
|
|
9583
|
+
}
|
|
9584
|
+
}
|
|
9449
9585
|
else {
|
|
9450
9586
|
throw new Error(`Unhandled statement kind: ${stmt.constructor.name}`);
|
|
9451
9587
|
}
|
|
@@ -9862,6 +9998,8 @@ function createAttributeOp(target, attributeKind, name, value) {
|
|
|
9862
9998
|
attributeKind,
|
|
9863
9999
|
name,
|
|
9864
10000
|
value,
|
|
10001
|
+
...TRAIT_DEPENDS_ON_SLOT_CONTEXT,
|
|
10002
|
+
...TRAIT_CONSUMES_VARS,
|
|
9865
10003
|
...NEW_OP,
|
|
9866
10004
|
};
|
|
9867
10005
|
}
|
|
@@ -9881,6 +10019,19 @@ function createInterpolatePropertyOp(xref, bindingKind, name, strings, expressio
|
|
|
9881
10019
|
...NEW_OP,
|
|
9882
10020
|
};
|
|
9883
10021
|
}
|
|
10022
|
+
function createInterpolateAttributeOp(target, attributeKind, name, strings, expressions) {
|
|
10023
|
+
return {
|
|
10024
|
+
kind: OpKind.InterpolateAttribute,
|
|
10025
|
+
target: target,
|
|
10026
|
+
attributeKind,
|
|
10027
|
+
name,
|
|
10028
|
+
strings,
|
|
10029
|
+
expressions,
|
|
10030
|
+
...TRAIT_DEPENDS_ON_SLOT_CONTEXT,
|
|
10031
|
+
...TRAIT_CONSUMES_VARS,
|
|
10032
|
+
...NEW_OP,
|
|
10033
|
+
};
|
|
10034
|
+
}
|
|
9884
10035
|
/**
|
|
9885
10036
|
* Create a `InterpolateStyleProp`.
|
|
9886
10037
|
*/
|
|
@@ -9972,6 +10123,9 @@ function varsUsedByOp(op) {
|
|
|
9972
10123
|
case OpKind.StyleMap:
|
|
9973
10124
|
// Property bindings use 1 variable slot.
|
|
9974
10125
|
return 1;
|
|
10126
|
+
case OpKind.Attribute:
|
|
10127
|
+
// Attribute bindings use 1 variable slot.
|
|
10128
|
+
return 1;
|
|
9975
10129
|
case OpKind.InterpolateText:
|
|
9976
10130
|
// `ir.InterpolateTextOp`s use a variable slot for each dynamic expression.
|
|
9977
10131
|
return op.expressions.length;
|
|
@@ -9981,6 +10135,9 @@ function varsUsedByOp(op) {
|
|
|
9981
10135
|
// `ir.InterpolatePropertyOp`s use a variable slot for each dynamic expression, plus one for
|
|
9982
10136
|
// the result.
|
|
9983
10137
|
return 1 + op.expressions.length;
|
|
10138
|
+
case OpKind.InterpolateAttribute:
|
|
10139
|
+
// One variable slot for each dynamic expression, plus one for the result.
|
|
10140
|
+
return 1 + op.expressions.length;
|
|
9984
10141
|
default:
|
|
9985
10142
|
throw new Error(`Unhandled op: ${OpKind[op.kind]}`);
|
|
9986
10143
|
}
|
|
@@ -10126,6 +10283,7 @@ const CHAINABLE = new Set([
|
|
|
10126
10283
|
Identifiers.elementEnd,
|
|
10127
10284
|
Identifiers.property,
|
|
10128
10285
|
Identifiers.styleProp,
|
|
10286
|
+
Identifiers.attribute,
|
|
10129
10287
|
Identifiers.elementContainerStart,
|
|
10130
10288
|
Identifiers.elementContainerEnd,
|
|
10131
10289
|
Identifiers.elementContainer,
|
|
@@ -10323,10 +10481,11 @@ function phaseNullishCoalescing(cpl) {
|
|
|
10323
10481
|
expr.operator !== BinaryOperator.NullishCoalesce) {
|
|
10324
10482
|
return expr;
|
|
10325
10483
|
}
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
// compatibility mode
|
|
10329
|
-
|
|
10484
|
+
const assignment = new AssignTemporaryExpr(expr.lhs.clone(), cpl.allocateXrefId());
|
|
10485
|
+
const read = new ReadTemporaryExpr(assignment.xref);
|
|
10486
|
+
// TODO: When not in compatibility mode for TemplateDefinitionBuilder, we can just emit
|
|
10487
|
+
// `t != null` instead of including an undefined check as well.
|
|
10488
|
+
return new ConditionalExpr(new BinaryOperatorExpr(BinaryOperator.And, new BinaryOperatorExpr(BinaryOperator.NotIdentical, assignment, NULL_EXPR), new BinaryOperatorExpr(BinaryOperator.NotIdentical, read, new LiteralExpr(undefined))), read.clone(), expr.rhs);
|
|
10330
10489
|
}, VisitorContextFlag.None);
|
|
10331
10490
|
}
|
|
10332
10491
|
}
|
|
@@ -10359,11 +10518,6 @@ function phaseGenerateVariables(cpl) {
|
|
|
10359
10518
|
function recursivelyProcessView(view, parentScope) {
|
|
10360
10519
|
// Extract a `Scope` from this view.
|
|
10361
10520
|
const scope = getScopeForView(view, parentScope);
|
|
10362
|
-
// Embedded views require an operation to save/restore the view context.
|
|
10363
|
-
if (view.parent !== null) {
|
|
10364
|
-
// Start the view creation block with an operation to save the current view context. This may be
|
|
10365
|
-
// used to restore the view context in any listeners that may be present.
|
|
10366
|
-
}
|
|
10367
10521
|
for (const op of view.create) {
|
|
10368
10522
|
switch (op.kind) {
|
|
10369
10523
|
case OpKind.Template:
|
|
@@ -10902,6 +11056,9 @@ function property(name, expression) {
|
|
|
10902
11056
|
expression,
|
|
10903
11057
|
]);
|
|
10904
11058
|
}
|
|
11059
|
+
function attribute(name, expression) {
|
|
11060
|
+
return call(Identifiers.attribute, [literal(name), expression]);
|
|
11061
|
+
}
|
|
10905
11062
|
function styleProp(name, expression, unit) {
|
|
10906
11063
|
const args = [literal(name), expression];
|
|
10907
11064
|
if (unit !== null) {
|
|
@@ -10958,6 +11115,10 @@ function propertyInterpolate(name, strings, expressions) {
|
|
|
10958
11115
|
const interpolationArgs = collateInterpolationArgs(strings, expressions);
|
|
10959
11116
|
return callVariadicInstruction(PROPERTY_INTERPOLATE_CONFIG, [literal(name)], interpolationArgs);
|
|
10960
11117
|
}
|
|
11118
|
+
function attributeInterpolate(name, strings, expressions) {
|
|
11119
|
+
const interpolationArgs = collateInterpolationArgs(strings, expressions);
|
|
11120
|
+
return callVariadicInstruction(ATTRIBUTE_INTERPOLATE_CONFIG, [literal(name)], interpolationArgs);
|
|
11121
|
+
}
|
|
10961
11122
|
function stylePropInterpolate(name, strings, expressions, unit) {
|
|
10962
11123
|
const interpolationArgs = collateInterpolationArgs(strings, expressions);
|
|
10963
11124
|
const extraArgs = [];
|
|
@@ -11072,6 +11233,29 @@ const STYLE_PROP_INTERPOLATE_CONFIG = {
|
|
|
11072
11233
|
return (n - 1) / 2;
|
|
11073
11234
|
},
|
|
11074
11235
|
};
|
|
11236
|
+
/**
|
|
11237
|
+
* `InterpolationConfig` for the `attributeInterpolate` instruction.
|
|
11238
|
+
*/
|
|
11239
|
+
const ATTRIBUTE_INTERPOLATE_CONFIG = {
|
|
11240
|
+
constant: [
|
|
11241
|
+
Identifiers.attribute,
|
|
11242
|
+
Identifiers.attributeInterpolate1,
|
|
11243
|
+
Identifiers.attributeInterpolate2,
|
|
11244
|
+
Identifiers.attributeInterpolate3,
|
|
11245
|
+
Identifiers.attributeInterpolate4,
|
|
11246
|
+
Identifiers.attributeInterpolate5,
|
|
11247
|
+
Identifiers.attributeInterpolate6,
|
|
11248
|
+
Identifiers.attributeInterpolate7,
|
|
11249
|
+
Identifiers.attributeInterpolate8,
|
|
11250
|
+
],
|
|
11251
|
+
variable: Identifiers.attributeInterpolateV,
|
|
11252
|
+
mapping: n => {
|
|
11253
|
+
if (n % 2 === 0) {
|
|
11254
|
+
throw new Error(`Expected odd number of arguments`);
|
|
11255
|
+
}
|
|
11256
|
+
return (n - 1) / 2;
|
|
11257
|
+
},
|
|
11258
|
+
};
|
|
11075
11259
|
/**
|
|
11076
11260
|
* `InterpolationConfig` for the `styleMapInterpolate` instruction.
|
|
11077
11261
|
*/
|
|
@@ -11227,6 +11411,12 @@ function reifyUpdateOperations(_view, ops) {
|
|
|
11227
11411
|
case OpKind.InterpolateText:
|
|
11228
11412
|
OpList.replace(op, textInterpolate(op.strings, op.expressions));
|
|
11229
11413
|
break;
|
|
11414
|
+
case OpKind.Attribute:
|
|
11415
|
+
OpList.replace(op, attribute(op.name, op.value));
|
|
11416
|
+
break;
|
|
11417
|
+
case OpKind.InterpolateAttribute:
|
|
11418
|
+
OpList.replace(op, attributeInterpolate(op.name, op.strings, op.expressions));
|
|
11419
|
+
break;
|
|
11230
11420
|
case OpKind.Variable:
|
|
11231
11421
|
if (op.variable.name === null) {
|
|
11232
11422
|
throw new Error(`AssertionError: unnamed variable ${op.xref}`);
|
|
@@ -11266,6 +11456,16 @@ function reifyIrExpression(expr) {
|
|
|
11266
11456
|
throw new Error(`Read of unnamed variable ${expr.xref}`);
|
|
11267
11457
|
}
|
|
11268
11458
|
return variable(expr.name);
|
|
11459
|
+
case ExpressionKind.ReadTemporaryExpr:
|
|
11460
|
+
if (expr.name === null) {
|
|
11461
|
+
throw new Error(`Read of unnamed temporary ${expr.xref}`);
|
|
11462
|
+
}
|
|
11463
|
+
return variable(expr.name);
|
|
11464
|
+
case ExpressionKind.AssignTemporaryExpr:
|
|
11465
|
+
if (expr.name === null) {
|
|
11466
|
+
throw new Error(`Assign of unnamed temporary ${expr.xref}`);
|
|
11467
|
+
}
|
|
11468
|
+
return variable(expr.name).set(expr.expr);
|
|
11269
11469
|
case ExpressionKind.PureFunctionExpr:
|
|
11270
11470
|
if (expr.fn === null) {
|
|
11271
11471
|
throw new Error(`AssertionError: expected PureFunctions to have been extracted`);
|
|
@@ -11453,14 +11653,17 @@ function processLexicalScope(view, ops, savedView) {
|
|
|
11453
11653
|
}
|
|
11454
11654
|
}, VisitorContextFlag.None);
|
|
11455
11655
|
}
|
|
11656
|
+
for (const op of ops) {
|
|
11657
|
+
visitExpressionsInOp(op, expr => {
|
|
11658
|
+
if (expr instanceof LexicalReadExpr) {
|
|
11659
|
+
throw new Error(`AssertionError: no lexical reads should remain, but found read of ${expr.name}`);
|
|
11660
|
+
}
|
|
11661
|
+
});
|
|
11662
|
+
}
|
|
11456
11663
|
}
|
|
11457
11664
|
|
|
11458
11665
|
function phaseSaveRestoreView(cpl) {
|
|
11459
11666
|
for (const view of cpl.views.values()) {
|
|
11460
|
-
if (view === cpl.root) {
|
|
11461
|
-
// Save/restore operations are not necessary for the root view.
|
|
11462
|
-
continue;
|
|
11463
|
-
}
|
|
11464
11667
|
view.create.prepend([
|
|
11465
11668
|
createVariableOp(view.tpl.allocateXrefId(), {
|
|
11466
11669
|
kind: SemanticVariableKind.SavedView,
|
|
@@ -11472,22 +11675,39 @@ function phaseSaveRestoreView(cpl) {
|
|
|
11472
11675
|
if (op.kind !== OpKind.Listener) {
|
|
11473
11676
|
continue;
|
|
11474
11677
|
}
|
|
11475
|
-
|
|
11476
|
-
|
|
11477
|
-
|
|
11478
|
-
|
|
11479
|
-
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
|
|
11485
|
-
for (const handlerOp of op.handlerOps) {
|
|
11486
|
-
if (handlerOp.kind === OpKind.Statement &&
|
|
11487
|
-
handlerOp.statement instanceof ReturnStatement) {
|
|
11488
|
-
handlerOp.statement.value = new ResetViewExpr(handlerOp.statement.value);
|
|
11678
|
+
// Embedded views always need the save/restore view operation.
|
|
11679
|
+
let needsRestoreView = view !== cpl.root;
|
|
11680
|
+
if (!needsRestoreView) {
|
|
11681
|
+
for (const handlerOp of op.handlerOps) {
|
|
11682
|
+
visitExpressionsInOp(handlerOp, expr => {
|
|
11683
|
+
if (expr instanceof ReferenceExpr) {
|
|
11684
|
+
// Listeners that reference() a local ref need the save/restore view operation.
|
|
11685
|
+
needsRestoreView = true;
|
|
11686
|
+
}
|
|
11687
|
+
});
|
|
11489
11688
|
}
|
|
11490
11689
|
}
|
|
11690
|
+
if (needsRestoreView) {
|
|
11691
|
+
addSaveRestoreViewOperationToListener(view, op);
|
|
11692
|
+
}
|
|
11693
|
+
}
|
|
11694
|
+
}
|
|
11695
|
+
}
|
|
11696
|
+
function addSaveRestoreViewOperationToListener(view, op) {
|
|
11697
|
+
op.handlerOps.prepend([
|
|
11698
|
+
createVariableOp(view.tpl.allocateXrefId(), {
|
|
11699
|
+
kind: SemanticVariableKind.Context,
|
|
11700
|
+
name: null,
|
|
11701
|
+
view: view.xref,
|
|
11702
|
+
}, new RestoreViewExpr(view.xref)),
|
|
11703
|
+
]);
|
|
11704
|
+
// The "restore view" operation in listeners requires a call to `resetView` to reset the
|
|
11705
|
+
// context prior to returning from the listener operation. Find any `return` statements in
|
|
11706
|
+
// the listener body and wrap them in a call to reset the view.
|
|
11707
|
+
for (const handlerOp of op.handlerOps) {
|
|
11708
|
+
if (handlerOp.kind === OpKind.Statement &&
|
|
11709
|
+
handlerOp.statement instanceof ReturnStatement) {
|
|
11710
|
+
handlerOp.statement.value = new ResetViewExpr(handlerOp.statement.value);
|
|
11491
11711
|
}
|
|
11492
11712
|
}
|
|
11493
11713
|
}
|
|
@@ -11936,19 +12156,107 @@ function allowConservativeInlining(decl, target) {
|
|
|
11936
12156
|
* Finds all unresolved safe read expressions, and converts them into the appropriate output AST
|
|
11937
12157
|
* reads, guarded by null checks.
|
|
11938
12158
|
*/
|
|
11939
|
-
function phaseExpandSafeReads(cpl) {
|
|
12159
|
+
function phaseExpandSafeReads(cpl, compatibility) {
|
|
11940
12160
|
for (const [_, view] of cpl.views) {
|
|
11941
12161
|
for (const op of view.ops()) {
|
|
11942
|
-
transformExpressionsInOp(op, safeTransform, VisitorContextFlag.None);
|
|
12162
|
+
transformExpressionsInOp(op, e => safeTransform(e, { cpl, compatibility }), VisitorContextFlag.None);
|
|
11943
12163
|
transformExpressionsInOp(op, ternaryTransform, VisitorContextFlag.None);
|
|
11944
12164
|
}
|
|
11945
12165
|
}
|
|
11946
12166
|
}
|
|
12167
|
+
// A lookup set of all the expression kinds that require a temporary variable to be generated.
|
|
12168
|
+
const requiresTemporary = [
|
|
12169
|
+
InvokeFunctionExpr, LiteralArrayExpr, LiteralMapExpr, SafeInvokeFunctionExpr,
|
|
12170
|
+
PipeBindingExpr
|
|
12171
|
+
].map(e => e.constructor.name);
|
|
12172
|
+
function needsTemporaryInSafeAccess(e) {
|
|
12173
|
+
// TODO: We probably want to use an expression visitor to recursively visit all descendents.
|
|
12174
|
+
// However, that would potentially do a lot of extra work (because it cannot short circuit), so we
|
|
12175
|
+
// implement the logic ourselves for now.
|
|
12176
|
+
if (e instanceof UnaryOperatorExpr) {
|
|
12177
|
+
return needsTemporaryInSafeAccess(e.expr);
|
|
12178
|
+
}
|
|
12179
|
+
else if (e instanceof BinaryOperatorExpr) {
|
|
12180
|
+
return needsTemporaryInSafeAccess(e.lhs) || needsTemporaryInSafeAccess(e.rhs);
|
|
12181
|
+
}
|
|
12182
|
+
else if (e instanceof ConditionalExpr) {
|
|
12183
|
+
if (e.falseCase && needsTemporaryInSafeAccess(e.falseCase))
|
|
12184
|
+
return true;
|
|
12185
|
+
return needsTemporaryInSafeAccess(e.condition) || needsTemporaryInSafeAccess(e.trueCase);
|
|
12186
|
+
}
|
|
12187
|
+
else if (e instanceof NotExpr) {
|
|
12188
|
+
return needsTemporaryInSafeAccess(e.condition);
|
|
12189
|
+
}
|
|
12190
|
+
else if (e instanceof AssignTemporaryExpr) {
|
|
12191
|
+
return needsTemporaryInSafeAccess(e.expr);
|
|
12192
|
+
}
|
|
12193
|
+
else if (e instanceof ReadPropExpr) {
|
|
12194
|
+
return needsTemporaryInSafeAccess(e.receiver);
|
|
12195
|
+
}
|
|
12196
|
+
else if (e instanceof ReadKeyExpr) {
|
|
12197
|
+
return needsTemporaryInSafeAccess(e.receiver) || needsTemporaryInSafeAccess(e.index);
|
|
12198
|
+
}
|
|
12199
|
+
// TODO: Switch to a method which is exhaustive of newly added expression subtypes.
|
|
12200
|
+
return e instanceof InvokeFunctionExpr || e instanceof LiteralArrayExpr ||
|
|
12201
|
+
e instanceof LiteralMapExpr || e instanceof SafeInvokeFunctionExpr ||
|
|
12202
|
+
e instanceof PipeBindingExpr;
|
|
12203
|
+
}
|
|
12204
|
+
function temporariesIn(e) {
|
|
12205
|
+
const temporaries = new Set();
|
|
12206
|
+
// TODO: Although it's not currently supported by the transform helper, we should be able to
|
|
12207
|
+
// short-circuit exploring the tree to do less work. In particular, we don't have to penetrate
|
|
12208
|
+
// into the subexpressions of temporary assignments.
|
|
12209
|
+
transformExpressionsInExpression(e, e => {
|
|
12210
|
+
if (e instanceof AssignTemporaryExpr) {
|
|
12211
|
+
temporaries.add(e.xref);
|
|
12212
|
+
}
|
|
12213
|
+
return e;
|
|
12214
|
+
}, VisitorContextFlag.None);
|
|
12215
|
+
return temporaries;
|
|
12216
|
+
}
|
|
12217
|
+
function eliminateTemporaryAssignments(e, tmps, ctx) {
|
|
12218
|
+
// TODO: We can be more efficient than the transform helper here. We don't need to visit any
|
|
12219
|
+
// descendents of temporary assignments.
|
|
12220
|
+
transformExpressionsInExpression(e, e => {
|
|
12221
|
+
if (e instanceof AssignTemporaryExpr && tmps.has(e.xref)) {
|
|
12222
|
+
const read = new ReadTemporaryExpr(e.xref);
|
|
12223
|
+
// `TemplateDefinitionBuilder` has the (accidental?) behavior of generating assignments of
|
|
12224
|
+
// temporary variables to themselves. This happens because some subexpression that the
|
|
12225
|
+
// temporary refers to, possibly through nested temporaries, has a function call. We copy that
|
|
12226
|
+
// behavior here.
|
|
12227
|
+
return ctx.compatibility ? new AssignTemporaryExpr(read, read.xref) : read;
|
|
12228
|
+
}
|
|
12229
|
+
return e;
|
|
12230
|
+
}, VisitorContextFlag.None);
|
|
12231
|
+
return e;
|
|
12232
|
+
}
|
|
12233
|
+
/**
|
|
12234
|
+
* Creates a safe ternary guarded by the input expression, and with a body generated by the provided
|
|
12235
|
+
* callback on the input expression. Generates a temporary variable assignment if needed, and
|
|
12236
|
+
* deduplicates nested temporary assignments if needed.
|
|
12237
|
+
*/
|
|
12238
|
+
function safeTernaryWithTemporary(guard, body, ctx) {
|
|
12239
|
+
let result;
|
|
12240
|
+
if (needsTemporaryInSafeAccess(guard)) {
|
|
12241
|
+
const xref = ctx.cpl.allocateXrefId();
|
|
12242
|
+
result = [new AssignTemporaryExpr(guard, xref), new ReadTemporaryExpr(xref)];
|
|
12243
|
+
}
|
|
12244
|
+
else {
|
|
12245
|
+
result = [guard, guard.clone()];
|
|
12246
|
+
// Consider an expression like `a?.[b?.c()]?.d`. The `b?.c()` will be transformed first,
|
|
12247
|
+
// introducing a temporary assignment into the key. Then, as part of expanding the `?.d`. That
|
|
12248
|
+
// assignment will be duplicated into both the guard and expression sides. We de-duplicate it,
|
|
12249
|
+
// by transforming it from an assignment into a read on the expression side.
|
|
12250
|
+
eliminateTemporaryAssignments(result[1], temporariesIn(result[0]), ctx);
|
|
12251
|
+
}
|
|
12252
|
+
return new SafeTernaryExpr(result[0], body(result[1]));
|
|
12253
|
+
}
|
|
11947
12254
|
function isSafeAccessExpression(e) {
|
|
11948
12255
|
return e instanceof SafePropertyReadExpr || e instanceof SafeKeyedReadExpr;
|
|
11949
12256
|
}
|
|
11950
12257
|
function isUnsafeAccessExpression(e) {
|
|
11951
|
-
return e instanceof ReadPropExpr || e instanceof ReadKeyExpr
|
|
12258
|
+
return e instanceof ReadPropExpr || e instanceof ReadKeyExpr ||
|
|
12259
|
+
e instanceof InvokeFunctionExpr;
|
|
11952
12260
|
}
|
|
11953
12261
|
function isAccessExpression(e) {
|
|
11954
12262
|
return isSafeAccessExpression(e) || isUnsafeAccessExpression(e);
|
|
@@ -11964,8 +12272,8 @@ function deepestSafeTernary(e) {
|
|
|
11964
12272
|
return null;
|
|
11965
12273
|
}
|
|
11966
12274
|
// TODO: When strict compatibility with TemplateDefinitionBuilder is not required, we can use `&&`
|
|
11967
|
-
// instead.
|
|
11968
|
-
function safeTransform(e) {
|
|
12275
|
+
// instead to save some code size.
|
|
12276
|
+
function safeTransform(e, ctx) {
|
|
11969
12277
|
if (e instanceof SafeInvokeFunctionExpr) {
|
|
11970
12278
|
// TODO: Implement safe function calls in a subsequent commit.
|
|
11971
12279
|
return new InvokeFunctionExpr(e.receiver, e.args);
|
|
@@ -11975,6 +12283,10 @@ function safeTransform(e) {
|
|
|
11975
12283
|
}
|
|
11976
12284
|
const dst = deepestSafeTernary(e);
|
|
11977
12285
|
if (dst) {
|
|
12286
|
+
if (e instanceof InvokeFunctionExpr) {
|
|
12287
|
+
dst.expr = dst.expr.callFn(e.args);
|
|
12288
|
+
return e.receiver;
|
|
12289
|
+
}
|
|
11978
12290
|
if (e instanceof ReadPropExpr) {
|
|
11979
12291
|
dst.expr = dst.expr.prop(e.name);
|
|
11980
12292
|
return e.receiver;
|
|
@@ -11984,20 +12296,20 @@ function safeTransform(e) {
|
|
|
11984
12296
|
return e.receiver;
|
|
11985
12297
|
}
|
|
11986
12298
|
if (e instanceof SafePropertyReadExpr) {
|
|
11987
|
-
dst.expr =
|
|
12299
|
+
dst.expr = safeTernaryWithTemporary(dst.expr, (r) => r.prop(e.name), ctx);
|
|
11988
12300
|
return e.receiver;
|
|
11989
12301
|
}
|
|
11990
12302
|
if (e instanceof SafeKeyedReadExpr) {
|
|
11991
|
-
dst.expr =
|
|
12303
|
+
dst.expr = safeTernaryWithTemporary(dst.expr, (r) => r.key(e.index), ctx);
|
|
11992
12304
|
return e.receiver;
|
|
11993
12305
|
}
|
|
11994
12306
|
}
|
|
11995
12307
|
else {
|
|
11996
12308
|
if (e instanceof SafePropertyReadExpr) {
|
|
11997
|
-
return
|
|
12309
|
+
return safeTernaryWithTemporary(e.receiver, (r) => r.prop(e.name), ctx);
|
|
11998
12310
|
}
|
|
11999
12311
|
if (e instanceof SafeKeyedReadExpr) {
|
|
12000
|
-
return
|
|
12312
|
+
return safeTernaryWithTemporary(e.receiver, (r) => r.key(e.index), ctx);
|
|
12001
12313
|
}
|
|
12002
12314
|
}
|
|
12003
12315
|
return e;
|
|
@@ -12009,6 +12321,50 @@ function ternaryTransform(e) {
|
|
|
12009
12321
|
return new ConditionalExpr(new BinaryOperatorExpr(BinaryOperator.Equals, e.guard, NULL_EXPR), NULL_EXPR, e.expr);
|
|
12010
12322
|
}
|
|
12011
12323
|
|
|
12324
|
+
/**
|
|
12325
|
+
* Find all assignments and usages of temporary variables, which are linked to each other with cross
|
|
12326
|
+
* references. Generate names for each cross-reference, and add a `DeclareVarStmt` to initialize
|
|
12327
|
+
* them at the beginning of the update block.
|
|
12328
|
+
*
|
|
12329
|
+
* TODO: Sometimes, it will be possible to reuse names across different subexpressions. For example,
|
|
12330
|
+
* in the double keyed read `a?.[f()]?.[f()]`, the two function calls have non-overlapping scopes.
|
|
12331
|
+
* Implement an algorithm for reuse.
|
|
12332
|
+
*/
|
|
12333
|
+
function phaseTemporaryVariables(cpl) {
|
|
12334
|
+
for (const view of cpl.views.values()) {
|
|
12335
|
+
let opCount = 0;
|
|
12336
|
+
let generatedStatements = [];
|
|
12337
|
+
for (const op of view.ops()) {
|
|
12338
|
+
let count = 0;
|
|
12339
|
+
let xrefs = new Set();
|
|
12340
|
+
let defs = new Map();
|
|
12341
|
+
visitExpressionsInOp(op, expr => {
|
|
12342
|
+
if (expr instanceof ReadTemporaryExpr || expr instanceof AssignTemporaryExpr) {
|
|
12343
|
+
xrefs.add(expr.xref);
|
|
12344
|
+
}
|
|
12345
|
+
});
|
|
12346
|
+
for (const xref of xrefs) {
|
|
12347
|
+
// TODO: Exactly replicate the naming scheme used by `TemplateDefinitionBuilder`. It seems
|
|
12348
|
+
// to rely on an expression index instead of an op index.
|
|
12349
|
+
defs.set(xref, `tmp_${opCount}_${count++}`);
|
|
12350
|
+
}
|
|
12351
|
+
visitExpressionsInOp(op, expr => {
|
|
12352
|
+
if (expr instanceof ReadTemporaryExpr || expr instanceof AssignTemporaryExpr) {
|
|
12353
|
+
const name = defs.get(expr.xref);
|
|
12354
|
+
if (name === undefined) {
|
|
12355
|
+
throw new Error('Found xref with unassigned name');
|
|
12356
|
+
}
|
|
12357
|
+
expr.name = name;
|
|
12358
|
+
}
|
|
12359
|
+
});
|
|
12360
|
+
generatedStatements.push(...Array.from(defs.values())
|
|
12361
|
+
.map(name => createStatementOp(new DeclareVarStmt(name))));
|
|
12362
|
+
opCount++;
|
|
12363
|
+
}
|
|
12364
|
+
view.update.prepend(generatedStatements);
|
|
12365
|
+
}
|
|
12366
|
+
}
|
|
12367
|
+
|
|
12012
12368
|
/**
|
|
12013
12369
|
* Run all transformation phases in the correct order against a `ComponentCompilation`. After this
|
|
12014
12370
|
* processing, the compilation should be in a state where it can be emitted via `emitTemplateFn`.s
|
|
@@ -12025,7 +12381,8 @@ function transformTemplate(cpl) {
|
|
|
12025
12381
|
phaseLocalRefs(cpl);
|
|
12026
12382
|
phaseConstCollection(cpl);
|
|
12027
12383
|
phaseNullishCoalescing(cpl);
|
|
12028
|
-
phaseExpandSafeReads(cpl);
|
|
12384
|
+
phaseExpandSafeReads(cpl, true);
|
|
12385
|
+
phaseTemporaryVariables(cpl);
|
|
12029
12386
|
phaseSlotAllocation(cpl);
|
|
12030
12387
|
phaseVarCounting(cpl);
|
|
12031
12388
|
phaseGenerateAdvance(cpl);
|
|
@@ -12422,6 +12779,9 @@ function ingestBindings(view, op, element) {
|
|
|
12422
12779
|
}
|
|
12423
12780
|
}
|
|
12424
12781
|
for (const attr of element.attributes) {
|
|
12782
|
+
// This is only attribute TextLiteral bindings, such as `attr.foo="bar'`. This can never be
|
|
12783
|
+
// `[attr.foo]="bar"` or `attr.foo="{{bar}}"`, both of which will be handled as inputs with
|
|
12784
|
+
// `BindingType.Attribute`.
|
|
12425
12785
|
view.update.push(createAttributeOp(op.xref, ElementAttributeKind.Attribute, attr.name, literal(attr.value)));
|
|
12426
12786
|
}
|
|
12427
12787
|
for (const input of element.inputs) {
|
|
@@ -12478,6 +12838,13 @@ function ingestPropertyBinding(view, xref, bindingKind, { name, value, type, uni
|
|
|
12478
12838
|
}
|
|
12479
12839
|
view.update.push(createInterpolateStylePropOp(xref, name, value.strings, value.expressions.map(expr => convertAst(expr, view.tpl)), unit));
|
|
12480
12840
|
break;
|
|
12841
|
+
case 1 /* e.BindingType.Attribute */:
|
|
12842
|
+
if (bindingKind !== ElementAttributeKind.Binding) {
|
|
12843
|
+
throw new Error('Attribute bindings on templates are not expected to be valid');
|
|
12844
|
+
}
|
|
12845
|
+
const attributeInterpolate = createInterpolateAttributeOp(xref, bindingKind, name, value.strings, value.expressions.map(expr => convertAst(expr, view.tpl)));
|
|
12846
|
+
view.update.push(attributeInterpolate);
|
|
12847
|
+
break;
|
|
12481
12848
|
default:
|
|
12482
12849
|
// TODO: implement remaining binding types.
|
|
12483
12850
|
throw Error(`Interpolated property binding type not handled: ${type}`);
|
|
@@ -12503,6 +12870,13 @@ function ingestPropertyBinding(view, xref, bindingKind, { name, value, type, uni
|
|
|
12503
12870
|
}
|
|
12504
12871
|
view.update.push(createStylePropOp(xref, name, convertAst(value, view.tpl), unit));
|
|
12505
12872
|
break;
|
|
12873
|
+
case 1 /* e.BindingType.Attribute */:
|
|
12874
|
+
if (bindingKind !== ElementAttributeKind.Binding) {
|
|
12875
|
+
throw new Error('Attribute bindings on templates are not expected to be valid');
|
|
12876
|
+
}
|
|
12877
|
+
const attrOp = createAttributeOp(xref, bindingKind, name, convertAst(value, view.tpl));
|
|
12878
|
+
view.update.push(attrOp);
|
|
12879
|
+
break;
|
|
12506
12880
|
default:
|
|
12507
12881
|
// TODO: implement remaining binding types.
|
|
12508
12882
|
throw Error(`Property binding type not handled: ${type}`);
|
|
@@ -14851,6 +15225,39 @@ class Comment {
|
|
|
14851
15225
|
return visitor.visitComment(this, context);
|
|
14852
15226
|
}
|
|
14853
15227
|
}
|
|
15228
|
+
class BlockGroup {
|
|
15229
|
+
constructor(blocks, sourceSpan, startSourceSpan, endSourceSpan = null) {
|
|
15230
|
+
this.blocks = blocks;
|
|
15231
|
+
this.sourceSpan = sourceSpan;
|
|
15232
|
+
this.startSourceSpan = startSourceSpan;
|
|
15233
|
+
this.endSourceSpan = endSourceSpan;
|
|
15234
|
+
}
|
|
15235
|
+
visit(visitor, context) {
|
|
15236
|
+
return visitor.visitBlockGroup(this, context);
|
|
15237
|
+
}
|
|
15238
|
+
}
|
|
15239
|
+
class Block {
|
|
15240
|
+
constructor(name, parameters, children, sourceSpan, startSourceSpan, endSourceSpan = null) {
|
|
15241
|
+
this.name = name;
|
|
15242
|
+
this.parameters = parameters;
|
|
15243
|
+
this.children = children;
|
|
15244
|
+
this.sourceSpan = sourceSpan;
|
|
15245
|
+
this.startSourceSpan = startSourceSpan;
|
|
15246
|
+
this.endSourceSpan = endSourceSpan;
|
|
15247
|
+
}
|
|
15248
|
+
visit(visitor, context) {
|
|
15249
|
+
return visitor.visitBlock(this, context);
|
|
15250
|
+
}
|
|
15251
|
+
}
|
|
15252
|
+
class BlockParameter {
|
|
15253
|
+
constructor(expression, sourceSpan) {
|
|
15254
|
+
this.expression = expression;
|
|
15255
|
+
this.sourceSpan = sourceSpan;
|
|
15256
|
+
}
|
|
15257
|
+
visit(visitor, context) {
|
|
15258
|
+
return visitor.visitBlockParameter(this, context);
|
|
15259
|
+
}
|
|
15260
|
+
}
|
|
14854
15261
|
function visitAll(visitor, nodes, context = null) {
|
|
14855
15262
|
const result = [];
|
|
14856
15263
|
const visit = visitor.visit ?
|
|
@@ -14881,6 +15288,18 @@ class RecursiveVisitor {
|
|
|
14881
15288
|
});
|
|
14882
15289
|
}
|
|
14883
15290
|
visitExpansionCase(ast, context) { }
|
|
15291
|
+
visitBlockGroup(ast, context) {
|
|
15292
|
+
this.visitChildren(context, visit => {
|
|
15293
|
+
visit(ast.blocks);
|
|
15294
|
+
});
|
|
15295
|
+
}
|
|
15296
|
+
visitBlock(block, context) {
|
|
15297
|
+
this.visitChildren(context, visit => {
|
|
15298
|
+
visit(block.parameters);
|
|
15299
|
+
visit(block.children);
|
|
15300
|
+
});
|
|
15301
|
+
}
|
|
15302
|
+
visitBlockParameter(ast, context) { }
|
|
14884
15303
|
visitChildren(context, cb) {
|
|
14885
15304
|
let results = [];
|
|
14886
15305
|
let t = this;
|
|
@@ -17633,8 +18052,8 @@ class _Tokenizer {
|
|
|
17633
18052
|
this._cursor = options.escapedString ? new EscapedCharacterCursor(_file, range) :
|
|
17634
18053
|
new PlainCharacterCursor(_file, range);
|
|
17635
18054
|
this._preserveLineEndings = options.preserveLineEndings || false;
|
|
17636
|
-
this._escapedString = options.escapedString || false;
|
|
17637
18055
|
this._i18nNormalizeLineEndingsInICUs = options.i18nNormalizeLineEndingsInICUs || false;
|
|
18056
|
+
this._tokenizeBlocks = options.tokenizeBlocks || false;
|
|
17638
18057
|
try {
|
|
17639
18058
|
this._cursor.init();
|
|
17640
18059
|
}
|
|
@@ -17675,6 +18094,15 @@ class _Tokenizer {
|
|
|
17675
18094
|
this._consumeTagOpen(start);
|
|
17676
18095
|
}
|
|
17677
18096
|
}
|
|
18097
|
+
else if (this._tokenizeBlocks && this._attemptStr('{#')) {
|
|
18098
|
+
this._consumeBlockGroupOpen(start);
|
|
18099
|
+
}
|
|
18100
|
+
else if (this._tokenizeBlocks && this._attemptStr('{/')) {
|
|
18101
|
+
this._consumeBlockGroupClose(start);
|
|
18102
|
+
}
|
|
18103
|
+
else if (this._tokenizeBlocks && this._attemptStr('{:')) {
|
|
18104
|
+
this._consumeBlock(start);
|
|
18105
|
+
}
|
|
17678
18106
|
else if (!(this._tokenizeIcu && this._tokenizeExpansionForm())) {
|
|
17679
18107
|
// In (possibly interpolated) text the end of the text is given by `isTextEnd()`, while
|
|
17680
18108
|
// the premature end of an interpolation is given by the start of a new HTML element.
|
|
@@ -17688,6 +18116,64 @@ class _Tokenizer {
|
|
|
17688
18116
|
this._beginToken(24 /* TokenType.EOF */);
|
|
17689
18117
|
this._endToken([]);
|
|
17690
18118
|
}
|
|
18119
|
+
_consumeBlockGroupOpen(start) {
|
|
18120
|
+
this._beginToken(25 /* TokenType.BLOCK_GROUP_OPEN_START */, start);
|
|
18121
|
+
const nameCursor = this._cursor.clone();
|
|
18122
|
+
this._attemptCharCodeUntilFn(code => !isBlockNameChar(code));
|
|
18123
|
+
this._endToken([this._cursor.getChars(nameCursor)]);
|
|
18124
|
+
this._consumeBlockParameters();
|
|
18125
|
+
this._beginToken(26 /* TokenType.BLOCK_GROUP_OPEN_END */);
|
|
18126
|
+
this._requireCharCode($RBRACE);
|
|
18127
|
+
this._endToken([]);
|
|
18128
|
+
}
|
|
18129
|
+
_consumeBlockGroupClose(start) {
|
|
18130
|
+
this._beginToken(27 /* TokenType.BLOCK_GROUP_CLOSE */, start);
|
|
18131
|
+
const nameCursor = this._cursor.clone();
|
|
18132
|
+
this._attemptCharCodeUntilFn(code => !isBlockNameChar(code));
|
|
18133
|
+
const name = this._cursor.getChars(nameCursor);
|
|
18134
|
+
this._requireCharCode($RBRACE);
|
|
18135
|
+
this._endToken([name]);
|
|
18136
|
+
}
|
|
18137
|
+
_consumeBlock(start) {
|
|
18138
|
+
this._beginToken(29 /* TokenType.BLOCK_OPEN_START */, start);
|
|
18139
|
+
const nameCursor = this._cursor.clone();
|
|
18140
|
+
this._attemptCharCodeUntilFn(code => !isBlockNameChar(code));
|
|
18141
|
+
this._endToken([this._cursor.getChars(nameCursor)]);
|
|
18142
|
+
this._consumeBlockParameters();
|
|
18143
|
+
this._beginToken(30 /* TokenType.BLOCK_OPEN_END */);
|
|
18144
|
+
this._requireCharCode($RBRACE);
|
|
18145
|
+
this._endToken([]);
|
|
18146
|
+
}
|
|
18147
|
+
_consumeBlockParameters() {
|
|
18148
|
+
// Trim the whitespace until the first parameter.
|
|
18149
|
+
this._attemptCharCodeUntilFn(isBlockParameterChar);
|
|
18150
|
+
while (this._cursor.peek() !== $RBRACE && this._cursor.peek() !== $EOF) {
|
|
18151
|
+
this._beginToken(28 /* TokenType.BLOCK_PARAMETER */);
|
|
18152
|
+
const start = this._cursor.clone();
|
|
18153
|
+
let inQuote = null;
|
|
18154
|
+
// Consume the parameter until the next semicolon or brace.
|
|
18155
|
+
// Note that we skip over semicolons/braces inside of strings.
|
|
18156
|
+
while ((this._cursor.peek() !== $SEMICOLON && this._cursor.peek() !== $RBRACE &&
|
|
18157
|
+
this._cursor.peek() !== $EOF) ||
|
|
18158
|
+
inQuote !== null) {
|
|
18159
|
+
const char = this._cursor.peek();
|
|
18160
|
+
// Skip to the next character if it was escaped.
|
|
18161
|
+
if (char === $BACKSLASH) {
|
|
18162
|
+
this._cursor.advance();
|
|
18163
|
+
}
|
|
18164
|
+
else if (char === inQuote) {
|
|
18165
|
+
inQuote = null;
|
|
18166
|
+
}
|
|
18167
|
+
else if (inQuote === null && isQuote(char)) {
|
|
18168
|
+
inQuote = char;
|
|
18169
|
+
}
|
|
18170
|
+
this._cursor.advance();
|
|
18171
|
+
}
|
|
18172
|
+
this._endToken([this._cursor.getChars(start)]);
|
|
18173
|
+
// Skip to the next parameter.
|
|
18174
|
+
this._attemptCharCodeUntilFn(isBlockParameterChar);
|
|
18175
|
+
}
|
|
18176
|
+
}
|
|
17691
18177
|
/**
|
|
17692
18178
|
* @returns whether an ICU token has been created
|
|
17693
18179
|
* @internal
|
|
@@ -18021,7 +18507,6 @@ class _Tokenizer {
|
|
|
18021
18507
|
this._endToken(prefixAndName);
|
|
18022
18508
|
}
|
|
18023
18509
|
_consumeAttributeValue() {
|
|
18024
|
-
let value;
|
|
18025
18510
|
if (this._cursor.peek() === $SQ || this._cursor.peek() === $DQ) {
|
|
18026
18511
|
const quoteChar = this._cursor.peek();
|
|
18027
18512
|
this._consumeQuote(quoteChar);
|
|
@@ -18210,7 +18695,7 @@ class _Tokenizer {
|
|
|
18210
18695
|
return this._processCarriageReturns(end.getChars(start));
|
|
18211
18696
|
}
|
|
18212
18697
|
_isTextEnd() {
|
|
18213
|
-
if (this._isTagStart() || this._cursor.peek() === $EOF) {
|
|
18698
|
+
if (this._isTagStart() || this._isBlockStart() || this._cursor.peek() === $EOF) {
|
|
18214
18699
|
return true;
|
|
18215
18700
|
}
|
|
18216
18701
|
if (this._tokenizeIcu && !this._inInterpolation) {
|
|
@@ -18243,6 +18728,23 @@ class _Tokenizer {
|
|
|
18243
18728
|
}
|
|
18244
18729
|
return false;
|
|
18245
18730
|
}
|
|
18731
|
+
_isBlockStart() {
|
|
18732
|
+
if (this._tokenizeBlocks && this._cursor.peek() === $LBRACE) {
|
|
18733
|
+
const tmp = this._cursor.clone();
|
|
18734
|
+
// Check that the cursor is on a `{#`, `{/` or `{:`.
|
|
18735
|
+
tmp.advance();
|
|
18736
|
+
const next = tmp.peek();
|
|
18737
|
+
if (next !== $BANG && next !== $SLASH && next !== $COLON) {
|
|
18738
|
+
return false;
|
|
18739
|
+
}
|
|
18740
|
+
// If it is, also verify that the next character is a valid block identifier.
|
|
18741
|
+
tmp.advance();
|
|
18742
|
+
if (isBlockNameChar(tmp.peek())) {
|
|
18743
|
+
return true;
|
|
18744
|
+
}
|
|
18745
|
+
}
|
|
18746
|
+
return false;
|
|
18747
|
+
}
|
|
18246
18748
|
_readUntil(char) {
|
|
18247
18749
|
const start = this._cursor.clone();
|
|
18248
18750
|
this._attemptUntilChar(char);
|
|
@@ -18298,6 +18800,12 @@ function compareCharCodeCaseInsensitive(code1, code2) {
|
|
|
18298
18800
|
function toUpperCaseCharCode(code) {
|
|
18299
18801
|
return code >= $a && code <= $z ? code - $a + $A : code;
|
|
18300
18802
|
}
|
|
18803
|
+
function isBlockNameChar(code) {
|
|
18804
|
+
return isAsciiLetter(code) || isDigit(code) || code === $_;
|
|
18805
|
+
}
|
|
18806
|
+
function isBlockParameterChar(code) {
|
|
18807
|
+
return code !== $SEMICOLON && isNotWhitespace(code);
|
|
18808
|
+
}
|
|
18301
18809
|
function mergeTextTokens(srcTokens) {
|
|
18302
18810
|
const dstTokens = [];
|
|
18303
18811
|
let lastDstToken = undefined;
|
|
@@ -18585,7 +19093,7 @@ class _TreeBuilder {
|
|
|
18585
19093
|
this.tokens = tokens;
|
|
18586
19094
|
this.getTagDefinition = getTagDefinition;
|
|
18587
19095
|
this._index = -1;
|
|
18588
|
-
this.
|
|
19096
|
+
this._containerStack = [];
|
|
18589
19097
|
this.rootNodes = [];
|
|
18590
19098
|
this.errors = [];
|
|
18591
19099
|
this._advance();
|
|
@@ -18615,6 +19123,18 @@ class _TreeBuilder {
|
|
|
18615
19123
|
else if (this._peek.type === 19 /* TokenType.EXPANSION_FORM_START */) {
|
|
18616
19124
|
this._consumeExpansion(this._advance());
|
|
18617
19125
|
}
|
|
19126
|
+
else if (this._peek.type === 25 /* TokenType.BLOCK_GROUP_OPEN_START */) {
|
|
19127
|
+
this._closeVoidElement();
|
|
19128
|
+
this._consumeBlockGroupOpen(this._advance());
|
|
19129
|
+
}
|
|
19130
|
+
else if (this._peek.type === 29 /* TokenType.BLOCK_OPEN_START */) {
|
|
19131
|
+
this._closeVoidElement();
|
|
19132
|
+
this._consumeBlock(this._advance(), 30 /* TokenType.BLOCK_OPEN_END */);
|
|
19133
|
+
}
|
|
19134
|
+
else if (this._peek.type === 27 /* TokenType.BLOCK_GROUP_CLOSE */) {
|
|
19135
|
+
this._closeVoidElement();
|
|
19136
|
+
this._consumeBlockGroupClose(this._advance());
|
|
19137
|
+
}
|
|
18618
19138
|
else {
|
|
18619
19139
|
// Skip all other tokens...
|
|
18620
19140
|
this._advance();
|
|
@@ -18731,7 +19251,12 @@ class _TreeBuilder {
|
|
|
18731
19251
|
const startSpan = token.sourceSpan;
|
|
18732
19252
|
let text = token.parts[0];
|
|
18733
19253
|
if (text.length > 0 && text[0] === '\n') {
|
|
18734
|
-
const parent = this.
|
|
19254
|
+
const parent = this._getContainer();
|
|
19255
|
+
// This is unlikely to happen, but we have an assertion just in case.
|
|
19256
|
+
if (parent instanceof BlockGroup) {
|
|
19257
|
+
this.errors.push(TreeError.create(null, startSpan, 'Text cannot be placed directly inside of a block group.'));
|
|
19258
|
+
return null;
|
|
19259
|
+
}
|
|
18735
19260
|
if (parent != null && parent.children.length === 0 &&
|
|
18736
19261
|
this.getTagDefinition(parent.name).ignoreFirstLf) {
|
|
18737
19262
|
text = text.substring(1);
|
|
@@ -18762,9 +19287,9 @@ class _TreeBuilder {
|
|
|
18762
19287
|
}
|
|
18763
19288
|
}
|
|
18764
19289
|
_closeVoidElement() {
|
|
18765
|
-
const el = this.
|
|
18766
|
-
if (el && this.getTagDefinition(el.name).isVoid) {
|
|
18767
|
-
this.
|
|
19290
|
+
const el = this._getContainer();
|
|
19291
|
+
if (el instanceof Element && this.getTagDefinition(el.name).isVoid) {
|
|
19292
|
+
this._containerStack.pop();
|
|
18768
19293
|
}
|
|
18769
19294
|
}
|
|
18770
19295
|
_consumeStartTag(startTagToken) {
|
|
@@ -18773,7 +19298,7 @@ class _TreeBuilder {
|
|
|
18773
19298
|
while (this._peek.type === 14 /* TokenType.ATTR_NAME */) {
|
|
18774
19299
|
attrs.push(this._consumeAttr(this._advance()));
|
|
18775
19300
|
}
|
|
18776
|
-
const fullName = this._getElementFullName(prefix, name, this.
|
|
19301
|
+
const fullName = this._getElementFullName(prefix, name, this._getClosestParentElement());
|
|
18777
19302
|
let selfClosing = false;
|
|
18778
19303
|
// Note: There could have been a tokenizer error
|
|
18779
19304
|
// so that we don't get a token for the end tag...
|
|
@@ -18794,33 +19319,34 @@ class _TreeBuilder {
|
|
|
18794
19319
|
// Create a separate `startSpan` because `span` will be modified when there is an `end` span.
|
|
18795
19320
|
const startSpan = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
|
|
18796
19321
|
const el = new Element(fullName, attrs, [], span, startSpan, undefined);
|
|
18797
|
-
this.
|
|
19322
|
+
const parentEl = this._getContainer();
|
|
19323
|
+
this._pushContainer(el, parentEl instanceof Element &&
|
|
19324
|
+
this.getTagDefinition(parentEl.name).isClosedByChild(el.name));
|
|
18798
19325
|
if (selfClosing) {
|
|
18799
19326
|
// Elements that are self-closed have their `endSourceSpan` set to the full span, as the
|
|
18800
19327
|
// element start tag also represents the end tag.
|
|
18801
|
-
this.
|
|
19328
|
+
this._popContainer(fullName, Element, span);
|
|
18802
19329
|
}
|
|
18803
19330
|
else if (startTagToken.type === 4 /* TokenType.INCOMPLETE_TAG_OPEN */) {
|
|
18804
19331
|
// We already know the opening tag is not complete, so it is unlikely it has a corresponding
|
|
18805
19332
|
// close tag. Let's optimistically parse it as a full element and emit an error.
|
|
18806
|
-
this.
|
|
19333
|
+
this._popContainer(fullName, Element, null);
|
|
18807
19334
|
this.errors.push(TreeError.create(fullName, span, `Opening tag "${fullName}" not terminated.`));
|
|
18808
19335
|
}
|
|
18809
19336
|
}
|
|
18810
|
-
|
|
18811
|
-
|
|
18812
|
-
|
|
18813
|
-
this._elementStack.pop();
|
|
19337
|
+
_pushContainer(node, isClosedByChild) {
|
|
19338
|
+
if (isClosedByChild) {
|
|
19339
|
+
this._containerStack.pop();
|
|
18814
19340
|
}
|
|
18815
|
-
this._addToParent(
|
|
18816
|
-
this.
|
|
19341
|
+
this._addToParent(node);
|
|
19342
|
+
this._containerStack.push(node);
|
|
18817
19343
|
}
|
|
18818
19344
|
_consumeEndTag(endTagToken) {
|
|
18819
|
-
const fullName = this._getElementFullName(endTagToken.parts[0], endTagToken.parts[1], this.
|
|
19345
|
+
const fullName = this._getElementFullName(endTagToken.parts[0], endTagToken.parts[1], this._getClosestParentElement());
|
|
18820
19346
|
if (this.getTagDefinition(fullName).isVoid) {
|
|
18821
19347
|
this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, `Void elements do not have end tags "${endTagToken.parts[1]}"`));
|
|
18822
19348
|
}
|
|
18823
|
-
else if (!this.
|
|
19349
|
+
else if (!this._popContainer(fullName, Element, endTagToken.sourceSpan)) {
|
|
18824
19350
|
const errMsg = `Unexpected closing tag "${fullName}". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags`;
|
|
18825
19351
|
this.errors.push(TreeError.create(fullName, endTagToken.sourceSpan, errMsg));
|
|
18826
19352
|
}
|
|
@@ -18831,20 +19357,23 @@ class _TreeBuilder {
|
|
|
18831
19357
|
* not have a closing tag (for example, this happens when an incomplete
|
|
18832
19358
|
* opening tag is recovered).
|
|
18833
19359
|
*/
|
|
18834
|
-
|
|
19360
|
+
_popContainer(fullName, expectedType, endSourceSpan) {
|
|
18835
19361
|
let unexpectedCloseTagDetected = false;
|
|
18836
|
-
for (let stackIndex = this.
|
|
18837
|
-
const
|
|
18838
|
-
|
|
19362
|
+
for (let stackIndex = this._containerStack.length - 1; stackIndex >= 0; stackIndex--) {
|
|
19363
|
+
const node = this._containerStack[stackIndex];
|
|
19364
|
+
const name = node instanceof BlockGroup ? node.blocks[0]?.name : node.name;
|
|
19365
|
+
if (name === fullName && node instanceof expectedType) {
|
|
18839
19366
|
// Record the parse span with the element that is being closed. Any elements that are
|
|
18840
19367
|
// removed from the element stack at this point are closed implicitly, so they won't get
|
|
18841
19368
|
// an end source span (as there is no explicit closing element).
|
|
18842
|
-
|
|
18843
|
-
|
|
18844
|
-
this.
|
|
19369
|
+
node.endSourceSpan = endSourceSpan;
|
|
19370
|
+
node.sourceSpan.end = endSourceSpan !== null ? endSourceSpan.end : node.sourceSpan.end;
|
|
19371
|
+
this._containerStack.splice(stackIndex, this._containerStack.length - stackIndex);
|
|
18845
19372
|
return !unexpectedCloseTagDetected;
|
|
18846
19373
|
}
|
|
18847
|
-
|
|
19374
|
+
// Blocks are self-closing while block groups and (most times) elements are not.
|
|
19375
|
+
if (node instanceof BlockGroup ||
|
|
19376
|
+
node instanceof Element && !this.getTagDefinition(node.name).closedByParent) {
|
|
18848
19377
|
// Note that we encountered an unexpected close tag but continue processing the element
|
|
18849
19378
|
// stack so we can assign an `endSourceSpan` if there is a corresponding start tag for this
|
|
18850
19379
|
// end tag in the stack.
|
|
@@ -18903,16 +19432,92 @@ class _TreeBuilder {
|
|
|
18903
19432
|
new ParseSourceSpan(valueStartSpan.start, valueEnd, valueStartSpan.fullStart);
|
|
18904
19433
|
return new Attribute(fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, attrEnd, attrName.sourceSpan.fullStart), attrName.sourceSpan, valueSpan, valueTokens.length > 0 ? valueTokens : undefined, undefined);
|
|
18905
19434
|
}
|
|
18906
|
-
|
|
18907
|
-
|
|
19435
|
+
_consumeBlockGroupOpen(token) {
|
|
19436
|
+
const end = this._peek.sourceSpan.fullStart;
|
|
19437
|
+
const span = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
|
|
19438
|
+
// Create a separate `startSpan` because `span` will be modified when there is an `end` span.
|
|
19439
|
+
const startSpan = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
|
|
19440
|
+
const blockGroup = new BlockGroup([], span, startSpan, null);
|
|
19441
|
+
this._pushContainer(blockGroup, false);
|
|
19442
|
+
const implicitBlock = this._consumeBlock(token, 26 /* TokenType.BLOCK_GROUP_OPEN_END */);
|
|
19443
|
+
// Block parameters are consumed as a part of the implicit block so we need to expand the
|
|
19444
|
+
// start source span once the block is parsed to include the full opening tag.
|
|
19445
|
+
startSpan.end = implicitBlock.startSourceSpan.end;
|
|
19446
|
+
}
|
|
19447
|
+
_consumeBlock(token, closeToken) {
|
|
19448
|
+
// The start of a block implicitly closes the previous block.
|
|
19449
|
+
this._conditionallyClosePreviousBlock();
|
|
19450
|
+
const parameters = [];
|
|
19451
|
+
while (this._peek.type === 28 /* TokenType.BLOCK_PARAMETER */) {
|
|
19452
|
+
const paramToken = this._advance();
|
|
19453
|
+
parameters.push(new BlockParameter(paramToken.parts[0], paramToken.sourceSpan));
|
|
19454
|
+
}
|
|
19455
|
+
if (this._peek.type === closeToken) {
|
|
19456
|
+
this._advance();
|
|
19457
|
+
}
|
|
19458
|
+
const end = this._peek.sourceSpan.fullStart;
|
|
19459
|
+
const span = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
|
|
19460
|
+
// Create a separate `startSpan` because `span` will be modified when there is an `end` span.
|
|
19461
|
+
const startSpan = new ParseSourceSpan(token.sourceSpan.start, end, token.sourceSpan.fullStart);
|
|
19462
|
+
const block = new Block(token.parts[0], parameters, [], span, startSpan);
|
|
19463
|
+
const parent = this._getContainer();
|
|
19464
|
+
if (!(parent instanceof BlockGroup)) {
|
|
19465
|
+
this.errors.push(TreeError.create(block.name, block.sourceSpan, 'Blocks can only be placed inside of block groups.'));
|
|
19466
|
+
}
|
|
19467
|
+
else {
|
|
19468
|
+
parent.blocks.push(block);
|
|
19469
|
+
this._containerStack.push(block);
|
|
19470
|
+
}
|
|
19471
|
+
return block;
|
|
19472
|
+
}
|
|
19473
|
+
_consumeBlockGroupClose(token) {
|
|
19474
|
+
const name = token.parts[0];
|
|
19475
|
+
const previousContainer = this._getContainer();
|
|
19476
|
+
// Blocks are implcitly closed by the block group.
|
|
19477
|
+
this._conditionallyClosePreviousBlock();
|
|
19478
|
+
if (!this._popContainer(name, BlockGroup, token.sourceSpan)) {
|
|
19479
|
+
const context = previousContainer instanceof Element ?
|
|
19480
|
+
`There is an unclosed "${previousContainer.name}" HTML tag named that may have to be closed first.` :
|
|
19481
|
+
`The block may have been closed earlier.`;
|
|
19482
|
+
this.errors.push(TreeError.create(name, token.sourceSpan, `Unexpected closing block "${name}". ${context}`));
|
|
19483
|
+
}
|
|
19484
|
+
}
|
|
19485
|
+
_conditionallyClosePreviousBlock() {
|
|
19486
|
+
const container = this._getContainer();
|
|
19487
|
+
if (container instanceof Block) {
|
|
19488
|
+
// Blocks don't have an explicit closing tag, they're closed either by the next block or
|
|
19489
|
+
// the end of the block group. Infer the end span from the last child node.
|
|
19490
|
+
const lastChild = container.children.length ? container.children[container.children.length - 1] : null;
|
|
19491
|
+
const endSpan = lastChild === null ?
|
|
19492
|
+
null :
|
|
19493
|
+
new ParseSourceSpan(lastChild.sourceSpan.end, lastChild.sourceSpan.end);
|
|
19494
|
+
this._popContainer(container.name, Block, endSpan);
|
|
19495
|
+
}
|
|
19496
|
+
}
|
|
19497
|
+
_getContainer() {
|
|
19498
|
+
return this._containerStack.length > 0 ? this._containerStack[this._containerStack.length - 1] :
|
|
19499
|
+
null;
|
|
19500
|
+
}
|
|
19501
|
+
_getClosestParentElement() {
|
|
19502
|
+
for (let i = this._containerStack.length - 1; i > -1; i--) {
|
|
19503
|
+
if (this._containerStack[i] instanceof Element) {
|
|
19504
|
+
return this._containerStack[i];
|
|
19505
|
+
}
|
|
19506
|
+
}
|
|
19507
|
+
return null;
|
|
18908
19508
|
}
|
|
18909
19509
|
_addToParent(node) {
|
|
18910
|
-
const parent = this.
|
|
18911
|
-
if (parent
|
|
18912
|
-
|
|
19510
|
+
const parent = this._getContainer();
|
|
19511
|
+
if (parent === null) {
|
|
19512
|
+
this.rootNodes.push(node);
|
|
19513
|
+
}
|
|
19514
|
+
else if (parent instanceof BlockGroup) {
|
|
19515
|
+
// Due to how parsing is set up, we're unlikely to hit this code path, but we
|
|
19516
|
+
// have the assertion here just in case and to satisfy the type checker.
|
|
19517
|
+
this.errors.push(TreeError.create(null, node.sourceSpan, 'Block groups can only contain blocks.'));
|
|
18913
19518
|
}
|
|
18914
19519
|
else {
|
|
18915
|
-
|
|
19520
|
+
parent.children.push(node);
|
|
18916
19521
|
}
|
|
18917
19522
|
}
|
|
18918
19523
|
_getElementFullName(prefix, localName, parentElement) {
|
|
@@ -19026,6 +19631,15 @@ class WhitespaceVisitor {
|
|
|
19026
19631
|
visitExpansionCase(expansionCase, context) {
|
|
19027
19632
|
return expansionCase;
|
|
19028
19633
|
}
|
|
19634
|
+
visitBlockGroup(group, context) {
|
|
19635
|
+
return new BlockGroup(visitAllWithSiblings(this, group.blocks), group.sourceSpan, group.startSourceSpan, group.endSourceSpan);
|
|
19636
|
+
}
|
|
19637
|
+
visitBlock(block, context) {
|
|
19638
|
+
return new Block(block.name, block.parameters, visitAllWithSiblings(this, block.children), block.sourceSpan, block.startSourceSpan);
|
|
19639
|
+
}
|
|
19640
|
+
visitBlockParameter(parameter, context) {
|
|
19641
|
+
return parameter;
|
|
19642
|
+
}
|
|
19029
19643
|
}
|
|
19030
19644
|
function createWhitespaceProcessedTextToken({ type, parts, sourceSpan }) {
|
|
19031
19645
|
return { type, parts: [processWhitespace(parts[0])], sourceSpan };
|
|
@@ -19814,6 +20428,15 @@ class HtmlAstToIvyAst {
|
|
|
19814
20428
|
}
|
|
19815
20429
|
return null;
|
|
19816
20430
|
}
|
|
20431
|
+
visitBlockGroup(group, context) {
|
|
20432
|
+
throw new Error('TODO');
|
|
20433
|
+
}
|
|
20434
|
+
visitBlock(block, context) {
|
|
20435
|
+
throw new Error('TODO');
|
|
20436
|
+
}
|
|
20437
|
+
visitBlockParameter(parameter, context) {
|
|
20438
|
+
throw new Error('TODO');
|
|
20439
|
+
}
|
|
19817
20440
|
// convert view engine `ParsedProperty` to a format suitable for IVY
|
|
19818
20441
|
extractAttributes(elementName, properties, i18nPropsMeta) {
|
|
19819
20442
|
const bound = [];
|
|
@@ -19991,6 +20614,15 @@ class NonBindableVisitor {
|
|
|
19991
20614
|
visitExpansionCase(expansionCase) {
|
|
19992
20615
|
return null;
|
|
19993
20616
|
}
|
|
20617
|
+
visitBlockGroup(group, context) {
|
|
20618
|
+
throw new Error('TODO');
|
|
20619
|
+
}
|
|
20620
|
+
visitBlock(block, context) {
|
|
20621
|
+
throw new Error('TODO');
|
|
20622
|
+
}
|
|
20623
|
+
visitBlockParameter(parameter, context) {
|
|
20624
|
+
throw new Error('TODO');
|
|
20625
|
+
}
|
|
19994
20626
|
}
|
|
19995
20627
|
const NON_BINDABLE_VISITOR = new NonBindableVisitor();
|
|
19996
20628
|
function normalizeAttributeName(attrName) {
|
|
@@ -20438,6 +21070,17 @@ class _I18nVisitor {
|
|
|
20438
21070
|
visitExpansionCase(_icuCase, _context) {
|
|
20439
21071
|
throw new Error('Unreachable code');
|
|
20440
21072
|
}
|
|
21073
|
+
visitBlockGroup(group, context) {
|
|
21074
|
+
const children = visitAll(this, group.blocks, context);
|
|
21075
|
+
const node = new Container(children, group.sourceSpan);
|
|
21076
|
+
return context.visitNodeFn(group, node);
|
|
21077
|
+
}
|
|
21078
|
+
visitBlock(block, context) {
|
|
21079
|
+
const children = visitAll(this, block.children, context);
|
|
21080
|
+
const node = new Container(children, block.sourceSpan);
|
|
21081
|
+
return context.visitNodeFn(block, node);
|
|
21082
|
+
}
|
|
21083
|
+
visitBlockParameter(_parameter, _context) { }
|
|
20441
21084
|
/**
|
|
20442
21085
|
* Convert, text and interpolated tokens up into text and placeholder pieces.
|
|
20443
21086
|
*
|
|
@@ -20684,6 +21327,17 @@ class I18nMetaVisitor {
|
|
|
20684
21327
|
visitExpansionCase(expansionCase) {
|
|
20685
21328
|
return expansionCase;
|
|
20686
21329
|
}
|
|
21330
|
+
visitBlockGroup(group, context) {
|
|
21331
|
+
visitAll(this, group.blocks, context);
|
|
21332
|
+
return group;
|
|
21333
|
+
}
|
|
21334
|
+
visitBlock(block, context) {
|
|
21335
|
+
visitAll(this, block.children, context);
|
|
21336
|
+
return block;
|
|
21337
|
+
}
|
|
21338
|
+
visitBlockParameter(parameter, context) {
|
|
21339
|
+
return parameter;
|
|
21340
|
+
}
|
|
20687
21341
|
/**
|
|
20688
21342
|
* Parse the general form `meta` passed into extract the explicit metadata needed to create a
|
|
20689
21343
|
* `Message`.
|
|
@@ -23556,6 +24210,7 @@ class CompilerFacadeImpl {
|
|
|
23556
24210
|
}
|
|
23557
24211
|
compileNgModule(angularCoreEnv, sourceMapUrl, facade) {
|
|
23558
24212
|
const meta = {
|
|
24213
|
+
kind: R3NgModuleMetadataKind.Global,
|
|
23559
24214
|
type: wrapReference(facade.type),
|
|
23560
24215
|
bootstrap: facade.bootstrap.map(wrapReference),
|
|
23561
24216
|
declarations: facade.declarations.map(wrapReference),
|
|
@@ -24067,7 +24722,7 @@ function publishFacade(global) {
|
|
|
24067
24722
|
* @description
|
|
24068
24723
|
* Entry point for all public APIs of the compiler package.
|
|
24069
24724
|
*/
|
|
24070
|
-
const VERSION = new Version('16.2.0-next.
|
|
24725
|
+
const VERSION = new Version('16.2.0-next.2');
|
|
24071
24726
|
|
|
24072
24727
|
class CompilerConfig {
|
|
24073
24728
|
constructor({ defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, missingTranslation = null, preserveWhitespaces, strictInjectionParameters } = {}) {
|
|
@@ -24288,6 +24943,13 @@ class _Visitor {
|
|
|
24288
24943
|
visitAttribute(attribute, context) {
|
|
24289
24944
|
throw new Error('unreachable code');
|
|
24290
24945
|
}
|
|
24946
|
+
visitBlockGroup(group, context) {
|
|
24947
|
+
visitAll(this, group.blocks, context);
|
|
24948
|
+
}
|
|
24949
|
+
visitBlock(block, context) {
|
|
24950
|
+
visitAll(this, block.children, context);
|
|
24951
|
+
}
|
|
24952
|
+
visitBlockParameter(parameter, context) { }
|
|
24291
24953
|
_init(mode, interpolationConfig) {
|
|
24292
24954
|
this._mode = mode;
|
|
24293
24955
|
this._inI18nBlock = false;
|
|
@@ -24500,8 +25162,9 @@ class XmlParser extends Parser {
|
|
|
24500
25162
|
constructor() {
|
|
24501
25163
|
super(getXmlTagDefinition);
|
|
24502
25164
|
}
|
|
24503
|
-
parse(source, url, options) {
|
|
24504
|
-
|
|
25165
|
+
parse(source, url, options = {}) {
|
|
25166
|
+
// Blocks aren't supported in an XML context.
|
|
25167
|
+
return super.parse(source, url, { ...options, tokenizeBlocks: false });
|
|
24505
25168
|
}
|
|
24506
25169
|
}
|
|
24507
25170
|
|
|
@@ -24685,6 +25348,9 @@ class XliffParser {
|
|
|
24685
25348
|
visitComment(comment, context) { }
|
|
24686
25349
|
visitExpansion(expansion, context) { }
|
|
24687
25350
|
visitExpansionCase(expansionCase, context) { }
|
|
25351
|
+
visitBlockGroup(group, context) { }
|
|
25352
|
+
visitBlock(block, context) { }
|
|
25353
|
+
visitBlockParameter(parameter, context) { }
|
|
24688
25354
|
_addError(node, message) {
|
|
24689
25355
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
24690
25356
|
}
|
|
@@ -24735,6 +25401,9 @@ class XmlToI18n$2 {
|
|
|
24735
25401
|
}
|
|
24736
25402
|
visitComment(comment, context) { }
|
|
24737
25403
|
visitAttribute(attribute, context) { }
|
|
25404
|
+
visitBlockGroup(group, context) { }
|
|
25405
|
+
visitBlock(block, context) { }
|
|
25406
|
+
visitBlockParameter(parameter, context) { }
|
|
24738
25407
|
_addError(node, message) {
|
|
24739
25408
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
24740
25409
|
}
|
|
@@ -24958,6 +25627,9 @@ class Xliff2Parser {
|
|
|
24958
25627
|
visitComment(comment, context) { }
|
|
24959
25628
|
visitExpansion(expansion, context) { }
|
|
24960
25629
|
visitExpansionCase(expansionCase, context) { }
|
|
25630
|
+
visitBlockGroup(group, context) { }
|
|
25631
|
+
visitBlock(block, context) { }
|
|
25632
|
+
visitBlockParameter(parameter, context) { }
|
|
24961
25633
|
_addError(node, message) {
|
|
24962
25634
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
24963
25635
|
}
|
|
@@ -25025,6 +25697,9 @@ class XmlToI18n$1 {
|
|
|
25025
25697
|
}
|
|
25026
25698
|
visitComment(comment, context) { }
|
|
25027
25699
|
visitAttribute(attribute, context) { }
|
|
25700
|
+
visitBlockGroup(group, context) { }
|
|
25701
|
+
visitBlock(block, context) { }
|
|
25702
|
+
visitBlockParameter(parameter, context) { }
|
|
25028
25703
|
_addError(node, message) {
|
|
25029
25704
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
25030
25705
|
}
|
|
@@ -25159,6 +25834,9 @@ class XtbParser {
|
|
|
25159
25834
|
visitComment(comment, context) { }
|
|
25160
25835
|
visitExpansion(expansion, context) { }
|
|
25161
25836
|
visitExpansionCase(expansionCase, context) { }
|
|
25837
|
+
visitBlockGroup(group, context) { }
|
|
25838
|
+
visitBlock(block, context) { }
|
|
25839
|
+
visitBlockParameter(block, context) { }
|
|
25162
25840
|
_addError(node, message) {
|
|
25163
25841
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
25164
25842
|
}
|
|
@@ -25207,6 +25885,9 @@ class XmlToI18n {
|
|
|
25207
25885
|
}
|
|
25208
25886
|
visitComment(comment, context) { }
|
|
25209
25887
|
visitAttribute(attribute, context) { }
|
|
25888
|
+
visitBlockGroup(group, context) { }
|
|
25889
|
+
visitBlock(block, context) { }
|
|
25890
|
+
visitBlockParameter(block, context) { }
|
|
25210
25891
|
_addError(node, message) {
|
|
25211
25892
|
this._errors.push(new I18nError(node.sourceSpan, message));
|
|
25212
25893
|
}
|
|
@@ -25995,7 +26676,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$6 = '12.0.0';
|
|
|
25995
26676
|
function compileDeclareClassMetadata(metadata) {
|
|
25996
26677
|
const definitionMap = new DefinitionMap();
|
|
25997
26678
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
|
|
25998
|
-
definitionMap.set('version', literal('16.2.0-next.
|
|
26679
|
+
definitionMap.set('version', literal('16.2.0-next.2'));
|
|
25999
26680
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
26000
26681
|
definitionMap.set('type', metadata.type);
|
|
26001
26682
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -26098,7 +26779,7 @@ function compileDeclareDirectiveFromMetadata(meta) {
|
|
|
26098
26779
|
function createDirectiveDefinitionMap(meta) {
|
|
26099
26780
|
const definitionMap = new DefinitionMap();
|
|
26100
26781
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
26101
|
-
definitionMap.set('version', literal('16.2.0-next.
|
|
26782
|
+
definitionMap.set('version', literal('16.2.0-next.2'));
|
|
26102
26783
|
// e.g. `type: MyDirective`
|
|
26103
26784
|
definitionMap.set('type', meta.type.value);
|
|
26104
26785
|
if (meta.isStandalone) {
|
|
@@ -26326,7 +27007,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
|
|
|
26326
27007
|
function compileDeclareFactoryFunction(meta) {
|
|
26327
27008
|
const definitionMap = new DefinitionMap();
|
|
26328
27009
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
26329
|
-
definitionMap.set('version', literal('16.2.0-next.
|
|
27010
|
+
definitionMap.set('version', literal('16.2.0-next.2'));
|
|
26330
27011
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
26331
27012
|
definitionMap.set('type', meta.type.value);
|
|
26332
27013
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -26361,7 +27042,7 @@ function compileDeclareInjectableFromMetadata(meta) {
|
|
|
26361
27042
|
function createInjectableDefinitionMap(meta) {
|
|
26362
27043
|
const definitionMap = new DefinitionMap();
|
|
26363
27044
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
26364
|
-
definitionMap.set('version', literal('16.2.0-next.
|
|
27045
|
+
definitionMap.set('version', literal('16.2.0-next.2'));
|
|
26365
27046
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
26366
27047
|
definitionMap.set('type', meta.type.value);
|
|
26367
27048
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -26412,7 +27093,7 @@ function compileDeclareInjectorFromMetadata(meta) {
|
|
|
26412
27093
|
function createInjectorDefinitionMap(meta) {
|
|
26413
27094
|
const definitionMap = new DefinitionMap();
|
|
26414
27095
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
26415
|
-
definitionMap.set('version', literal('16.2.0-next.
|
|
27096
|
+
definitionMap.set('version', literal('16.2.0-next.2'));
|
|
26416
27097
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
26417
27098
|
definitionMap.set('type', meta.type.value);
|
|
26418
27099
|
definitionMap.set('providers', meta.providers);
|
|
@@ -26441,8 +27122,11 @@ function compileDeclareNgModuleFromMetadata(meta) {
|
|
|
26441
27122
|
*/
|
|
26442
27123
|
function createNgModuleDefinitionMap(meta) {
|
|
26443
27124
|
const definitionMap = new DefinitionMap();
|
|
27125
|
+
if (meta.kind === R3NgModuleMetadataKind.Local) {
|
|
27126
|
+
throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
|
|
27127
|
+
}
|
|
26444
27128
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
26445
|
-
definitionMap.set('version', literal('16.2.0-next.
|
|
27129
|
+
definitionMap.set('version', literal('16.2.0-next.2'));
|
|
26446
27130
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
26447
27131
|
definitionMap.set('type', meta.type.value);
|
|
26448
27132
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -26493,7 +27177,7 @@ function compileDeclarePipeFromMetadata(meta) {
|
|
|
26493
27177
|
function createPipeDefinitionMap(meta) {
|
|
26494
27178
|
const definitionMap = new DefinitionMap();
|
|
26495
27179
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
26496
|
-
definitionMap.set('version', literal('16.2.0-next.
|
|
27180
|
+
definitionMap.set('version', literal('16.2.0-next.2'));
|
|
26497
27181
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
26498
27182
|
// e.g. `type: MyPipe`
|
|
26499
27183
|
definitionMap.set('type', meta.type.value);
|
|
@@ -26526,5 +27210,5 @@ publishFacade(_global);
|
|
|
26526
27210
|
|
|
26527
27211
|
// This file is not used to build this module. It is only used during editing
|
|
26528
27212
|
|
|
26529
|
-
export { AST, ASTWithName, ASTWithSource, AbsoluteSourceSpan, ArrayType, AstMemoryEfficientTransformer, AstTransformer, Attribute, Binary, BinaryOperator, BinaryOperatorExpr, BindingPipe, BoundElementProperty, BuiltinType, BuiltinTypeName, CUSTOM_ELEMENTS_SCHEMA, Call, Chain, ChangeDetectionStrategy, CommaExpr, Comment, CompilerConfig, Conditional, ConditionalExpr, ConstantPool, CssSelector, DEFAULT_INTERPOLATION_CONFIG, DYNAMIC_TYPE, DeclareFunctionStmt, DeclareVarStmt, DomElementSchemaRegistry, EOF, Element, ElementSchemaRegistry, EmitterVisitorContext, EmptyExpr$1 as EmptyExpr, Expansion, ExpansionCase, Expression, ExpressionBinding, ExpressionStatement, ExpressionType, ExternalExpr, ExternalReference, FactoryTarget$1 as FactoryTarget, FunctionExpr, HtmlParser, HtmlTagDefinition, I18NHtmlParser, IfStmt, ImplicitReceiver, InstantiateExpr, Interpolation, InterpolationConfig, InvokeFunctionExpr, JSDocComment, JitEvaluator, KeyedRead, KeyedWrite, LeadingComment, Lexer, LiteralArray, LiteralArrayExpr, LiteralExpr, LiteralMap, LiteralMapExpr, LiteralPrimitive, LocalizedString, MapType, MessageBundle, NONE_TYPE, NO_ERRORS_SCHEMA, NodeWithI18n, NonNullAssert, NotExpr, ParseError, ParseErrorLevel, ParseLocation, ParseSourceFile, ParseSourceSpan, ParseSpan, ParseTreeResult, ParsedEvent, ParsedProperty, ParsedPropertyType, ParsedVariable, Parser$1 as Parser, ParserError, PrefixNot, PropertyRead, PropertyWrite, R3BoundTarget, Identifiers as R3Identifiers, R3SelectorScopeMode, R3TargetBinder, R3TemplateDependencyKind, ReadKeyExpr, ReadPropExpr, ReadVarExpr, RecursiveAstVisitor, RecursiveVisitor, ResourceLoader, ReturnStatement, STRING_TYPE, SafeCall, SafeKeyedRead, SafePropertyRead, SelectorContext, SelectorListContext, SelectorMatcher, Serializer, SplitInterpolation, Statement, StmtModifier, TagContentType, TaggedTemplateExpr, TemplateBindingParseResult, TemplateLiteral, TemplateLiteralElement, Text, ThisReceiver, BoundAttribute as TmplAstBoundAttribute, BoundEvent as TmplAstBoundEvent, BoundText as TmplAstBoundText, Content as TmplAstContent, Element$1 as TmplAstElement, Icu$1 as TmplAstIcu, RecursiveVisitor$1 as TmplAstRecursiveVisitor, Reference as TmplAstReference, Template as TmplAstTemplate, Text$3 as TmplAstText, TextAttribute as TmplAstTextAttribute, Variable as TmplAstVariable, Token, TokenType, TransplantedType, TreeError, Type, TypeModifier, TypeofExpr, Unary, UnaryOperator, UnaryOperatorExpr, VERSION, VariableBinding, Version, ViewEncapsulation, WrappedNodeExpr, WriteKeyExpr, WritePropExpr, WriteVarExpr, Xliff, Xliff2, Xmb, XmlParser, Xtb, _ParseAST, compileClassMetadata, compileComponentFromMetadata, compileDeclareClassMetadata, compileDeclareComponentFromMetadata, compileDeclareDirectiveFromMetadata, compileDeclareFactoryFunction, compileDeclareInjectableFromMetadata, compileDeclareInjectorFromMetadata, compileDeclareNgModuleFromMetadata, compileDeclarePipeFromMetadata, compileDirectiveFromMetadata, compileFactoryFunction, compileInjectable, compileInjector, compileNgModule, compilePipeFromMetadata, computeMsgId, core, createInjectableType, createMayBeForwardRefExpression, devOnlyGuardedExpression, emitDistinctChangesOnlyDefaultValue, getHtmlTagDefinition, getNsPrefix, getSafePropertyAccessString, identifierName, isIdentifier, isNgContainer, isNgContent, isNgTemplate, jsDocComment, leadingComment, literalMap, makeBindingParser, mergeNsAndName, output_ast as outputAst, parseHostBindings, parseTemplate, preserveWhitespacesDefault, publishFacade, r3JitTypeSourceSpan, sanitizeIdentifier, splitNsName, verifyHostBindings, visitAll };
|
|
27213
|
+
export { AST, ASTWithName, ASTWithSource, AbsoluteSourceSpan, ArrayType, AstMemoryEfficientTransformer, AstTransformer, Attribute, Binary, BinaryOperator, BinaryOperatorExpr, BindingPipe, Block, BlockGroup, BlockParameter, BoundElementProperty, BuiltinType, BuiltinTypeName, CUSTOM_ELEMENTS_SCHEMA, Call, Chain, ChangeDetectionStrategy, CommaExpr, Comment, CompilerConfig, Conditional, ConditionalExpr, ConstantPool, CssSelector, DEFAULT_INTERPOLATION_CONFIG, DYNAMIC_TYPE, DeclareFunctionStmt, DeclareVarStmt, DomElementSchemaRegistry, EOF, Element, ElementSchemaRegistry, EmitterVisitorContext, EmptyExpr$1 as EmptyExpr, Expansion, ExpansionCase, Expression, ExpressionBinding, ExpressionStatement, ExpressionType, ExternalExpr, ExternalReference, FactoryTarget$1 as FactoryTarget, FunctionExpr, HtmlParser, HtmlTagDefinition, I18NHtmlParser, IfStmt, ImplicitReceiver, InstantiateExpr, Interpolation, InterpolationConfig, InvokeFunctionExpr, JSDocComment, JitEvaluator, KeyedRead, KeyedWrite, LeadingComment, Lexer, LiteralArray, LiteralArrayExpr, LiteralExpr, LiteralMap, LiteralMapExpr, LiteralPrimitive, LocalizedString, MapType, MessageBundle, NONE_TYPE, NO_ERRORS_SCHEMA, NodeWithI18n, NonNullAssert, NotExpr, ParseError, ParseErrorLevel, ParseLocation, ParseSourceFile, ParseSourceSpan, ParseSpan, ParseTreeResult, ParsedEvent, ParsedProperty, ParsedPropertyType, ParsedVariable, Parser$1 as Parser, ParserError, PrefixNot, PropertyRead, PropertyWrite, R3BoundTarget, Identifiers as R3Identifiers, R3NgModuleMetadataKind, R3SelectorScopeMode, R3TargetBinder, R3TemplateDependencyKind, ReadKeyExpr, ReadPropExpr, ReadVarExpr, RecursiveAstVisitor, RecursiveVisitor, ResourceLoader, ReturnStatement, STRING_TYPE, SafeCall, SafeKeyedRead, SafePropertyRead, SelectorContext, SelectorListContext, SelectorMatcher, Serializer, SplitInterpolation, Statement, StmtModifier, TagContentType, TaggedTemplateExpr, TemplateBindingParseResult, TemplateLiteral, TemplateLiteralElement, Text, ThisReceiver, BoundAttribute as TmplAstBoundAttribute, BoundEvent as TmplAstBoundEvent, BoundText as TmplAstBoundText, Content as TmplAstContent, Element$1 as TmplAstElement, Icu$1 as TmplAstIcu, RecursiveVisitor$1 as TmplAstRecursiveVisitor, Reference as TmplAstReference, Template as TmplAstTemplate, Text$3 as TmplAstText, TextAttribute as TmplAstTextAttribute, Variable as TmplAstVariable, Token, TokenType, TransplantedType, TreeError, Type, TypeModifier, TypeofExpr, Unary, UnaryOperator, UnaryOperatorExpr, VERSION, VariableBinding, Version, ViewEncapsulation, WrappedNodeExpr, WriteKeyExpr, WritePropExpr, WriteVarExpr, Xliff, Xliff2, Xmb, XmlParser, Xtb, _ParseAST, compileClassMetadata, compileComponentFromMetadata, compileDeclareClassMetadata, compileDeclareComponentFromMetadata, compileDeclareDirectiveFromMetadata, compileDeclareFactoryFunction, compileDeclareInjectableFromMetadata, compileDeclareInjectorFromMetadata, compileDeclareNgModuleFromMetadata, compileDeclarePipeFromMetadata, compileDirectiveFromMetadata, compileFactoryFunction, compileInjectable, compileInjector, compileNgModule, compilePipeFromMetadata, computeMsgId, core, createInjectableType, createMayBeForwardRefExpression, devOnlyGuardedExpression, emitDistinctChangesOnlyDefaultValue, getHtmlTagDefinition, getNsPrefix, getSafePropertyAccessString, identifierName, isIdentifier, isNgContainer, isNgContent, isNgTemplate, jsDocComment, leadingComment, literalMap, makeBindingParser, mergeNsAndName, output_ast as outputAst, parseHostBindings, parseTemplate, preserveWhitespacesDefault, publishFacade, r3JitTypeSourceSpan, sanitizeIdentifier, splitNsName, verifyHostBindings, visitAll };
|
|
26530
27214
|
//# sourceMappingURL=compiler.mjs.map
|