@angular/language-service 11.1.0 → 11.1.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/bundles/ivy.js +394 -149
- package/bundles/language-service.js +83 -47
- package/ivy/adapters.d.ts +5 -0
- package/ivy/adapters.js +9 -1
- package/ivy/compiler_factory.js +9 -6
- package/ivy/language_service.d.ts +2 -0
- package/ivy/language_service.js +26 -2
- package/ivy/ts_plugin.js +14 -2
- package/package.json +1 -1
package/bundles/ivy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v11.1.
|
|
2
|
+
* @license Angular v11.1.1
|
|
3
3
|
* Copyright Google LLC All Rights Reserved.
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -11543,13 +11543,25 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11543
11543
|
get currentAbsoluteOffset() {
|
|
11544
11544
|
return this.absoluteOffset + this.inputIndex;
|
|
11545
11545
|
}
|
|
11546
|
-
|
|
11547
|
-
|
|
11546
|
+
/**
|
|
11547
|
+
* Retrieve a `ParseSpan` from `start` to the current position (or to `artificialEndIndex` if
|
|
11548
|
+
* provided).
|
|
11549
|
+
*
|
|
11550
|
+
* @param start Position from which the `ParseSpan` will start.
|
|
11551
|
+
* @param artificialEndIndex Optional ending index to be used if provided (and if greater than the
|
|
11552
|
+
* natural ending index)
|
|
11553
|
+
*/
|
|
11554
|
+
span(start, artificialEndIndex) {
|
|
11555
|
+
let endIndex = this.currentEndIndex;
|
|
11556
|
+
if (artificialEndIndex !== undefined && artificialEndIndex > this.currentEndIndex) {
|
|
11557
|
+
endIndex = artificialEndIndex;
|
|
11558
|
+
}
|
|
11559
|
+
return new ParseSpan(start, endIndex);
|
|
11548
11560
|
}
|
|
11549
|
-
sourceSpan(start) {
|
|
11550
|
-
const serial = `${start}@${this.inputIndex}`;
|
|
11561
|
+
sourceSpan(start, artificialEndIndex) {
|
|
11562
|
+
const serial = `${start}@${this.inputIndex}:${artificialEndIndex}`;
|
|
11551
11563
|
if (!this.sourceSpanCache.has(serial)) {
|
|
11552
|
-
this.sourceSpanCache.set(serial, this.span(start).toAbsolute(this.absoluteOffset));
|
|
11564
|
+
this.sourceSpanCache.set(serial, this.span(start, artificialEndIndex).toAbsolute(this.absoluteOffset));
|
|
11553
11565
|
}
|
|
11554
11566
|
return this.sourceSpanCache.get(serial);
|
|
11555
11567
|
}
|
|
@@ -11612,7 +11624,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11612
11624
|
const n = this.next;
|
|
11613
11625
|
if (!n.isIdentifier() && !n.isKeyword()) {
|
|
11614
11626
|
this.error(`Unexpected ${this.prettyPrintToken(n)}, expected identifier or keyword`);
|
|
11615
|
-
return
|
|
11627
|
+
return null;
|
|
11616
11628
|
}
|
|
11617
11629
|
this.advance();
|
|
11618
11630
|
return n.toString();
|
|
@@ -11657,15 +11669,36 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11657
11669
|
}
|
|
11658
11670
|
do {
|
|
11659
11671
|
const nameStart = this.inputIndex;
|
|
11660
|
-
|
|
11661
|
-
|
|
11672
|
+
let nameId = this.expectIdentifierOrKeyword();
|
|
11673
|
+
let nameSpan;
|
|
11674
|
+
let fullSpanEnd = undefined;
|
|
11675
|
+
if (nameId !== null) {
|
|
11676
|
+
nameSpan = this.sourceSpan(nameStart);
|
|
11677
|
+
}
|
|
11678
|
+
else {
|
|
11679
|
+
// No valid identifier was found, so we'll assume an empty pipe name ('').
|
|
11680
|
+
nameId = '';
|
|
11681
|
+
// However, there may have been whitespace present between the pipe character and the next
|
|
11682
|
+
// token in the sequence (or the end of input). We want to track this whitespace so that
|
|
11683
|
+
// the `BindingPipe` we produce covers not just the pipe character, but any trailing
|
|
11684
|
+
// whitespace beyond it. Another way of thinking about this is that the zero-length name
|
|
11685
|
+
// is assumed to be at the end of any whitespace beyond the pipe character.
|
|
11686
|
+
//
|
|
11687
|
+
// Therefore, we push the end of the `ParseSpan` for this pipe all the way up to the
|
|
11688
|
+
// beginning of the next token, or until the end of input if the next token is EOF.
|
|
11689
|
+
fullSpanEnd = this.next.index !== -1 ? this.next.index : this.inputLength + this.offset;
|
|
11690
|
+
// The `nameSpan` for an empty pipe name is zero-length at the end of any whitespace
|
|
11691
|
+
// beyond the pipe character.
|
|
11692
|
+
nameSpan = new ParseSpan(fullSpanEnd, fullSpanEnd).toAbsolute(this.absoluteOffset);
|
|
11693
|
+
}
|
|
11662
11694
|
const args = [];
|
|
11663
11695
|
while (this.consumeOptionalCharacter($COLON)) {
|
|
11664
11696
|
args.push(this.parseExpression());
|
|
11697
|
+
// If there are additional expressions beyond the name, then the artificial end for the
|
|
11698
|
+
// name is no longer relevant.
|
|
11665
11699
|
}
|
|
11666
11700
|
const { start } = result.span;
|
|
11667
|
-
result =
|
|
11668
|
-
new BindingPipe(this.span(start), this.sourceSpan(start), result, name, args, nameSpan);
|
|
11701
|
+
result = new BindingPipe(this.span(start), this.sourceSpan(start, fullSpanEnd), result, nameId, args, nameSpan);
|
|
11669
11702
|
} while (this.consumeOptionalOperator('|'));
|
|
11670
11703
|
}
|
|
11671
11704
|
return result;
|
|
@@ -11954,7 +11987,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11954
11987
|
const start = receiver.span.start;
|
|
11955
11988
|
const nameStart = this.inputIndex;
|
|
11956
11989
|
const id = this.withContext(ParseContextFlags.Writable, () => {
|
|
11957
|
-
|
|
11990
|
+
var _a;
|
|
11991
|
+
const id = (_a = this.expectIdentifierOrKeyword()) !== null && _a !== void 0 ? _a : '';
|
|
11958
11992
|
if (id.length === 0) {
|
|
11959
11993
|
this.error(`Expected identifier for property access`, receiver.span.end);
|
|
11960
11994
|
}
|
|
@@ -16974,7 +17008,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
16974
17008
|
* Use of this source code is governed by an MIT-style license that can be
|
|
16975
17009
|
* found in the LICENSE file at https://angular.io/license
|
|
16976
17010
|
*/
|
|
16977
|
-
const VERSION$1 = new Version('11.1.
|
|
17011
|
+
const VERSION$1 = new Version('11.1.1');
|
|
16978
17012
|
|
|
16979
17013
|
/**
|
|
16980
17014
|
* @license
|
|
@@ -17631,7 +17665,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
17631
17665
|
*/
|
|
17632
17666
|
function createDirectiveDefinitionMap(meta) {
|
|
17633
17667
|
const definitionMap = new DefinitionMap();
|
|
17634
|
-
definitionMap.set('version', literal('11.1.
|
|
17668
|
+
definitionMap.set('version', literal('11.1.1'));
|
|
17635
17669
|
// e.g. `type: MyDirective`
|
|
17636
17670
|
definitionMap.set('type', meta.internalType);
|
|
17637
17671
|
// e.g. `selector: 'some-dir'`
|
|
@@ -21079,7 +21113,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21079
21113
|
* Use of this source code is governed by an MIT-style license that can be
|
|
21080
21114
|
* found in the LICENSE file at https://angular.io/license
|
|
21081
21115
|
*/
|
|
21082
|
-
const VERSION$2 = new Version('11.1.
|
|
21116
|
+
const VERSION$2 = new Version('11.1.1');
|
|
21083
21117
|
|
|
21084
21118
|
/**
|
|
21085
21119
|
* @license
|
|
@@ -21271,6 +21305,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21271
21305
|
* An injectable already has a `ɵprov` property.
|
|
21272
21306
|
*/
|
|
21273
21307
|
ErrorCode[ErrorCode["INJECTABLE_DUPLICATE_PROV"] = 9001] = "INJECTABLE_DUPLICATE_PROV";
|
|
21308
|
+
// 10XXX error codes are reserved for diagnostics with category
|
|
21309
|
+
// `ts.DiagnosticCategory.Suggestion`. These diagnostics are generated by
|
|
21310
|
+
// language service.
|
|
21311
|
+
/**
|
|
21312
|
+
* Suggest users to enable `strictTemplates` to make use of full capabilities
|
|
21313
|
+
* provided by Angular language service.
|
|
21314
|
+
*/
|
|
21315
|
+
ErrorCode[ErrorCode["SUGGEST_STRICT_TEMPLATES"] = 10001] = "SUGGEST_STRICT_TEMPLATES";
|
|
21274
21316
|
})(ErrorCode || (ErrorCode = {}));
|
|
21275
21317
|
/**
|
|
21276
21318
|
* @internal
|
|
@@ -25445,6 +25487,18 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
25445
25487
|
}
|
|
25446
25488
|
}
|
|
25447
25489
|
}
|
|
25490
|
+
updateResources(clazz) {
|
|
25491
|
+
if (!this.reflector.isClass(clazz) || !this.classes.has(clazz)) {
|
|
25492
|
+
return;
|
|
25493
|
+
}
|
|
25494
|
+
const record = this.classes.get(clazz);
|
|
25495
|
+
for (const trait of record.traits) {
|
|
25496
|
+
if (trait.state !== TraitState.Resolved || trait.handler.updateResources === undefined) {
|
|
25497
|
+
continue;
|
|
25498
|
+
}
|
|
25499
|
+
trait.handler.updateResources(clazz, trait.analysis, trait.resolution);
|
|
25500
|
+
}
|
|
25501
|
+
}
|
|
25448
25502
|
compile(clazz, constantPool) {
|
|
25449
25503
|
const original = ts$1.getOriginalNode(clazz);
|
|
25450
25504
|
if (!this.reflector.isClass(clazz) || !this.reflector.isClass(original) ||
|
|
@@ -28584,24 +28638,13 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28584
28638
|
template = preanalyzed;
|
|
28585
28639
|
}
|
|
28586
28640
|
else {
|
|
28587
|
-
|
|
28588
|
-
|
|
28589
|
-
const templateUrlExpr = component.get('templateUrl');
|
|
28590
|
-
const templateUrl = this.evaluator.evaluate(templateUrlExpr);
|
|
28591
|
-
if (typeof templateUrl !== 'string') {
|
|
28592
|
-
throw createValueHasWrongTypeError(templateUrlExpr, templateUrl, 'templateUrl must be a string');
|
|
28593
|
-
}
|
|
28594
|
-
const resourceUrl = this.resourceLoader.resolve(templateUrl, containingFile);
|
|
28595
|
-
template = this._extractExternalTemplate(node, component, templateUrlExpr, resourceUrl);
|
|
28596
|
-
}
|
|
28597
|
-
else {
|
|
28598
|
-
// Expect an inline template to be present.
|
|
28599
|
-
template = this._extractInlineTemplate(node, decorator, component, containingFile);
|
|
28600
|
-
}
|
|
28641
|
+
const templateDecl = this.parseTemplateDeclaration(decorator, component, containingFile);
|
|
28642
|
+
template = this.extractTemplate(node, templateDecl);
|
|
28601
28643
|
}
|
|
28602
|
-
const templateResource = template.isInline ?
|
|
28603
|
-
|
|
28604
|
-
|
|
28644
|
+
const templateResource = template.isInline ? { path: null, expression: component.get('template') } : {
|
|
28645
|
+
path: absoluteFrom(template.declaration.resolvedTemplateUrl),
|
|
28646
|
+
expression: template.sourceMapping.node
|
|
28647
|
+
};
|
|
28605
28648
|
// Figure out the set of styles. The ordering here is important: external resources (styleUrls)
|
|
28606
28649
|
// precede inline styles, and styles defined in the template override styles defined in the
|
|
28607
28650
|
// component.
|
|
@@ -28621,9 +28664,11 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28621
28664
|
}
|
|
28622
28665
|
}
|
|
28623
28666
|
}
|
|
28667
|
+
let inlineStyles = null;
|
|
28624
28668
|
if (component.has('styles')) {
|
|
28625
28669
|
const litStyles = parseFieldArrayValue(component, 'styles', this.evaluator);
|
|
28626
28670
|
if (litStyles !== null) {
|
|
28671
|
+
inlineStyles = [...litStyles];
|
|
28627
28672
|
if (styles === null) {
|
|
28628
28673
|
styles = litStyles;
|
|
28629
28674
|
}
|
|
@@ -28663,6 +28708,8 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28663
28708
|
template,
|
|
28664
28709
|
providersRequiringFactory,
|
|
28665
28710
|
viewProvidersRequiringFactory,
|
|
28711
|
+
inlineStyles,
|
|
28712
|
+
styleUrls,
|
|
28666
28713
|
resources: {
|
|
28667
28714
|
styles: styleResources,
|
|
28668
28715
|
template: templateResource,
|
|
@@ -28831,6 +28878,33 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28831
28878
|
}
|
|
28832
28879
|
return { data };
|
|
28833
28880
|
}
|
|
28881
|
+
updateResources(node, analysis) {
|
|
28882
|
+
const containingFile = node.getSourceFile().fileName;
|
|
28883
|
+
// If the template is external, re-parse it.
|
|
28884
|
+
const templateDecl = analysis.template.declaration;
|
|
28885
|
+
if (!templateDecl.isInline) {
|
|
28886
|
+
analysis.template = this.extractTemplate(node, templateDecl);
|
|
28887
|
+
}
|
|
28888
|
+
// Update any external stylesheets and rebuild the combined 'styles' list.
|
|
28889
|
+
// TODO(alxhub): write tests for styles when the primary compiler uses the updateResources path
|
|
28890
|
+
let styles = [];
|
|
28891
|
+
if (analysis.styleUrls !== null) {
|
|
28892
|
+
for (const styleUrl of analysis.styleUrls) {
|
|
28893
|
+
const resolvedStyleUrl = this.resourceLoader.resolve(styleUrl, containingFile);
|
|
28894
|
+
const styleText = this.resourceLoader.load(resolvedStyleUrl);
|
|
28895
|
+
styles.push(styleText);
|
|
28896
|
+
}
|
|
28897
|
+
}
|
|
28898
|
+
if (analysis.inlineStyles !== null) {
|
|
28899
|
+
for (const styleText of analysis.inlineStyles) {
|
|
28900
|
+
styles.push(styleText);
|
|
28901
|
+
}
|
|
28902
|
+
}
|
|
28903
|
+
for (const styleText of analysis.template.styles) {
|
|
28904
|
+
styles.push(styleText);
|
|
28905
|
+
}
|
|
28906
|
+
analysis.meta.styles = styles;
|
|
28907
|
+
}
|
|
28834
28908
|
compileFull(node, analysis, resolution, pool) {
|
|
28835
28909
|
if (analysis.template.errors !== null && analysis.template.errors.length > 0) {
|
|
28836
28910
|
return [];
|
|
@@ -28937,7 +29011,8 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28937
29011
|
// URLs to resolve.
|
|
28938
29012
|
if (templatePromise !== undefined) {
|
|
28939
29013
|
return templatePromise.then(() => {
|
|
28940
|
-
const
|
|
29014
|
+
const templateDecl = this.parseTemplateDeclaration(decorator, component, containingFile);
|
|
29015
|
+
const template = this.extractTemplate(node, templateDecl);
|
|
28941
29016
|
this.preanalyzeTemplateCache.set(node, template);
|
|
28942
29017
|
return template;
|
|
28943
29018
|
});
|
|
@@ -28947,100 +29022,78 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28947
29022
|
}
|
|
28948
29023
|
}
|
|
28949
29024
|
else {
|
|
28950
|
-
const
|
|
29025
|
+
const templateDecl = this.parseTemplateDeclaration(decorator, component, containingFile);
|
|
29026
|
+
const template = this.extractTemplate(node, templateDecl);
|
|
28951
29027
|
this.preanalyzeTemplateCache.set(node, template);
|
|
28952
29028
|
return Promise.resolve(template);
|
|
28953
29029
|
}
|
|
28954
29030
|
}
|
|
28955
|
-
|
|
28956
|
-
|
|
28957
|
-
|
|
28958
|
-
|
|
28959
|
-
|
|
28960
|
-
|
|
28961
|
-
|
|
28962
|
-
|
|
28963
|
-
|
|
28964
|
-
|
|
28965
|
-
|
|
28966
|
-
node
|
|
28967
|
-
|
|
28968
|
-
|
|
28969
|
-
|
|
28970
|
-
|
|
28971
|
-
|
|
28972
|
-
|
|
28973
|
-
|
|
28974
|
-
|
|
28975
|
-
|
|
28976
|
-
|
|
28977
|
-
let templateLiteral = null;
|
|
28978
|
-
let templateUrl = '';
|
|
28979
|
-
let templateRange = undefined;
|
|
28980
|
-
let sourceMapping;
|
|
28981
|
-
let escapedString = false;
|
|
28982
|
-
// We only support SourceMaps for inline templates that are simple string literals.
|
|
28983
|
-
if (ts$1.isStringLiteral(templateExpr) || ts$1.isNoSubstitutionTemplateLiteral(templateExpr)) {
|
|
28984
|
-
// the start and end of the `templateExpr` node includes the quotation marks, which we
|
|
28985
|
-
// must
|
|
28986
|
-
// strip
|
|
28987
|
-
templateRange = getTemplateRange(templateExpr);
|
|
28988
|
-
templateStr = templateExpr.getSourceFile().text;
|
|
28989
|
-
templateLiteral = templateExpr;
|
|
28990
|
-
templateUrl = containingFile;
|
|
28991
|
-
escapedString = true;
|
|
28992
|
-
sourceMapping = {
|
|
28993
|
-
type: 'direct',
|
|
28994
|
-
node: templateExpr,
|
|
28995
|
-
};
|
|
28996
|
-
}
|
|
28997
|
-
else {
|
|
28998
|
-
const resolvedTemplate = this.evaluator.evaluate(templateExpr);
|
|
28999
|
-
if (typeof resolvedTemplate !== 'string') {
|
|
29000
|
-
throw createValueHasWrongTypeError(templateExpr, resolvedTemplate, 'template must be a string');
|
|
29001
|
-
}
|
|
29002
|
-
templateStr = resolvedTemplate;
|
|
29003
|
-
sourceMapping = {
|
|
29004
|
-
type: 'indirect',
|
|
29005
|
-
node: templateExpr,
|
|
29006
|
-
componentClass: node,
|
|
29007
|
-
template: templateStr,
|
|
29008
|
-
};
|
|
29009
|
-
}
|
|
29010
|
-
const template = this._parseTemplate(component, templateStr, templateLiteral, templateUrl, templateRange, escapedString);
|
|
29011
|
-
return Object.assign(Object.assign({}, template), { sourceMapping });
|
|
29012
|
-
}
|
|
29013
|
-
_parseTemplate(component, templateStr, templateLiteral, templateUrl, templateRange, escapedString) {
|
|
29014
|
-
let preserveWhitespaces = this.defaultPreserveWhitespaces;
|
|
29015
|
-
if (component.has('preserveWhitespaces')) {
|
|
29016
|
-
const expr = component.get('preserveWhitespaces');
|
|
29017
|
-
const value = this.evaluator.evaluate(expr);
|
|
29018
|
-
if (typeof value !== 'boolean') {
|
|
29019
|
-
throw createValueHasWrongTypeError(expr, value, 'preserveWhitespaces must be a boolean');
|
|
29031
|
+
extractTemplate(node, template) {
|
|
29032
|
+
if (template.isInline) {
|
|
29033
|
+
let templateStr;
|
|
29034
|
+
let templateLiteral = null;
|
|
29035
|
+
let templateUrl = '';
|
|
29036
|
+
let templateRange = null;
|
|
29037
|
+
let sourceMapping;
|
|
29038
|
+
let escapedString = false;
|
|
29039
|
+
// We only support SourceMaps for inline templates that are simple string literals.
|
|
29040
|
+
if (ts$1.isStringLiteral(template.expression) ||
|
|
29041
|
+
ts$1.isNoSubstitutionTemplateLiteral(template.expression)) {
|
|
29042
|
+
// the start and end of the `templateExpr` node includes the quotation marks, which we must
|
|
29043
|
+
// strip
|
|
29044
|
+
templateRange = getTemplateRange(template.expression);
|
|
29045
|
+
templateStr = template.expression.getSourceFile().text;
|
|
29046
|
+
templateLiteral = template.expression;
|
|
29047
|
+
templateUrl = template.templateUrl;
|
|
29048
|
+
escapedString = true;
|
|
29049
|
+
sourceMapping = {
|
|
29050
|
+
type: 'direct',
|
|
29051
|
+
node: template.expression,
|
|
29052
|
+
};
|
|
29020
29053
|
}
|
|
29021
|
-
|
|
29022
|
-
|
|
29023
|
-
|
|
29024
|
-
|
|
29025
|
-
|
|
29026
|
-
|
|
29027
|
-
|
|
29028
|
-
|
|
29029
|
-
|
|
29054
|
+
else {
|
|
29055
|
+
const resolvedTemplate = this.evaluator.evaluate(template.expression);
|
|
29056
|
+
if (typeof resolvedTemplate !== 'string') {
|
|
29057
|
+
throw createValueHasWrongTypeError(template.expression, resolvedTemplate, 'template must be a string');
|
|
29058
|
+
}
|
|
29059
|
+
templateStr = resolvedTemplate;
|
|
29060
|
+
sourceMapping = {
|
|
29061
|
+
type: 'indirect',
|
|
29062
|
+
node: template.expression,
|
|
29063
|
+
componentClass: node,
|
|
29064
|
+
template: templateStr,
|
|
29065
|
+
};
|
|
29030
29066
|
}
|
|
29031
|
-
|
|
29067
|
+
return Object.assign(Object.assign({}, this._parseTemplate(template, templateStr, templateRange, escapedString)), { sourceMapping, declaration: template });
|
|
29032
29068
|
}
|
|
29069
|
+
else {
|
|
29070
|
+
const templateStr = this.resourceLoader.load(template.resolvedTemplateUrl);
|
|
29071
|
+
if (this.depTracker !== null) {
|
|
29072
|
+
this.depTracker.addResourceDependency(node.getSourceFile(), absoluteFrom(template.resolvedTemplateUrl));
|
|
29073
|
+
}
|
|
29074
|
+
return Object.assign(Object.assign({}, this._parseTemplate(template, templateStr, /* templateRange */ null,
|
|
29075
|
+
/* escapedString */ false)), { sourceMapping: {
|
|
29076
|
+
type: 'external',
|
|
29077
|
+
componentClass: node,
|
|
29078
|
+
// TODO(alxhub): TS in g3 is unable to make this inference on its own, so cast it here
|
|
29079
|
+
// until g3 is able to figure this out.
|
|
29080
|
+
node: template.templateUrlExpression,
|
|
29081
|
+
template: templateStr,
|
|
29082
|
+
templateUrl: template.resolvedTemplateUrl,
|
|
29083
|
+
}, declaration: template });
|
|
29084
|
+
}
|
|
29085
|
+
}
|
|
29086
|
+
_parseTemplate(template, templateStr, templateRange, escapedString) {
|
|
29033
29087
|
// We always normalize line endings if the template has been escaped (i.e. is inline).
|
|
29034
29088
|
const i18nNormalizeLineEndingsInICUs = escapedString || this.i18nNormalizeLineEndingsInICUs;
|
|
29035
|
-
const
|
|
29036
|
-
|
|
29037
|
-
|
|
29038
|
-
|
|
29039
|
-
range: templateRange,
|
|
29089
|
+
const parsedTemplate = parseTemplate(templateStr, template.sourceMapUrl, {
|
|
29090
|
+
preserveWhitespaces: template.preserveWhitespaces,
|
|
29091
|
+
interpolationConfig: template.interpolationConfig,
|
|
29092
|
+
range: templateRange !== null && templateRange !== void 0 ? templateRange : undefined,
|
|
29040
29093
|
escapedString,
|
|
29041
29094
|
enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat,
|
|
29042
29095
|
i18nNormalizeLineEndingsInICUs,
|
|
29043
|
-
isInline,
|
|
29096
|
+
isInline: template.isInline,
|
|
29044
29097
|
});
|
|
29045
29098
|
// Unfortunately, the primary parse of the template above may not contain accurate source map
|
|
29046
29099
|
// information. If used directly, it would result in incorrect code locations in template
|
|
@@ -29054,18 +29107,69 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
29054
29107
|
//
|
|
29055
29108
|
// In order to guarantee the correctness of diagnostics, templates are parsed a second time
|
|
29056
29109
|
// with the above options set to preserve source mappings.
|
|
29057
|
-
const { nodes: diagNodes } = parseTemplate(templateStr,
|
|
29110
|
+
const { nodes: diagNodes } = parseTemplate(templateStr, template.sourceMapUrl, {
|
|
29058
29111
|
preserveWhitespaces: true,
|
|
29059
|
-
interpolationConfig,
|
|
29060
|
-
range: templateRange,
|
|
29112
|
+
interpolationConfig: template.interpolationConfig,
|
|
29113
|
+
range: templateRange !== null && templateRange !== void 0 ? templateRange : undefined,
|
|
29061
29114
|
escapedString,
|
|
29062
29115
|
enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat,
|
|
29063
29116
|
i18nNormalizeLineEndingsInICUs,
|
|
29064
29117
|
leadingTriviaChars: [],
|
|
29065
|
-
isInline,
|
|
29118
|
+
isInline: template.isInline,
|
|
29066
29119
|
});
|
|
29067
|
-
return Object.assign(Object.assign({}, parsedTemplate), { diagNodes, template:
|
|
29068
|
-
|
|
29120
|
+
return Object.assign(Object.assign({}, parsedTemplate), { diagNodes, template: template.isInline ? new WrappedNodeExpr(template.expression) : templateStr, templateUrl: template.resolvedTemplateUrl, isInline: template.isInline, file: new ParseSourceFile(templateStr, template.resolvedTemplateUrl) });
|
|
29121
|
+
}
|
|
29122
|
+
parseTemplateDeclaration(decorator, component, containingFile) {
|
|
29123
|
+
let preserveWhitespaces = this.defaultPreserveWhitespaces;
|
|
29124
|
+
if (component.has('preserveWhitespaces')) {
|
|
29125
|
+
const expr = component.get('preserveWhitespaces');
|
|
29126
|
+
const value = this.evaluator.evaluate(expr);
|
|
29127
|
+
if (typeof value !== 'boolean') {
|
|
29128
|
+
throw createValueHasWrongTypeError(expr, value, 'preserveWhitespaces must be a boolean');
|
|
29129
|
+
}
|
|
29130
|
+
preserveWhitespaces = value;
|
|
29131
|
+
}
|
|
29132
|
+
let interpolationConfig = DEFAULT_INTERPOLATION_CONFIG;
|
|
29133
|
+
if (component.has('interpolation')) {
|
|
29134
|
+
const expr = component.get('interpolation');
|
|
29135
|
+
const value = this.evaluator.evaluate(expr);
|
|
29136
|
+
if (!Array.isArray(value) || value.length !== 2 ||
|
|
29137
|
+
!value.every(element => typeof element === 'string')) {
|
|
29138
|
+
throw createValueHasWrongTypeError(expr, value, 'interpolation must be an array with 2 elements of string type');
|
|
29139
|
+
}
|
|
29140
|
+
interpolationConfig = InterpolationConfig.fromArray(value);
|
|
29141
|
+
}
|
|
29142
|
+
if (component.has('templateUrl')) {
|
|
29143
|
+
const templateUrlExpr = component.get('templateUrl');
|
|
29144
|
+
const templateUrl = this.evaluator.evaluate(templateUrlExpr);
|
|
29145
|
+
if (typeof templateUrl !== 'string') {
|
|
29146
|
+
throw createValueHasWrongTypeError(templateUrlExpr, templateUrl, 'templateUrl must be a string');
|
|
29147
|
+
}
|
|
29148
|
+
const resourceUrl = this.resourceLoader.resolve(templateUrl, containingFile);
|
|
29149
|
+
return {
|
|
29150
|
+
isInline: false,
|
|
29151
|
+
interpolationConfig,
|
|
29152
|
+
preserveWhitespaces,
|
|
29153
|
+
templateUrl,
|
|
29154
|
+
templateUrlExpression: templateUrlExpr,
|
|
29155
|
+
resolvedTemplateUrl: resourceUrl,
|
|
29156
|
+
sourceMapUrl: sourceMapUrl(resourceUrl),
|
|
29157
|
+
};
|
|
29158
|
+
}
|
|
29159
|
+
else if (component.has('template')) {
|
|
29160
|
+
return {
|
|
29161
|
+
isInline: true,
|
|
29162
|
+
interpolationConfig,
|
|
29163
|
+
preserveWhitespaces,
|
|
29164
|
+
expression: component.get('template'),
|
|
29165
|
+
templateUrl: containingFile,
|
|
29166
|
+
resolvedTemplateUrl: containingFile,
|
|
29167
|
+
sourceMapUrl: containingFile,
|
|
29168
|
+
};
|
|
29169
|
+
}
|
|
29170
|
+
else {
|
|
29171
|
+
throw new FatalDiagnosticError(ErrorCode.COMPONENT_MISSING_TEMPLATE, Decorator.nodeForError(decorator), 'component is missing a template');
|
|
29172
|
+
}
|
|
29069
29173
|
}
|
|
29070
29174
|
_expressionToImportedFile(expr, origin) {
|
|
29071
29175
|
if (!(expr instanceof ExternalExpr)) {
|
|
@@ -31308,6 +31412,12 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
31308
31412
|
this.cache.set(resolvedUrl, result);
|
|
31309
31413
|
return result;
|
|
31310
31414
|
}
|
|
31415
|
+
/**
|
|
31416
|
+
* Invalidate the entire resource cache.
|
|
31417
|
+
*/
|
|
31418
|
+
invalidate() {
|
|
31419
|
+
this.cache.clear();
|
|
31420
|
+
}
|
|
31311
31421
|
/**
|
|
31312
31422
|
* Attempt to resolve `url` in the context of `fromFile`, while respecting the rootDirs
|
|
31313
31423
|
* option from the tsconfig. First, normalize the file name.
|
|
@@ -37704,6 +37814,22 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
37704
37814
|
}
|
|
37705
37815
|
return engine.getExpressionCompletionLocation(ast);
|
|
37706
37816
|
}
|
|
37817
|
+
invalidateClass(clazz) {
|
|
37818
|
+
var _a;
|
|
37819
|
+
this.completionCache.delete(clazz);
|
|
37820
|
+
this.symbolBuilderCache.delete(clazz);
|
|
37821
|
+
this.scopeCache.delete(clazz);
|
|
37822
|
+
this.elementTagCache.delete(clazz);
|
|
37823
|
+
const sf = clazz.getSourceFile();
|
|
37824
|
+
const sfPath = absoluteFromSourceFile(sf);
|
|
37825
|
+
const shimPath = this.typeCheckingStrategy.shimPathForComponent(clazz);
|
|
37826
|
+
const fileData = this.getFileData(sfPath);
|
|
37827
|
+
const templateId = fileData.sourceManager.getTemplateId(clazz);
|
|
37828
|
+
fileData.shimData.delete(shimPath);
|
|
37829
|
+
fileData.isComplete = false;
|
|
37830
|
+
(_a = fileData.templateOverrides) === null || _a === void 0 ? void 0 : _a.delete(templateId);
|
|
37831
|
+
this.isComplete = false;
|
|
37832
|
+
}
|
|
37707
37833
|
getOrCreateCompletionEngine(component) {
|
|
37708
37834
|
if (this.completionCache.has(component)) {
|
|
37709
37835
|
return this.completionCache.get(component);
|
|
@@ -38089,6 +38215,54 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
38089
38215
|
* Use of this source code is governed by an MIT-style license that can be
|
|
38090
38216
|
* found in the LICENSE file at https://angular.io/license
|
|
38091
38217
|
*/
|
|
38218
|
+
/**
|
|
38219
|
+
* Discriminant type for a `CompilationTicket`.
|
|
38220
|
+
*/
|
|
38221
|
+
var CompilationTicketKind;
|
|
38222
|
+
(function (CompilationTicketKind) {
|
|
38223
|
+
CompilationTicketKind[CompilationTicketKind["Fresh"] = 0] = "Fresh";
|
|
38224
|
+
CompilationTicketKind[CompilationTicketKind["IncrementalTypeScript"] = 1] = "IncrementalTypeScript";
|
|
38225
|
+
CompilationTicketKind[CompilationTicketKind["IncrementalResource"] = 2] = "IncrementalResource";
|
|
38226
|
+
})(CompilationTicketKind || (CompilationTicketKind = {}));
|
|
38227
|
+
/**
|
|
38228
|
+
* Create a `CompilationTicket` for a brand new compilation, using no prior state.
|
|
38229
|
+
*/
|
|
38230
|
+
function freshCompilationTicket(tsProgram, options, incrementalBuildStrategy, typeCheckingProgramStrategy, enableTemplateTypeChecker, usePoisonedData) {
|
|
38231
|
+
return {
|
|
38232
|
+
kind: CompilationTicketKind.Fresh,
|
|
38233
|
+
tsProgram,
|
|
38234
|
+
options,
|
|
38235
|
+
incrementalBuildStrategy,
|
|
38236
|
+
typeCheckingProgramStrategy,
|
|
38237
|
+
enableTemplateTypeChecker,
|
|
38238
|
+
usePoisonedData,
|
|
38239
|
+
};
|
|
38240
|
+
}
|
|
38241
|
+
/**
|
|
38242
|
+
* Create a `CompilationTicket` as efficiently as possible, based on a previous `NgCompiler`
|
|
38243
|
+
* instance and a new `ts.Program`.
|
|
38244
|
+
*/
|
|
38245
|
+
function incrementalFromCompilerTicket(oldCompiler, newProgram, incrementalBuildStrategy, typeCheckingProgramStrategy, modifiedResourceFiles) {
|
|
38246
|
+
const oldProgram = oldCompiler.getNextProgram();
|
|
38247
|
+
const oldDriver = oldCompiler.incrementalStrategy.getIncrementalDriver(oldProgram);
|
|
38248
|
+
if (oldDriver === null) {
|
|
38249
|
+
// No incremental step is possible here, since no IncrementalDriver was found for the old
|
|
38250
|
+
// program.
|
|
38251
|
+
return freshCompilationTicket(newProgram, oldCompiler.options, incrementalBuildStrategy, typeCheckingProgramStrategy, oldCompiler.enableTemplateTypeChecker, oldCompiler.usePoisonedData);
|
|
38252
|
+
}
|
|
38253
|
+
const newDriver = IncrementalDriver.reconcile(oldProgram, oldDriver, newProgram, modifiedResourceFiles);
|
|
38254
|
+
return {
|
|
38255
|
+
kind: CompilationTicketKind.IncrementalTypeScript,
|
|
38256
|
+
enableTemplateTypeChecker: oldCompiler.enableTemplateTypeChecker,
|
|
38257
|
+
usePoisonedData: oldCompiler.usePoisonedData,
|
|
38258
|
+
options: oldCompiler.options,
|
|
38259
|
+
incrementalBuildStrategy,
|
|
38260
|
+
typeCheckingProgramStrategy,
|
|
38261
|
+
newDriver,
|
|
38262
|
+
oldProgram,
|
|
38263
|
+
newProgram,
|
|
38264
|
+
};
|
|
38265
|
+
}
|
|
38092
38266
|
/**
|
|
38093
38267
|
* The heart of the Angular Ivy compiler.
|
|
38094
38268
|
*
|
|
@@ -38102,12 +38276,13 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
38102
38276
|
* See the README.md for more information.
|
|
38103
38277
|
*/
|
|
38104
38278
|
class NgCompiler {
|
|
38105
|
-
constructor(adapter, options, tsProgram, typeCheckingProgramStrategy, incrementalStrategy, enableTemplateTypeChecker, usePoisonedData,
|
|
38279
|
+
constructor(adapter, options, tsProgram, typeCheckingProgramStrategy, incrementalStrategy, incrementalDriver, enableTemplateTypeChecker, usePoisonedData, perfRecorder = NOOP_PERF_RECORDER) {
|
|
38106
38280
|
this.adapter = adapter;
|
|
38107
38281
|
this.options = options;
|
|
38108
38282
|
this.tsProgram = tsProgram;
|
|
38109
38283
|
this.typeCheckingProgramStrategy = typeCheckingProgramStrategy;
|
|
38110
38284
|
this.incrementalStrategy = incrementalStrategy;
|
|
38285
|
+
this.incrementalDriver = incrementalDriver;
|
|
38111
38286
|
this.enableTemplateTypeChecker = enableTemplateTypeChecker;
|
|
38112
38287
|
this.usePoisonedData = usePoisonedData;
|
|
38113
38288
|
this.perfRecorder = perfRecorder;
|
|
@@ -38151,31 +38326,55 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
38151
38326
|
new ModuleResolver(tsProgram, this.options, this.adapter, moduleResolutionCache);
|
|
38152
38327
|
this.resourceManager = new AdapterResourceLoader(adapter, this.options);
|
|
38153
38328
|
this.cycleAnalyzer = new CycleAnalyzer(new ImportGraph(this.moduleResolver));
|
|
38154
|
-
let modifiedResourceFiles = null;
|
|
38155
|
-
if (this.adapter.getModifiedResourceFiles !== undefined) {
|
|
38156
|
-
modifiedResourceFiles = this.adapter.getModifiedResourceFiles() || null;
|
|
38157
|
-
}
|
|
38158
|
-
if (oldProgram === null) {
|
|
38159
|
-
this.incrementalDriver = IncrementalDriver.fresh(tsProgram);
|
|
38160
|
-
}
|
|
38161
|
-
else {
|
|
38162
|
-
const oldDriver = this.incrementalStrategy.getIncrementalDriver(oldProgram);
|
|
38163
|
-
if (oldDriver !== null) {
|
|
38164
|
-
this.incrementalDriver =
|
|
38165
|
-
IncrementalDriver.reconcile(oldProgram, oldDriver, tsProgram, modifiedResourceFiles);
|
|
38166
|
-
}
|
|
38167
|
-
else {
|
|
38168
|
-
// A previous ts.Program was used to create the current one, but it wasn't from an
|
|
38169
|
-
// `NgCompiler`. That doesn't hurt anything, but the Angular analysis will have to start
|
|
38170
|
-
// from a fresh state.
|
|
38171
|
-
this.incrementalDriver = IncrementalDriver.fresh(tsProgram);
|
|
38172
|
-
}
|
|
38173
|
-
}
|
|
38174
38329
|
this.incrementalStrategy.setIncrementalDriver(this.incrementalDriver, tsProgram);
|
|
38175
38330
|
this.ignoreForDiagnostics =
|
|
38176
38331
|
new Set(tsProgram.getSourceFiles().filter(sf => this.adapter.isShim(sf)));
|
|
38177
38332
|
this.ignoreForEmit = this.adapter.ignoreForEmit;
|
|
38178
38333
|
}
|
|
38334
|
+
/**
|
|
38335
|
+
* Convert a `CompilationTicket` into an `NgCompiler` instance for the requested compilation.
|
|
38336
|
+
*
|
|
38337
|
+
* Depending on the nature of the compilation request, the `NgCompiler` instance may be reused
|
|
38338
|
+
* from a previous compilation and updated with any changes, it may be a new instance which
|
|
38339
|
+
* incrementally reuses state from a previous compilation, or it may represent a fresh compilation
|
|
38340
|
+
* entirely.
|
|
38341
|
+
*/
|
|
38342
|
+
static fromTicket(ticket, adapter, perfRecorder) {
|
|
38343
|
+
switch (ticket.kind) {
|
|
38344
|
+
case CompilationTicketKind.Fresh:
|
|
38345
|
+
return new NgCompiler(adapter, ticket.options, ticket.tsProgram, ticket.typeCheckingProgramStrategy, ticket.incrementalBuildStrategy, IncrementalDriver.fresh(ticket.tsProgram), ticket.enableTemplateTypeChecker, ticket.usePoisonedData, perfRecorder);
|
|
38346
|
+
case CompilationTicketKind.IncrementalTypeScript:
|
|
38347
|
+
return new NgCompiler(adapter, ticket.options, ticket.newProgram, ticket.typeCheckingProgramStrategy, ticket.incrementalBuildStrategy, ticket.newDriver, ticket.enableTemplateTypeChecker, ticket.usePoisonedData, perfRecorder);
|
|
38348
|
+
case CompilationTicketKind.IncrementalResource:
|
|
38349
|
+
const compiler = ticket.compiler;
|
|
38350
|
+
compiler.updateWithChangedResources(ticket.modifiedResourceFiles);
|
|
38351
|
+
return compiler;
|
|
38352
|
+
}
|
|
38353
|
+
}
|
|
38354
|
+
updateWithChangedResources(changedResources) {
|
|
38355
|
+
if (this.compilation === null) {
|
|
38356
|
+
// Analysis hasn't happened yet, so no update is necessary - any changes to resources will be
|
|
38357
|
+
// captured by the inital analysis pass itself.
|
|
38358
|
+
return;
|
|
38359
|
+
}
|
|
38360
|
+
this.resourceManager.invalidate();
|
|
38361
|
+
const classesToUpdate = new Set();
|
|
38362
|
+
for (const resourceFile of changedResources) {
|
|
38363
|
+
for (const templateClass of this.getComponentsWithTemplateFile(resourceFile)) {
|
|
38364
|
+
classesToUpdate.add(templateClass);
|
|
38365
|
+
}
|
|
38366
|
+
for (const styleClass of this.getComponentsWithStyleFile(resourceFile)) {
|
|
38367
|
+
classesToUpdate.add(styleClass);
|
|
38368
|
+
}
|
|
38369
|
+
}
|
|
38370
|
+
for (const clazz of classesToUpdate) {
|
|
38371
|
+
this.compilation.traitCompiler.updateResources(clazz);
|
|
38372
|
+
if (!ts$1.isClassDeclaration(clazz)) {
|
|
38373
|
+
continue;
|
|
38374
|
+
}
|
|
38375
|
+
this.compilation.templateTypeChecker.invalidateClass(clazz);
|
|
38376
|
+
}
|
|
38377
|
+
}
|
|
38179
38378
|
/**
|
|
38180
38379
|
* Get the resource dependencies of a file.
|
|
38181
38380
|
*
|
|
@@ -38802,7 +39001,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
38802
39001
|
}
|
|
38803
39002
|
/**
|
|
38804
39003
|
* Since "strictTemplates" is a true superset of type checking capabilities compared to
|
|
38805
|
-
* "
|
|
39004
|
+
* "fullTemplateTypeCheck", it is required that the latter is not explicitly disabled if the
|
|
38806
39005
|
* former is enabled.
|
|
38807
39006
|
*/
|
|
38808
39007
|
function verifyCompatibleTypeCheckOptions(options) {
|
|
@@ -39472,6 +39671,14 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
39472
39671
|
getCanonicalFileName(fileName) {
|
|
39473
39672
|
return this.project.projectService.toCanonicalFileName(fileName);
|
|
39474
39673
|
}
|
|
39674
|
+
/**
|
|
39675
|
+
* Return the real path of a symlink. This method is required in order to
|
|
39676
|
+
* resolve symlinks in node_modules.
|
|
39677
|
+
*/
|
|
39678
|
+
realpath(path) {
|
|
39679
|
+
var _a, _b, _c;
|
|
39680
|
+
return (_c = (_b = (_a = this.project).realpath) === null || _b === void 0 ? void 0 : _b.call(_a, path)) !== null && _c !== void 0 ? _c : path;
|
|
39681
|
+
}
|
|
39475
39682
|
/**
|
|
39476
39683
|
* readResource() is an Angular-specific method for reading files that are not
|
|
39477
39684
|
* managed by the TS compiler host, namely templates and stylesheets.
|
|
@@ -39582,11 +39789,14 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
39582
39789
|
getOrCreate() {
|
|
39583
39790
|
const program = this.programStrategy.getProgram();
|
|
39584
39791
|
if (this.compiler === null || program !== this.lastKnownProgram) {
|
|
39585
|
-
|
|
39586
|
-
this.
|
|
39587
|
-
|
|
39588
|
-
|
|
39589
|
-
|
|
39792
|
+
let ticket;
|
|
39793
|
+
if (this.compiler === null || this.lastKnownProgram === null) {
|
|
39794
|
+
ticket = freshCompilationTicket(program, this.options, this.incrementalStrategy, this.programStrategy, true, true);
|
|
39795
|
+
}
|
|
39796
|
+
else {
|
|
39797
|
+
ticket = incrementalFromCompilerTicket(this.compiler, program, this.incrementalStrategy, this.programStrategy, new Set());
|
|
39798
|
+
}
|
|
39799
|
+
this.compiler = NgCompiler.fromTicket(ticket, this.adapter);
|
|
39590
39800
|
this.lastKnownProgram = program;
|
|
39591
39801
|
}
|
|
39592
39802
|
return this.compiler;
|
|
@@ -41522,6 +41732,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
41522
41732
|
*/
|
|
41523
41733
|
class LanguageService {
|
|
41524
41734
|
constructor(project, tsLS) {
|
|
41735
|
+
this.project = project;
|
|
41525
41736
|
this.tsLS = tsLS;
|
|
41526
41737
|
this.parseConfigHost = new LSParseConfigHost(project.projectService.host);
|
|
41527
41738
|
this.options = parseNgCompilerOptions(project, this.parseConfigHost);
|
|
@@ -41638,6 +41849,28 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
41638
41849
|
this.compilerFactory.registerLastKnownProgram();
|
|
41639
41850
|
return result;
|
|
41640
41851
|
}
|
|
41852
|
+
getCompilerOptionsDiagnostics() {
|
|
41853
|
+
const project = this.project;
|
|
41854
|
+
if (!(project instanceof ts.server.ConfiguredProject)) {
|
|
41855
|
+
return [];
|
|
41856
|
+
}
|
|
41857
|
+
const diagnostics = [];
|
|
41858
|
+
const configSourceFile = ts.readJsonConfigFile(project.getConfigFilePath(), (path) => project.readFile(path));
|
|
41859
|
+
if (!this.options.strictTemplates && !this.options.fullTemplateTypeCheck) {
|
|
41860
|
+
diagnostics.push({
|
|
41861
|
+
messageText: 'Some language features are not available. ' +
|
|
41862
|
+
'To access all features, enable `strictTemplates` in `angularCompilerOptions`.',
|
|
41863
|
+
category: ts.DiagnosticCategory.Suggestion,
|
|
41864
|
+
code: ngErrorCode(ErrorCode.SUGGEST_STRICT_TEMPLATES),
|
|
41865
|
+
file: configSourceFile,
|
|
41866
|
+
start: undefined,
|
|
41867
|
+
length: undefined,
|
|
41868
|
+
});
|
|
41869
|
+
}
|
|
41870
|
+
const compiler = this.compilerFactory.getOrCreate();
|
|
41871
|
+
diagnostics.push(...compiler.getOptionDiagnostics());
|
|
41872
|
+
return diagnostics;
|
|
41873
|
+
}
|
|
41641
41874
|
watchConfigFile(project) {
|
|
41642
41875
|
// TODO: Check the case when the project is disposed. An InferredProject
|
|
41643
41876
|
// could be disposed when a tsconfig.json is added to the workspace,
|
|
@@ -41838,6 +42071,17 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
41838
42071
|
return (_a = tsLS.getCompletionEntrySymbol(fileName, position, name, source)) !== null && _a !== void 0 ? _a : ngLS.getCompletionEntrySymbol(fileName, position, name);
|
|
41839
42072
|
}
|
|
41840
42073
|
}
|
|
42074
|
+
/**
|
|
42075
|
+
* Gets global diagnostics related to the program configuration and compiler options.
|
|
42076
|
+
*/
|
|
42077
|
+
function getCompilerOptionsDiagnostics() {
|
|
42078
|
+
const diagnostics = [];
|
|
42079
|
+
if (!angularOnly) {
|
|
42080
|
+
diagnostics.push(...tsLS.getCompilerOptionsDiagnostics());
|
|
42081
|
+
}
|
|
42082
|
+
diagnostics.push(...ngLS.getCompilerOptionsDiagnostics());
|
|
42083
|
+
return diagnostics;
|
|
42084
|
+
}
|
|
41841
42085
|
return Object.assign(Object.assign({}, tsLS), { getSemanticDiagnostics,
|
|
41842
42086
|
getTypeDefinitionAtPosition,
|
|
41843
42087
|
getQuickInfoAtPosition,
|
|
@@ -41846,7 +42090,8 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
41846
42090
|
findRenameLocations,
|
|
41847
42091
|
getCompletionsAtPosition,
|
|
41848
42092
|
getCompletionEntryDetails,
|
|
41849
|
-
getCompletionEntrySymbol
|
|
42093
|
+
getCompletionEntrySymbol,
|
|
42094
|
+
getCompilerOptionsDiagnostics });
|
|
41850
42095
|
}
|
|
41851
42096
|
function getExternalFiles(project) {
|
|
41852
42097
|
if (!project.hasRoots()) {
|