@angular/core 20.2.0-next.0 → 20.2.0-next.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.d.d.ts +1 -1
- package/chrome_dev_tools_performance.d.d.ts +1 -1
- package/discovery.d.d.ts +1 -1
- package/event_dispatcher.d.d.ts +1 -1
- package/fesm2022/attribute.mjs +1 -1
- package/fesm2022/attribute.mjs.map +1 -1
- package/fesm2022/core.mjs +26 -9
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/debug_node.mjs +647 -15
- package/fesm2022/debug_node.mjs.map +1 -1
- package/fesm2022/not_found.mjs +1 -1
- package/fesm2022/not_found.mjs.map +1 -1
- package/fesm2022/primitives/di.mjs +1 -1
- package/fesm2022/primitives/di.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/resource.mjs +8 -5
- package/fesm2022/resource.mjs.map +1 -1
- package/fesm2022/root_effect_scheduler.mjs +126 -53
- package/fesm2022/root_effect_scheduler.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +2 -2
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/signal.mjs +1 -1
- package/fesm2022/signal.mjs.map +1 -1
- package/fesm2022/testing.mjs +16 -8
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/untracked.mjs +1 -1
- package/fesm2022/untracked.mjs.map +1 -1
- package/fesm2022/weak_ref.mjs +1 -1
- package/fesm2022/weak_ref.mjs.map +1 -1
- package/graph.d.d.ts +1 -1
- package/index.d.ts +162 -3
- package/package.json +2 -2
- package/primitives/di/index.d.ts +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/bundles/{apply_import_manager-B0fYYMpr.cjs → apply_import_manager-Bkosyy2x.cjs} +3 -3
- package/schematics/bundles/{checker-DLInMAS3.cjs → checker-Cfq29XaS.cjs} +1294 -530
- package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
- package/schematics/bundles/{compiler_host-Doj9KVJf.cjs → compiler_host-CSrf1kFh.cjs} +2 -2
- package/schematics/bundles/control-flow-migration.cjs +3 -3
- package/schematics/bundles/document-core.cjs +5 -5
- package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
- package/schematics/bundles/{index-BmuUS1AB.cjs → index-DYbdsCUu.cjs} +80 -43
- package/schematics/bundles/{index-Bp8sCiq1.cjs → index-DwmX8Ifa.cjs} +4 -4
- package/schematics/bundles/inject-flags.cjs +5 -5
- package/schematics/bundles/inject-migration.cjs +3 -3
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-CmZ0155c.cjs → migrate_ts_type_references-C7NB9fZH.cjs} +5 -441
- package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +6 -6
- package/schematics/bundles/{project_paths-D2SJWT7x.cjs → project_paths-5CoqAjNK.cjs} +3 -3
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +1 -1
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/route-lazy-loading.cjs +3 -3
- package/schematics/bundles/self-closing-tags-migration.cjs +4 -4
- package/schematics/bundles/signal-input-migration.cjs +8 -8
- package/schematics/bundles/signal-queries-migration.cjs +7 -7
- package/schematics/bundles/signals.cjs +7 -7
- package/schematics/bundles/standalone-migration.cjs +4 -4
- package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
- package/schematics/bundles/test-bed-get.cjs +4 -4
- package/signal.d.d.ts +1 -1
- package/testing/index.d.ts +12 -2
- package/weak_ref.d.d.ts +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.2.0-next.
|
|
3
|
+
* @license Angular v20.2.0-next.2
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -2693,7 +2693,18 @@ class Identifiers {
|
|
|
2693
2693
|
static pipeBind4 = { name: 'ɵɵpipeBind4', moduleName: CORE };
|
|
2694
2694
|
static pipeBindV = { name: 'ɵɵpipeBindV', moduleName: CORE };
|
|
2695
2695
|
static domProperty = { name: 'ɵɵdomProperty', moduleName: CORE };
|
|
2696
|
+
static ariaProperty = { name: 'ɵɵariaProperty', moduleName: CORE };
|
|
2696
2697
|
static property = { name: 'ɵɵproperty', moduleName: CORE };
|
|
2698
|
+
static animationEnterListener = {
|
|
2699
|
+
name: 'ɵɵanimateEnterListener',
|
|
2700
|
+
moduleName: CORE,
|
|
2701
|
+
};
|
|
2702
|
+
static animationLeaveListener = {
|
|
2703
|
+
name: 'ɵɵanimateLeaveListener',
|
|
2704
|
+
moduleName: CORE,
|
|
2705
|
+
};
|
|
2706
|
+
static animationEnter = { name: 'ɵɵanimateEnter', moduleName: CORE };
|
|
2707
|
+
static animationLeave = { name: 'ɵɵanimateLeave', moduleName: CORE };
|
|
2697
2708
|
static i18n = { name: 'ɵɵi18n', moduleName: CORE };
|
|
2698
2709
|
static i18nAttributes = { name: 'ɵɵi18nAttributes', moduleName: CORE };
|
|
2699
2710
|
static i18nExp = { name: 'ɵɵi18nExp', moduleName: CORE };
|
|
@@ -2837,6 +2848,10 @@ class Identifiers {
|
|
|
2837
2848
|
name: 'ɵɵExternalStylesFeature',
|
|
2838
2849
|
moduleName: CORE,
|
|
2839
2850
|
};
|
|
2851
|
+
static AnimationsFeature = {
|
|
2852
|
+
name: 'ɵɵAnimationsFeature',
|
|
2853
|
+
moduleName: CORE,
|
|
2854
|
+
};
|
|
2840
2855
|
static listener = { name: 'ɵɵlistener', moduleName: CORE };
|
|
2841
2856
|
static getInheritedFactory = {
|
|
2842
2857
|
name: 'ɵɵgetInheritedFactory',
|
|
@@ -2868,6 +2883,7 @@ class Identifiers {
|
|
|
2868
2883
|
static InputSignalBrandWriteType = { name: 'ɵINPUT_SIGNAL_BRAND_WRITE_TYPE', moduleName: CORE };
|
|
2869
2884
|
static UnwrapDirectiveSignalInputs = { name: 'ɵUnwrapDirectiveSignalInputs', moduleName: CORE };
|
|
2870
2885
|
static unwrapWritableSignal = { name: 'ɵunwrapWritableSignal', moduleName: CORE };
|
|
2886
|
+
static assertType = { name: 'ɵassertType', moduleName: CORE };
|
|
2871
2887
|
}
|
|
2872
2888
|
|
|
2873
2889
|
const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
|
|
@@ -4411,6 +4427,7 @@ class ParsedProperty {
|
|
|
4411
4427
|
valueSpan;
|
|
4412
4428
|
isLiteral;
|
|
4413
4429
|
isLegacyAnimation;
|
|
4430
|
+
isAnimation;
|
|
4414
4431
|
constructor(name, expression, type, sourceSpan, keySpan, valueSpan) {
|
|
4415
4432
|
this.name = name;
|
|
4416
4433
|
this.expression = expression;
|
|
@@ -4420,6 +4437,7 @@ class ParsedProperty {
|
|
|
4420
4437
|
this.valueSpan = valueSpan;
|
|
4421
4438
|
this.isLiteral = this.type === ParsedPropertyType.LITERAL_ATTR;
|
|
4422
4439
|
this.isLegacyAnimation = this.type === ParsedPropertyType.LEGACY_ANIMATION;
|
|
4440
|
+
this.isAnimation = this.type === ParsedPropertyType.ANIMATION;
|
|
4423
4441
|
}
|
|
4424
4442
|
}
|
|
4425
4443
|
var ParsedPropertyType;
|
|
@@ -4428,6 +4446,7 @@ var ParsedPropertyType;
|
|
|
4428
4446
|
ParsedPropertyType[ParsedPropertyType["LITERAL_ATTR"] = 1] = "LITERAL_ATTR";
|
|
4429
4447
|
ParsedPropertyType[ParsedPropertyType["LEGACY_ANIMATION"] = 2] = "LEGACY_ANIMATION";
|
|
4430
4448
|
ParsedPropertyType[ParsedPropertyType["TWO_WAY"] = 3] = "TWO_WAY";
|
|
4449
|
+
ParsedPropertyType[ParsedPropertyType["ANIMATION"] = 4] = "ANIMATION";
|
|
4431
4450
|
})(ParsedPropertyType || (ParsedPropertyType = {}));
|
|
4432
4451
|
exports.ParsedEventType = void 0;
|
|
4433
4452
|
(function (ParsedEventType) {
|
|
@@ -4437,6 +4456,8 @@ exports.ParsedEventType = void 0;
|
|
|
4437
4456
|
ParsedEventType[ParsedEventType["LegacyAnimation"] = 1] = "LegacyAnimation";
|
|
4438
4457
|
// Event side of a two-way binding (e.g. `[(property)]="expression"`).
|
|
4439
4458
|
ParsedEventType[ParsedEventType["TwoWay"] = 2] = "TwoWay";
|
|
4459
|
+
// Animation specific event
|
|
4460
|
+
ParsedEventType[ParsedEventType["Animation"] = 3] = "Animation";
|
|
4440
4461
|
})(exports.ParsedEventType || (exports.ParsedEventType = {}));
|
|
4441
4462
|
class ParsedEvent {
|
|
4442
4463
|
name;
|
|
@@ -4487,6 +4508,8 @@ exports.BindingType = void 0;
|
|
|
4487
4508
|
BindingType[BindingType["LegacyAnimation"] = 4] = "LegacyAnimation";
|
|
4488
4509
|
// Property side of a two-way binding (e.g. `[(property)]="expression"`).
|
|
4489
4510
|
BindingType[BindingType["TwoWay"] = 5] = "TwoWay";
|
|
4511
|
+
// A binding to an animation CSS class or function (e.g. `[animate.leave]="expression"`).
|
|
4512
|
+
BindingType[BindingType["Animation"] = 6] = "Animation";
|
|
4490
4513
|
})(exports.BindingType || (exports.BindingType = {}));
|
|
4491
4514
|
class BoundElementProperty {
|
|
4492
4515
|
name;
|
|
@@ -4689,8 +4712,9 @@ let Element$1 = class Element {
|
|
|
4689
4712
|
sourceSpan;
|
|
4690
4713
|
startSourceSpan;
|
|
4691
4714
|
endSourceSpan;
|
|
4715
|
+
isVoid;
|
|
4692
4716
|
i18n;
|
|
4693
|
-
constructor(name, attributes, inputs, outputs, directives, children, references, isSelfClosing, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
|
|
4717
|
+
constructor(name, attributes, inputs, outputs, directives, children, references, isSelfClosing, sourceSpan, startSourceSpan, endSourceSpan, isVoid, i18n) {
|
|
4694
4718
|
this.name = name;
|
|
4695
4719
|
this.attributes = attributes;
|
|
4696
4720
|
this.inputs = inputs;
|
|
@@ -4702,6 +4726,7 @@ let Element$1 = class Element {
|
|
|
4702
4726
|
this.sourceSpan = sourceSpan;
|
|
4703
4727
|
this.startSourceSpan = startSourceSpan;
|
|
4704
4728
|
this.endSourceSpan = endSourceSpan;
|
|
4729
|
+
this.isVoid = isVoid;
|
|
4705
4730
|
this.i18n = i18n;
|
|
4706
4731
|
}
|
|
4707
4732
|
visit(visitor) {
|
|
@@ -8615,6 +8640,22 @@ var OpKind;
|
|
|
8615
8640
|
* Creation op that attaches the location at which an element was defined in a template to it.
|
|
8616
8641
|
*/
|
|
8617
8642
|
OpKind[OpKind["SourceLocation"] = 52] = "SourceLocation";
|
|
8643
|
+
/**
|
|
8644
|
+
* An operation to bind animation css classes to an element.
|
|
8645
|
+
*/
|
|
8646
|
+
OpKind[OpKind["Animation"] = 53] = "Animation";
|
|
8647
|
+
/**
|
|
8648
|
+
* An operation to bind animation css classes to an element.
|
|
8649
|
+
*/
|
|
8650
|
+
OpKind[OpKind["AnimationString"] = 54] = "AnimationString";
|
|
8651
|
+
/**
|
|
8652
|
+
* An operation to bind animation css classes to an element.
|
|
8653
|
+
*/
|
|
8654
|
+
OpKind[OpKind["AnimationBinding"] = 55] = "AnimationBinding";
|
|
8655
|
+
/**
|
|
8656
|
+
* An operation to bind animation events to an element.
|
|
8657
|
+
*/
|
|
8658
|
+
OpKind[OpKind["AnimationListener"] = 56] = "AnimationListener";
|
|
8618
8659
|
})(OpKind || (OpKind = {}));
|
|
8619
8660
|
/**
|
|
8620
8661
|
* Distinguishes different kinds of IR expressions.
|
|
@@ -8805,6 +8846,10 @@ var BindingKind;
|
|
|
8805
8846
|
* Property side of a two-way binding.
|
|
8806
8847
|
*/
|
|
8807
8848
|
BindingKind[BindingKind["TwoWayProperty"] = 7] = "TwoWayProperty";
|
|
8849
|
+
/**
|
|
8850
|
+
* Property side of an animation binding.
|
|
8851
|
+
*/
|
|
8852
|
+
BindingKind[BindingKind["Animation"] = 8] = "Animation";
|
|
8808
8853
|
})(BindingKind || (BindingKind = {}));
|
|
8809
8854
|
/**
|
|
8810
8855
|
* Enumeration of possible times i18n params can be resolved.
|
|
@@ -9045,13 +9090,13 @@ function createBindingOp(target, kind, name, expression, unit, securityContext,
|
|
|
9045
9090
|
/**
|
|
9046
9091
|
* Create a `PropertyOp`.
|
|
9047
9092
|
*/
|
|
9048
|
-
function createPropertyOp(target, name, expression,
|
|
9093
|
+
function createPropertyOp(target, name, expression, bindingKind, securityContext, isStructuralTemplateAttribute, templateKind, i18nContext, i18nMessage, sourceSpan) {
|
|
9049
9094
|
return {
|
|
9050
9095
|
kind: OpKind.Property,
|
|
9051
9096
|
target,
|
|
9052
9097
|
name,
|
|
9053
9098
|
expression,
|
|
9054
|
-
|
|
9099
|
+
bindingKind,
|
|
9055
9100
|
securityContext,
|
|
9056
9101
|
sanitizer: null,
|
|
9057
9102
|
isStructuralTemplateAttribute,
|
|
@@ -9202,6 +9247,24 @@ function createRepeaterOp(repeaterCreate, targetSlot, collection, sourceSpan) {
|
|
|
9202
9247
|
...TRAIT_DEPENDS_ON_SLOT_CONTEXT,
|
|
9203
9248
|
};
|
|
9204
9249
|
}
|
|
9250
|
+
/**
|
|
9251
|
+
* Create an `AnimationBindingOp`.
|
|
9252
|
+
*/
|
|
9253
|
+
function createAnimationBindingOp(name, target, animationKind, expression, securityContext, sourceSpan, animationBindingKind) {
|
|
9254
|
+
return {
|
|
9255
|
+
kind: OpKind.AnimationBinding,
|
|
9256
|
+
name,
|
|
9257
|
+
target,
|
|
9258
|
+
animationKind,
|
|
9259
|
+
expression,
|
|
9260
|
+
i18nMessage: null,
|
|
9261
|
+
securityContext,
|
|
9262
|
+
sanitizer: null,
|
|
9263
|
+
sourceSpan,
|
|
9264
|
+
animationBindingKind,
|
|
9265
|
+
...NEW_OP,
|
|
9266
|
+
};
|
|
9267
|
+
}
|
|
9205
9268
|
function createDeferWhenOp(target, expr, modifier, sourceSpan) {
|
|
9206
9269
|
return {
|
|
9207
9270
|
kind: OpKind.DeferWhen,
|
|
@@ -10032,6 +10095,8 @@ function transformExpressionsInOp(op, transform, flags) {
|
|
|
10032
10095
|
case OpKind.StyleMap:
|
|
10033
10096
|
case OpKind.ClassProp:
|
|
10034
10097
|
case OpKind.ClassMap:
|
|
10098
|
+
case OpKind.AnimationString:
|
|
10099
|
+
case OpKind.AnimationBinding:
|
|
10035
10100
|
case OpKind.Binding:
|
|
10036
10101
|
if (op.expression instanceof Interpolation) {
|
|
10037
10102
|
transformExpressionsInInterpolation(op.expression, transform, flags);
|
|
@@ -10084,6 +10149,8 @@ function transformExpressionsInOp(op, transform, flags) {
|
|
|
10084
10149
|
op.contextValue = transformExpressionsInExpression(op.contextValue, transform, flags);
|
|
10085
10150
|
}
|
|
10086
10151
|
break;
|
|
10152
|
+
case OpKind.Animation:
|
|
10153
|
+
case OpKind.AnimationListener:
|
|
10087
10154
|
case OpKind.Listener:
|
|
10088
10155
|
case OpKind.TwoWayListener:
|
|
10089
10156
|
for (const innerOp of op.handlerOps) {
|
|
@@ -10735,6 +10802,43 @@ function createTextOp(xref, initialValue, icuPlaceholder, sourceSpan) {
|
|
|
10735
10802
|
...NEW_OP,
|
|
10736
10803
|
};
|
|
10737
10804
|
}
|
|
10805
|
+
/**
|
|
10806
|
+
* Create an `AnimationOp`.
|
|
10807
|
+
*/
|
|
10808
|
+
function createAnimationStringOp(name, target, animationKind, expression, securityContext, sourceSpan) {
|
|
10809
|
+
return {
|
|
10810
|
+
kind: OpKind.AnimationString,
|
|
10811
|
+
name,
|
|
10812
|
+
target,
|
|
10813
|
+
animationKind,
|
|
10814
|
+
expression,
|
|
10815
|
+
i18nMessage: null,
|
|
10816
|
+
securityContext,
|
|
10817
|
+
sanitizer: null,
|
|
10818
|
+
sourceSpan,
|
|
10819
|
+
...NEW_OP,
|
|
10820
|
+
};
|
|
10821
|
+
}
|
|
10822
|
+
/**
|
|
10823
|
+
* Create an `AnimationOp`.
|
|
10824
|
+
*/
|
|
10825
|
+
function createAnimationOp(name, target, animationKind, callbackOps, securityContext, sourceSpan) {
|
|
10826
|
+
const handlerOps = new OpList();
|
|
10827
|
+
handlerOps.push(callbackOps);
|
|
10828
|
+
return {
|
|
10829
|
+
kind: OpKind.Animation,
|
|
10830
|
+
name,
|
|
10831
|
+
target,
|
|
10832
|
+
animationKind,
|
|
10833
|
+
handlerOps,
|
|
10834
|
+
handlerFnName: null,
|
|
10835
|
+
i18nMessage: null,
|
|
10836
|
+
securityContext,
|
|
10837
|
+
sanitizer: null,
|
|
10838
|
+
sourceSpan,
|
|
10839
|
+
...NEW_OP,
|
|
10840
|
+
};
|
|
10841
|
+
}
|
|
10738
10842
|
/**
|
|
10739
10843
|
* Create a `ListenerOp`. Host bindings reuse all the listener logic.
|
|
10740
10844
|
*/
|
|
@@ -10758,6 +10862,28 @@ function createListenerOp(target, targetSlot, name, tag, handlerOps, legacyAnima
|
|
|
10758
10862
|
...NEW_OP,
|
|
10759
10863
|
};
|
|
10760
10864
|
}
|
|
10865
|
+
/**
|
|
10866
|
+
* Create a `ListenerOp`. Host bindings reuse all the listener logic.
|
|
10867
|
+
*/
|
|
10868
|
+
function createAnimationListenerOp(target, targetSlot, name, tag, handlerOps, animationKind, eventTarget, hostListener, sourceSpan) {
|
|
10869
|
+
const handlerList = new OpList();
|
|
10870
|
+
handlerList.push(handlerOps);
|
|
10871
|
+
return {
|
|
10872
|
+
kind: OpKind.AnimationListener,
|
|
10873
|
+
target,
|
|
10874
|
+
targetSlot,
|
|
10875
|
+
tag,
|
|
10876
|
+
hostListener,
|
|
10877
|
+
name,
|
|
10878
|
+
animationKind,
|
|
10879
|
+
handlerOps: handlerList,
|
|
10880
|
+
handlerFnName: null,
|
|
10881
|
+
consumesDollarEvent: false,
|
|
10882
|
+
eventTarget,
|
|
10883
|
+
sourceSpan,
|
|
10884
|
+
...NEW_OP,
|
|
10885
|
+
};
|
|
10886
|
+
}
|
|
10761
10887
|
/**
|
|
10762
10888
|
* Create a `TwoWayListenerOp`.
|
|
10763
10889
|
*/
|
|
@@ -11007,12 +11133,12 @@ function createSourceLocationOp(templatePath, locations) {
|
|
|
11007
11133
|
};
|
|
11008
11134
|
}
|
|
11009
11135
|
|
|
11010
|
-
function createDomPropertyOp(name, expression,
|
|
11136
|
+
function createDomPropertyOp(name, expression, bindingKind, i18nContext, securityContext, sourceSpan) {
|
|
11011
11137
|
return {
|
|
11012
11138
|
kind: OpKind.DomProperty,
|
|
11013
11139
|
name,
|
|
11014
11140
|
expression,
|
|
11015
|
-
|
|
11141
|
+
bindingKind,
|
|
11016
11142
|
i18nContext,
|
|
11017
11143
|
securityContext,
|
|
11018
11144
|
sanitizer: null,
|
|
@@ -11179,7 +11305,10 @@ class CompilationUnit {
|
|
|
11179
11305
|
*ops() {
|
|
11180
11306
|
for (const op of this.create) {
|
|
11181
11307
|
yield op;
|
|
11182
|
-
if (op.kind === OpKind.Listener ||
|
|
11308
|
+
if (op.kind === OpKind.Listener ||
|
|
11309
|
+
op.kind === OpKind.Animation ||
|
|
11310
|
+
op.kind === OpKind.AnimationListener ||
|
|
11311
|
+
op.kind === OpKind.TwoWayListener) {
|
|
11183
11312
|
for (const listenerOp of op.handlerOps) {
|
|
11184
11313
|
yield listenerOp;
|
|
11185
11314
|
}
|
|
@@ -11459,7 +11588,8 @@ function extractAttributes(job) {
|
|
|
11459
11588
|
extractAttributeOp(unit, op, elements);
|
|
11460
11589
|
break;
|
|
11461
11590
|
case OpKind.Property:
|
|
11462
|
-
if (
|
|
11591
|
+
if (op.bindingKind !== BindingKind.LegacyAnimation &&
|
|
11592
|
+
op.bindingKind !== BindingKind.Animation) {
|
|
11463
11593
|
let bindingKind;
|
|
11464
11594
|
if (op.i18nMessage !== null && op.templateKind === null) {
|
|
11465
11595
|
// If the binding has an i18n context, it is an i18n attribute, and should have that
|
|
@@ -11477,14 +11607,14 @@ function extractAttributes(job) {
|
|
|
11477
11607
|
createExtractedAttributeOp(op.target, bindingKind, null, op.name,
|
|
11478
11608
|
/* expression */ null,
|
|
11479
11609
|
/* i18nContext */ null,
|
|
11480
|
-
/* i18nMessage */ null, op.securityContext), lookupElement$
|
|
11610
|
+
/* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
|
|
11481
11611
|
}
|
|
11482
11612
|
break;
|
|
11483
11613
|
case OpKind.TwoWayProperty:
|
|
11484
11614
|
OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.TwoWayProperty, null, op.name,
|
|
11485
11615
|
/* expression */ null,
|
|
11486
11616
|
/* i18nContext */ null,
|
|
11487
|
-
/* i18nMessage */ null, op.securityContext), lookupElement$
|
|
11617
|
+
/* i18nMessage */ null, op.securityContext), lookupElement$3(elements, op.target));
|
|
11488
11618
|
break;
|
|
11489
11619
|
case OpKind.StyleProp:
|
|
11490
11620
|
case OpKind.ClassProp:
|
|
@@ -11497,7 +11627,7 @@ function extractAttributes(job) {
|
|
|
11497
11627
|
OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.Property, null, op.name,
|
|
11498
11628
|
/* expression */ null,
|
|
11499
11629
|
/* i18nContext */ null,
|
|
11500
|
-
/* i18nMessage */ null, SecurityContext.STYLE), lookupElement$
|
|
11630
|
+
/* i18nMessage */ null, SecurityContext.STYLE), lookupElement$3(elements, op.target));
|
|
11501
11631
|
}
|
|
11502
11632
|
break;
|
|
11503
11633
|
case OpKind.Listener:
|
|
@@ -11517,7 +11647,7 @@ function extractAttributes(job) {
|
|
|
11517
11647
|
unit.create.push(extractedAttributeOp);
|
|
11518
11648
|
}
|
|
11519
11649
|
else {
|
|
11520
|
-
OpList.insertBefore(extractedAttributeOp, lookupElement$
|
|
11650
|
+
OpList.insertBefore(extractedAttributeOp, lookupElement$3(elements, op.target));
|
|
11521
11651
|
}
|
|
11522
11652
|
}
|
|
11523
11653
|
break;
|
|
@@ -11528,7 +11658,7 @@ function extractAttributes(job) {
|
|
|
11528
11658
|
/* expression */ null,
|
|
11529
11659
|
/* i18nContext */ null,
|
|
11530
11660
|
/* i18nMessage */ null, SecurityContext.NONE);
|
|
11531
|
-
OpList.insertBefore(extractedAttributeOp, lookupElement$
|
|
11661
|
+
OpList.insertBefore(extractedAttributeOp, lookupElement$3(elements, op.target));
|
|
11532
11662
|
}
|
|
11533
11663
|
break;
|
|
11534
11664
|
}
|
|
@@ -11538,7 +11668,7 @@ function extractAttributes(job) {
|
|
|
11538
11668
|
/**
|
|
11539
11669
|
* Looks up an element in the given map by xref ID.
|
|
11540
11670
|
*/
|
|
11541
|
-
function lookupElement$
|
|
11671
|
+
function lookupElement$3(elements, xref) {
|
|
11542
11672
|
const el = elements.get(xref);
|
|
11543
11673
|
if (el === undefined) {
|
|
11544
11674
|
throw new Error('All attributes should have an element-like target.');
|
|
@@ -11566,7 +11696,7 @@ function extractAttributeOp(unit, op, elements) {
|
|
|
11566
11696
|
unit.create.push(extractedAttributeOp);
|
|
11567
11697
|
}
|
|
11568
11698
|
else {
|
|
11569
|
-
const ownerOp = lookupElement$
|
|
11699
|
+
const ownerOp = lookupElement$3(elements, op.target);
|
|
11570
11700
|
OpList.insertBefore(extractedAttributeOp, ownerOp);
|
|
11571
11701
|
}
|
|
11572
11702
|
OpList.remove(op);
|
|
@@ -11576,7 +11706,7 @@ function extractAttributeOp(unit, op, elements) {
|
|
|
11576
11706
|
/**
|
|
11577
11707
|
* Looks up an element in the given map by xref ID.
|
|
11578
11708
|
*/
|
|
11579
|
-
function lookupElement$
|
|
11709
|
+
function lookupElement$2(elements, xref) {
|
|
11580
11710
|
const el = elements.get(xref);
|
|
11581
11711
|
if (el === undefined) {
|
|
11582
11712
|
throw new Error('All attributes should have an element-like target.');
|
|
@@ -11602,21 +11732,27 @@ function specializeBindings(job) {
|
|
|
11602
11732
|
case BindingKind.Attribute:
|
|
11603
11733
|
if (op.name === 'ngNonBindable') {
|
|
11604
11734
|
OpList.remove(op);
|
|
11605
|
-
const target = lookupElement$
|
|
11735
|
+
const target = lookupElement$2(elements, op.target);
|
|
11606
11736
|
target.nonBindable = true;
|
|
11607
11737
|
}
|
|
11738
|
+
else if (op.name.startsWith('animate.')) {
|
|
11739
|
+
OpList.replace(op, createAnimationBindingOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, op.expression, op.securityContext, op.sourceSpan, 0 /* ir.AnimationBindingKind.STRING */));
|
|
11740
|
+
}
|
|
11608
11741
|
else {
|
|
11609
11742
|
const [namespace, name] = splitNsName(op.name);
|
|
11610
11743
|
OpList.replace(op, createAttributeOp(op.target, namespace, name, op.expression, op.securityContext, op.isTextAttribute, op.isStructuralTemplateAttribute, op.templateKind, op.i18nMessage, op.sourceSpan));
|
|
11611
11744
|
}
|
|
11612
11745
|
break;
|
|
11746
|
+
case BindingKind.Animation:
|
|
11747
|
+
OpList.replace(op, createAnimationBindingOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, op.expression, op.securityContext, op.sourceSpan, 1 /* ir.AnimationBindingKind.VALUE */));
|
|
11748
|
+
break;
|
|
11613
11749
|
case BindingKind.Property:
|
|
11614
11750
|
case BindingKind.LegacyAnimation:
|
|
11615
11751
|
if (job.kind === CompilationJobKind.Host) {
|
|
11616
|
-
OpList.replace(op, createDomPropertyOp(op.name, op.expression, op.bindingKind
|
|
11752
|
+
OpList.replace(op, createDomPropertyOp(op.name, op.expression, op.bindingKind, op.i18nContext, op.securityContext, op.sourceSpan));
|
|
11617
11753
|
}
|
|
11618
11754
|
else {
|
|
11619
|
-
OpList.replace(op, createPropertyOp(op.target, op.name, op.expression, op.bindingKind
|
|
11755
|
+
OpList.replace(op, createPropertyOp(op.target, op.name, op.expression, op.bindingKind, op.securityContext, op.isStructuralTemplateAttribute, op.templateKind, op.i18nContext, op.i18nMessage, op.sourceSpan));
|
|
11620
11756
|
}
|
|
11621
11757
|
break;
|
|
11622
11758
|
case BindingKind.TwoWayProperty:
|
|
@@ -11638,6 +11774,7 @@ function specializeBindings(job) {
|
|
|
11638
11774
|
}
|
|
11639
11775
|
|
|
11640
11776
|
const CHAIN_COMPATIBILITY = new Map([
|
|
11777
|
+
[Identifiers.ariaProperty, Identifiers.ariaProperty],
|
|
11641
11778
|
[Identifiers.attribute, Identifiers.attribute],
|
|
11642
11779
|
[Identifiers.classProp, Identifiers.classProp],
|
|
11643
11780
|
[Identifiers.element, Identifiers.element],
|
|
@@ -11668,6 +11805,10 @@ const CHAIN_COMPATIBILITY = new Map([
|
|
|
11668
11805
|
[Identifiers.domElementContainerEnd, Identifiers.domElementContainerEnd],
|
|
11669
11806
|
[Identifiers.domListener, Identifiers.domListener],
|
|
11670
11807
|
[Identifiers.domTemplate, Identifiers.domTemplate],
|
|
11808
|
+
[Identifiers.animationEnter, Identifiers.animationEnter],
|
|
11809
|
+
[Identifiers.animationLeave, Identifiers.animationLeave],
|
|
11810
|
+
[Identifiers.animationEnterListener, Identifiers.animationEnterListener],
|
|
11811
|
+
[Identifiers.animationLeaveListener, Identifiers.animationLeaveListener],
|
|
11671
11812
|
]);
|
|
11672
11813
|
/**
|
|
11673
11814
|
* Chaining results in repeated call expressions, causing a deep AST of receiver expressions. To prevent running out of
|
|
@@ -12088,6 +12229,52 @@ function serializeAttributes({ attributes, bindings, classes, i18n, projectAs, s
|
|
|
12088
12229
|
return literalArr(attrArray);
|
|
12089
12230
|
}
|
|
12090
12231
|
|
|
12232
|
+
/**
|
|
12233
|
+
* Looks up an element in the given map by xref ID.
|
|
12234
|
+
*/
|
|
12235
|
+
function lookupElement$1(elements, xref) {
|
|
12236
|
+
const el = elements.get(xref);
|
|
12237
|
+
if (el === undefined) {
|
|
12238
|
+
throw new Error('All attributes should have an element-like target.');
|
|
12239
|
+
}
|
|
12240
|
+
return el;
|
|
12241
|
+
}
|
|
12242
|
+
function convertAnimations(job) {
|
|
12243
|
+
const elements = new Map();
|
|
12244
|
+
for (const unit of job.units) {
|
|
12245
|
+
for (const op of unit.create) {
|
|
12246
|
+
if (!isElementOrContainerOp(op)) {
|
|
12247
|
+
continue;
|
|
12248
|
+
}
|
|
12249
|
+
elements.set(op.xref, op);
|
|
12250
|
+
}
|
|
12251
|
+
}
|
|
12252
|
+
for (const unit of job.units) {
|
|
12253
|
+
for (const op of unit.ops()) {
|
|
12254
|
+
if (op.kind === OpKind.AnimationBinding) {
|
|
12255
|
+
const createAnimationOp = getAnimationOp(op);
|
|
12256
|
+
if (job.kind === CompilationJobKind.Host) {
|
|
12257
|
+
unit.create.push(createAnimationOp);
|
|
12258
|
+
}
|
|
12259
|
+
else {
|
|
12260
|
+
OpList.insertAfter(createAnimationOp, lookupElement$1(elements, op.target));
|
|
12261
|
+
}
|
|
12262
|
+
OpList.remove(op);
|
|
12263
|
+
}
|
|
12264
|
+
}
|
|
12265
|
+
}
|
|
12266
|
+
}
|
|
12267
|
+
function getAnimationOp(op) {
|
|
12268
|
+
if (op.animationBindingKind === 0 /* ir.AnimationBindingKind.STRING */) {
|
|
12269
|
+
// this is a simple string case
|
|
12270
|
+
return createAnimationStringOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, op.expression, op.securityContext, op.sourceSpan);
|
|
12271
|
+
}
|
|
12272
|
+
else {
|
|
12273
|
+
const expression = op.expression;
|
|
12274
|
+
return createAnimationOp(op.name, op.target, op.name === 'animate.enter' ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, [createStatementOp(new ReturnStatement(expression, expression.sourceSpan))], op.securityContext, op.sourceSpan);
|
|
12275
|
+
}
|
|
12276
|
+
}
|
|
12277
|
+
|
|
12091
12278
|
/**
|
|
12092
12279
|
* Some binding instructions in the update block may actually correspond to i18n bindings. In that
|
|
12093
12280
|
* case, they should be replaced with i18nExp instructions for the dynamic portions.
|
|
@@ -12985,6 +13172,8 @@ function recursivelyProcessView(view, parentScope) {
|
|
|
12985
13172
|
op.trackByOps.prepend(generateVariablesInScopeForView(view, scope, false));
|
|
12986
13173
|
}
|
|
12987
13174
|
break;
|
|
13175
|
+
case OpKind.Animation:
|
|
13176
|
+
case OpKind.AnimationListener:
|
|
12988
13177
|
case OpKind.Listener:
|
|
12989
13178
|
case OpKind.TwoWayListener:
|
|
12990
13179
|
// Prepend variables to listener handler functions.
|
|
@@ -13067,7 +13256,7 @@ function getScopeForView(view, parent) {
|
|
|
13067
13256
|
* This is a recursive process, as views inherit variables available from their parent view, which
|
|
13068
13257
|
* itself may have inherited variables, etc.
|
|
13069
13258
|
*/
|
|
13070
|
-
function generateVariablesInScopeForView(view, scope,
|
|
13259
|
+
function generateVariablesInScopeForView(view, scope, isCallback) {
|
|
13071
13260
|
const newOps = [];
|
|
13072
13261
|
if (scope.view !== view.xref) {
|
|
13073
13262
|
// Before generating variables for a parent view, we need to switch to the context of the parent
|
|
@@ -13091,7 +13280,7 @@ function generateVariablesInScopeForView(view, scope, isListener) {
|
|
|
13091
13280
|
for (const ref of scope.references) {
|
|
13092
13281
|
newOps.push(createVariableOp(view.job.allocateXrefId(), ref.variable, new ReferenceExpr(ref.targetId, ref.targetSlot, ref.offset), VariableFlags.None));
|
|
13093
13282
|
}
|
|
13094
|
-
if (scope.view !== view.xref ||
|
|
13283
|
+
if (scope.view !== view.xref || isCallback) {
|
|
13095
13284
|
for (const decl of scope.letDeclarations) {
|
|
13096
13285
|
newOps.push(createVariableOp(view.job.allocateXrefId(), decl.variable, new ContextLetReferenceExpr(decl.targetId, decl.targetSlot), VariableFlags.None));
|
|
13097
13286
|
}
|
|
@@ -13321,7 +13510,8 @@ class Element extends NodeWithI18n {
|
|
|
13321
13510
|
isSelfClosing;
|
|
13322
13511
|
startSourceSpan;
|
|
13323
13512
|
endSourceSpan;
|
|
13324
|
-
|
|
13513
|
+
isVoid;
|
|
13514
|
+
constructor(name, attrs, directives, children, isSelfClosing, sourceSpan, startSourceSpan, endSourceSpan = null, isVoid, i18n) {
|
|
13325
13515
|
super(sourceSpan, i18n);
|
|
13326
13516
|
this.name = name;
|
|
13327
13517
|
this.attrs = attrs;
|
|
@@ -13330,6 +13520,7 @@ class Element extends NodeWithI18n {
|
|
|
13330
13520
|
this.isSelfClosing = isSelfClosing;
|
|
13331
13521
|
this.startSourceSpan = startSourceSpan;
|
|
13332
13522
|
this.endSourceSpan = endSourceSpan;
|
|
13523
|
+
this.isVoid = isVoid;
|
|
13333
13524
|
}
|
|
13334
13525
|
visit(visitor, context) {
|
|
13335
13526
|
return visitor.visitElement(this, context);
|
|
@@ -15667,6 +15858,19 @@ var CharacterReferenceType;
|
|
|
15667
15858
|
CharacterReferenceType["HEX"] = "hexadecimal";
|
|
15668
15859
|
CharacterReferenceType["DEC"] = "decimal";
|
|
15669
15860
|
})(CharacterReferenceType || (CharacterReferenceType = {}));
|
|
15861
|
+
const SUPPORTED_BLOCKS = [
|
|
15862
|
+
'@if',
|
|
15863
|
+
'@else', // Covers `@else if` as well
|
|
15864
|
+
'@for',
|
|
15865
|
+
'@switch',
|
|
15866
|
+
'@case',
|
|
15867
|
+
'@default',
|
|
15868
|
+
'@empty',
|
|
15869
|
+
'@defer',
|
|
15870
|
+
'@placeholder',
|
|
15871
|
+
'@loading',
|
|
15872
|
+
'@error',
|
|
15873
|
+
];
|
|
15670
15874
|
// See https://www.w3.org/TR/html51/syntax.html#writing-html-documents
|
|
15671
15875
|
class _Tokenizer {
|
|
15672
15876
|
_getTagDefinition;
|
|
@@ -15757,10 +15961,10 @@ class _Tokenizer {
|
|
|
15757
15961
|
// don't want to advance in case it's not `@let`.
|
|
15758
15962
|
this._cursor.peek() === $AT &&
|
|
15759
15963
|
!this._inInterpolation &&
|
|
15760
|
-
this.
|
|
15964
|
+
this._isLetStart()) {
|
|
15761
15965
|
this._consumeLetDeclaration(start);
|
|
15762
15966
|
}
|
|
15763
|
-
else if (this._tokenizeBlocks && this.
|
|
15967
|
+
else if (this._tokenizeBlocks && this._isBlockStart()) {
|
|
15764
15968
|
this._consumeBlockStart(start);
|
|
15765
15969
|
}
|
|
15766
15970
|
else if (this._tokenizeBlocks &&
|
|
@@ -15800,6 +16004,7 @@ class _Tokenizer {
|
|
|
15800
16004
|
return this._cursor.getChars(nameCursor).trim();
|
|
15801
16005
|
}
|
|
15802
16006
|
_consumeBlockStart(start) {
|
|
16007
|
+
this._requireCharCode($AT);
|
|
15803
16008
|
this._beginToken(24 /* TokenType.BLOCK_OPEN_START */, start);
|
|
15804
16009
|
const startToken = this._endToken([this._getBlockName()]);
|
|
15805
16010
|
if (this._cursor.peek() === $LPAREN) {
|
|
@@ -15872,6 +16077,7 @@ class _Tokenizer {
|
|
|
15872
16077
|
}
|
|
15873
16078
|
}
|
|
15874
16079
|
_consumeLetDeclaration(start) {
|
|
16080
|
+
this._requireStr('@let');
|
|
15875
16081
|
this._beginToken(29 /* TokenType.LET_START */, start);
|
|
15876
16082
|
// Require at least one white space after the `@let`.
|
|
15877
16083
|
if (isWhitespace(this._cursor.peek())) {
|
|
@@ -16085,6 +16291,27 @@ class _Tokenizer {
|
|
|
16085
16291
|
this._cursor.advance();
|
|
16086
16292
|
return char;
|
|
16087
16293
|
}
|
|
16294
|
+
_peekStr(chars) {
|
|
16295
|
+
const len = chars.length;
|
|
16296
|
+
if (this._cursor.charsLeft() < len) {
|
|
16297
|
+
return false;
|
|
16298
|
+
}
|
|
16299
|
+
const cursor = this._cursor.clone();
|
|
16300
|
+
for (let i = 0; i < len; i++) {
|
|
16301
|
+
if (cursor.peek() !== chars.charCodeAt(i)) {
|
|
16302
|
+
return false;
|
|
16303
|
+
}
|
|
16304
|
+
cursor.advance();
|
|
16305
|
+
}
|
|
16306
|
+
return true;
|
|
16307
|
+
}
|
|
16308
|
+
_isBlockStart() {
|
|
16309
|
+
return (this._cursor.peek() === $AT &&
|
|
16310
|
+
SUPPORTED_BLOCKS.some((blockName) => this._peekStr(blockName)));
|
|
16311
|
+
}
|
|
16312
|
+
_isLetStart() {
|
|
16313
|
+
return this._cursor.peek() === $AT && this._peekStr('@let');
|
|
16314
|
+
}
|
|
16088
16315
|
_consumeEntity(textTokenType) {
|
|
16089
16316
|
this._beginToken(9 /* TokenType.ENCODED_ENTITY */);
|
|
16090
16317
|
const start = this._cursor.clone();
|
|
@@ -16352,6 +16579,23 @@ class _Tokenizer {
|
|
|
16352
16579
|
return isNameEnd(code);
|
|
16353
16580
|
};
|
|
16354
16581
|
}
|
|
16582
|
+
else if (attrNameStart === $LBRACKET) {
|
|
16583
|
+
let openBrackets = 0;
|
|
16584
|
+
// Be more permissive for which characters are allowed inside square-bracketed attributes,
|
|
16585
|
+
// because they usually end up being bound as attribute values. Some third-party packages
|
|
16586
|
+
// like Tailwind take advantage of this.
|
|
16587
|
+
nameEndPredicate = (code) => {
|
|
16588
|
+
if (code === $LBRACKET) {
|
|
16589
|
+
openBrackets++;
|
|
16590
|
+
}
|
|
16591
|
+
else if (code === $RBRACKET) {
|
|
16592
|
+
openBrackets--;
|
|
16593
|
+
}
|
|
16594
|
+
// Only check for name-ending characters if the brackets are balanced or mismatched.
|
|
16595
|
+
// Also interrupt the matching on new lines.
|
|
16596
|
+
return openBrackets <= 0 ? isNameEnd(code) : isNewLine(code);
|
|
16597
|
+
};
|
|
16598
|
+
}
|
|
16355
16599
|
else {
|
|
16356
16600
|
nameEndPredicate = isNameEnd;
|
|
16357
16601
|
}
|
|
@@ -16631,7 +16875,7 @@ class _Tokenizer {
|
|
|
16631
16875
|
if (this._tokenizeBlocks &&
|
|
16632
16876
|
!this._inInterpolation &&
|
|
16633
16877
|
!this._isInExpansion() &&
|
|
16634
|
-
(this.
|
|
16878
|
+
(this._isBlockStart() || this._isLetStart() || this._cursor.peek() === $RBRACE)) {
|
|
16635
16879
|
return true;
|
|
16636
16880
|
}
|
|
16637
16881
|
return false;
|
|
@@ -17268,13 +17512,13 @@ class _TreeBuilder {
|
|
|
17268
17512
|
const directives = [];
|
|
17269
17513
|
this._consumeAttributesAndDirectives(attrs, directives);
|
|
17270
17514
|
const fullName = this._getElementFullName(startTagToken, this._getClosestElementLikeParent());
|
|
17515
|
+
const tagDef = this._getTagDefinition(fullName);
|
|
17271
17516
|
let selfClosing = false;
|
|
17272
17517
|
// Note: There could have been a tokenizer error
|
|
17273
17518
|
// so that we don't get a token for the end tag...
|
|
17274
17519
|
if (this._peek.type === 2 /* TokenType.TAG_OPEN_END_VOID */) {
|
|
17275
17520
|
this._advance();
|
|
17276
17521
|
selfClosing = true;
|
|
17277
|
-
const tagDef = this._getTagDefinition(fullName);
|
|
17278
17522
|
if (!(tagDef?.canSelfClose || getNsPrefix(fullName) !== null || tagDef?.isVoid)) {
|
|
17279
17523
|
this.errors.push(TreeError.create(fullName, startTagToken.sourceSpan, `Only void, custom and foreign elements can be self closed "${startTagToken.parts[1]}"`));
|
|
17280
17524
|
}
|
|
@@ -17287,7 +17531,7 @@ class _TreeBuilder {
|
|
|
17287
17531
|
const span = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
|
|
17288
17532
|
// Create a separate `startSpan` because `span` will be modified when there is an `end` span.
|
|
17289
17533
|
const startSpan = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
|
|
17290
|
-
const el = new Element(fullName, attrs, directives, [], selfClosing, span, startSpan, undefined);
|
|
17534
|
+
const el = new Element(fullName, attrs, directives, [], selfClosing, span, startSpan, undefined, tagDef?.isVoid ?? false);
|
|
17291
17535
|
const parent = this._getContainer();
|
|
17292
17536
|
const isClosedByChild = parent !== null && !!this._getTagDefinition(parent)?.isClosedByChild(el.name);
|
|
17293
17537
|
this._pushContainer(el, isClosedByChild);
|
|
@@ -17730,11 +17974,11 @@ class WhitespaceVisitor {
|
|
|
17730
17974
|
if (SKIP_WS_TRIM_TAGS.has(element.name) || hasPreserveWhitespacesAttr(element.attrs)) {
|
|
17731
17975
|
// don't descent into elements where we need to preserve whitespaces
|
|
17732
17976
|
// but still visit all attributes to eliminate one used as a market to preserve WS
|
|
17733
|
-
const newElement = new Element(element.name, visitAllWithSiblings(this, element.attrs), visitAllWithSiblings(this, element.directives), element.children, element.isSelfClosing, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
|
|
17977
|
+
const newElement = new Element(element.name, visitAllWithSiblings(this, element.attrs), visitAllWithSiblings(this, element.directives), element.children, element.isSelfClosing, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.isVoid, element.i18n);
|
|
17734
17978
|
this.originalNodeMap?.set(newElement, element);
|
|
17735
17979
|
return newElement;
|
|
17736
17980
|
}
|
|
17737
|
-
const newElement = new Element(element.name, element.attrs, element.directives, visitAllWithSiblings(this, element.children), element.isSelfClosing, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
|
|
17981
|
+
const newElement = new Element(element.name, element.attrs, element.directives, visitAllWithSiblings(this, element.children), element.isSelfClosing, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.isVoid, element.i18n);
|
|
17738
17982
|
this.originalNodeMap?.set(newElement, element);
|
|
17739
17983
|
return newElement;
|
|
17740
17984
|
}
|
|
@@ -19381,12 +19625,13 @@ class _ParseAST {
|
|
|
19381
19625
|
else {
|
|
19382
19626
|
if (this.isAssignmentOperator(this.next)) {
|
|
19383
19627
|
const operation = this.next.strValue;
|
|
19384
|
-
this.advance();
|
|
19385
19628
|
if (!(this.parseFlags & 1 /* ParseFlags.Action */)) {
|
|
19629
|
+
this.advance();
|
|
19386
19630
|
this.error('Bindings cannot contain assignments');
|
|
19387
19631
|
return new EmptyExpr$1(this.span(start), this.sourceSpan(start));
|
|
19388
19632
|
}
|
|
19389
19633
|
const receiver = new PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
|
|
19634
|
+
this.advance();
|
|
19390
19635
|
const value = this.parseConditional();
|
|
19391
19636
|
return new Binary(this.span(start), this.sourceSpan(start), operation, receiver, value);
|
|
19392
19637
|
}
|
|
@@ -19505,12 +19750,13 @@ class _ParseAST {
|
|
|
19505
19750
|
this.expectCharacter($RBRACKET);
|
|
19506
19751
|
if (this.isAssignmentOperator(this.next)) {
|
|
19507
19752
|
const operation = this.next.strValue;
|
|
19508
|
-
this.advance();
|
|
19509
19753
|
if (isSafe) {
|
|
19754
|
+
this.advance();
|
|
19510
19755
|
this.error("The '?.' operator cannot be used in the assignment");
|
|
19511
19756
|
}
|
|
19512
19757
|
else {
|
|
19513
19758
|
const binaryReceiver = new KeyedRead(this.span(start), this.sourceSpan(start), receiver, key);
|
|
19759
|
+
this.advance();
|
|
19514
19760
|
const value = this.parseConditional();
|
|
19515
19761
|
return new Binary(this.span(start), this.sourceSpan(start), operation, binaryReceiver, value);
|
|
19516
19762
|
}
|
|
@@ -20273,6 +20519,44 @@ const _ATTR_TO_PROP = new Map(Object.entries({
|
|
|
20273
20519
|
'innerHtml': 'innerHTML',
|
|
20274
20520
|
'readonly': 'readOnly',
|
|
20275
20521
|
'tabindex': 'tabIndex',
|
|
20522
|
+
// https://www.w3.org/TR/wai-aria-1.2/#accessibilityroleandproperties-correspondence
|
|
20523
|
+
'aria-atomic': 'ariaAtomic',
|
|
20524
|
+
'aria-autocomplete': 'ariaAutoComplete',
|
|
20525
|
+
'aria-busy': 'ariaBusy',
|
|
20526
|
+
'aria-checked': 'ariaChecked',
|
|
20527
|
+
'aria-colcount': 'ariaColCount',
|
|
20528
|
+
'aria-colindex': 'ariaColIndex',
|
|
20529
|
+
'aria-colspan': 'ariaColSpan',
|
|
20530
|
+
'aria-current': 'ariaCurrent',
|
|
20531
|
+
'aria-disabled': 'ariaDisabled',
|
|
20532
|
+
'aria-expanded': 'ariaExpanded',
|
|
20533
|
+
'aria-haspopup': 'ariaHasPopup',
|
|
20534
|
+
'aria-hidden': 'ariaHidden',
|
|
20535
|
+
'aria-invalid': 'ariaInvalid',
|
|
20536
|
+
'aria-keyshortcuts': 'ariaKeyShortcuts',
|
|
20537
|
+
'aria-label': 'ariaLabel',
|
|
20538
|
+
'aria-level': 'ariaLevel',
|
|
20539
|
+
'aria-live': 'ariaLive',
|
|
20540
|
+
'aria-modal': 'ariaModal',
|
|
20541
|
+
'aria-multiline': 'ariaMultiLine',
|
|
20542
|
+
'aria-multiselectable': 'ariaMultiSelectable',
|
|
20543
|
+
'aria-orientation': 'ariaOrientation',
|
|
20544
|
+
'aria-placeholder': 'ariaPlaceholder',
|
|
20545
|
+
'aria-posinset': 'ariaPosInSet',
|
|
20546
|
+
'aria-pressed': 'ariaPressed',
|
|
20547
|
+
'aria-readonly': 'ariaReadOnly',
|
|
20548
|
+
'aria-required': 'ariaRequired',
|
|
20549
|
+
'aria-roledescription': 'ariaRoleDescription',
|
|
20550
|
+
'aria-rowcount': 'ariaRowCount',
|
|
20551
|
+
'aria-rowindex': 'ariaRowIndex',
|
|
20552
|
+
'aria-rowspan': 'ariaRowSpan',
|
|
20553
|
+
'aria-selected': 'ariaSelected',
|
|
20554
|
+
'aria-setsize': 'ariaSetSize',
|
|
20555
|
+
'aria-sort': 'ariaSort',
|
|
20556
|
+
'aria-valuemax': 'ariaValueMax',
|
|
20557
|
+
'aria-valuemin': 'ariaValueMin',
|
|
20558
|
+
'aria-valuenow': 'ariaValueNow',
|
|
20559
|
+
'aria-valuetext': 'ariaValueText',
|
|
20276
20560
|
}));
|
|
20277
20561
|
// Invert _ATTR_TO_PROP.
|
|
20278
20562
|
const _PROP_TO_ATTR = Array.from(_ATTR_TO_PROP).reduce((inverted, [propertyName, attributeName]) => {
|
|
@@ -22219,10 +22503,33 @@ function addNamesToView(unit, baseName, state, compatibility) {
|
|
|
22219
22503
|
switch (op.kind) {
|
|
22220
22504
|
case OpKind.Property:
|
|
22221
22505
|
case OpKind.DomProperty:
|
|
22222
|
-
if (op.
|
|
22506
|
+
if (op.bindingKind === BindingKind.LegacyAnimation) {
|
|
22223
22507
|
op.name = '@' + op.name;
|
|
22224
22508
|
}
|
|
22225
22509
|
break;
|
|
22510
|
+
case OpKind.Animation:
|
|
22511
|
+
if (op.handlerFnName === null) {
|
|
22512
|
+
const animationKind = op.name.replace('.', '');
|
|
22513
|
+
op.handlerFnName = `${unit.fnName}_${animationKind}_cb`;
|
|
22514
|
+
op.handlerFnName = sanitizeIdentifier(op.handlerFnName);
|
|
22515
|
+
}
|
|
22516
|
+
break;
|
|
22517
|
+
case OpKind.AnimationListener:
|
|
22518
|
+
if (op.handlerFnName !== null) {
|
|
22519
|
+
break;
|
|
22520
|
+
}
|
|
22521
|
+
if (!op.hostListener && op.targetSlot.slot === null) {
|
|
22522
|
+
throw new Error(`Expected a slot to be assigned`);
|
|
22523
|
+
}
|
|
22524
|
+
const animationKind = op.name.replace('.', '');
|
|
22525
|
+
if (op.hostListener) {
|
|
22526
|
+
op.handlerFnName = `${baseName}_${animationKind}_HostBindingHandler`;
|
|
22527
|
+
}
|
|
22528
|
+
else {
|
|
22529
|
+
op.handlerFnName = `${unit.fnName}_${op.tag.replace('-', '_')}_${animationKind}_${op.targetSlot.slot}_listener`;
|
|
22530
|
+
}
|
|
22531
|
+
op.handlerFnName = sanitizeIdentifier(op.handlerFnName);
|
|
22532
|
+
break;
|
|
22226
22533
|
case OpKind.Listener:
|
|
22227
22534
|
if (op.handlerFnName !== null) {
|
|
22228
22535
|
break;
|
|
@@ -22380,7 +22687,10 @@ function stripImportant(name) {
|
|
|
22380
22687
|
function mergeNextContextExpressions(job) {
|
|
22381
22688
|
for (const unit of job.units) {
|
|
22382
22689
|
for (const op of unit.create) {
|
|
22383
|
-
if (op.kind === OpKind.Listener ||
|
|
22690
|
+
if (op.kind === OpKind.Listener ||
|
|
22691
|
+
op.kind === OpKind.Animation ||
|
|
22692
|
+
op.kind === OpKind.AnimationListener ||
|
|
22693
|
+
op.kind === OpKind.TwoWayListener) {
|
|
22384
22694
|
mergeNextContextsInOps(op.handlerOps);
|
|
22385
22695
|
}
|
|
22386
22696
|
}
|
|
@@ -22501,7 +22811,9 @@ function kindWithInterpolationTest(kind, interpolation) {
|
|
|
22501
22811
|
}
|
|
22502
22812
|
function basicListenerKindTest(op) {
|
|
22503
22813
|
return ((op.kind === OpKind.Listener && !(op.hostListener && op.isLegacyAnimationListener)) ||
|
|
22504
|
-
op.kind === OpKind.TwoWayListener
|
|
22814
|
+
op.kind === OpKind.TwoWayListener ||
|
|
22815
|
+
op.kind === OpKind.Animation ||
|
|
22816
|
+
op.kind === OpKind.AnimationListener);
|
|
22505
22817
|
}
|
|
22506
22818
|
function nonInterpolationPropertyKindTest(op) {
|
|
22507
22819
|
return ((op.kind === OpKind.Property || op.kind === OpKind.TwoWayProperty) &&
|
|
@@ -22548,6 +22860,7 @@ const UPDATE_HOST_ORDERING = [
|
|
|
22548
22860
|
const handledOpKinds = new Set([
|
|
22549
22861
|
OpKind.Listener,
|
|
22550
22862
|
OpKind.TwoWayListener,
|
|
22863
|
+
OpKind.AnimationListener,
|
|
22551
22864
|
OpKind.StyleMap,
|
|
22552
22865
|
OpKind.ClassMap,
|
|
22553
22866
|
OpKind.StyleProp,
|
|
@@ -22556,6 +22869,7 @@ const handledOpKinds = new Set([
|
|
|
22556
22869
|
OpKind.TwoWayProperty,
|
|
22557
22870
|
OpKind.DomProperty,
|
|
22558
22871
|
OpKind.Attribute,
|
|
22872
|
+
OpKind.Animation,
|
|
22559
22873
|
]);
|
|
22560
22874
|
/**
|
|
22561
22875
|
* Many type of operations have ordering constraints that must be respected. For example, a
|
|
@@ -23246,6 +23560,9 @@ function i18nAttributes(slot, i18nAttributesConfig) {
|
|
|
23246
23560
|
const args = [literal(slot), literal(i18nAttributesConfig)];
|
|
23247
23561
|
return call(Identifiers.i18nAttributes, args, null);
|
|
23248
23562
|
}
|
|
23563
|
+
function ariaProperty(name, expression, sourceSpan) {
|
|
23564
|
+
return propertyBase(Identifiers.ariaProperty, name, expression, null, sourceSpan);
|
|
23565
|
+
}
|
|
23249
23566
|
function property(name, expression, sanitizer, sourceSpan) {
|
|
23250
23567
|
return propertyBase(Identifiers.property, name, expression, sanitizer, sourceSpan);
|
|
23251
23568
|
}
|
|
@@ -23359,6 +23676,36 @@ function i18nApply(slot, sourceSpan) {
|
|
|
23359
23676
|
function domProperty(name, expression, sanitizer, sourceSpan) {
|
|
23360
23677
|
return propertyBase(Identifiers.domProperty, name, expression, sanitizer, sourceSpan);
|
|
23361
23678
|
}
|
|
23679
|
+
function animation(animationKind, handlerFn, sanitizer, sourceSpan) {
|
|
23680
|
+
const args = [handlerFn];
|
|
23681
|
+
if (sanitizer !== null) {
|
|
23682
|
+
args.push(sanitizer);
|
|
23683
|
+
}
|
|
23684
|
+
const identifier = animationKind === "enter" /* ir.AnimationKind.ENTER */
|
|
23685
|
+
? Identifiers.animationEnter
|
|
23686
|
+
: Identifiers.animationLeave;
|
|
23687
|
+
return call(identifier, args, sourceSpan);
|
|
23688
|
+
}
|
|
23689
|
+
function animationString(animationKind, expression, sanitizer, sourceSpan) {
|
|
23690
|
+
const value = expression instanceof Interpolation
|
|
23691
|
+
? interpolationToExpression(expression, sourceSpan)
|
|
23692
|
+
: expression;
|
|
23693
|
+
const args = [value];
|
|
23694
|
+
if (sanitizer !== null) {
|
|
23695
|
+
args.push(sanitizer);
|
|
23696
|
+
}
|
|
23697
|
+
const identifier = animationKind === "enter" /* ir.AnimationKind.ENTER */
|
|
23698
|
+
? Identifiers.animationEnter
|
|
23699
|
+
: Identifiers.animationLeave;
|
|
23700
|
+
return call(identifier, args, sourceSpan);
|
|
23701
|
+
}
|
|
23702
|
+
function animationListener(animationKind, handlerFn, eventTargetResolver, sourceSpan) {
|
|
23703
|
+
const args = [handlerFn];
|
|
23704
|
+
const identifier = animationKind === "enter" /* ir.AnimationKind.ENTER */
|
|
23705
|
+
? Identifiers.animationEnterListener
|
|
23706
|
+
: Identifiers.animationLeaveListener;
|
|
23707
|
+
return call(identifier, args, sourceSpan);
|
|
23708
|
+
}
|
|
23362
23709
|
function syntheticHostProperty(name, expression, sourceSpan) {
|
|
23363
23710
|
return call(Identifiers.syntheticHostProperty, [literal(name), expression], sourceSpan);
|
|
23364
23711
|
}
|
|
@@ -23492,6 +23839,7 @@ function callVariadicInstruction(config, baseArgs, interpolationArgs, extraArgs,
|
|
|
23492
23839
|
return createStatementOp(callVariadicInstructionExpr(config, baseArgs, interpolationArgs, extraArgs, sourceSpan).toStmt());
|
|
23493
23840
|
}
|
|
23494
23841
|
|
|
23842
|
+
const ARIA_PREFIX = 'aria';
|
|
23495
23843
|
/**
|
|
23496
23844
|
* Map of target resolvers for event listeners.
|
|
23497
23845
|
*/
|
|
@@ -23605,6 +23953,18 @@ function reifyCreateOperations(unit, ops) {
|
|
|
23605
23953
|
case OpKind.DeclareLet:
|
|
23606
23954
|
OpList.replace(op, declareLet(op.handle.slot, op.sourceSpan));
|
|
23607
23955
|
break;
|
|
23956
|
+
case OpKind.AnimationString:
|
|
23957
|
+
OpList.replace(op, animationString(op.animationKind, op.expression, op.sanitizer, op.sourceSpan));
|
|
23958
|
+
break;
|
|
23959
|
+
case OpKind.Animation:
|
|
23960
|
+
const animationCallbackFn = reifyListenerHandler(unit, op.handlerFnName, op.handlerOps,
|
|
23961
|
+
/* consumesDollarEvent */ false);
|
|
23962
|
+
OpList.replace(op, animation(op.animationKind, animationCallbackFn, op.sanitizer, op.sourceSpan));
|
|
23963
|
+
break;
|
|
23964
|
+
case OpKind.AnimationListener:
|
|
23965
|
+
const animationListenerFn = reifyListenerHandler(unit, op.handlerFnName, op.handlerOps, op.consumesDollarEvent);
|
|
23966
|
+
OpList.replace(op, animationListener(op.animationKind, animationListenerFn, null, op.sourceSpan));
|
|
23967
|
+
break;
|
|
23608
23968
|
case OpKind.Listener:
|
|
23609
23969
|
const listenerFn = reifyListenerHandler(unit, op.handlerFnName, op.handlerOps, op.consumesDollarEvent);
|
|
23610
23970
|
const eventTargetResolver = op.eventTarget
|
|
@@ -23783,9 +24143,11 @@ function reifyUpdateOperations(unit, ops) {
|
|
|
23783
24143
|
OpList.replace(op, advance(op.delta, op.sourceSpan));
|
|
23784
24144
|
break;
|
|
23785
24145
|
case OpKind.Property:
|
|
23786
|
-
OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly &&
|
|
23787
|
-
|
|
23788
|
-
|
|
24146
|
+
OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly &&
|
|
24147
|
+
op.bindingKind !== BindingKind.LegacyAnimation &&
|
|
24148
|
+
op.bindingKind !== BindingKind.Animation
|
|
24149
|
+
? reifyDomProperty(op)
|
|
24150
|
+
: reifyProperty(op));
|
|
23789
24151
|
break;
|
|
23790
24152
|
case OpKind.TwoWayProperty:
|
|
23791
24153
|
OpList.replace(op, twoWayProperty(op.name, op.expression, op.sanitizer, op.sourceSpan));
|
|
@@ -23819,11 +24181,12 @@ function reifyUpdateOperations(unit, ops) {
|
|
|
23819
24181
|
throw new Error('not yet handled');
|
|
23820
24182
|
}
|
|
23821
24183
|
else {
|
|
23822
|
-
if (op.
|
|
24184
|
+
if (op.bindingKind === BindingKind.LegacyAnimation ||
|
|
24185
|
+
op.bindingKind === BindingKind.Animation) {
|
|
23823
24186
|
OpList.replace(op, syntheticHostProperty(op.name, op.expression, op.sourceSpan));
|
|
23824
24187
|
}
|
|
23825
24188
|
else {
|
|
23826
|
-
OpList.replace(op,
|
|
24189
|
+
OpList.replace(op, reifyDomProperty(op));
|
|
23827
24190
|
}
|
|
23828
24191
|
}
|
|
23829
24192
|
break;
|
|
@@ -23855,6 +24218,61 @@ function reifyUpdateOperations(unit, ops) {
|
|
|
23855
24218
|
}
|
|
23856
24219
|
}
|
|
23857
24220
|
}
|
|
24221
|
+
/**
|
|
24222
|
+
* Converts an ARIA property name to its corresponding attribute name, if necessary.
|
|
24223
|
+
*
|
|
24224
|
+
* For example, converts `ariaLabel` to `aria-label`.
|
|
24225
|
+
*
|
|
24226
|
+
* https://www.w3.org/TR/wai-aria-1.2/#accessibilityroleandproperties-correspondence
|
|
24227
|
+
*
|
|
24228
|
+
* This must be kept in sync with the the function of the same name in
|
|
24229
|
+
* packages/core/src/render3/instructions/aria_property.ts.
|
|
24230
|
+
*
|
|
24231
|
+
* @param name A property name that starts with `aria`.
|
|
24232
|
+
* @returns The corresponding attribute name.
|
|
24233
|
+
*/
|
|
24234
|
+
function ariaAttrName(name) {
|
|
24235
|
+
return name.charAt(ARIA_PREFIX.length) !== '-'
|
|
24236
|
+
? ARIA_PREFIX + '-' + name.slice(ARIA_PREFIX.length).toLowerCase()
|
|
24237
|
+
: name; // Property already has attribute name.
|
|
24238
|
+
}
|
|
24239
|
+
/**
|
|
24240
|
+
* Returns whether `name` is an ARIA property (or attribute) name.
|
|
24241
|
+
*
|
|
24242
|
+
* This is a heuristic based on whether name begins with and is longer than `aria`. For example,
|
|
24243
|
+
* this returns true for both `ariaLabel` and `aria-label`.
|
|
24244
|
+
*/
|
|
24245
|
+
function isAriaProperty(name) {
|
|
24246
|
+
return name.startsWith(ARIA_PREFIX) && name.length > ARIA_PREFIX.length;
|
|
24247
|
+
}
|
|
24248
|
+
/**
|
|
24249
|
+
* Reifies a DOM property binding operation.
|
|
24250
|
+
*
|
|
24251
|
+
* This is an optimized version of {@link reifyProperty} that avoids unnecessarily trying to bind
|
|
24252
|
+
* to directive inputs at runtime for views that don't import any directives.
|
|
24253
|
+
*
|
|
24254
|
+
* @param op A property binding operation.
|
|
24255
|
+
* @returns A statement to update the property at runtime.
|
|
24256
|
+
*/
|
|
24257
|
+
function reifyDomProperty(op) {
|
|
24258
|
+
return isAriaProperty(op.name)
|
|
24259
|
+
? attribute(ariaAttrName(op.name), op.expression, null, null, op.sourceSpan)
|
|
24260
|
+
: domProperty(DOM_PROPERTY_REMAPPING.get(op.name) ?? op.name, op.expression, op.sanitizer, op.sourceSpan);
|
|
24261
|
+
}
|
|
24262
|
+
/**
|
|
24263
|
+
* Reifies a property binding operation.
|
|
24264
|
+
*
|
|
24265
|
+
* The returned statement attempts to bind to directive inputs before falling back to a DOM
|
|
24266
|
+
* property.
|
|
24267
|
+
*
|
|
24268
|
+
* @param op A property binding operation.
|
|
24269
|
+
* @returns A statement to update the property at runtime.
|
|
24270
|
+
*/
|
|
24271
|
+
function reifyProperty(op) {
|
|
24272
|
+
return isAriaProperty(op.name)
|
|
24273
|
+
? ariaProperty(op.name, op.expression, op.sourceSpan)
|
|
24274
|
+
: property(op.name, op.expression, op.sanitizer, op.sourceSpan);
|
|
24275
|
+
}
|
|
23858
24276
|
function reifyIrExpression(expr) {
|
|
23859
24277
|
if (!isIrExpression(expr)) {
|
|
23860
24278
|
return expr;
|
|
@@ -24096,6 +24514,8 @@ function processLexicalScope$1(view, ops) {
|
|
|
24096
24514
|
break;
|
|
24097
24515
|
}
|
|
24098
24516
|
break;
|
|
24517
|
+
case OpKind.Animation:
|
|
24518
|
+
case OpKind.AnimationListener:
|
|
24099
24519
|
case OpKind.Listener:
|
|
24100
24520
|
case OpKind.TwoWayListener:
|
|
24101
24521
|
processLexicalScope$1(view, op.handlerOps);
|
|
@@ -24161,11 +24581,13 @@ function resolveDollarEvent(job) {
|
|
|
24161
24581
|
}
|
|
24162
24582
|
function transformDollarEvent(ops) {
|
|
24163
24583
|
for (const op of ops) {
|
|
24164
|
-
if (op.kind === OpKind.Listener ||
|
|
24584
|
+
if (op.kind === OpKind.Listener ||
|
|
24585
|
+
op.kind === OpKind.TwoWayListener ||
|
|
24586
|
+
op.kind === OpKind.AnimationListener) {
|
|
24165
24587
|
transformExpressionsInOp(op, (expr) => {
|
|
24166
24588
|
if (expr instanceof LexicalReadExpr && expr.name === '$event') {
|
|
24167
24589
|
// Two-way listeners always consume `$event` so they omit this field.
|
|
24168
|
-
if (op.kind === OpKind.Listener) {
|
|
24590
|
+
if (op.kind === OpKind.Listener || op.kind === OpKind.AnimationListener) {
|
|
24169
24591
|
op.consumesDollarEvent = true;
|
|
24170
24592
|
}
|
|
24171
24593
|
return new ReadVarExpr(expr.name);
|
|
@@ -24556,6 +24978,8 @@ function processLexicalScope(unit, ops, savedView) {
|
|
|
24556
24978
|
break;
|
|
24557
24979
|
}
|
|
24558
24980
|
break;
|
|
24981
|
+
case OpKind.Animation:
|
|
24982
|
+
case OpKind.AnimationListener:
|
|
24559
24983
|
case OpKind.Listener:
|
|
24560
24984
|
case OpKind.TwoWayListener:
|
|
24561
24985
|
// Listener functions have separate variable declarations, so process them as a separate
|
|
@@ -24573,7 +24997,10 @@ function processLexicalScope(unit, ops, savedView) {
|
|
|
24573
24997
|
// scope. Also, look for `ir.RestoreViewExpr`s and match them with the snapshotted view context
|
|
24574
24998
|
// variable.
|
|
24575
24999
|
for (const op of ops) {
|
|
24576
|
-
if (op.kind == OpKind.Listener ||
|
|
25000
|
+
if (op.kind == OpKind.Listener ||
|
|
25001
|
+
op.kind === OpKind.TwoWayListener ||
|
|
25002
|
+
op.kind === OpKind.Animation ||
|
|
25003
|
+
op.kind === OpKind.AnimationListener) {
|
|
24577
25004
|
// Listeners were already processed above with their own scopes.
|
|
24578
25005
|
continue;
|
|
24579
25006
|
}
|
|
@@ -24742,7 +25169,10 @@ function saveAndRestoreView(job) {
|
|
|
24742
25169
|
}, new GetCurrentViewExpr(), VariableFlags.None),
|
|
24743
25170
|
]);
|
|
24744
25171
|
for (const op of unit.create) {
|
|
24745
|
-
if (op.kind !== OpKind.Listener &&
|
|
25172
|
+
if (op.kind !== OpKind.Listener &&
|
|
25173
|
+
op.kind !== OpKind.TwoWayListener &&
|
|
25174
|
+
op.kind !== OpKind.Animation &&
|
|
25175
|
+
op.kind !== OpKind.AnimationListener) {
|
|
24746
25176
|
continue;
|
|
24747
25177
|
}
|
|
24748
25178
|
// Embedded views always need the save/restore view operation.
|
|
@@ -25062,7 +25492,10 @@ function generateTemporaries(ops) {
|
|
|
25062
25492
|
// Add declarations for the temp vars.
|
|
25063
25493
|
generatedStatements.push(...Array.from(new Set(defs.values())).map((name) => createStatementOp(new DeclareVarStmt(name))));
|
|
25064
25494
|
opCount++;
|
|
25065
|
-
if (op.kind === OpKind.Listener ||
|
|
25495
|
+
if (op.kind === OpKind.Listener ||
|
|
25496
|
+
op.kind === OpKind.Animation ||
|
|
25497
|
+
op.kind === OpKind.AnimationListener ||
|
|
25498
|
+
op.kind === OpKind.TwoWayListener) {
|
|
25066
25499
|
op.handlerOps.prepend(generateTemporaries(op.handlerOps));
|
|
25067
25500
|
}
|
|
25068
25501
|
else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
|
|
@@ -25406,7 +25839,10 @@ function optimizeVariables(job) {
|
|
|
25406
25839
|
inlineAlwaysInlineVariables(unit.create);
|
|
25407
25840
|
inlineAlwaysInlineVariables(unit.update);
|
|
25408
25841
|
for (const op of unit.create) {
|
|
25409
|
-
if (op.kind === OpKind.Listener ||
|
|
25842
|
+
if (op.kind === OpKind.Listener ||
|
|
25843
|
+
op.kind === OpKind.Animation ||
|
|
25844
|
+
op.kind === OpKind.AnimationListener ||
|
|
25845
|
+
op.kind === OpKind.TwoWayListener) {
|
|
25410
25846
|
inlineAlwaysInlineVariables(op.handlerOps);
|
|
25411
25847
|
}
|
|
25412
25848
|
else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
|
|
@@ -25416,7 +25852,10 @@ function optimizeVariables(job) {
|
|
|
25416
25852
|
optimizeVariablesInOpList(unit.create, job.compatibility);
|
|
25417
25853
|
optimizeVariablesInOpList(unit.update, job.compatibility);
|
|
25418
25854
|
for (const op of unit.create) {
|
|
25419
|
-
if (op.kind === OpKind.Listener ||
|
|
25855
|
+
if (op.kind === OpKind.Listener ||
|
|
25856
|
+
op.kind === OpKind.Animation ||
|
|
25857
|
+
op.kind === OpKind.AnimationListener ||
|
|
25858
|
+
op.kind === OpKind.TwoWayListener) {
|
|
25420
25859
|
optimizeVariablesInOpList(op.handlerOps, job.compatibility);
|
|
25421
25860
|
}
|
|
25422
25861
|
else if (op.kind === OpKind.RepeaterCreate && op.trackByOps !== null) {
|
|
@@ -25853,6 +26292,7 @@ const phases = [
|
|
|
25853
26292
|
{ kind: CompilationJobKind.Both, fn: deduplicateTextBindings },
|
|
25854
26293
|
{ kind: CompilationJobKind.Both, fn: specializeStyleBindings },
|
|
25855
26294
|
{ kind: CompilationJobKind.Both, fn: specializeBindings },
|
|
26295
|
+
{ kind: CompilationJobKind.Both, fn: convertAnimations },
|
|
25856
26296
|
{ kind: CompilationJobKind.Both, fn: extractAttributes },
|
|
25857
26297
|
{ kind: CompilationJobKind.Tmpl, fn: createI18nContexts },
|
|
25858
26298
|
{ kind: CompilationJobKind.Both, fn: parseExtractedStyles },
|
|
@@ -26012,6 +26452,8 @@ const compatibilityMode = CompatibilityMode.TemplateDefinitionBuilder;
|
|
|
26012
26452
|
const domSchema = new DomElementSchemaRegistry();
|
|
26013
26453
|
// Tag name of the `ng-template` element.
|
|
26014
26454
|
const NG_TEMPLATE_TAG_NAME = 'ng-template';
|
|
26455
|
+
// prefix for any animation binding
|
|
26456
|
+
const ANIMATE_PREFIX$1 = 'animate.';
|
|
26015
26457
|
function isI18nRootNode(meta) {
|
|
26016
26458
|
return meta instanceof Message;
|
|
26017
26459
|
}
|
|
@@ -26044,6 +26486,9 @@ function ingestHostBinding(input, bindingParser, constantPool) {
|
|
|
26044
26486
|
if (property.isLegacyAnimation) {
|
|
26045
26487
|
bindingKind = BindingKind.LegacyAnimation;
|
|
26046
26488
|
}
|
|
26489
|
+
if (property.isAnimation) {
|
|
26490
|
+
bindingKind = BindingKind.Animation;
|
|
26491
|
+
}
|
|
26047
26492
|
const securityContexts = bindingParser
|
|
26048
26493
|
.calcPossibleSecurityContexts(input.componentSelector, property.name, bindingKind === BindingKind.Attribute)
|
|
26049
26494
|
.filter((context) => context !== SecurityContext.NONE);
|
|
@@ -26710,6 +27155,7 @@ const BINDING_KINDS = new Map([
|
|
|
26710
27155
|
[exports.BindingType.Class, BindingKind.ClassName],
|
|
26711
27156
|
[exports.BindingType.Style, BindingKind.StyleProperty],
|
|
26712
27157
|
[exports.BindingType.LegacyAnimation, BindingKind.LegacyAnimation],
|
|
27158
|
+
[exports.BindingType.Animation, BindingKind.Animation],
|
|
26713
27159
|
]);
|
|
26714
27160
|
/**
|
|
26715
27161
|
* Checks whether the given template is a plain ng-template (as opposed to another kind of template
|
|
@@ -26774,6 +27220,9 @@ function ingestElementBindings(unit, op, element) {
|
|
|
26774
27220
|
if (output.type === exports.ParsedEventType.TwoWay) {
|
|
26775
27221
|
unit.create.push(createTwoWayListenerOp(op.xref, op.handle, output.name, op.tag, makeTwoWayListenerHandlerOps(unit, output.handler, output.handlerSpan), output.sourceSpan));
|
|
26776
27222
|
}
|
|
27223
|
+
else if (output.type === exports.ParsedEventType.Animation) {
|
|
27224
|
+
unit.create.push(createAnimationListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.name.endsWith('enter') ? "enter" /* ir.AnimationKind.ENTER */ : "leave" /* ir.AnimationKind.LEAVE */, output.target, false, output.sourceSpan));
|
|
27225
|
+
}
|
|
26777
27226
|
else {
|
|
26778
27227
|
unit.create.push(createListenerOp(op.xref, op.handle, output.name, op.tag, makeListenerHandlerOps(unit, output.handler, output.handlerSpan), output.phase, output.target, false, output.sourceSpan));
|
|
26779
27228
|
}
|
|
@@ -26882,7 +27331,9 @@ function createTemplateBinding(view, xref, type, name, value, unit, securityCont
|
|
|
26882
27331
|
}
|
|
26883
27332
|
}
|
|
26884
27333
|
if (!isTextBinding &&
|
|
26885
|
-
(type === exports.BindingType.Attribute ||
|
|
27334
|
+
(type === exports.BindingType.Attribute ||
|
|
27335
|
+
type === exports.BindingType.LegacyAnimation ||
|
|
27336
|
+
type === exports.BindingType.Animation)) {
|
|
26886
27337
|
// Again, this binding doesn't really target the ng-template; it actually targets the element
|
|
26887
27338
|
// inside the structural template. In the case of non-text attribute or animation bindings,
|
|
26888
27339
|
// the binding doesn't even show up on the ng-template const array, so we just skip it
|
|
@@ -27040,14 +27491,18 @@ function ingestControlFlowInsertionPoint(unit, xref, node) {
|
|
|
27040
27491
|
if (root !== null) {
|
|
27041
27492
|
// Collect the static attributes for content projection purposes.
|
|
27042
27493
|
for (const attr of root.attributes) {
|
|
27043
|
-
|
|
27044
|
-
|
|
27494
|
+
if (!attr.name.startsWith(ANIMATE_PREFIX$1)) {
|
|
27495
|
+
const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
|
|
27496
|
+
unit.update.push(createBindingOp(xref, BindingKind.Attribute, attr.name, literal(attr.value), null, securityContext, true, false, null, asMessage(attr.i18n), attr.sourceSpan));
|
|
27497
|
+
}
|
|
27045
27498
|
}
|
|
27046
27499
|
// Also collect the inputs since they participate in content projection as well.
|
|
27047
27500
|
// Note that TDB used to collect the outputs as well, but it wasn't passing them into
|
|
27048
27501
|
// the template instruction. Here we just don't collect them.
|
|
27049
27502
|
for (const attr of root.inputs) {
|
|
27050
|
-
if (attr.type !== exports.BindingType.LegacyAnimation &&
|
|
27503
|
+
if (attr.type !== exports.BindingType.LegacyAnimation &&
|
|
27504
|
+
attr.type !== exports.BindingType.Animation &&
|
|
27505
|
+
attr.type !== exports.BindingType.Attribute) {
|
|
27051
27506
|
const securityContext = domSchema.securityContext(NG_TEMPLATE_TAG_NAME, attr.name, true);
|
|
27052
27507
|
unit.create.push(createExtractedAttributeOp(xref, BindingKind.Property, null, attr.name, null, null, null, securityContext));
|
|
27053
27508
|
}
|
|
@@ -27259,6 +27714,7 @@ class HtmlParser extends Parser$1 {
|
|
|
27259
27714
|
|
|
27260
27715
|
const PROPERTY_PARTS_SEPARATOR = '.';
|
|
27261
27716
|
const ATTRIBUTE_PREFIX = 'attr';
|
|
27717
|
+
const ANIMATE_PREFIX = 'animate';
|
|
27262
27718
|
const CLASS_PREFIX = 'class';
|
|
27263
27719
|
const STYLE_PREFIX = 'style';
|
|
27264
27720
|
const TEMPLATE_ATTR_PREFIX$1 = '*';
|
|
@@ -27458,6 +27914,9 @@ class BindingParser {
|
|
|
27458
27914
|
if (isLegacyAnimationProp) {
|
|
27459
27915
|
this._parseLegacyAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27460
27916
|
}
|
|
27917
|
+
else if (name.startsWith(ANIMATE_PREFIX)) {
|
|
27918
|
+
this._parseAnimation(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27919
|
+
}
|
|
27461
27920
|
else {
|
|
27462
27921
|
this._parsePropertyAst(name, this.parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), isPartOfAssignmentBinding, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
|
|
27463
27922
|
}
|
|
@@ -27474,6 +27933,10 @@ class BindingParser {
|
|
|
27474
27933
|
targetMatchableAttrs.push([name, ast.source]);
|
|
27475
27934
|
targetProps.push(new ParsedProperty(name, ast, isPartOfAssignmentBinding ? ParsedPropertyType.TWO_WAY : ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan));
|
|
27476
27935
|
}
|
|
27936
|
+
_parseAnimation(name, ast, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
27937
|
+
targetMatchableAttrs.push([name, ast.source]);
|
|
27938
|
+
targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.ANIMATION, sourceSpan, keySpan, valueSpan));
|
|
27939
|
+
}
|
|
27477
27940
|
_parseLegacyAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
|
|
27478
27941
|
if (name.length === 0) {
|
|
27479
27942
|
this._reportError('Animation trigger is missing', sourceSpan);
|
|
@@ -27536,6 +27999,11 @@ class BindingParser {
|
|
|
27536
27999
|
bindingType = exports.BindingType.Style;
|
|
27537
28000
|
securityContexts = [SecurityContext.STYLE];
|
|
27538
28001
|
}
|
|
28002
|
+
else if (parts[0] == ANIMATE_PREFIX) {
|
|
28003
|
+
boundPropertyName = boundProp.name;
|
|
28004
|
+
bindingType = exports.BindingType.Animation;
|
|
28005
|
+
securityContexts = [SecurityContext.NONE];
|
|
28006
|
+
}
|
|
27539
28007
|
}
|
|
27540
28008
|
// If not a special case, use the full property name
|
|
27541
28009
|
if (boundPropertyName === null) {
|
|
@@ -27550,7 +28018,6 @@ class BindingParser {
|
|
|
27550
28018
|
}
|
|
27551
28019
|
return new BoundElementProperty(boundPropertyName, bindingType, securityContexts[0], boundProp.expression, unit, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
|
|
27552
28020
|
}
|
|
27553
|
-
// TODO: keySpan should be required but was made optional to avoid changing VE parser.
|
|
27554
28021
|
parseEvent(name, expression, isAssignmentEvent, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents, keySpan) {
|
|
27555
28022
|
if (name.length === 0) {
|
|
27556
28023
|
this._reportError(`Event name is missing in binding`, sourceSpan);
|
|
@@ -27606,7 +28073,14 @@ class BindingParser {
|
|
|
27606
28073
|
if (isAssignmentEvent && isValid && !this._isAllowedAssignmentEvent(ast)) {
|
|
27607
28074
|
this._reportError('Unsupported expression in a two-way binding', sourceSpan);
|
|
27608
28075
|
}
|
|
27609
|
-
|
|
28076
|
+
let eventType = exports.ParsedEventType.Regular;
|
|
28077
|
+
if (isAssignmentEvent) {
|
|
28078
|
+
eventType = exports.ParsedEventType.TwoWay;
|
|
28079
|
+
}
|
|
28080
|
+
if (name.startsWith(ANIMATE_PREFIX)) {
|
|
28081
|
+
eventType = exports.ParsedEventType.Animation;
|
|
28082
|
+
}
|
|
28083
|
+
targetEvents.push(new ParsedEvent(eventName, target, eventType, ast, sourceSpan, handlerSpan, keySpan));
|
|
27610
28084
|
// Don't detect directives for event names for now,
|
|
27611
28085
|
// so don't add the event name to the matchableAttrs
|
|
27612
28086
|
}
|
|
@@ -28865,7 +29339,7 @@ class HtmlAstToIvyAst {
|
|
|
28865
29339
|
}
|
|
28866
29340
|
else {
|
|
28867
29341
|
const attrs = this.categorizePropertyAttributes(element.name, parsedProperties, i18nAttrsMeta);
|
|
28868
|
-
parsedElement = new Element$1(element.name, attributes, attrs.bound, boundEvents, directives, children, references, element.isSelfClosing, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.i18n);
|
|
29342
|
+
parsedElement = new Element$1(element.name, attributes, attrs.bound, boundEvents, directives, children, references, element.isSelfClosing, element.sourceSpan, element.startSourceSpan, element.endSourceSpan, element.isVoid, element.i18n);
|
|
28869
29343
|
}
|
|
28870
29344
|
if (elementHasInlineTemplate) {
|
|
28871
29345
|
// If this node is an inline-template (e.g. has *ngFor) then we need to create a template
|
|
@@ -29177,7 +29651,7 @@ class HtmlAstToIvyAst {
|
|
|
29177
29651
|
const identifier = bindParts[IDENT_KW_IDX];
|
|
29178
29652
|
const keySpan = createKeySpan(srcSpan, bindParts[KW_BINDON_IDX], identifier);
|
|
29179
29653
|
this.bindingParser.parsePropertyBinding(identifier, value, false, true, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
29180
|
-
this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan);
|
|
29654
|
+
this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan, absoluteOffset);
|
|
29181
29655
|
}
|
|
29182
29656
|
else if (bindParts[KW_AT_IDX]) {
|
|
29183
29657
|
const keySpan = createKeySpan(srcSpan, '', name);
|
|
@@ -29208,7 +29682,7 @@ class HtmlAstToIvyAst {
|
|
|
29208
29682
|
const keySpan = createKeySpan(srcSpan, delims.start, identifier);
|
|
29209
29683
|
if (delims.start === BINDING_DELIMS.BANANA_BOX.start) {
|
|
29210
29684
|
this.bindingParser.parsePropertyBinding(identifier, value, false, true, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
29211
|
-
this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan);
|
|
29685
|
+
this.parseAssignmentEvent(identifier, value, srcSpan, attribute.valueSpan, matchableAttributes, boundEvents, keySpan, absoluteOffset);
|
|
29212
29686
|
}
|
|
29213
29687
|
else if (delims.start === BINDING_DELIMS.PROPERTY.start) {
|
|
29214
29688
|
this.bindingParser.parsePropertyBinding(identifier, value, false, false, srcSpan, absoluteOffset, attribute.valueSpan, matchableAttributes, parsedProperties, keySpan);
|
|
@@ -29328,7 +29802,7 @@ class HtmlAstToIvyAst {
|
|
|
29328
29802
|
}
|
|
29329
29803
|
references.push(new Reference$1(identifier, value, sourceSpan, keySpan, valueSpan));
|
|
29330
29804
|
}
|
|
29331
|
-
parseAssignmentEvent(name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan) {
|
|
29805
|
+
parseAssignmentEvent(name, expression, sourceSpan, valueSpan, targetMatchableAttrs, boundEvents, keySpan, absoluteOffset) {
|
|
29332
29806
|
const events = [];
|
|
29333
29807
|
this.bindingParser.parseEvent(`${name}Change`, expression,
|
|
29334
29808
|
/* isAssignmentEvent */ true, sourceSpan, valueSpan || sourceSpan, targetMatchableAttrs, events, keySpan);
|
|
@@ -29371,7 +29845,7 @@ class NonBindableVisitor {
|
|
|
29371
29845
|
/* inputs */ [],
|
|
29372
29846
|
/* outputs */ [],
|
|
29373
29847
|
/* directives */ [], children,
|
|
29374
|
-
/* references */ [], ast.isSelfClosing, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
|
|
29848
|
+
/* references */ [], ast.isSelfClosing, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, ast.isVoid);
|
|
29375
29849
|
}
|
|
29376
29850
|
visitComment(comment) {
|
|
29377
29851
|
return null;
|
|
@@ -29412,7 +29886,7 @@ class NonBindableVisitor {
|
|
|
29412
29886
|
/* inputs */ [],
|
|
29413
29887
|
/* outputs */ [],
|
|
29414
29888
|
/* directives */ [], children,
|
|
29415
|
-
/* references */ [], ast.isSelfClosing, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
|
|
29889
|
+
/* references */ [], ast.isSelfClosing, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan, false);
|
|
29416
29890
|
}
|
|
29417
29891
|
visitDirective(directive, context) {
|
|
29418
29892
|
return null;
|
|
@@ -29556,9 +30030,184 @@ function makeBindingParser(interpolationConfig = DEFAULT_INTERPOLATION_CONFIG, s
|
|
|
29556
30030
|
return new BindingParser(new Parser(new Lexer(), selectorlessEnabled), interpolationConfig, elementRegistry, []);
|
|
29557
30031
|
}
|
|
29558
30032
|
|
|
30033
|
+
/*!
|
|
30034
|
+
* @license
|
|
30035
|
+
* Copyright Google LLC All Rights Reserved.
|
|
30036
|
+
*
|
|
30037
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
30038
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
30039
|
+
*/
|
|
30040
|
+
/**
|
|
30041
|
+
* Visitor that traverses all template and expression AST nodes in a template.
|
|
30042
|
+
* Useful for cases where every single node needs to be visited.
|
|
30043
|
+
*/
|
|
30044
|
+
class CombinedRecursiveAstVisitor extends RecursiveAstVisitor {
|
|
30045
|
+
visit(node) {
|
|
30046
|
+
if (node instanceof ASTWithSource) {
|
|
30047
|
+
this.visit(node.ast);
|
|
30048
|
+
}
|
|
30049
|
+
else {
|
|
30050
|
+
node.visit(this);
|
|
30051
|
+
}
|
|
30052
|
+
}
|
|
30053
|
+
visitElement(element) {
|
|
30054
|
+
this.visitAllTemplateNodes(element.attributes);
|
|
30055
|
+
this.visitAllTemplateNodes(element.inputs);
|
|
30056
|
+
this.visitAllTemplateNodes(element.outputs);
|
|
30057
|
+
this.visitAllTemplateNodes(element.directives);
|
|
30058
|
+
this.visitAllTemplateNodes(element.references);
|
|
30059
|
+
this.visitAllTemplateNodes(element.children);
|
|
30060
|
+
}
|
|
30061
|
+
visitTemplate(template) {
|
|
30062
|
+
this.visitAllTemplateNodes(template.attributes);
|
|
30063
|
+
this.visitAllTemplateNodes(template.inputs);
|
|
30064
|
+
this.visitAllTemplateNodes(template.outputs);
|
|
30065
|
+
this.visitAllTemplateNodes(template.directives);
|
|
30066
|
+
this.visitAllTemplateNodes(template.templateAttrs);
|
|
30067
|
+
this.visitAllTemplateNodes(template.variables);
|
|
30068
|
+
this.visitAllTemplateNodes(template.references);
|
|
30069
|
+
this.visitAllTemplateNodes(template.children);
|
|
30070
|
+
}
|
|
30071
|
+
visitContent(content) {
|
|
30072
|
+
this.visitAllTemplateNodes(content.children);
|
|
30073
|
+
}
|
|
30074
|
+
visitBoundAttribute(attribute) {
|
|
30075
|
+
this.visit(attribute.value);
|
|
30076
|
+
}
|
|
30077
|
+
visitBoundEvent(attribute) {
|
|
30078
|
+
this.visit(attribute.handler);
|
|
30079
|
+
}
|
|
30080
|
+
visitBoundText(text) {
|
|
30081
|
+
this.visit(text.value);
|
|
30082
|
+
}
|
|
30083
|
+
visitIcu(icu) {
|
|
30084
|
+
Object.keys(icu.vars).forEach((key) => this.visit(icu.vars[key]));
|
|
30085
|
+
Object.keys(icu.placeholders).forEach((key) => this.visit(icu.placeholders[key]));
|
|
30086
|
+
}
|
|
30087
|
+
visitDeferredBlock(deferred) {
|
|
30088
|
+
deferred.visitAll(this);
|
|
30089
|
+
}
|
|
30090
|
+
visitDeferredTrigger(trigger) {
|
|
30091
|
+
if (trigger instanceof BoundDeferredTrigger) {
|
|
30092
|
+
this.visit(trigger.value);
|
|
30093
|
+
}
|
|
30094
|
+
}
|
|
30095
|
+
visitDeferredBlockPlaceholder(block) {
|
|
30096
|
+
this.visitAllTemplateNodes(block.children);
|
|
30097
|
+
}
|
|
30098
|
+
visitDeferredBlockError(block) {
|
|
30099
|
+
this.visitAllTemplateNodes(block.children);
|
|
30100
|
+
}
|
|
30101
|
+
visitDeferredBlockLoading(block) {
|
|
30102
|
+
this.visitAllTemplateNodes(block.children);
|
|
30103
|
+
}
|
|
30104
|
+
visitSwitchBlock(block) {
|
|
30105
|
+
this.visit(block.expression);
|
|
30106
|
+
this.visitAllTemplateNodes(block.cases);
|
|
30107
|
+
}
|
|
30108
|
+
visitSwitchBlockCase(block) {
|
|
30109
|
+
block.expression && this.visit(block.expression);
|
|
30110
|
+
this.visitAllTemplateNodes(block.children);
|
|
30111
|
+
}
|
|
30112
|
+
visitForLoopBlock(block) {
|
|
30113
|
+
block.item.visit(this);
|
|
30114
|
+
this.visitAllTemplateNodes(block.contextVariables);
|
|
30115
|
+
this.visit(block.expression);
|
|
30116
|
+
this.visitAllTemplateNodes(block.children);
|
|
30117
|
+
block.empty?.visit(this);
|
|
30118
|
+
}
|
|
30119
|
+
visitForLoopBlockEmpty(block) {
|
|
30120
|
+
this.visitAllTemplateNodes(block.children);
|
|
30121
|
+
}
|
|
30122
|
+
visitIfBlock(block) {
|
|
30123
|
+
this.visitAllTemplateNodes(block.branches);
|
|
30124
|
+
}
|
|
30125
|
+
visitIfBlockBranch(block) {
|
|
30126
|
+
block.expression && this.visit(block.expression);
|
|
30127
|
+
block.expressionAlias?.visit(this);
|
|
30128
|
+
this.visitAllTemplateNodes(block.children);
|
|
30129
|
+
}
|
|
30130
|
+
visitLetDeclaration(decl) {
|
|
30131
|
+
this.visit(decl.value);
|
|
30132
|
+
}
|
|
30133
|
+
visitComponent(component) {
|
|
30134
|
+
this.visitAllTemplateNodes(component.attributes);
|
|
30135
|
+
this.visitAllTemplateNodes(component.inputs);
|
|
30136
|
+
this.visitAllTemplateNodes(component.outputs);
|
|
30137
|
+
this.visitAllTemplateNodes(component.directives);
|
|
30138
|
+
this.visitAllTemplateNodes(component.references);
|
|
30139
|
+
this.visitAllTemplateNodes(component.children);
|
|
30140
|
+
}
|
|
30141
|
+
visitDirective(directive) {
|
|
30142
|
+
this.visitAllTemplateNodes(directive.attributes);
|
|
30143
|
+
this.visitAllTemplateNodes(directive.inputs);
|
|
30144
|
+
this.visitAllTemplateNodes(directive.outputs);
|
|
30145
|
+
this.visitAllTemplateNodes(directive.references);
|
|
30146
|
+
}
|
|
30147
|
+
visitVariable(variable) { }
|
|
30148
|
+
visitReference(reference) { }
|
|
30149
|
+
visitTextAttribute(attribute) { }
|
|
30150
|
+
visitText(text) { }
|
|
30151
|
+
visitUnknownBlock(block) { }
|
|
30152
|
+
visitAllTemplateNodes(nodes) {
|
|
30153
|
+
for (const node of nodes) {
|
|
30154
|
+
this.visit(node);
|
|
30155
|
+
}
|
|
30156
|
+
}
|
|
30157
|
+
}
|
|
30158
|
+
|
|
30159
|
+
/*!
|
|
30160
|
+
* @license
|
|
30161
|
+
* Copyright Google LLC All Rights Reserved.
|
|
30162
|
+
*
|
|
30163
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
30164
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
30165
|
+
*/
|
|
30166
|
+
const ANIMATE_LEAVE$1 = `animate.leave`;
|
|
30167
|
+
/**
|
|
30168
|
+
* Analyzes a component's template to determine if it's using animate.enter
|
|
30169
|
+
* or animate.leave syntax.
|
|
30170
|
+
*/
|
|
30171
|
+
function analyzeTemplateForAnimations(template) {
|
|
30172
|
+
const analyzer = new AnimationsAnalyzer();
|
|
30173
|
+
visitAll$1(analyzer, template);
|
|
30174
|
+
// The template is considered selectorless only if there
|
|
30175
|
+
// are direct references to directives or pipes.
|
|
30176
|
+
return analyzer.hasAnimations;
|
|
30177
|
+
}
|
|
30178
|
+
/**
|
|
30179
|
+
* Visitor that traverses all the template nodes and
|
|
30180
|
+
* expressions to look for selectorless references.
|
|
30181
|
+
*/
|
|
30182
|
+
class AnimationsAnalyzer extends CombinedRecursiveAstVisitor {
|
|
30183
|
+
hasAnimations = false;
|
|
30184
|
+
visitElement(element) {
|
|
30185
|
+
// check for regular strings
|
|
30186
|
+
for (const attr of element.attributes) {
|
|
30187
|
+
if (attr.name === ANIMATE_LEAVE$1) {
|
|
30188
|
+
this.hasAnimations = true;
|
|
30189
|
+
}
|
|
30190
|
+
}
|
|
30191
|
+
// check for attribute bindings
|
|
30192
|
+
for (const input of element.inputs) {
|
|
30193
|
+
if (input.name === ANIMATE_LEAVE$1) {
|
|
30194
|
+
this.hasAnimations = true;
|
|
30195
|
+
}
|
|
30196
|
+
}
|
|
30197
|
+
// check for event bindings
|
|
30198
|
+
for (const output of element.outputs) {
|
|
30199
|
+
if (output.name === ANIMATE_LEAVE$1) {
|
|
30200
|
+
this.hasAnimations = true;
|
|
30201
|
+
}
|
|
30202
|
+
}
|
|
30203
|
+
super.visitElement(element);
|
|
30204
|
+
}
|
|
30205
|
+
}
|
|
30206
|
+
|
|
29559
30207
|
const COMPONENT_VARIABLE = '%COMP%';
|
|
29560
30208
|
const HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;
|
|
29561
30209
|
const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
|
|
30210
|
+
const ANIMATE_LEAVE = `animate.leave`;
|
|
29562
30211
|
function baseDirectiveFields(meta, constantPool, bindingParser) {
|
|
29563
30212
|
const definitionMap = new DefinitionMap();
|
|
29564
30213
|
const selectors = parseSelectorToR3Selector(meta.selector);
|
|
@@ -29592,6 +30241,11 @@ function baseDirectiveFields(meta, constantPool, bindingParser) {
|
|
|
29592
30241
|
}
|
|
29593
30242
|
return definitionMap;
|
|
29594
30243
|
}
|
|
30244
|
+
function hasAnimationHostBinding(meta) {
|
|
30245
|
+
return (meta.host.attributes[ANIMATE_LEAVE] !== undefined ||
|
|
30246
|
+
meta.host.properties[ANIMATE_LEAVE] !== undefined ||
|
|
30247
|
+
meta.host.listeners[ANIMATE_LEAVE] !== undefined);
|
|
30248
|
+
}
|
|
29595
30249
|
/**
|
|
29596
30250
|
* Add features to the definition map.
|
|
29597
30251
|
*/
|
|
@@ -29626,6 +30280,12 @@ function addFeatures(definitionMap, meta) {
|
|
|
29626
30280
|
const externalStyleNodes = meta.externalStyles.map((externalStyle) => literal(externalStyle));
|
|
29627
30281
|
features.push(importExpr(Identifiers.ExternalStylesFeature).callFn([literalArr(externalStyleNodes)]));
|
|
29628
30282
|
}
|
|
30283
|
+
const template = meta.template;
|
|
30284
|
+
if (hasAnimationHostBinding(meta) || (template && template.nodes.length > 0)) {
|
|
30285
|
+
if (hasAnimationHostBinding(meta) || analyzeTemplateForAnimations(template.nodes)) {
|
|
30286
|
+
features.push(importExpr(Identifiers.AnimationsFeature).callFn([]));
|
|
30287
|
+
}
|
|
30288
|
+
}
|
|
29629
30289
|
if (features.length) {
|
|
29630
30290
|
definitionMap.set('features', literalArr(features));
|
|
29631
30291
|
}
|
|
@@ -30066,132 +30726,6 @@ function compileDeferResolverFunction(meta) {
|
|
|
30066
30726
|
return arrowFn([], literalArr(depExpressions));
|
|
30067
30727
|
}
|
|
30068
30728
|
|
|
30069
|
-
/*!
|
|
30070
|
-
* @license
|
|
30071
|
-
* Copyright Google LLC All Rights Reserved.
|
|
30072
|
-
*
|
|
30073
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
30074
|
-
* found in the LICENSE file at https://angular.dev/license
|
|
30075
|
-
*/
|
|
30076
|
-
/**
|
|
30077
|
-
* Visitor that traverses all template and expression AST nodes in a template.
|
|
30078
|
-
* Useful for cases where every single node needs to be visited.
|
|
30079
|
-
*/
|
|
30080
|
-
class CombinedRecursiveAstVisitor extends RecursiveAstVisitor {
|
|
30081
|
-
visit(node) {
|
|
30082
|
-
if (node instanceof ASTWithSource) {
|
|
30083
|
-
this.visit(node.ast);
|
|
30084
|
-
}
|
|
30085
|
-
else {
|
|
30086
|
-
node.visit(this);
|
|
30087
|
-
}
|
|
30088
|
-
}
|
|
30089
|
-
visitElement(element) {
|
|
30090
|
-
this.visitAllTemplateNodes(element.attributes);
|
|
30091
|
-
this.visitAllTemplateNodes(element.inputs);
|
|
30092
|
-
this.visitAllTemplateNodes(element.outputs);
|
|
30093
|
-
this.visitAllTemplateNodes(element.directives);
|
|
30094
|
-
this.visitAllTemplateNodes(element.references);
|
|
30095
|
-
this.visitAllTemplateNodes(element.children);
|
|
30096
|
-
}
|
|
30097
|
-
visitTemplate(template) {
|
|
30098
|
-
this.visitAllTemplateNodes(template.attributes);
|
|
30099
|
-
this.visitAllTemplateNodes(template.inputs);
|
|
30100
|
-
this.visitAllTemplateNodes(template.outputs);
|
|
30101
|
-
this.visitAllTemplateNodes(template.directives);
|
|
30102
|
-
this.visitAllTemplateNodes(template.templateAttrs);
|
|
30103
|
-
this.visitAllTemplateNodes(template.variables);
|
|
30104
|
-
this.visitAllTemplateNodes(template.references);
|
|
30105
|
-
this.visitAllTemplateNodes(template.children);
|
|
30106
|
-
}
|
|
30107
|
-
visitContent(content) {
|
|
30108
|
-
this.visitAllTemplateNodes(content.children);
|
|
30109
|
-
}
|
|
30110
|
-
visitBoundAttribute(attribute) {
|
|
30111
|
-
this.visit(attribute.value);
|
|
30112
|
-
}
|
|
30113
|
-
visitBoundEvent(attribute) {
|
|
30114
|
-
this.visit(attribute.handler);
|
|
30115
|
-
}
|
|
30116
|
-
visitBoundText(text) {
|
|
30117
|
-
this.visit(text.value);
|
|
30118
|
-
}
|
|
30119
|
-
visitIcu(icu) {
|
|
30120
|
-
Object.keys(icu.vars).forEach((key) => this.visit(icu.vars[key]));
|
|
30121
|
-
Object.keys(icu.placeholders).forEach((key) => this.visit(icu.placeholders[key]));
|
|
30122
|
-
}
|
|
30123
|
-
visitDeferredBlock(deferred) {
|
|
30124
|
-
deferred.visitAll(this);
|
|
30125
|
-
}
|
|
30126
|
-
visitDeferredTrigger(trigger) {
|
|
30127
|
-
if (trigger instanceof BoundDeferredTrigger) {
|
|
30128
|
-
this.visit(trigger.value);
|
|
30129
|
-
}
|
|
30130
|
-
}
|
|
30131
|
-
visitDeferredBlockPlaceholder(block) {
|
|
30132
|
-
this.visitAllTemplateNodes(block.children);
|
|
30133
|
-
}
|
|
30134
|
-
visitDeferredBlockError(block) {
|
|
30135
|
-
this.visitAllTemplateNodes(block.children);
|
|
30136
|
-
}
|
|
30137
|
-
visitDeferredBlockLoading(block) {
|
|
30138
|
-
this.visitAllTemplateNodes(block.children);
|
|
30139
|
-
}
|
|
30140
|
-
visitSwitchBlock(block) {
|
|
30141
|
-
this.visit(block.expression);
|
|
30142
|
-
this.visitAllTemplateNodes(block.cases);
|
|
30143
|
-
}
|
|
30144
|
-
visitSwitchBlockCase(block) {
|
|
30145
|
-
block.expression && this.visit(block.expression);
|
|
30146
|
-
this.visitAllTemplateNodes(block.children);
|
|
30147
|
-
}
|
|
30148
|
-
visitForLoopBlock(block) {
|
|
30149
|
-
block.item.visit(this);
|
|
30150
|
-
this.visitAllTemplateNodes(block.contextVariables);
|
|
30151
|
-
this.visit(block.expression);
|
|
30152
|
-
this.visitAllTemplateNodes(block.children);
|
|
30153
|
-
block.empty?.visit(this);
|
|
30154
|
-
}
|
|
30155
|
-
visitForLoopBlockEmpty(block) {
|
|
30156
|
-
this.visitAllTemplateNodes(block.children);
|
|
30157
|
-
}
|
|
30158
|
-
visitIfBlock(block) {
|
|
30159
|
-
this.visitAllTemplateNodes(block.branches);
|
|
30160
|
-
}
|
|
30161
|
-
visitIfBlockBranch(block) {
|
|
30162
|
-
block.expression && this.visit(block.expression);
|
|
30163
|
-
block.expressionAlias?.visit(this);
|
|
30164
|
-
this.visitAllTemplateNodes(block.children);
|
|
30165
|
-
}
|
|
30166
|
-
visitLetDeclaration(decl) {
|
|
30167
|
-
this.visit(decl.value);
|
|
30168
|
-
}
|
|
30169
|
-
visitComponent(component) {
|
|
30170
|
-
this.visitAllTemplateNodes(component.attributes);
|
|
30171
|
-
this.visitAllTemplateNodes(component.inputs);
|
|
30172
|
-
this.visitAllTemplateNodes(component.outputs);
|
|
30173
|
-
this.visitAllTemplateNodes(component.directives);
|
|
30174
|
-
this.visitAllTemplateNodes(component.references);
|
|
30175
|
-
this.visitAllTemplateNodes(component.children);
|
|
30176
|
-
}
|
|
30177
|
-
visitDirective(directive) {
|
|
30178
|
-
this.visitAllTemplateNodes(directive.attributes);
|
|
30179
|
-
this.visitAllTemplateNodes(directive.inputs);
|
|
30180
|
-
this.visitAllTemplateNodes(directive.outputs);
|
|
30181
|
-
this.visitAllTemplateNodes(directive.references);
|
|
30182
|
-
}
|
|
30183
|
-
visitVariable(variable) { }
|
|
30184
|
-
visitReference(reference) { }
|
|
30185
|
-
visitTextAttribute(attribute) { }
|
|
30186
|
-
visitText(text) { }
|
|
30187
|
-
visitUnknownBlock(block) { }
|
|
30188
|
-
visitAllTemplateNodes(nodes) {
|
|
30189
|
-
for (const node of nodes) {
|
|
30190
|
-
this.visit(node);
|
|
30191
|
-
}
|
|
30192
|
-
}
|
|
30193
|
-
}
|
|
30194
|
-
|
|
30195
30729
|
/**
|
|
30196
30730
|
* Processes `Target`s with a given set of directives and performs a binding operation, which
|
|
30197
30731
|
* returns an object similar to TypeScript's `ts.TypeChecker` that contains knowledge about the
|
|
@@ -31451,7 +31985,7 @@ function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMap
|
|
|
31451
31985
|
declarations.push(...decl.directives.map((dir) => convertDirectiveDeclarationToMetadata(dir)));
|
|
31452
31986
|
decl.pipes && declarations.push(...convertPipeMapToMetadata(decl.pipes));
|
|
31453
31987
|
}
|
|
31454
|
-
const hasDirectiveDependencies = declarations.
|
|
31988
|
+
const hasDirectiveDependencies = declarations.some(({ kind }) => kind === exports.R3TemplateDependencyKind.Directive || kind === exports.R3TemplateDependencyKind.NgModule);
|
|
31455
31989
|
return {
|
|
31456
31990
|
...convertDeclareDirectiveFacadeToMetadata(decl, typeSourceSpan),
|
|
31457
31991
|
template,
|
|
@@ -31819,7 +32353,7 @@ class _Visitor {
|
|
|
31819
32353
|
this._init(_VisitorMode.Merge, interpolationConfig);
|
|
31820
32354
|
this._translations = translations;
|
|
31821
32355
|
// Construct a single fake root element
|
|
31822
|
-
const wrapper = new Element('wrapper', [], [], nodes, false, undefined, undefined, undefined);
|
|
32356
|
+
const wrapper = new Element('wrapper', [], [], nodes, false, undefined, undefined, undefined, false);
|
|
31823
32357
|
const translatedNode = wrapper.visit(this, null);
|
|
31824
32358
|
if (this._inI18nBlock) {
|
|
31825
32359
|
this._reportError(nodes[nodes.length - 1], 'Unclosed block');
|
|
@@ -31997,7 +32531,7 @@ class _Visitor {
|
|
|
31997
32531
|
this._inImplicitNode = wasInImplicitNode;
|
|
31998
32532
|
if (this._mode === _VisitorMode.Merge) {
|
|
31999
32533
|
if (node instanceof Element) {
|
|
32000
|
-
return new Element(node.name, this._translateAttributes(node), this._translateDirectives(node), childNodes, node.isSelfClosing, node.sourceSpan, node.startSourceSpan, node.endSourceSpan);
|
|
32534
|
+
return new Element(node.name, this._translateAttributes(node), this._translateDirectives(node), childNodes, node.isSelfClosing, node.sourceSpan, node.startSourceSpan, node.endSourceSpan, node.isVoid);
|
|
32001
32535
|
}
|
|
32002
32536
|
else {
|
|
32003
32537
|
return new Component(node.componentName, node.tagName, node.fullName, this._translateAttributes(node), this._translateDirectives(node), childNodes, node.isSelfClosing, node.sourceSpan, node.startSourceSpan, node.endSourceSpan);
|
|
@@ -32228,7 +32762,7 @@ function isAttrNode(ast) {
|
|
|
32228
32762
|
* @description
|
|
32229
32763
|
* Entry point for all public APIs of the compiler package.
|
|
32230
32764
|
*/
|
|
32231
|
-
new Version('20.2.0-next.
|
|
32765
|
+
new Version('20.2.0-next.2');
|
|
32232
32766
|
|
|
32233
32767
|
//////////////////////////////////////
|
|
32234
32768
|
// THIS FILE HAS GLOBAL SIDE EFFECT //
|
|
@@ -32761,6 +33295,20 @@ exports.ErrorCode = void 0;
|
|
|
32761
33295
|
* A structural directive is used in a template, but the directive is not imported.
|
|
32762
33296
|
*/
|
|
32763
33297
|
ErrorCode[ErrorCode["MISSING_STRUCTURAL_DIRECTIVE"] = 8116] = "MISSING_STRUCTURAL_DIRECTIVE";
|
|
33298
|
+
/**
|
|
33299
|
+
* A function in a text interpolation is not invoked.
|
|
33300
|
+
*
|
|
33301
|
+
* For example:
|
|
33302
|
+
* ```html
|
|
33303
|
+
* <p> {{ firstName }} </p>
|
|
33304
|
+
* ```
|
|
33305
|
+
*
|
|
33306
|
+
* The `firstName` function is not invoked. Instead, it should be:
|
|
33307
|
+
* ```html
|
|
33308
|
+
* <p> {{ firstName() }} </p>
|
|
33309
|
+
* ```
|
|
33310
|
+
*/
|
|
33311
|
+
ErrorCode[ErrorCode["UNINVOKED_FUNCTION_IN_TEXT_INTERPOLATION"] = 8117] = "UNINVOKED_FUNCTION_IN_TEXT_INTERPOLATION";
|
|
32764
33312
|
/**
|
|
32765
33313
|
* The template type-checking engine would need to generate an inline type check block for a
|
|
32766
33314
|
* component, but the current type-checking environment doesn't support it.
|
|
@@ -32922,6 +33470,7 @@ exports.ExtendedTemplateDiagnosticName = void 0;
|
|
|
32922
33470
|
ExtendedTemplateDiagnosticName["UNINVOKED_TRACK_FUNCTION"] = "uninvokedTrackFunction";
|
|
32923
33471
|
ExtendedTemplateDiagnosticName["UNUSED_STANDALONE_IMPORTS"] = "unusedStandaloneImports";
|
|
32924
33472
|
ExtendedTemplateDiagnosticName["UNPARENTHESIZED_NULLISH_COALESCING"] = "unparenthesizedNullishCoalescing";
|
|
33473
|
+
ExtendedTemplateDiagnosticName["UNINVOKED_FUNCTION_IN_TEXT_INTERPOLATION"] = "uninvokedFunctionInTextInterpolation";
|
|
32925
33474
|
})(exports.ExtendedTemplateDiagnosticName || (exports.ExtendedTemplateDiagnosticName = {}));
|
|
32926
33475
|
|
|
32927
33476
|
/**
|
|
@@ -33248,7 +33797,7 @@ class NodeJSPathManipulation {
|
|
|
33248
33797
|
// G3-ESM-MARKER: G3 uses CommonJS, but externally everything in ESM.
|
|
33249
33798
|
// CommonJS/ESM interop for determining the current file name and containing dir.
|
|
33250
33799
|
const isCommonJS = typeof __filename !== 'undefined';
|
|
33251
|
-
const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('checker-
|
|
33800
|
+
const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('checker-Cfq29XaS.cjs', document.baseURI).href));
|
|
33252
33801
|
// Note, when this code loads in the browser, `url` may be an empty `{}` due to the Closure shims.
|
|
33253
33802
|
const currentFileName = isCommonJS
|
|
33254
33803
|
? __filename
|
|
@@ -36668,75 +37217,83 @@ exports.PerfPhase = void 0;
|
|
|
36668
37217
|
* Time spent computing template type-checking diagnostics.
|
|
36669
37218
|
*/
|
|
36670
37219
|
PerfPhase[PerfPhase["TtcDiagnostics"] = 14] = "TtcDiagnostics";
|
|
37220
|
+
/**
|
|
37221
|
+
* Time spent computing template type-checking suggestion diagnostics.
|
|
37222
|
+
*/
|
|
37223
|
+
PerfPhase[PerfPhase["TtcSuggestionDiagnostics"] = 15] = "TtcSuggestionDiagnostics";
|
|
36671
37224
|
/**
|
|
36672
37225
|
* Time spent getting a `Symbol` from the `TemplateTypeChecker`.
|
|
36673
37226
|
*/
|
|
36674
|
-
PerfPhase[PerfPhase["TtcSymbol"] =
|
|
37227
|
+
PerfPhase[PerfPhase["TtcSymbol"] = 16] = "TtcSymbol";
|
|
36675
37228
|
/**
|
|
36676
37229
|
* Time spent by the Angular Language Service calculating a "get references" or a renaming
|
|
36677
37230
|
* operation.
|
|
36678
37231
|
*/
|
|
36679
|
-
PerfPhase[PerfPhase["LsReferencesAndRenames"] =
|
|
37232
|
+
PerfPhase[PerfPhase["LsReferencesAndRenames"] = 17] = "LsReferencesAndRenames";
|
|
36680
37233
|
/**
|
|
36681
37234
|
* Time spent by the Angular Language Service calculating a "quick info" operation.
|
|
36682
37235
|
*/
|
|
36683
|
-
PerfPhase[PerfPhase["LsQuickInfo"] =
|
|
37236
|
+
PerfPhase[PerfPhase["LsQuickInfo"] = 18] = "LsQuickInfo";
|
|
36684
37237
|
/**
|
|
36685
37238
|
* Time spent by the Angular Language Service calculating a "get type definition" or "get
|
|
36686
37239
|
* definition" operation.
|
|
36687
37240
|
*/
|
|
36688
|
-
PerfPhase[PerfPhase["LsDefinition"] =
|
|
37241
|
+
PerfPhase[PerfPhase["LsDefinition"] = 19] = "LsDefinition";
|
|
36689
37242
|
/**
|
|
36690
37243
|
* Time spent by the Angular Language Service calculating a "get completions" (AKA autocomplete)
|
|
36691
37244
|
* operation.
|
|
36692
37245
|
*/
|
|
36693
|
-
PerfPhase[PerfPhase["LsCompletions"] =
|
|
37246
|
+
PerfPhase[PerfPhase["LsCompletions"] = 20] = "LsCompletions";
|
|
36694
37247
|
/**
|
|
36695
37248
|
* Time spent by the Angular Language Service calculating a "view template typecheck block"
|
|
36696
37249
|
* operation.
|
|
36697
37250
|
*/
|
|
36698
|
-
PerfPhase[PerfPhase["LsTcb"] =
|
|
37251
|
+
PerfPhase[PerfPhase["LsTcb"] = 21] = "LsTcb";
|
|
36699
37252
|
/**
|
|
36700
37253
|
* Time spent by the Angular Language Service calculating diagnostics.
|
|
36701
37254
|
*/
|
|
36702
|
-
PerfPhase[PerfPhase["LsDiagnostics"] =
|
|
37255
|
+
PerfPhase[PerfPhase["LsDiagnostics"] = 22] = "LsDiagnostics";
|
|
37256
|
+
/**
|
|
37257
|
+
* Time spent by the Angular Language Service calculating suggestion diagnostics.
|
|
37258
|
+
*/
|
|
37259
|
+
PerfPhase[PerfPhase["LsSuggestionDiagnostics"] = 23] = "LsSuggestionDiagnostics";
|
|
36703
37260
|
/**
|
|
36704
37261
|
* Time spent by the Angular Language Service calculating a "get component locations for template"
|
|
36705
37262
|
* operation.
|
|
36706
37263
|
*/
|
|
36707
|
-
PerfPhase[PerfPhase["LsComponentLocations"] =
|
|
37264
|
+
PerfPhase[PerfPhase["LsComponentLocations"] = 24] = "LsComponentLocations";
|
|
36708
37265
|
/**
|
|
36709
37266
|
* Time spent by the Angular Language Service calculating signature help.
|
|
36710
37267
|
*/
|
|
36711
|
-
PerfPhase[PerfPhase["LsSignatureHelp"] =
|
|
37268
|
+
PerfPhase[PerfPhase["LsSignatureHelp"] = 25] = "LsSignatureHelp";
|
|
36712
37269
|
/**
|
|
36713
37270
|
* Time spent by the Angular Language Service calculating outlining spans.
|
|
36714
37271
|
*/
|
|
36715
|
-
PerfPhase[PerfPhase["OutliningSpans"] =
|
|
37272
|
+
PerfPhase[PerfPhase["OutliningSpans"] = 26] = "OutliningSpans";
|
|
36716
37273
|
/**
|
|
36717
37274
|
* Time spent by the Angular Language Service calculating code fixes.
|
|
36718
37275
|
*/
|
|
36719
|
-
PerfPhase[PerfPhase["LsCodeFixes"] =
|
|
37276
|
+
PerfPhase[PerfPhase["LsCodeFixes"] = 27] = "LsCodeFixes";
|
|
36720
37277
|
/**
|
|
36721
37278
|
* Time spent by the Angular Language Service to fix all detected same type errors.
|
|
36722
37279
|
*/
|
|
36723
|
-
PerfPhase[PerfPhase["LsCodeFixesAll"] =
|
|
37280
|
+
PerfPhase[PerfPhase["LsCodeFixesAll"] = 28] = "LsCodeFixesAll";
|
|
36724
37281
|
/**
|
|
36725
37282
|
* Time spent computing possible Angular refactorings.
|
|
36726
37283
|
*/
|
|
36727
|
-
PerfPhase[PerfPhase["LSComputeApplicableRefactorings"] =
|
|
37284
|
+
PerfPhase[PerfPhase["LSComputeApplicableRefactorings"] = 29] = "LSComputeApplicableRefactorings";
|
|
36728
37285
|
/**
|
|
36729
37286
|
* Time spent computing changes for applying a given refactoring.
|
|
36730
37287
|
*/
|
|
36731
|
-
PerfPhase[PerfPhase["LSApplyRefactoring"] =
|
|
37288
|
+
PerfPhase[PerfPhase["LSApplyRefactoring"] = 30] = "LSApplyRefactoring";
|
|
36732
37289
|
/**
|
|
36733
37290
|
* Time spent by the Angular Language Service calculating semantic classifications.
|
|
36734
37291
|
*/
|
|
36735
|
-
PerfPhase[PerfPhase["LSSemanticClassification"] =
|
|
37292
|
+
PerfPhase[PerfPhase["LSSemanticClassification"] = 31] = "LSSemanticClassification";
|
|
36736
37293
|
/**
|
|
36737
37294
|
* Tracks the number of `PerfPhase`s, and must appear at the end of the list.
|
|
36738
37295
|
*/
|
|
36739
|
-
PerfPhase[PerfPhase["LAST"] =
|
|
37296
|
+
PerfPhase[PerfPhase["LAST"] = 32] = "LAST";
|
|
36740
37297
|
})(exports.PerfPhase || (exports.PerfPhase = {}));
|
|
36741
37298
|
/**
|
|
36742
37299
|
* Represents some occurrence during compilation, and is tracked with a counter.
|
|
@@ -40275,6 +40832,314 @@ function extractHostBindingResources(nodes) {
|
|
|
40275
40832
|
return result;
|
|
40276
40833
|
}
|
|
40277
40834
|
|
|
40835
|
+
const parseSpanComment = /^(\d+),(\d+)$/;
|
|
40836
|
+
/**
|
|
40837
|
+
* Reads the trailing comments and finds the first match which is a span comment (i.e. 4,10) on a
|
|
40838
|
+
* node and returns it as an `AbsoluteSourceSpan`.
|
|
40839
|
+
*
|
|
40840
|
+
* Will return `null` if no trailing comments on the node match the expected form of a source span.
|
|
40841
|
+
*/
|
|
40842
|
+
function readSpanComment(node, sourceFile = node.getSourceFile()) {
|
|
40843
|
+
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40844
|
+
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40845
|
+
return null;
|
|
40846
|
+
}
|
|
40847
|
+
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40848
|
+
const match = commentText.match(parseSpanComment);
|
|
40849
|
+
if (match === null) {
|
|
40850
|
+
return null;
|
|
40851
|
+
}
|
|
40852
|
+
return new AbsoluteSourceSpan(+match[1], +match[2]);
|
|
40853
|
+
}) || null);
|
|
40854
|
+
}
|
|
40855
|
+
/** Used to identify what type the comment is. */
|
|
40856
|
+
var CommentTriviaType;
|
|
40857
|
+
(function (CommentTriviaType) {
|
|
40858
|
+
CommentTriviaType["DIAGNOSTIC"] = "D";
|
|
40859
|
+
CommentTriviaType["EXPRESSION_TYPE_IDENTIFIER"] = "T";
|
|
40860
|
+
})(CommentTriviaType || (CommentTriviaType = {}));
|
|
40861
|
+
/** Identifies what the TCB expression is for (for example, a directive declaration). */
|
|
40862
|
+
var ExpressionIdentifier;
|
|
40863
|
+
(function (ExpressionIdentifier) {
|
|
40864
|
+
ExpressionIdentifier["DIRECTIVE"] = "DIR";
|
|
40865
|
+
ExpressionIdentifier["COMPONENT_COMPLETION"] = "COMPCOMP";
|
|
40866
|
+
ExpressionIdentifier["EVENT_PARAMETER"] = "EP";
|
|
40867
|
+
ExpressionIdentifier["VARIABLE_AS_EXPRESSION"] = "VAE";
|
|
40868
|
+
})(ExpressionIdentifier || (ExpressionIdentifier = {}));
|
|
40869
|
+
/** Tags the node with the given expression identifier. */
|
|
40870
|
+
function addExpressionIdentifier(node, identifier) {
|
|
40871
|
+
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`,
|
|
40872
|
+
/* hasTrailingNewLine */ false);
|
|
40873
|
+
}
|
|
40874
|
+
const IGNORE_FOR_DIAGNOSTICS_MARKER = `${CommentTriviaType.DIAGNOSTIC}:ignore`;
|
|
40875
|
+
/**
|
|
40876
|
+
* Tag the `ts.Node` with an indication that any errors arising from the evaluation of the node
|
|
40877
|
+
* should be ignored.
|
|
40878
|
+
*/
|
|
40879
|
+
function markIgnoreDiagnostics(node) {
|
|
40880
|
+
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, IGNORE_FOR_DIAGNOSTICS_MARKER,
|
|
40881
|
+
/* hasTrailingNewLine */ false);
|
|
40882
|
+
}
|
|
40883
|
+
/** Returns true if the node has a marker that indicates diagnostics errors should be ignored. */
|
|
40884
|
+
function hasIgnoreForDiagnosticsMarker(node, sourceFile) {
|
|
40885
|
+
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40886
|
+
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40887
|
+
return null;
|
|
40888
|
+
}
|
|
40889
|
+
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40890
|
+
return commentText === IGNORE_FOR_DIAGNOSTICS_MARKER;
|
|
40891
|
+
}) === true);
|
|
40892
|
+
}
|
|
40893
|
+
function makeRecursiveVisitor(visitor) {
|
|
40894
|
+
function recursiveVisitor(node) {
|
|
40895
|
+
const res = visitor(node);
|
|
40896
|
+
return res !== null ? res : node.forEachChild(recursiveVisitor);
|
|
40897
|
+
}
|
|
40898
|
+
return recursiveVisitor;
|
|
40899
|
+
}
|
|
40900
|
+
function getSpanFromOptions(opts) {
|
|
40901
|
+
let withSpan = null;
|
|
40902
|
+
if (opts.withSpan !== undefined) {
|
|
40903
|
+
if (opts.withSpan instanceof AbsoluteSourceSpan) {
|
|
40904
|
+
withSpan = opts.withSpan;
|
|
40905
|
+
}
|
|
40906
|
+
else {
|
|
40907
|
+
withSpan = { start: opts.withSpan.start.offset, end: opts.withSpan.end.offset };
|
|
40908
|
+
}
|
|
40909
|
+
}
|
|
40910
|
+
return withSpan;
|
|
40911
|
+
}
|
|
40912
|
+
/**
|
|
40913
|
+
* Given a `ts.Node` with finds the first node whose matching the criteria specified
|
|
40914
|
+
* by the `FindOptions`.
|
|
40915
|
+
*
|
|
40916
|
+
* Returns `null` when no `ts.Node` matches the given conditions.
|
|
40917
|
+
*/
|
|
40918
|
+
function findFirstMatchingNode(tcb, opts) {
|
|
40919
|
+
const withSpan = getSpanFromOptions(opts);
|
|
40920
|
+
const withExpressionIdentifier = opts.withExpressionIdentifier;
|
|
40921
|
+
const sf = tcb.getSourceFile();
|
|
40922
|
+
const visitor = makeRecursiveVisitor((node) => {
|
|
40923
|
+
if (!opts.filter(node)) {
|
|
40924
|
+
return null;
|
|
40925
|
+
}
|
|
40926
|
+
if (withSpan !== null) {
|
|
40927
|
+
const comment = readSpanComment(node, sf);
|
|
40928
|
+
if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
|
40929
|
+
return null;
|
|
40930
|
+
}
|
|
40931
|
+
}
|
|
40932
|
+
if (withExpressionIdentifier !== undefined &&
|
|
40933
|
+
!hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
|
40934
|
+
return null;
|
|
40935
|
+
}
|
|
40936
|
+
return node;
|
|
40937
|
+
});
|
|
40938
|
+
return tcb.forEachChild(visitor) ?? null;
|
|
40939
|
+
}
|
|
40940
|
+
/**
|
|
40941
|
+
* Given a `ts.Node` with source span comments, finds the first node whose source span comment
|
|
40942
|
+
* matches the given `sourceSpan`. Additionally, the `filter` function allows matching only
|
|
40943
|
+
* `ts.Nodes` of a given type, which provides the ability to select only matches of a given type
|
|
40944
|
+
* when there may be more than one.
|
|
40945
|
+
*
|
|
40946
|
+
* Returns `null` when no `ts.Node` matches the given conditions.
|
|
40947
|
+
*/
|
|
40948
|
+
function findAllMatchingNodes(tcb, opts) {
|
|
40949
|
+
const withSpan = getSpanFromOptions(opts);
|
|
40950
|
+
const withExpressionIdentifier = opts.withExpressionIdentifier;
|
|
40951
|
+
const results = [];
|
|
40952
|
+
const stack = [tcb];
|
|
40953
|
+
const sf = tcb.getSourceFile();
|
|
40954
|
+
while (stack.length > 0) {
|
|
40955
|
+
const node = stack.pop();
|
|
40956
|
+
if (!opts.filter(node)) {
|
|
40957
|
+
stack.push(...node.getChildren());
|
|
40958
|
+
continue;
|
|
40959
|
+
}
|
|
40960
|
+
if (withSpan !== null) {
|
|
40961
|
+
const comment = readSpanComment(node, sf);
|
|
40962
|
+
if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
|
40963
|
+
stack.push(...node.getChildren());
|
|
40964
|
+
continue;
|
|
40965
|
+
}
|
|
40966
|
+
}
|
|
40967
|
+
if (withExpressionIdentifier !== undefined &&
|
|
40968
|
+
!hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
|
40969
|
+
continue;
|
|
40970
|
+
}
|
|
40971
|
+
results.push(node);
|
|
40972
|
+
}
|
|
40973
|
+
return results;
|
|
40974
|
+
}
|
|
40975
|
+
function hasExpressionIdentifier(sourceFile, node, identifier) {
|
|
40976
|
+
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40977
|
+
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40978
|
+
return false;
|
|
40979
|
+
}
|
|
40980
|
+
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40981
|
+
return commentText === `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`;
|
|
40982
|
+
}) || false);
|
|
40983
|
+
}
|
|
40984
|
+
|
|
40985
|
+
/**
|
|
40986
|
+
* A `Set` of `ts.SyntaxKind`s of `ts.Expression` which are safe to wrap in a `ts.AsExpression`
|
|
40987
|
+
* without needing to be wrapped in parentheses.
|
|
40988
|
+
*
|
|
40989
|
+
* For example, `foo.bar()` is a `ts.CallExpression`, and can be safely cast to `any` with
|
|
40990
|
+
* `foo.bar() as any`. however, `foo !== bar` is a `ts.BinaryExpression`, and attempting to cast
|
|
40991
|
+
* without the parentheses yields the expression `foo !== bar as any`. This is semantically
|
|
40992
|
+
* equivalent to `foo !== (bar as any)`, which is not what was intended. Thus,
|
|
40993
|
+
* `ts.BinaryExpression`s need to be wrapped in parentheses before casting.
|
|
40994
|
+
*/
|
|
40995
|
+
//
|
|
40996
|
+
let SAFE_TO_CAST_WITHOUT_PARENS = null;
|
|
40997
|
+
function tsCastToAny(expr) {
|
|
40998
|
+
if (SAFE_TO_CAST_WITHOUT_PARENS === null) {
|
|
40999
|
+
SAFE_TO_CAST_WITHOUT_PARENS = new Set([
|
|
41000
|
+
// Expressions which are already parenthesized can be cast without further wrapping.
|
|
41001
|
+
ts.SyntaxKind.ParenthesizedExpression,
|
|
41002
|
+
// Expressions which form a single lexical unit leave no room for precedence issues with the cast.
|
|
41003
|
+
ts.SyntaxKind.Identifier,
|
|
41004
|
+
ts.SyntaxKind.CallExpression,
|
|
41005
|
+
ts.SyntaxKind.NonNullExpression,
|
|
41006
|
+
ts.SyntaxKind.ElementAccessExpression,
|
|
41007
|
+
ts.SyntaxKind.PropertyAccessExpression,
|
|
41008
|
+
ts.SyntaxKind.ArrayLiteralExpression,
|
|
41009
|
+
ts.SyntaxKind.ObjectLiteralExpression,
|
|
41010
|
+
// The same goes for various literals.
|
|
41011
|
+
ts.SyntaxKind.StringLiteral,
|
|
41012
|
+
ts.SyntaxKind.NumericLiteral,
|
|
41013
|
+
ts.SyntaxKind.TrueKeyword,
|
|
41014
|
+
ts.SyntaxKind.FalseKeyword,
|
|
41015
|
+
ts.SyntaxKind.NullKeyword,
|
|
41016
|
+
ts.SyntaxKind.UndefinedKeyword,
|
|
41017
|
+
]);
|
|
41018
|
+
}
|
|
41019
|
+
// Wrap `expr` in parentheses if needed (see `SAFE_TO_CAST_WITHOUT_PARENS` above).
|
|
41020
|
+
if (!SAFE_TO_CAST_WITHOUT_PARENS.has(expr.kind)) {
|
|
41021
|
+
expr = ts.factory.createParenthesizedExpression(expr);
|
|
41022
|
+
}
|
|
41023
|
+
// The outer expression is always wrapped in parentheses.
|
|
41024
|
+
return ts.factory.createParenthesizedExpression(ts.factory.createAsExpression(expr, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)));
|
|
41025
|
+
}
|
|
41026
|
+
/**
|
|
41027
|
+
* Create an expression which instantiates an element by its HTML tagName.
|
|
41028
|
+
*
|
|
41029
|
+
* Thanks to narrowing of `document.createElement()`, this expression will have its type inferred
|
|
41030
|
+
* based on the tag name, including for custom elements that have appropriate .d.ts definitions.
|
|
41031
|
+
*/
|
|
41032
|
+
function tsCreateElement(...tagNames) {
|
|
41033
|
+
const createElement = ts.factory.createPropertyAccessExpression(
|
|
41034
|
+
/* expression */ ts.factory.createIdentifier('document'), 'createElement');
|
|
41035
|
+
let arg;
|
|
41036
|
+
if (tagNames.length === 1) {
|
|
41037
|
+
// If there's only one tag name, we can pass it in directly.
|
|
41038
|
+
arg = ts.factory.createStringLiteral(tagNames[0]);
|
|
41039
|
+
}
|
|
41040
|
+
else {
|
|
41041
|
+
// If there's more than one name, we have to generate a union of all the tag names. To do so,
|
|
41042
|
+
// create an expression in the form of `null! as 'tag-1' | 'tag-2' | 'tag-3'`. This allows
|
|
41043
|
+
// TypeScript to infer the type as a union of the differnet tags.
|
|
41044
|
+
const assertedNullExpression = ts.factory.createNonNullExpression(ts.factory.createNull());
|
|
41045
|
+
const type = ts.factory.createUnionTypeNode(tagNames.map((tag) => ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(tag))));
|
|
41046
|
+
arg = ts.factory.createAsExpression(assertedNullExpression, type);
|
|
41047
|
+
}
|
|
41048
|
+
return ts.factory.createCallExpression(
|
|
41049
|
+
/* expression */ createElement,
|
|
41050
|
+
/* typeArguments */ undefined,
|
|
41051
|
+
/* argumentsArray */ [arg]);
|
|
41052
|
+
}
|
|
41053
|
+
/**
|
|
41054
|
+
* Create a `ts.VariableStatement` which declares a variable without explicit initialization.
|
|
41055
|
+
*
|
|
41056
|
+
* The initializer `null!` is used to bypass strict variable initialization checks.
|
|
41057
|
+
*
|
|
41058
|
+
* Unlike with `tsCreateVariable`, the type of the variable is explicitly specified.
|
|
41059
|
+
*/
|
|
41060
|
+
function tsDeclareVariable(id, type) {
|
|
41061
|
+
// When we create a variable like `var _t1: boolean = null!`, TypeScript actually infers `_t1`
|
|
41062
|
+
// to be `never`, instead of a `boolean`. To work around it, we cast the value
|
|
41063
|
+
// in the initializer, e.g. `var _t1 = null! as boolean;`.
|
|
41064
|
+
addExpressionIdentifier(type, ExpressionIdentifier.VARIABLE_AS_EXPRESSION);
|
|
41065
|
+
const initializer = ts.factory.createAsExpression(ts.factory.createNonNullExpression(ts.factory.createNull()), type);
|
|
41066
|
+
const decl = ts.factory.createVariableDeclaration(
|
|
41067
|
+
/* name */ id,
|
|
41068
|
+
/* exclamationToken */ undefined,
|
|
41069
|
+
/* type */ undefined,
|
|
41070
|
+
/* initializer */ initializer);
|
|
41071
|
+
return ts.factory.createVariableStatement(
|
|
41072
|
+
/* modifiers */ undefined,
|
|
41073
|
+
/* declarationList */ [decl]);
|
|
41074
|
+
}
|
|
41075
|
+
/**
|
|
41076
|
+
* Creates a `ts.TypeQueryNode` for a coerced input.
|
|
41077
|
+
*
|
|
41078
|
+
* For example: `typeof MatInput.ngAcceptInputType_value`, where MatInput is `typeName` and `value`
|
|
41079
|
+
* is the `coercedInputName`.
|
|
41080
|
+
*
|
|
41081
|
+
* @param typeName The `EntityName` of the Directive where the static coerced input is defined.
|
|
41082
|
+
* @param coercedInputName The field name of the coerced input.
|
|
41083
|
+
*/
|
|
41084
|
+
function tsCreateTypeQueryForCoercedInput(typeName, coercedInputName) {
|
|
41085
|
+
return ts.factory.createTypeQueryNode(ts.factory.createQualifiedName(typeName, `ngAcceptInputType_${coercedInputName}`));
|
|
41086
|
+
}
|
|
41087
|
+
/**
|
|
41088
|
+
* Create a `ts.VariableStatement` that initializes a variable with a given expression.
|
|
41089
|
+
*
|
|
41090
|
+
* Unlike with `tsDeclareVariable`, the type of the variable is inferred from the initializer
|
|
41091
|
+
* expression.
|
|
41092
|
+
*/
|
|
41093
|
+
function tsCreateVariable(id, initializer, flags = null) {
|
|
41094
|
+
const decl = ts.factory.createVariableDeclaration(
|
|
41095
|
+
/* name */ id,
|
|
41096
|
+
/* exclamationToken */ undefined,
|
|
41097
|
+
/* type */ undefined,
|
|
41098
|
+
/* initializer */ initializer);
|
|
41099
|
+
return ts.factory.createVariableStatement(
|
|
41100
|
+
/* modifiers */ undefined,
|
|
41101
|
+
/* declarationList */ flags === null
|
|
41102
|
+
? [decl]
|
|
41103
|
+
: ts.factory.createVariableDeclarationList([decl], flags));
|
|
41104
|
+
}
|
|
41105
|
+
/**
|
|
41106
|
+
* Construct a `ts.CallExpression` that calls a method on a receiver.
|
|
41107
|
+
*/
|
|
41108
|
+
function tsCallMethod(receiver, methodName, args = []) {
|
|
41109
|
+
const methodAccess = ts.factory.createPropertyAccessExpression(receiver, methodName);
|
|
41110
|
+
return ts.factory.createCallExpression(
|
|
41111
|
+
/* expression */ methodAccess,
|
|
41112
|
+
/* typeArguments */ undefined,
|
|
41113
|
+
/* argumentsArray */ args);
|
|
41114
|
+
}
|
|
41115
|
+
function isAccessExpression(node) {
|
|
41116
|
+
return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node);
|
|
41117
|
+
}
|
|
41118
|
+
/**
|
|
41119
|
+
* Creates a TypeScript node representing a numeric value.
|
|
41120
|
+
*/
|
|
41121
|
+
function tsNumericExpression(value) {
|
|
41122
|
+
// As of TypeScript 5.3 negative numbers are represented as `prefixUnaryOperator` and passing a
|
|
41123
|
+
// negative number (even as a string) into `createNumericLiteral` will result in an error.
|
|
41124
|
+
if (value < 0) {
|
|
41125
|
+
const operand = ts.factory.createNumericLiteral(Math.abs(value));
|
|
41126
|
+
return ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, operand);
|
|
41127
|
+
}
|
|
41128
|
+
return ts.factory.createNumericLiteral(value);
|
|
41129
|
+
}
|
|
41130
|
+
/**
|
|
41131
|
+
* Check if a node represents a directive declaration in a TypeCheck Block.
|
|
41132
|
+
* Directive declarations can be either:
|
|
41133
|
+
* - var _t1: TestDir /*T:D*\/ = null! as TestDir;
|
|
41134
|
+
* - var _t1 /*T:D*\/ = _ctor1({});
|
|
41135
|
+
*/
|
|
41136
|
+
function isDirectiveDeclaration(node) {
|
|
41137
|
+
const sourceFile = node.getSourceFile();
|
|
41138
|
+
return ((ts.isTypeNode(node) || ts.isIdentifier(node)) &&
|
|
41139
|
+
ts.isVariableDeclaration(node.parent) &&
|
|
41140
|
+
hasExpressionIdentifier(sourceFile, node, ExpressionIdentifier.DIRECTIVE));
|
|
41141
|
+
}
|
|
41142
|
+
|
|
40278
41143
|
const NgOriginalFile = Symbol('NgOriginalFile');
|
|
40279
41144
|
exports.UpdateMode = void 0;
|
|
40280
41145
|
(function (UpdateMode) {
|
|
@@ -40463,12 +41328,13 @@ exports.SymbolKind = void 0;
|
|
|
40463
41328
|
|
|
40464
41329
|
/**
|
|
40465
41330
|
* Constructs a `ts.Diagnostic` for a given `ParseSourceSpan` within a template.
|
|
41331
|
+
*
|
|
41332
|
+
* @param deprecatedDiagInfo Optional information about deprecation and related messages.
|
|
40466
41333
|
*/
|
|
40467
|
-
function makeTemplateDiagnostic(id, mapping, span, category, code, messageText, relatedMessages) {
|
|
41334
|
+
function makeTemplateDiagnostic(id, mapping, span, category, code, messageText, relatedMessages, deprecatedDiagInfo) {
|
|
40468
41335
|
if (mapping.type === 'direct') {
|
|
40469
|
-
let relatedInformation =
|
|
41336
|
+
let relatedInformation = [];
|
|
40470
41337
|
if (relatedMessages !== undefined) {
|
|
40471
|
-
relatedInformation = [];
|
|
40472
41338
|
for (const relatedMessage of relatedMessages) {
|
|
40473
41339
|
relatedInformation.push({
|
|
40474
41340
|
category: ts.DiagnosticCategory.Message,
|
|
@@ -40480,6 +41346,9 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40480
41346
|
});
|
|
40481
41347
|
}
|
|
40482
41348
|
}
|
|
41349
|
+
if (deprecatedDiagInfo !== undefined) {
|
|
41350
|
+
relatedInformation.push(...(deprecatedDiagInfo.relatedMessages ?? []));
|
|
41351
|
+
}
|
|
40483
41352
|
// For direct mappings, the error is shown inline as ngtsc was able to pinpoint a string
|
|
40484
41353
|
// constant within the `@Component` decorator for the template. This allows us to map the error
|
|
40485
41354
|
// directly into the bytes of the source file.
|
|
@@ -40494,6 +41363,7 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40494
41363
|
start: span.start.offset,
|
|
40495
41364
|
length: span.end.offset - span.start.offset,
|
|
40496
41365
|
relatedInformation,
|
|
41366
|
+
reportsDeprecated: deprecatedDiagInfo?.reportsDeprecated,
|
|
40497
41367
|
};
|
|
40498
41368
|
}
|
|
40499
41369
|
else if (mapping.type === 'indirect' || mapping.type === 'external') {
|
|
@@ -40538,6 +41408,7 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40538
41408
|
start: mapping.node.getStart(),
|
|
40539
41409
|
length: mapping.node.getEnd() - mapping.node.getStart(),
|
|
40540
41410
|
relatedInformation,
|
|
41411
|
+
reportsDeprecated: deprecatedDiagInfo?.reportsDeprecated,
|
|
40541
41412
|
};
|
|
40542
41413
|
}
|
|
40543
41414
|
let typeForMessage;
|
|
@@ -40553,6 +41424,9 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40553
41424
|
else {
|
|
40554
41425
|
typeForMessage = 'Error';
|
|
40555
41426
|
}
|
|
41427
|
+
if (deprecatedDiagInfo !== undefined) {
|
|
41428
|
+
relatedInformation.push(...(deprecatedDiagInfo.relatedMessages ?? []));
|
|
41429
|
+
}
|
|
40556
41430
|
relatedInformation.push({
|
|
40557
41431
|
category: ts.DiagnosticCategory.Message,
|
|
40558
41432
|
code: 0,
|
|
@@ -40575,6 +41449,7 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40575
41449
|
length: span.end.offset - span.start.offset,
|
|
40576
41450
|
// Show a secondary message indicating the component whose template contains the error.
|
|
40577
41451
|
relatedInformation,
|
|
41452
|
+
reportsDeprecated: deprecatedDiagInfo?.reportsDeprecated,
|
|
40578
41453
|
};
|
|
40579
41454
|
}
|
|
40580
41455
|
else {
|
|
@@ -40607,156 +41482,6 @@ function getTypeCheckId$1(clazz) {
|
|
|
40607
41482
|
return sf[TYPE_CHECK_ID_MAP].get(clazz);
|
|
40608
41483
|
}
|
|
40609
41484
|
|
|
40610
|
-
const parseSpanComment = /^(\d+),(\d+)$/;
|
|
40611
|
-
/**
|
|
40612
|
-
* Reads the trailing comments and finds the first match which is a span comment (i.e. 4,10) on a
|
|
40613
|
-
* node and returns it as an `AbsoluteSourceSpan`.
|
|
40614
|
-
*
|
|
40615
|
-
* Will return `null` if no trailing comments on the node match the expected form of a source span.
|
|
40616
|
-
*/
|
|
40617
|
-
function readSpanComment(node, sourceFile = node.getSourceFile()) {
|
|
40618
|
-
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40619
|
-
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40620
|
-
return null;
|
|
40621
|
-
}
|
|
40622
|
-
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40623
|
-
const match = commentText.match(parseSpanComment);
|
|
40624
|
-
if (match === null) {
|
|
40625
|
-
return null;
|
|
40626
|
-
}
|
|
40627
|
-
return new AbsoluteSourceSpan(+match[1], +match[2]);
|
|
40628
|
-
}) || null);
|
|
40629
|
-
}
|
|
40630
|
-
/** Used to identify what type the comment is. */
|
|
40631
|
-
var CommentTriviaType;
|
|
40632
|
-
(function (CommentTriviaType) {
|
|
40633
|
-
CommentTriviaType["DIAGNOSTIC"] = "D";
|
|
40634
|
-
CommentTriviaType["EXPRESSION_TYPE_IDENTIFIER"] = "T";
|
|
40635
|
-
})(CommentTriviaType || (CommentTriviaType = {}));
|
|
40636
|
-
/** Identifies what the TCB expression is for (for example, a directive declaration). */
|
|
40637
|
-
var ExpressionIdentifier;
|
|
40638
|
-
(function (ExpressionIdentifier) {
|
|
40639
|
-
ExpressionIdentifier["DIRECTIVE"] = "DIR";
|
|
40640
|
-
ExpressionIdentifier["COMPONENT_COMPLETION"] = "COMPCOMP";
|
|
40641
|
-
ExpressionIdentifier["EVENT_PARAMETER"] = "EP";
|
|
40642
|
-
ExpressionIdentifier["VARIABLE_AS_EXPRESSION"] = "VAE";
|
|
40643
|
-
})(ExpressionIdentifier || (ExpressionIdentifier = {}));
|
|
40644
|
-
/** Tags the node with the given expression identifier. */
|
|
40645
|
-
function addExpressionIdentifier(node, identifier) {
|
|
40646
|
-
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`,
|
|
40647
|
-
/* hasTrailingNewLine */ false);
|
|
40648
|
-
}
|
|
40649
|
-
const IGNORE_FOR_DIAGNOSTICS_MARKER = `${CommentTriviaType.DIAGNOSTIC}:ignore`;
|
|
40650
|
-
/**
|
|
40651
|
-
* Tag the `ts.Node` with an indication that any errors arising from the evaluation of the node
|
|
40652
|
-
* should be ignored.
|
|
40653
|
-
*/
|
|
40654
|
-
function markIgnoreDiagnostics(node) {
|
|
40655
|
-
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, IGNORE_FOR_DIAGNOSTICS_MARKER,
|
|
40656
|
-
/* hasTrailingNewLine */ false);
|
|
40657
|
-
}
|
|
40658
|
-
/** Returns true if the node has a marker that indicates diagnostics errors should be ignored. */
|
|
40659
|
-
function hasIgnoreForDiagnosticsMarker(node, sourceFile) {
|
|
40660
|
-
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40661
|
-
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40662
|
-
return null;
|
|
40663
|
-
}
|
|
40664
|
-
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40665
|
-
return commentText === IGNORE_FOR_DIAGNOSTICS_MARKER;
|
|
40666
|
-
}) === true);
|
|
40667
|
-
}
|
|
40668
|
-
function makeRecursiveVisitor(visitor) {
|
|
40669
|
-
function recursiveVisitor(node) {
|
|
40670
|
-
const res = visitor(node);
|
|
40671
|
-
return res !== null ? res : node.forEachChild(recursiveVisitor);
|
|
40672
|
-
}
|
|
40673
|
-
return recursiveVisitor;
|
|
40674
|
-
}
|
|
40675
|
-
function getSpanFromOptions(opts) {
|
|
40676
|
-
let withSpan = null;
|
|
40677
|
-
if (opts.withSpan !== undefined) {
|
|
40678
|
-
if (opts.withSpan instanceof AbsoluteSourceSpan) {
|
|
40679
|
-
withSpan = opts.withSpan;
|
|
40680
|
-
}
|
|
40681
|
-
else {
|
|
40682
|
-
withSpan = { start: opts.withSpan.start.offset, end: opts.withSpan.end.offset };
|
|
40683
|
-
}
|
|
40684
|
-
}
|
|
40685
|
-
return withSpan;
|
|
40686
|
-
}
|
|
40687
|
-
/**
|
|
40688
|
-
* Given a `ts.Node` with finds the first node whose matching the criteria specified
|
|
40689
|
-
* by the `FindOptions`.
|
|
40690
|
-
*
|
|
40691
|
-
* Returns `null` when no `ts.Node` matches the given conditions.
|
|
40692
|
-
*/
|
|
40693
|
-
function findFirstMatchingNode(tcb, opts) {
|
|
40694
|
-
const withSpan = getSpanFromOptions(opts);
|
|
40695
|
-
const withExpressionIdentifier = opts.withExpressionIdentifier;
|
|
40696
|
-
const sf = tcb.getSourceFile();
|
|
40697
|
-
const visitor = makeRecursiveVisitor((node) => {
|
|
40698
|
-
if (!opts.filter(node)) {
|
|
40699
|
-
return null;
|
|
40700
|
-
}
|
|
40701
|
-
if (withSpan !== null) {
|
|
40702
|
-
const comment = readSpanComment(node, sf);
|
|
40703
|
-
if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
|
40704
|
-
return null;
|
|
40705
|
-
}
|
|
40706
|
-
}
|
|
40707
|
-
if (withExpressionIdentifier !== undefined &&
|
|
40708
|
-
!hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
|
40709
|
-
return null;
|
|
40710
|
-
}
|
|
40711
|
-
return node;
|
|
40712
|
-
});
|
|
40713
|
-
return tcb.forEachChild(visitor) ?? null;
|
|
40714
|
-
}
|
|
40715
|
-
/**
|
|
40716
|
-
* Given a `ts.Node` with source span comments, finds the first node whose source span comment
|
|
40717
|
-
* matches the given `sourceSpan`. Additionally, the `filter` function allows matching only
|
|
40718
|
-
* `ts.Nodes` of a given type, which provides the ability to select only matches of a given type
|
|
40719
|
-
* when there may be more than one.
|
|
40720
|
-
*
|
|
40721
|
-
* Returns `null` when no `ts.Node` matches the given conditions.
|
|
40722
|
-
*/
|
|
40723
|
-
function findAllMatchingNodes(tcb, opts) {
|
|
40724
|
-
const withSpan = getSpanFromOptions(opts);
|
|
40725
|
-
const withExpressionIdentifier = opts.withExpressionIdentifier;
|
|
40726
|
-
const results = [];
|
|
40727
|
-
const stack = [tcb];
|
|
40728
|
-
const sf = tcb.getSourceFile();
|
|
40729
|
-
while (stack.length > 0) {
|
|
40730
|
-
const node = stack.pop();
|
|
40731
|
-
if (!opts.filter(node)) {
|
|
40732
|
-
stack.push(...node.getChildren());
|
|
40733
|
-
continue;
|
|
40734
|
-
}
|
|
40735
|
-
if (withSpan !== null) {
|
|
40736
|
-
const comment = readSpanComment(node, sf);
|
|
40737
|
-
if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
|
40738
|
-
stack.push(...node.getChildren());
|
|
40739
|
-
continue;
|
|
40740
|
-
}
|
|
40741
|
-
}
|
|
40742
|
-
if (withExpressionIdentifier !== undefined &&
|
|
40743
|
-
!hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
|
40744
|
-
continue;
|
|
40745
|
-
}
|
|
40746
|
-
results.push(node);
|
|
40747
|
-
}
|
|
40748
|
-
return results;
|
|
40749
|
-
}
|
|
40750
|
-
function hasExpressionIdentifier(sourceFile, node, identifier) {
|
|
40751
|
-
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40752
|
-
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40753
|
-
return false;
|
|
40754
|
-
}
|
|
40755
|
-
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40756
|
-
return commentText === `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`;
|
|
40757
|
-
}) || false);
|
|
40758
|
-
}
|
|
40759
|
-
|
|
40760
41485
|
/**
|
|
40761
41486
|
* Powers autocompletion for a specific component.
|
|
40762
41487
|
*
|
|
@@ -42473,152 +43198,6 @@ class ReferenceEmitEnvironment {
|
|
|
42473
43198
|
}
|
|
42474
43199
|
}
|
|
42475
43200
|
|
|
42476
|
-
/**
|
|
42477
|
-
* A `Set` of `ts.SyntaxKind`s of `ts.Expression` which are safe to wrap in a `ts.AsExpression`
|
|
42478
|
-
* without needing to be wrapped in parentheses.
|
|
42479
|
-
*
|
|
42480
|
-
* For example, `foo.bar()` is a `ts.CallExpression`, and can be safely cast to `any` with
|
|
42481
|
-
* `foo.bar() as any`. however, `foo !== bar` is a `ts.BinaryExpression`, and attempting to cast
|
|
42482
|
-
* without the parentheses yields the expression `foo !== bar as any`. This is semantically
|
|
42483
|
-
* equivalent to `foo !== (bar as any)`, which is not what was intended. Thus,
|
|
42484
|
-
* `ts.BinaryExpression`s need to be wrapped in parentheses before casting.
|
|
42485
|
-
*/
|
|
42486
|
-
//
|
|
42487
|
-
let SAFE_TO_CAST_WITHOUT_PARENS = null;
|
|
42488
|
-
function tsCastToAny(expr) {
|
|
42489
|
-
if (SAFE_TO_CAST_WITHOUT_PARENS === null) {
|
|
42490
|
-
SAFE_TO_CAST_WITHOUT_PARENS = new Set([
|
|
42491
|
-
// Expressions which are already parenthesized can be cast without further wrapping.
|
|
42492
|
-
ts.SyntaxKind.ParenthesizedExpression,
|
|
42493
|
-
// Expressions which form a single lexical unit leave no room for precedence issues with the cast.
|
|
42494
|
-
ts.SyntaxKind.Identifier,
|
|
42495
|
-
ts.SyntaxKind.CallExpression,
|
|
42496
|
-
ts.SyntaxKind.NonNullExpression,
|
|
42497
|
-
ts.SyntaxKind.ElementAccessExpression,
|
|
42498
|
-
ts.SyntaxKind.PropertyAccessExpression,
|
|
42499
|
-
ts.SyntaxKind.ArrayLiteralExpression,
|
|
42500
|
-
ts.SyntaxKind.ObjectLiteralExpression,
|
|
42501
|
-
// The same goes for various literals.
|
|
42502
|
-
ts.SyntaxKind.StringLiteral,
|
|
42503
|
-
ts.SyntaxKind.NumericLiteral,
|
|
42504
|
-
ts.SyntaxKind.TrueKeyword,
|
|
42505
|
-
ts.SyntaxKind.FalseKeyword,
|
|
42506
|
-
ts.SyntaxKind.NullKeyword,
|
|
42507
|
-
ts.SyntaxKind.UndefinedKeyword,
|
|
42508
|
-
]);
|
|
42509
|
-
}
|
|
42510
|
-
// Wrap `expr` in parentheses if needed (see `SAFE_TO_CAST_WITHOUT_PARENS` above).
|
|
42511
|
-
if (!SAFE_TO_CAST_WITHOUT_PARENS.has(expr.kind)) {
|
|
42512
|
-
expr = ts.factory.createParenthesizedExpression(expr);
|
|
42513
|
-
}
|
|
42514
|
-
// The outer expression is always wrapped in parentheses.
|
|
42515
|
-
return ts.factory.createParenthesizedExpression(ts.factory.createAsExpression(expr, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)));
|
|
42516
|
-
}
|
|
42517
|
-
/**
|
|
42518
|
-
* Create an expression which instantiates an element by its HTML tagName.
|
|
42519
|
-
*
|
|
42520
|
-
* Thanks to narrowing of `document.createElement()`, this expression will have its type inferred
|
|
42521
|
-
* based on the tag name, including for custom elements that have appropriate .d.ts definitions.
|
|
42522
|
-
*/
|
|
42523
|
-
function tsCreateElement(...tagNames) {
|
|
42524
|
-
const createElement = ts.factory.createPropertyAccessExpression(
|
|
42525
|
-
/* expression */ ts.factory.createIdentifier('document'), 'createElement');
|
|
42526
|
-
let arg;
|
|
42527
|
-
if (tagNames.length === 1) {
|
|
42528
|
-
// If there's only one tag name, we can pass it in directly.
|
|
42529
|
-
arg = ts.factory.createStringLiteral(tagNames[0]);
|
|
42530
|
-
}
|
|
42531
|
-
else {
|
|
42532
|
-
// If there's more than one name, we have to generate a union of all the tag names. To do so,
|
|
42533
|
-
// create an expression in the form of `null! as 'tag-1' | 'tag-2' | 'tag-3'`. This allows
|
|
42534
|
-
// TypeScript to infer the type as a union of the differnet tags.
|
|
42535
|
-
const assertedNullExpression = ts.factory.createNonNullExpression(ts.factory.createNull());
|
|
42536
|
-
const type = ts.factory.createUnionTypeNode(tagNames.map((tag) => ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(tag))));
|
|
42537
|
-
arg = ts.factory.createAsExpression(assertedNullExpression, type);
|
|
42538
|
-
}
|
|
42539
|
-
return ts.factory.createCallExpression(
|
|
42540
|
-
/* expression */ createElement,
|
|
42541
|
-
/* typeArguments */ undefined,
|
|
42542
|
-
/* argumentsArray */ [arg]);
|
|
42543
|
-
}
|
|
42544
|
-
/**
|
|
42545
|
-
* Create a `ts.VariableStatement` which declares a variable without explicit initialization.
|
|
42546
|
-
*
|
|
42547
|
-
* The initializer `null!` is used to bypass strict variable initialization checks.
|
|
42548
|
-
*
|
|
42549
|
-
* Unlike with `tsCreateVariable`, the type of the variable is explicitly specified.
|
|
42550
|
-
*/
|
|
42551
|
-
function tsDeclareVariable(id, type) {
|
|
42552
|
-
// When we create a variable like `var _t1: boolean = null!`, TypeScript actually infers `_t1`
|
|
42553
|
-
// to be `never`, instead of a `boolean`. To work around it, we cast the value
|
|
42554
|
-
// in the initializer, e.g. `var _t1 = null! as boolean;`.
|
|
42555
|
-
addExpressionIdentifier(type, ExpressionIdentifier.VARIABLE_AS_EXPRESSION);
|
|
42556
|
-
const initializer = ts.factory.createAsExpression(ts.factory.createNonNullExpression(ts.factory.createNull()), type);
|
|
42557
|
-
const decl = ts.factory.createVariableDeclaration(
|
|
42558
|
-
/* name */ id,
|
|
42559
|
-
/* exclamationToken */ undefined,
|
|
42560
|
-
/* type */ undefined,
|
|
42561
|
-
/* initializer */ initializer);
|
|
42562
|
-
return ts.factory.createVariableStatement(
|
|
42563
|
-
/* modifiers */ undefined,
|
|
42564
|
-
/* declarationList */ [decl]);
|
|
42565
|
-
}
|
|
42566
|
-
/**
|
|
42567
|
-
* Creates a `ts.TypeQueryNode` for a coerced input.
|
|
42568
|
-
*
|
|
42569
|
-
* For example: `typeof MatInput.ngAcceptInputType_value`, where MatInput is `typeName` and `value`
|
|
42570
|
-
* is the `coercedInputName`.
|
|
42571
|
-
*
|
|
42572
|
-
* @param typeName The `EntityName` of the Directive where the static coerced input is defined.
|
|
42573
|
-
* @param coercedInputName The field name of the coerced input.
|
|
42574
|
-
*/
|
|
42575
|
-
function tsCreateTypeQueryForCoercedInput(typeName, coercedInputName) {
|
|
42576
|
-
return ts.factory.createTypeQueryNode(ts.factory.createQualifiedName(typeName, `ngAcceptInputType_${coercedInputName}`));
|
|
42577
|
-
}
|
|
42578
|
-
/**
|
|
42579
|
-
* Create a `ts.VariableStatement` that initializes a variable with a given expression.
|
|
42580
|
-
*
|
|
42581
|
-
* Unlike with `tsDeclareVariable`, the type of the variable is inferred from the initializer
|
|
42582
|
-
* expression.
|
|
42583
|
-
*/
|
|
42584
|
-
function tsCreateVariable(id, initializer, flags = null) {
|
|
42585
|
-
const decl = ts.factory.createVariableDeclaration(
|
|
42586
|
-
/* name */ id,
|
|
42587
|
-
/* exclamationToken */ undefined,
|
|
42588
|
-
/* type */ undefined,
|
|
42589
|
-
/* initializer */ initializer);
|
|
42590
|
-
return ts.factory.createVariableStatement(
|
|
42591
|
-
/* modifiers */ undefined,
|
|
42592
|
-
/* declarationList */ flags === null
|
|
42593
|
-
? [decl]
|
|
42594
|
-
: ts.factory.createVariableDeclarationList([decl], flags));
|
|
42595
|
-
}
|
|
42596
|
-
/**
|
|
42597
|
-
* Construct a `ts.CallExpression` that calls a method on a receiver.
|
|
42598
|
-
*/
|
|
42599
|
-
function tsCallMethod(receiver, methodName, args = []) {
|
|
42600
|
-
const methodAccess = ts.factory.createPropertyAccessExpression(receiver, methodName);
|
|
42601
|
-
return ts.factory.createCallExpression(
|
|
42602
|
-
/* expression */ methodAccess,
|
|
42603
|
-
/* typeArguments */ undefined,
|
|
42604
|
-
/* argumentsArray */ args);
|
|
42605
|
-
}
|
|
42606
|
-
function isAccessExpression(node) {
|
|
42607
|
-
return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node);
|
|
42608
|
-
}
|
|
42609
|
-
/**
|
|
42610
|
-
* Creates a TypeScript node representing a numeric value.
|
|
42611
|
-
*/
|
|
42612
|
-
function tsNumericExpression(value) {
|
|
42613
|
-
// As of TypeScript 5.3 negative numbers are represented as `prefixUnaryOperator` and passing a
|
|
42614
|
-
// negative number (even as a string) into `createNumericLiteral` will result in an error.
|
|
42615
|
-
if (value < 0) {
|
|
42616
|
-
const operand = ts.factory.createNumericLiteral(Math.abs(value));
|
|
42617
|
-
return ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, operand);
|
|
42618
|
-
}
|
|
42619
|
-
return ts.factory.createNumericLiteral(value);
|
|
42620
|
-
}
|
|
42621
|
-
|
|
42622
43201
|
/**
|
|
42623
43202
|
* See `TypeEmitter` for more information on the emitting process.
|
|
42624
43203
|
*/
|
|
@@ -42971,7 +43550,8 @@ function inferBoundAttribute(name) {
|
|
|
42971
43550
|
const attrPrefix = 'attr.';
|
|
42972
43551
|
const classPrefix = 'class.';
|
|
42973
43552
|
const stylePrefix = 'style.';
|
|
42974
|
-
const animationPrefix = '
|
|
43553
|
+
const animationPrefix = 'animate.';
|
|
43554
|
+
const legacyAnimationPrefix = '@';
|
|
42975
43555
|
let attrName;
|
|
42976
43556
|
let type;
|
|
42977
43557
|
// Infer the binding type based on the prefix.
|
|
@@ -42988,7 +43568,11 @@ function inferBoundAttribute(name) {
|
|
|
42988
43568
|
type = exports.BindingType.Style;
|
|
42989
43569
|
}
|
|
42990
43570
|
else if (name.startsWith(animationPrefix)) {
|
|
42991
|
-
attrName = name
|
|
43571
|
+
attrName = name;
|
|
43572
|
+
type = exports.BindingType.Animation;
|
|
43573
|
+
}
|
|
43574
|
+
else if (name.startsWith(legacyAnimationPrefix)) {
|
|
43575
|
+
attrName = name.slice(legacyAnimationPrefix.length);
|
|
42992
43576
|
type = exports.BindingType.LegacyAnimation;
|
|
42993
43577
|
}
|
|
42994
43578
|
else {
|
|
@@ -43993,7 +44577,12 @@ function translateDiagnostic(diagnostic, resolver) {
|
|
|
43993
44577
|
return null;
|
|
43994
44578
|
}
|
|
43995
44579
|
const { sourceLocation, sourceMapping: templateSourceMapping, span } = fullMapping;
|
|
43996
|
-
return makeTemplateDiagnostic(sourceLocation.id, templateSourceMapping, span, diagnostic.category, diagnostic.code, diagnostic.messageText
|
|
44580
|
+
return makeTemplateDiagnostic(sourceLocation.id, templateSourceMapping, span, diagnostic.category, diagnostic.code, diagnostic.messageText, undefined, diagnostic.reportsDeprecated !== undefined
|
|
44581
|
+
? {
|
|
44582
|
+
reportsDeprecated: diagnostic.reportsDeprecated,
|
|
44583
|
+
relatedMessages: diagnostic.relatedInformation,
|
|
44584
|
+
}
|
|
44585
|
+
: undefined);
|
|
43997
44586
|
}
|
|
43998
44587
|
|
|
43999
44588
|
/**
|
|
@@ -45351,7 +45940,7 @@ class TcbDomSchemaCheckerOp extends TcbOp {
|
|
|
45351
45940
|
}
|
|
45352
45941
|
if (isPropertyBinding && binding.name !== 'style' && binding.name !== 'class') {
|
|
45353
45942
|
// A direct binding to a property.
|
|
45354
|
-
const propertyName =
|
|
45943
|
+
const propertyName = REGISTRY$1.getMappedPropName(binding.name);
|
|
45355
45944
|
if (isTemplateElement) {
|
|
45356
45945
|
this.tcb.domSchemaChecker.checkTemplateElementProperty(this.tcb.id, this.getTagName(element), propertyName, binding.sourceSpan, this.tcb.schemas, this.tcb.hostIsStandalone);
|
|
45357
45946
|
}
|
|
@@ -45523,18 +46112,6 @@ class TcbComponentNodeOp extends TcbOp {
|
|
|
45523
46112
|
return id;
|
|
45524
46113
|
}
|
|
45525
46114
|
}
|
|
45526
|
-
/**
|
|
45527
|
-
* Mapping between attributes names that don't correspond to their element property names.
|
|
45528
|
-
* Note: this mapping has to be kept in sync with the equally named mapping in the runtime.
|
|
45529
|
-
*/
|
|
45530
|
-
const ATTR_TO_PROP = new Map(Object.entries({
|
|
45531
|
-
'class': 'className',
|
|
45532
|
-
'for': 'htmlFor',
|
|
45533
|
-
'formaction': 'formAction',
|
|
45534
|
-
'innerHtml': 'innerHTML',
|
|
45535
|
-
'readonly': 'readOnly',
|
|
45536
|
-
'tabindex': 'tabIndex',
|
|
45537
|
-
}));
|
|
45538
46115
|
/**
|
|
45539
46116
|
* A `TcbOp` which generates code to check "unclaimed inputs" - bindings on an element which were
|
|
45540
46117
|
* not attributed to any directive or component, and are instead processed against the HTML element
|
|
@@ -45580,7 +46157,7 @@ class TcbUnclaimedInputsOp extends TcbOp {
|
|
|
45580
46157
|
elId = this.scope.resolve(this.target);
|
|
45581
46158
|
}
|
|
45582
46159
|
// A direct binding to a property.
|
|
45583
|
-
const propertyName =
|
|
46160
|
+
const propertyName = REGISTRY$1.getMappedPropName(binding.name);
|
|
45584
46161
|
const prop = ts.factory.createElementAccessExpression(elId, ts.factory.createStringLiteral(propertyName));
|
|
45585
46162
|
const stmt = ts.factory.createBinaryExpression(prop, ts.SyntaxKind.EqualsToken, wrapForDiagnostics(expr));
|
|
45586
46163
|
addParseSpanInfo(stmt, binding.sourceSpan);
|
|
@@ -45718,14 +46295,19 @@ class TcbUnclaimedOutputsOp extends TcbOp {
|
|
|
45718
46295
|
const handler = tcbCreateEventHandler(output, this.tcb, this.scope, eventType);
|
|
45719
46296
|
this.scope.addStatement(ts.factory.createExpressionStatement(handler));
|
|
45720
46297
|
}
|
|
46298
|
+
else if (output.type === exports.ParsedEventType.Animation) {
|
|
46299
|
+
const eventType = this.tcb.env.referenceExternalType('@angular/core', 'AnimationCallbackEvent');
|
|
46300
|
+
const handler = tcbCreateEventHandler(output, this.tcb, this.scope, eventType);
|
|
46301
|
+
this.scope.addStatement(ts.factory.createExpressionStatement(handler));
|
|
46302
|
+
}
|
|
45721
46303
|
else if (this.tcb.env.config.checkTypeOfDomEvents) {
|
|
45722
46304
|
// If strict checking of DOM events is enabled, generate a call to `addEventListener` on
|
|
45723
46305
|
// the element instance so that TypeScript's type inference for
|
|
45724
46306
|
// `HTMLElement.addEventListener` using `HTMLElementEventMap` to infer an accurate type for
|
|
45725
46307
|
// `$event` depending on the event name. For unknown event names, TypeScript resorts to the
|
|
45726
46308
|
// base `Event` type.
|
|
45727
|
-
const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 0 /* EventParamType.Infer */);
|
|
45728
46309
|
let target;
|
|
46310
|
+
let domEventAssertion;
|
|
45729
46311
|
// Only check for `window` and `document` since in theory any target can be passed.
|
|
45730
46312
|
if (output.target === 'window' || output.target === 'document') {
|
|
45731
46313
|
target = ts.factory.createIdentifier(output.target);
|
|
@@ -45736,8 +46318,32 @@ class TcbUnclaimedOutputsOp extends TcbOp {
|
|
|
45736
46318
|
else {
|
|
45737
46319
|
target = elId;
|
|
45738
46320
|
}
|
|
46321
|
+
// By default the target of an event is `EventTarget | null`, because of bubbling
|
|
46322
|
+
// and custom events. This can be inconvenient in some common cases like `input` elements
|
|
46323
|
+
// since we don't have the ability to type cast in templates. We can improve the type
|
|
46324
|
+
// checking for some of these cases by inferring the target based on the element it was
|
|
46325
|
+
// bound to. We can only do this safely if the element is a void element (e.g. `input` or
|
|
46326
|
+
// `img`), because we know that it couldn't have bubbled from a child. The event handler
|
|
46327
|
+
// with the assertion would look as follows:
|
|
46328
|
+
//
|
|
46329
|
+
// ```
|
|
46330
|
+
// const _t1 = document.createElement('input');
|
|
46331
|
+
//
|
|
46332
|
+
// _t1.addEventListener('input', ($event) => {
|
|
46333
|
+
// ɵassertType<typeof _t1>($event.target);
|
|
46334
|
+
// handler($event.target);
|
|
46335
|
+
// });
|
|
46336
|
+
// ```
|
|
46337
|
+
if (this.target instanceof Element$1 &&
|
|
46338
|
+
this.target.isVoid &&
|
|
46339
|
+
ts.isIdentifier(target)) {
|
|
46340
|
+
domEventAssertion = ts.factory.createCallExpression(this.tcb.env.referenceExternalSymbol('@angular/core', 'ɵassertType'), [ts.factory.createTypeQueryNode(target)], [
|
|
46341
|
+
ts.factory.createPropertyAccessExpression(ts.factory.createIdentifier(EVENT_PARAMETER), 'target'),
|
|
46342
|
+
]);
|
|
46343
|
+
}
|
|
45739
46344
|
const propertyAccess = ts.factory.createPropertyAccessExpression(target, 'addEventListener');
|
|
45740
46345
|
addParseSpanInfo(propertyAccess, output.keySpan);
|
|
46346
|
+
const handler = tcbCreateEventHandler(output, this.tcb, this.scope, 0 /* EventParamType.Infer */, domEventAssertion);
|
|
45741
46347
|
const call = ts.factory.createCallExpression(
|
|
45742
46348
|
/* expression */ propertyAccess,
|
|
45743
46349
|
/* typeArguments */ undefined,
|
|
@@ -47168,9 +47774,12 @@ const EVENT_PARAMETER = '$event';
|
|
|
47168
47774
|
* parameter will have an explicit `any` type, effectively disabling strict type checking of event
|
|
47169
47775
|
* bindings. Alternatively, an explicit type can be passed for the `$event` parameter.
|
|
47170
47776
|
*/
|
|
47171
|
-
function tcbCreateEventHandler(event, tcb, scope, eventType) {
|
|
47777
|
+
function tcbCreateEventHandler(event, tcb, scope, eventType, assertionExpression) {
|
|
47172
47778
|
const handler = tcbEventHandlerExpression(event.handler, tcb, scope);
|
|
47173
47779
|
const statements = [];
|
|
47780
|
+
if (assertionExpression !== undefined) {
|
|
47781
|
+
statements.push(ts.factory.createExpressionStatement(assertionExpression));
|
|
47782
|
+
}
|
|
47174
47783
|
// TODO(crisbeto): remove the `checkTwoWayBoundEvents` check in v20.
|
|
47175
47784
|
if (event.type === exports.ParsedEventType.TwoWay && tcb.env.config.checkTwoWayBoundEvents) {
|
|
47176
47785
|
// If we're dealing with a two-way event, we create a variable initialized to the unwrapped
|
|
@@ -48016,13 +48625,6 @@ class SymbolBuilder {
|
|
|
48016
48625
|
}
|
|
48017
48626
|
getDirectivesOfNode(templateNode) {
|
|
48018
48627
|
const elementSourceSpan = templateNode.startSourceSpan ?? templateNode.sourceSpan;
|
|
48019
|
-
const tcbSourceFile = this.typeCheckBlock.getSourceFile();
|
|
48020
|
-
// directives could be either:
|
|
48021
|
-
// - var _t1: TestDir /*T:D*/ = null! as TestDir;
|
|
48022
|
-
// - var _t1 /*T:D*/ = _ctor1({});
|
|
48023
|
-
const isDirectiveDeclaration = (node) => (ts.isTypeNode(node) || ts.isIdentifier(node)) &&
|
|
48024
|
-
ts.isVariableDeclaration(node.parent) &&
|
|
48025
|
-
hasExpressionIdentifier(tcbSourceFile, node, ExpressionIdentifier.DIRECTIVE);
|
|
48026
48628
|
const nodes = findAllMatchingNodes(this.typeCheckBlock, {
|
|
48027
48629
|
withSpan: elementSourceSpan,
|
|
48028
48630
|
filter: isDirectiveDeclaration,
|
|
@@ -48886,6 +49488,29 @@ class TemplateTypeCheckerImpl {
|
|
|
48886
49488
|
return diagnostics.filter((diag) => diag !== null);
|
|
48887
49489
|
});
|
|
48888
49490
|
}
|
|
49491
|
+
getSuggestionDiagnosticsForFile(sf, tsLs, optimizeFor) {
|
|
49492
|
+
switch (optimizeFor) {
|
|
49493
|
+
case exports.OptimizeFor.WholeProgram:
|
|
49494
|
+
this.ensureAllShimsForAllFiles();
|
|
49495
|
+
break;
|
|
49496
|
+
case exports.OptimizeFor.SingleFile:
|
|
49497
|
+
this.ensureAllShimsForOneFile(sf);
|
|
49498
|
+
break;
|
|
49499
|
+
}
|
|
49500
|
+
return this.perf.inPhase(exports.PerfPhase.TtcSuggestionDiagnostics, () => {
|
|
49501
|
+
const sfPath = absoluteFromSourceFile(sf);
|
|
49502
|
+
const fileRecord = this.state.get(sfPath);
|
|
49503
|
+
const diagnostics = [];
|
|
49504
|
+
const program = this.programDriver.getProgram();
|
|
49505
|
+
if (fileRecord.hasInlines) {
|
|
49506
|
+
diagnostics.push(...getDeprecatedSuggestionDiagnostics(tsLs, program, sfPath, fileRecord, this));
|
|
49507
|
+
}
|
|
49508
|
+
for (const [shimPath] of fileRecord.shimData) {
|
|
49509
|
+
diagnostics.push(...getDeprecatedSuggestionDiagnostics(tsLs, program, shimPath, fileRecord, this));
|
|
49510
|
+
}
|
|
49511
|
+
return diagnostics.filter((diag) => diag !== null);
|
|
49512
|
+
});
|
|
49513
|
+
}
|
|
48889
49514
|
getDiagnosticsForComponent(component) {
|
|
48890
49515
|
this.ensureShimForComponent(component);
|
|
48891
49516
|
return this.perf.inPhase(exports.PerfPhase.TtcDiagnostics, () => {
|
|
@@ -48917,6 +49542,27 @@ class TemplateTypeCheckerImpl {
|
|
|
48917
49542
|
return diagnostics.filter((diag) => diag !== null && diag.typeCheckId === id);
|
|
48918
49543
|
});
|
|
48919
49544
|
}
|
|
49545
|
+
getSuggestionDiagnosticsForComponent(component, tsLs) {
|
|
49546
|
+
this.ensureShimForComponent(component);
|
|
49547
|
+
return this.perf.inPhase(exports.PerfPhase.TtcSuggestionDiagnostics, () => {
|
|
49548
|
+
const sf = component.getSourceFile();
|
|
49549
|
+
const sfPath = absoluteFromSourceFile(sf);
|
|
49550
|
+
const shimPath = TypeCheckShimGenerator.shimFor(sfPath);
|
|
49551
|
+
const fileRecord = this.getFileData(sfPath);
|
|
49552
|
+
if (!fileRecord.shimData.has(shimPath)) {
|
|
49553
|
+
return [];
|
|
49554
|
+
}
|
|
49555
|
+
const templateId = fileRecord.sourceManager.getTypeCheckId(component);
|
|
49556
|
+
const shimRecord = fileRecord.shimData.get(shimPath);
|
|
49557
|
+
const diagnostics = [];
|
|
49558
|
+
const program = this.programDriver.getProgram();
|
|
49559
|
+
if (shimRecord.hasInlines) {
|
|
49560
|
+
diagnostics.push(...getDeprecatedSuggestionDiagnostics(tsLs, program, sfPath, fileRecord, this));
|
|
49561
|
+
}
|
|
49562
|
+
diagnostics.push(...getDeprecatedSuggestionDiagnostics(tsLs, program, shimPath, fileRecord, this));
|
|
49563
|
+
return diagnostics.filter((diag) => diag !== null && diag.typeCheckId === templateId);
|
|
49564
|
+
});
|
|
49565
|
+
}
|
|
48920
49566
|
getTypeCheckBlock(component) {
|
|
48921
49567
|
return this.getLatestComponentState(component).tcb;
|
|
48922
49568
|
}
|
|
@@ -49740,6 +50386,124 @@ function getClassDeclFromSymbol(symbol, checker) {
|
|
|
49740
50386
|
}
|
|
49741
50387
|
return null;
|
|
49742
50388
|
}
|
|
50389
|
+
/**
|
|
50390
|
+
* Returns the diagnostics that report deprecated symbols in the given TypeScript language service.
|
|
50391
|
+
*
|
|
50392
|
+
* There are two logins here:
|
|
50393
|
+
*
|
|
50394
|
+
* 1. For input properties, function calls, and so on, the diagnostics reported in the TypeScript
|
|
50395
|
+
* Language Service can be directly transformed into template diagnostics.
|
|
50396
|
+
* 2. For the element tag deprecation, we need to manually connect the TCB node to the template node
|
|
50397
|
+
* and generate the template diagnostics.
|
|
50398
|
+
*/
|
|
50399
|
+
function getDeprecatedSuggestionDiagnostics(tsLs, program, path, fileRecord, templateTypeChecker) {
|
|
50400
|
+
const sourceFile = program.getSourceFile(path);
|
|
50401
|
+
if (sourceFile === undefined) {
|
|
50402
|
+
return [];
|
|
50403
|
+
}
|
|
50404
|
+
const tsDiags = tsLs.getSuggestionDiagnostics(path).filter(isDeprecatedDiagnostics);
|
|
50405
|
+
const commonTemplateDiags = tsDiags.map((diag) => {
|
|
50406
|
+
return convertDiagnostic(diag, fileRecord.sourceManager);
|
|
50407
|
+
});
|
|
50408
|
+
const elementTagDiags = getTheElementTagDeprecatedSuggestionDiagnostics(path, program, fileRecord, tsDiags, templateTypeChecker);
|
|
50409
|
+
return [...commonTemplateDiags, ...elementTagDiags];
|
|
50410
|
+
}
|
|
50411
|
+
/**
|
|
50412
|
+
* Connect the TCB node to the template node and generate the template diagnostics.
|
|
50413
|
+
*
|
|
50414
|
+
* How to generate the template diagnostics:
|
|
50415
|
+
*
|
|
50416
|
+
* 1. For each diagnostic, find the TCB node that is reported.
|
|
50417
|
+
* 2. Build a map called `nodeToDiag` that the key is the type node and value is the diagnostic.
|
|
50418
|
+
* For example:
|
|
50419
|
+
* ```
|
|
50420
|
+
* var _t1 = null! as TestDir;
|
|
50421
|
+
* ^^^^^^^------ This is diagnostic node that is reported by the ts.
|
|
50422
|
+
* ```
|
|
50423
|
+
* The key is the class component of TestDir.
|
|
50424
|
+
* 3. Find the all directive nodes in the TCB.
|
|
50425
|
+
* For example:
|
|
50426
|
+
* In the above example, the directive node is `_t1`, get the type of `_t1` which is the
|
|
50427
|
+
* class component of `TestDir`. Check if there is a diagnostic in the `nodeToDiag` map
|
|
50428
|
+
* that matches the class component of `TestDir`.
|
|
50429
|
+
* If there is a match, it means that the diagnostic is reported for the directive node
|
|
50430
|
+
* 4. Generate the template diagnostic and return the template diagnostics.
|
|
50431
|
+
*/
|
|
50432
|
+
function getTheElementTagDeprecatedSuggestionDiagnostics(shimPath, program, fileRecord, diags, templateTypeChecker) {
|
|
50433
|
+
const sourceFile = program.getSourceFile(shimPath);
|
|
50434
|
+
if (sourceFile === undefined) {
|
|
50435
|
+
return [];
|
|
50436
|
+
}
|
|
50437
|
+
const typeChecker = program.getTypeChecker();
|
|
50438
|
+
const nodeToDiag = new Map();
|
|
50439
|
+
for (const tsDiag of diags) {
|
|
50440
|
+
const diagNode = getTokenAtPosition(sourceFile, tsDiag.start);
|
|
50441
|
+
const nodeType = typeChecker.getTypeAtLocation(diagNode);
|
|
50442
|
+
const nodeSymbolDeclarations = nodeType.symbol.declarations;
|
|
50443
|
+
const decl = nodeSymbolDeclarations !== undefined && nodeSymbolDeclarations.length > 0
|
|
50444
|
+
? nodeSymbolDeclarations[0]
|
|
50445
|
+
: undefined;
|
|
50446
|
+
if (decl === undefined || !ts.isClassDeclaration(decl)) {
|
|
50447
|
+
continue;
|
|
50448
|
+
}
|
|
50449
|
+
const directiveForDiagnostic = templateTypeChecker.getDirectiveMetadata(decl);
|
|
50450
|
+
// For now, we only report deprecations for components. This is because
|
|
50451
|
+
// directive spans apply to the entire element, so it would cause the deprecation to
|
|
50452
|
+
// appear as a deprecation for the element rather than whatever the selector (likely an attribute)
|
|
50453
|
+
// is for the directive. Technically components have this issue as well but nearly
|
|
50454
|
+
// all component selectors are element selectors.
|
|
50455
|
+
if (directiveForDiagnostic === null || !directiveForDiagnostic.isComponent) {
|
|
50456
|
+
continue;
|
|
50457
|
+
}
|
|
50458
|
+
nodeToDiag.set(decl, tsDiag);
|
|
50459
|
+
}
|
|
50460
|
+
const directiveNodesInTcb = findAllMatchingNodes(sourceFile, {
|
|
50461
|
+
filter: isDirectiveDeclaration,
|
|
50462
|
+
});
|
|
50463
|
+
const templateDiagnostics = [];
|
|
50464
|
+
for (const directive of directiveNodesInTcb) {
|
|
50465
|
+
const directiveType = typeChecker.getTypeAtLocation(directive);
|
|
50466
|
+
const directiveSymbolDeclarations = directiveType.symbol.declarations;
|
|
50467
|
+
const decl = directiveSymbolDeclarations !== undefined && directiveSymbolDeclarations.length > 0
|
|
50468
|
+
? directiveSymbolDeclarations[0]
|
|
50469
|
+
: undefined;
|
|
50470
|
+
if (decl === undefined) {
|
|
50471
|
+
continue;
|
|
50472
|
+
}
|
|
50473
|
+
if (!ts.isClassDeclaration(decl)) {
|
|
50474
|
+
continue;
|
|
50475
|
+
}
|
|
50476
|
+
const diagnostic = nodeToDiag.get(decl);
|
|
50477
|
+
if (diagnostic === undefined) {
|
|
50478
|
+
continue;
|
|
50479
|
+
}
|
|
50480
|
+
const fullMapping = getSourceMapping(diagnostic.file, directive.getStart(), fileRecord.sourceManager,
|
|
50481
|
+
/**
|
|
50482
|
+
* Don't set to true, the deprecated diagnostics will be ignored if this is a diagnostics request.
|
|
50483
|
+
* Only the deprecated diagnostics will be reported here.
|
|
50484
|
+
*/
|
|
50485
|
+
// For example:
|
|
50486
|
+
// var _t2 /*T:DIR*/ /*87,104*/ = _ctor1({ "name": ("") /*96,103*/ }) /*D:ignore*/;
|
|
50487
|
+
// At the end of the statement, there is a comment `/*D:ignore*/` which means that this diagnostic
|
|
50488
|
+
// should be ignored in diagnostics request.
|
|
50489
|
+
/*isDiagnosticsRequest*/ false);
|
|
50490
|
+
if (fullMapping === null) {
|
|
50491
|
+
continue;
|
|
50492
|
+
}
|
|
50493
|
+
const { sourceLocation, sourceMapping: templateSourceMapping, span } = fullMapping;
|
|
50494
|
+
const templateDiagnostic = makeTemplateDiagnostic(sourceLocation.id, templateSourceMapping, span, diagnostic.category, diagnostic.code, diagnostic.messageText, undefined, diagnostic.reportsDeprecated !== undefined
|
|
50495
|
+
? {
|
|
50496
|
+
reportsDeprecated: diagnostic.reportsDeprecated,
|
|
50497
|
+
relatedMessages: diagnostic.relatedInformation,
|
|
50498
|
+
}
|
|
50499
|
+
: undefined);
|
|
50500
|
+
templateDiagnostics.push(templateDiagnostic);
|
|
50501
|
+
}
|
|
50502
|
+
return templateDiagnostics;
|
|
50503
|
+
}
|
|
50504
|
+
function isDeprecatedDiagnostics(diag) {
|
|
50505
|
+
return diag.reportsDeprecated !== undefined;
|
|
50506
|
+
}
|
|
49743
50507
|
|
|
49744
50508
|
exports.AST = AST;
|
|
49745
50509
|
exports.ASTWithSource = ASTWithSource;
|