@angular/core 19.0.0-next.9 → 19.0.0-rc.0
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/fesm2022/core.mjs +21506 -19585
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +71 -47
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +8 -6
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +90 -10
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +175 -114
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +556 -89
- package/package.json +1 -1
- package/primitives/event-dispatch/index.d.ts +7 -4
- package/primitives/signals/index.d.ts +3 -1
- package/rxjs-interop/index.d.ts +35 -4
- package/schematics/bundles/{checker-3b2ea20f.js → checker-2451e7c5.js} +2347 -1063
- package/schematics/bundles/{group_replacements-e1b5cbf8.js → combine_units-c52492ab.js} +1767 -2136
- package/schematics/bundles/{compiler_host-b4ba5a28.js → compiler_host-f54f8309.js} +2 -2
- package/schematics/bundles/control-flow-migration.js +3 -3
- package/schematics/bundles/explicit-standalone-flag.js +31 -11
- package/schematics/bundles/{imports-4ac08251.js → imports-44987700.js} +1 -1
- package/schematics/bundles/inject-migration.js +122 -48
- package/schematics/bundles/{leading_space-d190b83b.js → leading_space-6e7a8ec6.js} +1 -1
- package/schematics/bundles/migrate_ts_type_references-ab18a7c3.js +1463 -0
- package/schematics/bundles/{nodes-0e7d45ca.js → ng_decorators-3ad437d2.js} +2 -15
- package/schematics/bundles/nodes-ffdce442.js +27 -0
- package/schematics/bundles/output-migration.js +7450 -0
- package/schematics/bundles/pending-tasks.js +5 -5
- package/schematics/bundles/{program-6534a30a.js → program-58424797.js} +1305 -447
- package/schematics/bundles/{project_tsconfig_paths-e9ccccbf.js → project_tsconfig_paths-6c9cde78.js} +1 -1
- package/schematics/bundles/provide-initializer.js +190 -0
- package/schematics/bundles/route-lazy-loading.js +4 -4
- package/schematics/bundles/signal-input-migration.js +184 -312
- package/schematics/bundles/signal-queries-migration.js +401 -143
- package/schematics/bundles/signals.js +54 -0
- package/schematics/bundles/standalone-migration.js +38 -20
- package/schematics/collection.json +11 -0
- package/schematics/migrations.json +7 -1
- package/schematics/ng-generate/output-migration/schema.json +19 -0
- package/schematics/ng-generate/signal-queries-migration/schema.json +11 -0
- package/schematics/ng-generate/signals/schema.json +65 -0
- package/testing/index.d.ts +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-
|
|
3
|
+
* @license Angular v19.0.0-rc.0
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
var checker = require('./checker-
|
|
9
|
+
var checker = require('./checker-2451e7c5.js');
|
|
10
10
|
var ts = require('typescript');
|
|
11
11
|
var p = require('path');
|
|
12
12
|
require('os');
|
|
@@ -34,9 +34,31 @@ function _interopNamespace(e) {
|
|
|
34
34
|
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
35
35
|
var p__namespace = /*#__PURE__*/_interopNamespace(p);
|
|
36
36
|
|
|
37
|
+
class XmlTagDefinition {
|
|
38
|
+
closedByParent = false;
|
|
39
|
+
implicitNamespacePrefix = null;
|
|
40
|
+
isVoid = false;
|
|
41
|
+
ignoreFirstLf = false;
|
|
42
|
+
canSelfClose = true;
|
|
43
|
+
preventNamespaceInheritance = false;
|
|
44
|
+
requireExtraParent(currentParent) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
isClosedByChild(name) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
getContentType() {
|
|
51
|
+
return checker.TagContentType.PARSABLE_DATA;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const _TAG_DEFINITION = new XmlTagDefinition();
|
|
55
|
+
function getXmlTagDefinition(tagName) {
|
|
56
|
+
return _TAG_DEFINITION;
|
|
57
|
+
}
|
|
58
|
+
|
|
37
59
|
class XmlParser extends checker.Parser {
|
|
38
60
|
constructor() {
|
|
39
|
-
super(
|
|
61
|
+
super(getXmlTagDefinition);
|
|
40
62
|
}
|
|
41
63
|
parse(source, url, options = {}) {
|
|
42
64
|
// Blocks and let declarations aren't supported in an XML context.
|
|
@@ -190,9 +212,11 @@ class _WriteVisitor$1 {
|
|
|
190
212
|
// TODO(vicb): add error management (structure)
|
|
191
213
|
// Extract messages as xml nodes from the xliff file
|
|
192
214
|
class XliffParser {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
215
|
+
// using non-null assertions because they're re(set) by parse()
|
|
216
|
+
_unitMlString;
|
|
217
|
+
_errors;
|
|
218
|
+
_msgIdToHtml;
|
|
219
|
+
_locale = null;
|
|
196
220
|
parse(xliff, url) {
|
|
197
221
|
this._unitMlString = null;
|
|
198
222
|
this._msgIdToHtml = {};
|
|
@@ -268,6 +292,8 @@ class XliffParser {
|
|
|
268
292
|
}
|
|
269
293
|
// Convert ml nodes (xliff syntax) to i18n nodes
|
|
270
294
|
class XmlToI18n$1 {
|
|
295
|
+
// using non-null assertion because it's re(set) by convert()
|
|
296
|
+
_errors;
|
|
271
297
|
convert(message, url) {
|
|
272
298
|
const xmlIcu = new XmlParser().parse(message, url, { tokenizeExpansionForms: true });
|
|
273
299
|
this._errors = xmlIcu.errors;
|
|
@@ -399,13 +425,11 @@ class Xliff2 extends checker.Serializer {
|
|
|
399
425
|
return { locale: locale, i18nNodesByMsgId };
|
|
400
426
|
}
|
|
401
427
|
digest(message) {
|
|
402
|
-
return checker.decimalDigest(message
|
|
428
|
+
return checker.decimalDigest(message);
|
|
403
429
|
}
|
|
404
430
|
}
|
|
405
431
|
class _WriteVisitor {
|
|
406
|
-
|
|
407
|
-
this._nextPlaceholderId = 0;
|
|
408
|
-
}
|
|
432
|
+
_nextPlaceholderId = 0;
|
|
409
433
|
visitText(text, context) {
|
|
410
434
|
return [new checker.Text$1(text.value)];
|
|
411
435
|
}
|
|
@@ -498,9 +522,11 @@ class _WriteVisitor {
|
|
|
498
522
|
}
|
|
499
523
|
// Extract messages as xml nodes from the xliff file
|
|
500
524
|
class Xliff2Parser {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
525
|
+
// using non-null assertions because they're all (re)set by parse()
|
|
526
|
+
_unitMlString;
|
|
527
|
+
_errors;
|
|
528
|
+
_msgIdToHtml;
|
|
529
|
+
_locale = null;
|
|
504
530
|
parse(xliff, url) {
|
|
505
531
|
this._unitMlString = null;
|
|
506
532
|
this._msgIdToHtml = {};
|
|
@@ -581,6 +607,8 @@ class Xliff2Parser {
|
|
|
581
607
|
}
|
|
582
608
|
// Convert ml nodes (xliff syntax) to i18n nodes
|
|
583
609
|
class XmlToI18n {
|
|
610
|
+
// using non-null assertion because re(set) by convert()
|
|
611
|
+
_errors;
|
|
584
612
|
convert(message, url) {
|
|
585
613
|
const xmlIcu = new XmlParser().parse(message, url, { tokenizeExpansionForms: true });
|
|
586
614
|
this._errors = xmlIcu.errors;
|
|
@@ -669,13 +697,18 @@ function getTypeForTag(tag) {
|
|
|
669
697
|
* A container for message extracted from the templates.
|
|
670
698
|
*/
|
|
671
699
|
class MessageBundle {
|
|
700
|
+
_htmlParser;
|
|
701
|
+
_implicitTags;
|
|
702
|
+
_implicitAttrs;
|
|
703
|
+
_locale;
|
|
704
|
+
_preserveWhitespace;
|
|
705
|
+
_messages = [];
|
|
672
706
|
constructor(_htmlParser, _implicitTags, _implicitAttrs, _locale = null, _preserveWhitespace = true) {
|
|
673
707
|
this._htmlParser = _htmlParser;
|
|
674
708
|
this._implicitTags = _implicitTags;
|
|
675
709
|
this._implicitAttrs = _implicitAttrs;
|
|
676
710
|
this._locale = _locale;
|
|
677
711
|
this._preserveWhitespace = _preserveWhitespace;
|
|
678
|
-
this._messages = [];
|
|
679
712
|
}
|
|
680
713
|
updateFromTemplate(source, url, interpolationConfig) {
|
|
681
714
|
const htmlParserResult = this._htmlParser.parse(source, url, {
|
|
@@ -849,6 +882,72 @@ function compileClassDebugInfo(debugInfo) {
|
|
|
849
882
|
return iife.callFn([]);
|
|
850
883
|
}
|
|
851
884
|
|
|
885
|
+
/*!
|
|
886
|
+
* @license
|
|
887
|
+
* Copyright Google LLC All Rights Reserved.
|
|
888
|
+
*
|
|
889
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
890
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
891
|
+
*/
|
|
892
|
+
/**
|
|
893
|
+
* Compiles the expression that initializes HMR for a class.
|
|
894
|
+
* @param meta HMR metadata extracted from the class.
|
|
895
|
+
*/
|
|
896
|
+
function compileHmrInitializer(meta) {
|
|
897
|
+
const id = encodeURIComponent(`${meta.filePath}@${meta.className}`);
|
|
898
|
+
const urlPartial = `/@ng/component?c=${id}&t=`;
|
|
899
|
+
const moduleName = 'm';
|
|
900
|
+
const dataName = 'd';
|
|
901
|
+
const locals = meta.locals.map((localName) => checker.variable(localName));
|
|
902
|
+
// ɵɵreplaceMetadata(Comp, m.default, [...]);
|
|
903
|
+
const replaceMetadata = checker.importExpr(checker.Identifiers.replaceMetadata)
|
|
904
|
+
.callFn([meta.type, checker.variable(moduleName).prop('default'), checker.literalArr(locals)]);
|
|
905
|
+
// (m) => ɵɵreplaceMetadata(...)
|
|
906
|
+
const replaceCallback = checker.arrowFn([new checker.FnParam(moduleName)], replaceMetadata);
|
|
907
|
+
// '<urlPartial>' + encodeURIComponent(d.timestamp)
|
|
908
|
+
const urlValue = checker.literal(urlPartial)
|
|
909
|
+
.plus(checker.variable('encodeURIComponent').callFn([checker.variable(dataName).prop('timestamp')]));
|
|
910
|
+
// import(/* @vite-ignore */ url).then(() => replaceMetadata(...));
|
|
911
|
+
// The vite-ignore special comment is required to avoid Vite from generating a superfluous
|
|
912
|
+
// warning for each usage within the development code. If Vite provides a method to
|
|
913
|
+
// programmatically avoid this warning in the future, this added comment can be removed here.
|
|
914
|
+
const dynamicImport = new checker.DynamicImportExpr(urlValue, null, '@vite-ignore')
|
|
915
|
+
.prop('then')
|
|
916
|
+
.callFn([replaceCallback]);
|
|
917
|
+
// (d) => { if (d.id === <id>) { replaceMetadata(...) } }
|
|
918
|
+
const listenerCallback = checker.arrowFn([new checker.FnParam(dataName)], [checker.ifStmt(checker.variable(dataName).prop('id').equals(checker.literal(id)), [dynamicImport.toStmt()])]);
|
|
919
|
+
// import.meta.hot
|
|
920
|
+
const hotRead = checker.variable('import').prop('meta').prop('hot');
|
|
921
|
+
// import.meta.hot.on('angular:component-update', () => ...);
|
|
922
|
+
const hotListener = hotRead
|
|
923
|
+
.clone()
|
|
924
|
+
.prop('on')
|
|
925
|
+
.callFn([checker.literal('angular:component-update'), listenerCallback]);
|
|
926
|
+
// import.meta.hot && import.meta.hot.on(...)
|
|
927
|
+
return checker.arrowFn([], [checker.devOnlyGuardedExpression(hotRead.and(hotListener)).toStmt()]).callFn([]);
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Compiles the HMR update callback for a class.
|
|
931
|
+
* @param definitions Compiled definitions for the class (e.g. `defineComponent` calls).
|
|
932
|
+
* @param constantStatements Supporting constants statements that were generated alongside
|
|
933
|
+
* the definition.
|
|
934
|
+
* @param meta HMR metadata extracted from the class.
|
|
935
|
+
*/
|
|
936
|
+
function compileHmrUpdateCallback(definitions, constantStatements, meta) {
|
|
937
|
+
// The class name should always be first and core should be second.
|
|
938
|
+
const params = [meta.className, meta.coreName, ...meta.locals].map((name) => new checker.FnParam(name, checker.DYNAMIC_TYPE));
|
|
939
|
+
const body = [...constantStatements];
|
|
940
|
+
for (const field of definitions) {
|
|
941
|
+
if (field.initializer !== null) {
|
|
942
|
+
body.push(checker.variable(meta.className).prop(field.name).set(field.initializer).toStmt());
|
|
943
|
+
for (const stmt of field.statements) {
|
|
944
|
+
body.push(stmt);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
return new checker.DeclareFunctionStmt(`${meta.className}_UpdateMetadata`, params, body, null, checker.StmtModifier.Final);
|
|
949
|
+
}
|
|
950
|
+
|
|
852
951
|
/**
|
|
853
952
|
* Every time we make a breaking change to the declaration interface or partial-linker behavior, we
|
|
854
953
|
* must update this constant to prevent old partial-linkers from incorrectly processing the
|
|
@@ -864,7 +963,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
|
|
|
864
963
|
function compileDeclareClassMetadata(metadata) {
|
|
865
964
|
const definitionMap = new checker.DefinitionMap();
|
|
866
965
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
867
|
-
definitionMap.set('version', checker.literal('19.0.0-
|
|
966
|
+
definitionMap.set('version', checker.literal('19.0.0-rc.0'));
|
|
868
967
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
869
968
|
definitionMap.set('type', metadata.type);
|
|
870
969
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -882,7 +981,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
|
|
|
882
981
|
callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? checker.literal(null));
|
|
883
982
|
callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? checker.literal(null));
|
|
884
983
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
|
|
885
|
-
definitionMap.set('version', checker.literal('19.0.0-
|
|
984
|
+
definitionMap.set('version', checker.literal('19.0.0-rc.0'));
|
|
886
985
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
887
986
|
definitionMap.set('type', metadata.type);
|
|
888
987
|
definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
|
|
@@ -977,10 +1076,10 @@ function createDirectiveDefinitionMap(meta) {
|
|
|
977
1076
|
const definitionMap = new checker.DefinitionMap();
|
|
978
1077
|
const minVersion = getMinimumVersionForPartialOutput(meta);
|
|
979
1078
|
definitionMap.set('minVersion', checker.literal(minVersion));
|
|
980
|
-
definitionMap.set('version', checker.literal('19.0.0-
|
|
1079
|
+
definitionMap.set('version', checker.literal('19.0.0-rc.0'));
|
|
981
1080
|
// e.g. `type: MyDirective`
|
|
982
1081
|
definitionMap.set('type', meta.type.value);
|
|
983
|
-
if (meta.isStandalone) {
|
|
1082
|
+
if (meta.isStandalone !== undefined) {
|
|
984
1083
|
definitionMap.set('isStandalone', checker.literal(meta.isStandalone));
|
|
985
1084
|
}
|
|
986
1085
|
if (meta.isSignal) {
|
|
@@ -1349,10 +1448,7 @@ function compileUsedDependenciesMetadata(meta) {
|
|
|
1349
1448
|
});
|
|
1350
1449
|
}
|
|
1351
1450
|
class BlockPresenceVisitor extends checker.RecursiveVisitor$1 {
|
|
1352
|
-
|
|
1353
|
-
super(...arguments);
|
|
1354
|
-
this.hasBlocks = false;
|
|
1355
|
-
}
|
|
1451
|
+
hasBlocks = false;
|
|
1356
1452
|
visitDeferredBlock() {
|
|
1357
1453
|
this.hasBlocks = true;
|
|
1358
1454
|
}
|
|
@@ -1396,7 +1492,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
|
|
|
1396
1492
|
function compileDeclareFactoryFunction(meta) {
|
|
1397
1493
|
const definitionMap = new checker.DefinitionMap();
|
|
1398
1494
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
1399
|
-
definitionMap.set('version', checker.literal('19.0.0-
|
|
1495
|
+
definitionMap.set('version', checker.literal('19.0.0-rc.0'));
|
|
1400
1496
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1401
1497
|
definitionMap.set('type', meta.type.value);
|
|
1402
1498
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -1431,7 +1527,7 @@ function compileDeclareInjectableFromMetadata(meta) {
|
|
|
1431
1527
|
function createInjectableDefinitionMap(meta) {
|
|
1432
1528
|
const definitionMap = new checker.DefinitionMap();
|
|
1433
1529
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
1434
|
-
definitionMap.set('version', checker.literal('19.0.0-
|
|
1530
|
+
definitionMap.set('version', checker.literal('19.0.0-rc.0'));
|
|
1435
1531
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1436
1532
|
definitionMap.set('type', meta.type.value);
|
|
1437
1533
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -1482,7 +1578,7 @@ function compileDeclareInjectorFromMetadata(meta) {
|
|
|
1482
1578
|
function createInjectorDefinitionMap(meta) {
|
|
1483
1579
|
const definitionMap = new checker.DefinitionMap();
|
|
1484
1580
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
1485
|
-
definitionMap.set('version', checker.literal('19.0.0-
|
|
1581
|
+
definitionMap.set('version', checker.literal('19.0.0-rc.0'));
|
|
1486
1582
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1487
1583
|
definitionMap.set('type', meta.type.value);
|
|
1488
1584
|
definitionMap.set('providers', meta.providers);
|
|
@@ -1515,7 +1611,7 @@ function createNgModuleDefinitionMap(meta) {
|
|
|
1515
1611
|
throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
|
|
1516
1612
|
}
|
|
1517
1613
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
1518
|
-
definitionMap.set('version', checker.literal('19.0.0-
|
|
1614
|
+
definitionMap.set('version', checker.literal('19.0.0-rc.0'));
|
|
1519
1615
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1520
1616
|
definitionMap.set('type', meta.type.value);
|
|
1521
1617
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -1566,11 +1662,11 @@ function compileDeclarePipeFromMetadata(meta) {
|
|
|
1566
1662
|
function createPipeDefinitionMap(meta) {
|
|
1567
1663
|
const definitionMap = new checker.DefinitionMap();
|
|
1568
1664
|
definitionMap.set('minVersion', checker.literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
1569
|
-
definitionMap.set('version', checker.literal('19.0.0-
|
|
1665
|
+
definitionMap.set('version', checker.literal('19.0.0-rc.0'));
|
|
1570
1666
|
definitionMap.set('ngImport', checker.importExpr(checker.Identifiers.core));
|
|
1571
1667
|
// e.g. `type: MyPipe`
|
|
1572
1668
|
definitionMap.set('type', meta.type.value);
|
|
1573
|
-
if (meta.isStandalone) {
|
|
1669
|
+
if (meta.isStandalone !== undefined) {
|
|
1574
1670
|
definitionMap.set('isStandalone', checker.literal(meta.isStandalone));
|
|
1575
1671
|
}
|
|
1576
1672
|
// e.g. `name: "myPipe"`
|
|
@@ -1601,14 +1697,15 @@ const CHARS_TO_ESCAPE = /[^a-zA-Z0-9/_]/g;
|
|
|
1601
1697
|
* README.md for more details.
|
|
1602
1698
|
*/
|
|
1603
1699
|
class UnifiedModulesAliasingHost {
|
|
1700
|
+
unifiedModulesHost;
|
|
1604
1701
|
constructor(unifiedModulesHost) {
|
|
1605
1702
|
this.unifiedModulesHost = unifiedModulesHost;
|
|
1606
|
-
/**
|
|
1607
|
-
* With a `UnifiedModulesHost`, aliases are chosen automatically without the need to look through
|
|
1608
|
-
* the exports present in a .d.ts file, so we can avoid cluttering the .d.ts files.
|
|
1609
|
-
*/
|
|
1610
|
-
this.aliasExportsInDts = false;
|
|
1611
1703
|
}
|
|
1704
|
+
/**
|
|
1705
|
+
* With a `UnifiedModulesHost`, aliases are chosen automatically without the need to look through
|
|
1706
|
+
* the exports present in a .d.ts file, so we can avoid cluttering the .d.ts files.
|
|
1707
|
+
*/
|
|
1708
|
+
aliasExportsInDts = false;
|
|
1612
1709
|
maybeAliasSymbolAs(ref, context, ngModuleName, isReExport) {
|
|
1613
1710
|
if (!isReExport) {
|
|
1614
1711
|
// Aliasing is used with a UnifiedModulesHost to prevent transitive dependencies. Thus,
|
|
@@ -1654,16 +1751,17 @@ class UnifiedModulesAliasingHost {
|
|
|
1654
1751
|
* more details.
|
|
1655
1752
|
*/
|
|
1656
1753
|
class PrivateExportAliasingHost {
|
|
1754
|
+
host;
|
|
1657
1755
|
constructor(host) {
|
|
1658
1756
|
this.host = host;
|
|
1659
|
-
/**
|
|
1660
|
-
* Under private export aliasing, the `AbsoluteModuleStrategy` used for emitting references will
|
|
1661
|
-
* will select aliased exports that it finds in the .d.ts file for an NgModule's file. Thus,
|
|
1662
|
-
* emitting these exports in .d.ts is a requirement for the `PrivateExportAliasingHost` to
|
|
1663
|
-
* function correctly.
|
|
1664
|
-
*/
|
|
1665
|
-
this.aliasExportsInDts = true;
|
|
1666
1757
|
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Under private export aliasing, the `AbsoluteModuleStrategy` used for emitting references will
|
|
1760
|
+
* will select aliased exports that it finds in the .d.ts file for an NgModule's file. Thus,
|
|
1761
|
+
* emitting these exports in .d.ts is a requirement for the `PrivateExportAliasingHost` to
|
|
1762
|
+
* function correctly.
|
|
1763
|
+
*/
|
|
1764
|
+
aliasExportsInDts = true;
|
|
1667
1765
|
maybeAliasSymbolAs(ref, context, ngModuleName) {
|
|
1668
1766
|
if (ref.hasOwningModuleGuess) {
|
|
1669
1767
|
// Skip nodes that already have an associated absolute module specifier, since they can be
|
|
@@ -1731,6 +1829,27 @@ function normalizeSeparators(path) {
|
|
|
1731
1829
|
// TODO: normalize path only for OS that need it.
|
|
1732
1830
|
return path.replace(/\\/g, '/');
|
|
1733
1831
|
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Attempts to generate a project-relative path
|
|
1834
|
+
* @param sourceFile
|
|
1835
|
+
* @param rootDirs
|
|
1836
|
+
* @param compilerHost
|
|
1837
|
+
* @returns
|
|
1838
|
+
*/
|
|
1839
|
+
function getProjectRelativePath(sourceFile, rootDirs, compilerHost) {
|
|
1840
|
+
// Note: we need to pass both the file name and the root directories through getCanonicalFileName,
|
|
1841
|
+
// because the root directories might've been passed through it already while the source files
|
|
1842
|
+
// definitely have not. This can break the relative return value, because in some platforms
|
|
1843
|
+
// getCanonicalFileName lowercases the path.
|
|
1844
|
+
const filePath = compilerHost.getCanonicalFileName(sourceFile.fileName);
|
|
1845
|
+
for (const rootDir of rootDirs) {
|
|
1846
|
+
const rel = checker.relative(compilerHost.getCanonicalFileName(rootDir), filePath);
|
|
1847
|
+
if (!rel.startsWith('..')) {
|
|
1848
|
+
return rel;
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
return null;
|
|
1852
|
+
}
|
|
1734
1853
|
|
|
1735
1854
|
/**
|
|
1736
1855
|
* `ImportRewriter` that does no rewriting.
|
|
@@ -1742,6 +1861,9 @@ class NoopImportRewriter {
|
|
|
1742
1861
|
rewriteSpecifier(specifier, inContextOfFile) {
|
|
1743
1862
|
return specifier;
|
|
1744
1863
|
}
|
|
1864
|
+
rewriteNamespaceImportIdentifier(specifier) {
|
|
1865
|
+
return specifier;
|
|
1866
|
+
}
|
|
1745
1867
|
}
|
|
1746
1868
|
/**
|
|
1747
1869
|
* A mapping of supported symbols that can be imported from within @angular/core, and the names by
|
|
@@ -1768,6 +1890,7 @@ const CORE_MODULE = '@angular/core';
|
|
|
1768
1890
|
* file instead.
|
|
1769
1891
|
*/
|
|
1770
1892
|
class R3SymbolsImportRewriter {
|
|
1893
|
+
r3SymbolsPath;
|
|
1771
1894
|
constructor(r3SymbolsPath) {
|
|
1772
1895
|
this.r3SymbolsPath = r3SymbolsPath;
|
|
1773
1896
|
}
|
|
@@ -1789,6 +1912,9 @@ class R3SymbolsImportRewriter {
|
|
|
1789
1912
|
}
|
|
1790
1913
|
return relativePathToR3Symbols;
|
|
1791
1914
|
}
|
|
1915
|
+
rewriteNamespaceImportIdentifier(specifier) {
|
|
1916
|
+
return specifier;
|
|
1917
|
+
}
|
|
1792
1918
|
}
|
|
1793
1919
|
function validateAndRewriteCoreSymbol(name) {
|
|
1794
1920
|
if (!CORE_SUPPORTED_SYMBOLS.has(name)) {
|
|
@@ -1806,15 +1932,17 @@ const AssumeEager = 'AssumeEager';
|
|
|
1806
1932
|
* in favor of using a dynamic import for cases when defer blocks are used.
|
|
1807
1933
|
*/
|
|
1808
1934
|
class DeferredSymbolTracker {
|
|
1935
|
+
typeChecker;
|
|
1936
|
+
onlyExplicitDeferDependencyImports;
|
|
1937
|
+
imports = new Map();
|
|
1938
|
+
/**
|
|
1939
|
+
* Map of a component class -> all import declarations that bring symbols
|
|
1940
|
+
* used within `@Component.deferredImports` field.
|
|
1941
|
+
*/
|
|
1942
|
+
explicitlyDeferredImports = new Map();
|
|
1809
1943
|
constructor(typeChecker, onlyExplicitDeferDependencyImports) {
|
|
1810
1944
|
this.typeChecker = typeChecker;
|
|
1811
1945
|
this.onlyExplicitDeferDependencyImports = onlyExplicitDeferDependencyImports;
|
|
1812
|
-
this.imports = new Map();
|
|
1813
|
-
/**
|
|
1814
|
-
* Map of a component class -> all import declarations that bring symbols
|
|
1815
|
-
* used within `@Component.deferredImports` field.
|
|
1816
|
-
*/
|
|
1817
|
-
this.explicitlyDeferredImports = new Map();
|
|
1818
1946
|
}
|
|
1819
1947
|
/**
|
|
1820
1948
|
* Given an import declaration node, extract the names of all imported symbols
|
|
@@ -1993,10 +2121,8 @@ class DeferredSymbolTracker {
|
|
|
1993
2121
|
* type checker may be necessary, depending on the context. Also does not track dynamic imports.
|
|
1994
2122
|
*/
|
|
1995
2123
|
class ImportedSymbolsTracker {
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
this.fileToNamespaceImports = new WeakMap();
|
|
1999
|
-
}
|
|
2124
|
+
fileToNamedImports = new WeakMap();
|
|
2125
|
+
fileToNamespaceImports = new WeakMap();
|
|
2000
2126
|
/**
|
|
2001
2127
|
* Checks if an identifier is a potential reference to a specific named import within the same
|
|
2002
2128
|
* file.
|
|
@@ -2112,12 +2238,13 @@ class ImportedSymbolsTracker {
|
|
|
2112
2238
|
*
|
|
2113
2239
|
*/
|
|
2114
2240
|
class LocalCompilationExtraImportsTracker {
|
|
2241
|
+
typeChecker;
|
|
2242
|
+
localImportsMap = new Map();
|
|
2243
|
+
globalImportsSet = new Set();
|
|
2244
|
+
/** Names of the files marked for extra import generation. */
|
|
2245
|
+
markedFilesSet = new Set();
|
|
2115
2246
|
constructor(typeChecker) {
|
|
2116
2247
|
this.typeChecker = typeChecker;
|
|
2117
|
-
this.localImportsMap = new Map();
|
|
2118
|
-
this.globalImportsSet = new Set();
|
|
2119
|
-
/** Names of the files marked for extra import generation. */
|
|
2120
|
-
this.markedFilesSet = new Set();
|
|
2121
2248
|
}
|
|
2122
2249
|
/**
|
|
2123
2250
|
* Marks the source file for extra imports generation.
|
|
@@ -2192,6 +2319,10 @@ function removeQuotations(s) {
|
|
|
2192
2319
|
* definitions).
|
|
2193
2320
|
*/
|
|
2194
2321
|
class ModuleResolver {
|
|
2322
|
+
program;
|
|
2323
|
+
compilerOptions;
|
|
2324
|
+
host;
|
|
2325
|
+
moduleResolutionCache;
|
|
2195
2326
|
constructor(program, compilerOptions, host, moduleResolutionCache) {
|
|
2196
2327
|
this.program = program;
|
|
2197
2328
|
this.compilerOptions = compilerOptions;
|
|
@@ -2401,6 +2532,14 @@ function createUnsuitableInjectionTokenError(clazz, error) {
|
|
|
2401
2532
|
* property name, or mapping from a specific class property to its binding property name.
|
|
2402
2533
|
*/
|
|
2403
2534
|
class ClassPropertyMapping {
|
|
2535
|
+
/**
|
|
2536
|
+
* Mapping from class property names to the single `InputOrOutput` for that class property.
|
|
2537
|
+
*/
|
|
2538
|
+
forwardMap;
|
|
2539
|
+
/**
|
|
2540
|
+
* Mapping from property names to one or more `InputOrOutput`s which share that name.
|
|
2541
|
+
*/
|
|
2542
|
+
reverseMap;
|
|
2404
2543
|
constructor(forwardMap) {
|
|
2405
2544
|
this.forwardMap = forwardMap;
|
|
2406
2545
|
this.reverseMap = reverseMapFromForwardMap(forwardMap);
|
|
@@ -2530,6 +2669,8 @@ function reverseMapFromForwardMap(forwardMap) {
|
|
|
2530
2669
|
* from an upstream compilation already.
|
|
2531
2670
|
*/
|
|
2532
2671
|
class DtsMetadataReader {
|
|
2672
|
+
checker;
|
|
2673
|
+
reflector;
|
|
2533
2674
|
constructor(checker, reflector) {
|
|
2534
2675
|
this.checker = checker;
|
|
2535
2676
|
this.reflector = reflector;
|
|
@@ -2608,6 +2749,8 @@ class DtsMetadataReader {
|
|
|
2608
2749
|
param.typeValueReference.importedName === 'TemplateRef');
|
|
2609
2750
|
});
|
|
2610
2751
|
const ngContentSelectors = def.type.typeArguments.length > 6 ? checker.readStringArrayType(def.type.typeArguments[6]) : null;
|
|
2752
|
+
// Note: the default value is still `false` here, because only legacy .d.ts files written before
|
|
2753
|
+
// we had so many arguments use this default.
|
|
2611
2754
|
const isStandalone = def.type.typeArguments.length > 7 && (checker.readBooleanType(def.type.typeArguments[7]) ?? false);
|
|
2612
2755
|
const inputs = ClassPropertyMapping.fromMappedObject(readInputsType(def.type.typeArguments[3]));
|
|
2613
2756
|
const outputs = ClassPropertyMapping.fromMappedObject(checker.readMapType(def.type.typeArguments[4], checker.readStringType));
|
|
@@ -2867,11 +3010,9 @@ function flattenInheritedDirectiveMetadata(reader, dir) {
|
|
|
2867
3010
|
* unit, which supports both reading and registering.
|
|
2868
3011
|
*/
|
|
2869
3012
|
class LocalMetadataRegistry {
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
this.pipes = new Map();
|
|
2874
|
-
}
|
|
3013
|
+
directives = new Map();
|
|
3014
|
+
ngModules = new Map();
|
|
3015
|
+
pipes = new Map();
|
|
2875
3016
|
getDirectiveMetadata(ref) {
|
|
2876
3017
|
return this.directives.has(ref.node) ? this.directives.get(ref.node) : null;
|
|
2877
3018
|
}
|
|
@@ -2906,6 +3047,7 @@ class LocalMetadataRegistry {
|
|
|
2906
3047
|
* instances.
|
|
2907
3048
|
*/
|
|
2908
3049
|
class CompoundMetadataRegistry {
|
|
3050
|
+
registries;
|
|
2909
3051
|
constructor(registries) {
|
|
2910
3052
|
this.registries = registries;
|
|
2911
3053
|
}
|
|
@@ -2934,12 +3076,10 @@ class CompoundMetadataRegistry {
|
|
|
2934
3076
|
* assistance.
|
|
2935
3077
|
*/
|
|
2936
3078
|
class ResourceRegistry {
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
this.externalStyleToComponentsMap = new Map();
|
|
2942
|
-
}
|
|
3079
|
+
externalTemplateToComponentsMap = new Map();
|
|
3080
|
+
componentToTemplateMap = new Map();
|
|
3081
|
+
componentToStylesMap = new Map();
|
|
3082
|
+
externalStyleToComponentsMap = new Map();
|
|
2943
3083
|
getComponentsWithTemplate(template) {
|
|
2944
3084
|
if (!this.externalTemplateToComponentsMap.has(template)) {
|
|
2945
3085
|
return new Set();
|
|
@@ -3002,14 +3142,15 @@ class ResourceRegistry {
|
|
|
3002
3142
|
* the NgModule & standalone import graph.
|
|
3003
3143
|
*/
|
|
3004
3144
|
class ExportedProviderStatusResolver {
|
|
3145
|
+
metaReader;
|
|
3146
|
+
/**
|
|
3147
|
+
* `ClassDeclaration`s that we are in the process of determining the provider status for.
|
|
3148
|
+
*
|
|
3149
|
+
* This is used to detect cycles in the import graph and avoid getting stuck in them.
|
|
3150
|
+
*/
|
|
3151
|
+
calculating = new Set();
|
|
3005
3152
|
constructor(metaReader) {
|
|
3006
3153
|
this.metaReader = metaReader;
|
|
3007
|
-
/**
|
|
3008
|
-
* `ClassDeclaration`s that we are in the process of determining the provider status for.
|
|
3009
|
-
*
|
|
3010
|
-
* This is used to detect cycles in the import graph and avoid getting stuck in them.
|
|
3011
|
-
*/
|
|
3012
|
-
this.calculating = new Set();
|
|
3013
3154
|
}
|
|
3014
3155
|
/**
|
|
3015
3156
|
* Determines whether `ref` may or may not export providers to NgModules which import it.
|
|
@@ -3080,9 +3221,10 @@ class ExportedProviderStatusResolver {
|
|
|
3080
3221
|
const EMPTY_ARRAY$1 = [];
|
|
3081
3222
|
/** Resolves the host directives of a directive to a flat array of matches. */
|
|
3082
3223
|
class HostDirectivesResolver {
|
|
3224
|
+
metaReader;
|
|
3225
|
+
cache = new Map();
|
|
3083
3226
|
constructor(metaReader) {
|
|
3084
3227
|
this.metaReader = metaReader;
|
|
3085
|
-
this.cache = new Map();
|
|
3086
3228
|
}
|
|
3087
3229
|
/** Resolves all of the host directives that apply to a directive. */
|
|
3088
3230
|
resolve(metadata) {
|
|
@@ -3226,9 +3368,10 @@ function traceDynamicValue(node, value) {
|
|
|
3226
3368
|
return value.accept(new TraceDynamicValueVisitor(node));
|
|
3227
3369
|
}
|
|
3228
3370
|
class TraceDynamicValueVisitor {
|
|
3371
|
+
node;
|
|
3372
|
+
currentContainerNode = null;
|
|
3229
3373
|
constructor(node) {
|
|
3230
3374
|
this.node = node;
|
|
3231
|
-
this.currentContainerNode = null;
|
|
3232
3375
|
}
|
|
3233
3376
|
visitDynamicInput(value) {
|
|
3234
3377
|
const trace = value.reason.accept(this);
|
|
@@ -3326,6 +3469,9 @@ function getContainerNode(node) {
|
|
|
3326
3469
|
}
|
|
3327
3470
|
|
|
3328
3471
|
class PartialEvaluator {
|
|
3472
|
+
host;
|
|
3473
|
+
checker;
|
|
3474
|
+
dependencyTracker;
|
|
3329
3475
|
constructor(host, checker, dependencyTracker) {
|
|
3330
3476
|
this.host = host;
|
|
3331
3477
|
this.checker = checker;
|
|
@@ -3380,6 +3526,12 @@ function timeSinceInMicros(mark) {
|
|
|
3380
3526
|
* A `PerfRecorder` that actively tracks performance statistics.
|
|
3381
3527
|
*/
|
|
3382
3528
|
class ActivePerfRecorder {
|
|
3529
|
+
zeroTime;
|
|
3530
|
+
counters;
|
|
3531
|
+
phaseTime;
|
|
3532
|
+
bytes;
|
|
3533
|
+
currentPhase = checker.PerfPhase.Unaccounted;
|
|
3534
|
+
currentPhaseEntered;
|
|
3383
3535
|
/**
|
|
3384
3536
|
* Creates an `ActivePerfRecorder` with its zero point set to the current time.
|
|
3385
3537
|
*/
|
|
@@ -3388,7 +3540,6 @@ class ActivePerfRecorder {
|
|
|
3388
3540
|
}
|
|
3389
3541
|
constructor(zeroTime) {
|
|
3390
3542
|
this.zeroTime = zeroTime;
|
|
3391
|
-
this.currentPhase = checker.PerfPhase.Unaccounted;
|
|
3392
3543
|
this.currentPhaseEntered = this.zeroTime;
|
|
3393
3544
|
this.counters = Array(checker.PerfEvent.LAST).fill(0);
|
|
3394
3545
|
this.phaseTime = Array(checker.PerfPhase.LAST).fill(0);
|
|
@@ -3463,6 +3614,7 @@ class ActivePerfRecorder {
|
|
|
3463
3614
|
* the same `NgCompiler` for a new compilation.
|
|
3464
3615
|
*/
|
|
3465
3616
|
class DelegatingPerfRecorder {
|
|
3617
|
+
target;
|
|
3466
3618
|
constructor(target) {
|
|
3467
3619
|
this.target = target;
|
|
3468
3620
|
}
|
|
@@ -3503,6 +3655,32 @@ class DelegatingPerfRecorder {
|
|
|
3503
3655
|
* class (like adding fields or type declarations).
|
|
3504
3656
|
*/
|
|
3505
3657
|
class TraitCompiler {
|
|
3658
|
+
handlers;
|
|
3659
|
+
reflector;
|
|
3660
|
+
perf;
|
|
3661
|
+
incrementalBuild;
|
|
3662
|
+
compileNonExportedClasses;
|
|
3663
|
+
compilationMode;
|
|
3664
|
+
dtsTransforms;
|
|
3665
|
+
semanticDepGraphUpdater;
|
|
3666
|
+
sourceFileTypeIdentifier;
|
|
3667
|
+
/**
|
|
3668
|
+
* Maps class declarations to their `ClassRecord`, which tracks the Ivy traits being applied to
|
|
3669
|
+
* those classes.
|
|
3670
|
+
*/
|
|
3671
|
+
classes = new Map();
|
|
3672
|
+
/**
|
|
3673
|
+
* Maps source files to any class declaration(s) within them which have been discovered to contain
|
|
3674
|
+
* Ivy traits.
|
|
3675
|
+
*/
|
|
3676
|
+
fileToClasses = new Map();
|
|
3677
|
+
/**
|
|
3678
|
+
* Tracks which source files have been analyzed but did not contain any traits. This set allows
|
|
3679
|
+
* the compiler to skip analyzing these files in an incremental rebuild.
|
|
3680
|
+
*/
|
|
3681
|
+
filesWithoutTraits = new Set();
|
|
3682
|
+
reexportMap = new Map();
|
|
3683
|
+
handlersByName = new Map();
|
|
3506
3684
|
constructor(handlers, reflector, perf, incrementalBuild, compileNonExportedClasses, compilationMode, dtsTransforms, semanticDepGraphUpdater, sourceFileTypeIdentifier) {
|
|
3507
3685
|
this.handlers = handlers;
|
|
3508
3686
|
this.reflector = reflector;
|
|
@@ -3513,23 +3691,6 @@ class TraitCompiler {
|
|
|
3513
3691
|
this.dtsTransforms = dtsTransforms;
|
|
3514
3692
|
this.semanticDepGraphUpdater = semanticDepGraphUpdater;
|
|
3515
3693
|
this.sourceFileTypeIdentifier = sourceFileTypeIdentifier;
|
|
3516
|
-
/**
|
|
3517
|
-
* Maps class declarations to their `ClassRecord`, which tracks the Ivy traits being applied to
|
|
3518
|
-
* those classes.
|
|
3519
|
-
*/
|
|
3520
|
-
this.classes = new Map();
|
|
3521
|
-
/**
|
|
3522
|
-
* Maps source files to any class declaration(s) within them which have been discovered to contain
|
|
3523
|
-
* Ivy traits.
|
|
3524
|
-
*/
|
|
3525
|
-
this.fileToClasses = new Map();
|
|
3526
|
-
/**
|
|
3527
|
-
* Tracks which source files have been analyzed but did not contain any traits. This set allows
|
|
3528
|
-
* the compiler to skip analyzing these files in an incremental rebuild.
|
|
3529
|
-
*/
|
|
3530
|
-
this.filesWithoutTraits = new Set();
|
|
3531
|
-
this.reexportMap = new Map();
|
|
3532
|
-
this.handlersByName = new Map();
|
|
3533
3694
|
for (const handler of handlers) {
|
|
3534
3695
|
this.handlersByName.set(handler.name, handler);
|
|
3535
3696
|
}
|
|
@@ -4024,6 +4185,25 @@ class TraitCompiler {
|
|
|
4024
4185
|
// Return the instruction to the transformer so the fields will be added.
|
|
4025
4186
|
return res.length > 0 ? res : null;
|
|
4026
4187
|
}
|
|
4188
|
+
compileHmrUpdateCallback(clazz) {
|
|
4189
|
+
const original = ts__default["default"].getOriginalNode(clazz);
|
|
4190
|
+
if (!this.reflector.isClass(clazz) ||
|
|
4191
|
+
!this.reflector.isClass(original) ||
|
|
4192
|
+
!this.classes.has(original)) {
|
|
4193
|
+
return null;
|
|
4194
|
+
}
|
|
4195
|
+
const record = this.classes.get(original);
|
|
4196
|
+
for (const trait of record.traits) {
|
|
4197
|
+
// Cannot compile a trait that is not resolved, or had any errors in its declaration.
|
|
4198
|
+
if (trait.state === checker.TraitState.Resolved &&
|
|
4199
|
+
trait.handler.compileHmrUpdateDeclaration !== undefined &&
|
|
4200
|
+
!containsErrors(trait.analysisDiagnostics) &&
|
|
4201
|
+
!containsErrors(trait.resolveDiagnostics)) {
|
|
4202
|
+
return trait.handler.compileHmrUpdateDeclaration(clazz, trait.analysis, trait.resolution);
|
|
4203
|
+
}
|
|
4204
|
+
}
|
|
4205
|
+
return null;
|
|
4206
|
+
}
|
|
4027
4207
|
decoratorsFor(node) {
|
|
4028
4208
|
const original = ts__default["default"].getOriginalNode(node);
|
|
4029
4209
|
if (!this.reflector.isClass(original) || !this.classes.has(original)) {
|
|
@@ -4075,9 +4255,7 @@ function containsErrors(diagnostics) {
|
|
|
4075
4255
|
* have their declaration file transformed.
|
|
4076
4256
|
*/
|
|
4077
4257
|
class DtsTransformRegistry {
|
|
4078
|
-
|
|
4079
|
-
this.ivyDeclarationTransforms = new Map();
|
|
4080
|
-
}
|
|
4258
|
+
ivyDeclarationTransforms = new Map();
|
|
4081
4259
|
getIvyDeclarationTransform(sf) {
|
|
4082
4260
|
if (!this.ivyDeclarationTransforms.has(sf)) {
|
|
4083
4261
|
this.ivyDeclarationTransforms.set(sf, new IvyDeclarationDtsTransform());
|
|
@@ -4125,6 +4303,10 @@ function declarationTransformFactory(transformRegistry, reflector, refEmitter, i
|
|
|
4125
4303
|
* Processes .d.ts file text and adds static field declarations, with types.
|
|
4126
4304
|
*/
|
|
4127
4305
|
class DtsTransformer {
|
|
4306
|
+
ctx;
|
|
4307
|
+
reflector;
|
|
4308
|
+
refEmitter;
|
|
4309
|
+
importRewriter;
|
|
4128
4310
|
constructor(ctx, reflector, refEmitter, importRewriter) {
|
|
4129
4311
|
this.ctx = ctx;
|
|
4130
4312
|
this.reflector = reflector;
|
|
@@ -4206,9 +4388,7 @@ class DtsTransformer {
|
|
|
4206
4388
|
}
|
|
4207
4389
|
}
|
|
4208
4390
|
class IvyDeclarationDtsTransform {
|
|
4209
|
-
|
|
4210
|
-
this.declarationFields = new Map();
|
|
4211
|
-
}
|
|
4391
|
+
declarationFields = new Map();
|
|
4212
4392
|
addFields(decl, fields) {
|
|
4213
4393
|
this.declarationFields.set(decl, fields);
|
|
4214
4394
|
}
|
|
@@ -4254,16 +4434,14 @@ function visit(node, visitor, context) {
|
|
|
4254
4434
|
* of other nodes before them.
|
|
4255
4435
|
*/
|
|
4256
4436
|
class Visitor {
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
this._after = new Map();
|
|
4266
|
-
}
|
|
4437
|
+
/**
|
|
4438
|
+
* Maps statements to an array of statements that should be inserted before them.
|
|
4439
|
+
*/
|
|
4440
|
+
_before = new Map();
|
|
4441
|
+
/**
|
|
4442
|
+
* Maps statements to an array of statements that should be inserted after them.
|
|
4443
|
+
*/
|
|
4444
|
+
_after = new Map();
|
|
4267
4445
|
_visitListEntryNode(node, visitor) {
|
|
4268
4446
|
const result = visitor(node);
|
|
4269
4447
|
if (result.before !== undefined) {
|
|
@@ -4349,12 +4527,14 @@ function ivyTransformFactory(compilation, reflector, importRewriter, defaultImpo
|
|
|
4349
4527
|
* does NOT perform any TS transformations.
|
|
4350
4528
|
*/
|
|
4351
4529
|
class IvyCompilationVisitor extends Visitor {
|
|
4530
|
+
compilation;
|
|
4531
|
+
constantPool;
|
|
4532
|
+
classCompilationMap = new Map();
|
|
4533
|
+
deferrableImports = new Set();
|
|
4352
4534
|
constructor(compilation, constantPool) {
|
|
4353
4535
|
super();
|
|
4354
4536
|
this.compilation = compilation;
|
|
4355
4537
|
this.constantPool = constantPool;
|
|
4356
|
-
this.classCompilationMap = new Map();
|
|
4357
|
-
this.deferrableImports = new Set();
|
|
4358
4538
|
}
|
|
4359
4539
|
visitClassDeclaration(node) {
|
|
4360
4540
|
// Determine if this class has an Ivy field that needs to be added, and compile the field
|
|
@@ -4379,6 +4559,14 @@ class IvyCompilationVisitor extends Visitor {
|
|
|
4379
4559
|
* compilation results (provided as an argument).
|
|
4380
4560
|
*/
|
|
4381
4561
|
class IvyTransformationVisitor extends Visitor {
|
|
4562
|
+
compilation;
|
|
4563
|
+
classCompilationMap;
|
|
4564
|
+
reflector;
|
|
4565
|
+
importManager;
|
|
4566
|
+
recordWrappedNodeExpr;
|
|
4567
|
+
isClosureCompilerEnabled;
|
|
4568
|
+
isCore;
|
|
4569
|
+
deferrableImports;
|
|
4382
4570
|
constructor(compilation, classCompilationMap, reflector, importManager, recordWrappedNodeExpr, isClosureCompilerEnabled, isCore, deferrableImports) {
|
|
4383
4571
|
super();
|
|
4384
4572
|
this.compilation = compilation;
|
|
@@ -5036,10 +5224,12 @@ function compileDeclareFactory(metadata) {
|
|
|
5036
5224
|
* injectables, directives, pipes).
|
|
5037
5225
|
*/
|
|
5038
5226
|
class InjectableClassRegistry {
|
|
5227
|
+
host;
|
|
5228
|
+
isCore;
|
|
5229
|
+
classes = new Map();
|
|
5039
5230
|
constructor(host, isCore) {
|
|
5040
5231
|
this.host = host;
|
|
5041
5232
|
this.isCore = isCore;
|
|
5042
|
-
this.classes = new Map();
|
|
5043
5233
|
}
|
|
5044
5234
|
registerInjectable(declaration, meta) {
|
|
5045
5235
|
this.classes.set(declaration, meta);
|
|
@@ -5205,12 +5395,12 @@ function removeIdentifierReferences(node, names) {
|
|
|
5205
5395
|
return result.transformed[0];
|
|
5206
5396
|
}
|
|
5207
5397
|
|
|
5208
|
-
function extractClassDebugInfo(clazz, reflection, rootDirs, forbidOrphanRendering) {
|
|
5398
|
+
function extractClassDebugInfo(clazz, reflection, compilerHost, rootDirs, forbidOrphanRendering) {
|
|
5209
5399
|
if (!reflection.isClass(clazz)) {
|
|
5210
5400
|
return null;
|
|
5211
5401
|
}
|
|
5212
5402
|
const srcFile = clazz.getSourceFile();
|
|
5213
|
-
const srcFileMaybeRelativePath =
|
|
5403
|
+
const srcFileMaybeRelativePath = getProjectRelativePath(srcFile, rootDirs, compilerHost);
|
|
5214
5404
|
return {
|
|
5215
5405
|
type: new checker.WrappedNodeExpr(clazz.name),
|
|
5216
5406
|
className: checker.literal(clazz.name.getText()),
|
|
@@ -5219,19 +5409,6 @@ function extractClassDebugInfo(clazz, reflection, rootDirs, forbidOrphanRenderin
|
|
|
5219
5409
|
forbidOrphanRendering,
|
|
5220
5410
|
};
|
|
5221
5411
|
}
|
|
5222
|
-
/**
|
|
5223
|
-
* Computes a source file path relative to the project root folder if possible, otherwise returns
|
|
5224
|
-
* null.
|
|
5225
|
-
*/
|
|
5226
|
-
function computeRelativePathIfPossible(filePath, rootDirs) {
|
|
5227
|
-
for (const rootDir of rootDirs) {
|
|
5228
|
-
const rel = p__namespace.relative(rootDir, filePath);
|
|
5229
|
-
if (!rel.startsWith('..')) {
|
|
5230
|
-
return rel;
|
|
5231
|
-
}
|
|
5232
|
-
}
|
|
5233
|
-
return null;
|
|
5234
|
-
}
|
|
5235
5412
|
|
|
5236
5413
|
/**
|
|
5237
5414
|
* This registry does nothing.
|
|
@@ -5302,9 +5479,7 @@ function compileInputTransformFields(inputs) {
|
|
|
5302
5479
|
* marked for JIT compilation and are skipping compilation by trait handlers.
|
|
5303
5480
|
*/
|
|
5304
5481
|
class JitDeclarationRegistry {
|
|
5305
|
-
|
|
5306
|
-
this.jitDeclarations = new Set();
|
|
5307
|
-
}
|
|
5482
|
+
jitDeclarations = new Set();
|
|
5308
5483
|
}
|
|
5309
5484
|
|
|
5310
5485
|
/**
|
|
@@ -5314,6 +5489,21 @@ class JitDeclarationRegistry {
|
|
|
5314
5489
|
* from the prior compilation.
|
|
5315
5490
|
*/
|
|
5316
5491
|
class SemanticSymbol {
|
|
5492
|
+
decl;
|
|
5493
|
+
/**
|
|
5494
|
+
* The path of the file that declares this symbol.
|
|
5495
|
+
*/
|
|
5496
|
+
path;
|
|
5497
|
+
/**
|
|
5498
|
+
* The identifier of this symbol, or null if no identifier could be determined. It should
|
|
5499
|
+
* uniquely identify the symbol relative to `file`. This is typically just the name of a
|
|
5500
|
+
* top-level class declaration, as that uniquely identifies the class within the file.
|
|
5501
|
+
*
|
|
5502
|
+
* If the identifier is null, then this symbol cannot be recognized across rebuilds. In that
|
|
5503
|
+
* case, the symbol is always assumed to have semantically changed to guarantee a proper
|
|
5504
|
+
* rebuild.
|
|
5505
|
+
*/
|
|
5506
|
+
identifier;
|
|
5317
5507
|
constructor(
|
|
5318
5508
|
/**
|
|
5319
5509
|
* The declaration for this symbol.
|
|
@@ -5352,14 +5542,12 @@ class OpaqueSymbol extends SemanticSymbol {
|
|
|
5352
5542
|
* The semantic dependency graph of a single compilation.
|
|
5353
5543
|
*/
|
|
5354
5544
|
class SemanticDepGraph {
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
this.symbolByDecl = new Map();
|
|
5362
|
-
}
|
|
5545
|
+
files = new Map();
|
|
5546
|
+
// Note: the explicit type annotation is used to work around a CI failure on Windows:
|
|
5547
|
+
// error TS2742: The inferred type of 'symbolByDecl' cannot be named without a reference to
|
|
5548
|
+
// '../../../../../../../external/npm/node_modules/typescript/lib/typescript'. This is likely
|
|
5549
|
+
// not portable. A type annotation is necessary.
|
|
5550
|
+
symbolByDecl = new Map();
|
|
5363
5551
|
/**
|
|
5364
5552
|
* Registers a symbol in the graph. The symbol is given a unique identifier if possible, such that
|
|
5365
5553
|
* its equivalent symbol can be obtained from a prior graph even if its declaration node has
|
|
@@ -5426,6 +5614,13 @@ class SemanticDepGraph {
|
|
|
5426
5614
|
* on which files have been affected.
|
|
5427
5615
|
*/
|
|
5428
5616
|
class SemanticDepGraphUpdater {
|
|
5617
|
+
priorGraph;
|
|
5618
|
+
newGraph = new SemanticDepGraph();
|
|
5619
|
+
/**
|
|
5620
|
+
* Contains opaque symbols that were created for declarations for which there was no symbol
|
|
5621
|
+
* registered, which happens for e.g. external declarations.
|
|
5622
|
+
*/
|
|
5623
|
+
opaqueSymbols = new Map();
|
|
5429
5624
|
constructor(
|
|
5430
5625
|
/**
|
|
5431
5626
|
* The semantic dependency graph of the most recently succeeded compilation, or null if this
|
|
@@ -5433,12 +5628,6 @@ class SemanticDepGraphUpdater {
|
|
|
5433
5628
|
*/
|
|
5434
5629
|
priorGraph) {
|
|
5435
5630
|
this.priorGraph = priorGraph;
|
|
5436
|
-
this.newGraph = new SemanticDepGraph();
|
|
5437
|
-
/**
|
|
5438
|
-
* Contains opaque symbols that were created for declarations for which there was no symbol
|
|
5439
|
-
* registered, which happens for e.g. external declarations.
|
|
5440
|
-
*/
|
|
5441
|
-
this.opaqueSymbols = new Map();
|
|
5442
5631
|
}
|
|
5443
5632
|
/**
|
|
5444
5633
|
* Registers the symbol in the new graph that is being created.
|
|
@@ -5676,6 +5865,7 @@ function isTypeParameterEqual(a, b) {
|
|
|
5676
5865
|
* registry and from the incremental state).
|
|
5677
5866
|
*/
|
|
5678
5867
|
class CompoundComponentScopeReader {
|
|
5868
|
+
readers;
|
|
5679
5869
|
constructor(readers) {
|
|
5680
5870
|
this.readers = readers;
|
|
5681
5871
|
}
|
|
@@ -5707,16 +5897,18 @@ class CompoundComponentScopeReader {
|
|
|
5707
5897
|
* fields on directives, components, pipes, and NgModules.
|
|
5708
5898
|
*/
|
|
5709
5899
|
class MetadataDtsModuleScopeResolver {
|
|
5900
|
+
dtsMetaReader;
|
|
5901
|
+
aliasingHost;
|
|
5902
|
+
/**
|
|
5903
|
+
* Cache which holds fully resolved scopes for NgModule classes from .d.ts files.
|
|
5904
|
+
*/
|
|
5905
|
+
cache = new Map();
|
|
5710
5906
|
/**
|
|
5711
5907
|
* @param dtsMetaReader a `MetadataReader` which can read metadata from `.d.ts` files.
|
|
5712
5908
|
*/
|
|
5713
5909
|
constructor(dtsMetaReader, aliasingHost) {
|
|
5714
5910
|
this.dtsMetaReader = dtsMetaReader;
|
|
5715
5911
|
this.aliasingHost = aliasingHost;
|
|
5716
|
-
/**
|
|
5717
|
-
* Cache which holds fully resolved scopes for NgModule classes from .d.ts files.
|
|
5718
|
-
*/
|
|
5719
|
-
this.cache = new Map();
|
|
5720
5912
|
}
|
|
5721
5913
|
/**
|
|
5722
5914
|
* Resolve a `Reference`'d NgModule from a .d.ts file and produce a transitive `ExportScope`
|
|
@@ -5850,6 +6042,8 @@ function makeUnknownComponentDeferredImportDiagnostic(ref, rawExpr) {
|
|
|
5850
6042
|
return checker.makeDiagnostic(checker.ErrorCode.COMPONENT_UNKNOWN_DEFERRED_IMPORT, getDiagnosticNode(ref, rawExpr), `Component deferred imports must be standalone components, directives or pipes.`);
|
|
5851
6043
|
}
|
|
5852
6044
|
|
|
6045
|
+
/** Value used to mark a module whose scope is in the process of being resolved. */
|
|
6046
|
+
const IN_PROGRESS_RESOLUTION = {};
|
|
5853
6047
|
/**
|
|
5854
6048
|
* A registry which collects information about NgModules, Directives, Components, and Pipes which
|
|
5855
6049
|
* are local (declared in the ts.Program being compiled), and can produce `LocalModuleScope`s
|
|
@@ -5870,54 +6064,59 @@ function makeUnknownComponentDeferredImportDiagnostic(ref, rawExpr) {
|
|
|
5870
6064
|
* semantics are violated.
|
|
5871
6065
|
*/
|
|
5872
6066
|
class LocalModuleScopeRegistry {
|
|
6067
|
+
localReader;
|
|
6068
|
+
fullReader;
|
|
6069
|
+
dependencyScopeReader;
|
|
6070
|
+
refEmitter;
|
|
6071
|
+
aliasingHost;
|
|
6072
|
+
/**
|
|
6073
|
+
* Tracks whether the registry has been asked to produce scopes for a module or component. Once
|
|
6074
|
+
* this is true, the registry cannot accept registrations of new directives/pipes/modules as it
|
|
6075
|
+
* would invalidate the cached scope data.
|
|
6076
|
+
*/
|
|
6077
|
+
sealed = false;
|
|
6078
|
+
/**
|
|
6079
|
+
* A map of components from the current compilation unit to the NgModule which declared them.
|
|
6080
|
+
*
|
|
6081
|
+
* As components and directives are not distinguished at the NgModule level, this map may also
|
|
6082
|
+
* contain directives. This doesn't cause any problems but isn't useful as there is no concept of
|
|
6083
|
+
* a directive's compilation scope.
|
|
6084
|
+
*/
|
|
6085
|
+
declarationToModule = new Map();
|
|
6086
|
+
/**
|
|
6087
|
+
* This maps from the directive/pipe class to a map of data for each NgModule that declares the
|
|
6088
|
+
* directive/pipe. This data is needed to produce an error for the given class.
|
|
6089
|
+
*/
|
|
6090
|
+
duplicateDeclarations = new Map();
|
|
6091
|
+
moduleToRef = new Map();
|
|
6092
|
+
/**
|
|
6093
|
+
* A cache of calculated `LocalModuleScope`s for each NgModule declared in the current program.
|
|
6094
|
+
|
|
6095
|
+
*/
|
|
6096
|
+
cache = new Map();
|
|
6097
|
+
/**
|
|
6098
|
+
* Tracks the `RemoteScope` for components requiring "remote scoping".
|
|
6099
|
+
*
|
|
6100
|
+
* Remote scoping is when the set of directives which apply to a given component is set in the
|
|
6101
|
+
* NgModule's file instead of directly on the component def (which is sometimes needed to get
|
|
6102
|
+
* around cyclic import issues). This is not used in calculation of `LocalModuleScope`s, but is
|
|
6103
|
+
* tracked here for convenience.
|
|
6104
|
+
*/
|
|
6105
|
+
remoteScoping = new Map();
|
|
6106
|
+
/**
|
|
6107
|
+
* Tracks errors accumulated in the processing of scopes for each module declaration.
|
|
6108
|
+
*/
|
|
6109
|
+
scopeErrors = new Map();
|
|
6110
|
+
/**
|
|
6111
|
+
* Tracks which NgModules have directives/pipes that are declared in more than one module.
|
|
6112
|
+
*/
|
|
6113
|
+
modulesWithStructuralErrors = new Set();
|
|
5873
6114
|
constructor(localReader, fullReader, dependencyScopeReader, refEmitter, aliasingHost) {
|
|
5874
6115
|
this.localReader = localReader;
|
|
5875
6116
|
this.fullReader = fullReader;
|
|
5876
6117
|
this.dependencyScopeReader = dependencyScopeReader;
|
|
5877
6118
|
this.refEmitter = refEmitter;
|
|
5878
6119
|
this.aliasingHost = aliasingHost;
|
|
5879
|
-
/**
|
|
5880
|
-
* Tracks whether the registry has been asked to produce scopes for a module or component. Once
|
|
5881
|
-
* this is true, the registry cannot accept registrations of new directives/pipes/modules as it
|
|
5882
|
-
* would invalidate the cached scope data.
|
|
5883
|
-
*/
|
|
5884
|
-
this.sealed = false;
|
|
5885
|
-
/**
|
|
5886
|
-
* A map of components from the current compilation unit to the NgModule which declared them.
|
|
5887
|
-
*
|
|
5888
|
-
* As components and directives are not distinguished at the NgModule level, this map may also
|
|
5889
|
-
* contain directives. This doesn't cause any problems but isn't useful as there is no concept of
|
|
5890
|
-
* a directive's compilation scope.
|
|
5891
|
-
*/
|
|
5892
|
-
this.declarationToModule = new Map();
|
|
5893
|
-
/**
|
|
5894
|
-
* This maps from the directive/pipe class to a map of data for each NgModule that declares the
|
|
5895
|
-
* directive/pipe. This data is needed to produce an error for the given class.
|
|
5896
|
-
*/
|
|
5897
|
-
this.duplicateDeclarations = new Map();
|
|
5898
|
-
this.moduleToRef = new Map();
|
|
5899
|
-
/**
|
|
5900
|
-
* A cache of calculated `LocalModuleScope`s for each NgModule declared in the current program.
|
|
5901
|
-
|
|
5902
|
-
*/
|
|
5903
|
-
this.cache = new Map();
|
|
5904
|
-
/**
|
|
5905
|
-
* Tracks the `RemoteScope` for components requiring "remote scoping".
|
|
5906
|
-
*
|
|
5907
|
-
* Remote scoping is when the set of directives which apply to a given component is set in the
|
|
5908
|
-
* NgModule's file instead of directly on the component def (which is sometimes needed to get
|
|
5909
|
-
* around cyclic import issues). This is not used in calculation of `LocalModuleScope`s, but is
|
|
5910
|
-
* tracked here for convenience.
|
|
5911
|
-
*/
|
|
5912
|
-
this.remoteScoping = new Map();
|
|
5913
|
-
/**
|
|
5914
|
-
* Tracks errors accumulated in the processing of scopes for each module declaration.
|
|
5915
|
-
*/
|
|
5916
|
-
this.scopeErrors = new Map();
|
|
5917
|
-
/**
|
|
5918
|
-
* Tracks which NgModules have directives/pipes that are declared in more than one module.
|
|
5919
|
-
*/
|
|
5920
|
-
this.modulesWithStructuralErrors = new Set();
|
|
5921
6120
|
}
|
|
5922
6121
|
/**
|
|
5923
6122
|
* Add an NgModule's data to the registry.
|
|
@@ -6021,8 +6220,12 @@ class LocalModuleScopeRegistry {
|
|
|
6021
6220
|
*/
|
|
6022
6221
|
getScopeOfModuleReference(ref) {
|
|
6023
6222
|
if (this.cache.has(ref.node)) {
|
|
6024
|
-
|
|
6223
|
+
const cachedValue = this.cache.get(ref.node);
|
|
6224
|
+
if (cachedValue !== IN_PROGRESS_RESOLUTION) {
|
|
6225
|
+
return cachedValue;
|
|
6226
|
+
}
|
|
6025
6227
|
}
|
|
6228
|
+
this.cache.set(ref.node, IN_PROGRESS_RESOLUTION);
|
|
6026
6229
|
// Seal the registry to protect the integrity of the `LocalModuleScope` cache.
|
|
6027
6230
|
this.sealed = true;
|
|
6028
6231
|
// `ref` should be an NgModule previously added to the registry. If not, a scope for it
|
|
@@ -6067,13 +6270,18 @@ class LocalModuleScopeRegistry {
|
|
|
6067
6270
|
for (const decl of ngModule.imports) {
|
|
6068
6271
|
const importScope = this.getExportedScope(decl, diagnostics, ref.node, 'import');
|
|
6069
6272
|
if (importScope !== null) {
|
|
6070
|
-
if (importScope === 'invalid' ||
|
|
6273
|
+
if (importScope === 'invalid' ||
|
|
6274
|
+
importScope === 'cycle' ||
|
|
6275
|
+
importScope.exported.isPoisoned) {
|
|
6071
6276
|
// An import was an NgModule but contained errors of its own. Record this as an error too,
|
|
6072
6277
|
// because this scope is always going to be incorrect if one of its imports could not be
|
|
6073
6278
|
// read.
|
|
6074
|
-
diagnostics.push(invalidTransitiveNgModuleRef(decl, ngModule.rawImports, 'import'));
|
|
6075
6279
|
isPoisoned = true;
|
|
6076
|
-
|
|
6280
|
+
// Prevent the module from reporting a diagnostic about itself when there's a cycle.
|
|
6281
|
+
if (importScope !== 'cycle') {
|
|
6282
|
+
diagnostics.push(invalidTransitiveNgModuleRef(decl, ngModule.rawImports, 'import'));
|
|
6283
|
+
}
|
|
6284
|
+
if (importScope === 'invalid' || importScope === 'cycle') {
|
|
6077
6285
|
continue;
|
|
6078
6286
|
}
|
|
6079
6287
|
}
|
|
@@ -6159,13 +6367,18 @@ class LocalModuleScopeRegistry {
|
|
|
6159
6367
|
for (const decl of ngModule.exports) {
|
|
6160
6368
|
// Attempt to resolve decl as an NgModule.
|
|
6161
6369
|
const exportScope = this.getExportedScope(decl, diagnostics, ref.node, 'export');
|
|
6162
|
-
if (exportScope === 'invalid' ||
|
|
6370
|
+
if (exportScope === 'invalid' ||
|
|
6371
|
+
exportScope === 'cycle' ||
|
|
6372
|
+
(exportScope !== null && exportScope.exported.isPoisoned)) {
|
|
6163
6373
|
// An export was an NgModule but contained errors of its own. Record this as an error too,
|
|
6164
6374
|
// because this scope is always going to be incorrect if one of its exports could not be
|
|
6165
6375
|
// read.
|
|
6166
|
-
diagnostics.push(invalidTransitiveNgModuleRef(decl, ngModule.rawExports, 'export'));
|
|
6167
6376
|
isPoisoned = true;
|
|
6168
|
-
|
|
6377
|
+
// Prevent the module from reporting a diagnostic about itself when there's a cycle.
|
|
6378
|
+
if (exportScope !== 'cycle') {
|
|
6379
|
+
diagnostics.push(invalidTransitiveNgModuleRef(decl, ngModule.rawExports, 'export'));
|
|
6380
|
+
}
|
|
6381
|
+
if (exportScope === 'invalid' || exportScope === 'cycle') {
|
|
6169
6382
|
continue;
|
|
6170
6383
|
}
|
|
6171
6384
|
}
|
|
@@ -6270,6 +6483,12 @@ class LocalModuleScopeRegistry {
|
|
|
6270
6483
|
return this.dependencyScopeReader.resolve(ref);
|
|
6271
6484
|
}
|
|
6272
6485
|
else {
|
|
6486
|
+
if (this.cache.get(ref.node) === IN_PROGRESS_RESOLUTION) {
|
|
6487
|
+
diagnostics.push(checker.makeDiagnostic(type === 'import'
|
|
6488
|
+
? checker.ErrorCode.NGMODULE_INVALID_IMPORT
|
|
6489
|
+
: checker.ErrorCode.NGMODULE_INVALID_EXPORT, checker.identifierOfNode(ref.node) || ref.node, `NgModule "${type}" field contains a cycle`));
|
|
6490
|
+
return 'cycle';
|
|
6491
|
+
}
|
|
6273
6492
|
// The NgModule is declared locally in the current program. Resolve it from the registry.
|
|
6274
6493
|
return this.getScopeOfModuleReference(ref);
|
|
6275
6494
|
}
|
|
@@ -6423,19 +6642,22 @@ function reexportCollision(module, refA, refB) {
|
|
|
6423
6642
|
* Computes scope information to be used in template type checking.
|
|
6424
6643
|
*/
|
|
6425
6644
|
class TypeCheckScopeRegistry {
|
|
6645
|
+
scopeReader;
|
|
6646
|
+
metaReader;
|
|
6647
|
+
hostDirectivesResolver;
|
|
6648
|
+
/**
|
|
6649
|
+
* Cache of flattened directive metadata. Because flattened metadata is scope-invariant it's
|
|
6650
|
+
* cached individually, such that all scopes refer to the same flattened metadata.
|
|
6651
|
+
*/
|
|
6652
|
+
flattenedDirectiveMetaCache = new Map();
|
|
6653
|
+
/**
|
|
6654
|
+
* Cache of the computed type check scope per NgModule declaration.
|
|
6655
|
+
*/
|
|
6656
|
+
scopeCache = new Map();
|
|
6426
6657
|
constructor(scopeReader, metaReader, hostDirectivesResolver) {
|
|
6427
6658
|
this.scopeReader = scopeReader;
|
|
6428
6659
|
this.metaReader = metaReader;
|
|
6429
6660
|
this.hostDirectivesResolver = hostDirectivesResolver;
|
|
6430
|
-
/**
|
|
6431
|
-
* Cache of flattened directive metadata. Because flattened metadata is scope-invariant it's
|
|
6432
|
-
* cached individually, such that all scopes refer to the same flattened metadata.
|
|
6433
|
-
*/
|
|
6434
|
-
this.flattenedDirectiveMetaCache = new Map();
|
|
6435
|
-
/**
|
|
6436
|
-
* Cache of the computed type check scope per NgModule declaration.
|
|
6437
|
-
*/
|
|
6438
|
-
this.scopeCache = new Map();
|
|
6439
6661
|
}
|
|
6440
6662
|
/**
|
|
6441
6663
|
* Computes the type-check scope information for the component declaration. If the NgModule
|
|
@@ -6532,7 +6754,7 @@ const QUERY_TYPES = new Set(queryDecoratorNames);
|
|
|
6532
6754
|
* appear in the declarations of an `NgModule` and additional verification is done when processing
|
|
6533
6755
|
* the module.
|
|
6534
6756
|
*/
|
|
6535
|
-
function extractDirectiveMetadata(clazz, decorator, reflector, importTracker, evaluator, refEmitter, referencesRegistry, isCore, annotateForClosureCompiler, compilationMode, defaultSelector, strictStandalone) {
|
|
6757
|
+
function extractDirectiveMetadata(clazz, decorator, reflector, importTracker, evaluator, refEmitter, referencesRegistry, isCore, annotateForClosureCompiler, compilationMode, defaultSelector, strictStandalone, implicitStandaloneValue) {
|
|
6536
6758
|
let directive;
|
|
6537
6759
|
if (decorator.args === null || decorator.args.length === 0) {
|
|
6538
6760
|
directive = new Map();
|
|
@@ -6636,7 +6858,7 @@ function extractDirectiveMetadata(clazz, decorator, reflector, importTracker, ev
|
|
|
6636
6858
|
ctorDeps.some((dep) => dep.token instanceof checker.ExternalExpr &&
|
|
6637
6859
|
dep.token.value.moduleName === '@angular/core' &&
|
|
6638
6860
|
dep.token.value.name === 'TemplateRef');
|
|
6639
|
-
let isStandalone =
|
|
6861
|
+
let isStandalone = implicitStandaloneValue;
|
|
6640
6862
|
if (directive.has('standalone')) {
|
|
6641
6863
|
const expr = directive.get('standalone');
|
|
6642
6864
|
const resolved = evaluator.evaluate(expr);
|
|
@@ -7513,6 +7735,13 @@ function toR3InputMetadata(mapping) {
|
|
|
7513
7735
|
* from this symbol.
|
|
7514
7736
|
*/
|
|
7515
7737
|
class DirectiveSymbol extends SemanticSymbol {
|
|
7738
|
+
selector;
|
|
7739
|
+
inputs;
|
|
7740
|
+
outputs;
|
|
7741
|
+
exportAs;
|
|
7742
|
+
typeCheckMeta;
|
|
7743
|
+
typeParameters;
|
|
7744
|
+
baseClass = null;
|
|
7516
7745
|
constructor(decl, selector, inputs, outputs, exportAs, typeCheckMeta, typeParameters) {
|
|
7517
7746
|
super(decl);
|
|
7518
7747
|
this.selector = selector;
|
|
@@ -7521,7 +7750,6 @@ class DirectiveSymbol extends SemanticSymbol {
|
|
|
7521
7750
|
this.exportAs = exportAs;
|
|
7522
7751
|
this.typeCheckMeta = typeCheckMeta;
|
|
7523
7752
|
this.typeParameters = typeParameters;
|
|
7524
|
-
this.baseClass = null;
|
|
7525
7753
|
}
|
|
7526
7754
|
isPublicApiAffected(previousSymbol) {
|
|
7527
7755
|
// Note: since components and directives have exactly the same items contributing to their
|
|
@@ -7640,7 +7868,26 @@ const LIFECYCLE_HOOKS = new Set([
|
|
|
7640
7868
|
'ngAfterContentChecked',
|
|
7641
7869
|
]);
|
|
7642
7870
|
class DirectiveDecoratorHandler {
|
|
7643
|
-
|
|
7871
|
+
reflector;
|
|
7872
|
+
evaluator;
|
|
7873
|
+
metaRegistry;
|
|
7874
|
+
scopeRegistry;
|
|
7875
|
+
metaReader;
|
|
7876
|
+
injectableRegistry;
|
|
7877
|
+
refEmitter;
|
|
7878
|
+
referencesRegistry;
|
|
7879
|
+
isCore;
|
|
7880
|
+
strictCtorDeps;
|
|
7881
|
+
semanticDepGraphUpdater;
|
|
7882
|
+
annotateForClosureCompiler;
|
|
7883
|
+
perf;
|
|
7884
|
+
importTracker;
|
|
7885
|
+
includeClassMetadata;
|
|
7886
|
+
compilationMode;
|
|
7887
|
+
jitDeclarationRegistry;
|
|
7888
|
+
strictStandalone;
|
|
7889
|
+
implicitStandaloneValue;
|
|
7890
|
+
constructor(reflector, evaluator, metaRegistry, scopeRegistry, metaReader, injectableRegistry, refEmitter, referencesRegistry, isCore, strictCtorDeps, semanticDepGraphUpdater, annotateForClosureCompiler, perf, importTracker, includeClassMetadata, compilationMode, jitDeclarationRegistry, strictStandalone, implicitStandaloneValue) {
|
|
7644
7891
|
this.reflector = reflector;
|
|
7645
7892
|
this.evaluator = evaluator;
|
|
7646
7893
|
this.metaRegistry = metaRegistry;
|
|
@@ -7659,9 +7906,10 @@ class DirectiveDecoratorHandler {
|
|
|
7659
7906
|
this.compilationMode = compilationMode;
|
|
7660
7907
|
this.jitDeclarationRegistry = jitDeclarationRegistry;
|
|
7661
7908
|
this.strictStandalone = strictStandalone;
|
|
7662
|
-
this.
|
|
7663
|
-
this.name = 'DirectiveDecoratorHandler';
|
|
7909
|
+
this.implicitStandaloneValue = implicitStandaloneValue;
|
|
7664
7910
|
}
|
|
7911
|
+
precedence = checker.HandlerPrecedence.PRIMARY;
|
|
7912
|
+
name = 'DirectiveDecoratorHandler';
|
|
7665
7913
|
detect(node, decorators) {
|
|
7666
7914
|
// If a class is undecorated but uses Angular features, we detect it as an
|
|
7667
7915
|
// abstract directive. This is an unsupported pattern as of v10, but we want
|
|
@@ -7692,7 +7940,7 @@ class DirectiveDecoratorHandler {
|
|
|
7692
7940
|
}
|
|
7693
7941
|
this.perf.eventCount(checker.PerfEvent.AnalyzeDirective);
|
|
7694
7942
|
const directiveResult = extractDirectiveMetadata(node, decorator, this.reflector, this.importTracker, this.evaluator, this.refEmitter, this.referencesRegistry, this.isCore, this.annotateForClosureCompiler, this.compilationMode,
|
|
7695
|
-
/* defaultSelector */ null, this.strictStandalone);
|
|
7943
|
+
/* defaultSelector */ null, this.strictStandalone, this.implicitStandaloneValue);
|
|
7696
7944
|
// `extractDirectiveMetadata` returns `jitForced = true` when the `@Directive` has
|
|
7697
7945
|
// set `jit: true`. In this case, compilation of the decorator is skipped. Returning
|
|
7698
7946
|
// an empty object signifies that no analysis was produced.
|
|
@@ -7955,20 +8203,21 @@ function isResolvedModuleWithProviders(sv) {
|
|
|
7955
8203
|
* Represents an Angular NgModule.
|
|
7956
8204
|
*/
|
|
7957
8205
|
class NgModuleSymbol extends SemanticSymbol {
|
|
8206
|
+
hasProviders;
|
|
8207
|
+
remotelyScopedComponents = [];
|
|
8208
|
+
/**
|
|
8209
|
+
* `SemanticSymbol`s of the transitive imports of this NgModule which came from imported
|
|
8210
|
+
* standalone components.
|
|
8211
|
+
*
|
|
8212
|
+
* Standalone components are excluded/included in the `InjectorDef` emit output of the NgModule
|
|
8213
|
+
* based on whether the compiler can prove that their transitive imports may contain exported
|
|
8214
|
+
* providers, so a change in this set of symbols may affect the compilation output of this
|
|
8215
|
+
* NgModule.
|
|
8216
|
+
*/
|
|
8217
|
+
transitiveImportsFromStandaloneComponents = new Set();
|
|
7958
8218
|
constructor(decl, hasProviders) {
|
|
7959
8219
|
super(decl);
|
|
7960
8220
|
this.hasProviders = hasProviders;
|
|
7961
|
-
this.remotelyScopedComponents = [];
|
|
7962
|
-
/**
|
|
7963
|
-
* `SemanticSymbol`s of the transitive imports of this NgModule which came from imported
|
|
7964
|
-
* standalone components.
|
|
7965
|
-
*
|
|
7966
|
-
* Standalone components are excluded/included in the `InjectorDef` emit output of the NgModule
|
|
7967
|
-
* based on whether the compiler can prove that their transitive imports may contain exported
|
|
7968
|
-
* providers, so a change in this set of symbols may affect the compilation output of this
|
|
7969
|
-
* NgModule.
|
|
7970
|
-
*/
|
|
7971
|
-
this.transitiveImportsFromStandaloneComponents = new Set();
|
|
7972
8221
|
}
|
|
7973
8222
|
isPublicApiAffected(previousSymbol) {
|
|
7974
8223
|
if (!(previousSymbol instanceof NgModuleSymbol)) {
|
|
@@ -8043,6 +8292,25 @@ class NgModuleSymbol extends SemanticSymbol {
|
|
|
8043
8292
|
* Compiles @NgModule annotations to ngModuleDef fields.
|
|
8044
8293
|
*/
|
|
8045
8294
|
class NgModuleDecoratorHandler {
|
|
8295
|
+
reflector;
|
|
8296
|
+
evaluator;
|
|
8297
|
+
metaReader;
|
|
8298
|
+
metaRegistry;
|
|
8299
|
+
scopeRegistry;
|
|
8300
|
+
referencesRegistry;
|
|
8301
|
+
exportedProviderStatusResolver;
|
|
8302
|
+
semanticDepGraphUpdater;
|
|
8303
|
+
isCore;
|
|
8304
|
+
refEmitter;
|
|
8305
|
+
annotateForClosureCompiler;
|
|
8306
|
+
onlyPublishPublicTypings;
|
|
8307
|
+
injectableRegistry;
|
|
8308
|
+
perf;
|
|
8309
|
+
includeClassMetadata;
|
|
8310
|
+
includeSelectorScope;
|
|
8311
|
+
compilationMode;
|
|
8312
|
+
localCompilationExtraImportsTracker;
|
|
8313
|
+
jitDeclarationRegistry;
|
|
8046
8314
|
constructor(reflector, evaluator, metaReader, metaRegistry, scopeRegistry, referencesRegistry, exportedProviderStatusResolver, semanticDepGraphUpdater, isCore, refEmitter, annotateForClosureCompiler, onlyPublishPublicTypings, injectableRegistry, perf, includeClassMetadata, includeSelectorScope, compilationMode, localCompilationExtraImportsTracker, jitDeclarationRegistry) {
|
|
8047
8315
|
this.reflector = reflector;
|
|
8048
8316
|
this.evaluator = evaluator;
|
|
@@ -8063,9 +8331,9 @@ class NgModuleDecoratorHandler {
|
|
|
8063
8331
|
this.compilationMode = compilationMode;
|
|
8064
8332
|
this.localCompilationExtraImportsTracker = localCompilationExtraImportsTracker;
|
|
8065
8333
|
this.jitDeclarationRegistry = jitDeclarationRegistry;
|
|
8066
|
-
this.precedence = checker.HandlerPrecedence.PRIMARY;
|
|
8067
|
-
this.name = 'NgModuleDecoratorHandler';
|
|
8068
8334
|
}
|
|
8335
|
+
precedence = checker.HandlerPrecedence.PRIMARY;
|
|
8336
|
+
name = 'NgModuleDecoratorHandler';
|
|
8069
8337
|
detect(node, decorators) {
|
|
8070
8338
|
if (!decorators) {
|
|
8071
8339
|
return undefined;
|
|
@@ -9166,12 +9434,9 @@ function _extractTemplateStyleUrls(template) {
|
|
|
9166
9434
|
* Represents an Angular component.
|
|
9167
9435
|
*/
|
|
9168
9436
|
class ComponentSymbol extends DirectiveSymbol {
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
this.usedPipes = [];
|
|
9173
|
-
this.isRemotelyScoped = false;
|
|
9174
|
-
}
|
|
9437
|
+
usedDirectives = [];
|
|
9438
|
+
usedPipes = [];
|
|
9439
|
+
isRemotelyScoped = false;
|
|
9175
9440
|
isEmitAffected(previousSymbol, publicApiAffected) {
|
|
9176
9441
|
if (!(previousSymbol instanceof ComponentSymbol)) {
|
|
9177
9442
|
return true;
|
|
@@ -9346,39 +9611,47 @@ function makeShimFileName(fileName, suffix) {
|
|
|
9346
9611
|
* (which already may contain shim files and thus have a different creation flow).
|
|
9347
9612
|
*/
|
|
9348
9613
|
class ShimAdapter {
|
|
9614
|
+
delegate;
|
|
9615
|
+
/**
|
|
9616
|
+
* A map of shim file names to the `ts.SourceFile` generated for those shims.
|
|
9617
|
+
*/
|
|
9618
|
+
shims = new Map();
|
|
9619
|
+
/**
|
|
9620
|
+
* A map of shim file names to existing shims which were part of a previous iteration of this
|
|
9621
|
+
* program.
|
|
9622
|
+
*
|
|
9623
|
+
* Not all of these shims will be inherited into this program.
|
|
9624
|
+
*/
|
|
9625
|
+
priorShims = new Map();
|
|
9626
|
+
/**
|
|
9627
|
+
* File names which are already known to not be shims.
|
|
9628
|
+
*
|
|
9629
|
+
* This allows for short-circuit returns without the expense of running regular expressions
|
|
9630
|
+
* against the filename repeatedly.
|
|
9631
|
+
*/
|
|
9632
|
+
notShims = new Set();
|
|
9633
|
+
/**
|
|
9634
|
+
* The shim generators supported by this adapter as well as extra precalculated data facilitating
|
|
9635
|
+
* their use.
|
|
9636
|
+
*/
|
|
9637
|
+
generators = [];
|
|
9638
|
+
/**
|
|
9639
|
+
* A `Set` of shim `ts.SourceFile`s which should not be emitted.
|
|
9640
|
+
*/
|
|
9641
|
+
ignoreForEmit = new Set();
|
|
9642
|
+
/**
|
|
9643
|
+
* A list of extra filenames which should be considered inputs to program creation.
|
|
9644
|
+
*
|
|
9645
|
+
* This includes any top-level shims generated for the program, as well as per-file shim names for
|
|
9646
|
+
* those files which are included in the root files of the program.
|
|
9647
|
+
*/
|
|
9648
|
+
extraInputFiles;
|
|
9649
|
+
/**
|
|
9650
|
+
* Extension prefixes of all installed per-file shims.
|
|
9651
|
+
*/
|
|
9652
|
+
extensionPrefixes = [];
|
|
9349
9653
|
constructor(delegate, tsRootFiles, topLevelGenerators, perFileGenerators, oldProgram) {
|
|
9350
9654
|
this.delegate = delegate;
|
|
9351
|
-
/**
|
|
9352
|
-
* A map of shim file names to the `ts.SourceFile` generated for those shims.
|
|
9353
|
-
*/
|
|
9354
|
-
this.shims = new Map();
|
|
9355
|
-
/**
|
|
9356
|
-
* A map of shim file names to existing shims which were part of a previous iteration of this
|
|
9357
|
-
* program.
|
|
9358
|
-
*
|
|
9359
|
-
* Not all of these shims will be inherited into this program.
|
|
9360
|
-
*/
|
|
9361
|
-
this.priorShims = new Map();
|
|
9362
|
-
/**
|
|
9363
|
-
* File names which are already known to not be shims.
|
|
9364
|
-
*
|
|
9365
|
-
* This allows for short-circuit returns without the expense of running regular expressions
|
|
9366
|
-
* against the filename repeatedly.
|
|
9367
|
-
*/
|
|
9368
|
-
this.notShims = new Set();
|
|
9369
|
-
/**
|
|
9370
|
-
* The shim generators supported by this adapter as well as extra precalculated data facilitating
|
|
9371
|
-
* their use.
|
|
9372
|
-
*/
|
|
9373
|
-
this.generators = [];
|
|
9374
|
-
/**
|
|
9375
|
-
* A `Set` of shim `ts.SourceFile`s which should not be emitted.
|
|
9376
|
-
*/
|
|
9377
|
-
this.ignoreForEmit = new Set();
|
|
9378
|
-
/**
|
|
9379
|
-
* Extension prefixes of all installed per-file shims.
|
|
9380
|
-
*/
|
|
9381
|
-
this.extensionPrefixes = [];
|
|
9382
9655
|
// Initialize `this.generators` with a regex that matches each generator's paths.
|
|
9383
9656
|
for (const gen of perFileGenerators) {
|
|
9384
9657
|
// This regex matches paths for shims from this generator. The first (and only) capture group
|
|
@@ -9516,17 +9789,18 @@ class ShimAdapter {
|
|
|
9516
9789
|
* `ShimReferenceTagger`s are intended to operate during program creation only.
|
|
9517
9790
|
*/
|
|
9518
9791
|
class ShimReferenceTagger {
|
|
9792
|
+
suffixes;
|
|
9793
|
+
/**
|
|
9794
|
+
* Tracks which original files have been processed and had shims generated if necessary.
|
|
9795
|
+
*
|
|
9796
|
+
* This is used to avoid generating shims twice for the same file.
|
|
9797
|
+
*/
|
|
9798
|
+
tagged = new Set();
|
|
9799
|
+
/**
|
|
9800
|
+
* Whether shim tagging is currently being performed.
|
|
9801
|
+
*/
|
|
9802
|
+
enabled = true;
|
|
9519
9803
|
constructor(shimExtensions) {
|
|
9520
|
-
/**
|
|
9521
|
-
* Tracks which original files have been processed and had shims generated if necessary.
|
|
9522
|
-
*
|
|
9523
|
-
* This is used to avoid generating shims twice for the same file.
|
|
9524
|
-
*/
|
|
9525
|
-
this.tagged = new Set();
|
|
9526
|
-
/**
|
|
9527
|
-
* Whether shim tagging is currently being performed.
|
|
9528
|
-
*/
|
|
9529
|
-
this.enabled = true;
|
|
9530
9804
|
this.suffixes = shimExtensions.map((extension) => `.${extension}.ts`);
|
|
9531
9805
|
}
|
|
9532
9806
|
/**
|
|
@@ -9576,6 +9850,30 @@ class ShimReferenceTagger {
|
|
|
9576
9850
|
* generated for this class.
|
|
9577
9851
|
*/
|
|
9578
9852
|
class DelegatingCompilerHost$1 {
|
|
9853
|
+
delegate;
|
|
9854
|
+
createHash;
|
|
9855
|
+
directoryExists;
|
|
9856
|
+
getCancellationToken;
|
|
9857
|
+
getCanonicalFileName;
|
|
9858
|
+
getCurrentDirectory;
|
|
9859
|
+
getDefaultLibFileName;
|
|
9860
|
+
getDefaultLibLocation;
|
|
9861
|
+
getDirectories;
|
|
9862
|
+
getEnvironmentVariable;
|
|
9863
|
+
getNewLine;
|
|
9864
|
+
getParsedCommandLine;
|
|
9865
|
+
getSourceFileByPath;
|
|
9866
|
+
readDirectory;
|
|
9867
|
+
readFile;
|
|
9868
|
+
realpath;
|
|
9869
|
+
resolveModuleNames;
|
|
9870
|
+
resolveTypeReferenceDirectives;
|
|
9871
|
+
trace;
|
|
9872
|
+
useCaseSensitiveFileNames;
|
|
9873
|
+
getModuleResolutionCache;
|
|
9874
|
+
hasInvalidatedResolutions;
|
|
9875
|
+
resolveModuleNameLiterals;
|
|
9876
|
+
resolveTypeReferenceDirectiveReferences;
|
|
9579
9877
|
// jsDocParsingMode is not a method like the other elements above
|
|
9580
9878
|
// TODO: ignore usage can be dropped once 5.2 support is dropped
|
|
9581
9879
|
get jsDocParsingMode() {
|
|
@@ -9624,6 +9922,23 @@ class DelegatingCompilerHost$1 {
|
|
|
9624
9922
|
* A `ts.CompilerHost` which augments source files.
|
|
9625
9923
|
*/
|
|
9626
9924
|
class UpdatedProgramHost extends DelegatingCompilerHost$1 {
|
|
9925
|
+
originalProgram;
|
|
9926
|
+
shimExtensionPrefixes;
|
|
9927
|
+
/**
|
|
9928
|
+
* Map of source file names to `ts.SourceFile` instances.
|
|
9929
|
+
*/
|
|
9930
|
+
sfMap;
|
|
9931
|
+
/**
|
|
9932
|
+
* The `ShimReferenceTagger` responsible for tagging `ts.SourceFile`s loaded via this host.
|
|
9933
|
+
*
|
|
9934
|
+
* The `UpdatedProgramHost` is used in the creation of a new `ts.Program`. Even though this new
|
|
9935
|
+
* program is based on a prior one, TypeScript will still start from the root files and enumerate
|
|
9936
|
+
* all source files to include in the new program. This means that just like during the original
|
|
9937
|
+
* program's creation, these source files must be tagged with references to per-file shims in
|
|
9938
|
+
* order for those shims to be loaded, and then cleaned up afterwards. Thus the
|
|
9939
|
+
* `UpdatedProgramHost` has its own `ShimReferenceTagger` to perform this function.
|
|
9940
|
+
*/
|
|
9941
|
+
shimTagger;
|
|
9627
9942
|
constructor(sfMap, originalProgram, delegate, shimExtensionPrefixes) {
|
|
9628
9943
|
super(delegate);
|
|
9629
9944
|
this.originalProgram = originalProgram;
|
|
@@ -9673,21 +9988,26 @@ class UpdatedProgramHost extends DelegatingCompilerHost$1 {
|
|
|
9673
9988
|
* TypeScript compiler APIs for incremental program creation.
|
|
9674
9989
|
*/
|
|
9675
9990
|
class TsCreateProgramDriver {
|
|
9991
|
+
originalProgram;
|
|
9992
|
+
originalHost;
|
|
9993
|
+
options;
|
|
9994
|
+
shimExtensionPrefixes;
|
|
9995
|
+
/**
|
|
9996
|
+
* A map of source file paths to replacement `ts.SourceFile`s for those paths.
|
|
9997
|
+
*
|
|
9998
|
+
* Effectively, this tracks the delta between the user's program (represented by the
|
|
9999
|
+
* `originalHost`) and the template type-checking program being managed.
|
|
10000
|
+
*/
|
|
10001
|
+
sfMap = new Map();
|
|
10002
|
+
program;
|
|
9676
10003
|
constructor(originalProgram, originalHost, options, shimExtensionPrefixes) {
|
|
9677
10004
|
this.originalProgram = originalProgram;
|
|
9678
10005
|
this.originalHost = originalHost;
|
|
9679
10006
|
this.options = options;
|
|
9680
10007
|
this.shimExtensionPrefixes = shimExtensionPrefixes;
|
|
9681
|
-
/**
|
|
9682
|
-
* A map of source file paths to replacement `ts.SourceFile`s for those paths.
|
|
9683
|
-
*
|
|
9684
|
-
* Effectively, this tracks the delta between the user's program (represented by the
|
|
9685
|
-
* `originalHost`) and the template type-checking program being managed.
|
|
9686
|
-
*/
|
|
9687
|
-
this.sfMap = new Map();
|
|
9688
|
-
this.supportsInlineOperations = true;
|
|
9689
10008
|
this.program = this.originalProgram;
|
|
9690
10009
|
}
|
|
10010
|
+
supportsInlineOperations = true;
|
|
9691
10011
|
getProgram() {
|
|
9692
10012
|
return this.program;
|
|
9693
10013
|
}
|
|
@@ -9730,6 +10050,275 @@ class TsCreateProgramDriver {
|
|
|
9730
10050
|
}
|
|
9731
10051
|
}
|
|
9732
10052
|
|
|
10053
|
+
/*!
|
|
10054
|
+
* @license
|
|
10055
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10056
|
+
*
|
|
10057
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10058
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
10059
|
+
*/
|
|
10060
|
+
/**
|
|
10061
|
+
* Determines the names of the file-level locals that the HMR
|
|
10062
|
+
* initializer needs to capture and pass along.
|
|
10063
|
+
* @param sourceFile File in which the file is being compiled.
|
|
10064
|
+
* @param definition Compiled component definition.
|
|
10065
|
+
* @param factory Compiled component factory.
|
|
10066
|
+
* @param classMetadata Compiled `setClassMetadata` expression, if any.
|
|
10067
|
+
* @param debugInfo Compiled `setClassDebugInfo` expression, if any.
|
|
10068
|
+
*/
|
|
10069
|
+
function extractHmrLocals(node, definition, factory, classMetadata, debugInfo) {
|
|
10070
|
+
const name = ts__default["default"].isClassDeclaration(node) && node.name ? node.name.text : null;
|
|
10071
|
+
const visitor = new PotentialTopLevelReadsVisitor();
|
|
10072
|
+
const sourceFile = node.getSourceFile();
|
|
10073
|
+
// Visit all of the compiled expression to look for potential
|
|
10074
|
+
// local references that would have to be retained.
|
|
10075
|
+
definition.expression.visitExpression(visitor, null);
|
|
10076
|
+
definition.statements.forEach((statement) => statement.visitStatement(visitor, null));
|
|
10077
|
+
factory.initializer?.visitExpression(visitor, null);
|
|
10078
|
+
factory.statements.forEach((statement) => statement.visitStatement(visitor, null));
|
|
10079
|
+
classMetadata?.visitStatement(visitor, null);
|
|
10080
|
+
debugInfo?.visitStatement(visitor, null);
|
|
10081
|
+
// Filter out only the references to defined top-level symbols. This allows us to ignore local
|
|
10082
|
+
// variables inside of functions. Note that we filter out the class name since it is always
|
|
10083
|
+
// defined and it saves us having to repeat this logic wherever the locals are consumed.
|
|
10084
|
+
const availableTopLevel = getTopLevelDeclarationNames(sourceFile);
|
|
10085
|
+
return Array.from(visitor.allReads).filter((r) => r !== name && availableTopLevel.has(r));
|
|
10086
|
+
}
|
|
10087
|
+
/**
|
|
10088
|
+
* Gets the names of all top-level declarations within the file (imports, declared classes etc).
|
|
10089
|
+
* @param sourceFile File in which to search for locals.
|
|
10090
|
+
*/
|
|
10091
|
+
function getTopLevelDeclarationNames(sourceFile) {
|
|
10092
|
+
const results = new Set();
|
|
10093
|
+
// Only look through the top-level statements.
|
|
10094
|
+
for (const node of sourceFile.statements) {
|
|
10095
|
+
// Class, function and const enum declarations need to be captured since they correspond
|
|
10096
|
+
// to runtime code. Intentionally excludes interfaces and type declarations.
|
|
10097
|
+
if (ts__default["default"].isClassDeclaration(node) ||
|
|
10098
|
+
ts__default["default"].isFunctionDeclaration(node) ||
|
|
10099
|
+
(ts__default["default"].isEnumDeclaration(node) &&
|
|
10100
|
+
!node.modifiers?.some((m) => m.kind === ts__default["default"].SyntaxKind.ConstKeyword))) {
|
|
10101
|
+
if (node.name) {
|
|
10102
|
+
results.add(node.name.text);
|
|
10103
|
+
}
|
|
10104
|
+
continue;
|
|
10105
|
+
}
|
|
10106
|
+
// Variable declarations.
|
|
10107
|
+
if (ts__default["default"].isVariableStatement(node)) {
|
|
10108
|
+
for (const decl of node.declarationList.declarations) {
|
|
10109
|
+
trackBindingName(decl.name, results);
|
|
10110
|
+
}
|
|
10111
|
+
continue;
|
|
10112
|
+
}
|
|
10113
|
+
// Import declarations.
|
|
10114
|
+
if (ts__default["default"].isImportDeclaration(node) && node.importClause) {
|
|
10115
|
+
const importClause = node.importClause;
|
|
10116
|
+
// Skip over type-only imports since they won't be emitted to JS.
|
|
10117
|
+
if (importClause.isTypeOnly) {
|
|
10118
|
+
continue;
|
|
10119
|
+
}
|
|
10120
|
+
// import foo from 'foo'
|
|
10121
|
+
if (importClause.name) {
|
|
10122
|
+
results.add(importClause.name.text);
|
|
10123
|
+
}
|
|
10124
|
+
if (importClause.namedBindings) {
|
|
10125
|
+
const namedBindings = importClause.namedBindings;
|
|
10126
|
+
if (ts__default["default"].isNamespaceImport(namedBindings)) {
|
|
10127
|
+
// import * as foo from 'foo';
|
|
10128
|
+
results.add(namedBindings.name.text);
|
|
10129
|
+
}
|
|
10130
|
+
else {
|
|
10131
|
+
// import {foo} from 'foo';
|
|
10132
|
+
namedBindings.elements.forEach((el) => {
|
|
10133
|
+
if (!el.isTypeOnly) {
|
|
10134
|
+
results.add(el.name.text);
|
|
10135
|
+
}
|
|
10136
|
+
});
|
|
10137
|
+
}
|
|
10138
|
+
}
|
|
10139
|
+
continue;
|
|
10140
|
+
}
|
|
10141
|
+
}
|
|
10142
|
+
return results;
|
|
10143
|
+
}
|
|
10144
|
+
/**
|
|
10145
|
+
* Adds all the variables declared through a `ts.BindingName` to a set of results.
|
|
10146
|
+
* @param node Node from which to start searching for variables.
|
|
10147
|
+
* @param results Set to which to add the matches.
|
|
10148
|
+
*/
|
|
10149
|
+
function trackBindingName(node, results) {
|
|
10150
|
+
if (ts__default["default"].isIdentifier(node)) {
|
|
10151
|
+
results.add(node.text);
|
|
10152
|
+
}
|
|
10153
|
+
else {
|
|
10154
|
+
for (const el of node.elements) {
|
|
10155
|
+
if (!ts__default["default"].isOmittedExpression(el)) {
|
|
10156
|
+
trackBindingName(el.name, results);
|
|
10157
|
+
}
|
|
10158
|
+
}
|
|
10159
|
+
}
|
|
10160
|
+
}
|
|
10161
|
+
/**
|
|
10162
|
+
* Visitor that will traverse an AST looking for potential top-level variable reads.
|
|
10163
|
+
* The reads are "potential", because the visitor doesn't account for local variables
|
|
10164
|
+
* inside functions.
|
|
10165
|
+
*/
|
|
10166
|
+
class PotentialTopLevelReadsVisitor extends checker.RecursiveAstVisitor {
|
|
10167
|
+
allReads = new Set();
|
|
10168
|
+
visitReadVarExpr(ast, context) {
|
|
10169
|
+
this.allReads.add(ast.name);
|
|
10170
|
+
super.visitReadVarExpr(ast, context);
|
|
10171
|
+
}
|
|
10172
|
+
visitWrappedNodeExpr(ast, context) {
|
|
10173
|
+
if (this.isTypeScriptNode(ast.node)) {
|
|
10174
|
+
this.addAllTopLevelIdentifiers(ast.node);
|
|
10175
|
+
}
|
|
10176
|
+
super.visitWrappedNodeExpr(ast, context);
|
|
10177
|
+
}
|
|
10178
|
+
/**
|
|
10179
|
+
* Traverses a TypeScript AST and tracks all the top-level reads.
|
|
10180
|
+
* @param node Node from which to start the traversal.
|
|
10181
|
+
*/
|
|
10182
|
+
addAllTopLevelIdentifiers = (node) => {
|
|
10183
|
+
if (ts__default["default"].isIdentifier(node) && this.isTopLevelIdentifierReference(node)) {
|
|
10184
|
+
this.allReads.add(node.text);
|
|
10185
|
+
}
|
|
10186
|
+
else {
|
|
10187
|
+
ts__default["default"].forEachChild(node, this.addAllTopLevelIdentifiers);
|
|
10188
|
+
}
|
|
10189
|
+
};
|
|
10190
|
+
/**
|
|
10191
|
+
* TypeScript identifiers are used both when referring to a variable (e.g. `console.log(foo)`)
|
|
10192
|
+
* and for names (e.g. `{foo: 123}`). This function determines if the identifier is a top-level
|
|
10193
|
+
* variable read, rather than a nested name.
|
|
10194
|
+
* @param node Identifier to check.
|
|
10195
|
+
*/
|
|
10196
|
+
isTopLevelIdentifierReference(node) {
|
|
10197
|
+
const parent = node.parent;
|
|
10198
|
+
// The parent might be undefined for a synthetic node or if `setParentNodes` is set to false
|
|
10199
|
+
// when the SourceFile was created. We can account for such cases using the type checker, at
|
|
10200
|
+
// the expense of performance. At the moment of writing, we're keeping it simple since the
|
|
10201
|
+
// compiler sets `setParentNodes: true`.
|
|
10202
|
+
if (!parent) {
|
|
10203
|
+
return false;
|
|
10204
|
+
}
|
|
10205
|
+
// Identifier referenced at the top level. Unlikely.
|
|
10206
|
+
if (ts__default["default"].isSourceFile(parent) ||
|
|
10207
|
+
(ts__default["default"].isExpressionStatement(parent) && parent.expression === node)) {
|
|
10208
|
+
return true;
|
|
10209
|
+
}
|
|
10210
|
+
// Identifier used inside a call is only top-level if it's an argument.
|
|
10211
|
+
// This also covers decorators since their expression is usually a call.
|
|
10212
|
+
if (ts__default["default"].isCallExpression(parent)) {
|
|
10213
|
+
return parent.expression === node || parent.arguments.includes(node);
|
|
10214
|
+
}
|
|
10215
|
+
// Identifier used in a property read is only top-level if it's the expression.
|
|
10216
|
+
if (ts__default["default"].isPropertyAccessExpression(parent)) {
|
|
10217
|
+
return parent.expression === node;
|
|
10218
|
+
}
|
|
10219
|
+
// Identifier used in an array is only top-level if it's one of the elements.
|
|
10220
|
+
if (ts__default["default"].isArrayLiteralExpression(parent)) {
|
|
10221
|
+
return parent.elements.includes(node);
|
|
10222
|
+
}
|
|
10223
|
+
// Identifier in a property assignment is only top level if it's the initializer.
|
|
10224
|
+
if (ts__default["default"].isPropertyAssignment(parent)) {
|
|
10225
|
+
return parent.initializer === node;
|
|
10226
|
+
}
|
|
10227
|
+
// Identifier in a class is only top level if it's the name.
|
|
10228
|
+
if (ts__default["default"].isClassDeclaration(parent)) {
|
|
10229
|
+
return parent.name === node;
|
|
10230
|
+
}
|
|
10231
|
+
// Otherwise it's not top-level.
|
|
10232
|
+
return false;
|
|
10233
|
+
}
|
|
10234
|
+
/** Checks if a value is a TypeScript AST node. */
|
|
10235
|
+
isTypeScriptNode(value) {
|
|
10236
|
+
// If this is too permissive, we can also check for `getSourceFile`. This code runs
|
|
10237
|
+
// on a narrow set of use cases so checking for `kind` should be enough.
|
|
10238
|
+
return !!value && typeof value.kind === 'number';
|
|
10239
|
+
}
|
|
10240
|
+
}
|
|
10241
|
+
|
|
10242
|
+
/*!
|
|
10243
|
+
* @license
|
|
10244
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10245
|
+
*
|
|
10246
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10247
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
10248
|
+
*/
|
|
10249
|
+
/**
|
|
10250
|
+
* Extracts the HMR metadata for a class declaration.
|
|
10251
|
+
* @param clazz Class being analyzed.
|
|
10252
|
+
* @param reflection Reflection host.
|
|
10253
|
+
* @param compilerHost Compiler host to use when resolving file names.
|
|
10254
|
+
* @param rootDirs Root directories configured by the user.
|
|
10255
|
+
* @param definition Analyzed component definition.
|
|
10256
|
+
* @param factory Analyzed component factory.
|
|
10257
|
+
* @param classMetadata Analyzed `setClassMetadata` expression, if any.
|
|
10258
|
+
* @param debugInfo Analyzed `setClassDebugInfo` expression, if any.
|
|
10259
|
+
*/
|
|
10260
|
+
function extractHmrMetatadata(clazz, reflection, compilerHost, rootDirs, definition, factory, classMetadata, debugInfo) {
|
|
10261
|
+
if (!reflection.isClass(clazz)) {
|
|
10262
|
+
return null;
|
|
10263
|
+
}
|
|
10264
|
+
const sourceFile = clazz.getSourceFile();
|
|
10265
|
+
const filePath = getProjectRelativePath(sourceFile, rootDirs, compilerHost) ||
|
|
10266
|
+
compilerHost.getCanonicalFileName(sourceFile.fileName);
|
|
10267
|
+
const meta = {
|
|
10268
|
+
type: new checker.WrappedNodeExpr(clazz.name),
|
|
10269
|
+
className: clazz.name.text,
|
|
10270
|
+
filePath,
|
|
10271
|
+
locals: extractHmrLocals(clazz, definition, factory, classMetadata, debugInfo),
|
|
10272
|
+
coreName: '__ngCore__',
|
|
10273
|
+
};
|
|
10274
|
+
return meta;
|
|
10275
|
+
}
|
|
10276
|
+
|
|
10277
|
+
/*!
|
|
10278
|
+
* @license
|
|
10279
|
+
* Copyright Google LLC All Rights Reserved.
|
|
10280
|
+
*
|
|
10281
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
10282
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
10283
|
+
*/
|
|
10284
|
+
/**
|
|
10285
|
+
* Gets the declaration for the function that replaces the metadata of a class during HMR.
|
|
10286
|
+
* @param compilationResults Code generated for the class during compilation.
|
|
10287
|
+
* @param meta HMR metadata about the class.
|
|
10288
|
+
* @param sourceFile File in which the class is defined.
|
|
10289
|
+
*/
|
|
10290
|
+
function getHmrUpdateDeclaration(compilationResults, constantStatements, meta, sourceFile) {
|
|
10291
|
+
const importRewriter = new HmrModuleImportRewriter(meta.coreName);
|
|
10292
|
+
const importManager = new checker.ImportManager({
|
|
10293
|
+
...checker.presetImportManagerForceNamespaceImports,
|
|
10294
|
+
rewriter: importRewriter,
|
|
10295
|
+
});
|
|
10296
|
+
const callback = compileHmrUpdateCallback(compilationResults, constantStatements, meta);
|
|
10297
|
+
const node = checker.translateStatement(sourceFile, callback, importManager);
|
|
10298
|
+
// The output AST doesn't support modifiers so we have to emit to
|
|
10299
|
+
// TS and then update the declaration to add `export default`.
|
|
10300
|
+
return ts__default["default"].factory.updateFunctionDeclaration(node, [
|
|
10301
|
+
ts__default["default"].factory.createToken(ts__default["default"].SyntaxKind.ExportKeyword),
|
|
10302
|
+
ts__default["default"].factory.createToken(ts__default["default"].SyntaxKind.DefaultKeyword),
|
|
10303
|
+
], node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body);
|
|
10304
|
+
}
|
|
10305
|
+
/** Rewriter that replaces namespace imports to `@angular/core` with a specifier identifier. */
|
|
10306
|
+
class HmrModuleImportRewriter {
|
|
10307
|
+
coreName;
|
|
10308
|
+
constructor(coreName) {
|
|
10309
|
+
this.coreName = coreName;
|
|
10310
|
+
}
|
|
10311
|
+
rewriteNamespaceImportIdentifier(specifier, moduleName) {
|
|
10312
|
+
return moduleName === '@angular/core' ? this.coreName : specifier;
|
|
10313
|
+
}
|
|
10314
|
+
rewriteSymbol(symbol) {
|
|
10315
|
+
return symbol;
|
|
10316
|
+
}
|
|
10317
|
+
rewriteSpecifier(specifier) {
|
|
10318
|
+
return specifier;
|
|
10319
|
+
}
|
|
10320
|
+
}
|
|
10321
|
+
|
|
9733
10322
|
const EMPTY_ARRAY = [];
|
|
9734
10323
|
const isUsedDirective = (decl) => decl.kind === checker.R3TemplateDependencyKind.Directive;
|
|
9735
10324
|
const isUsedPipe = (decl) => decl.kind === checker.R3TemplateDependencyKind.Pipe;
|
|
@@ -9737,13 +10326,56 @@ const isUsedPipe = (decl) => decl.kind === checker.R3TemplateDependencyKind.Pipe
|
|
|
9737
10326
|
* `DecoratorHandler` which handles the `@Component` annotation.
|
|
9738
10327
|
*/
|
|
9739
10328
|
class ComponentDecoratorHandler {
|
|
9740
|
-
|
|
10329
|
+
reflector;
|
|
10330
|
+
evaluator;
|
|
10331
|
+
metaRegistry;
|
|
10332
|
+
metaReader;
|
|
10333
|
+
scopeReader;
|
|
10334
|
+
compilerHost;
|
|
10335
|
+
scopeRegistry;
|
|
10336
|
+
typeCheckScopeRegistry;
|
|
10337
|
+
resourceRegistry;
|
|
10338
|
+
isCore;
|
|
10339
|
+
strictCtorDeps;
|
|
10340
|
+
resourceLoader;
|
|
10341
|
+
rootDirs;
|
|
10342
|
+
defaultPreserveWhitespaces;
|
|
10343
|
+
i18nUseExternalIds;
|
|
10344
|
+
enableI18nLegacyMessageIdFormat;
|
|
10345
|
+
usePoisonedData;
|
|
10346
|
+
i18nNormalizeLineEndingsInICUs;
|
|
10347
|
+
moduleResolver;
|
|
10348
|
+
cycleAnalyzer;
|
|
10349
|
+
cycleHandlingStrategy;
|
|
10350
|
+
refEmitter;
|
|
10351
|
+
referencesRegistry;
|
|
10352
|
+
depTracker;
|
|
10353
|
+
injectableRegistry;
|
|
10354
|
+
semanticDepGraphUpdater;
|
|
10355
|
+
annotateForClosureCompiler;
|
|
10356
|
+
perf;
|
|
10357
|
+
hostDirectivesResolver;
|
|
10358
|
+
importTracker;
|
|
10359
|
+
includeClassMetadata;
|
|
10360
|
+
compilationMode;
|
|
10361
|
+
deferredSymbolTracker;
|
|
10362
|
+
forbidOrphanRendering;
|
|
10363
|
+
enableBlockSyntax;
|
|
10364
|
+
enableLetSyntax;
|
|
10365
|
+
externalRuntimeStyles;
|
|
10366
|
+
localCompilationExtraImportsTracker;
|
|
10367
|
+
jitDeclarationRegistry;
|
|
10368
|
+
i18nPreserveSignificantWhitespace;
|
|
10369
|
+
strictStandalone;
|
|
10370
|
+
enableHmr;
|
|
10371
|
+
implicitStandaloneValue;
|
|
10372
|
+
constructor(reflector, evaluator, metaRegistry, metaReader, scopeReader, compilerHost, scopeRegistry, typeCheckScopeRegistry, resourceRegistry, isCore, strictCtorDeps, resourceLoader, rootDirs, defaultPreserveWhitespaces, i18nUseExternalIds, enableI18nLegacyMessageIdFormat, usePoisonedData, i18nNormalizeLineEndingsInICUs, moduleResolver, cycleAnalyzer, cycleHandlingStrategy, refEmitter, referencesRegistry, depTracker, injectableRegistry, semanticDepGraphUpdater, annotateForClosureCompiler, perf, hostDirectivesResolver, importTracker, includeClassMetadata, compilationMode, deferredSymbolTracker, forbidOrphanRendering, enableBlockSyntax, enableLetSyntax, externalRuntimeStyles, localCompilationExtraImportsTracker, jitDeclarationRegistry, i18nPreserveSignificantWhitespace, strictStandalone, enableHmr, implicitStandaloneValue) {
|
|
9741
10373
|
this.reflector = reflector;
|
|
9742
10374
|
this.evaluator = evaluator;
|
|
9743
10375
|
this.metaRegistry = metaRegistry;
|
|
9744
10376
|
this.metaReader = metaReader;
|
|
9745
10377
|
this.scopeReader = scopeReader;
|
|
9746
|
-
this.
|
|
10378
|
+
this.compilerHost = compilerHost;
|
|
9747
10379
|
this.scopeRegistry = scopeRegistry;
|
|
9748
10380
|
this.typeCheckScopeRegistry = typeCheckScopeRegistry;
|
|
9749
10381
|
this.resourceRegistry = resourceRegistry;
|
|
@@ -9779,17 +10411,8 @@ class ComponentDecoratorHandler {
|
|
|
9779
10411
|
this.jitDeclarationRegistry = jitDeclarationRegistry;
|
|
9780
10412
|
this.i18nPreserveSignificantWhitespace = i18nPreserveSignificantWhitespace;
|
|
9781
10413
|
this.strictStandalone = strictStandalone;
|
|
9782
|
-
this.
|
|
9783
|
-
this.
|
|
9784
|
-
/**
|
|
9785
|
-
* During the asynchronous preanalyze phase, it's necessary to parse the template to extract
|
|
9786
|
-
* any potential <link> tags which might need to be loaded. This cache ensures that work is not
|
|
9787
|
-
* thrown away, and the parsed template is reused during the analyze phase.
|
|
9788
|
-
*/
|
|
9789
|
-
this.preanalyzeTemplateCache = new Map();
|
|
9790
|
-
this.preanalyzeStylesCache = new Map();
|
|
9791
|
-
this.precedence = checker.HandlerPrecedence.PRIMARY;
|
|
9792
|
-
this.name = 'ComponentDecoratorHandler';
|
|
10414
|
+
this.enableHmr = enableHmr;
|
|
10415
|
+
this.implicitStandaloneValue = implicitStandaloneValue;
|
|
9793
10416
|
this.extractTemplateOptions = {
|
|
9794
10417
|
enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat,
|
|
9795
10418
|
i18nNormalizeLineEndingsInICUs: this.i18nNormalizeLineEndingsInICUs,
|
|
@@ -9798,7 +10421,25 @@ class ComponentDecoratorHandler {
|
|
|
9798
10421
|
enableLetSyntax: this.enableLetSyntax,
|
|
9799
10422
|
preserveSignificantWhitespace: this.i18nPreserveSignificantWhitespace,
|
|
9800
10423
|
};
|
|
10424
|
+
// Dependencies can't be deferred during HMR, because the HMR update module can't have
|
|
10425
|
+
// dynamic imports and its dependencies need to be passed in directly. If dependencies
|
|
10426
|
+
// are deferred, their imports will be deleted so we won't may lose the reference to them.
|
|
10427
|
+
this.canDeferDeps = !enableHmr;
|
|
9801
10428
|
}
|
|
10429
|
+
literalCache = new Map();
|
|
10430
|
+
elementSchemaRegistry = new checker.DomElementSchemaRegistry();
|
|
10431
|
+
/**
|
|
10432
|
+
* During the asynchronous preanalyze phase, it's necessary to parse the template to extract
|
|
10433
|
+
* any potential <link> tags which might need to be loaded. This cache ensures that work is not
|
|
10434
|
+
* thrown away, and the parsed template is reused during the analyze phase.
|
|
10435
|
+
*/
|
|
10436
|
+
preanalyzeTemplateCache = new Map();
|
|
10437
|
+
preanalyzeStylesCache = new Map();
|
|
10438
|
+
/** Whether generated code for a component can defer its dependencies. */
|
|
10439
|
+
canDeferDeps;
|
|
10440
|
+
extractTemplateOptions;
|
|
10441
|
+
precedence = checker.HandlerPrecedence.PRIMARY;
|
|
10442
|
+
name = 'ComponentDecoratorHandler';
|
|
9802
10443
|
detect(node, decorators) {
|
|
9803
10444
|
if (!decorators) {
|
|
9804
10445
|
return undefined;
|
|
@@ -9908,7 +10549,7 @@ class ComponentDecoratorHandler {
|
|
|
9908
10549
|
let isPoisoned = false;
|
|
9909
10550
|
// @Component inherits @Directive, so begin by extracting the @Directive metadata and building
|
|
9910
10551
|
// on it.
|
|
9911
|
-
const directiveResult = extractDirectiveMetadata(node, decorator, this.reflector, this.importTracker, this.evaluator, this.refEmitter, this.referencesRegistry, this.isCore, this.annotateForClosureCompiler, this.compilationMode, this.elementSchemaRegistry.getDefaultComponentElementName(), this.strictStandalone);
|
|
10552
|
+
const directiveResult = extractDirectiveMetadata(node, decorator, this.reflector, this.importTracker, this.evaluator, this.refEmitter, this.referencesRegistry, this.isCore, this.annotateForClosureCompiler, this.compilationMode, this.elementSchemaRegistry.getDefaultComponentElementName(), this.strictStandalone, this.implicitStandaloneValue);
|
|
9912
10553
|
// `extractDirectiveMetadata` returns `jitForced = true` when the `@Component` has
|
|
9913
10554
|
// set `jit: true`. In this case, compilation of the decorator is skipped. Returning
|
|
9914
10555
|
// an empty object signifies that no analysis was produced.
|
|
@@ -10200,7 +10841,7 @@ class ComponentDecoratorHandler {
|
|
|
10200
10841
|
classMetadata: this.includeClassMetadata
|
|
10201
10842
|
? extractClassMetadata(node, this.reflector, this.isCore, this.annotateForClosureCompiler, (dec) => transformDecoratorResources(dec, component, styles, template))
|
|
10202
10843
|
: null,
|
|
10203
|
-
classDebugInfo: extractClassDebugInfo(node, this.reflector, this.rootDirs,
|
|
10844
|
+
classDebugInfo: extractClassDebugInfo(node, this.reflector, this.compilerHost, this.rootDirs,
|
|
10204
10845
|
/* forbidOrphanRenderering */ this.forbidOrphanRendering),
|
|
10205
10846
|
template,
|
|
10206
10847
|
providersRequiringFactory,
|
|
@@ -10715,14 +11356,18 @@ class ComponentDecoratorHandler {
|
|
|
10715
11356
|
if (analysis.template.errors !== null && analysis.template.errors.length > 0) {
|
|
10716
11357
|
return [];
|
|
10717
11358
|
}
|
|
10718
|
-
const perComponentDeferredDeps = this.
|
|
11359
|
+
const perComponentDeferredDeps = this.canDeferDeps
|
|
11360
|
+
? this.resolveAllDeferredDependencies(resolution)
|
|
11361
|
+
: null;
|
|
10719
11362
|
const meta = {
|
|
10720
11363
|
...analysis.meta,
|
|
10721
11364
|
...resolution,
|
|
10722
11365
|
defer: this.compileDeferBlocks(resolution),
|
|
10723
11366
|
};
|
|
10724
11367
|
const fac = compileNgFactoryDefField(checker.toFactoryMetadata(meta, checker.FactoryTarget.Component));
|
|
10725
|
-
|
|
11368
|
+
if (perComponentDeferredDeps !== null) {
|
|
11369
|
+
removeDeferrableTypesFromComponentDecorator(analysis, perComponentDeferredDeps);
|
|
11370
|
+
}
|
|
10726
11371
|
const def = checker.compileComponentFromMetadata(meta, pool, checker.makeBindingParser());
|
|
10727
11372
|
const inputTransformFields = compileInputTransformFields(analysis.inputs);
|
|
10728
11373
|
const classMetadata = analysis.classMetadata !== null
|
|
@@ -10731,8 +11376,14 @@ class ComponentDecoratorHandler {
|
|
|
10731
11376
|
const debugInfo = analysis.classDebugInfo !== null
|
|
10732
11377
|
? compileClassDebugInfo(analysis.classDebugInfo).toStmt()
|
|
10733
11378
|
: null;
|
|
10734
|
-
const
|
|
10735
|
-
|
|
11379
|
+
const hmrMeta = this.enableHmr
|
|
11380
|
+
? extractHmrMetatadata(node, this.reflector, this.compilerHost, this.rootDirs, def, fac, classMetadata, debugInfo)
|
|
11381
|
+
: null;
|
|
11382
|
+
const hmrInitializer = hmrMeta ? compileHmrInitializer(hmrMeta).toStmt() : null;
|
|
11383
|
+
const deferrableImports = this.canDeferDeps
|
|
11384
|
+
? this.deferredSymbolTracker.getDeferrableImportDecls()
|
|
11385
|
+
: null;
|
|
11386
|
+
return checker.compileResults(fac, def, classMetadata, 'ɵcmp', inputTransformFields, deferrableImports, debugInfo, hmrInitializer);
|
|
10736
11387
|
}
|
|
10737
11388
|
compilePartial(node, analysis, resolution) {
|
|
10738
11389
|
if (analysis.template.errors !== null && analysis.template.errors.length > 0) {
|
|
@@ -10746,7 +11397,9 @@ class ComponentDecoratorHandler {
|
|
|
10746
11397
|
? new checker.WrappedNodeExpr(analysis.template.sourceMapping.node)
|
|
10747
11398
|
: null,
|
|
10748
11399
|
};
|
|
10749
|
-
const perComponentDeferredDeps = this.
|
|
11400
|
+
const perComponentDeferredDeps = this.canDeferDeps
|
|
11401
|
+
? this.resolveAllDeferredDependencies(resolution)
|
|
11402
|
+
: null;
|
|
10750
11403
|
const meta = {
|
|
10751
11404
|
...analysis.meta,
|
|
10752
11405
|
...resolution,
|
|
@@ -10758,21 +11411,27 @@ class ComponentDecoratorHandler {
|
|
|
10758
11411
|
const classMetadata = analysis.classMetadata !== null
|
|
10759
11412
|
? compileComponentDeclareClassMetadata(analysis.classMetadata, perComponentDeferredDeps).toStmt()
|
|
10760
11413
|
: null;
|
|
10761
|
-
const
|
|
10762
|
-
|
|
11414
|
+
const hmrMeta = this.enableHmr
|
|
11415
|
+
? extractHmrMetatadata(node, this.reflector, this.compilerHost, this.rootDirs, def, fac, classMetadata, null)
|
|
11416
|
+
: null;
|
|
11417
|
+
const hmrInitializer = hmrMeta ? compileHmrInitializer(hmrMeta).toStmt() : null;
|
|
11418
|
+
const deferrableImports = this.canDeferDeps
|
|
11419
|
+
? this.deferredSymbolTracker.getDeferrableImportDecls()
|
|
11420
|
+
: null;
|
|
11421
|
+
return checker.compileResults(fac, def, classMetadata, 'ɵcmp', inputTransformFields, deferrableImports, null, hmrInitializer);
|
|
10763
11422
|
}
|
|
10764
11423
|
compileLocal(node, analysis, resolution, pool) {
|
|
10765
11424
|
// In the local compilation mode we can only rely on the information available
|
|
10766
11425
|
// within the `@Component.deferredImports` array, because in this mode compiler
|
|
10767
11426
|
// doesn't have information on which dependencies belong to which defer blocks.
|
|
10768
|
-
const deferrableTypes = analysis.explicitlyDeferredTypes;
|
|
11427
|
+
const deferrableTypes = this.canDeferDeps ? analysis.explicitlyDeferredTypes : null;
|
|
10769
11428
|
const meta = {
|
|
10770
11429
|
...analysis.meta,
|
|
10771
11430
|
...resolution,
|
|
10772
11431
|
defer: this.compileDeferBlocks(resolution),
|
|
10773
11432
|
};
|
|
10774
|
-
if (
|
|
10775
|
-
removeDeferrableTypesFromComponentDecorator(analysis,
|
|
11433
|
+
if (deferrableTypes !== null) {
|
|
11434
|
+
removeDeferrableTypesFromComponentDecorator(analysis, deferrableTypes);
|
|
10776
11435
|
}
|
|
10777
11436
|
const fac = compileNgFactoryDefField(checker.toFactoryMetadata(meta, checker.FactoryTarget.Component));
|
|
10778
11437
|
const def = checker.compileComponentFromMetadata(meta, pool, checker.makeBindingParser());
|
|
@@ -10783,8 +11442,41 @@ class ComponentDecoratorHandler {
|
|
|
10783
11442
|
const debugInfo = analysis.classDebugInfo !== null
|
|
10784
11443
|
? compileClassDebugInfo(analysis.classDebugInfo).toStmt()
|
|
10785
11444
|
: null;
|
|
10786
|
-
const
|
|
10787
|
-
|
|
11445
|
+
const hmrMeta = this.enableHmr
|
|
11446
|
+
? extractHmrMetatadata(node, this.reflector, this.compilerHost, this.rootDirs, def, fac, classMetadata, debugInfo)
|
|
11447
|
+
: null;
|
|
11448
|
+
const hmrInitializer = hmrMeta ? compileHmrInitializer(hmrMeta).toStmt() : null;
|
|
11449
|
+
const deferrableImports = this.canDeferDeps
|
|
11450
|
+
? this.deferredSymbolTracker.getDeferrableImportDecls()
|
|
11451
|
+
: null;
|
|
11452
|
+
return checker.compileResults(fac, def, classMetadata, 'ɵcmp', inputTransformFields, deferrableImports, debugInfo, hmrInitializer);
|
|
11453
|
+
}
|
|
11454
|
+
compileHmrUpdateDeclaration(node, analysis, resolution) {
|
|
11455
|
+
if (analysis.template.errors !== null && analysis.template.errors.length > 0) {
|
|
11456
|
+
return null;
|
|
11457
|
+
}
|
|
11458
|
+
// Create a brand-new constant pool since there shouldn't be any constant sharing.
|
|
11459
|
+
const pool = new checker.ConstantPool();
|
|
11460
|
+
const meta = {
|
|
11461
|
+
...analysis.meta,
|
|
11462
|
+
...resolution,
|
|
11463
|
+
defer: this.compileDeferBlocks(resolution),
|
|
11464
|
+
};
|
|
11465
|
+
const fac = compileNgFactoryDefField(checker.toFactoryMetadata(meta, checker.FactoryTarget.Component));
|
|
11466
|
+
const def = checker.compileComponentFromMetadata(meta, pool, checker.makeBindingParser());
|
|
11467
|
+
const classMetadata = analysis.classMetadata !== null
|
|
11468
|
+
? compileComponentClassMetadata(analysis.classMetadata, null).toStmt()
|
|
11469
|
+
: null;
|
|
11470
|
+
const debugInfo = analysis.classDebugInfo !== null
|
|
11471
|
+
? compileClassDebugInfo(analysis.classDebugInfo).toStmt()
|
|
11472
|
+
: null;
|
|
11473
|
+
const hmrMeta = this.enableHmr
|
|
11474
|
+
? extractHmrMetatadata(node, this.reflector, this.compilerHost, this.rootDirs, def, fac, classMetadata, debugInfo)
|
|
11475
|
+
: null;
|
|
11476
|
+
const res = checker.compileResults(fac, def, classMetadata, 'ɵcmp', null, null, debugInfo, null);
|
|
11477
|
+
return hmrMeta === null || res.length === 0
|
|
11478
|
+
? null
|
|
11479
|
+
: getHmrUpdateDeclaration(res, pool.statements, hmrMeta, node.getSourceFile());
|
|
10788
11480
|
}
|
|
10789
11481
|
/**
|
|
10790
11482
|
* Locates defer blocks in case scope information is not available.
|
|
@@ -11110,6 +11802,15 @@ function isDefaultImport(node) {
|
|
|
11110
11802
|
* Adapts the `compileInjectable` compiler for `@Injectable` decorators to the Ivy compiler.
|
|
11111
11803
|
*/
|
|
11112
11804
|
class InjectableDecoratorHandler {
|
|
11805
|
+
reflector;
|
|
11806
|
+
evaluator;
|
|
11807
|
+
isCore;
|
|
11808
|
+
strictCtorDeps;
|
|
11809
|
+
injectableRegistry;
|
|
11810
|
+
perf;
|
|
11811
|
+
includeClassMetadata;
|
|
11812
|
+
compilationMode;
|
|
11813
|
+
errorOnDuplicateProv;
|
|
11113
11814
|
constructor(reflector, evaluator, isCore, strictCtorDeps, injectableRegistry, perf, includeClassMetadata, compilationMode,
|
|
11114
11815
|
/**
|
|
11115
11816
|
* What to do if the injectable already contains a ɵprov property.
|
|
@@ -11127,9 +11828,9 @@ class InjectableDecoratorHandler {
|
|
|
11127
11828
|
this.includeClassMetadata = includeClassMetadata;
|
|
11128
11829
|
this.compilationMode = compilationMode;
|
|
11129
11830
|
this.errorOnDuplicateProv = errorOnDuplicateProv;
|
|
11130
|
-
this.precedence = checker.HandlerPrecedence.SHARED;
|
|
11131
|
-
this.name = 'InjectableDecoratorHandler';
|
|
11132
11831
|
}
|
|
11832
|
+
precedence = checker.HandlerPrecedence.SHARED;
|
|
11833
|
+
name = 'InjectableDecoratorHandler';
|
|
11133
11834
|
detect(node, decorators) {
|
|
11134
11835
|
if (!decorators) {
|
|
11135
11836
|
return undefined;
|
|
@@ -11397,6 +12098,7 @@ function getDep(dep, reflector) {
|
|
|
11397
12098
|
* Represents an Angular pipe.
|
|
11398
12099
|
*/
|
|
11399
12100
|
class PipeSymbol extends SemanticSymbol {
|
|
12101
|
+
name;
|
|
11400
12102
|
constructor(decl, name) {
|
|
11401
12103
|
super(decl);
|
|
11402
12104
|
this.name = name;
|
|
@@ -11412,7 +12114,19 @@ class PipeSymbol extends SemanticSymbol {
|
|
|
11412
12114
|
}
|
|
11413
12115
|
}
|
|
11414
12116
|
class PipeDecoratorHandler {
|
|
11415
|
-
|
|
12117
|
+
reflector;
|
|
12118
|
+
evaluator;
|
|
12119
|
+
metaRegistry;
|
|
12120
|
+
scopeRegistry;
|
|
12121
|
+
injectableRegistry;
|
|
12122
|
+
isCore;
|
|
12123
|
+
perf;
|
|
12124
|
+
includeClassMetadata;
|
|
12125
|
+
compilationMode;
|
|
12126
|
+
generateExtraImportsInLocalMode;
|
|
12127
|
+
strictStandalone;
|
|
12128
|
+
implicitStandaloneValue;
|
|
12129
|
+
constructor(reflector, evaluator, metaRegistry, scopeRegistry, injectableRegistry, isCore, perf, includeClassMetadata, compilationMode, generateExtraImportsInLocalMode, strictStandalone, implicitStandaloneValue) {
|
|
11416
12130
|
this.reflector = reflector;
|
|
11417
12131
|
this.evaluator = evaluator;
|
|
11418
12132
|
this.metaRegistry = metaRegistry;
|
|
@@ -11424,9 +12138,10 @@ class PipeDecoratorHandler {
|
|
|
11424
12138
|
this.compilationMode = compilationMode;
|
|
11425
12139
|
this.generateExtraImportsInLocalMode = generateExtraImportsInLocalMode;
|
|
11426
12140
|
this.strictStandalone = strictStandalone;
|
|
11427
|
-
this.
|
|
11428
|
-
this.name = 'PipeDecoratorHandler';
|
|
12141
|
+
this.implicitStandaloneValue = implicitStandaloneValue;
|
|
11429
12142
|
}
|
|
12143
|
+
precedence = checker.HandlerPrecedence.PRIMARY;
|
|
12144
|
+
name = 'PipeDecoratorHandler';
|
|
11430
12145
|
detect(node, decorators) {
|
|
11431
12146
|
if (!decorators) {
|
|
11432
12147
|
return undefined;
|
|
@@ -11475,7 +12190,7 @@ class PipeDecoratorHandler {
|
|
|
11475
12190
|
}
|
|
11476
12191
|
pure = pureValue;
|
|
11477
12192
|
}
|
|
11478
|
-
let isStandalone =
|
|
12193
|
+
let isStandalone = this.implicitStandaloneValue;
|
|
11479
12194
|
if (pipe.has('standalone')) {
|
|
11480
12195
|
const expr = pipe.get('standalone');
|
|
11481
12196
|
const resolved = this.evaluator.evaluate(expr);
|
|
@@ -12356,12 +13071,7 @@ function i18nSerialize(bundle, formatName, options) {
|
|
|
12356
13071
|
let serializer;
|
|
12357
13072
|
switch (format) {
|
|
12358
13073
|
case 'xmb':
|
|
12359
|
-
serializer = new checker.Xmb(
|
|
12360
|
-
// Whenever we disable whitespace preservation, we also want to stop preserving
|
|
12361
|
-
// placeholders because they contain whitespace we want to drop too. Whitespace
|
|
12362
|
-
// inside `{{ name }}` should be ignored for the same reasons as whitespace
|
|
12363
|
-
// outside placeholders.
|
|
12364
|
-
/* preservePlaceholders */ options.i18nPreserveWhitespaceForLegacyExtraction);
|
|
13074
|
+
serializer = new checker.Xmb();
|
|
12365
13075
|
break;
|
|
12366
13076
|
case 'xliff2':
|
|
12367
13077
|
case 'xlf2':
|
|
@@ -12494,15 +13204,16 @@ function verifySupportedTypeScriptVersion() {
|
|
|
12494
13204
|
* Analyzes a `ts.Program` for cycles.
|
|
12495
13205
|
*/
|
|
12496
13206
|
class CycleAnalyzer {
|
|
13207
|
+
importGraph;
|
|
13208
|
+
/**
|
|
13209
|
+
* Cycle detection is requested with the same `from` source file for all used directives and pipes
|
|
13210
|
+
* within a component, which makes it beneficial to cache the results as long as the `from` source
|
|
13211
|
+
* file has not changed. This avoids visiting the import graph that is reachable from multiple
|
|
13212
|
+
* directives/pipes more than once.
|
|
13213
|
+
*/
|
|
13214
|
+
cachedResults = null;
|
|
12497
13215
|
constructor(importGraph) {
|
|
12498
13216
|
this.importGraph = importGraph;
|
|
12499
|
-
/**
|
|
12500
|
-
* Cycle detection is requested with the same `from` source file for all used directives and pipes
|
|
12501
|
-
* within a component, which makes it beneficial to cache the results as long as the `from` source
|
|
12502
|
-
* file has not changed. This avoids visiting the import graph that is reachable from multiple
|
|
12503
|
-
* directives/pipes more than once.
|
|
12504
|
-
*/
|
|
12505
|
-
this.cachedResults = null;
|
|
12506
13217
|
}
|
|
12507
13218
|
/**
|
|
12508
13219
|
* Check for a cycle to be created in the `ts.Program` by adding an import between `from` and
|
|
@@ -12539,11 +13250,13 @@ const NgCyclicResult = Symbol('NgCyclicResult');
|
|
|
12539
13250
|
* on the source file) as earlier executions.
|
|
12540
13251
|
*/
|
|
12541
13252
|
class CycleResults {
|
|
13253
|
+
from;
|
|
13254
|
+
importGraph;
|
|
13255
|
+
cyclic = {};
|
|
13256
|
+
acyclic = {};
|
|
12542
13257
|
constructor(from, importGraph) {
|
|
12543
13258
|
this.from = from;
|
|
12544
13259
|
this.importGraph = importGraph;
|
|
12545
|
-
this.cyclic = {};
|
|
12546
|
-
this.acyclic = {};
|
|
12547
13260
|
}
|
|
12548
13261
|
wouldBeCyclic(sf) {
|
|
12549
13262
|
const cached = this.getCachedResult(sf);
|
|
@@ -12600,6 +13313,9 @@ class CycleResults {
|
|
|
12600
13313
|
* needed.
|
|
12601
13314
|
*/
|
|
12602
13315
|
class Cycle {
|
|
13316
|
+
importGraph;
|
|
13317
|
+
from;
|
|
13318
|
+
to;
|
|
12603
13319
|
constructor(importGraph, from, to) {
|
|
12604
13320
|
this.importGraph = importGraph;
|
|
12605
13321
|
this.from = from;
|
|
@@ -12623,10 +13339,12 @@ class Cycle {
|
|
|
12623
13339
|
* dependencies within the same program are tracked; imports into packages on NPM are not.
|
|
12624
13340
|
*/
|
|
12625
13341
|
class ImportGraph {
|
|
13342
|
+
checker;
|
|
13343
|
+
perf;
|
|
13344
|
+
imports = new Map();
|
|
12626
13345
|
constructor(checker, perf) {
|
|
12627
13346
|
this.checker = checker;
|
|
12628
13347
|
this.perf = perf;
|
|
12629
|
-
this.imports = new Map();
|
|
12630
13348
|
}
|
|
12631
13349
|
/**
|
|
12632
13350
|
* List the direct (not transitive) imports of a given `ts.SourceFile`.
|
|
@@ -12735,6 +13453,8 @@ function isTypeOnlyImportClause(node) {
|
|
|
12735
13453
|
* `getPath()` above.
|
|
12736
13454
|
*/
|
|
12737
13455
|
class Found {
|
|
13456
|
+
sourceFile;
|
|
13457
|
+
parent;
|
|
12738
13458
|
constructor(sourceFile, parent) {
|
|
12739
13459
|
this.sourceFile = sourceFile;
|
|
12740
13460
|
this.parent = parent;
|
|
@@ -12889,6 +13609,9 @@ function extractResolvedTypeString(node, checker) {
|
|
|
12889
13609
|
}
|
|
12890
13610
|
|
|
12891
13611
|
class FunctionExtractor {
|
|
13612
|
+
name;
|
|
13613
|
+
exportDeclaration;
|
|
13614
|
+
typeChecker;
|
|
12892
13615
|
constructor(name, exportDeclaration, typeChecker) {
|
|
12893
13616
|
this.name = name;
|
|
12894
13617
|
this.exportDeclaration = exportDeclaration;
|
|
@@ -13000,6 +13723,8 @@ function hasLeadingInternalComment(member) {
|
|
|
13000
13723
|
|
|
13001
13724
|
/** Extractor to pull info for API reference documentation for a TypeScript class or interface. */
|
|
13002
13725
|
class ClassExtractor {
|
|
13726
|
+
declaration;
|
|
13727
|
+
typeChecker;
|
|
13003
13728
|
constructor(declaration, typeChecker) {
|
|
13004
13729
|
this.declaration = declaration;
|
|
13005
13730
|
this.typeChecker = typeChecker;
|
|
@@ -13162,9 +13887,22 @@ class ClassExtractor {
|
|
|
13162
13887
|
}
|
|
13163
13888
|
/** The result only contains properties, method implementations and abstracts */
|
|
13164
13889
|
filterMethodOverloads(declarations) {
|
|
13165
|
-
return declarations.filter((declaration) => {
|
|
13890
|
+
return declarations.filter((declaration, index) => {
|
|
13166
13891
|
if (ts__default["default"].isFunctionDeclaration(declaration) || ts__default["default"].isMethodDeclaration(declaration)) {
|
|
13167
|
-
|
|
13892
|
+
if (ts__default["default"].getCombinedModifierFlags(declaration) & ts__default["default"].ModifierFlags.Abstract) {
|
|
13893
|
+
// TS enforces that all declarations of an abstract method are consecutive
|
|
13894
|
+
const previousDeclaration = declarations[index - 1];
|
|
13895
|
+
const samePreviousAbstractMethod = previousDeclaration &&
|
|
13896
|
+
ts__default["default"].isMethodDeclaration(previousDeclaration) &&
|
|
13897
|
+
ts__default["default"].getCombinedModifierFlags(previousDeclaration) & ts__default["default"].ModifierFlags.Abstract &&
|
|
13898
|
+
previousDeclaration.name.getText() === declaration.name?.getText();
|
|
13899
|
+
// We just need a reference to one member
|
|
13900
|
+
// In the case of Abstract Methods we only want to return the first abstract.
|
|
13901
|
+
// Others with the same name are considered as overloads
|
|
13902
|
+
// Later on, the function extractor will handle overloads and implementation detection
|
|
13903
|
+
return !samePreviousAbstractMethod;
|
|
13904
|
+
}
|
|
13905
|
+
return !!declaration.body;
|
|
13168
13906
|
}
|
|
13169
13907
|
return true;
|
|
13170
13908
|
});
|
|
@@ -13259,6 +13997,8 @@ class ClassExtractor {
|
|
|
13259
13997
|
}
|
|
13260
13998
|
/** Extractor to pull info for API reference documentation for an Angular directive. */
|
|
13261
13999
|
class DirectiveExtractor extends ClassExtractor {
|
|
14000
|
+
reference;
|
|
14001
|
+
metadata;
|
|
13262
14002
|
constructor(declaration, reference, metadata, checker) {
|
|
13263
14003
|
super(declaration, checker);
|
|
13264
14004
|
this.reference = reference;
|
|
@@ -13303,6 +14043,8 @@ class DirectiveExtractor extends ClassExtractor {
|
|
|
13303
14043
|
}
|
|
13304
14044
|
/** Extractor to pull info for API reference documentation for an Angular pipe. */
|
|
13305
14045
|
class PipeExtractor extends ClassExtractor {
|
|
14046
|
+
reference;
|
|
14047
|
+
metadata;
|
|
13306
14048
|
constructor(declaration, reference, metadata, typeChecker) {
|
|
13307
14049
|
super(declaration, typeChecker);
|
|
13308
14050
|
this.reference = reference;
|
|
@@ -13319,6 +14061,8 @@ class PipeExtractor extends ClassExtractor {
|
|
|
13319
14061
|
}
|
|
13320
14062
|
/** Extractor to pull info for API reference documentation for an Angular pipe. */
|
|
13321
14063
|
class NgModuleExtractor extends ClassExtractor {
|
|
14064
|
+
reference;
|
|
14065
|
+
metadata;
|
|
13322
14066
|
constructor(declaration, reference, metadata, typeChecker) {
|
|
13323
14067
|
super(declaration, typeChecker);
|
|
13324
14068
|
this.reference = reference;
|
|
@@ -13770,6 +14514,8 @@ function getImportedSymbols(sourceFile) {
|
|
|
13770
14514
|
* public API documentation.
|
|
13771
14515
|
*/
|
|
13772
14516
|
class DocsExtractor {
|
|
14517
|
+
typeChecker;
|
|
14518
|
+
metadataReader;
|
|
13773
14519
|
constructor(typeChecker, metadataReader) {
|
|
13774
14520
|
this.typeChecker = typeChecker;
|
|
13775
14521
|
this.metadataReader = metadataReader;
|
|
@@ -13903,10 +14649,13 @@ function getRelativeFilePath(sourceFile, rootDir) {
|
|
|
13903
14649
|
|
|
13904
14650
|
/// <reference types="node" />
|
|
13905
14651
|
class FlatIndexGenerator {
|
|
14652
|
+
entryPoint;
|
|
14653
|
+
moduleName;
|
|
14654
|
+
flatIndexPath;
|
|
14655
|
+
shouldEmit = true;
|
|
13906
14656
|
constructor(entryPoint, relativeFlatIndexPath, moduleName) {
|
|
13907
14657
|
this.entryPoint = entryPoint;
|
|
13908
14658
|
this.moduleName = moduleName;
|
|
13909
|
-
this.shouldEmit = true;
|
|
13910
14659
|
this.flatIndexPath =
|
|
13911
14660
|
checker.join(checker.dirname(entryPoint), relativeFlatIndexPath).replace(/\.js$/, '') + '.ts';
|
|
13912
14661
|
}
|
|
@@ -14074,9 +14823,7 @@ function getDescriptorOfDeclaration(decl) {
|
|
|
14074
14823
|
}
|
|
14075
14824
|
|
|
14076
14825
|
class ReferenceGraph {
|
|
14077
|
-
|
|
14078
|
-
this.references = new Map();
|
|
14079
|
-
}
|
|
14826
|
+
references = new Map();
|
|
14080
14827
|
add(from, to) {
|
|
14081
14828
|
if (!this.references.has(from)) {
|
|
14082
14829
|
this.references.set(from, new Set());
|
|
@@ -14152,9 +14899,7 @@ class ReferenceGraph {
|
|
|
14152
14899
|
* 3. One of its resource dependencies has physically changed.
|
|
14153
14900
|
*/
|
|
14154
14901
|
class FileDependencyGraph {
|
|
14155
|
-
|
|
14156
|
-
this.nodes = new Map();
|
|
14157
|
-
}
|
|
14902
|
+
nodes = new Map();
|
|
14158
14903
|
addDependency(from, on) {
|
|
14159
14904
|
this.nodeFor(from).dependsOn.add(checker.absoluteFromSourceFile(on));
|
|
14160
14905
|
}
|
|
@@ -14272,6 +15017,17 @@ var PhaseKind;
|
|
|
14272
15017
|
* future one.
|
|
14273
15018
|
*/
|
|
14274
15019
|
class IncrementalCompilation {
|
|
15020
|
+
depGraph;
|
|
15021
|
+
versions;
|
|
15022
|
+
step;
|
|
15023
|
+
phase;
|
|
15024
|
+
/**
|
|
15025
|
+
* `IncrementalState` of this compilation if it were to be reused in a subsequent incremental
|
|
15026
|
+
* compilation at the current moment.
|
|
15027
|
+
*
|
|
15028
|
+
* Exposed via the `state` read-only getter.
|
|
15029
|
+
*/
|
|
15030
|
+
_state;
|
|
14275
15031
|
constructor(state, depGraph, versions, step) {
|
|
14276
15032
|
this.depGraph = depGraph;
|
|
14277
15033
|
this.versions = versions;
|
|
@@ -14550,10 +15306,8 @@ function toOriginalSourceFile(sf) {
|
|
|
14550
15306
|
* Tracks an `IncrementalState` within the strategy itself.
|
|
14551
15307
|
*/
|
|
14552
15308
|
class TrackedIncrementalBuildStrategy {
|
|
14553
|
-
|
|
14554
|
-
|
|
14555
|
-
this.isSet = false;
|
|
14556
|
-
}
|
|
15309
|
+
state = null;
|
|
15310
|
+
isSet = false;
|
|
14557
15311
|
getIncrementalState() {
|
|
14558
15312
|
return this.state;
|
|
14559
15313
|
}
|
|
@@ -14587,6 +15341,8 @@ var IdentifierKind;
|
|
|
14587
15341
|
* Describes the absolute byte offsets of a text anchor in a source code.
|
|
14588
15342
|
*/
|
|
14589
15343
|
class AbsoluteSourceSpan {
|
|
15344
|
+
start;
|
|
15345
|
+
end;
|
|
14590
15346
|
constructor(start, end) {
|
|
14591
15347
|
this.start = start;
|
|
14592
15348
|
this.end = end;
|
|
@@ -14600,9 +15356,7 @@ class AbsoluteSourceSpan {
|
|
|
14600
15356
|
* `DecoratorHandler`s and exposes them to be indexed.
|
|
14601
15357
|
*/
|
|
14602
15358
|
class IndexingContext {
|
|
14603
|
-
|
|
14604
|
-
this.components = new Set();
|
|
14605
|
-
}
|
|
15359
|
+
components = new Set();
|
|
14606
15360
|
/**
|
|
14607
15361
|
* Adds a component to the context.
|
|
14608
15362
|
*/
|
|
@@ -14620,15 +15374,19 @@ class IndexingContext {
|
|
|
14620
15374
|
* Visiting `text {{prop}}` will return
|
|
14621
15375
|
* `[TopLevelIdentifier {name: 'prop', span: {start: 7, end: 11}}]`.
|
|
14622
15376
|
*/
|
|
14623
|
-
class ExpressionVisitor extends checker.RecursiveAstVisitor {
|
|
15377
|
+
class ExpressionVisitor extends checker.RecursiveAstVisitor$1 {
|
|
15378
|
+
expressionStr;
|
|
15379
|
+
absoluteOffset;
|
|
15380
|
+
boundTemplate;
|
|
15381
|
+
targetToIdentifier;
|
|
15382
|
+
identifiers = [];
|
|
15383
|
+
errors = [];
|
|
14624
15384
|
constructor(expressionStr, absoluteOffset, boundTemplate, targetToIdentifier) {
|
|
14625
15385
|
super();
|
|
14626
15386
|
this.expressionStr = expressionStr;
|
|
14627
15387
|
this.absoluteOffset = absoluteOffset;
|
|
14628
15388
|
this.boundTemplate = boundTemplate;
|
|
14629
15389
|
this.targetToIdentifier = targetToIdentifier;
|
|
14630
|
-
this.identifiers = [];
|
|
14631
|
-
this.errors = [];
|
|
14632
15390
|
}
|
|
14633
15391
|
/**
|
|
14634
15392
|
* Returns identifiers discovered in an expression.
|
|
@@ -14702,6 +15460,14 @@ class ExpressionVisitor extends checker.RecursiveAstVisitor {
|
|
|
14702
15460
|
* identifiers of interest, deferring to an `ExpressionVisitor` as needed.
|
|
14703
15461
|
*/
|
|
14704
15462
|
class TemplateVisitor$1 extends checker.RecursiveVisitor$1 {
|
|
15463
|
+
boundTemplate;
|
|
15464
|
+
// Identifiers of interest found in the template.
|
|
15465
|
+
identifiers = new Set();
|
|
15466
|
+
errors = [];
|
|
15467
|
+
// Map of targets in a template to their identifiers.
|
|
15468
|
+
targetIdentifierCache = new Map();
|
|
15469
|
+
// Map of elements and templates to their identifiers.
|
|
15470
|
+
elementAndTemplateIdentifierCache = new Map();
|
|
14705
15471
|
/**
|
|
14706
15472
|
* Creates a template visitor for a bound template target. The bound target can be used when
|
|
14707
15473
|
* deferred to the expression visitor to get information about the target of an expression.
|
|
@@ -14711,13 +15477,6 @@ class TemplateVisitor$1 extends checker.RecursiveVisitor$1 {
|
|
|
14711
15477
|
constructor(boundTemplate) {
|
|
14712
15478
|
super();
|
|
14713
15479
|
this.boundTemplate = boundTemplate;
|
|
14714
|
-
// Identifiers of interest found in the template.
|
|
14715
|
-
this.identifiers = new Set();
|
|
14716
|
-
this.errors = [];
|
|
14717
|
-
// Map of targets in a template to their identifiers.
|
|
14718
|
-
this.targetIdentifierCache = new Map();
|
|
14719
|
-
// Map of elements and templates to their identifiers.
|
|
14720
|
-
this.elementAndTemplateIdentifierCache = new Map();
|
|
14721
15480
|
}
|
|
14722
15481
|
/**
|
|
14723
15482
|
* Visits a node in the template.
|
|
@@ -15043,17 +15802,19 @@ function generateAnalysis(context) {
|
|
|
15043
15802
|
* An index of all NgModules that export or re-export a given trait.
|
|
15044
15803
|
*/
|
|
15045
15804
|
class NgModuleIndexImpl {
|
|
15805
|
+
metaReader;
|
|
15806
|
+
localReader;
|
|
15046
15807
|
constructor(metaReader, localReader) {
|
|
15047
15808
|
this.metaReader = metaReader;
|
|
15048
15809
|
this.localReader = localReader;
|
|
15049
|
-
// A map from an NgModule's Class Declaration to the "main" reference to that module, aka the one
|
|
15050
|
-
// present in the reader metadata object
|
|
15051
|
-
this.ngModuleAuthoritativeReference = new Map();
|
|
15052
|
-
// A map from a Directive/Pipe's class declaration to the class declarations of all re-exporting
|
|
15053
|
-
// NgModules
|
|
15054
|
-
this.typeToExportingModules = new Map();
|
|
15055
|
-
this.indexed = false;
|
|
15056
15810
|
}
|
|
15811
|
+
// A map from an NgModule's Class Declaration to the "main" reference to that module, aka the one
|
|
15812
|
+
// present in the reader metadata object
|
|
15813
|
+
ngModuleAuthoritativeReference = new Map();
|
|
15814
|
+
// A map from a Directive/Pipe's class declaration to the class declarations of all re-exporting
|
|
15815
|
+
// NgModules
|
|
15816
|
+
typeToExportingModules = new Map();
|
|
15817
|
+
indexed = false;
|
|
15057
15818
|
updateWith(cache, key, elem) {
|
|
15058
15819
|
if (cache.has(key)) {
|
|
15059
15820
|
cache.get(key).add(elem);
|
|
@@ -15146,11 +15907,16 @@ const RESOURCE_MARKER_TS = RESOURCE_MARKER + '.ts';
|
|
|
15146
15907
|
* `ResourceLoader` which delegates to an `NgCompilerAdapter`'s resource loading methods.
|
|
15147
15908
|
*/
|
|
15148
15909
|
class AdapterResourceLoader {
|
|
15910
|
+
adapter;
|
|
15911
|
+
options;
|
|
15912
|
+
cache = new Map();
|
|
15913
|
+
fetching = new Map();
|
|
15914
|
+
lookupResolutionHost;
|
|
15915
|
+
canPreload;
|
|
15916
|
+
canPreprocess;
|
|
15149
15917
|
constructor(adapter, options) {
|
|
15150
15918
|
this.adapter = adapter;
|
|
15151
15919
|
this.options = options;
|
|
15152
|
-
this.cache = new Map();
|
|
15153
|
-
this.fetching = new Map();
|
|
15154
15920
|
this.lookupResolutionHost = createLookupResolutionHost(this.adapter);
|
|
15155
15921
|
this.canPreload = !!this.adapter.readResource;
|
|
15156
15922
|
this.canPreprocess = !!this.adapter.transformResource;
|
|
@@ -15382,11 +16148,14 @@ function createLookupResolutionHost(adapter) {
|
|
|
15382
16148
|
* scopes where necessary.
|
|
15383
16149
|
*/
|
|
15384
16150
|
class StandaloneComponentScopeReader {
|
|
16151
|
+
metaReader;
|
|
16152
|
+
localModuleReader;
|
|
16153
|
+
dtsModuleReader;
|
|
16154
|
+
cache = new Map();
|
|
15385
16155
|
constructor(metaReader, localModuleReader, dtsModuleReader) {
|
|
15386
16156
|
this.metaReader = metaReader;
|
|
15387
16157
|
this.localModuleReader = localModuleReader;
|
|
15388
16158
|
this.dtsModuleReader = dtsModuleReader;
|
|
15389
|
-
this.cache = new Map();
|
|
15390
16159
|
}
|
|
15391
16160
|
getScopeForComponent(clazz) {
|
|
15392
16161
|
if (!this.cache.has(clazz)) {
|
|
@@ -15522,18 +16291,16 @@ function isSignalSymbol(symbol) {
|
|
|
15522
16291
|
* This abstract class provides a base implementation for the run method.
|
|
15523
16292
|
*/
|
|
15524
16293
|
class TemplateCheckWithVisitor {
|
|
15525
|
-
|
|
15526
|
-
|
|
15527
|
-
|
|
15528
|
-
|
|
15529
|
-
|
|
15530
|
-
|
|
15531
|
-
|
|
15532
|
-
|
|
15533
|
-
|
|
15534
|
-
|
|
15535
|
-
this.canVisitStructuralAttributes = true;
|
|
15536
|
-
}
|
|
16294
|
+
/**
|
|
16295
|
+
* When extended diagnostics were first introduced, the visitor wasn't implemented correctly
|
|
16296
|
+
* which meant that it wasn't visiting the `templateAttrs` of structural directives (e.g.
|
|
16297
|
+
* the expression of `*ngIf`). Fixing the issue causes a lot of internal breakages and will likely
|
|
16298
|
+
* need to be done in a major version to avoid external breakages. This flag is used to opt out
|
|
16299
|
+
* pre-existing diagnostics from the correct behavior until the breakages have been fixed while
|
|
16300
|
+
* ensuring that newly-written diagnostics are correct from the beginning.
|
|
16301
|
+
* TODO(crisbeto): remove this flag and fix the internal brekages.
|
|
16302
|
+
*/
|
|
16303
|
+
canVisitStructuralAttributes = true;
|
|
15537
16304
|
/**
|
|
15538
16305
|
* Base implementation for run function, visits all nodes in template and calls
|
|
15539
16306
|
* `visitNode()` for each one.
|
|
@@ -15546,13 +16313,16 @@ class TemplateCheckWithVisitor {
|
|
|
15546
16313
|
/**
|
|
15547
16314
|
* Visits all nodes in a template (TmplAstNode and AST) and calls `visitNode` for each one.
|
|
15548
16315
|
*/
|
|
15549
|
-
class TemplateVisitor extends checker.RecursiveAstVisitor {
|
|
16316
|
+
class TemplateVisitor extends checker.RecursiveAstVisitor$1 {
|
|
16317
|
+
ctx;
|
|
16318
|
+
component;
|
|
16319
|
+
check;
|
|
16320
|
+
diagnostics = [];
|
|
15550
16321
|
constructor(ctx, component, check) {
|
|
15551
16322
|
super();
|
|
15552
16323
|
this.ctx = ctx;
|
|
15553
16324
|
this.component = component;
|
|
15554
16325
|
this.check = check;
|
|
15555
|
-
this.diagnostics = [];
|
|
15556
16326
|
}
|
|
15557
16327
|
visit(node, context) {
|
|
15558
16328
|
this.diagnostics.push(...this.check.visitNode(this.ctx, this.component, node));
|
|
@@ -15680,10 +16450,7 @@ const FUNCTION_INSTANCE_PROPERTIES = new Set(['name', 'length', 'prototype']);
|
|
|
15680
16450
|
* Ensures Signals are invoked when used in template interpolations.
|
|
15681
16451
|
*/
|
|
15682
16452
|
class InterpolatedSignalCheck extends TemplateCheckWithVisitor {
|
|
15683
|
-
|
|
15684
|
-
super(...arguments);
|
|
15685
|
-
this.code = checker.ErrorCode.INTERPOLATED_SIGNAL_NOT_INVOKED;
|
|
15686
|
-
}
|
|
16453
|
+
code = checker.ErrorCode.INTERPOLATED_SIGNAL_NOT_INVOKED;
|
|
15687
16454
|
visitNode(ctx, component, node) {
|
|
15688
16455
|
// interpolations like `{{ mySignal }}`
|
|
15689
16456
|
if (node instanceof checker.Interpolation) {
|
|
@@ -15763,10 +16530,7 @@ const factory$9 = {
|
|
|
15763
16530
|
* Will return diagnostic information when "([])" is found.
|
|
15764
16531
|
*/
|
|
15765
16532
|
class InvalidBananaInBoxCheck extends TemplateCheckWithVisitor {
|
|
15766
|
-
|
|
15767
|
-
super(...arguments);
|
|
15768
|
-
this.code = checker.ErrorCode.INVALID_BANANA_IN_BOX;
|
|
15769
|
-
}
|
|
16533
|
+
code = checker.ErrorCode.INVALID_BANANA_IN_BOX;
|
|
15770
16534
|
visitNode(ctx, component, node) {
|
|
15771
16535
|
if (!(node instanceof checker.BoundEvent))
|
|
15772
16536
|
return [];
|
|
@@ -15811,10 +16575,7 @@ const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
|
|
|
15811
16575
|
* hard error instead of a warning.
|
|
15812
16576
|
*/
|
|
15813
16577
|
class MissingControlFlowDirectiveCheck extends TemplateCheckWithVisitor {
|
|
15814
|
-
|
|
15815
|
-
super(...arguments);
|
|
15816
|
-
this.code = checker.ErrorCode.MISSING_CONTROL_FLOW_DIRECTIVE;
|
|
15817
|
-
}
|
|
16578
|
+
code = checker.ErrorCode.MISSING_CONTROL_FLOW_DIRECTIVE;
|
|
15818
16579
|
run(ctx, component, template) {
|
|
15819
16580
|
const componentMetadata = ctx.templateTypeChecker.getDirectiveMetadata(component);
|
|
15820
16581
|
// Avoid running this check for non-standalone components.
|
|
@@ -15857,10 +16618,7 @@ const factory$7 = {
|
|
|
15857
16618
|
* Will return diagnostic information when `let` is missing.
|
|
15858
16619
|
*/
|
|
15859
16620
|
class MissingNgForOfLetCheck extends TemplateCheckWithVisitor {
|
|
15860
|
-
|
|
15861
|
-
super(...arguments);
|
|
15862
|
-
this.code = checker.ErrorCode.MISSING_NGFOROF_LET;
|
|
15863
|
-
}
|
|
16621
|
+
code = checker.ErrorCode.MISSING_NGFOROF_LET;
|
|
15864
16622
|
visitNode(ctx, component, node) {
|
|
15865
16623
|
if (!(node instanceof checker.Template)) {
|
|
15866
16624
|
return [];
|
|
@@ -15893,11 +16651,8 @@ const factory$6 = {
|
|
|
15893
16651
|
* otherwise it would produce inaccurate results.
|
|
15894
16652
|
*/
|
|
15895
16653
|
class NullishCoalescingNotNullableCheck extends TemplateCheckWithVisitor {
|
|
15896
|
-
|
|
15897
|
-
|
|
15898
|
-
this.canVisitStructuralAttributes = false;
|
|
15899
|
-
this.code = checker.ErrorCode.NULLISH_COALESCING_NOT_NULLABLE;
|
|
15900
|
-
}
|
|
16654
|
+
canVisitStructuralAttributes = false;
|
|
16655
|
+
code = checker.ErrorCode.NULLISH_COALESCING_NOT_NULLABLE;
|
|
15901
16656
|
visitNode(ctx, component, node) {
|
|
15902
16657
|
if (!(node instanceof checker.Binary) || node.operation !== '??')
|
|
15903
16658
|
return [];
|
|
@@ -15948,11 +16703,8 @@ const factory$5 = {
|
|
|
15948
16703
|
* otherwise it would produce inaccurate results.
|
|
15949
16704
|
*/
|
|
15950
16705
|
class OptionalChainNotNullableCheck extends TemplateCheckWithVisitor {
|
|
15951
|
-
|
|
15952
|
-
|
|
15953
|
-
this.canVisitStructuralAttributes = false;
|
|
15954
|
-
this.code = checker.ErrorCode.OPTIONAL_CHAIN_NOT_NULLABLE;
|
|
15955
|
-
}
|
|
16706
|
+
canVisitStructuralAttributes = false;
|
|
16707
|
+
code = checker.ErrorCode.OPTIONAL_CHAIN_NOT_NULLABLE;
|
|
15956
16708
|
visitNode(ctx, component, node) {
|
|
15957
16709
|
if (!(node instanceof checker.SafeCall) &&
|
|
15958
16710
|
!(node instanceof checker.SafePropertyRead) &&
|
|
@@ -16007,10 +16759,7 @@ const STYLE_SUFFIXES = ['px', '%', 'em'];
|
|
|
16007
16759
|
* binding. These suffixes are only available for style bindings.
|
|
16008
16760
|
*/
|
|
16009
16761
|
class SuffixNotSupportedCheck extends TemplateCheckWithVisitor {
|
|
16010
|
-
|
|
16011
|
-
super(...arguments);
|
|
16012
|
-
this.code = checker.ErrorCode.SUFFIX_NOT_SUPPORTED;
|
|
16013
|
-
}
|
|
16762
|
+
code = checker.ErrorCode.SUFFIX_NOT_SUPPORTED;
|
|
16014
16763
|
visitNode(ctx, component, node) {
|
|
16015
16764
|
if (!(node instanceof checker.BoundAttribute))
|
|
16016
16765
|
return [];
|
|
@@ -16036,10 +16785,7 @@ const factory$3 = {
|
|
|
16036
16785
|
* to 'my-id'.
|
|
16037
16786
|
*/
|
|
16038
16787
|
class TextAttributeNotBindingSpec extends TemplateCheckWithVisitor {
|
|
16039
|
-
|
|
16040
|
-
super(...arguments);
|
|
16041
|
-
this.code = checker.ErrorCode.TEXT_ATTRIBUTE_NOT_BINDING;
|
|
16042
|
-
}
|
|
16788
|
+
code = checker.ErrorCode.TEXT_ATTRIBUTE_NOT_BINDING;
|
|
16043
16789
|
visitNode(ctx, component, node) {
|
|
16044
16790
|
if (!(node instanceof checker.TextAttribute))
|
|
16045
16791
|
return [];
|
|
@@ -16082,10 +16828,7 @@ const factory$2 = {
|
|
|
16082
16828
|
* This is likely not the intent of the developer. Instead, the intent is likely to call `myFunc`.
|
|
16083
16829
|
*/
|
|
16084
16830
|
class UninvokedFunctionInEventBindingSpec extends TemplateCheckWithVisitor {
|
|
16085
|
-
|
|
16086
|
-
super(...arguments);
|
|
16087
|
-
this.code = checker.ErrorCode.UNINVOKED_FUNCTION_IN_EVENT_BINDING;
|
|
16088
|
-
}
|
|
16831
|
+
code = checker.ErrorCode.UNINVOKED_FUNCTION_IN_EVENT_BINDING;
|
|
16089
16832
|
visitNode(ctx, component, node) {
|
|
16090
16833
|
// If the node is not a bound event, skip it.
|
|
16091
16834
|
if (!(node instanceof checker.BoundEvent))
|
|
@@ -16143,11 +16886,8 @@ const factory$1 = {
|
|
|
16143
16886
|
* Ensures that all `@let` declarations in a template are used.
|
|
16144
16887
|
*/
|
|
16145
16888
|
class UnusedLetDeclarationCheck extends TemplateCheckWithVisitor {
|
|
16146
|
-
|
|
16147
|
-
|
|
16148
|
-
this.code = checker.ErrorCode.UNUSED_LET_DECLARATION;
|
|
16149
|
-
this.analysis = new Map();
|
|
16150
|
-
}
|
|
16889
|
+
code = checker.ErrorCode.UNUSED_LET_DECLARATION;
|
|
16890
|
+
analysis = new Map();
|
|
16151
16891
|
run(ctx, component, template) {
|
|
16152
16892
|
super.run(ctx, component, template);
|
|
16153
16893
|
const diagnostics = [];
|
|
@@ -16203,6 +16943,8 @@ var DiagnosticCategoryLabel;
|
|
|
16203
16943
|
})(DiagnosticCategoryLabel || (DiagnosticCategoryLabel = {}));
|
|
16204
16944
|
|
|
16205
16945
|
class ExtendedTemplateCheckerImpl {
|
|
16946
|
+
partialCtx;
|
|
16947
|
+
templateChecks;
|
|
16206
16948
|
constructor(templateTypeChecker, typeChecker, templateCheckFactories, options) {
|
|
16207
16949
|
this.partialCtx = { templateTypeChecker, typeChecker };
|
|
16208
16950
|
this.templateChecks = new Map();
|
|
@@ -16289,6 +17031,7 @@ const SUPPORTED_DIAGNOSTIC_NAMES = new Set([
|
|
|
16289
17031
|
]);
|
|
16290
17032
|
|
|
16291
17033
|
class TemplateSemanticsCheckerImpl {
|
|
17034
|
+
templateTypeChecker;
|
|
16292
17035
|
constructor(templateTypeChecker) {
|
|
16293
17036
|
this.templateTypeChecker = templateTypeChecker;
|
|
16294
17037
|
}
|
|
@@ -16301,6 +17044,7 @@ class TemplateSemanticsCheckerImpl {
|
|
|
16301
17044
|
}
|
|
16302
17045
|
/** Visitor that verifies the semantics of a template. */
|
|
16303
17046
|
class TemplateSemanticsVisitor extends checker.RecursiveVisitor$1 {
|
|
17047
|
+
expressionVisitor;
|
|
16304
17048
|
constructor(expressionVisitor) {
|
|
16305
17049
|
super();
|
|
16306
17050
|
this.expressionVisitor = expressionVisitor;
|
|
@@ -16318,7 +17062,10 @@ class TemplateSemanticsVisitor extends checker.RecursiveVisitor$1 {
|
|
|
16318
17062
|
}
|
|
16319
17063
|
}
|
|
16320
17064
|
/** Visitor that verifies the semantics of the expressions within a template. */
|
|
16321
|
-
class ExpressionsSemanticsVisitor extends checker.RecursiveAstVisitor {
|
|
17065
|
+
class ExpressionsSemanticsVisitor extends checker.RecursiveAstVisitor$1 {
|
|
17066
|
+
templateTypeChecker;
|
|
17067
|
+
component;
|
|
17068
|
+
diagnostics;
|
|
16322
17069
|
constructor(templateTypeChecker, component, diagnostics) {
|
|
16323
17070
|
super();
|
|
16324
17071
|
this.templateTypeChecker = templateTypeChecker;
|
|
@@ -16404,6 +17151,8 @@ const APIS_TO_CHECK = [
|
|
|
16404
17151
|
* Rule that flags any initializer APIs that are used outside of an initializer.
|
|
16405
17152
|
*/
|
|
16406
17153
|
class InitializerApiUsageRule {
|
|
17154
|
+
reflector;
|
|
17155
|
+
importedSymbolsTracker;
|
|
16407
17156
|
constructor(reflector, importedSymbolsTracker) {
|
|
16408
17157
|
this.reflector = reflector;
|
|
16409
17158
|
this.importedSymbolsTracker = importedSymbolsTracker;
|
|
@@ -16467,6 +17216,9 @@ class InitializerApiUsageRule {
|
|
|
16467
17216
|
* Rule that flags unused symbols inside of the `imports` array of a component.
|
|
16468
17217
|
*/
|
|
16469
17218
|
class UnusedStandaloneImportsRule {
|
|
17219
|
+
templateTypeChecker;
|
|
17220
|
+
typeCheckingConfig;
|
|
17221
|
+
importedSymbolsTracker;
|
|
16470
17222
|
constructor(templateTypeChecker, typeCheckingConfig, importedSymbolsTracker) {
|
|
16471
17223
|
this.templateTypeChecker = templateTypeChecker;
|
|
16472
17224
|
this.typeCheckingConfig = typeCheckingConfig;
|
|
@@ -16576,6 +17328,7 @@ class UnusedStandaloneImportsRule {
|
|
|
16576
17328
|
* Validates that TypeScript files match a specific set of rules set by the Angular compiler.
|
|
16577
17329
|
*/
|
|
16578
17330
|
class SourceFileValidator {
|
|
17331
|
+
rules;
|
|
16579
17332
|
constructor(reflector, importedSymbolsTracker, templateTypeChecker, typeCheckingConfig) {
|
|
16580
17333
|
this.rules = [new InitializerApiUsageRule(reflector, importedSymbolsTracker)];
|
|
16581
17334
|
{
|
|
@@ -19307,7 +20060,7 @@ var semver = /*@__PURE__*/getDefaultExportFromCjs(semverExports);
|
|
|
19307
20060
|
* @param minVersion Minimum required version for the feature.
|
|
19308
20061
|
*/
|
|
19309
20062
|
function coreVersionSupportsFeature(coreVersion, minVersion) {
|
|
19310
|
-
// A version of `19.0.0-
|
|
20063
|
+
// A version of `19.0.0-rc.0` usually means that core is at head so it supports
|
|
19311
20064
|
// all features. Use string interpolation prevent the placeholder from being replaced
|
|
19312
20065
|
// with the current version during build time.
|
|
19313
20066
|
if (coreVersion === `0.0.0-${'PLACEHOLDER'}`) {
|
|
@@ -19381,6 +20134,54 @@ function incrementalFromCompilerTicket(oldCompiler, newProgram, incrementalBuild
|
|
|
19381
20134
|
* See the README.md for more information.
|
|
19382
20135
|
*/
|
|
19383
20136
|
class NgCompiler {
|
|
20137
|
+
adapter;
|
|
20138
|
+
options;
|
|
20139
|
+
inputProgram;
|
|
20140
|
+
programDriver;
|
|
20141
|
+
incrementalStrategy;
|
|
20142
|
+
incrementalCompilation;
|
|
20143
|
+
usePoisonedData;
|
|
20144
|
+
livePerfRecorder;
|
|
20145
|
+
/**
|
|
20146
|
+
* Lazily evaluated state of the compilation.
|
|
20147
|
+
*
|
|
20148
|
+
* This is created on demand by calling `ensureAnalyzed`.
|
|
20149
|
+
*/
|
|
20150
|
+
compilation = null;
|
|
20151
|
+
/**
|
|
20152
|
+
* Any diagnostics related to the construction of the compilation.
|
|
20153
|
+
*
|
|
20154
|
+
* These are diagnostics which arose during setup of the host and/or program.
|
|
20155
|
+
*/
|
|
20156
|
+
constructionDiagnostics = [];
|
|
20157
|
+
/**
|
|
20158
|
+
* Non-template diagnostics related to the program itself. Does not include template
|
|
20159
|
+
* diagnostics because the template type checker memoizes them itself.
|
|
20160
|
+
*
|
|
20161
|
+
* This is set by (and memoizes) `getNonTemplateDiagnostics`.
|
|
20162
|
+
*/
|
|
20163
|
+
nonTemplateDiagnostics = null;
|
|
20164
|
+
closureCompilerEnabled;
|
|
20165
|
+
currentProgram;
|
|
20166
|
+
entryPoint;
|
|
20167
|
+
moduleResolver;
|
|
20168
|
+
resourceManager;
|
|
20169
|
+
cycleAnalyzer;
|
|
20170
|
+
ignoreForDiagnostics;
|
|
20171
|
+
ignoreForEmit;
|
|
20172
|
+
enableTemplateTypeChecker;
|
|
20173
|
+
enableBlockSyntax;
|
|
20174
|
+
enableLetSyntax;
|
|
20175
|
+
angularCoreVersion;
|
|
20176
|
+
enableHmr;
|
|
20177
|
+
implicitStandaloneValue;
|
|
20178
|
+
/**
|
|
20179
|
+
* `NgCompiler` can be reused for multiple compilations (for resource-only changes), and each
|
|
20180
|
+
* new compilation uses a fresh `PerfRecorder`. Thus, classes created with a lifespan of the
|
|
20181
|
+
* `NgCompiler` use a `DelegatingPerfRecorder` so the `PerfRecorder` they write to can be updated
|
|
20182
|
+
* with each fresh compilation.
|
|
20183
|
+
*/
|
|
20184
|
+
delegatingPerfRecorder;
|
|
19384
20185
|
/**
|
|
19385
20186
|
* Convert a `CompilationTicket` into an `NgCompiler` instance for the requested compilation.
|
|
19386
20187
|
*
|
|
@@ -19410,25 +20211,7 @@ class NgCompiler {
|
|
|
19410
20211
|
this.incrementalCompilation = incrementalCompilation;
|
|
19411
20212
|
this.usePoisonedData = usePoisonedData;
|
|
19412
20213
|
this.livePerfRecorder = livePerfRecorder;
|
|
19413
|
-
|
|
19414
|
-
* Lazily evaluated state of the compilation.
|
|
19415
|
-
*
|
|
19416
|
-
* This is created on demand by calling `ensureAnalyzed`.
|
|
19417
|
-
*/
|
|
19418
|
-
this.compilation = null;
|
|
19419
|
-
/**
|
|
19420
|
-
* Any diagnostics related to the construction of the compilation.
|
|
19421
|
-
*
|
|
19422
|
-
* These are diagnostics which arose during setup of the host and/or program.
|
|
19423
|
-
*/
|
|
19424
|
-
this.constructionDiagnostics = [];
|
|
19425
|
-
/**
|
|
19426
|
-
* Non-template diagnostics related to the program itself. Does not include template
|
|
19427
|
-
* diagnostics because the template type checker memoizes them itself.
|
|
19428
|
-
*
|
|
19429
|
-
* This is set by (and memoizes) `getNonTemplateDiagnostics`.
|
|
19430
|
-
*/
|
|
19431
|
-
this.nonTemplateDiagnostics = null;
|
|
20214
|
+
this.angularCoreVersion = options['_angularCoreVersion'] ?? null;
|
|
19432
20215
|
this.delegatingPerfRecorder = new DelegatingPerfRecorder(this.perfRecorder);
|
|
19433
20216
|
this.usePoisonedData = usePoisonedData || !!options._compilePoisonedComponents;
|
|
19434
20217
|
this.enableTemplateTypeChecker =
|
|
@@ -19436,7 +20219,13 @@ class NgCompiler {
|
|
|
19436
20219
|
// TODO(crisbeto): remove this flag and base `enableBlockSyntax` on the `angularCoreVersion`.
|
|
19437
20220
|
this.enableBlockSyntax = options['_enableBlockSyntax'] ?? true;
|
|
19438
20221
|
this.enableLetSyntax = options['_enableLetSyntax'] ?? true;
|
|
19439
|
-
|
|
20222
|
+
// Standalone by default is enabled since v19. We need to toggle it here,
|
|
20223
|
+
// because the language service extension may be running with the latest
|
|
20224
|
+
// version of the compiler against an older version of Angular.
|
|
20225
|
+
this.implicitStandaloneValue =
|
|
20226
|
+
this.angularCoreVersion === null ||
|
|
20227
|
+
coreVersionSupportsFeature(this.angularCoreVersion, '>= 19.0.0-0');
|
|
20228
|
+
this.enableHmr = !!options['_enableHmr'];
|
|
19440
20229
|
this.constructionDiagnostics.push(...this.adapter.constructionDiagnostics, ...verifyCompatibleTypeCheckOptions(this.options));
|
|
19441
20230
|
this.currentProgram = inputProgram;
|
|
19442
20231
|
this.closureCompilerEnabled = !!this.options.annotateForClosureCompiler;
|
|
@@ -19804,6 +20593,28 @@ class NgCompiler {
|
|
|
19804
20593
|
const compilation = this.ensureAnalyzed();
|
|
19805
20594
|
compilation.traitCompiler.xi18n(ctx);
|
|
19806
20595
|
}
|
|
20596
|
+
/**
|
|
20597
|
+
* Emits the JavaScript module that can be used to replace the metadata of a class during HMR.
|
|
20598
|
+
* @param node Class for which to generate the update module.
|
|
20599
|
+
*/
|
|
20600
|
+
emitHmrUpdateModule(node) {
|
|
20601
|
+
const { traitCompiler, reflector } = this.ensureAnalyzed();
|
|
20602
|
+
if (!reflector.isClass(node)) {
|
|
20603
|
+
return null;
|
|
20604
|
+
}
|
|
20605
|
+
const callback = traitCompiler.compileHmrUpdateCallback(node);
|
|
20606
|
+
if (callback === null) {
|
|
20607
|
+
return null;
|
|
20608
|
+
}
|
|
20609
|
+
const sourceFile = node.getSourceFile();
|
|
20610
|
+
const printer = ts__default["default"].createPrinter();
|
|
20611
|
+
const nodeText = printer.printNode(ts__default["default"].EmitHint.Unspecified, callback, sourceFile);
|
|
20612
|
+
return ts__default["default"].transpileModule(nodeText, {
|
|
20613
|
+
compilerOptions: this.options,
|
|
20614
|
+
fileName: sourceFile.fileName,
|
|
20615
|
+
reportDiagnostics: false,
|
|
20616
|
+
}).outputText;
|
|
20617
|
+
}
|
|
19807
20618
|
ensureAnalyzed() {
|
|
19808
20619
|
if (this.compilation === null) {
|
|
19809
20620
|
this.analyzeSync();
|
|
@@ -20182,13 +20993,13 @@ class NgCompiler {
|
|
|
20182
20993
|
const jitDeclarationRegistry = new JitDeclarationRegistry();
|
|
20183
20994
|
// Set up the IvyCompilation, which manages state for the Ivy transformer.
|
|
20184
20995
|
const handlers = [
|
|
20185
|
-
new ComponentDecoratorHandler(reflector, evaluator, metaRegistry, metaReader, scopeReader,
|
|
20996
|
+
new ComponentDecoratorHandler(reflector, evaluator, metaRegistry, metaReader, scopeReader, this.adapter, ngModuleScopeRegistry, typeCheckScopeRegistry, resourceRegistry, isCore, strictCtorDeps, this.resourceManager, this.adapter.rootDirs, this.options.preserveWhitespaces || false, this.options.i18nUseExternalIds !== false, this.options.enableI18nLegacyMessageIdFormat !== false, this.usePoisonedData, this.options.i18nNormalizeLineEndingsInICUs === true, this.moduleResolver, this.cycleAnalyzer, cycleHandlingStrategy, refEmitter, referencesRegistry, this.incrementalCompilation.depGraph, injectableRegistry, semanticDepGraphUpdater, this.closureCompilerEnabled, this.delegatingPerfRecorder, hostDirectivesResolver, importTracker, supportTestBed, compilationMode, deferredSymbolsTracker, !!this.options.forbidOrphanComponents, this.enableBlockSyntax, this.enableLetSyntax, externalRuntimeStyles, localCompilationExtraImportsTracker, jitDeclarationRegistry, this.options.i18nPreserveWhitespaceForLegacyExtraction ?? true, !!this.options.strictStandalone, this.enableHmr, this.implicitStandaloneValue),
|
|
20186
20997
|
// TODO(alxhub): understand why the cast here is necessary (something to do with `null`
|
|
20187
20998
|
// not being assignable to `unknown` when wrapped in `Readonly`).
|
|
20188
|
-
new DirectiveDecoratorHandler(reflector, evaluator, metaRegistry, ngModuleScopeRegistry, metaReader, injectableRegistry, refEmitter, referencesRegistry, isCore, strictCtorDeps, semanticDepGraphUpdater, this.closureCompilerEnabled, this.delegatingPerfRecorder, importTracker, supportTestBed, compilationMode, jitDeclarationRegistry, !!this.options.strictStandalone),
|
|
20999
|
+
new DirectiveDecoratorHandler(reflector, evaluator, metaRegistry, ngModuleScopeRegistry, metaReader, injectableRegistry, refEmitter, referencesRegistry, isCore, strictCtorDeps, semanticDepGraphUpdater, this.closureCompilerEnabled, this.delegatingPerfRecorder, importTracker, supportTestBed, compilationMode, jitDeclarationRegistry, !!this.options.strictStandalone, this.implicitStandaloneValue),
|
|
20189
21000
|
// Pipe handler must be before injectable handler in list so pipe factories are printed
|
|
20190
21001
|
// before injectable factories (so injectable factories can delegate to them)
|
|
20191
|
-
new PipeDecoratorHandler(reflector, evaluator, metaRegistry, ngModuleScopeRegistry, injectableRegistry, isCore, this.delegatingPerfRecorder, supportTestBed, compilationMode, !!this.options.generateExtraImportsInLocalMode, !!this.options.strictStandalone),
|
|
21002
|
+
new PipeDecoratorHandler(reflector, evaluator, metaRegistry, ngModuleScopeRegistry, injectableRegistry, isCore, this.delegatingPerfRecorder, supportTestBed, compilationMode, !!this.options.generateExtraImportsInLocalMode, !!this.options.strictStandalone, this.implicitStandaloneValue),
|
|
20192
21003
|
new InjectableDecoratorHandler(reflector, evaluator, isCore, strictCtorDeps, injectableRegistry, this.delegatingPerfRecorder, supportTestBed, compilationMode),
|
|
20193
21004
|
new NgModuleDecoratorHandler(reflector, evaluator, metaReader, metaRegistry, ngModuleScopeRegistry, referencesRegistry, exportedProviderStatusResolver, semanticDepGraphUpdater, isCore, refEmitter, this.closureCompilerEnabled, this.options.onlyPublishPublicTypingsForNgModules ?? false, injectableRegistry, this.delegatingPerfRecorder, supportTestBed, supportJitMode, compilationMode, localCompilationExtraImportsTracker, jitDeclarationRegistry),
|
|
20194
21005
|
];
|
|
@@ -20367,6 +21178,7 @@ function makeConfigDiagnostic({ category, code, messageText, }) {
|
|
|
20367
21178
|
};
|
|
20368
21179
|
}
|
|
20369
21180
|
class ReferenceGraphAdapter {
|
|
21181
|
+
graph;
|
|
20370
21182
|
constructor(graph) {
|
|
20371
21183
|
this.graph = graph;
|
|
20372
21184
|
}
|
|
@@ -20384,6 +21196,9 @@ class ReferenceGraphAdapter {
|
|
|
20384
21196
|
}
|
|
20385
21197
|
}
|
|
20386
21198
|
class NotifyingProgramDriverWrapper {
|
|
21199
|
+
delegate;
|
|
21200
|
+
notifyNewProgram;
|
|
21201
|
+
getSourceFileVersion;
|
|
20387
21202
|
constructor(delegate, notifyNewProgram) {
|
|
20388
21203
|
this.delegate = delegate;
|
|
20389
21204
|
this.notifyNewProgram = notifyNewProgram;
|
|
@@ -20424,6 +21239,36 @@ function versionMapFromProgram(program, driver) {
|
|
|
20424
21239
|
* generated for this class.
|
|
20425
21240
|
*/
|
|
20426
21241
|
class DelegatingCompilerHost {
|
|
21242
|
+
delegate;
|
|
21243
|
+
createHash;
|
|
21244
|
+
directoryExists;
|
|
21245
|
+
fileNameToModuleName;
|
|
21246
|
+
getCancellationToken;
|
|
21247
|
+
getCanonicalFileName;
|
|
21248
|
+
getCurrentDirectory;
|
|
21249
|
+
getDefaultLibFileName;
|
|
21250
|
+
getDefaultLibLocation;
|
|
21251
|
+
getDirectories;
|
|
21252
|
+
getEnvironmentVariable;
|
|
21253
|
+
getModifiedResourceFiles;
|
|
21254
|
+
getNewLine;
|
|
21255
|
+
getParsedCommandLine;
|
|
21256
|
+
getSourceFileByPath;
|
|
21257
|
+
readDirectory;
|
|
21258
|
+
readFile;
|
|
21259
|
+
readResource;
|
|
21260
|
+
transformResource;
|
|
21261
|
+
realpath;
|
|
21262
|
+
resolveModuleNames;
|
|
21263
|
+
resolveTypeReferenceDirectives;
|
|
21264
|
+
resourceNameToFileName;
|
|
21265
|
+
trace;
|
|
21266
|
+
useCaseSensitiveFileNames;
|
|
21267
|
+
writeFile;
|
|
21268
|
+
getModuleResolutionCache;
|
|
21269
|
+
hasInvalidatedResolutions;
|
|
21270
|
+
resolveModuleNameLiterals;
|
|
21271
|
+
resolveTypeReferenceDirectiveReferences;
|
|
20427
21272
|
// jsDocParsingMode is not a method like the other elements above
|
|
20428
21273
|
// TODO: ignore usage can be dropped once 5.2 support is dropped
|
|
20429
21274
|
get jsDocParsingMode() {
|
|
@@ -20487,11 +21332,16 @@ class DelegatingCompilerHost {
|
|
|
20487
21332
|
* `ExtendedTsCompilerHost` methods whenever present.
|
|
20488
21333
|
*/
|
|
20489
21334
|
class NgCompilerHost extends DelegatingCompilerHost {
|
|
21335
|
+
shimAdapter;
|
|
21336
|
+
shimTagger;
|
|
21337
|
+
entryPoint = null;
|
|
21338
|
+
constructionDiagnostics;
|
|
21339
|
+
inputFiles;
|
|
21340
|
+
rootDirs;
|
|
20490
21341
|
constructor(delegate, inputFiles, rootDirs, shimAdapter, shimTagger, entryPoint, diagnostics) {
|
|
20491
21342
|
super(delegate);
|
|
20492
21343
|
this.shimAdapter = shimAdapter;
|
|
20493
21344
|
this.shimTagger = shimTagger;
|
|
20494
|
-
this.entryPoint = null;
|
|
20495
21345
|
this.entryPoint = entryPoint;
|
|
20496
21346
|
this.constructionDiagnostics = diagnostics;
|
|
20497
21347
|
this.inputFiles = [...inputFiles, ...shimAdapter.extraInputFiles];
|
|
@@ -20636,6 +21486,14 @@ class NgCompilerHost extends DelegatingCompilerHost {
|
|
|
20636
21486
|
* command-line main() function or the Angular CLI.
|
|
20637
21487
|
*/
|
|
20638
21488
|
class NgtscProgram {
|
|
21489
|
+
options;
|
|
21490
|
+
compiler;
|
|
21491
|
+
/**
|
|
21492
|
+
* The primary TypeScript program, which is used for analysis and emit.
|
|
21493
|
+
*/
|
|
21494
|
+
tsProgram;
|
|
21495
|
+
host;
|
|
21496
|
+
incrementalStrategy;
|
|
20639
21497
|
constructor(rootNames, options, delegateHost, oldProgram) {
|
|
20640
21498
|
this.options = options;
|
|
20641
21499
|
const perfRecorder = ActivePerfRecorder.zeroedToNow();
|