@angular/language-service 11.2.8 → 11.2.9
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/bundles/ivy.js +288 -198
- package/bundles/language-service.js +36 -6
- package/ivy/language_service.d.ts +20 -1
- package/ivy/language_service.js +158 -124
- package/package.json +1 -1
package/bundles/ivy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v11.2.
|
|
2
|
+
* @license Angular v11.2.9
|
|
3
3
|
* Copyright Google LLC All Rights Reserved.
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -20399,7 +20399,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20399
20399
|
* Use of this source code is governed by an MIT-style license that can be
|
|
20400
20400
|
* found in the LICENSE file at https://angular.io/license
|
|
20401
20401
|
*/
|
|
20402
|
-
const VERSION$1 = new Version('11.2.
|
|
20402
|
+
const VERSION$1 = new Version('11.2.9');
|
|
20403
20403
|
|
|
20404
20404
|
/**
|
|
20405
20405
|
* @license
|
|
@@ -21056,7 +21056,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21056
21056
|
*/
|
|
21057
21057
|
function createDirectiveDefinitionMap(meta) {
|
|
21058
21058
|
const definitionMap = new DefinitionMap();
|
|
21059
|
-
definitionMap.set('version', literal('11.2.
|
|
21059
|
+
definitionMap.set('version', literal('11.2.9'));
|
|
21060
21060
|
// e.g. `type: MyDirective`
|
|
21061
21061
|
definitionMap.set('type', meta.internalType);
|
|
21062
21062
|
// e.g. `selector: 'some-dir'`
|
|
@@ -21277,7 +21277,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21277
21277
|
*/
|
|
21278
21278
|
function createPipeDefinitionMap(meta) {
|
|
21279
21279
|
const definitionMap = new DefinitionMap();
|
|
21280
|
-
definitionMap.set('version', literal('11.2.
|
|
21280
|
+
definitionMap.set('version', literal('11.2.9'));
|
|
21281
21281
|
definitionMap.set('ngImport', importExpr(Identifiers$1.core));
|
|
21282
21282
|
// e.g. `type: MyPipe`
|
|
21283
21283
|
definitionMap.set('type', meta.internalType);
|
|
@@ -21309,7 +21309,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21309
21309
|
* Use of this source code is governed by an MIT-style license that can be
|
|
21310
21310
|
* found in the LICENSE file at https://angular.io/license
|
|
21311
21311
|
*/
|
|
21312
|
-
const VERSION$2 = new Version('11.2.
|
|
21312
|
+
const VERSION$2 = new Version('11.2.9');
|
|
21313
21313
|
|
|
21314
21314
|
/**
|
|
21315
21315
|
* @license
|
|
@@ -25632,10 +25632,38 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
25632
25632
|
* operation.
|
|
25633
25633
|
*/
|
|
25634
25634
|
PerfPhase[PerfPhase["LsReferencesAndRenames"] = 16] = "LsReferencesAndRenames";
|
|
25635
|
+
/**
|
|
25636
|
+
* Time spent by the Angular Language Service calculating a "quick info" operation.
|
|
25637
|
+
*/
|
|
25638
|
+
PerfPhase[PerfPhase["LsQuickInfo"] = 17] = "LsQuickInfo";
|
|
25639
|
+
/**
|
|
25640
|
+
* Time spent by the Angular Language Service calculating a "get type definition" or "get
|
|
25641
|
+
* definition" operation.
|
|
25642
|
+
*/
|
|
25643
|
+
PerfPhase[PerfPhase["LsDefinition"] = 18] = "LsDefinition";
|
|
25644
|
+
/**
|
|
25645
|
+
* Time spent by the Angular Language Service calculating a "get completions" (AKA autocomplete)
|
|
25646
|
+
* operation.
|
|
25647
|
+
*/
|
|
25648
|
+
PerfPhase[PerfPhase["LsCompletions"] = 19] = "LsCompletions";
|
|
25649
|
+
/**
|
|
25650
|
+
* Time spent by the Angular Language Service calculating a "view template typecheck block"
|
|
25651
|
+
* operation.
|
|
25652
|
+
*/
|
|
25653
|
+
PerfPhase[PerfPhase["LsTcb"] = 20] = "LsTcb";
|
|
25654
|
+
/**
|
|
25655
|
+
* Time spent by the Angular Language Service calculating diagnostics.
|
|
25656
|
+
*/
|
|
25657
|
+
PerfPhase[PerfPhase["LsDiagnostics"] = 21] = "LsDiagnostics";
|
|
25658
|
+
/**
|
|
25659
|
+
* Time spent by the Angular Language Service calculating a "get component locations for template"
|
|
25660
|
+
* operation.
|
|
25661
|
+
*/
|
|
25662
|
+
PerfPhase[PerfPhase["LsComponentLocations"] = 22] = "LsComponentLocations";
|
|
25635
25663
|
/**
|
|
25636
25664
|
* Tracks the number of `PerfPhase`s, and must appear at the end of the list.
|
|
25637
25665
|
*/
|
|
25638
|
-
PerfPhase[PerfPhase["LAST"] =
|
|
25666
|
+
PerfPhase[PerfPhase["LAST"] = 23] = "LAST";
|
|
25639
25667
|
})(PerfPhase || (PerfPhase = {}));
|
|
25640
25668
|
/**
|
|
25641
25669
|
* Represents some occurrence during compilation, and is tracked with a counter.
|
|
@@ -30267,9 +30295,16 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30267
30295
|
const meta = this._resolveLiteral(decorator);
|
|
30268
30296
|
const component = reflectObjectLiteral(meta);
|
|
30269
30297
|
const containingFile = node.getSourceFile().fileName;
|
|
30270
|
-
const resolveStyleUrl = (styleUrl
|
|
30271
|
-
|
|
30272
|
-
|
|
30298
|
+
const resolveStyleUrl = (styleUrl) => {
|
|
30299
|
+
try {
|
|
30300
|
+
const resourceUrl = this.resourceLoader.resolve(styleUrl, containingFile);
|
|
30301
|
+
return this.resourceLoader.preload(resourceUrl);
|
|
30302
|
+
}
|
|
30303
|
+
catch (_a) {
|
|
30304
|
+
// Don't worry about failures to preload. We can handle this problem during analysis by
|
|
30305
|
+
// producing a diagnostic.
|
|
30306
|
+
return undefined;
|
|
30307
|
+
}
|
|
30273
30308
|
};
|
|
30274
30309
|
// A Promise that waits for the template and all <link>ed styles within it to be preloaded.
|
|
30275
30310
|
const templateAndTemplateStyleResources = this._preloadAndParseTemplate(node, decorator, component, containingFile)
|
|
@@ -30277,9 +30312,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30277
30312
|
if (template === null) {
|
|
30278
30313
|
return undefined;
|
|
30279
30314
|
}
|
|
30280
|
-
|
|
30281
|
-
return Promise
|
|
30282
|
-
.all(template.styleUrls.map(styleUrl => resolveStyleUrl(styleUrl, nodeForError, 1 /* StylesheetFromTemplate */)))
|
|
30315
|
+
return Promise.all(template.styleUrls.map(styleUrl => resolveStyleUrl(styleUrl)))
|
|
30283
30316
|
.then(() => undefined);
|
|
30284
30317
|
});
|
|
30285
30318
|
// Extract all the styleUrls in the decorator.
|
|
@@ -30294,7 +30327,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30294
30327
|
return Promise
|
|
30295
30328
|
.all([
|
|
30296
30329
|
templateAndTemplateStyleResources,
|
|
30297
|
-
...componentStyleUrls.map(styleUrl => resolveStyleUrl(styleUrl.url
|
|
30330
|
+
...componentStyleUrls.map(styleUrl => resolveStyleUrl(styleUrl.url))
|
|
30298
30331
|
])
|
|
30299
30332
|
.then(() => undefined);
|
|
30300
30333
|
}
|
|
@@ -30304,6 +30337,8 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30304
30337
|
this.perf.eventCount(PerfEvent.AnalyzeComponent);
|
|
30305
30338
|
const containingFile = node.getSourceFile().fileName;
|
|
30306
30339
|
this.literalCache.delete(decorator);
|
|
30340
|
+
let diagnostics;
|
|
30341
|
+
let isPoisoned = false;
|
|
30307
30342
|
// @Component inherits @Directive, so begin by extracting the @Directive metadata and building
|
|
30308
30343
|
// on it.
|
|
30309
30344
|
const directiveResult = extractDirectiveMetadata(node, decorator, this.reflector, this.evaluator, this.defaultImportRecorder, this.isCore, flags, this.annotateForClosureCompiler, this.elementSchemaRegistry.getDefaultComponentElementName());
|
|
@@ -30371,14 +30406,23 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30371
30406
|
...this._extractComponentStyleUrls(component), ...this._extractTemplateStyleUrls(template)
|
|
30372
30407
|
];
|
|
30373
30408
|
for (const styleUrl of styleUrls) {
|
|
30374
|
-
|
|
30375
|
-
|
|
30376
|
-
|
|
30377
|
-
|
|
30378
|
-
|
|
30379
|
-
|
|
30380
|
-
|
|
30381
|
-
|
|
30409
|
+
try {
|
|
30410
|
+
const resourceUrl = this.resourceLoader.resolve(styleUrl.url, containingFile);
|
|
30411
|
+
const resourceStr = this.resourceLoader.load(resourceUrl);
|
|
30412
|
+
styles.push(resourceStr);
|
|
30413
|
+
if (this.depTracker !== null) {
|
|
30414
|
+
this.depTracker.addResourceDependency(node.getSourceFile(), absoluteFrom(resourceUrl));
|
|
30415
|
+
}
|
|
30416
|
+
}
|
|
30417
|
+
catch (_b) {
|
|
30418
|
+
if (diagnostics === undefined) {
|
|
30419
|
+
diagnostics = [];
|
|
30420
|
+
}
|
|
30421
|
+
const resourceType = styleUrl.source === 2 /* StylesheetFromDecorator */ ?
|
|
30422
|
+
2 /* StylesheetFromDecorator */ :
|
|
30423
|
+
1 /* StylesheetFromTemplate */;
|
|
30424
|
+
diagnostics.push(this.makeResourceNotFoundError(styleUrl.url, styleUrl.nodeForError, resourceType)
|
|
30425
|
+
.toDiagnostic());
|
|
30382
30426
|
}
|
|
30383
30427
|
}
|
|
30384
30428
|
let inlineStyles = null;
|
|
@@ -30421,8 +30465,9 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30421
30465
|
styles: styleResources,
|
|
30422
30466
|
template: templateResource,
|
|
30423
30467
|
},
|
|
30424
|
-
isPoisoned
|
|
30468
|
+
isPoisoned,
|
|
30425
30469
|
},
|
|
30470
|
+
diagnostics,
|
|
30426
30471
|
};
|
|
30427
30472
|
if (changeDetection !== null) {
|
|
30428
30473
|
output.analysis.meta.changeDetection = changeDetection;
|
|
@@ -30651,12 +30696,15 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30651
30696
|
let styles = [];
|
|
30652
30697
|
if (analysis.styleUrls !== null) {
|
|
30653
30698
|
for (const styleUrl of analysis.styleUrls) {
|
|
30654
|
-
|
|
30655
|
-
|
|
30656
|
-
|
|
30657
|
-
|
|
30658
|
-
|
|
30659
|
-
|
|
30699
|
+
try {
|
|
30700
|
+
const resolvedStyleUrl = this.resourceLoader.resolve(styleUrl.url, containingFile);
|
|
30701
|
+
const styleText = this.resourceLoader.load(resolvedStyleUrl);
|
|
30702
|
+
styles.push(styleText);
|
|
30703
|
+
}
|
|
30704
|
+
catch (e) {
|
|
30705
|
+
// Resource resolve failures should already be in the diagnostics list from the analyze
|
|
30706
|
+
// stage. We do not need to do anything with them when updating resources.
|
|
30707
|
+
}
|
|
30660
30708
|
}
|
|
30661
30709
|
}
|
|
30662
30710
|
if (analysis.inlineStyles !== null) {
|
|
@@ -30778,8 +30826,15 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30778
30826
|
const styleUrlsExpr = component.get('styleUrls');
|
|
30779
30827
|
if (styleUrlsExpr !== undefined && ts$1.isArrayLiteralExpression(styleUrlsExpr)) {
|
|
30780
30828
|
for (const expression of stringLiteralElements(styleUrlsExpr)) {
|
|
30781
|
-
|
|
30782
|
-
|
|
30829
|
+
try {
|
|
30830
|
+
const resourceUrl = this.resourceLoader.resolve(expression.text, containingFile);
|
|
30831
|
+
styles.add({ path: absoluteFrom(resourceUrl), expression });
|
|
30832
|
+
}
|
|
30833
|
+
catch (_a) {
|
|
30834
|
+
// Errors in style resource extraction do not need to be handled here. We will produce
|
|
30835
|
+
// diagnostics for each one that fails in the analysis, after we evaluate the `styleUrls`
|
|
30836
|
+
// expression to determine _all_ style resources, not just the string literals.
|
|
30837
|
+
}
|
|
30783
30838
|
}
|
|
30784
30839
|
}
|
|
30785
30840
|
const stylesExpr = component.get('styles');
|
|
@@ -30798,20 +30853,25 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30798
30853
|
if (typeof templateUrl !== 'string') {
|
|
30799
30854
|
throw createValueHasWrongTypeError(templateUrlExpr, templateUrl, 'templateUrl must be a string');
|
|
30800
30855
|
}
|
|
30801
|
-
|
|
30802
|
-
|
|
30803
|
-
|
|
30804
|
-
|
|
30805
|
-
|
|
30806
|
-
|
|
30807
|
-
|
|
30808
|
-
|
|
30809
|
-
|
|
30810
|
-
|
|
30811
|
-
|
|
30856
|
+
try {
|
|
30857
|
+
const resourceUrl = this.resourceLoader.resolve(templateUrl, containingFile);
|
|
30858
|
+
const templatePromise = this.resourceLoader.preload(resourceUrl);
|
|
30859
|
+
// If the preload worked, then actually load and parse the template, and wait for any style
|
|
30860
|
+
// URLs to resolve.
|
|
30861
|
+
if (templatePromise !== undefined) {
|
|
30862
|
+
return templatePromise.then(() => {
|
|
30863
|
+
const templateDecl = this.parseTemplateDeclaration(decorator, component, containingFile);
|
|
30864
|
+
const template = this.extractTemplate(node, templateDecl);
|
|
30865
|
+
this.preanalyzeTemplateCache.set(node, template);
|
|
30866
|
+
return template;
|
|
30867
|
+
});
|
|
30868
|
+
}
|
|
30869
|
+
else {
|
|
30870
|
+
return Promise.resolve(null);
|
|
30871
|
+
}
|
|
30812
30872
|
}
|
|
30813
|
-
|
|
30814
|
-
|
|
30873
|
+
catch (e) {
|
|
30874
|
+
throw this.makeResourceNotFoundError(templateUrl, templateUrlExpr, 0 /* Template */);
|
|
30815
30875
|
}
|
|
30816
30876
|
}
|
|
30817
30877
|
else {
|
|
@@ -30943,16 +31003,21 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30943
31003
|
if (typeof templateUrl !== 'string') {
|
|
30944
31004
|
throw createValueHasWrongTypeError(templateUrlExpr, templateUrl, 'templateUrl must be a string');
|
|
30945
31005
|
}
|
|
30946
|
-
|
|
30947
|
-
|
|
30948
|
-
|
|
30949
|
-
|
|
30950
|
-
|
|
30951
|
-
|
|
30952
|
-
|
|
30953
|
-
|
|
30954
|
-
|
|
30955
|
-
|
|
31006
|
+
try {
|
|
31007
|
+
const resourceUrl = this.resourceLoader.resolve(templateUrl, containingFile);
|
|
31008
|
+
return {
|
|
31009
|
+
isInline: false,
|
|
31010
|
+
interpolationConfig,
|
|
31011
|
+
preserveWhitespaces,
|
|
31012
|
+
templateUrl,
|
|
31013
|
+
templateUrlExpression: templateUrlExpr,
|
|
31014
|
+
resolvedTemplateUrl: resourceUrl,
|
|
31015
|
+
sourceMapUrl: sourceMapUrl(resourceUrl),
|
|
31016
|
+
};
|
|
31017
|
+
}
|
|
31018
|
+
catch (e) {
|
|
31019
|
+
throw this.makeResourceNotFoundError(templateUrl, templateUrlExpr, 0 /* Template */);
|
|
31020
|
+
}
|
|
30956
31021
|
}
|
|
30957
31022
|
else if (component.has('template')) {
|
|
30958
31023
|
return {
|
|
@@ -31005,30 +31070,20 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
31005
31070
|
}
|
|
31006
31071
|
this.cycleAnalyzer.recordSyntheticImport(origin, imported);
|
|
31007
31072
|
}
|
|
31008
|
-
|
|
31009
|
-
|
|
31010
|
-
|
|
31011
|
-
|
|
31012
|
-
|
|
31013
|
-
|
|
31014
|
-
|
|
31015
|
-
|
|
31016
|
-
|
|
31017
|
-
|
|
31018
|
-
|
|
31019
|
-
|
|
31020
|
-
case 0 /* Template */:
|
|
31021
|
-
errorText = `Could not find template file '${file}'.`;
|
|
31022
|
-
break;
|
|
31023
|
-
case 1 /* StylesheetFromTemplate */:
|
|
31024
|
-
errorText = `Could not find stylesheet file '${file}' linked from the template.`;
|
|
31025
|
-
break;
|
|
31026
|
-
case 2 /* StylesheetFromDecorator */:
|
|
31027
|
-
errorText = `Could not find stylesheet file '${file}'.`;
|
|
31028
|
-
break;
|
|
31029
|
-
}
|
|
31030
|
-
throw new FatalDiagnosticError(ErrorCode.COMPONENT_RESOURCE_NOT_FOUND, nodeForError, errorText);
|
|
31073
|
+
makeResourceNotFoundError(file, nodeForError, resourceType) {
|
|
31074
|
+
let errorText;
|
|
31075
|
+
switch (resourceType) {
|
|
31076
|
+
case 0 /* Template */:
|
|
31077
|
+
errorText = `Could not find template file '${file}'.`;
|
|
31078
|
+
break;
|
|
31079
|
+
case 1 /* StylesheetFromTemplate */:
|
|
31080
|
+
errorText = `Could not find stylesheet file '${file}' linked from the template.`;
|
|
31081
|
+
break;
|
|
31082
|
+
case 2 /* StylesheetFromDecorator */:
|
|
31083
|
+
errorText = `Could not find stylesheet file '${file}'.`;
|
|
31084
|
+
break;
|
|
31031
31085
|
}
|
|
31086
|
+
return new FatalDiagnosticError(ErrorCode.COMPONENT_RESOURCE_NOT_FOUND, nodeForError, errorText);
|
|
31032
31087
|
}
|
|
31033
31088
|
_extractTemplateStyleUrls(template) {
|
|
31034
31089
|
if (template.styleUrls === null) {
|
|
@@ -40590,24 +40645,30 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
40590
40645
|
};
|
|
40591
40646
|
}
|
|
40592
40647
|
function getExtendedConfigPath(configFile, extendsValue, host, fs) {
|
|
40593
|
-
|
|
40648
|
+
const result = getExtendedConfigPathWorker(configFile, extendsValue, host, fs);
|
|
40649
|
+
if (result !== null) {
|
|
40650
|
+
return result;
|
|
40651
|
+
}
|
|
40652
|
+
// Try to resolve the paths with a json extension append a json extension to the file in case if
|
|
40653
|
+
// it is missing and the resolution failed. This is to replicate TypeScript behaviour, see:
|
|
40654
|
+
// https://github.com/microsoft/TypeScript/blob/294a5a7d784a5a95a8048ee990400979a6bc3a1c/src/compiler/commandLineParser.ts#L2806
|
|
40655
|
+
return getExtendedConfigPathWorker(configFile, `${extendsValue}.json`, host, fs);
|
|
40656
|
+
}
|
|
40657
|
+
function getExtendedConfigPathWorker(configFile, extendsValue, host, fs) {
|
|
40594
40658
|
if (extendsValue.startsWith('.') || fs.isRooted(extendsValue)) {
|
|
40595
|
-
extendedConfigPath = host.resolve(host.dirname(configFile), extendsValue);
|
|
40596
|
-
|
|
40597
|
-
extendedConfigPath
|
|
40598
|
-
|
|
40659
|
+
const extendedConfigPath = host.resolve(host.dirname(configFile), extendsValue);
|
|
40660
|
+
if (host.exists(extendedConfigPath)) {
|
|
40661
|
+
return extendedConfigPath;
|
|
40662
|
+
}
|
|
40599
40663
|
}
|
|
40600
40664
|
else {
|
|
40601
40665
|
const parseConfigHost = createParseConfigHost(host, fs);
|
|
40602
40666
|
// Path isn't a rooted or relative path, resolve like a module.
|
|
40603
40667
|
const { resolvedModule, } = ts$1.nodeModuleNameResolver(extendsValue, configFile, { moduleResolution: ts$1.ModuleResolutionKind.NodeJs, resolveJsonModule: true }, parseConfigHost);
|
|
40604
40668
|
if (resolvedModule) {
|
|
40605
|
-
|
|
40669
|
+
return absoluteFrom(resolvedModule.resolvedFileName);
|
|
40606
40670
|
}
|
|
40607
40671
|
}
|
|
40608
|
-
if (extendedConfigPath !== null && host.exists(extendedConfigPath)) {
|
|
40609
|
-
return extendedConfigPath;
|
|
40610
|
-
}
|
|
40611
40672
|
return null;
|
|
40612
40673
|
}
|
|
40613
40674
|
|
|
@@ -43501,49 +43562,52 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43501
43562
|
return this.options;
|
|
43502
43563
|
}
|
|
43503
43564
|
getSemanticDiagnostics(fileName) {
|
|
43504
|
-
|
|
43505
|
-
|
|
43506
|
-
|
|
43507
|
-
|
|
43508
|
-
|
|
43509
|
-
|
|
43510
|
-
|
|
43511
|
-
|
|
43512
|
-
|
|
43513
|
-
|
|
43514
|
-
|
|
43515
|
-
|
|
43516
|
-
|
|
43517
|
-
|
|
43518
|
-
|
|
43519
|
-
|
|
43520
|
-
|
|
43521
|
-
|
|
43522
|
-
|
|
43523
|
-
|
|
43524
|
-
|
|
43525
|
-
|
|
43526
|
-
|
|
43527
|
-
|
|
43528
|
-
|
|
43529
|
-
|
|
43530
|
-
|
|
43531
|
-
|
|
43565
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsDiagnostics, (compiler) => {
|
|
43566
|
+
const ttc = compiler.getTemplateTypeChecker();
|
|
43567
|
+
const diagnostics = [];
|
|
43568
|
+
if (isTypeScriptFile(fileName)) {
|
|
43569
|
+
const program = compiler.getNextProgram();
|
|
43570
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
43571
|
+
if (sourceFile) {
|
|
43572
|
+
const ngDiagnostics = compiler.getDiagnosticsForFile(sourceFile, OptimizeFor.SingleFile);
|
|
43573
|
+
// There are several kinds of diagnostics returned by `NgCompiler` for a source file:
|
|
43574
|
+
//
|
|
43575
|
+
// 1. Angular-related non-template diagnostics from decorated classes within that
|
|
43576
|
+
// file.
|
|
43577
|
+
// 2. Template diagnostics for components with direct inline templates (a string
|
|
43578
|
+
// literal).
|
|
43579
|
+
// 3. Template diagnostics for components with indirect inline templates (templates
|
|
43580
|
+
// computed
|
|
43581
|
+
// by expression).
|
|
43582
|
+
// 4. Template diagnostics for components with external templates.
|
|
43583
|
+
//
|
|
43584
|
+
// When showing diagnostics for a TS source file, we want to only include kinds 1 and
|
|
43585
|
+
// 2 - those diagnostics which are reported at a location within the TS file itself.
|
|
43586
|
+
// Diagnostics for external templates will be shown when editing that template file
|
|
43587
|
+
// (the `else` block) below.
|
|
43588
|
+
//
|
|
43589
|
+
// Currently, indirect inline template diagnostics (kind 3) are not shown at all by
|
|
43590
|
+
// the Language Service, because there is no sensible location in the user's code for
|
|
43591
|
+
// them. Such templates are an edge case, though, and should not be common.
|
|
43592
|
+
//
|
|
43593
|
+
// TODO(alxhub): figure out a good user experience for indirect template diagnostics
|
|
43594
|
+
// and show them from within the Language Service.
|
|
43595
|
+
diagnostics.push(...ngDiagnostics.filter(diag => diag.file !== undefined && diag.file.fileName === sourceFile.fileName));
|
|
43596
|
+
}
|
|
43532
43597
|
}
|
|
43533
|
-
|
|
43534
|
-
|
|
43535
|
-
|
|
43536
|
-
|
|
43537
|
-
|
|
43538
|
-
|
|
43598
|
+
else {
|
|
43599
|
+
const components = compiler.getComponentsWithTemplateFile(fileName);
|
|
43600
|
+
for (const component of components) {
|
|
43601
|
+
if (ts.isClassDeclaration(component)) {
|
|
43602
|
+
diagnostics.push(...ttc.getDiagnosticsForComponent(component));
|
|
43603
|
+
}
|
|
43539
43604
|
}
|
|
43540
43605
|
}
|
|
43541
|
-
|
|
43542
|
-
|
|
43543
|
-
return diagnostics;
|
|
43606
|
+
return diagnostics;
|
|
43607
|
+
});
|
|
43544
43608
|
}
|
|
43545
43609
|
getDefinitionAndBoundSpan(fileName, position) {
|
|
43546
|
-
return this.
|
|
43610
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsDefinition, (compiler) => {
|
|
43547
43611
|
if (!isInAngularContext(compiler.getNextProgram(), fileName, position)) {
|
|
43548
43612
|
return undefined;
|
|
43549
43613
|
}
|
|
@@ -43552,7 +43616,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43552
43616
|
});
|
|
43553
43617
|
}
|
|
43554
43618
|
getTypeDefinitionAtPosition(fileName, position) {
|
|
43555
|
-
return this.
|
|
43619
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsDefinition, (compiler) => {
|
|
43556
43620
|
if (!isTemplateContext(compiler.getNextProgram(), fileName, position)) {
|
|
43557
43621
|
return undefined;
|
|
43558
43622
|
}
|
|
@@ -43561,56 +43625,57 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43561
43625
|
});
|
|
43562
43626
|
}
|
|
43563
43627
|
getQuickInfoAtPosition(fileName, position) {
|
|
43564
|
-
return this.
|
|
43565
|
-
|
|
43566
|
-
return undefined;
|
|
43567
|
-
}
|
|
43568
|
-
const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler);
|
|
43569
|
-
if (templateInfo === undefined) {
|
|
43570
|
-
return undefined;
|
|
43571
|
-
}
|
|
43572
|
-
const positionDetails = getTargetAtPosition(templateInfo.template, position);
|
|
43573
|
-
if (positionDetails === null) {
|
|
43574
|
-
return undefined;
|
|
43575
|
-
}
|
|
43576
|
-
// Because we can only show 1 quick info, just use the bound attribute if the target is a two
|
|
43577
|
-
// way binding. We may consider concatenating additional display parts from the other target
|
|
43578
|
-
// nodes or representing the two way binding in some other manner in the future.
|
|
43579
|
-
const node = positionDetails.context.kind === TargetNodeKind.TwoWayBindingContext ?
|
|
43580
|
-
positionDetails.context.nodes[0] :
|
|
43581
|
-
positionDetails.context.node;
|
|
43582
|
-
return new QuickInfoBuilder(this.tsLS, compiler, templateInfo.component, node).get();
|
|
43628
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsQuickInfo, (compiler) => {
|
|
43629
|
+
return this.getQuickInfoAtPositionImpl(fileName, position, compiler);
|
|
43583
43630
|
});
|
|
43584
43631
|
}
|
|
43632
|
+
getQuickInfoAtPositionImpl(fileName, position, compiler) {
|
|
43633
|
+
if (!isTemplateContext(compiler.getNextProgram(), fileName, position)) {
|
|
43634
|
+
return undefined;
|
|
43635
|
+
}
|
|
43636
|
+
const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler);
|
|
43637
|
+
if (templateInfo === undefined) {
|
|
43638
|
+
return undefined;
|
|
43639
|
+
}
|
|
43640
|
+
const positionDetails = getTargetAtPosition(templateInfo.template, position);
|
|
43641
|
+
if (positionDetails === null) {
|
|
43642
|
+
return undefined;
|
|
43643
|
+
}
|
|
43644
|
+
// Because we can only show 1 quick info, just use the bound attribute if the target is a two
|
|
43645
|
+
// way binding. We may consider concatenating additional display parts from the other target
|
|
43646
|
+
// nodes or representing the two way binding in some other manner in the future.
|
|
43647
|
+
const node = positionDetails.context.kind === TargetNodeKind.TwoWayBindingContext ?
|
|
43648
|
+
positionDetails.context.nodes[0] :
|
|
43649
|
+
positionDetails.context.node;
|
|
43650
|
+
return new QuickInfoBuilder(this.tsLS, compiler, templateInfo.component, node).get();
|
|
43651
|
+
}
|
|
43585
43652
|
getReferencesAtPosition(fileName, position) {
|
|
43586
|
-
|
|
43587
|
-
|
|
43588
|
-
|
|
43589
|
-
|
|
43590
|
-
return results;
|
|
43653
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsReferencesAndRenames, (compiler) => {
|
|
43654
|
+
return new ReferencesAndRenameBuilder(this.strategy, this.tsLS, compiler)
|
|
43655
|
+
.getReferencesAtPosition(fileName, position);
|
|
43656
|
+
});
|
|
43591
43657
|
}
|
|
43592
43658
|
getRenameInfo(fileName, position) {
|
|
43593
|
-
|
|
43594
|
-
|
|
43595
|
-
|
|
43596
|
-
|
|
43597
|
-
|
|
43598
|
-
|
|
43599
|
-
|
|
43600
|
-
|
|
43601
|
-
|
|
43602
|
-
|
|
43603
|
-
|
|
43659
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsReferencesAndRenames, (compiler) => {
|
|
43660
|
+
var _a, _b, _c;
|
|
43661
|
+
const renameInfo = new ReferencesAndRenameBuilder(this.strategy, this.tsLS, compiler)
|
|
43662
|
+
.getRenameInfo(absoluteFrom(fileName), position);
|
|
43663
|
+
if (!renameInfo.canRename) {
|
|
43664
|
+
return renameInfo;
|
|
43665
|
+
}
|
|
43666
|
+
const quickInfo = (_a = this.getQuickInfoAtPositionImpl(fileName, position, compiler)) !== null && _a !== void 0 ? _a : this.tsLS.getQuickInfoAtPosition(fileName, position);
|
|
43667
|
+
const kind = (_b = quickInfo === null || quickInfo === void 0 ? void 0 : quickInfo.kind) !== null && _b !== void 0 ? _b : ts.ScriptElementKind.unknown;
|
|
43668
|
+
const kindModifiers = (_c = quickInfo === null || quickInfo === void 0 ? void 0 : quickInfo.kindModifiers) !== null && _c !== void 0 ? _c : ts.ScriptElementKind.unknown;
|
|
43669
|
+
return Object.assign(Object.assign({}, renameInfo), { kind, kindModifiers });
|
|
43670
|
+
});
|
|
43604
43671
|
}
|
|
43605
43672
|
findRenameLocations(fileName, position) {
|
|
43606
|
-
|
|
43607
|
-
|
|
43608
|
-
|
|
43609
|
-
|
|
43610
|
-
return results;
|
|
43673
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsReferencesAndRenames, (compiler) => {
|
|
43674
|
+
return new ReferencesAndRenameBuilder(this.strategy, this.tsLS, compiler)
|
|
43675
|
+
.findRenameLocations(fileName, position);
|
|
43676
|
+
});
|
|
43611
43677
|
}
|
|
43612
|
-
getCompletionBuilder(fileName, position) {
|
|
43613
|
-
const compiler = this.compilerFactory.getOrCreate();
|
|
43678
|
+
getCompletionBuilder(fileName, position, compiler) {
|
|
43614
43679
|
const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler);
|
|
43615
43680
|
if (templateInfo === undefined) {
|
|
43616
43681
|
return null;
|
|
@@ -43627,23 +43692,26 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43627
43692
|
return new CompletionBuilder(this.tsLS, compiler, templateInfo.component, node, positionDetails, isTypeScriptFile(fileName));
|
|
43628
43693
|
}
|
|
43629
43694
|
getCompletionsAtPosition(fileName, position, options) {
|
|
43630
|
-
return this.
|
|
43631
|
-
|
|
43632
|
-
return undefined;
|
|
43633
|
-
}
|
|
43634
|
-
const builder = this.getCompletionBuilder(fileName, position);
|
|
43635
|
-
if (builder === null) {
|
|
43636
|
-
return undefined;
|
|
43637
|
-
}
|
|
43638
|
-
return builder.getCompletionsAtPosition(options);
|
|
43695
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsCompletions, (compiler) => {
|
|
43696
|
+
return this.getCompletionsAtPositionImpl(fileName, position, options, compiler);
|
|
43639
43697
|
});
|
|
43640
43698
|
}
|
|
43699
|
+
getCompletionsAtPositionImpl(fileName, position, options, compiler) {
|
|
43700
|
+
if (!isTemplateContext(compiler.getNextProgram(), fileName, position)) {
|
|
43701
|
+
return undefined;
|
|
43702
|
+
}
|
|
43703
|
+
const builder = this.getCompletionBuilder(fileName, position, compiler);
|
|
43704
|
+
if (builder === null) {
|
|
43705
|
+
return undefined;
|
|
43706
|
+
}
|
|
43707
|
+
return builder.getCompletionsAtPosition(options);
|
|
43708
|
+
}
|
|
43641
43709
|
getCompletionEntryDetails(fileName, position, entryName, formatOptions, preferences) {
|
|
43642
|
-
return this.
|
|
43710
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsCompletions, (compiler) => {
|
|
43643
43711
|
if (!isTemplateContext(compiler.getNextProgram(), fileName, position)) {
|
|
43644
43712
|
return undefined;
|
|
43645
43713
|
}
|
|
43646
|
-
const builder = this.getCompletionBuilder(fileName, position);
|
|
43714
|
+
const builder = this.getCompletionBuilder(fileName, position, compiler);
|
|
43647
43715
|
if (builder === null) {
|
|
43648
43716
|
return undefined;
|
|
43649
43717
|
}
|
|
@@ -43651,11 +43719,11 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43651
43719
|
});
|
|
43652
43720
|
}
|
|
43653
43721
|
getCompletionEntrySymbol(fileName, position, entryName) {
|
|
43654
|
-
return this.
|
|
43722
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsCompletions, (compiler) => {
|
|
43655
43723
|
if (!isTemplateContext(compiler.getNextProgram(), fileName, position)) {
|
|
43656
43724
|
return undefined;
|
|
43657
43725
|
}
|
|
43658
|
-
const builder = this.getCompletionBuilder(fileName, position);
|
|
43726
|
+
const builder = this.getCompletionBuilder(fileName, position, compiler);
|
|
43659
43727
|
if (builder === null) {
|
|
43660
43728
|
return undefined;
|
|
43661
43729
|
}
|
|
@@ -43665,7 +43733,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43665
43733
|
});
|
|
43666
43734
|
}
|
|
43667
43735
|
getTcb(fileName, position) {
|
|
43668
|
-
return this.
|
|
43736
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsTcb, compiler => {
|
|
43669
43737
|
const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler);
|
|
43670
43738
|
if (templateInfo === undefined) {
|
|
43671
43739
|
return undefined;
|
|
@@ -43705,10 +43773,31 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43705
43773
|
};
|
|
43706
43774
|
});
|
|
43707
43775
|
}
|
|
43708
|
-
|
|
43776
|
+
/**
|
|
43777
|
+
* Provides an instance of the `NgCompiler` and traces perf results. Perf results are logged only
|
|
43778
|
+
* if the log level is verbose or higher. This method is intended to be called once per public
|
|
43779
|
+
* method call.
|
|
43780
|
+
*
|
|
43781
|
+
* Here is an example of the log output.
|
|
43782
|
+
*
|
|
43783
|
+
* Perf 245 [16:16:39.353] LanguageService#getQuickInfoAtPosition(): {"events":{},"phases":{
|
|
43784
|
+
* "Unaccounted":379,"TtcSymbol":4},"memory":{}}
|
|
43785
|
+
*
|
|
43786
|
+
* Passing name of caller instead of using `arguments.caller` because 'caller', 'callee', and
|
|
43787
|
+
* 'arguments' properties may not be accessed in strict mode.
|
|
43788
|
+
*
|
|
43789
|
+
* @param phase the `PerfPhase` to execute the `p` callback in
|
|
43790
|
+
* @param p callback to be run synchronously with an instance of the `NgCompiler` as argument
|
|
43791
|
+
* @return the result of running the `p` callback
|
|
43792
|
+
*/
|
|
43793
|
+
withCompilerAndPerfTracing(phase, p) {
|
|
43709
43794
|
const compiler = this.compilerFactory.getOrCreate();
|
|
43710
|
-
const result = p(compiler);
|
|
43795
|
+
const result = compiler.perfRecorder.inPhase(phase, () => p(compiler));
|
|
43711
43796
|
this.compilerFactory.registerLastKnownProgram();
|
|
43797
|
+
const logger = this.project.projectService.logger;
|
|
43798
|
+
if (logger.hasLevel(ts.server.LogLevel.verbose)) {
|
|
43799
|
+
logger.perftrc(`LanguageService#${PerfPhase[phase]}: ${JSON.stringify(compiler.perfRecorder.finalize())}`);
|
|
43800
|
+
}
|
|
43712
43801
|
return result;
|
|
43713
43802
|
}
|
|
43714
43803
|
getCompilerOptionsDiagnostics() {
|
|
@@ -43716,22 +43805,23 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43716
43805
|
if (!(project instanceof ts.server.ConfiguredProject)) {
|
|
43717
43806
|
return [];
|
|
43718
43807
|
}
|
|
43719
|
-
|
|
43720
|
-
|
|
43721
|
-
|
|
43722
|
-
|
|
43723
|
-
|
|
43724
|
-
'
|
|
43725
|
-
|
|
43726
|
-
|
|
43727
|
-
|
|
43728
|
-
|
|
43729
|
-
|
|
43730
|
-
|
|
43731
|
-
|
|
43732
|
-
|
|
43733
|
-
|
|
43734
|
-
|
|
43808
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsDiagnostics, (compiler) => {
|
|
43809
|
+
const diagnostics = [];
|
|
43810
|
+
const configSourceFile = ts.readJsonConfigFile(project.getConfigFilePath(), (path) => project.readFile(path));
|
|
43811
|
+
if (!this.options.strictTemplates && !this.options.fullTemplateTypeCheck) {
|
|
43812
|
+
diagnostics.push({
|
|
43813
|
+
messageText: 'Some language features are not available. ' +
|
|
43814
|
+
'To access all features, enable `strictTemplates` in `angularCompilerOptions`.',
|
|
43815
|
+
category: ts.DiagnosticCategory.Suggestion,
|
|
43816
|
+
code: ngErrorCode(ErrorCode.SUGGEST_STRICT_TEMPLATES),
|
|
43817
|
+
file: configSourceFile,
|
|
43818
|
+
start: undefined,
|
|
43819
|
+
length: undefined,
|
|
43820
|
+
});
|
|
43821
|
+
}
|
|
43822
|
+
diagnostics.push(...compiler.getOptionDiagnostics());
|
|
43823
|
+
return diagnostics;
|
|
43824
|
+
});
|
|
43735
43825
|
}
|
|
43736
43826
|
watchConfigFile(project) {
|
|
43737
43827
|
// TODO: Check the case when the project is disposed. An InferredProject
|