@angular/compiler 17.0.0-next.3 → 17.0.0-next.5
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/i18n/digest.mjs +8 -49
- package/esm2022/src/ml_parser/parser.mjs +2 -2
- package/esm2022/src/output/output_jit_trusted_types.mjs +7 -7
- package/esm2022/src/render3/partial/class_metadata.mjs +1 -1
- package/esm2022/src/render3/partial/directive.mjs +1 -1
- package/esm2022/src/render3/partial/factory.mjs +1 -1
- package/esm2022/src/render3/partial/injectable.mjs +1 -1
- package/esm2022/src/render3/partial/injector.mjs +1 -1
- package/esm2022/src/render3/partial/ng_module.mjs +1 -1
- package/esm2022/src/render3/partial/pipe.mjs +1 -1
- package/esm2022/src/render3/r3_ast.mjs +10 -3
- package/esm2022/src/render3/r3_control_flow.mjs +16 -9
- package/esm2022/src/render3/r3_deferred_triggers.mjs +7 -7
- package/esm2022/src/render3/r3_module_compiler.mjs +9 -11
- package/esm2022/src/render3/view/compiler.mjs +6 -3
- package/esm2022/src/render3/view/t2_api.mjs +1 -1
- package/esm2022/src/render3/view/t2_binder.mjs +178 -78
- package/esm2022/src/render3/view/template.mjs +32 -46
- package/esm2022/src/template/pipeline/ir/src/enums.mjs +14 -7
- package/esm2022/src/template/pipeline/ir/src/expression.mjs +3 -1
- package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +28 -3
- package/esm2022/src/template/pipeline/src/compilation.mjs +6 -1
- package/esm2022/src/template/pipeline/src/conversion.mjs +7 -1
- package/esm2022/src/template/pipeline/src/emit.mjs +7 -1
- package/esm2022/src/template/pipeline/src/ingest.mjs +16 -3
- package/esm2022/src/template/pipeline/src/instruction.mjs +19 -3
- package/esm2022/src/template/pipeline/src/phases/align_pipe_variadic_var_offset.mjs +2 -1
- package/esm2022/src/template/pipeline/src/phases/const_collection.mjs +22 -29
- package/esm2022/src/template/pipeline/src/phases/generate_projection_def.mjs +46 -0
- package/esm2022/src/template/pipeline/src/phases/i18n_const_collection.mjs +33 -0
- package/esm2022/src/template/pipeline/src/phases/next_context_merging.mjs +2 -1
- package/esm2022/src/template/pipeline/src/phases/phase_remove_content_selectors.mjs +39 -0
- package/esm2022/src/template/pipeline/src/phases/reify.mjs +11 -2
- package/esm2022/src/version.mjs +1 -1
- package/fesm2022/compiler.mjs +534 -476
- package/fesm2022/compiler.mjs.map +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/index.d.ts +53 -40
- package/package.json +3 -3
- package/testing/index.d.ts +1 -1
- package/esm2022/src/i18n/big_integer.mjs +0 -180
package/fesm2022/compiler.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v17.0.0-next.
|
|
2
|
+
* @license Angular v17.0.0-next.5
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -480,179 +480,6 @@ var core = /*#__PURE__*/Object.freeze({
|
|
|
480
480
|
parseSelectorToR3Selector: parseSelectorToR3Selector
|
|
481
481
|
});
|
|
482
482
|
|
|
483
|
-
/**
|
|
484
|
-
* Represents a big integer using a buffer of its individual digits, with the least significant
|
|
485
|
-
* digit stored at the beginning of the array (little endian).
|
|
486
|
-
*
|
|
487
|
-
* For performance reasons, each instance is mutable. The addition operation can be done in-place
|
|
488
|
-
* to reduce memory pressure of allocation for the digits array.
|
|
489
|
-
*/
|
|
490
|
-
class BigInteger {
|
|
491
|
-
static zero() {
|
|
492
|
-
return new BigInteger([0]);
|
|
493
|
-
}
|
|
494
|
-
static one() {
|
|
495
|
-
return new BigInteger([1]);
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Creates a big integer using its individual digits in little endian storage.
|
|
499
|
-
*/
|
|
500
|
-
constructor(digits) {
|
|
501
|
-
this.digits = digits;
|
|
502
|
-
}
|
|
503
|
-
/**
|
|
504
|
-
* Creates a clone of this instance.
|
|
505
|
-
*/
|
|
506
|
-
clone() {
|
|
507
|
-
return new BigInteger(this.digits.slice());
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Returns a new big integer with the sum of `this` and `other` as its value. This does not mutate
|
|
511
|
-
* `this` but instead returns a new instance, unlike `addToSelf`.
|
|
512
|
-
*/
|
|
513
|
-
add(other) {
|
|
514
|
-
const result = this.clone();
|
|
515
|
-
result.addToSelf(other);
|
|
516
|
-
return result;
|
|
517
|
-
}
|
|
518
|
-
/**
|
|
519
|
-
* Adds `other` to the instance itself, thereby mutating its value.
|
|
520
|
-
*/
|
|
521
|
-
addToSelf(other) {
|
|
522
|
-
const maxNrOfDigits = Math.max(this.digits.length, other.digits.length);
|
|
523
|
-
let carry = 0;
|
|
524
|
-
for (let i = 0; i < maxNrOfDigits; i++) {
|
|
525
|
-
let digitSum = carry;
|
|
526
|
-
if (i < this.digits.length) {
|
|
527
|
-
digitSum += this.digits[i];
|
|
528
|
-
}
|
|
529
|
-
if (i < other.digits.length) {
|
|
530
|
-
digitSum += other.digits[i];
|
|
531
|
-
}
|
|
532
|
-
if (digitSum >= 10) {
|
|
533
|
-
this.digits[i] = digitSum - 10;
|
|
534
|
-
carry = 1;
|
|
535
|
-
}
|
|
536
|
-
else {
|
|
537
|
-
this.digits[i] = digitSum;
|
|
538
|
-
carry = 0;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
// Apply a remaining carry if needed.
|
|
542
|
-
if (carry > 0) {
|
|
543
|
-
this.digits[maxNrOfDigits] = 1;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* Builds the decimal string representation of the big integer. As this is stored in
|
|
548
|
-
* little endian, the digits are concatenated in reverse order.
|
|
549
|
-
*/
|
|
550
|
-
toString() {
|
|
551
|
-
let res = '';
|
|
552
|
-
for (let i = this.digits.length - 1; i >= 0; i--) {
|
|
553
|
-
res += this.digits[i];
|
|
554
|
-
}
|
|
555
|
-
return res;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
/**
|
|
559
|
-
* Represents a big integer which is optimized for multiplication operations, as its power-of-twos
|
|
560
|
-
* are memoized. See `multiplyBy()` for details on the multiplication algorithm.
|
|
561
|
-
*/
|
|
562
|
-
class BigIntForMultiplication {
|
|
563
|
-
constructor(value) {
|
|
564
|
-
this.powerOfTwos = [value];
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Returns the big integer itself.
|
|
568
|
-
*/
|
|
569
|
-
getValue() {
|
|
570
|
-
return this.powerOfTwos[0];
|
|
571
|
-
}
|
|
572
|
-
/**
|
|
573
|
-
* Computes the value for `num * b`, where `num` is a JS number and `b` is a big integer. The
|
|
574
|
-
* value for `b` is represented by a storage model that is optimized for this computation.
|
|
575
|
-
*
|
|
576
|
-
* This operation is implemented in N(log2(num)) by continuous halving of the number, where the
|
|
577
|
-
* least-significant bit (LSB) is tested in each iteration. If the bit is set, the bit's index is
|
|
578
|
-
* used as exponent into the power-of-two multiplication of `b`.
|
|
579
|
-
*
|
|
580
|
-
* As an example, consider the multiplication num=42, b=1337. In binary 42 is 0b00101010 and the
|
|
581
|
-
* algorithm unrolls into the following iterations:
|
|
582
|
-
*
|
|
583
|
-
* Iteration | num | LSB | b * 2^iter | Add? | product
|
|
584
|
-
* -----------|------------|------|------------|------|--------
|
|
585
|
-
* 0 | 0b00101010 | 0 | 1337 | No | 0
|
|
586
|
-
* 1 | 0b00010101 | 1 | 2674 | Yes | 2674
|
|
587
|
-
* 2 | 0b00001010 | 0 | 5348 | No | 2674
|
|
588
|
-
* 3 | 0b00000101 | 1 | 10696 | Yes | 13370
|
|
589
|
-
* 4 | 0b00000010 | 0 | 21392 | No | 13370
|
|
590
|
-
* 5 | 0b00000001 | 1 | 42784 | Yes | 56154
|
|
591
|
-
* 6 | 0b00000000 | 0 | 85568 | No | 56154
|
|
592
|
-
*
|
|
593
|
-
* The computed product of 56154 is indeed the correct result.
|
|
594
|
-
*
|
|
595
|
-
* The `BigIntForMultiplication` representation for a big integer provides memoized access to the
|
|
596
|
-
* power-of-two values to reduce the workload in computing those values.
|
|
597
|
-
*/
|
|
598
|
-
multiplyBy(num) {
|
|
599
|
-
const product = BigInteger.zero();
|
|
600
|
-
this.multiplyByAndAddTo(num, product);
|
|
601
|
-
return product;
|
|
602
|
-
}
|
|
603
|
-
/**
|
|
604
|
-
* See `multiplyBy()` for details. This function allows for the computed product to be added
|
|
605
|
-
* directly to the provided result big integer.
|
|
606
|
-
*/
|
|
607
|
-
multiplyByAndAddTo(num, result) {
|
|
608
|
-
for (let exponent = 0; num !== 0; num = num >>> 1, exponent++) {
|
|
609
|
-
if (num & 1) {
|
|
610
|
-
const value = this.getMultipliedByPowerOfTwo(exponent);
|
|
611
|
-
result.addToSelf(value);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
/**
|
|
616
|
-
* Computes and memoizes the big integer value for `this.number * 2^exponent`.
|
|
617
|
-
*/
|
|
618
|
-
getMultipliedByPowerOfTwo(exponent) {
|
|
619
|
-
// Compute the powers up until the requested exponent, where each value is computed from its
|
|
620
|
-
// predecessor. This is simple as `this.number * 2^(exponent - 1)` only has to be doubled (i.e.
|
|
621
|
-
// added to itself) to reach `this.number * 2^exponent`.
|
|
622
|
-
for (let i = this.powerOfTwos.length; i <= exponent; i++) {
|
|
623
|
-
const previousPower = this.powerOfTwos[i - 1];
|
|
624
|
-
this.powerOfTwos[i] = previousPower.add(previousPower);
|
|
625
|
-
}
|
|
626
|
-
return this.powerOfTwos[exponent];
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
/**
|
|
630
|
-
* Represents an exponentiation operation for the provided base, of which exponents are computed and
|
|
631
|
-
* memoized. The results are represented by a `BigIntForMultiplication` which is tailored for
|
|
632
|
-
* multiplication operations by memoizing the power-of-twos. This effectively results in a matrix
|
|
633
|
-
* representation that is lazily computed upon request.
|
|
634
|
-
*/
|
|
635
|
-
class BigIntExponentiation {
|
|
636
|
-
constructor(base) {
|
|
637
|
-
this.base = base;
|
|
638
|
-
this.exponents = [new BigIntForMultiplication(BigInteger.one())];
|
|
639
|
-
}
|
|
640
|
-
/**
|
|
641
|
-
* Compute the value for `this.base^exponent`, resulting in a big integer that is optimized for
|
|
642
|
-
* further multiplication operations.
|
|
643
|
-
*/
|
|
644
|
-
toThePowerOf(exponent) {
|
|
645
|
-
// Compute the results up until the requested exponent, where every value is computed from its
|
|
646
|
-
// predecessor. This is because `this.base^(exponent - 1)` only has to be multiplied by `base`
|
|
647
|
-
// to reach `this.base^exponent`.
|
|
648
|
-
for (let i = this.exponents.length; i <= exponent; i++) {
|
|
649
|
-
const value = this.exponents[i - 1].multiplyBy(this.base);
|
|
650
|
-
this.exponents[i] = new BigIntForMultiplication(value);
|
|
651
|
-
}
|
|
652
|
-
return this.exponents[exponent];
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
|
|
656
483
|
/**
|
|
657
484
|
* A lazily created TextEncoder instance for converting strings into UTF-8 bytes
|
|
658
485
|
*/
|
|
@@ -815,17 +642,18 @@ function fingerprint(str) {
|
|
|
815
642
|
hi = hi ^ 0x130f9bef;
|
|
816
643
|
lo = lo ^ -0x6b5f56d8;
|
|
817
644
|
}
|
|
818
|
-
return
|
|
645
|
+
return (BigInt.asUintN(32, BigInt(hi)) << BigInt(32)) | BigInt.asUintN(32, BigInt(lo));
|
|
819
646
|
}
|
|
820
647
|
function computeMsgId(msg, meaning = '') {
|
|
821
648
|
let msgFingerprint = fingerprint(msg);
|
|
822
649
|
if (meaning) {
|
|
823
|
-
|
|
824
|
-
|
|
650
|
+
// Rotate the 64-bit message fingerprint one bit to the left and then add the meaning
|
|
651
|
+
// fingerprint.
|
|
652
|
+
msgFingerprint = BigInt.asUintN(64, msgFingerprint << BigInt(1)) |
|
|
653
|
+
((msgFingerprint >> BigInt(63)) & BigInt(1));
|
|
654
|
+
msgFingerprint += fingerprint(meaning);
|
|
825
655
|
}
|
|
826
|
-
|
|
827
|
-
const lo = msgFingerprint[1];
|
|
828
|
-
return wordsToDecimalString(hi & 0x7fffffff, lo);
|
|
656
|
+
return BigInt.asUintN(63, msgFingerprint).toString();
|
|
829
657
|
}
|
|
830
658
|
function hash32(view, length, c) {
|
|
831
659
|
let a = 0x9e3779b9, b = 0x9e3779b9;
|
|
@@ -931,26 +759,10 @@ function add32to64(a, b) {
|
|
|
931
759
|
const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
|
|
932
760
|
return [high >>> 16, (high << 16) | (low & 0xffff)];
|
|
933
761
|
}
|
|
934
|
-
function add64(a, b) {
|
|
935
|
-
const ah = a[0], al = a[1];
|
|
936
|
-
const bh = b[0], bl = b[1];
|
|
937
|
-
const result = add32to64(al, bl);
|
|
938
|
-
const carry = result[0];
|
|
939
|
-
const l = result[1];
|
|
940
|
-
const h = add32(add32(ah, bh), carry);
|
|
941
|
-
return [h, l];
|
|
942
|
-
}
|
|
943
762
|
// Rotate a 32b number left `count` position
|
|
944
763
|
function rol32(a, count) {
|
|
945
764
|
return (a << count) | (a >>> (32 - count));
|
|
946
765
|
}
|
|
947
|
-
// Rotate a 64b number left `count` position
|
|
948
|
-
function rol64(num, count) {
|
|
949
|
-
const hi = num[0], lo = num[1];
|
|
950
|
-
const h = (hi << count) | (lo >>> (32 - count));
|
|
951
|
-
const l = (lo << count) | (hi >>> (32 - count));
|
|
952
|
-
return [h, l];
|
|
953
|
-
}
|
|
954
766
|
function bytesToWords32(bytes, endian) {
|
|
955
767
|
const size = (bytes.length + 3) >>> 2;
|
|
956
768
|
const words32 = [];
|
|
@@ -976,31 +788,6 @@ function wordAt(bytes, index, endian) {
|
|
|
976
788
|
}
|
|
977
789
|
return word;
|
|
978
790
|
}
|
|
979
|
-
/**
|
|
980
|
-
* Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized
|
|
981
|
-
* power-of-256 results with memoized power-of-two computations for efficient multiplication.
|
|
982
|
-
*
|
|
983
|
-
* For our purposes, this can be safely stored as a global without memory concerns. The reason is
|
|
984
|
-
* that we encode two words, so only need the 0th (for the low word) and 4th (for the high word)
|
|
985
|
-
* exponent.
|
|
986
|
-
*/
|
|
987
|
-
const base256 = new BigIntExponentiation(256);
|
|
988
|
-
/**
|
|
989
|
-
* Represents two 32-bit words as a single decimal number. This requires a big integer storage
|
|
990
|
-
* model as JS numbers are not accurate enough to represent the 64-bit number.
|
|
991
|
-
*
|
|
992
|
-
* Based on https://www.danvk.org/hex2dec.html
|
|
993
|
-
*/
|
|
994
|
-
function wordsToDecimalString(hi, lo) {
|
|
995
|
-
// Encode the four bytes in lo in the lower digits of the decimal number.
|
|
996
|
-
// Note: the multiplication results in lo itself but represented by a big integer using its
|
|
997
|
-
// decimal digits.
|
|
998
|
-
const decimal = base256.toThePowerOf(0).multiplyBy(lo);
|
|
999
|
-
// Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why
|
|
1000
|
-
// this multiplication factor is applied.
|
|
1001
|
-
base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal);
|
|
1002
|
-
return decimal.toString();
|
|
1003
|
-
}
|
|
1004
791
|
|
|
1005
792
|
//// Types
|
|
1006
793
|
var TypeModifier;
|
|
@@ -4014,6 +3801,10 @@ class IdleDeferredTrigger extends DeferredTrigger {
|
|
|
4014
3801
|
class ImmediateDeferredTrigger extends DeferredTrigger {
|
|
4015
3802
|
}
|
|
4016
3803
|
class HoverDeferredTrigger extends DeferredTrigger {
|
|
3804
|
+
constructor(reference, sourceSpan) {
|
|
3805
|
+
super(sourceSpan);
|
|
3806
|
+
this.reference = reference;
|
|
3807
|
+
}
|
|
4017
3808
|
}
|
|
4018
3809
|
class TimerDeferredTrigger extends DeferredTrigger {
|
|
4019
3810
|
constructor(delay, sourceSpan) {
|
|
@@ -4126,8 +3917,8 @@ class SwitchBlockCase {
|
|
|
4126
3917
|
}
|
|
4127
3918
|
}
|
|
4128
3919
|
class ForLoopBlock {
|
|
4129
|
-
constructor(
|
|
4130
|
-
this.
|
|
3920
|
+
constructor(item, expression, trackBy, contextVariables, children, empty, sourceSpan, startSourceSpan, endSourceSpan) {
|
|
3921
|
+
this.item = item;
|
|
4131
3922
|
this.expression = expression;
|
|
4132
3923
|
this.trackBy = trackBy;
|
|
4133
3924
|
this.contextVariables = contextVariables;
|
|
@@ -4280,6 +4071,8 @@ class RecursiveVisitor$1 {
|
|
|
4280
4071
|
visitAll$1(this, block.children);
|
|
4281
4072
|
}
|
|
4282
4073
|
visitForLoopBlock(block) {
|
|
4074
|
+
block.item.visit(this);
|
|
4075
|
+
visitAll$1(this, Object.values(block.contextVariables));
|
|
4283
4076
|
visitAll$1(this, block.children);
|
|
4284
4077
|
block.empty?.visit(this);
|
|
4285
4078
|
}
|
|
@@ -4291,6 +4084,7 @@ class RecursiveVisitor$1 {
|
|
|
4291
4084
|
}
|
|
4292
4085
|
visitIfBlockBranch(block) {
|
|
4293
4086
|
visitAll$1(this, block.children);
|
|
4087
|
+
block.expressionAlias?.visit(this);
|
|
4294
4088
|
}
|
|
4295
4089
|
visitContent(content) { }
|
|
4296
4090
|
visitVariable(variable) { }
|
|
@@ -5803,13 +5597,13 @@ let policy;
|
|
|
5803
5597
|
*/
|
|
5804
5598
|
function getPolicy() {
|
|
5805
5599
|
if (policy === undefined) {
|
|
5600
|
+
const trustedTypes = _global['trustedTypes'];
|
|
5806
5601
|
policy = null;
|
|
5807
|
-
if (
|
|
5602
|
+
if (trustedTypes) {
|
|
5808
5603
|
try {
|
|
5809
|
-
policy =
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
});
|
|
5604
|
+
policy = trustedTypes.createPolicy('angular#unsafe-jit', {
|
|
5605
|
+
createScript: (s) => s,
|
|
5606
|
+
});
|
|
5813
5607
|
}
|
|
5814
5608
|
catch {
|
|
5815
5609
|
// trustedTypes.createPolicy throws if called with a name that is
|
|
@@ -5839,7 +5633,7 @@ function trustedScriptFromString(script) {
|
|
|
5839
5633
|
* vulnerabilities.
|
|
5840
5634
|
*/
|
|
5841
5635
|
function newTrustedFunctionForJIT(...args) {
|
|
5842
|
-
if (!_global
|
|
5636
|
+
if (!_global['trustedTypes']) {
|
|
5843
5637
|
// In environments that don't support Trusted Types, fall back to the most
|
|
5844
5638
|
// straightforward implementation:
|
|
5845
5639
|
return new Function(...args);
|
|
@@ -6089,16 +5883,11 @@ function compileNgModule(meta) {
|
|
|
6089
5883
|
const statements = [];
|
|
6090
5884
|
const definitionMap = new DefinitionMap();
|
|
6091
5885
|
definitionMap.set('type', meta.type.value);
|
|
6092
|
-
// Assign bootstrap definition
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
}
|
|
6098
|
-
else {
|
|
6099
|
-
if (meta.bootstrapExpression) {
|
|
6100
|
-
definitionMap.set('bootstrap', meta.bootstrapExpression);
|
|
6101
|
-
}
|
|
5886
|
+
// Assign bootstrap definition. In local compilation mode (i.e., for
|
|
5887
|
+
// `R3NgModuleMetadataKind.LOCAL`) we assign the bootstrap field using the runtime
|
|
5888
|
+
// `ɵɵsetNgModuleScope`.
|
|
5889
|
+
if (meta.kind === R3NgModuleMetadataKind.Global && meta.bootstrap.length > 0) {
|
|
5890
|
+
definitionMap.set('bootstrap', refsToArray(meta.bootstrap, meta.containsForwardDecls));
|
|
6102
5891
|
}
|
|
6103
5892
|
if (meta.selectorScopeMode === R3SelectorScopeMode.Inline) {
|
|
6104
5893
|
// If requested to emit scope information inline, pass the `declarations`, `imports` and
|
|
@@ -6217,6 +6006,9 @@ function generateSetNgModuleScopeCall(meta) {
|
|
|
6217
6006
|
scopeMap.set('exports', meta.exportsExpression);
|
|
6218
6007
|
}
|
|
6219
6008
|
}
|
|
6009
|
+
if (meta.kind === R3NgModuleMetadataKind.Local && meta.bootstrapExpression) {
|
|
6010
|
+
scopeMap.set('bootstrap', meta.bootstrapExpression);
|
|
6011
|
+
}
|
|
6220
6012
|
if (Object.keys(scopeMap.values).length === 0) {
|
|
6221
6013
|
return null;
|
|
6222
6014
|
}
|
|
@@ -8979,19 +8771,26 @@ var OpKind;
|
|
|
8979
8771
|
* A namespace change, which causes the subsequent elements to be processed as either HTML or SVG.
|
|
8980
8772
|
*/
|
|
8981
8773
|
OpKind[OpKind["Namespace"] = 28] = "Namespace";
|
|
8774
|
+
/**
|
|
8775
|
+
* Configure a content projeciton definition for the view.
|
|
8776
|
+
*/
|
|
8777
|
+
OpKind[OpKind["ProjectionDef"] = 29] = "ProjectionDef";
|
|
8778
|
+
/**
|
|
8779
|
+
* Create a content projection slot.
|
|
8780
|
+
*/
|
|
8781
|
+
OpKind[OpKind["Projection"] = 30] = "Projection";
|
|
8982
8782
|
/**
|
|
8983
8783
|
* The start of an i18n block.
|
|
8984
8784
|
*/
|
|
8985
|
-
OpKind[OpKind["I18nStart"] =
|
|
8785
|
+
OpKind[OpKind["I18nStart"] = 31] = "I18nStart";
|
|
8986
8786
|
/**
|
|
8987
8787
|
* A self-closing i18n on a single element.
|
|
8988
8788
|
*/
|
|
8989
|
-
OpKind[OpKind["I18n"] =
|
|
8789
|
+
OpKind[OpKind["I18n"] = 32] = "I18n";
|
|
8990
8790
|
/**
|
|
8991
8791
|
* The end of an i18n block.
|
|
8992
8792
|
*/
|
|
8993
|
-
OpKind[OpKind["I18nEnd"] =
|
|
8994
|
-
// TODO: Add Host Listeners, and possibly other host ops also.
|
|
8793
|
+
OpKind[OpKind["I18nEnd"] = 33] = "I18nEnd";
|
|
8995
8794
|
})(OpKind || (OpKind = {}));
|
|
8996
8795
|
/**
|
|
8997
8796
|
* Distinguishes different kinds of IR expressions.
|
|
@@ -9103,8 +8902,8 @@ var SemanticVariableKind;
|
|
|
9103
8902
|
})(SemanticVariableKind || (SemanticVariableKind = {}));
|
|
9104
8903
|
/**
|
|
9105
8904
|
* Whether to compile in compatibilty mode. In compatibility mode, the template pipeline will
|
|
9106
|
-
* attempt to match the output of `TemplateDefinitionBuilder` as exactly as possible, at the cost
|
|
9107
|
-
* producing quirky or larger code in some cases.
|
|
8905
|
+
* attempt to match the output of `TemplateDefinitionBuilder` as exactly as possible, at the cost
|
|
8906
|
+
* of producing quirky or larger code in some cases.
|
|
9108
8907
|
*/
|
|
9109
8908
|
var CompatibilityMode;
|
|
9110
8909
|
(function (CompatibilityMode) {
|
|
@@ -10094,6 +9893,8 @@ function transformExpressionsInOp(op, transform, flags) {
|
|
|
10094
9893
|
transformExpressionsInExpression(op.tagNameParams[placeholder], transform, flags);
|
|
10095
9894
|
}
|
|
10096
9895
|
break;
|
|
9896
|
+
case OpKind.Projection:
|
|
9897
|
+
case OpKind.ProjectionDef:
|
|
10097
9898
|
case OpKind.Element:
|
|
10098
9899
|
case OpKind.ElementStart:
|
|
10099
9900
|
case OpKind.ElementEnd:
|
|
@@ -10484,7 +10285,8 @@ class OpList {
|
|
|
10484
10285
|
* The set of OpKinds that represent the creation of an element or container
|
|
10485
10286
|
*/
|
|
10486
10287
|
const elementContainerOpKinds = new Set([
|
|
10487
|
-
OpKind.Element, OpKind.ElementStart, OpKind.Container, OpKind.ContainerStart, OpKind.Template
|
|
10288
|
+
OpKind.Element, OpKind.ElementStart, OpKind.Container, OpKind.ContainerStart, OpKind.Template,
|
|
10289
|
+
OpKind.Projection
|
|
10488
10290
|
]);
|
|
10489
10291
|
/**
|
|
10490
10292
|
* Checks whether the given operation represents the creation of an element or container.
|
|
@@ -10513,12 +10315,13 @@ function createElementStartOp(tag, xref, namespace, i18n, sourceSpan) {
|
|
|
10513
10315
|
/**
|
|
10514
10316
|
* Create a `TemplateOp`.
|
|
10515
10317
|
*/
|
|
10516
|
-
function createTemplateOp(xref, tag, namespace, i18n, sourceSpan) {
|
|
10318
|
+
function createTemplateOp(xref, tag, namespace, controlFlow, i18n, sourceSpan) {
|
|
10517
10319
|
return {
|
|
10518
10320
|
kind: OpKind.Template,
|
|
10519
10321
|
xref,
|
|
10520
10322
|
attributes: null,
|
|
10521
10323
|
tag,
|
|
10324
|
+
controlFlow,
|
|
10522
10325
|
decls: null,
|
|
10523
10326
|
vars: null,
|
|
10524
10327
|
localRefs: [],
|
|
@@ -10612,6 +10415,29 @@ function createNamespaceOp(namespace) {
|
|
|
10612
10415
|
...NEW_OP,
|
|
10613
10416
|
};
|
|
10614
10417
|
}
|
|
10418
|
+
function createProjectionDefOp(def) {
|
|
10419
|
+
return {
|
|
10420
|
+
kind: OpKind.ProjectionDef,
|
|
10421
|
+
def,
|
|
10422
|
+
...NEW_OP,
|
|
10423
|
+
};
|
|
10424
|
+
}
|
|
10425
|
+
function createProjectionOp(xref, selector) {
|
|
10426
|
+
return {
|
|
10427
|
+
kind: OpKind.Projection,
|
|
10428
|
+
xref,
|
|
10429
|
+
selector,
|
|
10430
|
+
projectionSlotIndex: 0,
|
|
10431
|
+
attributes: null,
|
|
10432
|
+
localRefs: [],
|
|
10433
|
+
nonBindable: false,
|
|
10434
|
+
i18n: undefined,
|
|
10435
|
+
sourceSpan: null,
|
|
10436
|
+
...NEW_OP,
|
|
10437
|
+
...TRAIT_CONSUMES_SLOT,
|
|
10438
|
+
...TRAIT_USES_SLOT_INDEX,
|
|
10439
|
+
};
|
|
10440
|
+
}
|
|
10615
10441
|
/**
|
|
10616
10442
|
* Create an `ExtractedAttributeOp`.
|
|
10617
10443
|
*/
|
|
@@ -10714,6 +10540,11 @@ class ComponentCompilationJob extends CompilationJob {
|
|
|
10714
10540
|
this.kind = CompilationJobKind.Tmpl;
|
|
10715
10541
|
this.fnSuffix = 'Template';
|
|
10716
10542
|
this.views = new Map();
|
|
10543
|
+
/**
|
|
10544
|
+
* Causes ngContentSelectors to be emitted, for content projection slots in the view. Possibly a
|
|
10545
|
+
* reference into the constant pool.
|
|
10546
|
+
*/
|
|
10547
|
+
this.contentSelectors = null;
|
|
10717
10548
|
/**
|
|
10718
10549
|
* Constant expressions used by operations within this component's compilation.
|
|
10719
10550
|
*
|
|
@@ -10964,6 +10795,7 @@ function phaseAlignPipeVariadicVarOffset(job) {
|
|
|
10964
10795
|
expr.varOffset = expr.args.varOffset;
|
|
10965
10796
|
// Put the PureFunction vars following the PipeBindingVariadic vars.
|
|
10966
10797
|
expr.args.varOffset = expr.varOffset + varsUsedByIrExpression(expr);
|
|
10798
|
+
return undefined;
|
|
10967
10799
|
});
|
|
10968
10800
|
}
|
|
10969
10801
|
}
|
|
@@ -11018,7 +10850,7 @@ function phaseAttributeExtraction(job) {
|
|
|
11018
10850
|
break;
|
|
11019
10851
|
case OpKind.Property:
|
|
11020
10852
|
if (!op.isAnimationTrigger) {
|
|
11021
|
-
OpList.insertBefore(createExtractedAttributeOp(op.target, op.isTemplate ? BindingKind.Template : BindingKind.Property, op.name, null), lookupElement$
|
|
10853
|
+
OpList.insertBefore(createExtractedAttributeOp(op.target, op.isTemplate ? BindingKind.Template : BindingKind.Property, op.name, null), lookupElement$3(elements, op.target));
|
|
11022
10854
|
}
|
|
11023
10855
|
break;
|
|
11024
10856
|
case OpKind.StyleProp:
|
|
@@ -11028,7 +10860,7 @@ function phaseAttributeExtraction(job) {
|
|
|
11028
10860
|
// mode.
|
|
11029
10861
|
if (unit.job.compatibility === CompatibilityMode.TemplateDefinitionBuilder &&
|
|
11030
10862
|
op.expression instanceof EmptyExpr) {
|
|
11031
|
-
OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.Property, op.name, null), lookupElement$
|
|
10863
|
+
OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.Property, op.name, null), lookupElement$3(elements, op.target));
|
|
11032
10864
|
}
|
|
11033
10865
|
break;
|
|
11034
10866
|
case OpKind.Listener:
|
|
@@ -11040,7 +10872,7 @@ function phaseAttributeExtraction(job) {
|
|
|
11040
10872
|
unit.create.push(extractedAttributeOp);
|
|
11041
10873
|
}
|
|
11042
10874
|
else {
|
|
11043
|
-
OpList.insertBefore(extractedAttributeOp, lookupElement$
|
|
10875
|
+
OpList.insertBefore(extractedAttributeOp, lookupElement$3(elements, op.target));
|
|
11044
10876
|
}
|
|
11045
10877
|
}
|
|
11046
10878
|
break;
|
|
@@ -11051,7 +10883,7 @@ function phaseAttributeExtraction(job) {
|
|
|
11051
10883
|
/**
|
|
11052
10884
|
* Looks up an element in the given map by xref ID.
|
|
11053
10885
|
*/
|
|
11054
|
-
function lookupElement$
|
|
10886
|
+
function lookupElement$3(elements, xref) {
|
|
11055
10887
|
const el = elements.get(xref);
|
|
11056
10888
|
if (el === undefined) {
|
|
11057
10889
|
throw new Error('All attributes should have an element-like target.');
|
|
@@ -11089,7 +10921,7 @@ function extractAttributeOp(unit, op, elements) {
|
|
|
11089
10921
|
unit.create.push(extractedAttributeOp);
|
|
11090
10922
|
}
|
|
11091
10923
|
else {
|
|
11092
|
-
const ownerOp = lookupElement$
|
|
10924
|
+
const ownerOp = lookupElement$3(elements, op.target);
|
|
11093
10925
|
OpList.insertBefore(extractedAttributeOp, ownerOp);
|
|
11094
10926
|
}
|
|
11095
10927
|
OpList.remove(op);
|
|
@@ -11099,7 +10931,7 @@ function extractAttributeOp(unit, op, elements) {
|
|
|
11099
10931
|
/**
|
|
11100
10932
|
* Looks up an element in the given map by xref ID.
|
|
11101
10933
|
*/
|
|
11102
|
-
function lookupElement$
|
|
10934
|
+
function lookupElement$2(elements, xref) {
|
|
11103
10935
|
const el = elements.get(xref);
|
|
11104
10936
|
if (el === undefined) {
|
|
11105
10937
|
throw new Error('All attributes should have an element-like target.');
|
|
@@ -11125,7 +10957,7 @@ function phaseBindingSpecialization(job) {
|
|
|
11125
10957
|
case BindingKind.Attribute:
|
|
11126
10958
|
if (op.name === 'ngNonBindable') {
|
|
11127
10959
|
OpList.remove(op);
|
|
11128
|
-
const target = lookupElement$
|
|
10960
|
+
const target = lookupElement$2(elements, op.target);
|
|
11129
10961
|
target.nonBindable = true;
|
|
11130
10962
|
}
|
|
11131
10963
|
else {
|
|
@@ -11310,38 +11142,65 @@ function mergeNsAndName(prefix, localName) {
|
|
|
11310
11142
|
return prefix ? `:${prefix}:${localName}` : localName;
|
|
11311
11143
|
}
|
|
11312
11144
|
|
|
11145
|
+
const BINARY_OPERATORS = new Map([
|
|
11146
|
+
['&&', BinaryOperator.And],
|
|
11147
|
+
['>', BinaryOperator.Bigger],
|
|
11148
|
+
['>=', BinaryOperator.BiggerEquals],
|
|
11149
|
+
['&', BinaryOperator.BitwiseAnd],
|
|
11150
|
+
['/', BinaryOperator.Divide],
|
|
11151
|
+
['==', BinaryOperator.Equals],
|
|
11152
|
+
['===', BinaryOperator.Identical],
|
|
11153
|
+
['<', BinaryOperator.Lower],
|
|
11154
|
+
['<=', BinaryOperator.LowerEquals],
|
|
11155
|
+
['-', BinaryOperator.Minus],
|
|
11156
|
+
['%', BinaryOperator.Modulo],
|
|
11157
|
+
['*', BinaryOperator.Multiply],
|
|
11158
|
+
['!=', BinaryOperator.NotEquals],
|
|
11159
|
+
['!==', BinaryOperator.NotIdentical],
|
|
11160
|
+
['??', BinaryOperator.NullishCoalesce],
|
|
11161
|
+
['||', BinaryOperator.Or],
|
|
11162
|
+
['+', BinaryOperator.Plus],
|
|
11163
|
+
]);
|
|
11164
|
+
const NAMESPACES = new Map([['svg', Namespace.SVG], ['math', Namespace.Math]]);
|
|
11165
|
+
function namespaceForKey(namespacePrefixKey) {
|
|
11166
|
+
if (namespacePrefixKey === null) {
|
|
11167
|
+
return Namespace.HTML;
|
|
11168
|
+
}
|
|
11169
|
+
return NAMESPACES.get(namespacePrefixKey) ?? Namespace.HTML;
|
|
11170
|
+
}
|
|
11171
|
+
function keyForNamespace(namespace) {
|
|
11172
|
+
for (const [k, n] of NAMESPACES.entries()) {
|
|
11173
|
+
if (n === namespace) {
|
|
11174
|
+
return k;
|
|
11175
|
+
}
|
|
11176
|
+
}
|
|
11177
|
+
return null; // No namespace prefix for HTML
|
|
11178
|
+
}
|
|
11179
|
+
function prefixWithNamespace(strippedTag, namespace) {
|
|
11180
|
+
if (namespace === Namespace.HTML) {
|
|
11181
|
+
return strippedTag;
|
|
11182
|
+
}
|
|
11183
|
+
return `:${keyForNamespace(namespace)}:${strippedTag}`;
|
|
11184
|
+
}
|
|
11185
|
+
function literalOrArrayLiteral(value) {
|
|
11186
|
+
if (Array.isArray(value)) {
|
|
11187
|
+
return literalArr(value.map(literalOrArrayLiteral));
|
|
11188
|
+
}
|
|
11189
|
+
return literal(value, INFERRED_TYPE);
|
|
11190
|
+
}
|
|
11191
|
+
|
|
11313
11192
|
/**
|
|
11314
11193
|
* Converts the semantic attributes of element-like operations (elements, templates) into constant
|
|
11315
11194
|
* array expressions, and lifts them into the overall component `consts`.
|
|
11316
11195
|
*/
|
|
11317
11196
|
function phaseConstCollection(job) {
|
|
11318
|
-
if (job instanceof ComponentCompilationJob) {
|
|
11319
|
-
// Serialize the extracted messages into the const array.
|
|
11320
|
-
const messageConstIndices = {};
|
|
11321
|
-
for (const unit of job.units) {
|
|
11322
|
-
for (const op of unit.create) {
|
|
11323
|
-
if (op.kind === OpKind.ExtractedMessage) {
|
|
11324
|
-
messageConstIndices[op.owner] = job.addConst(op.expression, op.statements);
|
|
11325
|
-
OpList.remove(op);
|
|
11326
|
-
}
|
|
11327
|
-
}
|
|
11328
|
-
}
|
|
11329
|
-
// Assign const index to i18n ops that messages were extracted from.
|
|
11330
|
-
for (const unit of job.units) {
|
|
11331
|
-
for (const op of unit.create) {
|
|
11332
|
-
if (op.kind === OpKind.I18nStart && messageConstIndices[op.xref] !== undefined) {
|
|
11333
|
-
op.messageIndex = messageConstIndices[op.xref];
|
|
11334
|
-
}
|
|
11335
|
-
}
|
|
11336
|
-
}
|
|
11337
|
-
}
|
|
11338
11197
|
// Collect all extracted attributes.
|
|
11339
|
-
const
|
|
11198
|
+
const allElementAttributes = new Map();
|
|
11340
11199
|
for (const unit of job.units) {
|
|
11341
11200
|
for (const op of unit.create) {
|
|
11342
11201
|
if (op.kind === OpKind.ExtractedAttribute) {
|
|
11343
|
-
const attributes =
|
|
11344
|
-
|
|
11202
|
+
const attributes = allElementAttributes.get(op.target) || new ElementAttributes();
|
|
11203
|
+
allElementAttributes.set(op.target, attributes);
|
|
11345
11204
|
attributes.add(op.bindingKind, op.name, op.expression);
|
|
11346
11205
|
OpList.remove(op);
|
|
11347
11206
|
}
|
|
@@ -11351,9 +11210,8 @@ function phaseConstCollection(job) {
|
|
|
11351
11210
|
if (job instanceof ComponentCompilationJob) {
|
|
11352
11211
|
for (const unit of job.units) {
|
|
11353
11212
|
for (const op of unit.create) {
|
|
11354
|
-
if (op
|
|
11355
|
-
|
|
11356
|
-
const attributes = elementAttributes.get(op.xref);
|
|
11213
|
+
if (isElementOrContainerOp(op)) {
|
|
11214
|
+
const attributes = allElementAttributes.get(op.xref);
|
|
11357
11215
|
if (attributes !== undefined) {
|
|
11358
11216
|
const attrArray = serializeAttributes(attributes);
|
|
11359
11217
|
if (attrArray.entries.length > 0) {
|
|
@@ -11367,7 +11225,7 @@ function phaseConstCollection(job) {
|
|
|
11367
11225
|
else if (job instanceof HostBindingCompilationJob) {
|
|
11368
11226
|
// TODO: If the host binding case further diverges, we may want to split it into its own
|
|
11369
11227
|
// phase.
|
|
11370
|
-
for (const [xref, attributes] of
|
|
11228
|
+
for (const [xref, attributes] of allElementAttributes.entries()) {
|
|
11371
11229
|
if (xref !== job.root.xref) {
|
|
11372
11230
|
throw new Error(`An attribute would be const collected into the host binding's template function, but is not associated with the root xref.`);
|
|
11373
11231
|
}
|
|
@@ -11414,6 +11272,15 @@ class ElementAttributes {
|
|
|
11414
11272
|
return;
|
|
11415
11273
|
}
|
|
11416
11274
|
this.known.add(name);
|
|
11275
|
+
if (name === 'ngProjectAs') {
|
|
11276
|
+
if (value === null || !(value instanceof LiteralExpr) || (value.value == null) ||
|
|
11277
|
+
(typeof value.value?.toString() !== 'string')) {
|
|
11278
|
+
throw Error('ngProjectAs must have a string literal value');
|
|
11279
|
+
}
|
|
11280
|
+
this.projectAs = value.value.toString();
|
|
11281
|
+
// TODO: TemplateDefinitionBuilder allows `ngProjectAs` to also be assigned as a literal
|
|
11282
|
+
// attribute. Is this sane?
|
|
11283
|
+
}
|
|
11417
11284
|
const array = this.arrayFor(kind);
|
|
11418
11285
|
array.push(...getAttributeNameLiterals$1(name));
|
|
11419
11286
|
if (kind === BindingKind.Attribute || kind === BindingKind.StyleProperty) {
|
|
@@ -11449,7 +11316,10 @@ function getAttributeNameLiterals$1(name) {
|
|
|
11449
11316
|
function serializeAttributes({ attributes, bindings, classes, i18n, projectAs, styles, template }) {
|
|
11450
11317
|
const attrArray = [...attributes];
|
|
11451
11318
|
if (projectAs !== null) {
|
|
11452
|
-
|
|
11319
|
+
// Parse the attribute value into a CssSelectorList. Note that we only take the
|
|
11320
|
+
// first selector, because we don't support multiple selectors in ngProjectAs.
|
|
11321
|
+
const parsedR3Selector = parseSelectorToR3Selector(projectAs)[0];
|
|
11322
|
+
attrArray.push(literal(5 /* core.AttributeMarker.ProjectAs */), literalOrArrayLiteral(parsedR3Selector));
|
|
11453
11323
|
}
|
|
11454
11324
|
if (classes.length > 0) {
|
|
11455
11325
|
attrArray.push(literal(1 /* core.AttributeMarker.Classes */), ...classes);
|
|
@@ -18057,7 +17927,7 @@ class _TreeBuilder {
|
|
|
18057
17927
|
// This is unlikely to happen, but we have an assertion just in case.
|
|
18058
17928
|
if (parent instanceof BlockGroup) {
|
|
18059
17929
|
this.errors.push(TreeError.create(null, startSpan, 'Text cannot be placed directly inside of a block group.'));
|
|
18060
|
-
return
|
|
17930
|
+
return;
|
|
18061
17931
|
}
|
|
18062
17932
|
if (parent != null && parent.children.length === 0 &&
|
|
18063
17933
|
this.getTagDefinition(parent.name).ignoreFirstLf) {
|
|
@@ -19094,47 +18964,6 @@ function hyphenate(value) {
|
|
|
19094
18964
|
.toLowerCase();
|
|
19095
18965
|
}
|
|
19096
18966
|
|
|
19097
|
-
const BINARY_OPERATORS = new Map([
|
|
19098
|
-
['&&', BinaryOperator.And],
|
|
19099
|
-
['>', BinaryOperator.Bigger],
|
|
19100
|
-
['>=', BinaryOperator.BiggerEquals],
|
|
19101
|
-
['&', BinaryOperator.BitwiseAnd],
|
|
19102
|
-
['/', BinaryOperator.Divide],
|
|
19103
|
-
['==', BinaryOperator.Equals],
|
|
19104
|
-
['===', BinaryOperator.Identical],
|
|
19105
|
-
['<', BinaryOperator.Lower],
|
|
19106
|
-
['<=', BinaryOperator.LowerEquals],
|
|
19107
|
-
['-', BinaryOperator.Minus],
|
|
19108
|
-
['%', BinaryOperator.Modulo],
|
|
19109
|
-
['*', BinaryOperator.Multiply],
|
|
19110
|
-
['!=', BinaryOperator.NotEquals],
|
|
19111
|
-
['!==', BinaryOperator.NotIdentical],
|
|
19112
|
-
['??', BinaryOperator.NullishCoalesce],
|
|
19113
|
-
['||', BinaryOperator.Or],
|
|
19114
|
-
['+', BinaryOperator.Plus],
|
|
19115
|
-
]);
|
|
19116
|
-
const NAMESPACES = new Map([['svg', Namespace.SVG], ['math', Namespace.Math]]);
|
|
19117
|
-
function namespaceForKey(namespacePrefixKey) {
|
|
19118
|
-
if (namespacePrefixKey === null) {
|
|
19119
|
-
return Namespace.HTML;
|
|
19120
|
-
}
|
|
19121
|
-
return NAMESPACES.get(namespacePrefixKey) ?? Namespace.HTML;
|
|
19122
|
-
}
|
|
19123
|
-
function keyForNamespace(namespace) {
|
|
19124
|
-
for (const [k, n] of NAMESPACES.entries()) {
|
|
19125
|
-
if (n === namespace) {
|
|
19126
|
-
return k;
|
|
19127
|
-
}
|
|
19128
|
-
}
|
|
19129
|
-
return null; // No namespace prefix for HTML
|
|
19130
|
-
}
|
|
19131
|
-
function prefixWithNamespace(strippedTag, namespace) {
|
|
19132
|
-
if (namespace === Namespace.HTML) {
|
|
19133
|
-
return strippedTag;
|
|
19134
|
-
}
|
|
19135
|
-
return `:${keyForNamespace(namespace)}:${strippedTag}`;
|
|
19136
|
-
}
|
|
19137
|
-
|
|
19138
18967
|
/**
|
|
19139
18968
|
* Generate names for functions and variables across all views.
|
|
19140
18969
|
*
|
|
@@ -19310,6 +19139,7 @@ function mergeNextContextsInOps(ops) {
|
|
|
19310
19139
|
tryToMerge = false;
|
|
19311
19140
|
break;
|
|
19312
19141
|
}
|
|
19142
|
+
return;
|
|
19313
19143
|
});
|
|
19314
19144
|
}
|
|
19315
19145
|
}
|
|
@@ -19367,7 +19197,7 @@ function phaseNoListenersOnTemplates(job) {
|
|
|
19367
19197
|
/**
|
|
19368
19198
|
* Looks up an element in the given map by xref ID.
|
|
19369
19199
|
*/
|
|
19370
|
-
function lookupElement(elements, xref) {
|
|
19200
|
+
function lookupElement$1(elements, xref) {
|
|
19371
19201
|
const el = elements.get(xref);
|
|
19372
19202
|
if (el === undefined) {
|
|
19373
19203
|
throw new Error('All attributes should have an element-like target.');
|
|
@@ -19396,7 +19226,7 @@ function phaseNonbindable(job) {
|
|
|
19396
19226
|
OpList.insertAfter(createDisableBindingsOp(op.xref), op);
|
|
19397
19227
|
}
|
|
19398
19228
|
if ((op.kind === OpKind.ElementEnd || op.kind === OpKind.ContainerEnd) &&
|
|
19399
|
-
lookupElement(elements, op.xref).nonBindable) {
|
|
19229
|
+
lookupElement$1(elements, op.xref).nonBindable) {
|
|
19400
19230
|
OpList.insertBefore(createEnableBindingsOp(op.xref), op);
|
|
19401
19231
|
}
|
|
19402
19232
|
}
|
|
@@ -19734,8 +19564,11 @@ function elementContainerEnd() {
|
|
|
19734
19564
|
}
|
|
19735
19565
|
function template(slot, templateFnRef, decls, vars, tag, constIndex, sourceSpan) {
|
|
19736
19566
|
const args = [literal(slot), templateFnRef, literal(decls), literal(vars)];
|
|
19737
|
-
if (tag
|
|
19738
|
-
args.push(literal(tag)
|
|
19567
|
+
if (tag !== null) {
|
|
19568
|
+
args.push(literal(tag));
|
|
19569
|
+
if (constIndex !== null) {
|
|
19570
|
+
args.push(literal(constIndex));
|
|
19571
|
+
}
|
|
19739
19572
|
}
|
|
19740
19573
|
return call(Identifiers.templateCreate, args, sourceSpan);
|
|
19741
19574
|
}
|
|
@@ -19805,6 +19638,19 @@ function text(slot, initialValue, sourceSpan) {
|
|
|
19805
19638
|
}
|
|
19806
19639
|
return call(Identifiers.text, args, sourceSpan);
|
|
19807
19640
|
}
|
|
19641
|
+
function projectionDef(def) {
|
|
19642
|
+
return call(Identifiers.projectionDef, def ? [def] : [], null);
|
|
19643
|
+
}
|
|
19644
|
+
function projection(slot, projectionSlotIndex, attributes) {
|
|
19645
|
+
const args = [literal(slot)];
|
|
19646
|
+
if (projectionSlotIndex !== 0 || attributes !== null) {
|
|
19647
|
+
args.push(literal(projectionSlotIndex));
|
|
19648
|
+
if (attributes != null) {
|
|
19649
|
+
args.push(literal(attributes));
|
|
19650
|
+
}
|
|
19651
|
+
}
|
|
19652
|
+
return call(Identifiers.projection, args, null);
|
|
19653
|
+
}
|
|
19808
19654
|
function i18nStart(slot, constIndex) {
|
|
19809
19655
|
return call(Identifiers.i18nStart, [literal(slot), literal(constIndex)], null);
|
|
19810
19656
|
}
|
|
@@ -20195,7 +20041,7 @@ function reifyCreateOperations(unit, ops) {
|
|
|
20195
20041
|
throw new Error(`AssertionError: must be compiling a component`);
|
|
20196
20042
|
}
|
|
20197
20043
|
const childView = unit.job.views.get(op.xref);
|
|
20198
|
-
OpList.replace(op, template(op.slot, variable(childView.fnName), childView.decls, childView.vars, op.tag, op.attributes, op.sourceSpan));
|
|
20044
|
+
OpList.replace(op, template(op.slot, variable(childView.fnName), childView.decls, childView.vars, op.controlFlow ? null : op.tag, op.attributes, op.sourceSpan));
|
|
20199
20045
|
break;
|
|
20200
20046
|
case OpKind.DisableBindings:
|
|
20201
20047
|
OpList.replace(op, disableBindings());
|
|
@@ -20232,6 +20078,15 @@ function reifyCreateOperations(unit, ops) {
|
|
|
20232
20078
|
break;
|
|
20233
20079
|
}
|
|
20234
20080
|
break;
|
|
20081
|
+
case OpKind.ProjectionDef:
|
|
20082
|
+
OpList.replace(op, projectionDef(op.def));
|
|
20083
|
+
break;
|
|
20084
|
+
case OpKind.Projection:
|
|
20085
|
+
if (op.slot === null) {
|
|
20086
|
+
throw new Error('No slot was assigned for project instruction');
|
|
20087
|
+
}
|
|
20088
|
+
OpList.replace(op, projection(op.slot, op.projectionSlotIndex, op.attributes));
|
|
20089
|
+
break;
|
|
20235
20090
|
case OpKind.Statement:
|
|
20236
20091
|
// Pass statement operations directly through.
|
|
20237
20092
|
break;
|
|
@@ -21284,7 +21139,99 @@ function allowConservativeInlining(decl, target) {
|
|
|
21284
21139
|
}
|
|
21285
21140
|
}
|
|
21286
21141
|
|
|
21142
|
+
/**
|
|
21143
|
+
* Locate projection slots, populate the each component's `ngContentSelectors` literal field,
|
|
21144
|
+
* populate `project` arguments, and generate the required `projectionDef` instruction for the job's
|
|
21145
|
+
* root view.
|
|
21146
|
+
*/
|
|
21147
|
+
function phaseGenerateProjectionDef(job) {
|
|
21148
|
+
// TODO: Why does TemplateDefinitionBuilder force a shared constant?
|
|
21149
|
+
const share = job.compatibility === CompatibilityMode.TemplateDefinitionBuilder;
|
|
21150
|
+
// Collect all selectors from this component, and its nested views. Also, assign each projection a
|
|
21151
|
+
// unique ascending projection slot index.
|
|
21152
|
+
const selectors = [];
|
|
21153
|
+
let projectionSlotIndex = 0;
|
|
21154
|
+
for (const unit of job.units) {
|
|
21155
|
+
for (const op of unit.create) {
|
|
21156
|
+
if (op.kind === OpKind.Projection) {
|
|
21157
|
+
selectors.push(op.selector);
|
|
21158
|
+
op.projectionSlotIndex = projectionSlotIndex++;
|
|
21159
|
+
}
|
|
21160
|
+
}
|
|
21161
|
+
}
|
|
21162
|
+
if (selectors.length > 0) {
|
|
21163
|
+
// Create the projectionDef array. If we only found a single wildcard selector, then we use the
|
|
21164
|
+
// default behavior with no arguments instead.
|
|
21165
|
+
let defExpr = null;
|
|
21166
|
+
if (selectors.length > 1 || selectors[0] !== '*') {
|
|
21167
|
+
const def = selectors.map(s => s === '*' ? s : parseSelectorToR3Selector(s));
|
|
21168
|
+
defExpr = job.pool.getConstLiteral(literalOrArrayLiteral(def), share);
|
|
21169
|
+
}
|
|
21170
|
+
// Create the ngContentSelectors constant.
|
|
21171
|
+
job.contentSelectors = job.pool.getConstLiteral(literalOrArrayLiteral(selectors), share);
|
|
21172
|
+
// The projection def instruction goes at the beginning of the root view, before any
|
|
21173
|
+
// `projection` instructions.
|
|
21174
|
+
job.root.create.prepend([createProjectionDefOp(defExpr)]);
|
|
21175
|
+
}
|
|
21176
|
+
}
|
|
21177
|
+
|
|
21178
|
+
/**
|
|
21179
|
+
* Lifts i18n properties into the consts array.
|
|
21180
|
+
*/
|
|
21181
|
+
function phaseI18nConstCollection(job) {
|
|
21182
|
+
// Serialize the extracted messages into the const array.
|
|
21183
|
+
// TODO: Use `Map` instead of object.
|
|
21184
|
+
const messageConstIndices = {};
|
|
21185
|
+
for (const unit of job.units) {
|
|
21186
|
+
for (const op of unit.create) {
|
|
21187
|
+
if (op.kind === OpKind.ExtractedMessage) {
|
|
21188
|
+
messageConstIndices[op.owner] = job.addConst(op.expression, op.statements);
|
|
21189
|
+
OpList.remove(op);
|
|
21190
|
+
}
|
|
21191
|
+
}
|
|
21192
|
+
}
|
|
21193
|
+
// Assign const index to i18n ops that messages were extracted from.
|
|
21194
|
+
for (const unit of job.units) {
|
|
21195
|
+
for (const op of unit.create) {
|
|
21196
|
+
if (op.kind === OpKind.I18nStart && messageConstIndices[op.xref] !== undefined) {
|
|
21197
|
+
op.messageIndex = messageConstIndices[op.xref];
|
|
21198
|
+
}
|
|
21199
|
+
}
|
|
21200
|
+
}
|
|
21201
|
+
}
|
|
21202
|
+
|
|
21203
|
+
/**
|
|
21204
|
+
* Attributes of `ng-content` named 'select' are specifically removed, because they control which
|
|
21205
|
+
* content matches as a property of the `projection`, and are not a plain attribute.
|
|
21206
|
+
*/
|
|
21207
|
+
function phaseRemoveContentSelectors(job) {
|
|
21208
|
+
for (const unit of job.units) {
|
|
21209
|
+
const elements = getElementsByXrefId(unit);
|
|
21210
|
+
for (const op of unit.update) {
|
|
21211
|
+
switch (op.kind) {
|
|
21212
|
+
case OpKind.Binding:
|
|
21213
|
+
const target = lookupElement(elements, op.target);
|
|
21214
|
+
if (op.name.toLowerCase() === 'select' && target.kind === OpKind.Projection) {
|
|
21215
|
+
OpList.remove(op);
|
|
21216
|
+
}
|
|
21217
|
+
continue;
|
|
21218
|
+
}
|
|
21219
|
+
}
|
|
21220
|
+
}
|
|
21221
|
+
}
|
|
21222
|
+
/**
|
|
21223
|
+
* Looks up an element in the given map by xref ID.
|
|
21224
|
+
*/
|
|
21225
|
+
function lookupElement(elements, xref) {
|
|
21226
|
+
const el = elements.get(xref);
|
|
21227
|
+
if (el === undefined) {
|
|
21228
|
+
throw new Error('All attributes should have an element-like target.');
|
|
21229
|
+
}
|
|
21230
|
+
return el;
|
|
21231
|
+
}
|
|
21232
|
+
|
|
21287
21233
|
const phases = [
|
|
21234
|
+
{ kind: CompilationJobKind.Tmpl, fn: phaseRemoveContentSelectors },
|
|
21288
21235
|
{ kind: CompilationJobKind.Tmpl, fn: phaseGenerateI18nBlocks },
|
|
21289
21236
|
{ kind: CompilationJobKind.Tmpl, fn: phaseI18nTextExtraction },
|
|
21290
21237
|
{ kind: CompilationJobKind.Host, fn: phaseHostStylePropertyParsing },
|
|
@@ -21299,6 +21246,7 @@ const phases = [
|
|
|
21299
21246
|
{ kind: CompilationJobKind.Tmpl, fn: phasePipeCreation },
|
|
21300
21247
|
{ kind: CompilationJobKind.Tmpl, fn: phasePipeVariadic },
|
|
21301
21248
|
{ kind: CompilationJobKind.Both, fn: phasePureLiteralStructures },
|
|
21249
|
+
{ kind: CompilationJobKind.Tmpl, fn: phaseGenerateProjectionDef },
|
|
21302
21250
|
{ kind: CompilationJobKind.Tmpl, fn: phaseGenerateVariables },
|
|
21303
21251
|
{ kind: CompilationJobKind.Tmpl, fn: phaseSaveRestoreView },
|
|
21304
21252
|
{ kind: CompilationJobKind.Tmpl, fn: phaseFindAnyCasts },
|
|
@@ -21313,6 +21261,7 @@ const phases = [
|
|
|
21313
21261
|
{ kind: CompilationJobKind.Tmpl, fn: phaseSlotAllocation },
|
|
21314
21262
|
{ kind: CompilationJobKind.Tmpl, fn: phaseResolveI18nPlaceholders },
|
|
21315
21263
|
{ kind: CompilationJobKind.Tmpl, fn: phaseI18nMessageExtraction },
|
|
21264
|
+
{ kind: CompilationJobKind.Tmpl, fn: phaseI18nConstCollection },
|
|
21316
21265
|
{ kind: CompilationJobKind.Both, fn: phaseConstCollection },
|
|
21317
21266
|
{ kind: CompilationJobKind.Both, fn: phaseVarCounting },
|
|
21318
21267
|
{ kind: CompilationJobKind.Tmpl, fn: phaseGenerateAdvance },
|
|
@@ -21508,6 +21457,9 @@ function ingestNodes(unit, template) {
|
|
|
21508
21457
|
else if (node instanceof Template) {
|
|
21509
21458
|
ingestTemplate(unit, node);
|
|
21510
21459
|
}
|
|
21460
|
+
else if (node instanceof Content) {
|
|
21461
|
+
ingestContent(unit, node);
|
|
21462
|
+
}
|
|
21511
21463
|
else if (node instanceof Text$3) {
|
|
21512
21464
|
ingestText(unit, node);
|
|
21513
21465
|
}
|
|
@@ -21550,7 +21502,7 @@ function ingestTemplate(unit, tmpl) {
|
|
|
21550
21502
|
[namespacePrefix, tagNameWithoutNamespace] = splitNsName(tmpl.tagName);
|
|
21551
21503
|
}
|
|
21552
21504
|
// TODO: validate the fallback tag name here.
|
|
21553
|
-
const tplOp = createTemplateOp(childView.xref, tagNameWithoutNamespace ?? 'ng-template', namespaceForKey(namespacePrefix), tmpl.i18n, tmpl.startSourceSpan);
|
|
21505
|
+
const tplOp = createTemplateOp(childView.xref, tagNameWithoutNamespace ?? 'ng-template', namespaceForKey(namespacePrefix), false, tmpl.i18n, tmpl.startSourceSpan);
|
|
21554
21506
|
unit.create.push(tplOp);
|
|
21555
21507
|
ingestBindings(unit, tplOp, tmpl);
|
|
21556
21508
|
ingestReferences(tplOp, tmpl);
|
|
@@ -21559,6 +21511,16 @@ function ingestTemplate(unit, tmpl) {
|
|
|
21559
21511
|
childView.contextVariables.set(name, value);
|
|
21560
21512
|
}
|
|
21561
21513
|
}
|
|
21514
|
+
/**
|
|
21515
|
+
* Ingest a literal text node from the AST into the given `ViewCompilation`.
|
|
21516
|
+
*/
|
|
21517
|
+
function ingestContent(unit, content) {
|
|
21518
|
+
const op = createProjectionOp(unit.job.allocateXrefId(), content.selector);
|
|
21519
|
+
for (const attr of content.attributes) {
|
|
21520
|
+
ingestBinding(unit, op.xref, attr.name, literal(attr.value), 1 /* e.BindingType.Attribute */, null, SecurityContext.NONE, attr.sourceSpan, true, false);
|
|
21521
|
+
}
|
|
21522
|
+
unit.create.push(op);
|
|
21523
|
+
}
|
|
21562
21524
|
/**
|
|
21563
21525
|
* Ingest a literal text node from the AST into the given `ViewCompilation`.
|
|
21564
21526
|
*/
|
|
@@ -21590,7 +21552,7 @@ function ingestSwitchBlock(unit, switchBlock) {
|
|
|
21590
21552
|
const cView = unit.job.allocateView(unit.xref);
|
|
21591
21553
|
if (!firstXref)
|
|
21592
21554
|
firstXref = cView.xref;
|
|
21593
|
-
unit.create.push(createTemplateOp(cView.xref, 'Case', Namespace.HTML, undefined, null));
|
|
21555
|
+
unit.create.push(createTemplateOp(cView.xref, 'Case', Namespace.HTML, true, undefined, null));
|
|
21594
21556
|
const caseExpr = switchCase.expression ? convertAst(switchCase.expression, unit.job) : null;
|
|
21595
21557
|
conditions.push([cView.xref, caseExpr]);
|
|
21596
21558
|
ingestNodes(cView, switchCase.children);
|
|
@@ -23043,16 +23005,15 @@ function parseForLoopParameters(block, errors, bindingParser) {
|
|
|
23043
23005
|
}
|
|
23044
23006
|
const [, itemName, rawExpression] = match;
|
|
23045
23007
|
const result = {
|
|
23046
|
-
itemName,
|
|
23008
|
+
itemName: new Variable(itemName, '$implicit', expressionParam.sourceSpan, expressionParam.sourceSpan),
|
|
23047
23009
|
trackBy: null,
|
|
23048
23010
|
expression: parseBlockParameterToBinding(expressionParam, bindingParser, rawExpression),
|
|
23049
|
-
context:
|
|
23011
|
+
context: {},
|
|
23050
23012
|
};
|
|
23051
23013
|
for (const param of secondaryParams) {
|
|
23052
23014
|
const letMatch = param.expression.match(FOR_LOOP_LET_PATTERN);
|
|
23053
23015
|
if (letMatch !== null) {
|
|
23054
|
-
|
|
23055
|
-
parseLetParameter(param.sourceSpan, letMatch[1], result.context, errors);
|
|
23016
|
+
parseLetParameter(param.sourceSpan, letMatch[1], param.sourceSpan, result.context, errors);
|
|
23056
23017
|
continue;
|
|
23057
23018
|
}
|
|
23058
23019
|
const trackMatch = param.expression.match(FOR_LOOP_TRACK_PATTERN);
|
|
@@ -23067,15 +23028,22 @@ function parseForLoopParameters(block, errors, bindingParser) {
|
|
|
23067
23028
|
}
|
|
23068
23029
|
errors.push(new ParseError(param.sourceSpan, `Unrecognized loop paramater "${param.expression}"`));
|
|
23069
23030
|
}
|
|
23031
|
+
// Fill out any variables that haven't been defined explicitly.
|
|
23032
|
+
for (const variableName of ALLOWED_FOR_LOOP_LET_VARIABLES) {
|
|
23033
|
+
if (!result.context.hasOwnProperty(variableName)) {
|
|
23034
|
+
result.context[variableName] =
|
|
23035
|
+
new Variable(variableName, variableName, block.startSourceSpan, block.startSourceSpan);
|
|
23036
|
+
}
|
|
23037
|
+
}
|
|
23070
23038
|
return result;
|
|
23071
23039
|
}
|
|
23072
23040
|
/** Parses the `let` parameter of a `for` loop block. */
|
|
23073
|
-
function parseLetParameter(sourceSpan, expression, context, errors) {
|
|
23041
|
+
function parseLetParameter(sourceSpan, expression, span, context, errors) {
|
|
23074
23042
|
const parts = expression.split(',');
|
|
23075
23043
|
for (const part of parts) {
|
|
23076
23044
|
const expressionParts = part.split('=');
|
|
23077
23045
|
const name = expressionParts.length === 2 ? expressionParts[0].trim() : '';
|
|
23078
|
-
const variableName = expressionParts.length === 2 ? expressionParts[1].trim() : '';
|
|
23046
|
+
const variableName = (expressionParts.length === 2 ? expressionParts[1].trim() : '');
|
|
23079
23047
|
if (name.length === 0 || variableName.length === 0) {
|
|
23080
23048
|
errors.push(new ParseError(sourceSpan, `Invalid for loop "let" parameter. Parameter should match the pattern "<name> = <variable name>"`));
|
|
23081
23049
|
}
|
|
@@ -23086,7 +23054,7 @@ function parseLetParameter(sourceSpan, expression, context, errors) {
|
|
|
23086
23054
|
errors.push(new ParseError(sourceSpan, `Duplicate "let" parameter variable "${variableName}"`));
|
|
23087
23055
|
}
|
|
23088
23056
|
else {
|
|
23089
|
-
context[variableName] = name;
|
|
23057
|
+
context[variableName] = new Variable(name, variableName, span, span);
|
|
23090
23058
|
}
|
|
23091
23059
|
}
|
|
23092
23060
|
}
|
|
@@ -23203,7 +23171,8 @@ function parseConditionalBlockParameters(block, errors, bindingParser) {
|
|
|
23203
23171
|
errors.push(new ParseError(param.sourceSpan, 'Conditional can only have one "as" expression'));
|
|
23204
23172
|
}
|
|
23205
23173
|
else {
|
|
23206
|
-
|
|
23174
|
+
const name = aliasMatch[1].trim();
|
|
23175
|
+
expressionAlias = new Variable(name, name, param.sourceSpan, param.sourceSpan);
|
|
23207
23176
|
}
|
|
23208
23177
|
}
|
|
23209
23178
|
return { expression, expressionAlias };
|
|
@@ -23482,10 +23451,10 @@ function createTimerTrigger(parameters, sourceSpan) {
|
|
|
23482
23451
|
return new TimerDeferredTrigger(delay, sourceSpan);
|
|
23483
23452
|
}
|
|
23484
23453
|
function createInteractionTrigger(parameters, sourceSpan) {
|
|
23485
|
-
if (parameters.length
|
|
23486
|
-
throw new Error(`"${OnTriggerType.INTERACTION}" trigger
|
|
23454
|
+
if (parameters.length !== 1) {
|
|
23455
|
+
throw new Error(`"${OnTriggerType.INTERACTION}" trigger must have exactly one parameter`);
|
|
23487
23456
|
}
|
|
23488
|
-
return new InteractionDeferredTrigger(parameters[0]
|
|
23457
|
+
return new InteractionDeferredTrigger(parameters[0], sourceSpan);
|
|
23489
23458
|
}
|
|
23490
23459
|
function createImmediateTrigger(parameters, sourceSpan) {
|
|
23491
23460
|
if (parameters.length > 0) {
|
|
@@ -23494,10 +23463,10 @@ function createImmediateTrigger(parameters, sourceSpan) {
|
|
|
23494
23463
|
return new ImmediateDeferredTrigger(sourceSpan);
|
|
23495
23464
|
}
|
|
23496
23465
|
function createHoverTrigger(parameters, sourceSpan) {
|
|
23497
|
-
if (parameters.length
|
|
23498
|
-
throw new Error(`"${OnTriggerType.HOVER}" trigger
|
|
23466
|
+
if (parameters.length !== 1) {
|
|
23467
|
+
throw new Error(`"${OnTriggerType.HOVER}" trigger must have exactly one parameter`);
|
|
23499
23468
|
}
|
|
23500
|
-
return new HoverDeferredTrigger(sourceSpan);
|
|
23469
|
+
return new HoverDeferredTrigger(parameters[0], sourceSpan);
|
|
23501
23470
|
}
|
|
23502
23471
|
function createViewportTrigger(parameters, sourceSpan) {
|
|
23503
23472
|
// TODO: the RFC has some more potential parameters for `viewport`.
|
|
@@ -25246,8 +25215,8 @@ class TemplateDefinitionBuilder {
|
|
|
25246
25215
|
// If the branch has an alias, it'll be assigned directly to the container's context.
|
|
25247
25216
|
// We define a variable referring directly to the context so that any nested usages can be
|
|
25248
25217
|
// rewritten to refer to it.
|
|
25249
|
-
const variables = expressionAlias ?
|
|
25250
|
-
[new Variable(expressionAlias, DIRECT_CONTEXT_REFERENCE, sourceSpan,
|
|
25218
|
+
const variables = expressionAlias !== null ?
|
|
25219
|
+
[new Variable(expressionAlias.name, DIRECT_CONTEXT_REFERENCE, expressionAlias.sourceSpan, expressionAlias.keySpan)] :
|
|
25251
25220
|
undefined;
|
|
25252
25221
|
return {
|
|
25253
25222
|
index: this.createEmbeddedTemplateFn(null, children, '_Conditional', sourceSpan, variables),
|
|
@@ -25455,11 +25424,7 @@ class TemplateDefinitionBuilder {
|
|
|
25455
25424
|
// Allocate one slot for the repeater metadata. The slots for the primary and empty block
|
|
25456
25425
|
// are implicitly inferred by the runtime to index + 1 and index + 2.
|
|
25457
25426
|
const blockIndex = this.allocateDataSlot();
|
|
25458
|
-
const primaryData = this.prepareEmbeddedTemplateFn(block.children, '_For', [
|
|
25459
|
-
new Variable(block.itemName, '$implicit', block.sourceSpan, block.sourceSpan),
|
|
25460
|
-
new Variable(getLoopLocalName(block, '$index'), '$index', block.sourceSpan, block.sourceSpan),
|
|
25461
|
-
new Variable(getLoopLocalName(block, '$count'), '$count', block.sourceSpan, block.sourceSpan),
|
|
25462
|
-
]);
|
|
25427
|
+
const primaryData = this.prepareEmbeddedTemplateFn(block.children, '_For', [block.item, block.contextVariables.$index, block.contextVariables.$count]);
|
|
25463
25428
|
const emptyData = block.empty === null ?
|
|
25464
25429
|
null :
|
|
25465
25430
|
this.prepareEmbeddedTemplateFn(block.empty.children, '_ForEmpty');
|
|
@@ -25489,34 +25454,35 @@ class TemplateDefinitionBuilder {
|
|
|
25489
25454
|
this.updateInstruction(block.sourceSpan, Identifiers.repeater, () => [literal(blockIndex), this.convertPropertyBinding(value)]);
|
|
25490
25455
|
}
|
|
25491
25456
|
registerComputedLoopVariables(block, bindingScope) {
|
|
25492
|
-
const indexLocalName =
|
|
25493
|
-
const countLocalName =
|
|
25457
|
+
const indexLocalName = block.contextVariables.$index.name;
|
|
25458
|
+
const countLocalName = block.contextVariables.$count.name;
|
|
25494
25459
|
const level = bindingScope.bindingLevel;
|
|
25495
|
-
bindingScope.set(level,
|
|
25496
|
-
bindingScope.set(level,
|
|
25497
|
-
bindingScope.set(level,
|
|
25498
|
-
bindingScope.set(level,
|
|
25460
|
+
bindingScope.set(level, block.contextVariables.$odd.name, scope => scope.get(indexLocalName).modulo(literal(2)).notIdentical(literal(0)));
|
|
25461
|
+
bindingScope.set(level, block.contextVariables.$even.name, scope => scope.get(indexLocalName).modulo(literal(2)).identical(literal(0)));
|
|
25462
|
+
bindingScope.set(level, block.contextVariables.$first.name, scope => scope.get(indexLocalName).identical(literal(0)));
|
|
25463
|
+
bindingScope.set(level, block.contextVariables.$last.name, scope => scope.get(indexLocalName).identical(scope.get(countLocalName).minus(literal(1))));
|
|
25499
25464
|
}
|
|
25500
25465
|
optimizeTrackByFunction(block) {
|
|
25466
|
+
const indexLocalName = block.contextVariables.$index.name;
|
|
25467
|
+
const itemName = block.item.name;
|
|
25501
25468
|
const ast = block.trackBy.ast;
|
|
25502
25469
|
// Top-level access of `$index` uses the built in `repeaterTrackByIndex`.
|
|
25503
25470
|
if (ast instanceof PropertyRead && ast.receiver instanceof ImplicitReceiver &&
|
|
25504
|
-
ast.name ===
|
|
25471
|
+
ast.name === indexLocalName) {
|
|
25505
25472
|
return { expression: importExpr(Identifiers.repeaterTrackByIndex), usesComponentInstance: false };
|
|
25506
25473
|
}
|
|
25507
25474
|
// Top-level access of the item uses the built in `repeaterTrackByIdentity`.
|
|
25508
25475
|
if (ast instanceof PropertyRead && ast.receiver instanceof ImplicitReceiver &&
|
|
25509
|
-
ast.name ===
|
|
25476
|
+
ast.name === itemName) {
|
|
25510
25477
|
return { expression: importExpr(Identifiers.repeaterTrackByIdentity), usesComponentInstance: false };
|
|
25511
25478
|
}
|
|
25512
25479
|
// Top-level calls in the form of `fn($index, item)` can be passed in directly.
|
|
25513
25480
|
if (ast instanceof Call && ast.receiver instanceof PropertyRead &&
|
|
25514
25481
|
ast.receiver.receiver instanceof ImplicitReceiver && ast.args.length === 2) {
|
|
25515
25482
|
const firstIsIndex = ast.args[0] instanceof PropertyRead &&
|
|
25516
|
-
ast.args[0].receiver instanceof ImplicitReceiver &&
|
|
25517
|
-
ast.args[0].name === getLoopLocalName(block, '$index');
|
|
25483
|
+
ast.args[0].receiver instanceof ImplicitReceiver && ast.args[0].name === indexLocalName;
|
|
25518
25484
|
const secondIsItem = ast.args[1] instanceof PropertyRead &&
|
|
25519
|
-
ast.args[1].receiver instanceof ImplicitReceiver && ast.args[1].name ===
|
|
25485
|
+
ast.args[1].receiver instanceof ImplicitReceiver && ast.args[1].name === itemName;
|
|
25520
25486
|
if (firstIsIndex && secondIsItem) {
|
|
25521
25487
|
// If we're in the top-level component, we can access directly through `ctx`,
|
|
25522
25488
|
// otherwise we have to get a hold of the component through `componentInstance()`.
|
|
@@ -25533,20 +25499,22 @@ class TemplateDefinitionBuilder {
|
|
|
25533
25499
|
if (optimizedFn !== null) {
|
|
25534
25500
|
return optimizedFn;
|
|
25535
25501
|
}
|
|
25536
|
-
|
|
25537
|
-
// might not have. `$index` is special because of backwards compatibility.
|
|
25538
|
-
const bannedGlobals = new Set([
|
|
25539
|
-
getLoopLocalName(block, '$count'), getLoopLocalName(block, '$first'),
|
|
25540
|
-
getLoopLocalName(block, '$last'), getLoopLocalName(block, '$even'),
|
|
25541
|
-
getLoopLocalName(block, '$odd')
|
|
25542
|
-
]);
|
|
25502
|
+
const contextVars = block.contextVariables;
|
|
25543
25503
|
const scope = new TrackByBindingScope(this._bindingScope, {
|
|
25544
25504
|
// Alias `$index` and the item name to `$index` and `$item` respectively.
|
|
25545
25505
|
// This allows us to reuse pure functions that may have different item names,
|
|
25546
25506
|
// but are otherwise identical.
|
|
25547
|
-
[
|
|
25548
|
-
[block.
|
|
25549
|
-
|
|
25507
|
+
[contextVars.$index.name]: '$index',
|
|
25508
|
+
[block.item.name]: '$item',
|
|
25509
|
+
// Accessing these variables in a tracking function will result in a template diagnostic.
|
|
25510
|
+
// We define them as globals so that their accesses are preserved verbatim instead of being
|
|
25511
|
+
// rewritten to the actual accesses.
|
|
25512
|
+
[contextVars.$count.name]: contextVars.$count.name,
|
|
25513
|
+
[contextVars.$first.name]: contextVars.$first.name,
|
|
25514
|
+
[contextVars.$last.name]: contextVars.$last.name,
|
|
25515
|
+
[contextVars.$even.name]: contextVars.$even.name,
|
|
25516
|
+
[contextVars.$odd.name]: contextVars.$odd.name,
|
|
25517
|
+
});
|
|
25550
25518
|
const params = [new FnParam('$index'), new FnParam('$item')];
|
|
25551
25519
|
const stmts = convertPureComponentScopeFunction(block.trackBy.ast, scope, variable(CONTEXT_NAME), 'track');
|
|
25552
25520
|
const usesComponentInstance = scope.getComponentAccessCount() > 0;
|
|
@@ -25562,6 +25530,7 @@ class TemplateDefinitionBuilder {
|
|
|
25562
25530
|
stmts[stmts.length - 1] = new ReturnStatement(lastStatement.expr);
|
|
25563
25531
|
}
|
|
25564
25532
|
}
|
|
25533
|
+
// This has to be a function expression, because `.bind` doesn't work on arrow functions.
|
|
25565
25534
|
fn$1 = fn(params, stmts);
|
|
25566
25535
|
}
|
|
25567
25536
|
return {
|
|
@@ -26204,25 +26173,20 @@ class BindingScope {
|
|
|
26204
26173
|
}
|
|
26205
26174
|
/** Binding scope of a `track` function inside a `for` loop block. */
|
|
26206
26175
|
class TrackByBindingScope extends BindingScope {
|
|
26207
|
-
constructor(parentScope, globalAliases
|
|
26176
|
+
constructor(parentScope, globalAliases) {
|
|
26208
26177
|
super(parentScope.bindingLevel + 1, parentScope);
|
|
26209
26178
|
this.globalAliases = globalAliases;
|
|
26210
|
-
this.bannedGlobals = bannedGlobals;
|
|
26211
26179
|
this.componentAccessCount = 0;
|
|
26212
26180
|
}
|
|
26213
26181
|
get(name) {
|
|
26214
26182
|
let current = this.parent;
|
|
26215
|
-
//
|
|
26183
|
+
// Prevent accesses of template variables outside the `for` loop.
|
|
26216
26184
|
while (current) {
|
|
26217
26185
|
if (current.hasLocal(name)) {
|
|
26218
|
-
|
|
26186
|
+
return null;
|
|
26219
26187
|
}
|
|
26220
26188
|
current = current.parent;
|
|
26221
26189
|
}
|
|
26222
|
-
// If the variable is one of the banned globals, we have to throw.
|
|
26223
|
-
if (this.bannedGlobals.has(name)) {
|
|
26224
|
-
this.forbiddenAccessError(name);
|
|
26225
|
-
}
|
|
26226
26190
|
// Intercept any aliased globals.
|
|
26227
26191
|
if (this.globalAliases[name]) {
|
|
26228
26192
|
return variable(this.globalAliases[name]);
|
|
@@ -26235,11 +26199,6 @@ class TrackByBindingScope extends BindingScope {
|
|
|
26235
26199
|
getComponentAccessCount() {
|
|
26236
26200
|
return this.componentAccessCount;
|
|
26237
26201
|
}
|
|
26238
|
-
forbiddenAccessError(propertyName) {
|
|
26239
|
-
// TODO(crisbeto): this should be done through template type checking once it is available.
|
|
26240
|
-
throw new Error(`Accessing ${propertyName} inside of a track expression is not allowed. ` +
|
|
26241
|
-
`Tracking expressions can only access the item, $index and properties on the containing component.`);
|
|
26242
|
-
}
|
|
26243
26202
|
}
|
|
26244
26203
|
/**
|
|
26245
26204
|
* Creates a `CssSelector` given a tag name and a map of attributes
|
|
@@ -26557,10 +26516,6 @@ function createClosureModeGuard() {
|
|
|
26557
26516
|
.notIdentical(literal('undefined', STRING_TYPE))
|
|
26558
26517
|
.and(variable(NG_I18N_CLOSURE_MODE));
|
|
26559
26518
|
}
|
|
26560
|
-
/** Determines the name that a built in loop context variable is available under. */
|
|
26561
|
-
function getLoopLocalName(block, name) {
|
|
26562
|
-
return block.contextVariables?.[name] || name;
|
|
26563
|
-
}
|
|
26564
26519
|
|
|
26565
26520
|
// This regex matches any binding names that contain the "attr." prefix, e.g. "attr.required"
|
|
26566
26521
|
// If there is a match, the first matching group will contain the attribute name to bind.
|
|
@@ -26719,6 +26674,9 @@ function compileComponentFromMetadata(meta, constantPool, bindingParser) {
|
|
|
26719
26674
|
transform(tpl, CompilationJobKind.Tmpl);
|
|
26720
26675
|
// Finally we emit the template function:
|
|
26721
26676
|
const templateFn = emitTemplateFn(tpl, constantPool);
|
|
26677
|
+
if (tpl.contentSelectors !== null) {
|
|
26678
|
+
definitionMap.set('ngContentSelectors', tpl.contentSelectors);
|
|
26679
|
+
}
|
|
26722
26680
|
definitionMap.set('decls', literal(tpl.root.decls));
|
|
26723
26681
|
definitionMap.set('vars', literal(tpl.root.vars));
|
|
26724
26682
|
if (tpl.consts.length > 0) {
|
|
@@ -26967,11 +26925,11 @@ function createHostBindingsFunction(hostBindingsMetadata, typeSourceSpan, bindin
|
|
|
26967
26925
|
// actually already handle these special attributes internally. Therefore, we just drop them
|
|
26968
26926
|
// into the attributes map.
|
|
26969
26927
|
if (hostBindingsMetadata.specialAttributes.styleAttr) {
|
|
26970
|
-
hostBindingsMetadata.attributes
|
|
26928
|
+
hostBindingsMetadata.attributes['style'] =
|
|
26971
26929
|
literal(hostBindingsMetadata.specialAttributes.styleAttr);
|
|
26972
26930
|
}
|
|
26973
26931
|
if (hostBindingsMetadata.specialAttributes.classAttr) {
|
|
26974
|
-
hostBindingsMetadata.attributes
|
|
26932
|
+
hostBindingsMetadata.attributes['class'] =
|
|
26975
26933
|
literal(hostBindingsMetadata.specialAttributes.classAttr);
|
|
26976
26934
|
}
|
|
26977
26935
|
const hostJob = ingestHostBinding({
|
|
@@ -27946,7 +27904,7 @@ function publishFacade(global) {
|
|
|
27946
27904
|
* @description
|
|
27947
27905
|
* Entry point for all public APIs of the compiler package.
|
|
27948
27906
|
*/
|
|
27949
|
-
const VERSION = new Version('17.0.0-next.
|
|
27907
|
+
const VERSION = new Version('17.0.0-next.5');
|
|
27950
27908
|
|
|
27951
27909
|
class CompilerConfig {
|
|
27952
27910
|
constructor({ defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, missingTranslation = null, preserveWhitespaces, strictInjectionParameters } = {}) {
|
|
@@ -29408,7 +29366,7 @@ class R3TargetBinder {
|
|
|
29408
29366
|
// scopes in the template and makes them available for later use.
|
|
29409
29367
|
const scope = Scope.apply(target.template);
|
|
29410
29368
|
// Use the `Scope` to extract the entities present at every level of the template.
|
|
29411
|
-
const
|
|
29369
|
+
const scopedNodeEntities = extractScopedNodeEntities(scope);
|
|
29412
29370
|
// Next, perform directive matching on the template using the `DirectiveBinder`. This returns:
|
|
29413
29371
|
// - directives: Map of nodes (elements & ng-templates) to the directives on them.
|
|
29414
29372
|
// - bindings: Map of inputs, outputs, and attributes to the directive/element that claims
|
|
@@ -29418,7 +29376,7 @@ class R3TargetBinder {
|
|
|
29418
29376
|
// Finally, run the TemplateBinder to bind references, variables, and other entities within the
|
|
29419
29377
|
// template. This extracts all the metadata that doesn't depend on directive matching.
|
|
29420
29378
|
const { expressions, symbols, nestingLevel, usedPipes, eagerPipes, deferBlocks } = TemplateBinder.applyWithScope(target.template, scope);
|
|
29421
|
-
return new R3BoundTarget(target, directives, eagerDirectives, bindings, references, expressions, symbols, nestingLevel,
|
|
29379
|
+
return new R3BoundTarget(target, directives, eagerDirectives, bindings, references, expressions, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferBlocks);
|
|
29422
29380
|
}
|
|
29423
29381
|
}
|
|
29424
29382
|
/**
|
|
@@ -29429,17 +29387,19 @@ class R3TargetBinder {
|
|
|
29429
29387
|
* be analyzed and have their child `Scope`s available in `childScopes`.
|
|
29430
29388
|
*/
|
|
29431
29389
|
class Scope {
|
|
29432
|
-
constructor(parentScope,
|
|
29390
|
+
constructor(parentScope, rootNode) {
|
|
29433
29391
|
this.parentScope = parentScope;
|
|
29434
|
-
this.
|
|
29392
|
+
this.rootNode = rootNode;
|
|
29435
29393
|
/**
|
|
29436
29394
|
* Named members of the `Scope`, such as `Reference`s or `Variable`s.
|
|
29437
29395
|
*/
|
|
29438
29396
|
this.namedEntities = new Map();
|
|
29439
29397
|
/**
|
|
29440
|
-
* Child `Scope`s for immediately nested `
|
|
29398
|
+
* Child `Scope`s for immediately nested `ScopedNode`s.
|
|
29441
29399
|
*/
|
|
29442
29400
|
this.childScopes = new Map();
|
|
29401
|
+
this.isDeferred =
|
|
29402
|
+
parentScope !== null && parentScope.isDeferred ? true : rootNode instanceof DeferredBlock;
|
|
29443
29403
|
}
|
|
29444
29404
|
static newRootScope() {
|
|
29445
29405
|
return new Scope(null, null);
|
|
@@ -29454,18 +29414,35 @@ class Scope {
|
|
|
29454
29414
|
return scope;
|
|
29455
29415
|
}
|
|
29456
29416
|
/**
|
|
29457
|
-
* Internal method to process the
|
|
29417
|
+
* Internal method to process the scoped node and populate the `Scope`.
|
|
29458
29418
|
*/
|
|
29459
|
-
ingest(
|
|
29460
|
-
if (
|
|
29419
|
+
ingest(nodeOrNodes) {
|
|
29420
|
+
if (nodeOrNodes instanceof Template) {
|
|
29461
29421
|
// Variables on an <ng-template> are defined in the inner scope.
|
|
29462
|
-
|
|
29422
|
+
nodeOrNodes.variables.forEach(node => this.visitVariable(node));
|
|
29463
29423
|
// Process the nodes of the template.
|
|
29464
|
-
|
|
29424
|
+
nodeOrNodes.children.forEach(node => node.visit(this));
|
|
29425
|
+
}
|
|
29426
|
+
else if (nodeOrNodes instanceof IfBlockBranch) {
|
|
29427
|
+
if (nodeOrNodes.expressionAlias !== null) {
|
|
29428
|
+
this.visitVariable(nodeOrNodes.expressionAlias);
|
|
29429
|
+
}
|
|
29430
|
+
nodeOrNodes.children.forEach(node => node.visit(this));
|
|
29431
|
+
}
|
|
29432
|
+
else if (nodeOrNodes instanceof ForLoopBlock) {
|
|
29433
|
+
this.visitVariable(nodeOrNodes.item);
|
|
29434
|
+
Object.values(nodeOrNodes.contextVariables).forEach(v => this.visitVariable(v));
|
|
29435
|
+
nodeOrNodes.children.forEach(node => node.visit(this));
|
|
29436
|
+
}
|
|
29437
|
+
else if (nodeOrNodes instanceof SwitchBlockCase || nodeOrNodes instanceof ForLoopBlockEmpty ||
|
|
29438
|
+
nodeOrNodes instanceof DeferredBlock || nodeOrNodes instanceof DeferredBlockError ||
|
|
29439
|
+
nodeOrNodes instanceof DeferredBlockPlaceholder ||
|
|
29440
|
+
nodeOrNodes instanceof DeferredBlockLoading) {
|
|
29441
|
+
nodeOrNodes.children.forEach(node => node.visit(this));
|
|
29465
29442
|
}
|
|
29466
29443
|
else {
|
|
29467
29444
|
// No overarching `Template` instance, so process the nodes directly.
|
|
29468
|
-
|
|
29445
|
+
nodeOrNodes.forEach(node => node.visit(this));
|
|
29469
29446
|
}
|
|
29470
29447
|
}
|
|
29471
29448
|
visitElement(element) {
|
|
@@ -29479,9 +29456,7 @@ class Scope {
|
|
|
29479
29456
|
// processing the template's child scope.
|
|
29480
29457
|
template.references.forEach(node => this.visitReference(node));
|
|
29481
29458
|
// Next, create an inner scope and process the template within it.
|
|
29482
|
-
|
|
29483
|
-
scope.ingest(template);
|
|
29484
|
-
this.childScopes.set(template, scope);
|
|
29459
|
+
this.ingestScopedNode(template);
|
|
29485
29460
|
}
|
|
29486
29461
|
visitVariable(variable) {
|
|
29487
29462
|
// Declare the variable if it's not already.
|
|
@@ -29492,38 +29467,38 @@ class Scope {
|
|
|
29492
29467
|
this.maybeDeclare(reference);
|
|
29493
29468
|
}
|
|
29494
29469
|
visitDeferredBlock(deferred) {
|
|
29495
|
-
|
|
29470
|
+
this.ingestScopedNode(deferred);
|
|
29496
29471
|
deferred.placeholder?.visit(this);
|
|
29497
29472
|
deferred.loading?.visit(this);
|
|
29498
29473
|
deferred.error?.visit(this);
|
|
29499
29474
|
}
|
|
29500
29475
|
visitDeferredBlockPlaceholder(block) {
|
|
29501
|
-
|
|
29476
|
+
this.ingestScopedNode(block);
|
|
29502
29477
|
}
|
|
29503
29478
|
visitDeferredBlockError(block) {
|
|
29504
|
-
|
|
29479
|
+
this.ingestScopedNode(block);
|
|
29505
29480
|
}
|
|
29506
29481
|
visitDeferredBlockLoading(block) {
|
|
29507
|
-
|
|
29482
|
+
this.ingestScopedNode(block);
|
|
29508
29483
|
}
|
|
29509
29484
|
visitSwitchBlock(block) {
|
|
29510
29485
|
block.cases.forEach(node => node.visit(this));
|
|
29511
29486
|
}
|
|
29512
29487
|
visitSwitchBlockCase(block) {
|
|
29513
|
-
|
|
29488
|
+
this.ingestScopedNode(block);
|
|
29514
29489
|
}
|
|
29515
29490
|
visitForLoopBlock(block) {
|
|
29516
|
-
|
|
29491
|
+
this.ingestScopedNode(block);
|
|
29517
29492
|
block.empty?.visit(this);
|
|
29518
29493
|
}
|
|
29519
29494
|
visitForLoopBlockEmpty(block) {
|
|
29520
|
-
|
|
29495
|
+
this.ingestScopedNode(block);
|
|
29521
29496
|
}
|
|
29522
29497
|
visitIfBlock(block) {
|
|
29523
29498
|
block.branches.forEach(node => node.visit(this));
|
|
29524
29499
|
}
|
|
29525
29500
|
visitIfBlockBranch(block) {
|
|
29526
|
-
|
|
29501
|
+
this.ingestScopedNode(block);
|
|
29527
29502
|
}
|
|
29528
29503
|
// Unused visitors.
|
|
29529
29504
|
visitContent(content) { }
|
|
@@ -29560,17 +29535,22 @@ class Scope {
|
|
|
29560
29535
|
}
|
|
29561
29536
|
}
|
|
29562
29537
|
/**
|
|
29563
|
-
* Get the child scope for a `
|
|
29538
|
+
* Get the child scope for a `ScopedNode`.
|
|
29564
29539
|
*
|
|
29565
29540
|
* This should always be defined.
|
|
29566
29541
|
*/
|
|
29567
|
-
getChildScope(
|
|
29568
|
-
const res = this.childScopes.get(
|
|
29542
|
+
getChildScope(node) {
|
|
29543
|
+
const res = this.childScopes.get(node);
|
|
29569
29544
|
if (res === undefined) {
|
|
29570
|
-
throw new Error(`Assertion error: child scope for ${
|
|
29545
|
+
throw new Error(`Assertion error: child scope for ${node} not found`);
|
|
29571
29546
|
}
|
|
29572
29547
|
return res;
|
|
29573
29548
|
}
|
|
29549
|
+
ingestScopedNode(node) {
|
|
29550
|
+
const scope = new Scope(this, node);
|
|
29551
|
+
scope.ingest(node);
|
|
29552
|
+
this.childScopes.set(node, scope);
|
|
29553
|
+
}
|
|
29574
29554
|
}
|
|
29575
29555
|
/**
|
|
29576
29556
|
* Processes a template and matches directives on nodes (elements and templates).
|
|
@@ -29703,6 +29683,8 @@ class DirectiveBinder {
|
|
|
29703
29683
|
block.children.forEach(node => node.visit(this));
|
|
29704
29684
|
}
|
|
29705
29685
|
visitForLoopBlock(block) {
|
|
29686
|
+
block.item.visit(this);
|
|
29687
|
+
Object.values(block.contextVariables).forEach(v => v.visit(this));
|
|
29706
29688
|
block.children.forEach(node => node.visit(this));
|
|
29707
29689
|
block.empty?.visit(this);
|
|
29708
29690
|
}
|
|
@@ -29713,6 +29695,7 @@ class DirectiveBinder {
|
|
|
29713
29695
|
block.branches.forEach(node => node.visit(this));
|
|
29714
29696
|
}
|
|
29715
29697
|
visitIfBlockBranch(block) {
|
|
29698
|
+
block.expressionAlias?.visit(this);
|
|
29716
29699
|
block.children.forEach(node => node.visit(this));
|
|
29717
29700
|
}
|
|
29718
29701
|
// Unused visitors.
|
|
@@ -29738,7 +29721,7 @@ class DirectiveBinder {
|
|
|
29738
29721
|
* by overridden methods from that visitor.
|
|
29739
29722
|
*/
|
|
29740
29723
|
class TemplateBinder extends RecursiveAstVisitor {
|
|
29741
|
-
constructor(bindings, symbols, usedPipes, eagerPipes, deferBlocks, nestingLevel, scope,
|
|
29724
|
+
constructor(bindings, symbols, usedPipes, eagerPipes, deferBlocks, nestingLevel, scope, rootNode, level) {
|
|
29742
29725
|
super();
|
|
29743
29726
|
this.bindings = bindings;
|
|
29744
29727
|
this.symbols = symbols;
|
|
@@ -29747,10 +29730,8 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
29747
29730
|
this.deferBlocks = deferBlocks;
|
|
29748
29731
|
this.nestingLevel = nestingLevel;
|
|
29749
29732
|
this.scope = scope;
|
|
29750
|
-
this.
|
|
29733
|
+
this.rootNode = rootNode;
|
|
29751
29734
|
this.level = level;
|
|
29752
|
-
// Indicates whether we are visiting elements within a {#defer} block
|
|
29753
|
-
this.isInDeferBlock = false;
|
|
29754
29735
|
// Save a bit of processing time by constructing this closure in advance.
|
|
29755
29736
|
this.visitNode = (node) => node.visit(this);
|
|
29756
29737
|
}
|
|
@@ -29790,18 +29771,39 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
29790
29771
|
binder.ingest(nodes);
|
|
29791
29772
|
return { expressions, symbols, nestingLevel, usedPipes, eagerPipes, deferBlocks };
|
|
29792
29773
|
}
|
|
29793
|
-
ingest(
|
|
29794
|
-
if (
|
|
29774
|
+
ingest(nodeOrNodes) {
|
|
29775
|
+
if (nodeOrNodes instanceof Template) {
|
|
29795
29776
|
// For <ng-template>s, process only variables and child nodes. Inputs, outputs, templateAttrs,
|
|
29796
29777
|
// and references were all processed in the scope of the containing template.
|
|
29797
|
-
|
|
29798
|
-
|
|
29778
|
+
nodeOrNodes.variables.forEach(this.visitNode);
|
|
29779
|
+
nodeOrNodes.children.forEach(this.visitNode);
|
|
29799
29780
|
// Set the nesting level.
|
|
29800
|
-
this.nestingLevel.set(
|
|
29781
|
+
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
29782
|
+
}
|
|
29783
|
+
else if (nodeOrNodes instanceof IfBlockBranch) {
|
|
29784
|
+
if (nodeOrNodes.expressionAlias !== null) {
|
|
29785
|
+
this.visitNode(nodeOrNodes.expressionAlias);
|
|
29786
|
+
}
|
|
29787
|
+
nodeOrNodes.children.forEach(this.visitNode);
|
|
29788
|
+
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
29789
|
+
}
|
|
29790
|
+
else if (nodeOrNodes instanceof ForLoopBlock) {
|
|
29791
|
+
this.visitNode(nodeOrNodes.item);
|
|
29792
|
+
Object.values(nodeOrNodes.contextVariables).forEach(v => this.visitNode(v));
|
|
29793
|
+
nodeOrNodes.trackBy.visit(this);
|
|
29794
|
+
nodeOrNodes.children.forEach(this.visitNode);
|
|
29795
|
+
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
29796
|
+
}
|
|
29797
|
+
else if (nodeOrNodes instanceof SwitchBlockCase || nodeOrNodes instanceof ForLoopBlockEmpty ||
|
|
29798
|
+
nodeOrNodes instanceof DeferredBlock || nodeOrNodes instanceof DeferredBlockError ||
|
|
29799
|
+
nodeOrNodes instanceof DeferredBlockPlaceholder ||
|
|
29800
|
+
nodeOrNodes instanceof DeferredBlockLoading) {
|
|
29801
|
+
nodeOrNodes.children.forEach(node => node.visit(this));
|
|
29802
|
+
this.nestingLevel.set(nodeOrNodes, this.level);
|
|
29801
29803
|
}
|
|
29802
29804
|
else {
|
|
29803
29805
|
// Visit each node from the top-level template.
|
|
29804
|
-
|
|
29806
|
+
nodeOrNodes.forEach(this.visitNode);
|
|
29805
29807
|
}
|
|
29806
29808
|
}
|
|
29807
29809
|
visitElement(element) {
|
|
@@ -29809,29 +29811,27 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
29809
29811
|
element.inputs.forEach(this.visitNode);
|
|
29810
29812
|
element.outputs.forEach(this.visitNode);
|
|
29811
29813
|
element.children.forEach(this.visitNode);
|
|
29814
|
+
element.references.forEach(this.visitNode);
|
|
29812
29815
|
}
|
|
29813
29816
|
visitTemplate(template) {
|
|
29814
29817
|
// First, visit inputs, outputs and template attributes of the template node.
|
|
29815
29818
|
template.inputs.forEach(this.visitNode);
|
|
29816
29819
|
template.outputs.forEach(this.visitNode);
|
|
29817
29820
|
template.templateAttrs.forEach(this.visitNode);
|
|
29818
|
-
// References are also evaluated in the outer context.
|
|
29819
29821
|
template.references.forEach(this.visitNode);
|
|
29820
|
-
// Next, recurse into the template
|
|
29821
|
-
|
|
29822
|
-
const binder = new TemplateBinder(this.bindings, this.symbols, this.usedPipes, this.eagerPipes, this.deferBlocks, this.nestingLevel, childScope, template, this.level + 1);
|
|
29823
|
-
binder.ingest(template);
|
|
29822
|
+
// Next, recurse into the template.
|
|
29823
|
+
this.ingestScopedNode(template);
|
|
29824
29824
|
}
|
|
29825
29825
|
visitVariable(variable) {
|
|
29826
29826
|
// Register the `Variable` as a symbol in the current `Template`.
|
|
29827
|
-
if (this.
|
|
29828
|
-
this.symbols.set(variable, this.
|
|
29827
|
+
if (this.rootNode !== null) {
|
|
29828
|
+
this.symbols.set(variable, this.rootNode);
|
|
29829
29829
|
}
|
|
29830
29830
|
}
|
|
29831
29831
|
visitReference(reference) {
|
|
29832
29832
|
// Register the `Reference` as a symbol in the current `Template`.
|
|
29833
|
-
if (this.
|
|
29834
|
-
this.symbols.set(reference, this.
|
|
29833
|
+
if (this.rootNode !== null) {
|
|
29834
|
+
this.symbols.set(reference, this.rootNode);
|
|
29835
29835
|
}
|
|
29836
29836
|
}
|
|
29837
29837
|
// Unused template visitors
|
|
@@ -29851,10 +29851,7 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
29851
29851
|
}
|
|
29852
29852
|
visitDeferredBlock(deferred) {
|
|
29853
29853
|
this.deferBlocks.add(deferred);
|
|
29854
|
-
|
|
29855
|
-
this.isInDeferBlock = true;
|
|
29856
|
-
deferred.children.forEach(this.visitNode);
|
|
29857
|
-
this.isInDeferBlock = wasInDeferBlock;
|
|
29854
|
+
this.ingestScopedNode(deferred);
|
|
29858
29855
|
deferred.placeholder && this.visitNode(deferred.placeholder);
|
|
29859
29856
|
deferred.loading && this.visitNode(deferred.loading);
|
|
29860
29857
|
deferred.error && this.visitNode(deferred.error);
|
|
@@ -29865,13 +29862,13 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
29865
29862
|
}
|
|
29866
29863
|
}
|
|
29867
29864
|
visitDeferredBlockPlaceholder(block) {
|
|
29868
|
-
|
|
29865
|
+
this.ingestScopedNode(block);
|
|
29869
29866
|
}
|
|
29870
29867
|
visitDeferredBlockError(block) {
|
|
29871
|
-
|
|
29868
|
+
this.ingestScopedNode(block);
|
|
29872
29869
|
}
|
|
29873
29870
|
visitDeferredBlockLoading(block) {
|
|
29874
|
-
|
|
29871
|
+
this.ingestScopedNode(block);
|
|
29875
29872
|
}
|
|
29876
29873
|
visitSwitchBlock(block) {
|
|
29877
29874
|
block.expression.visit(this);
|
|
@@ -29879,29 +29876,29 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
29879
29876
|
}
|
|
29880
29877
|
visitSwitchBlockCase(block) {
|
|
29881
29878
|
block.expression?.visit(this);
|
|
29882
|
-
|
|
29879
|
+
this.ingestScopedNode(block);
|
|
29883
29880
|
}
|
|
29884
29881
|
visitForLoopBlock(block) {
|
|
29885
29882
|
block.expression.visit(this);
|
|
29886
|
-
|
|
29883
|
+
this.ingestScopedNode(block);
|
|
29887
29884
|
block.empty?.visit(this);
|
|
29888
29885
|
}
|
|
29889
29886
|
visitForLoopBlockEmpty(block) {
|
|
29890
|
-
|
|
29887
|
+
this.ingestScopedNode(block);
|
|
29891
29888
|
}
|
|
29892
29889
|
visitIfBlock(block) {
|
|
29893
29890
|
block.branches.forEach(node => node.visit(this));
|
|
29894
29891
|
}
|
|
29895
29892
|
visitIfBlockBranch(block) {
|
|
29896
29893
|
block.expression?.visit(this);
|
|
29897
|
-
|
|
29894
|
+
this.ingestScopedNode(block);
|
|
29898
29895
|
}
|
|
29899
29896
|
visitBoundText(text) {
|
|
29900
29897
|
text.value.visit(this);
|
|
29901
29898
|
}
|
|
29902
29899
|
visitPipe(ast, context) {
|
|
29903
29900
|
this.usedPipes.add(ast.name);
|
|
29904
|
-
if (!this.
|
|
29901
|
+
if (!this.scope.isDeferred) {
|
|
29905
29902
|
this.eagerPipes.add(ast.name);
|
|
29906
29903
|
}
|
|
29907
29904
|
return super.visitPipe(ast, context);
|
|
@@ -29909,18 +29906,23 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
29909
29906
|
// These five types of AST expressions can refer to expression roots, which could be variables
|
|
29910
29907
|
// or references in the current scope.
|
|
29911
29908
|
visitPropertyRead(ast, context) {
|
|
29912
|
-
this.maybeMap(
|
|
29909
|
+
this.maybeMap(ast, ast.name);
|
|
29913
29910
|
return super.visitPropertyRead(ast, context);
|
|
29914
29911
|
}
|
|
29915
29912
|
visitSafePropertyRead(ast, context) {
|
|
29916
|
-
this.maybeMap(
|
|
29913
|
+
this.maybeMap(ast, ast.name);
|
|
29917
29914
|
return super.visitSafePropertyRead(ast, context);
|
|
29918
29915
|
}
|
|
29919
29916
|
visitPropertyWrite(ast, context) {
|
|
29920
|
-
this.maybeMap(
|
|
29917
|
+
this.maybeMap(ast, ast.name);
|
|
29921
29918
|
return super.visitPropertyWrite(ast, context);
|
|
29922
29919
|
}
|
|
29923
|
-
|
|
29920
|
+
ingestScopedNode(node) {
|
|
29921
|
+
const childScope = this.scope.getChildScope(node);
|
|
29922
|
+
const binder = new TemplateBinder(this.bindings, this.symbols, this.usedPipes, this.eagerPipes, this.deferBlocks, this.nestingLevel, childScope, node, this.level + 1);
|
|
29923
|
+
binder.ingest(node);
|
|
29924
|
+
}
|
|
29925
|
+
maybeMap(ast, name) {
|
|
29924
29926
|
// If the receiver of the expression isn't the `ImplicitReceiver`, this isn't the root of an
|
|
29925
29927
|
// `AST` expression that maps to a `Variable` or `Reference`.
|
|
29926
29928
|
if (!(ast.receiver instanceof ImplicitReceiver)) {
|
|
@@ -29940,7 +29942,7 @@ class TemplateBinder extends RecursiveAstVisitor {
|
|
|
29940
29942
|
* See `BoundTarget` for documentation on the individual methods.
|
|
29941
29943
|
*/
|
|
29942
29944
|
class R3BoundTarget {
|
|
29943
|
-
constructor(target, directives, eagerDirectives, bindings, references, exprTargets, symbols, nestingLevel,
|
|
29945
|
+
constructor(target, directives, eagerDirectives, bindings, references, exprTargets, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferredBlocks) {
|
|
29944
29946
|
this.target = target;
|
|
29945
29947
|
this.directives = directives;
|
|
29946
29948
|
this.eagerDirectives = eagerDirectives;
|
|
@@ -29949,13 +29951,13 @@ class R3BoundTarget {
|
|
|
29949
29951
|
this.exprTargets = exprTargets;
|
|
29950
29952
|
this.symbols = symbols;
|
|
29951
29953
|
this.nestingLevel = nestingLevel;
|
|
29952
|
-
this.
|
|
29954
|
+
this.scopedNodeEntities = scopedNodeEntities;
|
|
29953
29955
|
this.usedPipes = usedPipes;
|
|
29954
29956
|
this.eagerPipes = eagerPipes;
|
|
29955
29957
|
this.deferredBlocks = deferredBlocks;
|
|
29956
29958
|
}
|
|
29957
|
-
|
|
29958
|
-
return this.
|
|
29959
|
+
getEntitiesInScope(node) {
|
|
29960
|
+
return this.scopedNodeEntities.get(node) ?? new Set();
|
|
29959
29961
|
}
|
|
29960
29962
|
getDirectivesOfNode(node) {
|
|
29961
29963
|
return this.directives.get(node) || null;
|
|
@@ -29969,11 +29971,11 @@ class R3BoundTarget {
|
|
|
29969
29971
|
getExpressionTarget(expr) {
|
|
29970
29972
|
return this.exprTargets.get(expr) || null;
|
|
29971
29973
|
}
|
|
29972
|
-
|
|
29974
|
+
getDefinitionNodeOfSymbol(symbol) {
|
|
29973
29975
|
return this.symbols.get(symbol) || null;
|
|
29974
29976
|
}
|
|
29975
|
-
getNestingLevel(
|
|
29976
|
-
return this.nestingLevel.get(
|
|
29977
|
+
getNestingLevel(node) {
|
|
29978
|
+
return this.nestingLevel.get(node) || 0;
|
|
29977
29979
|
}
|
|
29978
29980
|
getUsedDirectives() {
|
|
29979
29981
|
const set = new Set();
|
|
@@ -29993,23 +29995,79 @@ class R3BoundTarget {
|
|
|
29993
29995
|
getDeferBlocks() {
|
|
29994
29996
|
return Array.from(this.deferredBlocks);
|
|
29995
29997
|
}
|
|
29998
|
+
getDeferredTriggerTarget(block, trigger) {
|
|
29999
|
+
// Only triggers that refer to DOM nodes can be resolved.
|
|
30000
|
+
if (!(trigger instanceof InteractionDeferredTrigger) &&
|
|
30001
|
+
!(trigger instanceof ViewportDeferredTrigger) &&
|
|
30002
|
+
!(trigger instanceof HoverDeferredTrigger)) {
|
|
30003
|
+
return null;
|
|
30004
|
+
}
|
|
30005
|
+
const name = trigger.reference;
|
|
30006
|
+
// TODO(crisbeto): account for `viewport` trigger without a `reference`.
|
|
30007
|
+
if (name === null) {
|
|
30008
|
+
return null;
|
|
30009
|
+
}
|
|
30010
|
+
const outsideRef = this.findEntityInScope(block, name);
|
|
30011
|
+
// First try to resolve the target in the scope of the main deferred block. Note that we
|
|
30012
|
+
// skip triggers defined inside the main block itself, because they might not exist yet.
|
|
30013
|
+
if (outsideRef instanceof Reference && this.getDefinitionNodeOfSymbol(outsideRef) !== block) {
|
|
30014
|
+
const target = this.getReferenceTarget(outsideRef);
|
|
30015
|
+
if (target !== null) {
|
|
30016
|
+
return this.referenceTargetToElement(target);
|
|
30017
|
+
}
|
|
30018
|
+
}
|
|
30019
|
+
// If the trigger couldn't be found in the main block, check the
|
|
30020
|
+
// placeholder block which is shown before the main block has loaded.
|
|
30021
|
+
if (block.placeholder !== null) {
|
|
30022
|
+
const refInPlaceholder = this.findEntityInScope(block.placeholder, name);
|
|
30023
|
+
const targetInPlaceholder = refInPlaceholder instanceof Reference ? this.getReferenceTarget(refInPlaceholder) : null;
|
|
30024
|
+
if (targetInPlaceholder !== null) {
|
|
30025
|
+
return this.referenceTargetToElement(targetInPlaceholder);
|
|
30026
|
+
}
|
|
30027
|
+
}
|
|
30028
|
+
return null;
|
|
30029
|
+
}
|
|
30030
|
+
/**
|
|
30031
|
+
* Finds an entity with a specific name in a scope.
|
|
30032
|
+
* @param rootNode Root node of the scope.
|
|
30033
|
+
* @param name Name of the entity.
|
|
30034
|
+
*/
|
|
30035
|
+
findEntityInScope(rootNode, name) {
|
|
30036
|
+
const entities = this.getEntitiesInScope(rootNode);
|
|
30037
|
+
for (const entitity of entities) {
|
|
30038
|
+
if (entitity.name === name) {
|
|
30039
|
+
return entitity;
|
|
30040
|
+
}
|
|
30041
|
+
}
|
|
30042
|
+
return null;
|
|
30043
|
+
}
|
|
30044
|
+
/** Coerces a `ReferenceTarget` to an `Element`, if possible. */
|
|
30045
|
+
referenceTargetToElement(target) {
|
|
30046
|
+
if (target instanceof Element$1) {
|
|
30047
|
+
return target;
|
|
30048
|
+
}
|
|
30049
|
+
if (target instanceof Template) {
|
|
30050
|
+
return null;
|
|
30051
|
+
}
|
|
30052
|
+
return this.referenceTargetToElement(target.node);
|
|
30053
|
+
}
|
|
29996
30054
|
}
|
|
29997
|
-
function
|
|
30055
|
+
function extractScopedNodeEntities(rootScope) {
|
|
29998
30056
|
const entityMap = new Map();
|
|
29999
30057
|
function extractScopeEntities(scope) {
|
|
30000
|
-
if (entityMap.has(scope.
|
|
30001
|
-
return entityMap.get(scope.
|
|
30058
|
+
if (entityMap.has(scope.rootNode)) {
|
|
30059
|
+
return entityMap.get(scope.rootNode);
|
|
30002
30060
|
}
|
|
30003
30061
|
const currentEntities = scope.namedEntities;
|
|
30004
|
-
let
|
|
30062
|
+
let entities;
|
|
30005
30063
|
if (scope.parentScope !== null) {
|
|
30006
|
-
|
|
30064
|
+
entities = new Map([...extractScopeEntities(scope.parentScope), ...currentEntities]);
|
|
30007
30065
|
}
|
|
30008
30066
|
else {
|
|
30009
|
-
|
|
30067
|
+
entities = new Map(currentEntities);
|
|
30010
30068
|
}
|
|
30011
|
-
entityMap.set(scope.
|
|
30012
|
-
return
|
|
30069
|
+
entityMap.set(scope.rootNode, entities);
|
|
30070
|
+
return entities;
|
|
30013
30071
|
}
|
|
30014
30072
|
const scopesToProcess = [rootScope];
|
|
30015
30073
|
while (scopesToProcess.length > 0) {
|
|
@@ -30104,7 +30162,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$6 = '12.0.0';
|
|
|
30104
30162
|
function compileDeclareClassMetadata(metadata) {
|
|
30105
30163
|
const definitionMap = new DefinitionMap();
|
|
30106
30164
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
|
|
30107
|
-
definitionMap.set('version', literal('17.0.0-next.
|
|
30165
|
+
definitionMap.set('version', literal('17.0.0-next.5'));
|
|
30108
30166
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
30109
30167
|
definitionMap.set('type', metadata.type);
|
|
30110
30168
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -30212,7 +30270,7 @@ function createDirectiveDefinitionMap(meta) {
|
|
|
30212
30270
|
// in 16.1 is actually used.
|
|
30213
30271
|
const minVersion = hasTransformFunctions ? MINIMUM_PARTIAL_LINKER_VERSION$5 : '14.0.0';
|
|
30214
30272
|
definitionMap.set('minVersion', literal(minVersion));
|
|
30215
|
-
definitionMap.set('version', literal('17.0.0-next.
|
|
30273
|
+
definitionMap.set('version', literal('17.0.0-next.5'));
|
|
30216
30274
|
// e.g. `type: MyDirective`
|
|
30217
30275
|
definitionMap.set('type', meta.type.value);
|
|
30218
30276
|
if (meta.isStandalone) {
|
|
@@ -30443,7 +30501,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
|
|
|
30443
30501
|
function compileDeclareFactoryFunction(meta) {
|
|
30444
30502
|
const definitionMap = new DefinitionMap();
|
|
30445
30503
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
30446
|
-
definitionMap.set('version', literal('17.0.0-next.
|
|
30504
|
+
definitionMap.set('version', literal('17.0.0-next.5'));
|
|
30447
30505
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
30448
30506
|
definitionMap.set('type', meta.type.value);
|
|
30449
30507
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -30478,7 +30536,7 @@ function compileDeclareInjectableFromMetadata(meta) {
|
|
|
30478
30536
|
function createInjectableDefinitionMap(meta) {
|
|
30479
30537
|
const definitionMap = new DefinitionMap();
|
|
30480
30538
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
30481
|
-
definitionMap.set('version', literal('17.0.0-next.
|
|
30539
|
+
definitionMap.set('version', literal('17.0.0-next.5'));
|
|
30482
30540
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
30483
30541
|
definitionMap.set('type', meta.type.value);
|
|
30484
30542
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -30529,7 +30587,7 @@ function compileDeclareInjectorFromMetadata(meta) {
|
|
|
30529
30587
|
function createInjectorDefinitionMap(meta) {
|
|
30530
30588
|
const definitionMap = new DefinitionMap();
|
|
30531
30589
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
30532
|
-
definitionMap.set('version', literal('17.0.0-next.
|
|
30590
|
+
definitionMap.set('version', literal('17.0.0-next.5'));
|
|
30533
30591
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
30534
30592
|
definitionMap.set('type', meta.type.value);
|
|
30535
30593
|
definitionMap.set('providers', meta.providers);
|
|
@@ -30562,7 +30620,7 @@ function createNgModuleDefinitionMap(meta) {
|
|
|
30562
30620
|
throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
|
|
30563
30621
|
}
|
|
30564
30622
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
30565
|
-
definitionMap.set('version', literal('17.0.0-next.
|
|
30623
|
+
definitionMap.set('version', literal('17.0.0-next.5'));
|
|
30566
30624
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
30567
30625
|
definitionMap.set('type', meta.type.value);
|
|
30568
30626
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -30613,7 +30671,7 @@ function compileDeclarePipeFromMetadata(meta) {
|
|
|
30613
30671
|
function createPipeDefinitionMap(meta) {
|
|
30614
30672
|
const definitionMap = new DefinitionMap();
|
|
30615
30673
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
30616
|
-
definitionMap.set('version', literal('17.0.0-next.
|
|
30674
|
+
definitionMap.set('version', literal('17.0.0-next.5'));
|
|
30617
30675
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
30618
30676
|
// e.g. `type: MyPipe`
|
|
30619
30677
|
definitionMap.set('type', meta.type.value);
|