@angular/core 20.1.2 → 20.2.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.d.d.ts +1 -1
- package/chrome_dev_tools_performance.d.d.ts +1 -1
- package/discovery.d.d.ts +1 -1
- package/event_dispatcher.d.d.ts +1 -1
- package/fesm2022/attribute.mjs +1 -1
- package/fesm2022/attribute.mjs.map +1 -1
- package/fesm2022/core.mjs +2 -2
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/debug_node.mjs +2 -2
- package/fesm2022/debug_node.mjs.map +1 -1
- package/fesm2022/not_found.mjs +1 -1
- package/fesm2022/not_found.mjs.map +1 -1
- package/fesm2022/primitives/di.mjs +1 -1
- package/fesm2022/primitives/di.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/resource.mjs +1 -1
- package/fesm2022/resource.mjs.map +1 -1
- package/fesm2022/root_effect_scheduler.mjs +1 -1
- package/fesm2022/root_effect_scheduler.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/signal.mjs +1 -1
- package/fesm2022/signal.mjs.map +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/untracked.mjs +1 -1
- package/fesm2022/untracked.mjs.map +1 -1
- package/fesm2022/weak_ref.mjs +1 -1
- package/fesm2022/weak_ref.mjs.map +1 -1
- package/graph.d.d.ts +1 -1
- package/index.d.ts +1 -1
- package/package.json +2 -2
- package/primitives/di/index.d.ts +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/bundles/{apply_import_manager-4lhgojXS.cjs → apply_import_manager-ceekZYTK.cjs} +3 -3
- package/schematics/bundles/{checker-B0RMVBjs.cjs → checker-BVY3FNBy.cjs} +517 -327
- package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
- package/schematics/bundles/{compiler_host-D9M-RwqC.cjs → compiler_host-DRAgYPzr.cjs} +2 -2
- package/schematics/bundles/control-flow-migration.cjs +3 -3
- package/schematics/bundles/document-core.cjs +5 -5
- package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
- package/schematics/bundles/{index-BIFHM-Gi.cjs → index-B7rvD9dh.cjs} +13 -13
- package/schematics/bundles/{index-B1wVLvRR.cjs → index-DkKydW5H.cjs} +4 -4
- package/schematics/bundles/inject-flags.cjs +5 -5
- package/schematics/bundles/inject-migration.cjs +3 -3
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-DEjd_J_s.cjs → migrate_ts_type_references-BRFh6uWT.cjs} +5 -5
- package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +6 -6
- package/schematics/bundles/{project_paths-B-mniue6.cjs → project_paths-zgvnBQD8.cjs} +3 -3
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +1 -1
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/route-lazy-loading.cjs +3 -3
- package/schematics/bundles/self-closing-tags-migration.cjs +4 -4
- package/schematics/bundles/signal-input-migration.cjs +7 -7
- package/schematics/bundles/signal-queries-migration.cjs +7 -7
- package/schematics/bundles/signals.cjs +7 -7
- package/schematics/bundles/standalone-migration.cjs +4 -4
- package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
- package/schematics/bundles/test-bed-get.cjs +4 -4
- package/signal.d.d.ts +1 -1
- package/testing/index.d.ts +1 -1
- package/weak_ref.d.d.ts +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.1
|
|
3
|
+
* @license Angular v20.2.0-next.1
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -31494,7 +31494,7 @@ function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMap
|
|
|
31494
31494
|
declarations.push(...decl.directives.map((dir) => convertDirectiveDeclarationToMetadata(dir)));
|
|
31495
31495
|
decl.pipes && declarations.push(...convertPipeMapToMetadata(decl.pipes));
|
|
31496
31496
|
}
|
|
31497
|
-
const hasDirectiveDependencies = declarations.
|
|
31497
|
+
const hasDirectiveDependencies = declarations.every(({ kind }) => kind === exports.R3TemplateDependencyKind.Directive || kind === exports.R3TemplateDependencyKind.NgModule);
|
|
31498
31498
|
return {
|
|
31499
31499
|
...convertDeclareDirectiveFacadeToMetadata(decl, typeSourceSpan),
|
|
31500
31500
|
template,
|
|
@@ -32271,7 +32271,7 @@ function isAttrNode(ast) {
|
|
|
32271
32271
|
* @description
|
|
32272
32272
|
* Entry point for all public APIs of the compiler package.
|
|
32273
32273
|
*/
|
|
32274
|
-
new Version('20.1
|
|
32274
|
+
new Version('20.2.0-next.1');
|
|
32275
32275
|
|
|
32276
32276
|
//////////////////////////////////////
|
|
32277
32277
|
// THIS FILE HAS GLOBAL SIDE EFFECT //
|
|
@@ -33291,7 +33291,7 @@ class NodeJSPathManipulation {
|
|
|
33291
33291
|
// G3-ESM-MARKER: G3 uses CommonJS, but externally everything in ESM.
|
|
33292
33292
|
// CommonJS/ESM interop for determining the current file name and containing dir.
|
|
33293
33293
|
const isCommonJS = typeof __filename !== 'undefined';
|
|
33294
|
-
const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('checker-
|
|
33294
|
+
const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('checker-BVY3FNBy.cjs', document.baseURI).href));
|
|
33295
33295
|
// Note, when this code loads in the browser, `url` may be an empty `{}` due to the Closure shims.
|
|
33296
33296
|
const currentFileName = isCommonJS
|
|
33297
33297
|
? __filename
|
|
@@ -36711,75 +36711,83 @@ exports.PerfPhase = void 0;
|
|
|
36711
36711
|
* Time spent computing template type-checking diagnostics.
|
|
36712
36712
|
*/
|
|
36713
36713
|
PerfPhase[PerfPhase["TtcDiagnostics"] = 14] = "TtcDiagnostics";
|
|
36714
|
+
/**
|
|
36715
|
+
* Time spent computing template type-checking suggestion diagnostics.
|
|
36716
|
+
*/
|
|
36717
|
+
PerfPhase[PerfPhase["TtcSuggestionDiagnostics"] = 15] = "TtcSuggestionDiagnostics";
|
|
36714
36718
|
/**
|
|
36715
36719
|
* Time spent getting a `Symbol` from the `TemplateTypeChecker`.
|
|
36716
36720
|
*/
|
|
36717
|
-
PerfPhase[PerfPhase["TtcSymbol"] =
|
|
36721
|
+
PerfPhase[PerfPhase["TtcSymbol"] = 16] = "TtcSymbol";
|
|
36718
36722
|
/**
|
|
36719
36723
|
* Time spent by the Angular Language Service calculating a "get references" or a renaming
|
|
36720
36724
|
* operation.
|
|
36721
36725
|
*/
|
|
36722
|
-
PerfPhase[PerfPhase["LsReferencesAndRenames"] =
|
|
36726
|
+
PerfPhase[PerfPhase["LsReferencesAndRenames"] = 17] = "LsReferencesAndRenames";
|
|
36723
36727
|
/**
|
|
36724
36728
|
* Time spent by the Angular Language Service calculating a "quick info" operation.
|
|
36725
36729
|
*/
|
|
36726
|
-
PerfPhase[PerfPhase["LsQuickInfo"] =
|
|
36730
|
+
PerfPhase[PerfPhase["LsQuickInfo"] = 18] = "LsQuickInfo";
|
|
36727
36731
|
/**
|
|
36728
36732
|
* Time spent by the Angular Language Service calculating a "get type definition" or "get
|
|
36729
36733
|
* definition" operation.
|
|
36730
36734
|
*/
|
|
36731
|
-
PerfPhase[PerfPhase["LsDefinition"] =
|
|
36735
|
+
PerfPhase[PerfPhase["LsDefinition"] = 19] = "LsDefinition";
|
|
36732
36736
|
/**
|
|
36733
36737
|
* Time spent by the Angular Language Service calculating a "get completions" (AKA autocomplete)
|
|
36734
36738
|
* operation.
|
|
36735
36739
|
*/
|
|
36736
|
-
PerfPhase[PerfPhase["LsCompletions"] =
|
|
36740
|
+
PerfPhase[PerfPhase["LsCompletions"] = 20] = "LsCompletions";
|
|
36737
36741
|
/**
|
|
36738
36742
|
* Time spent by the Angular Language Service calculating a "view template typecheck block"
|
|
36739
36743
|
* operation.
|
|
36740
36744
|
*/
|
|
36741
|
-
PerfPhase[PerfPhase["LsTcb"] =
|
|
36745
|
+
PerfPhase[PerfPhase["LsTcb"] = 21] = "LsTcb";
|
|
36742
36746
|
/**
|
|
36743
36747
|
* Time spent by the Angular Language Service calculating diagnostics.
|
|
36744
36748
|
*/
|
|
36745
|
-
PerfPhase[PerfPhase["LsDiagnostics"] =
|
|
36749
|
+
PerfPhase[PerfPhase["LsDiagnostics"] = 22] = "LsDiagnostics";
|
|
36750
|
+
/**
|
|
36751
|
+
* Time spent by the Angular Language Service calculating suggestion diagnostics.
|
|
36752
|
+
*/
|
|
36753
|
+
PerfPhase[PerfPhase["LsSuggestionDiagnostics"] = 23] = "LsSuggestionDiagnostics";
|
|
36746
36754
|
/**
|
|
36747
36755
|
* Time spent by the Angular Language Service calculating a "get component locations for template"
|
|
36748
36756
|
* operation.
|
|
36749
36757
|
*/
|
|
36750
|
-
PerfPhase[PerfPhase["LsComponentLocations"] =
|
|
36758
|
+
PerfPhase[PerfPhase["LsComponentLocations"] = 24] = "LsComponentLocations";
|
|
36751
36759
|
/**
|
|
36752
36760
|
* Time spent by the Angular Language Service calculating signature help.
|
|
36753
36761
|
*/
|
|
36754
|
-
PerfPhase[PerfPhase["LsSignatureHelp"] =
|
|
36762
|
+
PerfPhase[PerfPhase["LsSignatureHelp"] = 25] = "LsSignatureHelp";
|
|
36755
36763
|
/**
|
|
36756
36764
|
* Time spent by the Angular Language Service calculating outlining spans.
|
|
36757
36765
|
*/
|
|
36758
|
-
PerfPhase[PerfPhase["OutliningSpans"] =
|
|
36766
|
+
PerfPhase[PerfPhase["OutliningSpans"] = 26] = "OutliningSpans";
|
|
36759
36767
|
/**
|
|
36760
36768
|
* Time spent by the Angular Language Service calculating code fixes.
|
|
36761
36769
|
*/
|
|
36762
|
-
PerfPhase[PerfPhase["LsCodeFixes"] =
|
|
36770
|
+
PerfPhase[PerfPhase["LsCodeFixes"] = 27] = "LsCodeFixes";
|
|
36763
36771
|
/**
|
|
36764
36772
|
* Time spent by the Angular Language Service to fix all detected same type errors.
|
|
36765
36773
|
*/
|
|
36766
|
-
PerfPhase[PerfPhase["LsCodeFixesAll"] =
|
|
36774
|
+
PerfPhase[PerfPhase["LsCodeFixesAll"] = 28] = "LsCodeFixesAll";
|
|
36767
36775
|
/**
|
|
36768
36776
|
* Time spent computing possible Angular refactorings.
|
|
36769
36777
|
*/
|
|
36770
|
-
PerfPhase[PerfPhase["LSComputeApplicableRefactorings"] =
|
|
36778
|
+
PerfPhase[PerfPhase["LSComputeApplicableRefactorings"] = 29] = "LSComputeApplicableRefactorings";
|
|
36771
36779
|
/**
|
|
36772
36780
|
* Time spent computing changes for applying a given refactoring.
|
|
36773
36781
|
*/
|
|
36774
|
-
PerfPhase[PerfPhase["LSApplyRefactoring"] =
|
|
36782
|
+
PerfPhase[PerfPhase["LSApplyRefactoring"] = 30] = "LSApplyRefactoring";
|
|
36775
36783
|
/**
|
|
36776
36784
|
* Time spent by the Angular Language Service calculating semantic classifications.
|
|
36777
36785
|
*/
|
|
36778
|
-
PerfPhase[PerfPhase["LSSemanticClassification"] =
|
|
36786
|
+
PerfPhase[PerfPhase["LSSemanticClassification"] = 31] = "LSSemanticClassification";
|
|
36779
36787
|
/**
|
|
36780
36788
|
* Tracks the number of `PerfPhase`s, and must appear at the end of the list.
|
|
36781
36789
|
*/
|
|
36782
|
-
PerfPhase[PerfPhase["LAST"] =
|
|
36790
|
+
PerfPhase[PerfPhase["LAST"] = 32] = "LAST";
|
|
36783
36791
|
})(exports.PerfPhase || (exports.PerfPhase = {}));
|
|
36784
36792
|
/**
|
|
36785
36793
|
* Represents some occurrence during compilation, and is tracked with a counter.
|
|
@@ -40318,6 +40326,314 @@ function extractHostBindingResources(nodes) {
|
|
|
40318
40326
|
return result;
|
|
40319
40327
|
}
|
|
40320
40328
|
|
|
40329
|
+
const parseSpanComment = /^(\d+),(\d+)$/;
|
|
40330
|
+
/**
|
|
40331
|
+
* Reads the trailing comments and finds the first match which is a span comment (i.e. 4,10) on a
|
|
40332
|
+
* node and returns it as an `AbsoluteSourceSpan`.
|
|
40333
|
+
*
|
|
40334
|
+
* Will return `null` if no trailing comments on the node match the expected form of a source span.
|
|
40335
|
+
*/
|
|
40336
|
+
function readSpanComment(node, sourceFile = node.getSourceFile()) {
|
|
40337
|
+
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40338
|
+
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40339
|
+
return null;
|
|
40340
|
+
}
|
|
40341
|
+
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40342
|
+
const match = commentText.match(parseSpanComment);
|
|
40343
|
+
if (match === null) {
|
|
40344
|
+
return null;
|
|
40345
|
+
}
|
|
40346
|
+
return new AbsoluteSourceSpan(+match[1], +match[2]);
|
|
40347
|
+
}) || null);
|
|
40348
|
+
}
|
|
40349
|
+
/** Used to identify what type the comment is. */
|
|
40350
|
+
var CommentTriviaType;
|
|
40351
|
+
(function (CommentTriviaType) {
|
|
40352
|
+
CommentTriviaType["DIAGNOSTIC"] = "D";
|
|
40353
|
+
CommentTriviaType["EXPRESSION_TYPE_IDENTIFIER"] = "T";
|
|
40354
|
+
})(CommentTriviaType || (CommentTriviaType = {}));
|
|
40355
|
+
/** Identifies what the TCB expression is for (for example, a directive declaration). */
|
|
40356
|
+
var ExpressionIdentifier;
|
|
40357
|
+
(function (ExpressionIdentifier) {
|
|
40358
|
+
ExpressionIdentifier["DIRECTIVE"] = "DIR";
|
|
40359
|
+
ExpressionIdentifier["COMPONENT_COMPLETION"] = "COMPCOMP";
|
|
40360
|
+
ExpressionIdentifier["EVENT_PARAMETER"] = "EP";
|
|
40361
|
+
ExpressionIdentifier["VARIABLE_AS_EXPRESSION"] = "VAE";
|
|
40362
|
+
})(ExpressionIdentifier || (ExpressionIdentifier = {}));
|
|
40363
|
+
/** Tags the node with the given expression identifier. */
|
|
40364
|
+
function addExpressionIdentifier(node, identifier) {
|
|
40365
|
+
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`,
|
|
40366
|
+
/* hasTrailingNewLine */ false);
|
|
40367
|
+
}
|
|
40368
|
+
const IGNORE_FOR_DIAGNOSTICS_MARKER = `${CommentTriviaType.DIAGNOSTIC}:ignore`;
|
|
40369
|
+
/**
|
|
40370
|
+
* Tag the `ts.Node` with an indication that any errors arising from the evaluation of the node
|
|
40371
|
+
* should be ignored.
|
|
40372
|
+
*/
|
|
40373
|
+
function markIgnoreDiagnostics(node) {
|
|
40374
|
+
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, IGNORE_FOR_DIAGNOSTICS_MARKER,
|
|
40375
|
+
/* hasTrailingNewLine */ false);
|
|
40376
|
+
}
|
|
40377
|
+
/** Returns true if the node has a marker that indicates diagnostics errors should be ignored. */
|
|
40378
|
+
function hasIgnoreForDiagnosticsMarker(node, sourceFile) {
|
|
40379
|
+
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40380
|
+
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40381
|
+
return null;
|
|
40382
|
+
}
|
|
40383
|
+
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40384
|
+
return commentText === IGNORE_FOR_DIAGNOSTICS_MARKER;
|
|
40385
|
+
}) === true);
|
|
40386
|
+
}
|
|
40387
|
+
function makeRecursiveVisitor(visitor) {
|
|
40388
|
+
function recursiveVisitor(node) {
|
|
40389
|
+
const res = visitor(node);
|
|
40390
|
+
return res !== null ? res : node.forEachChild(recursiveVisitor);
|
|
40391
|
+
}
|
|
40392
|
+
return recursiveVisitor;
|
|
40393
|
+
}
|
|
40394
|
+
function getSpanFromOptions(opts) {
|
|
40395
|
+
let withSpan = null;
|
|
40396
|
+
if (opts.withSpan !== undefined) {
|
|
40397
|
+
if (opts.withSpan instanceof AbsoluteSourceSpan) {
|
|
40398
|
+
withSpan = opts.withSpan;
|
|
40399
|
+
}
|
|
40400
|
+
else {
|
|
40401
|
+
withSpan = { start: opts.withSpan.start.offset, end: opts.withSpan.end.offset };
|
|
40402
|
+
}
|
|
40403
|
+
}
|
|
40404
|
+
return withSpan;
|
|
40405
|
+
}
|
|
40406
|
+
/**
|
|
40407
|
+
* Given a `ts.Node` with finds the first node whose matching the criteria specified
|
|
40408
|
+
* by the `FindOptions`.
|
|
40409
|
+
*
|
|
40410
|
+
* Returns `null` when no `ts.Node` matches the given conditions.
|
|
40411
|
+
*/
|
|
40412
|
+
function findFirstMatchingNode(tcb, opts) {
|
|
40413
|
+
const withSpan = getSpanFromOptions(opts);
|
|
40414
|
+
const withExpressionIdentifier = opts.withExpressionIdentifier;
|
|
40415
|
+
const sf = tcb.getSourceFile();
|
|
40416
|
+
const visitor = makeRecursiveVisitor((node) => {
|
|
40417
|
+
if (!opts.filter(node)) {
|
|
40418
|
+
return null;
|
|
40419
|
+
}
|
|
40420
|
+
if (withSpan !== null) {
|
|
40421
|
+
const comment = readSpanComment(node, sf);
|
|
40422
|
+
if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
|
40423
|
+
return null;
|
|
40424
|
+
}
|
|
40425
|
+
}
|
|
40426
|
+
if (withExpressionIdentifier !== undefined &&
|
|
40427
|
+
!hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
|
40428
|
+
return null;
|
|
40429
|
+
}
|
|
40430
|
+
return node;
|
|
40431
|
+
});
|
|
40432
|
+
return tcb.forEachChild(visitor) ?? null;
|
|
40433
|
+
}
|
|
40434
|
+
/**
|
|
40435
|
+
* Given a `ts.Node` with source span comments, finds the first node whose source span comment
|
|
40436
|
+
* matches the given `sourceSpan`. Additionally, the `filter` function allows matching only
|
|
40437
|
+
* `ts.Nodes` of a given type, which provides the ability to select only matches of a given type
|
|
40438
|
+
* when there may be more than one.
|
|
40439
|
+
*
|
|
40440
|
+
* Returns `null` when no `ts.Node` matches the given conditions.
|
|
40441
|
+
*/
|
|
40442
|
+
function findAllMatchingNodes(tcb, opts) {
|
|
40443
|
+
const withSpan = getSpanFromOptions(opts);
|
|
40444
|
+
const withExpressionIdentifier = opts.withExpressionIdentifier;
|
|
40445
|
+
const results = [];
|
|
40446
|
+
const stack = [tcb];
|
|
40447
|
+
const sf = tcb.getSourceFile();
|
|
40448
|
+
while (stack.length > 0) {
|
|
40449
|
+
const node = stack.pop();
|
|
40450
|
+
if (!opts.filter(node)) {
|
|
40451
|
+
stack.push(...node.getChildren());
|
|
40452
|
+
continue;
|
|
40453
|
+
}
|
|
40454
|
+
if (withSpan !== null) {
|
|
40455
|
+
const comment = readSpanComment(node, sf);
|
|
40456
|
+
if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
|
40457
|
+
stack.push(...node.getChildren());
|
|
40458
|
+
continue;
|
|
40459
|
+
}
|
|
40460
|
+
}
|
|
40461
|
+
if (withExpressionIdentifier !== undefined &&
|
|
40462
|
+
!hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
|
40463
|
+
continue;
|
|
40464
|
+
}
|
|
40465
|
+
results.push(node);
|
|
40466
|
+
}
|
|
40467
|
+
return results;
|
|
40468
|
+
}
|
|
40469
|
+
function hasExpressionIdentifier(sourceFile, node, identifier) {
|
|
40470
|
+
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40471
|
+
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40472
|
+
return false;
|
|
40473
|
+
}
|
|
40474
|
+
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40475
|
+
return commentText === `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`;
|
|
40476
|
+
}) || false);
|
|
40477
|
+
}
|
|
40478
|
+
|
|
40479
|
+
/**
|
|
40480
|
+
* A `Set` of `ts.SyntaxKind`s of `ts.Expression` which are safe to wrap in a `ts.AsExpression`
|
|
40481
|
+
* without needing to be wrapped in parentheses.
|
|
40482
|
+
*
|
|
40483
|
+
* For example, `foo.bar()` is a `ts.CallExpression`, and can be safely cast to `any` with
|
|
40484
|
+
* `foo.bar() as any`. however, `foo !== bar` is a `ts.BinaryExpression`, and attempting to cast
|
|
40485
|
+
* without the parentheses yields the expression `foo !== bar as any`. This is semantically
|
|
40486
|
+
* equivalent to `foo !== (bar as any)`, which is not what was intended. Thus,
|
|
40487
|
+
* `ts.BinaryExpression`s need to be wrapped in parentheses before casting.
|
|
40488
|
+
*/
|
|
40489
|
+
//
|
|
40490
|
+
let SAFE_TO_CAST_WITHOUT_PARENS = null;
|
|
40491
|
+
function tsCastToAny(expr) {
|
|
40492
|
+
if (SAFE_TO_CAST_WITHOUT_PARENS === null) {
|
|
40493
|
+
SAFE_TO_CAST_WITHOUT_PARENS = new Set([
|
|
40494
|
+
// Expressions which are already parenthesized can be cast without further wrapping.
|
|
40495
|
+
ts.SyntaxKind.ParenthesizedExpression,
|
|
40496
|
+
// Expressions which form a single lexical unit leave no room for precedence issues with the cast.
|
|
40497
|
+
ts.SyntaxKind.Identifier,
|
|
40498
|
+
ts.SyntaxKind.CallExpression,
|
|
40499
|
+
ts.SyntaxKind.NonNullExpression,
|
|
40500
|
+
ts.SyntaxKind.ElementAccessExpression,
|
|
40501
|
+
ts.SyntaxKind.PropertyAccessExpression,
|
|
40502
|
+
ts.SyntaxKind.ArrayLiteralExpression,
|
|
40503
|
+
ts.SyntaxKind.ObjectLiteralExpression,
|
|
40504
|
+
// The same goes for various literals.
|
|
40505
|
+
ts.SyntaxKind.StringLiteral,
|
|
40506
|
+
ts.SyntaxKind.NumericLiteral,
|
|
40507
|
+
ts.SyntaxKind.TrueKeyword,
|
|
40508
|
+
ts.SyntaxKind.FalseKeyword,
|
|
40509
|
+
ts.SyntaxKind.NullKeyword,
|
|
40510
|
+
ts.SyntaxKind.UndefinedKeyword,
|
|
40511
|
+
]);
|
|
40512
|
+
}
|
|
40513
|
+
// Wrap `expr` in parentheses if needed (see `SAFE_TO_CAST_WITHOUT_PARENS` above).
|
|
40514
|
+
if (!SAFE_TO_CAST_WITHOUT_PARENS.has(expr.kind)) {
|
|
40515
|
+
expr = ts.factory.createParenthesizedExpression(expr);
|
|
40516
|
+
}
|
|
40517
|
+
// The outer expression is always wrapped in parentheses.
|
|
40518
|
+
return ts.factory.createParenthesizedExpression(ts.factory.createAsExpression(expr, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)));
|
|
40519
|
+
}
|
|
40520
|
+
/**
|
|
40521
|
+
* Create an expression which instantiates an element by its HTML tagName.
|
|
40522
|
+
*
|
|
40523
|
+
* Thanks to narrowing of `document.createElement()`, this expression will have its type inferred
|
|
40524
|
+
* based on the tag name, including for custom elements that have appropriate .d.ts definitions.
|
|
40525
|
+
*/
|
|
40526
|
+
function tsCreateElement(...tagNames) {
|
|
40527
|
+
const createElement = ts.factory.createPropertyAccessExpression(
|
|
40528
|
+
/* expression */ ts.factory.createIdentifier('document'), 'createElement');
|
|
40529
|
+
let arg;
|
|
40530
|
+
if (tagNames.length === 1) {
|
|
40531
|
+
// If there's only one tag name, we can pass it in directly.
|
|
40532
|
+
arg = ts.factory.createStringLiteral(tagNames[0]);
|
|
40533
|
+
}
|
|
40534
|
+
else {
|
|
40535
|
+
// If there's more than one name, we have to generate a union of all the tag names. To do so,
|
|
40536
|
+
// create an expression in the form of `null! as 'tag-1' | 'tag-2' | 'tag-3'`. This allows
|
|
40537
|
+
// TypeScript to infer the type as a union of the differnet tags.
|
|
40538
|
+
const assertedNullExpression = ts.factory.createNonNullExpression(ts.factory.createNull());
|
|
40539
|
+
const type = ts.factory.createUnionTypeNode(tagNames.map((tag) => ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(tag))));
|
|
40540
|
+
arg = ts.factory.createAsExpression(assertedNullExpression, type);
|
|
40541
|
+
}
|
|
40542
|
+
return ts.factory.createCallExpression(
|
|
40543
|
+
/* expression */ createElement,
|
|
40544
|
+
/* typeArguments */ undefined,
|
|
40545
|
+
/* argumentsArray */ [arg]);
|
|
40546
|
+
}
|
|
40547
|
+
/**
|
|
40548
|
+
* Create a `ts.VariableStatement` which declares a variable without explicit initialization.
|
|
40549
|
+
*
|
|
40550
|
+
* The initializer `null!` is used to bypass strict variable initialization checks.
|
|
40551
|
+
*
|
|
40552
|
+
* Unlike with `tsCreateVariable`, the type of the variable is explicitly specified.
|
|
40553
|
+
*/
|
|
40554
|
+
function tsDeclareVariable(id, type) {
|
|
40555
|
+
// When we create a variable like `var _t1: boolean = null!`, TypeScript actually infers `_t1`
|
|
40556
|
+
// to be `never`, instead of a `boolean`. To work around it, we cast the value
|
|
40557
|
+
// in the initializer, e.g. `var _t1 = null! as boolean;`.
|
|
40558
|
+
addExpressionIdentifier(type, ExpressionIdentifier.VARIABLE_AS_EXPRESSION);
|
|
40559
|
+
const initializer = ts.factory.createAsExpression(ts.factory.createNonNullExpression(ts.factory.createNull()), type);
|
|
40560
|
+
const decl = ts.factory.createVariableDeclaration(
|
|
40561
|
+
/* name */ id,
|
|
40562
|
+
/* exclamationToken */ undefined,
|
|
40563
|
+
/* type */ undefined,
|
|
40564
|
+
/* initializer */ initializer);
|
|
40565
|
+
return ts.factory.createVariableStatement(
|
|
40566
|
+
/* modifiers */ undefined,
|
|
40567
|
+
/* declarationList */ [decl]);
|
|
40568
|
+
}
|
|
40569
|
+
/**
|
|
40570
|
+
* Creates a `ts.TypeQueryNode` for a coerced input.
|
|
40571
|
+
*
|
|
40572
|
+
* For example: `typeof MatInput.ngAcceptInputType_value`, where MatInput is `typeName` and `value`
|
|
40573
|
+
* is the `coercedInputName`.
|
|
40574
|
+
*
|
|
40575
|
+
* @param typeName The `EntityName` of the Directive where the static coerced input is defined.
|
|
40576
|
+
* @param coercedInputName The field name of the coerced input.
|
|
40577
|
+
*/
|
|
40578
|
+
function tsCreateTypeQueryForCoercedInput(typeName, coercedInputName) {
|
|
40579
|
+
return ts.factory.createTypeQueryNode(ts.factory.createQualifiedName(typeName, `ngAcceptInputType_${coercedInputName}`));
|
|
40580
|
+
}
|
|
40581
|
+
/**
|
|
40582
|
+
* Create a `ts.VariableStatement` that initializes a variable with a given expression.
|
|
40583
|
+
*
|
|
40584
|
+
* Unlike with `tsDeclareVariable`, the type of the variable is inferred from the initializer
|
|
40585
|
+
* expression.
|
|
40586
|
+
*/
|
|
40587
|
+
function tsCreateVariable(id, initializer, flags = null) {
|
|
40588
|
+
const decl = ts.factory.createVariableDeclaration(
|
|
40589
|
+
/* name */ id,
|
|
40590
|
+
/* exclamationToken */ undefined,
|
|
40591
|
+
/* type */ undefined,
|
|
40592
|
+
/* initializer */ initializer);
|
|
40593
|
+
return ts.factory.createVariableStatement(
|
|
40594
|
+
/* modifiers */ undefined,
|
|
40595
|
+
/* declarationList */ flags === null
|
|
40596
|
+
? [decl]
|
|
40597
|
+
: ts.factory.createVariableDeclarationList([decl], flags));
|
|
40598
|
+
}
|
|
40599
|
+
/**
|
|
40600
|
+
* Construct a `ts.CallExpression` that calls a method on a receiver.
|
|
40601
|
+
*/
|
|
40602
|
+
function tsCallMethod(receiver, methodName, args = []) {
|
|
40603
|
+
const methodAccess = ts.factory.createPropertyAccessExpression(receiver, methodName);
|
|
40604
|
+
return ts.factory.createCallExpression(
|
|
40605
|
+
/* expression */ methodAccess,
|
|
40606
|
+
/* typeArguments */ undefined,
|
|
40607
|
+
/* argumentsArray */ args);
|
|
40608
|
+
}
|
|
40609
|
+
function isAccessExpression(node) {
|
|
40610
|
+
return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node);
|
|
40611
|
+
}
|
|
40612
|
+
/**
|
|
40613
|
+
* Creates a TypeScript node representing a numeric value.
|
|
40614
|
+
*/
|
|
40615
|
+
function tsNumericExpression(value) {
|
|
40616
|
+
// As of TypeScript 5.3 negative numbers are represented as `prefixUnaryOperator` and passing a
|
|
40617
|
+
// negative number (even as a string) into `createNumericLiteral` will result in an error.
|
|
40618
|
+
if (value < 0) {
|
|
40619
|
+
const operand = ts.factory.createNumericLiteral(Math.abs(value));
|
|
40620
|
+
return ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, operand);
|
|
40621
|
+
}
|
|
40622
|
+
return ts.factory.createNumericLiteral(value);
|
|
40623
|
+
}
|
|
40624
|
+
/**
|
|
40625
|
+
* Check if a node represents a directive declaration in a TypeCheck Block.
|
|
40626
|
+
* Directive declarations can be either:
|
|
40627
|
+
* - var _t1: TestDir /*T:D*\/ = null! as TestDir;
|
|
40628
|
+
* - var _t1 /*T:D*\/ = _ctor1({});
|
|
40629
|
+
*/
|
|
40630
|
+
function isDirectiveDeclaration(node) {
|
|
40631
|
+
const sourceFile = node.getSourceFile();
|
|
40632
|
+
return ((ts.isTypeNode(node) || ts.isIdentifier(node)) &&
|
|
40633
|
+
ts.isVariableDeclaration(node.parent) &&
|
|
40634
|
+
hasExpressionIdentifier(sourceFile, node, ExpressionIdentifier.DIRECTIVE));
|
|
40635
|
+
}
|
|
40636
|
+
|
|
40321
40637
|
const NgOriginalFile = Symbol('NgOriginalFile');
|
|
40322
40638
|
exports.UpdateMode = void 0;
|
|
40323
40639
|
(function (UpdateMode) {
|
|
@@ -40506,12 +40822,13 @@ exports.SymbolKind = void 0;
|
|
|
40506
40822
|
|
|
40507
40823
|
/**
|
|
40508
40824
|
* Constructs a `ts.Diagnostic` for a given `ParseSourceSpan` within a template.
|
|
40825
|
+
*
|
|
40826
|
+
* @param deprecatedDiagInfo Optional information about deprecation and related messages.
|
|
40509
40827
|
*/
|
|
40510
|
-
function makeTemplateDiagnostic(id, mapping, span, category, code, messageText, relatedMessages) {
|
|
40828
|
+
function makeTemplateDiagnostic(id, mapping, span, category, code, messageText, relatedMessages, deprecatedDiagInfo) {
|
|
40511
40829
|
if (mapping.type === 'direct') {
|
|
40512
|
-
let relatedInformation =
|
|
40830
|
+
let relatedInformation = [];
|
|
40513
40831
|
if (relatedMessages !== undefined) {
|
|
40514
|
-
relatedInformation = [];
|
|
40515
40832
|
for (const relatedMessage of relatedMessages) {
|
|
40516
40833
|
relatedInformation.push({
|
|
40517
40834
|
category: ts.DiagnosticCategory.Message,
|
|
@@ -40523,6 +40840,9 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40523
40840
|
});
|
|
40524
40841
|
}
|
|
40525
40842
|
}
|
|
40843
|
+
if (deprecatedDiagInfo !== undefined) {
|
|
40844
|
+
relatedInformation.push(...(deprecatedDiagInfo.relatedMessages ?? []));
|
|
40845
|
+
}
|
|
40526
40846
|
// For direct mappings, the error is shown inline as ngtsc was able to pinpoint a string
|
|
40527
40847
|
// constant within the `@Component` decorator for the template. This allows us to map the error
|
|
40528
40848
|
// directly into the bytes of the source file.
|
|
@@ -40537,6 +40857,7 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40537
40857
|
start: span.start.offset,
|
|
40538
40858
|
length: span.end.offset - span.start.offset,
|
|
40539
40859
|
relatedInformation,
|
|
40860
|
+
reportsDeprecated: deprecatedDiagInfo?.reportsDeprecated,
|
|
40540
40861
|
};
|
|
40541
40862
|
}
|
|
40542
40863
|
else if (mapping.type === 'indirect' || mapping.type === 'external') {
|
|
@@ -40581,6 +40902,7 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40581
40902
|
start: mapping.node.getStart(),
|
|
40582
40903
|
length: mapping.node.getEnd() - mapping.node.getStart(),
|
|
40583
40904
|
relatedInformation,
|
|
40905
|
+
reportsDeprecated: deprecatedDiagInfo?.reportsDeprecated,
|
|
40584
40906
|
};
|
|
40585
40907
|
}
|
|
40586
40908
|
let typeForMessage;
|
|
@@ -40596,6 +40918,9 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40596
40918
|
else {
|
|
40597
40919
|
typeForMessage = 'Error';
|
|
40598
40920
|
}
|
|
40921
|
+
if (deprecatedDiagInfo !== undefined) {
|
|
40922
|
+
relatedInformation.push(...(deprecatedDiagInfo.relatedMessages ?? []));
|
|
40923
|
+
}
|
|
40599
40924
|
relatedInformation.push({
|
|
40600
40925
|
category: ts.DiagnosticCategory.Message,
|
|
40601
40926
|
code: 0,
|
|
@@ -40618,6 +40943,7 @@ function makeTemplateDiagnostic(id, mapping, span, category, code, messageText,
|
|
|
40618
40943
|
length: span.end.offset - span.start.offset,
|
|
40619
40944
|
// Show a secondary message indicating the component whose template contains the error.
|
|
40620
40945
|
relatedInformation,
|
|
40946
|
+
reportsDeprecated: deprecatedDiagInfo?.reportsDeprecated,
|
|
40621
40947
|
};
|
|
40622
40948
|
}
|
|
40623
40949
|
else {
|
|
@@ -40650,156 +40976,6 @@ function getTypeCheckId$1(clazz) {
|
|
|
40650
40976
|
return sf[TYPE_CHECK_ID_MAP].get(clazz);
|
|
40651
40977
|
}
|
|
40652
40978
|
|
|
40653
|
-
const parseSpanComment = /^(\d+),(\d+)$/;
|
|
40654
|
-
/**
|
|
40655
|
-
* Reads the trailing comments and finds the first match which is a span comment (i.e. 4,10) on a
|
|
40656
|
-
* node and returns it as an `AbsoluteSourceSpan`.
|
|
40657
|
-
*
|
|
40658
|
-
* Will return `null` if no trailing comments on the node match the expected form of a source span.
|
|
40659
|
-
*/
|
|
40660
|
-
function readSpanComment(node, sourceFile = node.getSourceFile()) {
|
|
40661
|
-
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40662
|
-
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40663
|
-
return null;
|
|
40664
|
-
}
|
|
40665
|
-
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40666
|
-
const match = commentText.match(parseSpanComment);
|
|
40667
|
-
if (match === null) {
|
|
40668
|
-
return null;
|
|
40669
|
-
}
|
|
40670
|
-
return new AbsoluteSourceSpan(+match[1], +match[2]);
|
|
40671
|
-
}) || null);
|
|
40672
|
-
}
|
|
40673
|
-
/** Used to identify what type the comment is. */
|
|
40674
|
-
var CommentTriviaType;
|
|
40675
|
-
(function (CommentTriviaType) {
|
|
40676
|
-
CommentTriviaType["DIAGNOSTIC"] = "D";
|
|
40677
|
-
CommentTriviaType["EXPRESSION_TYPE_IDENTIFIER"] = "T";
|
|
40678
|
-
})(CommentTriviaType || (CommentTriviaType = {}));
|
|
40679
|
-
/** Identifies what the TCB expression is for (for example, a directive declaration). */
|
|
40680
|
-
var ExpressionIdentifier;
|
|
40681
|
-
(function (ExpressionIdentifier) {
|
|
40682
|
-
ExpressionIdentifier["DIRECTIVE"] = "DIR";
|
|
40683
|
-
ExpressionIdentifier["COMPONENT_COMPLETION"] = "COMPCOMP";
|
|
40684
|
-
ExpressionIdentifier["EVENT_PARAMETER"] = "EP";
|
|
40685
|
-
ExpressionIdentifier["VARIABLE_AS_EXPRESSION"] = "VAE";
|
|
40686
|
-
})(ExpressionIdentifier || (ExpressionIdentifier = {}));
|
|
40687
|
-
/** Tags the node with the given expression identifier. */
|
|
40688
|
-
function addExpressionIdentifier(node, identifier) {
|
|
40689
|
-
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`,
|
|
40690
|
-
/* hasTrailingNewLine */ false);
|
|
40691
|
-
}
|
|
40692
|
-
const IGNORE_FOR_DIAGNOSTICS_MARKER = `${CommentTriviaType.DIAGNOSTIC}:ignore`;
|
|
40693
|
-
/**
|
|
40694
|
-
* Tag the `ts.Node` with an indication that any errors arising from the evaluation of the node
|
|
40695
|
-
* should be ignored.
|
|
40696
|
-
*/
|
|
40697
|
-
function markIgnoreDiagnostics(node) {
|
|
40698
|
-
ts.addSyntheticTrailingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, IGNORE_FOR_DIAGNOSTICS_MARKER,
|
|
40699
|
-
/* hasTrailingNewLine */ false);
|
|
40700
|
-
}
|
|
40701
|
-
/** Returns true if the node has a marker that indicates diagnostics errors should be ignored. */
|
|
40702
|
-
function hasIgnoreForDiagnosticsMarker(node, sourceFile) {
|
|
40703
|
-
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40704
|
-
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40705
|
-
return null;
|
|
40706
|
-
}
|
|
40707
|
-
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40708
|
-
return commentText === IGNORE_FOR_DIAGNOSTICS_MARKER;
|
|
40709
|
-
}) === true);
|
|
40710
|
-
}
|
|
40711
|
-
function makeRecursiveVisitor(visitor) {
|
|
40712
|
-
function recursiveVisitor(node) {
|
|
40713
|
-
const res = visitor(node);
|
|
40714
|
-
return res !== null ? res : node.forEachChild(recursiveVisitor);
|
|
40715
|
-
}
|
|
40716
|
-
return recursiveVisitor;
|
|
40717
|
-
}
|
|
40718
|
-
function getSpanFromOptions(opts) {
|
|
40719
|
-
let withSpan = null;
|
|
40720
|
-
if (opts.withSpan !== undefined) {
|
|
40721
|
-
if (opts.withSpan instanceof AbsoluteSourceSpan) {
|
|
40722
|
-
withSpan = opts.withSpan;
|
|
40723
|
-
}
|
|
40724
|
-
else {
|
|
40725
|
-
withSpan = { start: opts.withSpan.start.offset, end: opts.withSpan.end.offset };
|
|
40726
|
-
}
|
|
40727
|
-
}
|
|
40728
|
-
return withSpan;
|
|
40729
|
-
}
|
|
40730
|
-
/**
|
|
40731
|
-
* Given a `ts.Node` with finds the first node whose matching the criteria specified
|
|
40732
|
-
* by the `FindOptions`.
|
|
40733
|
-
*
|
|
40734
|
-
* Returns `null` when no `ts.Node` matches the given conditions.
|
|
40735
|
-
*/
|
|
40736
|
-
function findFirstMatchingNode(tcb, opts) {
|
|
40737
|
-
const withSpan = getSpanFromOptions(opts);
|
|
40738
|
-
const withExpressionIdentifier = opts.withExpressionIdentifier;
|
|
40739
|
-
const sf = tcb.getSourceFile();
|
|
40740
|
-
const visitor = makeRecursiveVisitor((node) => {
|
|
40741
|
-
if (!opts.filter(node)) {
|
|
40742
|
-
return null;
|
|
40743
|
-
}
|
|
40744
|
-
if (withSpan !== null) {
|
|
40745
|
-
const comment = readSpanComment(node, sf);
|
|
40746
|
-
if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
|
40747
|
-
return null;
|
|
40748
|
-
}
|
|
40749
|
-
}
|
|
40750
|
-
if (withExpressionIdentifier !== undefined &&
|
|
40751
|
-
!hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
|
40752
|
-
return null;
|
|
40753
|
-
}
|
|
40754
|
-
return node;
|
|
40755
|
-
});
|
|
40756
|
-
return tcb.forEachChild(visitor) ?? null;
|
|
40757
|
-
}
|
|
40758
|
-
/**
|
|
40759
|
-
* Given a `ts.Node` with source span comments, finds the first node whose source span comment
|
|
40760
|
-
* matches the given `sourceSpan`. Additionally, the `filter` function allows matching only
|
|
40761
|
-
* `ts.Nodes` of a given type, which provides the ability to select only matches of a given type
|
|
40762
|
-
* when there may be more than one.
|
|
40763
|
-
*
|
|
40764
|
-
* Returns `null` when no `ts.Node` matches the given conditions.
|
|
40765
|
-
*/
|
|
40766
|
-
function findAllMatchingNodes(tcb, opts) {
|
|
40767
|
-
const withSpan = getSpanFromOptions(opts);
|
|
40768
|
-
const withExpressionIdentifier = opts.withExpressionIdentifier;
|
|
40769
|
-
const results = [];
|
|
40770
|
-
const stack = [tcb];
|
|
40771
|
-
const sf = tcb.getSourceFile();
|
|
40772
|
-
while (stack.length > 0) {
|
|
40773
|
-
const node = stack.pop();
|
|
40774
|
-
if (!opts.filter(node)) {
|
|
40775
|
-
stack.push(...node.getChildren());
|
|
40776
|
-
continue;
|
|
40777
|
-
}
|
|
40778
|
-
if (withSpan !== null) {
|
|
40779
|
-
const comment = readSpanComment(node, sf);
|
|
40780
|
-
if (comment === null || withSpan.start !== comment.start || withSpan.end !== comment.end) {
|
|
40781
|
-
stack.push(...node.getChildren());
|
|
40782
|
-
continue;
|
|
40783
|
-
}
|
|
40784
|
-
}
|
|
40785
|
-
if (withExpressionIdentifier !== undefined &&
|
|
40786
|
-
!hasExpressionIdentifier(sf, node, withExpressionIdentifier)) {
|
|
40787
|
-
continue;
|
|
40788
|
-
}
|
|
40789
|
-
results.push(node);
|
|
40790
|
-
}
|
|
40791
|
-
return results;
|
|
40792
|
-
}
|
|
40793
|
-
function hasExpressionIdentifier(sourceFile, node, identifier) {
|
|
40794
|
-
return (ts.forEachTrailingCommentRange(sourceFile.text, node.getEnd(), (pos, end, kind) => {
|
|
40795
|
-
if (kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
|
|
40796
|
-
return false;
|
|
40797
|
-
}
|
|
40798
|
-
const commentText = sourceFile.text.substring(pos + 2, end - 2);
|
|
40799
|
-
return commentText === `${CommentTriviaType.EXPRESSION_TYPE_IDENTIFIER}:${identifier}`;
|
|
40800
|
-
}) || false);
|
|
40801
|
-
}
|
|
40802
|
-
|
|
40803
40979
|
/**
|
|
40804
40980
|
* Powers autocompletion for a specific component.
|
|
40805
40981
|
*
|
|
@@ -42516,152 +42692,6 @@ class ReferenceEmitEnvironment {
|
|
|
42516
42692
|
}
|
|
42517
42693
|
}
|
|
42518
42694
|
|
|
42519
|
-
/**
|
|
42520
|
-
* A `Set` of `ts.SyntaxKind`s of `ts.Expression` which are safe to wrap in a `ts.AsExpression`
|
|
42521
|
-
* without needing to be wrapped in parentheses.
|
|
42522
|
-
*
|
|
42523
|
-
* For example, `foo.bar()` is a `ts.CallExpression`, and can be safely cast to `any` with
|
|
42524
|
-
* `foo.bar() as any`. however, `foo !== bar` is a `ts.BinaryExpression`, and attempting to cast
|
|
42525
|
-
* without the parentheses yields the expression `foo !== bar as any`. This is semantically
|
|
42526
|
-
* equivalent to `foo !== (bar as any)`, which is not what was intended. Thus,
|
|
42527
|
-
* `ts.BinaryExpression`s need to be wrapped in parentheses before casting.
|
|
42528
|
-
*/
|
|
42529
|
-
//
|
|
42530
|
-
let SAFE_TO_CAST_WITHOUT_PARENS = null;
|
|
42531
|
-
function tsCastToAny(expr) {
|
|
42532
|
-
if (SAFE_TO_CAST_WITHOUT_PARENS === null) {
|
|
42533
|
-
SAFE_TO_CAST_WITHOUT_PARENS = new Set([
|
|
42534
|
-
// Expressions which are already parenthesized can be cast without further wrapping.
|
|
42535
|
-
ts.SyntaxKind.ParenthesizedExpression,
|
|
42536
|
-
// Expressions which form a single lexical unit leave no room for precedence issues with the cast.
|
|
42537
|
-
ts.SyntaxKind.Identifier,
|
|
42538
|
-
ts.SyntaxKind.CallExpression,
|
|
42539
|
-
ts.SyntaxKind.NonNullExpression,
|
|
42540
|
-
ts.SyntaxKind.ElementAccessExpression,
|
|
42541
|
-
ts.SyntaxKind.PropertyAccessExpression,
|
|
42542
|
-
ts.SyntaxKind.ArrayLiteralExpression,
|
|
42543
|
-
ts.SyntaxKind.ObjectLiteralExpression,
|
|
42544
|
-
// The same goes for various literals.
|
|
42545
|
-
ts.SyntaxKind.StringLiteral,
|
|
42546
|
-
ts.SyntaxKind.NumericLiteral,
|
|
42547
|
-
ts.SyntaxKind.TrueKeyword,
|
|
42548
|
-
ts.SyntaxKind.FalseKeyword,
|
|
42549
|
-
ts.SyntaxKind.NullKeyword,
|
|
42550
|
-
ts.SyntaxKind.UndefinedKeyword,
|
|
42551
|
-
]);
|
|
42552
|
-
}
|
|
42553
|
-
// Wrap `expr` in parentheses if needed (see `SAFE_TO_CAST_WITHOUT_PARENS` above).
|
|
42554
|
-
if (!SAFE_TO_CAST_WITHOUT_PARENS.has(expr.kind)) {
|
|
42555
|
-
expr = ts.factory.createParenthesizedExpression(expr);
|
|
42556
|
-
}
|
|
42557
|
-
// The outer expression is always wrapped in parentheses.
|
|
42558
|
-
return ts.factory.createParenthesizedExpression(ts.factory.createAsExpression(expr, ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword)));
|
|
42559
|
-
}
|
|
42560
|
-
/**
|
|
42561
|
-
* Create an expression which instantiates an element by its HTML tagName.
|
|
42562
|
-
*
|
|
42563
|
-
* Thanks to narrowing of `document.createElement()`, this expression will have its type inferred
|
|
42564
|
-
* based on the tag name, including for custom elements that have appropriate .d.ts definitions.
|
|
42565
|
-
*/
|
|
42566
|
-
function tsCreateElement(...tagNames) {
|
|
42567
|
-
const createElement = ts.factory.createPropertyAccessExpression(
|
|
42568
|
-
/* expression */ ts.factory.createIdentifier('document'), 'createElement');
|
|
42569
|
-
let arg;
|
|
42570
|
-
if (tagNames.length === 1) {
|
|
42571
|
-
// If there's only one tag name, we can pass it in directly.
|
|
42572
|
-
arg = ts.factory.createStringLiteral(tagNames[0]);
|
|
42573
|
-
}
|
|
42574
|
-
else {
|
|
42575
|
-
// If there's more than one name, we have to generate a union of all the tag names. To do so,
|
|
42576
|
-
// create an expression in the form of `null! as 'tag-1' | 'tag-2' | 'tag-3'`. This allows
|
|
42577
|
-
// TypeScript to infer the type as a union of the differnet tags.
|
|
42578
|
-
const assertedNullExpression = ts.factory.createNonNullExpression(ts.factory.createNull());
|
|
42579
|
-
const type = ts.factory.createUnionTypeNode(tagNames.map((tag) => ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(tag))));
|
|
42580
|
-
arg = ts.factory.createAsExpression(assertedNullExpression, type);
|
|
42581
|
-
}
|
|
42582
|
-
return ts.factory.createCallExpression(
|
|
42583
|
-
/* expression */ createElement,
|
|
42584
|
-
/* typeArguments */ undefined,
|
|
42585
|
-
/* argumentsArray */ [arg]);
|
|
42586
|
-
}
|
|
42587
|
-
/**
|
|
42588
|
-
* Create a `ts.VariableStatement` which declares a variable without explicit initialization.
|
|
42589
|
-
*
|
|
42590
|
-
* The initializer `null!` is used to bypass strict variable initialization checks.
|
|
42591
|
-
*
|
|
42592
|
-
* Unlike with `tsCreateVariable`, the type of the variable is explicitly specified.
|
|
42593
|
-
*/
|
|
42594
|
-
function tsDeclareVariable(id, type) {
|
|
42595
|
-
// When we create a variable like `var _t1: boolean = null!`, TypeScript actually infers `_t1`
|
|
42596
|
-
// to be `never`, instead of a `boolean`. To work around it, we cast the value
|
|
42597
|
-
// in the initializer, e.g. `var _t1 = null! as boolean;`.
|
|
42598
|
-
addExpressionIdentifier(type, ExpressionIdentifier.VARIABLE_AS_EXPRESSION);
|
|
42599
|
-
const initializer = ts.factory.createAsExpression(ts.factory.createNonNullExpression(ts.factory.createNull()), type);
|
|
42600
|
-
const decl = ts.factory.createVariableDeclaration(
|
|
42601
|
-
/* name */ id,
|
|
42602
|
-
/* exclamationToken */ undefined,
|
|
42603
|
-
/* type */ undefined,
|
|
42604
|
-
/* initializer */ initializer);
|
|
42605
|
-
return ts.factory.createVariableStatement(
|
|
42606
|
-
/* modifiers */ undefined,
|
|
42607
|
-
/* declarationList */ [decl]);
|
|
42608
|
-
}
|
|
42609
|
-
/**
|
|
42610
|
-
* Creates a `ts.TypeQueryNode` for a coerced input.
|
|
42611
|
-
*
|
|
42612
|
-
* For example: `typeof MatInput.ngAcceptInputType_value`, where MatInput is `typeName` and `value`
|
|
42613
|
-
* is the `coercedInputName`.
|
|
42614
|
-
*
|
|
42615
|
-
* @param typeName The `EntityName` of the Directive where the static coerced input is defined.
|
|
42616
|
-
* @param coercedInputName The field name of the coerced input.
|
|
42617
|
-
*/
|
|
42618
|
-
function tsCreateTypeQueryForCoercedInput(typeName, coercedInputName) {
|
|
42619
|
-
return ts.factory.createTypeQueryNode(ts.factory.createQualifiedName(typeName, `ngAcceptInputType_${coercedInputName}`));
|
|
42620
|
-
}
|
|
42621
|
-
/**
|
|
42622
|
-
* Create a `ts.VariableStatement` that initializes a variable with a given expression.
|
|
42623
|
-
*
|
|
42624
|
-
* Unlike with `tsDeclareVariable`, the type of the variable is inferred from the initializer
|
|
42625
|
-
* expression.
|
|
42626
|
-
*/
|
|
42627
|
-
function tsCreateVariable(id, initializer, flags = null) {
|
|
42628
|
-
const decl = ts.factory.createVariableDeclaration(
|
|
42629
|
-
/* name */ id,
|
|
42630
|
-
/* exclamationToken */ undefined,
|
|
42631
|
-
/* type */ undefined,
|
|
42632
|
-
/* initializer */ initializer);
|
|
42633
|
-
return ts.factory.createVariableStatement(
|
|
42634
|
-
/* modifiers */ undefined,
|
|
42635
|
-
/* declarationList */ flags === null
|
|
42636
|
-
? [decl]
|
|
42637
|
-
: ts.factory.createVariableDeclarationList([decl], flags));
|
|
42638
|
-
}
|
|
42639
|
-
/**
|
|
42640
|
-
* Construct a `ts.CallExpression` that calls a method on a receiver.
|
|
42641
|
-
*/
|
|
42642
|
-
function tsCallMethod(receiver, methodName, args = []) {
|
|
42643
|
-
const methodAccess = ts.factory.createPropertyAccessExpression(receiver, methodName);
|
|
42644
|
-
return ts.factory.createCallExpression(
|
|
42645
|
-
/* expression */ methodAccess,
|
|
42646
|
-
/* typeArguments */ undefined,
|
|
42647
|
-
/* argumentsArray */ args);
|
|
42648
|
-
}
|
|
42649
|
-
function isAccessExpression(node) {
|
|
42650
|
-
return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node);
|
|
42651
|
-
}
|
|
42652
|
-
/**
|
|
42653
|
-
* Creates a TypeScript node representing a numeric value.
|
|
42654
|
-
*/
|
|
42655
|
-
function tsNumericExpression(value) {
|
|
42656
|
-
// As of TypeScript 5.3 negative numbers are represented as `prefixUnaryOperator` and passing a
|
|
42657
|
-
// negative number (even as a string) into `createNumericLiteral` will result in an error.
|
|
42658
|
-
if (value < 0) {
|
|
42659
|
-
const operand = ts.factory.createNumericLiteral(Math.abs(value));
|
|
42660
|
-
return ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, operand);
|
|
42661
|
-
}
|
|
42662
|
-
return ts.factory.createNumericLiteral(value);
|
|
42663
|
-
}
|
|
42664
|
-
|
|
42665
42695
|
/**
|
|
42666
42696
|
* See `TypeEmitter` for more information on the emitting process.
|
|
42667
42697
|
*/
|
|
@@ -44036,7 +44066,12 @@ function translateDiagnostic(diagnostic, resolver) {
|
|
|
44036
44066
|
return null;
|
|
44037
44067
|
}
|
|
44038
44068
|
const { sourceLocation, sourceMapping: templateSourceMapping, span } = fullMapping;
|
|
44039
|
-
return makeTemplateDiagnostic(sourceLocation.id, templateSourceMapping, span, diagnostic.category, diagnostic.code, diagnostic.messageText
|
|
44069
|
+
return makeTemplateDiagnostic(sourceLocation.id, templateSourceMapping, span, diagnostic.category, diagnostic.code, diagnostic.messageText, undefined, diagnostic.reportsDeprecated !== undefined
|
|
44070
|
+
? {
|
|
44071
|
+
reportsDeprecated: diagnostic.reportsDeprecated,
|
|
44072
|
+
relatedMessages: diagnostic.relatedInformation,
|
|
44073
|
+
}
|
|
44074
|
+
: undefined);
|
|
44040
44075
|
}
|
|
44041
44076
|
|
|
44042
44077
|
/**
|
|
@@ -48086,13 +48121,6 @@ class SymbolBuilder {
|
|
|
48086
48121
|
}
|
|
48087
48122
|
getDirectivesOfNode(templateNode) {
|
|
48088
48123
|
const elementSourceSpan = templateNode.startSourceSpan ?? templateNode.sourceSpan;
|
|
48089
|
-
const tcbSourceFile = this.typeCheckBlock.getSourceFile();
|
|
48090
|
-
// directives could be either:
|
|
48091
|
-
// - var _t1: TestDir /*T:D*/ = null! as TestDir;
|
|
48092
|
-
// - var _t1 /*T:D*/ = _ctor1({});
|
|
48093
|
-
const isDirectiveDeclaration = (node) => (ts.isTypeNode(node) || ts.isIdentifier(node)) &&
|
|
48094
|
-
ts.isVariableDeclaration(node.parent) &&
|
|
48095
|
-
hasExpressionIdentifier(tcbSourceFile, node, ExpressionIdentifier.DIRECTIVE);
|
|
48096
48124
|
const nodes = findAllMatchingNodes(this.typeCheckBlock, {
|
|
48097
48125
|
withSpan: elementSourceSpan,
|
|
48098
48126
|
filter: isDirectiveDeclaration,
|
|
@@ -48956,6 +48984,29 @@ class TemplateTypeCheckerImpl {
|
|
|
48956
48984
|
return diagnostics.filter((diag) => diag !== null);
|
|
48957
48985
|
});
|
|
48958
48986
|
}
|
|
48987
|
+
getSuggestionDiagnosticsForFile(sf, tsLs, optimizeFor) {
|
|
48988
|
+
switch (optimizeFor) {
|
|
48989
|
+
case exports.OptimizeFor.WholeProgram:
|
|
48990
|
+
this.ensureAllShimsForAllFiles();
|
|
48991
|
+
break;
|
|
48992
|
+
case exports.OptimizeFor.SingleFile:
|
|
48993
|
+
this.ensureAllShimsForOneFile(sf);
|
|
48994
|
+
break;
|
|
48995
|
+
}
|
|
48996
|
+
return this.perf.inPhase(exports.PerfPhase.TtcSuggestionDiagnostics, () => {
|
|
48997
|
+
const sfPath = absoluteFromSourceFile(sf);
|
|
48998
|
+
const fileRecord = this.state.get(sfPath);
|
|
48999
|
+
const diagnostics = [];
|
|
49000
|
+
const program = this.programDriver.getProgram();
|
|
49001
|
+
if (fileRecord.hasInlines) {
|
|
49002
|
+
diagnostics.push(...getDeprecatedSuggestionDiagnostics(tsLs, program, sfPath, fileRecord, this));
|
|
49003
|
+
}
|
|
49004
|
+
for (const [shimPath] of fileRecord.shimData) {
|
|
49005
|
+
diagnostics.push(...getDeprecatedSuggestionDiagnostics(tsLs, program, shimPath, fileRecord, this));
|
|
49006
|
+
}
|
|
49007
|
+
return diagnostics.filter((diag) => diag !== null);
|
|
49008
|
+
});
|
|
49009
|
+
}
|
|
48959
49010
|
getDiagnosticsForComponent(component) {
|
|
48960
49011
|
this.ensureShimForComponent(component);
|
|
48961
49012
|
return this.perf.inPhase(exports.PerfPhase.TtcDiagnostics, () => {
|
|
@@ -48987,6 +49038,27 @@ class TemplateTypeCheckerImpl {
|
|
|
48987
49038
|
return diagnostics.filter((diag) => diag !== null && diag.typeCheckId === id);
|
|
48988
49039
|
});
|
|
48989
49040
|
}
|
|
49041
|
+
getSuggestionDiagnosticsForComponent(component, tsLs) {
|
|
49042
|
+
this.ensureShimForComponent(component);
|
|
49043
|
+
return this.perf.inPhase(exports.PerfPhase.TtcSuggestionDiagnostics, () => {
|
|
49044
|
+
const sf = component.getSourceFile();
|
|
49045
|
+
const sfPath = absoluteFromSourceFile(sf);
|
|
49046
|
+
const shimPath = TypeCheckShimGenerator.shimFor(sfPath);
|
|
49047
|
+
const fileRecord = this.getFileData(sfPath);
|
|
49048
|
+
if (!fileRecord.shimData.has(shimPath)) {
|
|
49049
|
+
return [];
|
|
49050
|
+
}
|
|
49051
|
+
const templateId = fileRecord.sourceManager.getTypeCheckId(component);
|
|
49052
|
+
const shimRecord = fileRecord.shimData.get(shimPath);
|
|
49053
|
+
const diagnostics = [];
|
|
49054
|
+
const program = this.programDriver.getProgram();
|
|
49055
|
+
if (shimRecord.hasInlines) {
|
|
49056
|
+
diagnostics.push(...getDeprecatedSuggestionDiagnostics(tsLs, program, sfPath, fileRecord, this));
|
|
49057
|
+
}
|
|
49058
|
+
diagnostics.push(...getDeprecatedSuggestionDiagnostics(tsLs, program, shimPath, fileRecord, this));
|
|
49059
|
+
return diagnostics.filter((diag) => diag !== null && diag.typeCheckId === templateId);
|
|
49060
|
+
});
|
|
49061
|
+
}
|
|
48990
49062
|
getTypeCheckBlock(component) {
|
|
48991
49063
|
return this.getLatestComponentState(component).tcb;
|
|
48992
49064
|
}
|
|
@@ -49810,6 +49882,124 @@ function getClassDeclFromSymbol(symbol, checker) {
|
|
|
49810
49882
|
}
|
|
49811
49883
|
return null;
|
|
49812
49884
|
}
|
|
49885
|
+
/**
|
|
49886
|
+
* Returns the diagnostics that report deprecated symbols in the given TypeScript language service.
|
|
49887
|
+
*
|
|
49888
|
+
* There are two logins here:
|
|
49889
|
+
*
|
|
49890
|
+
* 1. For input properties, function calls, and so on, the diagnostics reported in the TypeScript
|
|
49891
|
+
* Language Service can be directly transformed into template diagnostics.
|
|
49892
|
+
* 2. For the element tag deprecation, we need to manually connect the TCB node to the template node
|
|
49893
|
+
* and generate the template diagnostics.
|
|
49894
|
+
*/
|
|
49895
|
+
function getDeprecatedSuggestionDiagnostics(tsLs, program, path, fileRecord, templateTypeChecker) {
|
|
49896
|
+
const sourceFile = program.getSourceFile(path);
|
|
49897
|
+
if (sourceFile === undefined) {
|
|
49898
|
+
return [];
|
|
49899
|
+
}
|
|
49900
|
+
const tsDiags = tsLs.getSuggestionDiagnostics(path).filter(isDeprecatedDiagnostics);
|
|
49901
|
+
const commonTemplateDiags = tsDiags.map((diag) => {
|
|
49902
|
+
return convertDiagnostic(diag, fileRecord.sourceManager);
|
|
49903
|
+
});
|
|
49904
|
+
const elementTagDiags = getTheElementTagDeprecatedSuggestionDiagnostics(path, program, fileRecord, tsDiags, templateTypeChecker);
|
|
49905
|
+
return [...commonTemplateDiags, ...elementTagDiags];
|
|
49906
|
+
}
|
|
49907
|
+
/**
|
|
49908
|
+
* Connect the TCB node to the template node and generate the template diagnostics.
|
|
49909
|
+
*
|
|
49910
|
+
* How to generate the template diagnostics:
|
|
49911
|
+
*
|
|
49912
|
+
* 1. For each diagnostic, find the TCB node that is reported.
|
|
49913
|
+
* 2. Build a map called `nodeToDiag` that the key is the type node and value is the diagnostic.
|
|
49914
|
+
* For example:
|
|
49915
|
+
* ```
|
|
49916
|
+
* var _t1 = null! as TestDir;
|
|
49917
|
+
* ^^^^^^^------ This is diagnostic node that is reported by the ts.
|
|
49918
|
+
* ```
|
|
49919
|
+
* The key is the class component of TestDir.
|
|
49920
|
+
* 3. Find the all directive nodes in the TCB.
|
|
49921
|
+
* For example:
|
|
49922
|
+
* In the above example, the directive node is `_t1`, get the type of `_t1` which is the
|
|
49923
|
+
* class component of `TestDir`. Check if there is a diagnostic in the `nodeToDiag` map
|
|
49924
|
+
* that matches the class component of `TestDir`.
|
|
49925
|
+
* If there is a match, it means that the diagnostic is reported for the directive node
|
|
49926
|
+
* 4. Generate the template diagnostic and return the template diagnostics.
|
|
49927
|
+
*/
|
|
49928
|
+
function getTheElementTagDeprecatedSuggestionDiagnostics(shimPath, program, fileRecord, diags, templateTypeChecker) {
|
|
49929
|
+
const sourceFile = program.getSourceFile(shimPath);
|
|
49930
|
+
if (sourceFile === undefined) {
|
|
49931
|
+
return [];
|
|
49932
|
+
}
|
|
49933
|
+
const typeChecker = program.getTypeChecker();
|
|
49934
|
+
const nodeToDiag = new Map();
|
|
49935
|
+
for (const tsDiag of diags) {
|
|
49936
|
+
const diagNode = getTokenAtPosition(sourceFile, tsDiag.start);
|
|
49937
|
+
const nodeType = typeChecker.getTypeAtLocation(diagNode);
|
|
49938
|
+
const nodeSymbolDeclarations = nodeType.symbol.declarations;
|
|
49939
|
+
const decl = nodeSymbolDeclarations !== undefined && nodeSymbolDeclarations.length > 0
|
|
49940
|
+
? nodeSymbolDeclarations[0]
|
|
49941
|
+
: undefined;
|
|
49942
|
+
if (decl === undefined || !ts.isClassDeclaration(decl)) {
|
|
49943
|
+
continue;
|
|
49944
|
+
}
|
|
49945
|
+
const directiveForDiagnostic = templateTypeChecker.getDirectiveMetadata(decl);
|
|
49946
|
+
// For now, we only report deprecations for components. This is because
|
|
49947
|
+
// directive spans apply to the entire element, so it would cause the deprecation to
|
|
49948
|
+
// appear as a deprecation for the element rather than whatever the selector (likely an attribute)
|
|
49949
|
+
// is for the directive. Technically components have this issue as well but nearly
|
|
49950
|
+
// all component selectors are element selectors.
|
|
49951
|
+
if (directiveForDiagnostic === null || !directiveForDiagnostic.isComponent) {
|
|
49952
|
+
continue;
|
|
49953
|
+
}
|
|
49954
|
+
nodeToDiag.set(decl, tsDiag);
|
|
49955
|
+
}
|
|
49956
|
+
const directiveNodesInTcb = findAllMatchingNodes(sourceFile, {
|
|
49957
|
+
filter: isDirectiveDeclaration,
|
|
49958
|
+
});
|
|
49959
|
+
const templateDiagnostics = [];
|
|
49960
|
+
for (const directive of directiveNodesInTcb) {
|
|
49961
|
+
const directiveType = typeChecker.getTypeAtLocation(directive);
|
|
49962
|
+
const directiveSymbolDeclarations = directiveType.symbol.declarations;
|
|
49963
|
+
const decl = directiveSymbolDeclarations !== undefined && directiveSymbolDeclarations.length > 0
|
|
49964
|
+
? directiveSymbolDeclarations[0]
|
|
49965
|
+
: undefined;
|
|
49966
|
+
if (decl === undefined) {
|
|
49967
|
+
continue;
|
|
49968
|
+
}
|
|
49969
|
+
if (!ts.isClassDeclaration(decl)) {
|
|
49970
|
+
continue;
|
|
49971
|
+
}
|
|
49972
|
+
const diagnostic = nodeToDiag.get(decl);
|
|
49973
|
+
if (diagnostic === undefined) {
|
|
49974
|
+
continue;
|
|
49975
|
+
}
|
|
49976
|
+
const fullMapping = getSourceMapping(diagnostic.file, directive.getStart(), fileRecord.sourceManager,
|
|
49977
|
+
/**
|
|
49978
|
+
* Don't set to true, the deprecated diagnostics will be ignored if this is a diagnostics request.
|
|
49979
|
+
* Only the deprecated diagnostics will be reported here.
|
|
49980
|
+
*/
|
|
49981
|
+
// For example:
|
|
49982
|
+
// var _t2 /*T:DIR*/ /*87,104*/ = _ctor1({ "name": ("") /*96,103*/ }) /*D:ignore*/;
|
|
49983
|
+
// At the end of the statement, there is a comment `/*D:ignore*/` which means that this diagnostic
|
|
49984
|
+
// should be ignored in diagnostics request.
|
|
49985
|
+
/*isDiagnosticsRequest*/ false);
|
|
49986
|
+
if (fullMapping === null) {
|
|
49987
|
+
continue;
|
|
49988
|
+
}
|
|
49989
|
+
const { sourceLocation, sourceMapping: templateSourceMapping, span } = fullMapping;
|
|
49990
|
+
const templateDiagnostic = makeTemplateDiagnostic(sourceLocation.id, templateSourceMapping, span, diagnostic.category, diagnostic.code, diagnostic.messageText, undefined, diagnostic.reportsDeprecated !== undefined
|
|
49991
|
+
? {
|
|
49992
|
+
reportsDeprecated: diagnostic.reportsDeprecated,
|
|
49993
|
+
relatedMessages: diagnostic.relatedInformation,
|
|
49994
|
+
}
|
|
49995
|
+
: undefined);
|
|
49996
|
+
templateDiagnostics.push(templateDiagnostic);
|
|
49997
|
+
}
|
|
49998
|
+
return templateDiagnostics;
|
|
49999
|
+
}
|
|
50000
|
+
function isDeprecatedDiagnostics(diag) {
|
|
50001
|
+
return diag.reportsDeprecated !== undefined;
|
|
50002
|
+
}
|
|
49813
50003
|
|
|
49814
50004
|
exports.AST = AST;
|
|
49815
50005
|
exports.ASTWithSource = ASTWithSource;
|