@angular/language-service 13.0.0-next.2 → 13.0.0-next.6
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.ts +2 -0
- package/api.js +1 -1
- package/bundles/ivy.js +370 -25
- package/bundles/language-service.js +11 -870
- package/package.json +1 -1
package/api.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export declare type GetTcbResponse = {
|
|
|
48
48
|
selections: ts.TextSpan[];
|
|
49
49
|
};
|
|
50
50
|
export declare type GetComponentLocationsForTemplateResponse = ts.DocumentSpan[];
|
|
51
|
+
export declare type GetTemplateLocationForComponentResponse = ts.DocumentSpan | undefined;
|
|
51
52
|
/**
|
|
52
53
|
* `NgLanguageService` describes an instance of an Angular language service,
|
|
53
54
|
* whose API surface is a strict superset of TypeScript's language service.
|
|
@@ -55,5 +56,6 @@ export declare type GetComponentLocationsForTemplateResponse = ts.DocumentSpan[]
|
|
|
55
56
|
export interface NgLanguageService extends ts.LanguageService {
|
|
56
57
|
getTcb(fileName: string, position: number): GetTcbResponse | undefined;
|
|
57
58
|
getComponentLocationsForTemplate(fileName: string): GetComponentLocationsForTemplateResponse;
|
|
59
|
+
getTemplateLocationForComponent(fileName: string, position: number): GetTemplateLocationForComponentResponse;
|
|
58
60
|
}
|
|
59
61
|
export declare function isNgLanguageService(ls: ts.LanguageService | NgLanguageService): ls is NgLanguageService;
|
package/api.js
CHANGED
|
@@ -22,4 +22,4 @@
|
|
|
22
22
|
}
|
|
23
23
|
exports.isNgLanguageService = isNgLanguageService;
|
|
24
24
|
});
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbGFuZ3VhZ2Utc2VydmljZS9hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HOzs7Ozs7Ozs7Ozs7O0lBNkRILFNBQWdCLG1CQUFtQixDQUFDLEVBQ2lCO1FBQ25ELE9BQU8sUUFBUSxJQUFJLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBSEQsa0RBR0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLyoqXG4gKiBAbW9kdWxlXG4gKiBAZGVzY3JpcHRpb25cbiAqIEVudHJ5IHBvaW50IGZvciBhbGwgcHVibGljIEFQSXMgb2YgdGhlIGxhbmd1YWdlIHNlcnZpY2UgcGFja2FnZS5cbiAqL1xuXG5pbXBvcnQgKiBhcyB0cyBmcm9tICd0eXBlc2NyaXB0JztcblxuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5Db25maWcge1xuICAvKipcbiAgICogSWYgdHJ1ZSwgcmV0dXJuIG9ubHkgQW5ndWxhciByZXN1bHRzLiBPdGhlcndpc2UsIHJldHVybiBBbmd1bGFyICsgVHlwZVNjcmlwdFxuICAgKiByZXN1bHRzLlxuICAgKi9cbiAgYW5ndWxhck9ubHk6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBJZiB0cnVlLCByZXR1cm4gZmFjdG9yeSBmdW5jdGlvbiBmb3IgSXZ5IExTIGR1cmluZyBwbHVnaW4gaW5pdGlhbGl6YXRpb24uXG4gICAqIE90aGVyd2lzZSByZXR1cm4gZmFjdG9yeSBmdW5jdGlvbiBmb3IgVmlldyBFbmdpbmUgTFMuXG4gICAqL1xuICBpdnk6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBJZiB0cnVlLCBlbmFibGUgYHN0cmljdFRlbXBsYXRlc2AgaW4gQW5ndWxhciBjb21waWxlciBvcHRpb25zIHJlZ2FyZGxlc3NcbiAgICogb2YgaXRzIHZhbHVlIGluIHRzY29uZmlnLmpzb24uXG4gICAqL1xuICBmb3JjZVN0cmljdFRlbXBsYXRlcz86IHRydWU7XG59XG5cbmV4cG9ydCB0eXBlIEdldFRjYlJlc3BvbnNlID0ge1xuICAvKipcbiAgICogVGhlIGZpbGVuYW1lIG9mIHRoZSBTb3VyY2VGaWxlIHRoaXMgdHlwZWNoZWNrIGJsb2NrIGJlbG9uZ3MgdG8uXG4gICAqIFRoZSBmaWxlbmFtZSBpcyBlbnRpcmVseSBvcGFxdWUgYW5kIHVuc3RhYmxlLCB1c2VmdWwgb25seSBmb3IgZGVidWdnaW5nXG4gICAqIHB1cnBvc2VzLlxuICAgKi9cbiAgZmlsZU5hbWU6IHN0cmluZyxcbiAgLyoqIFRoZSBjb250ZW50IG9mIHRoZSBTb3VyY2VGaWxlIHRoaXMgdHlwZWNoZWNrIGJsb2NrIGJlbG9uZ3MgdG8uICovXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgLyoqXG4gICAqIFNwYW5zIG92ZXIgbm9kZShzKSBpbiB0aGUgdHlwZWNoZWNrIGJsb2NrIGNvcnJlc3BvbmRpbmcgdG8gdGhlXG4gICAqIFRTIGNvZGUgZ2VuZXJhdGVkIGZvciB0ZW1wbGF0ZSBub2RlIHVuZGVyIHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvbi5cbiAgICpcbiAgICogV2hlbiB0aGUgY3Vyc29yIHBvc2l0aW9uIGlzIG92ZXIgYSBzb3VyY2UgZm9yIHdoaWNoIHRoZXJlIGlzIG5vIGdlbmVyYXRlZFxuICAgKiBjb2RlLCBgc2VsZWN0aW9uc2AgaXMgZW1wdHkuXG4gICAqL1xuICBzZWxlY3Rpb25zOiB0cy5UZXh0U3BhbltdLFxufTtcblxuZXhwb3J0IHR5cGUgR2V0Q29tcG9uZW50TG9jYXRpb25zRm9yVGVtcGxhdGVSZXNwb25zZSA9IHRzLkRvY3VtZW50U3BhbltdO1xuZXhwb3J0IHR5cGUgR2V0VGVtcGxhdGVMb2NhdGlvbkZvckNvbXBvbmVudFJlc3BvbnNlID0gdHMuRG9jdW1lbnRTcGFufHVuZGVmaW5lZDtcblxuLyoqXG4gKiBgTmdMYW5ndWFnZVNlcnZpY2VgIGRlc2NyaWJlcyBhbiBpbnN0YW5jZSBvZiBhbiBBbmd1bGFyIGxhbmd1YWdlIHNlcnZpY2UsXG4gKiB3aG9zZSBBUEkgc3VyZmFjZSBpcyBhIHN0cmljdCBzdXBlcnNldCBvZiBUeXBlU2NyaXB0J3MgbGFuZ3VhZ2Ugc2VydmljZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBOZ0xhbmd1YWdlU2VydmljZSBleHRlbmRzIHRzLkxhbmd1YWdlU2VydmljZSB7XG4gIGdldFRjYihmaWxlTmFtZTogc3RyaW5nLCBwb3NpdGlvbjogbnVtYmVyKTogR2V0VGNiUmVzcG9uc2V8dW5kZWZpbmVkO1xuICBnZXRDb21wb25lbnRMb2NhdGlvbnNGb3JUZW1wbGF0ZShmaWxlTmFtZTogc3RyaW5nKTogR2V0Q29tcG9uZW50TG9jYXRpb25zRm9yVGVtcGxhdGVSZXNwb25zZTtcbiAgZ2V0VGVtcGxhdGVMb2NhdGlvbkZvckNvbXBvbmVudChmaWxlTmFtZTogc3RyaW5nLCBwb3NpdGlvbjogbnVtYmVyKTpcbiAgICAgIEdldFRlbXBsYXRlTG9jYXRpb25Gb3JDb21wb25lbnRSZXNwb25zZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTmdMYW5ndWFnZVNlcnZpY2UobHM6IHRzLkxhbmd1YWdlU2VydmljZXxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5nTGFuZ3VhZ2VTZXJ2aWNlKTogbHMgaXMgTmdMYW5ndWFnZVNlcnZpY2Uge1xuICByZXR1cm4gJ2dldFRjYicgaW4gbHM7XG59XG4iXX0=
|
package/bundles/ivy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v13.0.0-next.
|
|
2
|
+
* @license Angular v13.0.0-next.6
|
|
3
3
|
* Copyright Google LLC All Rights Reserved.
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -19938,7 +19938,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
19938
19938
|
* Use of this source code is governed by an MIT-style license that can be
|
|
19939
19939
|
* found in the LICENSE file at https://angular.io/license
|
|
19940
19940
|
*/
|
|
19941
|
-
const VERSION$1 = new Version('13.0.0-next.
|
|
19941
|
+
const VERSION$1 = new Version('13.0.0-next.6');
|
|
19942
19942
|
|
|
19943
19943
|
/**
|
|
19944
19944
|
* @license
|
|
@@ -20577,7 +20577,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20577
20577
|
function compileDeclareClassMetadata(metadata) {
|
|
20578
20578
|
const definitionMap = new DefinitionMap();
|
|
20579
20579
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
20580
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20580
|
+
definitionMap.set('version', literal('13.0.0-next.6'));
|
|
20581
20581
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20582
20582
|
definitionMap.set('type', metadata.type);
|
|
20583
20583
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -20617,7 +20617,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20617
20617
|
function createDirectiveDefinitionMap(meta) {
|
|
20618
20618
|
const definitionMap = new DefinitionMap();
|
|
20619
20619
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
20620
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20620
|
+
definitionMap.set('version', literal('13.0.0-next.6'));
|
|
20621
20621
|
// e.g. `type: MyDirective`
|
|
20622
20622
|
definitionMap.set('type', meta.internalType);
|
|
20623
20623
|
// e.g. `selector: 'some-dir'`
|
|
@@ -20834,7 +20834,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20834
20834
|
function compileDeclareFactoryFunction(meta) {
|
|
20835
20835
|
const definitionMap = new DefinitionMap();
|
|
20836
20836
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
20837
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20837
|
+
definitionMap.set('version', literal('13.0.0-next.6'));
|
|
20838
20838
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20839
20839
|
definitionMap.set('type', meta.internalType);
|
|
20840
20840
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -20876,7 +20876,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20876
20876
|
function createInjectableDefinitionMap(meta) {
|
|
20877
20877
|
const definitionMap = new DefinitionMap();
|
|
20878
20878
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
20879
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20879
|
+
definitionMap.set('version', literal('13.0.0-next.6'));
|
|
20880
20880
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20881
20881
|
definitionMap.set('type', meta.internalType);
|
|
20882
20882
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -20955,7 +20955,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20955
20955
|
function createInjectorDefinitionMap(meta) {
|
|
20956
20956
|
const definitionMap = new DefinitionMap();
|
|
20957
20957
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
20958
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20958
|
+
definitionMap.set('version', literal('13.0.0-next.6'));
|
|
20959
20959
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20960
20960
|
definitionMap.set('type', meta.internalType);
|
|
20961
20961
|
definitionMap.set('providers', meta.providers);
|
|
@@ -20992,7 +20992,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20992
20992
|
function createNgModuleDefinitionMap(meta) {
|
|
20993
20993
|
const definitionMap = new DefinitionMap();
|
|
20994
20994
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
20995
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20995
|
+
definitionMap.set('version', literal('13.0.0-next.6'));
|
|
20996
20996
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20997
20997
|
definitionMap.set('type', meta.internalType);
|
|
20998
20998
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -21050,7 +21050,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21050
21050
|
function createPipeDefinitionMap(meta) {
|
|
21051
21051
|
const definitionMap = new DefinitionMap();
|
|
21052
21052
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
|
|
21053
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
21053
|
+
definitionMap.set('version', literal('13.0.0-next.6'));
|
|
21054
21054
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
21055
21055
|
// e.g. `type: MyPipe`
|
|
21056
21056
|
definitionMap.set('type', meta.internalType);
|
|
@@ -21082,7 +21082,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21082
21082
|
* Use of this source code is governed by an MIT-style license that can be
|
|
21083
21083
|
* found in the LICENSE file at https://angular.io/license
|
|
21084
21084
|
*/
|
|
21085
|
-
const VERSION$2 = new Version('13.0.0-next.
|
|
21085
|
+
const VERSION$2 = new Version('13.0.0-next.6');
|
|
21086
21086
|
|
|
21087
21087
|
/**
|
|
21088
21088
|
* @license
|
|
@@ -21294,6 +21294,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21294
21294
|
* ```
|
|
21295
21295
|
*/
|
|
21296
21296
|
ErrorCode[ErrorCode["INVALID_BANANA_IN_BOX"] = 8101] = "INVALID_BANANA_IN_BOX";
|
|
21297
|
+
/**
|
|
21298
|
+
* The left side of a nullish coalescing operation is not nullable.
|
|
21299
|
+
*
|
|
21300
|
+
* ```
|
|
21301
|
+
* {{ foo ?? bar }}
|
|
21302
|
+
* ```
|
|
21303
|
+
* When the type of foo doesn't include `null` or `undefined`.
|
|
21304
|
+
*/
|
|
21305
|
+
ErrorCode[ErrorCode["NULLISH_COALESCING_NOT_NULLABLE"] = 8102] = "NULLISH_COALESCING_NOT_NULLABLE";
|
|
21297
21306
|
/**
|
|
21298
21307
|
* The template type-checking engine would need to generate an inline type check block for a
|
|
21299
21308
|
* component, but the current type-checking environment doesn't support it.
|
|
@@ -26546,6 +26555,26 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
26546
26555
|
}
|
|
26547
26556
|
}
|
|
26548
26557
|
}
|
|
26558
|
+
extendedTemplateCheck(sf, extendedTemplateChecker) {
|
|
26559
|
+
const classes = this.fileToClasses.get(sf);
|
|
26560
|
+
if (classes === undefined) {
|
|
26561
|
+
return [];
|
|
26562
|
+
}
|
|
26563
|
+
const diagnostics = [];
|
|
26564
|
+
for (const clazz of classes) {
|
|
26565
|
+
if (!isNamedClassDeclaration(clazz)) {
|
|
26566
|
+
continue;
|
|
26567
|
+
}
|
|
26568
|
+
const record = this.classes.get(clazz);
|
|
26569
|
+
for (const trait of record.traits) {
|
|
26570
|
+
if (trait.handler.extendedTemplateCheck === undefined) {
|
|
26571
|
+
continue;
|
|
26572
|
+
}
|
|
26573
|
+
diagnostics.push(...trait.handler.extendedTemplateCheck(clazz, extendedTemplateChecker));
|
|
26574
|
+
}
|
|
26575
|
+
}
|
|
26576
|
+
return diagnostics;
|
|
26577
|
+
}
|
|
26549
26578
|
index(ctx) {
|
|
26550
26579
|
for (const clazz of this.classes.keys()) {
|
|
26551
26580
|
const record = this.classes.get(clazz);
|
|
@@ -28777,7 +28806,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28777
28806
|
* If no such metadata is present, this function returns `null`. Otherwise, the call is returned
|
|
28778
28807
|
* as a `Statement` for inclusion along with the class.
|
|
28779
28808
|
*/
|
|
28780
|
-
function extractClassMetadata(clazz, reflection, isCore, annotateForClosureCompiler) {
|
|
28809
|
+
function extractClassMetadata(clazz, reflection, isCore, annotateForClosureCompiler, angularDecoratorTransform = dec => dec) {
|
|
28781
28810
|
if (!reflection.isClass(clazz)) {
|
|
28782
28811
|
return null;
|
|
28783
28812
|
}
|
|
@@ -28789,7 +28818,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28789
28818
|
return null;
|
|
28790
28819
|
}
|
|
28791
28820
|
const ngClassDecorators = classDecorators.filter(dec => isAngularDecorator$1(dec, isCore))
|
|
28792
|
-
.map(decorator => decoratorToMetadata(decorator, annotateForClosureCompiler))
|
|
28821
|
+
.map(decorator => decoratorToMetadata(angularDecoratorTransform(decorator), annotateForClosureCompiler))
|
|
28793
28822
|
// Since the `setClassMetadata` call is intended to be emitted after the class
|
|
28794
28823
|
// declaration, we have to strip references to the existing identifiers or
|
|
28795
28824
|
// TypeScript might generate invalid code when it emits to JS. In particular
|
|
@@ -28892,8 +28921,8 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
28892
28921
|
}
|
|
28893
28922
|
/**
|
|
28894
28923
|
* Recursively recreates all of the `Identifier` descendant nodes with a particular name inside
|
|
28895
|
-
* of an AST node, thus removing any references to them. Useful if a particular node has to be
|
|
28896
|
-
*
|
|
28924
|
+
* of an AST node, thus removing any references to them. Useful if a particular node has to be
|
|
28925
|
+
* taken from one place any emitted to another one exactly as it has been written.
|
|
28897
28926
|
*/
|
|
28898
28927
|
function removeIdentifierReferences(node, name) {
|
|
28899
28928
|
const result = ts$1.transform(node, [context => root => ts$1.visitNode(root, function walk(current) {
|
|
@@ -30476,7 +30505,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30476
30505
|
// analyzed and the full compilation scope for the component can be realized.
|
|
30477
30506
|
animations, viewProviders: wrappedViewProviders, i18nUseExternalIds: this.i18nUseExternalIds, relativeContextFilePath }),
|
|
30478
30507
|
typeCheckMeta: extractDirectiveTypeCheckMeta(node, inputs, this.reflector),
|
|
30479
|
-
classMetadata: extractClassMetadata(node, this.reflector, this.isCore, this.annotateForClosureCompiler),
|
|
30508
|
+
classMetadata: extractClassMetadata(node, this.reflector, this.isCore, this.annotateForClosureCompiler, dec => this._transformDecoratorToInlineResources(dec, component, styles, template)),
|
|
30480
30509
|
template,
|
|
30481
30510
|
providersRequiringFactory,
|
|
30482
30511
|
viewProvidersRequiringFactory,
|
|
@@ -30553,6 +30582,9 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30553
30582
|
const binder = new R3TargetBinder(scope.matcher);
|
|
30554
30583
|
ctx.addTemplate(new Reference$1(node), binder, meta.template.diagNodes, scope.pipes, scope.schemas, meta.template.sourceMapping, meta.template.file, meta.template.errors);
|
|
30555
30584
|
}
|
|
30585
|
+
extendedTemplateCheck(component, extendedTemplateChecker) {
|
|
30586
|
+
return extendedTemplateChecker.getDiagnosticsForComponent(component);
|
|
30587
|
+
}
|
|
30556
30588
|
resolve(node, analysis, symbol) {
|
|
30557
30589
|
if (this.semanticDepGraphUpdater !== null && analysis.baseClass instanceof Reference$1) {
|
|
30558
30590
|
symbol.baseClass = this.semanticDepGraphUpdater.getSymbol(analysis.baseClass.node);
|
|
@@ -30774,6 +30806,46 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30774
30806
|
null;
|
|
30775
30807
|
return compileResults(fac, def, classMetadata, 'ɵcmp');
|
|
30776
30808
|
}
|
|
30809
|
+
/**
|
|
30810
|
+
* Transforms the given decorator to inline external resources. i.e. if the decorator
|
|
30811
|
+
* resolves to `@Component`, the `templateUrl` and `styleUrls` metadata fields will be
|
|
30812
|
+
* transformed to their semantically-equivalent inline variants.
|
|
30813
|
+
*
|
|
30814
|
+
* This method is used for serializing decorators into the class metadata. The emitted
|
|
30815
|
+
* class metadata should not refer to external resources as this would be inconsistent
|
|
30816
|
+
* with the component definitions/declarations which already inline external resources.
|
|
30817
|
+
*
|
|
30818
|
+
* Additionally, the references to external resources would require libraries to ship
|
|
30819
|
+
* external resources exclusively for the class metadata.
|
|
30820
|
+
*/
|
|
30821
|
+
_transformDecoratorToInlineResources(dec, component, styles, template) {
|
|
30822
|
+
if (dec.name !== 'Component') {
|
|
30823
|
+
return dec;
|
|
30824
|
+
}
|
|
30825
|
+
// If no external resources are referenced, preserve the original decorator
|
|
30826
|
+
// for the best source map experience when the decorator is emitted in TS.
|
|
30827
|
+
if (!component.has('templateUrl') && !component.has('styleUrls')) {
|
|
30828
|
+
return dec;
|
|
30829
|
+
}
|
|
30830
|
+
const metadata = new Map(component);
|
|
30831
|
+
// Set the `template` property if the `templateUrl` property is set.
|
|
30832
|
+
if (metadata.has('templateUrl')) {
|
|
30833
|
+
metadata.delete('templateUrl');
|
|
30834
|
+
metadata.set('template', ts$1.createStringLiteral(template.content));
|
|
30835
|
+
}
|
|
30836
|
+
// Set the `styles` property if the `styleUrls` property is set.
|
|
30837
|
+
if (metadata.has('styleUrls')) {
|
|
30838
|
+
metadata.delete('styleUrls');
|
|
30839
|
+
metadata.set('styles', ts$1.createArrayLiteral(styles.map(s => ts$1.createStringLiteral(s))));
|
|
30840
|
+
}
|
|
30841
|
+
// Convert the metadata to TypeScript AST object literal element nodes.
|
|
30842
|
+
const newMetadataFields = [];
|
|
30843
|
+
for (const [name, value] of metadata.entries()) {
|
|
30844
|
+
newMetadataFields.push(ts$1.createPropertyAssignment(name, value));
|
|
30845
|
+
}
|
|
30846
|
+
// Return the original decorator with the overridden metadata argument.
|
|
30847
|
+
return Object.assign(Object.assign({}, dec), { args: [ts$1.createObjectLiteral(newMetadataFields)] });
|
|
30848
|
+
}
|
|
30777
30849
|
_resolveLiteral(decorator) {
|
|
30778
30850
|
if (this.literalCache.has(decorator)) {
|
|
30779
30851
|
return this.literalCache.get(decorator);
|
|
@@ -39731,7 +39803,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
39731
39803
|
const fileRecord = this.state.get(sfPath);
|
|
39732
39804
|
const templateId = fileRecord.sourceManager.getTemplateId(clazz);
|
|
39733
39805
|
const mapping = fileRecord.sourceManager.getSourceMapping(templateId);
|
|
39734
|
-
return makeTemplateDiagnostic(templateId, mapping, sourceSpan, category, errorCode, message, relatedInformation);
|
|
39806
|
+
return Object.assign(Object.assign({}, makeTemplateDiagnostic(templateId, mapping, sourceSpan, category, ngErrorCode(errorCode), message, relatedInformation)), { __ngCode: errorCode });
|
|
39735
39807
|
}
|
|
39736
39808
|
getOrCreateCompletionEngine(component) {
|
|
39737
39809
|
if (this.completionCache.has(component)) {
|
|
@@ -40093,6 +40165,195 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40093
40165
|
}
|
|
40094
40166
|
}
|
|
40095
40167
|
|
|
40168
|
+
/**
|
|
40169
|
+
* @license
|
|
40170
|
+
* Copyright Google LLC All Rights Reserved.
|
|
40171
|
+
*
|
|
40172
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
40173
|
+
* found in the LICENSE file at https://angular.io/license
|
|
40174
|
+
*/
|
|
40175
|
+
class ExtendedTemplateCheckerImpl {
|
|
40176
|
+
constructor(templateTypeChecker, typeChecker, templateChecks) {
|
|
40177
|
+
this.templateChecks = templateChecks;
|
|
40178
|
+
this.ctx = { templateTypeChecker: templateTypeChecker, typeChecker: typeChecker };
|
|
40179
|
+
}
|
|
40180
|
+
getDiagnosticsForComponent(component) {
|
|
40181
|
+
const template = this.ctx.templateTypeChecker.getTemplate(component);
|
|
40182
|
+
// Skip checks if component has no template. This can happen if the user writes a
|
|
40183
|
+
// `@Component()` but doesn't add the template, could happen in the language service
|
|
40184
|
+
// when users are in the middle of typing code.
|
|
40185
|
+
if (template === null) {
|
|
40186
|
+
return [];
|
|
40187
|
+
}
|
|
40188
|
+
const diagnostics = [];
|
|
40189
|
+
for (const check of this.templateChecks) {
|
|
40190
|
+
diagnostics.push(...check.run(this.ctx, component, template));
|
|
40191
|
+
}
|
|
40192
|
+
return diagnostics;
|
|
40193
|
+
}
|
|
40194
|
+
}
|
|
40195
|
+
|
|
40196
|
+
/**
|
|
40197
|
+
* @license
|
|
40198
|
+
* Copyright Google LLC All Rights Reserved.
|
|
40199
|
+
*
|
|
40200
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
40201
|
+
* found in the LICENSE file at https://angular.io/license
|
|
40202
|
+
*/
|
|
40203
|
+
/**
|
|
40204
|
+
* This abstract class provides a base implementation for the run method.
|
|
40205
|
+
*/
|
|
40206
|
+
class TemplateCheckWithVisitor {
|
|
40207
|
+
/**
|
|
40208
|
+
* Base implementation for run function, visits all nodes in template and calls
|
|
40209
|
+
* `visitNode()` for each one.
|
|
40210
|
+
*/
|
|
40211
|
+
run(ctx, component, template) {
|
|
40212
|
+
const visitor = new TemplateVisitor$1(ctx, component, this);
|
|
40213
|
+
return visitor.getDiagnostics(template);
|
|
40214
|
+
}
|
|
40215
|
+
}
|
|
40216
|
+
/**
|
|
40217
|
+
* Visits all nodes in a template (TmplAstNode and AST) and calls `visitNode` for each one.
|
|
40218
|
+
*/
|
|
40219
|
+
class TemplateVisitor$1 extends RecursiveAstVisitor {
|
|
40220
|
+
constructor(ctx, component, check) {
|
|
40221
|
+
super();
|
|
40222
|
+
this.ctx = ctx;
|
|
40223
|
+
this.component = component;
|
|
40224
|
+
this.check = check;
|
|
40225
|
+
this.diagnostics = [];
|
|
40226
|
+
}
|
|
40227
|
+
visit(node, context) {
|
|
40228
|
+
this.diagnostics.push(...this.check.visitNode(this.ctx, this.component, node));
|
|
40229
|
+
node.visit(this);
|
|
40230
|
+
}
|
|
40231
|
+
visitAllNodes(nodes) {
|
|
40232
|
+
for (const node of nodes) {
|
|
40233
|
+
this.visit(node);
|
|
40234
|
+
}
|
|
40235
|
+
}
|
|
40236
|
+
visitAst(ast) {
|
|
40237
|
+
if (ast instanceof ASTWithSource) {
|
|
40238
|
+
ast = ast.ast;
|
|
40239
|
+
}
|
|
40240
|
+
this.visit(ast);
|
|
40241
|
+
}
|
|
40242
|
+
visitElement(element) {
|
|
40243
|
+
this.visitAllNodes(element.attributes);
|
|
40244
|
+
this.visitAllNodes(element.inputs);
|
|
40245
|
+
this.visitAllNodes(element.outputs);
|
|
40246
|
+
this.visitAllNodes(element.references);
|
|
40247
|
+
this.visitAllNodes(element.children);
|
|
40248
|
+
}
|
|
40249
|
+
visitTemplate(template) {
|
|
40250
|
+
this.visitAllNodes(template.attributes);
|
|
40251
|
+
if (template.tagName === 'ng-template') {
|
|
40252
|
+
// Only visit input/outputs/templateAttrs if this isn't an inline template node
|
|
40253
|
+
// generated for a structural directive (like `<div *ngIf></div>`). These nodes
|
|
40254
|
+
// would be visited when the underlying element of an inline template node is processed.
|
|
40255
|
+
this.visitAllNodes(template.inputs);
|
|
40256
|
+
this.visitAllNodes(template.outputs);
|
|
40257
|
+
this.visitAllNodes(template.templateAttrs);
|
|
40258
|
+
}
|
|
40259
|
+
this.visitAllNodes(template.variables);
|
|
40260
|
+
this.visitAllNodes(template.references);
|
|
40261
|
+
this.visitAllNodes(template.children);
|
|
40262
|
+
}
|
|
40263
|
+
visitContent(content) { }
|
|
40264
|
+
visitVariable(variable) { }
|
|
40265
|
+
visitReference(reference) { }
|
|
40266
|
+
visitTextAttribute(attribute) { }
|
|
40267
|
+
visitBoundAttribute(attribute) {
|
|
40268
|
+
this.visitAst(attribute.value);
|
|
40269
|
+
}
|
|
40270
|
+
visitBoundEvent(attribute) {
|
|
40271
|
+
this.visitAst(attribute.handler);
|
|
40272
|
+
}
|
|
40273
|
+
visitText(text) { }
|
|
40274
|
+
visitBoundText(text) {
|
|
40275
|
+
this.visitAst(text.value);
|
|
40276
|
+
}
|
|
40277
|
+
visitIcu(icu) { }
|
|
40278
|
+
getDiagnostics(template) {
|
|
40279
|
+
this.diagnostics = [];
|
|
40280
|
+
this.visitAllNodes(template);
|
|
40281
|
+
return this.diagnostics;
|
|
40282
|
+
}
|
|
40283
|
+
}
|
|
40284
|
+
|
|
40285
|
+
/**
|
|
40286
|
+
* @license
|
|
40287
|
+
* Copyright Google LLC All Rights Reserved.
|
|
40288
|
+
*
|
|
40289
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
40290
|
+
* found in the LICENSE file at https://angular.io/license
|
|
40291
|
+
*/
|
|
40292
|
+
/**
|
|
40293
|
+
* Ensures the two-way binding syntax is correct.
|
|
40294
|
+
* Parentheses should be inside the brackets "[()]".
|
|
40295
|
+
* Will return diagnostic information when "([])" is found.
|
|
40296
|
+
*/
|
|
40297
|
+
class InvalidBananaInBoxCheck extends TemplateCheckWithVisitor {
|
|
40298
|
+
constructor() {
|
|
40299
|
+
super(...arguments);
|
|
40300
|
+
this.code = ErrorCode.INVALID_BANANA_IN_BOX;
|
|
40301
|
+
}
|
|
40302
|
+
visitNode(ctx, component, node) {
|
|
40303
|
+
if (!(node instanceof BoundEvent))
|
|
40304
|
+
return [];
|
|
40305
|
+
const name = node.name;
|
|
40306
|
+
if (!name.startsWith('[') || !name.endsWith(']'))
|
|
40307
|
+
return [];
|
|
40308
|
+
const boundSyntax = node.sourceSpan.toString();
|
|
40309
|
+
const expectedBoundSyntax = boundSyntax.replace(`(${name})`, `[(${name.slice(1, -1)})]`);
|
|
40310
|
+
const diagnostic = ctx.templateTypeChecker.makeTemplateDiagnostic(component, node.sourceSpan, ts$1.DiagnosticCategory.Warning, ErrorCode.INVALID_BANANA_IN_BOX, `In the two-way binding syntax the parentheses should be inside the brackets, ex. '${expectedBoundSyntax}'.
|
|
40311
|
+
Find more at https://angular.io/guide/two-way-binding`);
|
|
40312
|
+
return [diagnostic];
|
|
40313
|
+
}
|
|
40314
|
+
}
|
|
40315
|
+
|
|
40316
|
+
/**
|
|
40317
|
+
* @license
|
|
40318
|
+
* Copyright Google LLC All Rights Reserved.
|
|
40319
|
+
*
|
|
40320
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
40321
|
+
* found in the LICENSE file at https://angular.io/license
|
|
40322
|
+
*/
|
|
40323
|
+
/**
|
|
40324
|
+
* Ensures the left side of a nullish coalescing operation is nullable.
|
|
40325
|
+
* Returns diagnostics for the cases where the operator is useless.
|
|
40326
|
+
* This check should only be use if `strictNullChecks` is enabled,
|
|
40327
|
+
* otherwise it would produce inaccurate results.
|
|
40328
|
+
*/
|
|
40329
|
+
class NullishCoalescingNotNullableCheck extends TemplateCheckWithVisitor {
|
|
40330
|
+
constructor() {
|
|
40331
|
+
super(...arguments);
|
|
40332
|
+
this.code = ErrorCode.NULLISH_COALESCING_NOT_NULLABLE;
|
|
40333
|
+
}
|
|
40334
|
+
visitNode(ctx, component, node) {
|
|
40335
|
+
if (!(node instanceof Binary) || node.operation !== '??')
|
|
40336
|
+
return [];
|
|
40337
|
+
const symbolLeft = ctx.templateTypeChecker.getSymbolOfNode(node.left, component);
|
|
40338
|
+
if (symbolLeft.kind !== SymbolKind.Expression) {
|
|
40339
|
+
return [];
|
|
40340
|
+
}
|
|
40341
|
+
const typeLeft = symbolLeft.tsType;
|
|
40342
|
+
// If the left operand's type is different from its non-nullable self, then it must
|
|
40343
|
+
// contain a null or undefined so this nullish coalescing operator is useful. No diagnostic to
|
|
40344
|
+
// report.
|
|
40345
|
+
if (typeLeft.getNonNullableType() !== typeLeft)
|
|
40346
|
+
return [];
|
|
40347
|
+
const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
|
|
40348
|
+
if (symbol.kind !== SymbolKind.Expression) {
|
|
40349
|
+
return [];
|
|
40350
|
+
}
|
|
40351
|
+
const span = ctx.templateTypeChecker.getTemplateMappingAtShimLocation(symbol.shimLocation).span;
|
|
40352
|
+
const diagnostic = ctx.templateTypeChecker.makeTemplateDiagnostic(component, span, ts$1.DiagnosticCategory.Warning, ErrorCode.NULLISH_COALESCING_NOT_NULLABLE, `The left side of this nullish coalescing operation does not include 'null' or 'undefined' in its type, therefore the '??' operator can be safely removed.`);
|
|
40353
|
+
return [diagnostic];
|
|
40354
|
+
}
|
|
40355
|
+
}
|
|
40356
|
+
|
|
40096
40357
|
/**
|
|
40097
40358
|
* @license
|
|
40098
40359
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -40209,6 +40470,10 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40209
40470
|
* with each fresh compilation.
|
|
40210
40471
|
*/
|
|
40211
40472
|
this.delegatingPerfRecorder = new DelegatingPerfRecorder(this.perfRecorder);
|
|
40473
|
+
if (this.options._extendedTemplateDiagnostics === true &&
|
|
40474
|
+
this.options.strictTemplates === false) {
|
|
40475
|
+
throw new Error('The \'_extendedTemplateDiagnostics\' option requires \'strictTemplates\' to also be enabled.');
|
|
40476
|
+
}
|
|
40212
40477
|
this.constructionDiagnostics.push(...this.adapter.constructionDiagnostics);
|
|
40213
40478
|
const incompatibleTypeCheckOptionsDiagnostic = verifyCompatibleTypeCheckOptions(this.options);
|
|
40214
40479
|
if (incompatibleTypeCheckOptionsDiagnostic !== null) {
|
|
@@ -40318,7 +40583,12 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40318
40583
|
* Get all Angular-related diagnostics for this compilation.
|
|
40319
40584
|
*/
|
|
40320
40585
|
getDiagnostics() {
|
|
40321
|
-
|
|
40586
|
+
const diagnostics = [];
|
|
40587
|
+
diagnostics.push(...this.getNonTemplateDiagnostics(), ...this.getTemplateDiagnostics());
|
|
40588
|
+
if (this.options._extendedTemplateDiagnostics) {
|
|
40589
|
+
diagnostics.push(...this.getExtendedTemplateDiagnostics());
|
|
40590
|
+
}
|
|
40591
|
+
return this.addMessageTextDetails(diagnostics);
|
|
40322
40592
|
}
|
|
40323
40593
|
/**
|
|
40324
40594
|
* Get all Angular-related diagnostics for this compilation.
|
|
@@ -40326,10 +40596,26 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40326
40596
|
* If a `ts.SourceFile` is passed, only diagnostics related to that file are returned.
|
|
40327
40597
|
*/
|
|
40328
40598
|
getDiagnosticsForFile(file, optimizeFor) {
|
|
40329
|
-
|
|
40330
|
-
|
|
40331
|
-
|
|
40332
|
-
|
|
40599
|
+
const diagnostics = [];
|
|
40600
|
+
diagnostics.push(...this.getNonTemplateDiagnostics().filter(diag => diag.file === file), ...this.getTemplateDiagnosticsForFile(file, optimizeFor));
|
|
40601
|
+
if (this.options._extendedTemplateDiagnostics) {
|
|
40602
|
+
diagnostics.push(...this.getExtendedTemplateDiagnostics(file));
|
|
40603
|
+
}
|
|
40604
|
+
return this.addMessageTextDetails(diagnostics);
|
|
40605
|
+
}
|
|
40606
|
+
/**
|
|
40607
|
+
* Get all `ts.Diagnostic`s currently available that pertain to the given component.
|
|
40608
|
+
*/
|
|
40609
|
+
getDiagnosticsForComponent(component) {
|
|
40610
|
+
const compilation = this.ensureAnalyzed();
|
|
40611
|
+
const ttc = compilation.templateTypeChecker;
|
|
40612
|
+
const diagnostics = [];
|
|
40613
|
+
diagnostics.push(...ttc.getDiagnosticsForComponent(component));
|
|
40614
|
+
if (this.options._extendedTemplateDiagnostics) {
|
|
40615
|
+
const extendedTemplateChecker = compilation.extendedTemplateChecker;
|
|
40616
|
+
diagnostics.push(...extendedTemplateChecker.getDiagnosticsForComponent(component));
|
|
40617
|
+
}
|
|
40618
|
+
return this.addMessageTextDetails(diagnostics);
|
|
40333
40619
|
}
|
|
40334
40620
|
/**
|
|
40335
40621
|
* Add Angular.io error guide links to diagnostics for this compilation.
|
|
@@ -40719,6 +41005,24 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40719
41005
|
}
|
|
40720
41006
|
return this.nonTemplateDiagnostics;
|
|
40721
41007
|
}
|
|
41008
|
+
/**
|
|
41009
|
+
* Calls the `extendedTemplateCheck` phase of the trait compiler
|
|
41010
|
+
* @param sf optional parameter to get diagnostics for a certain file
|
|
41011
|
+
* or all files in the program if `sf` is undefined
|
|
41012
|
+
* @returns generated extended template diagnostics
|
|
41013
|
+
*/
|
|
41014
|
+
getExtendedTemplateDiagnostics(sf) {
|
|
41015
|
+
const diagnostics = [];
|
|
41016
|
+
const compilation = this.ensureAnalyzed();
|
|
41017
|
+
const extendedTemplateChecker = compilation.extendedTemplateChecker;
|
|
41018
|
+
if (sf !== undefined) {
|
|
41019
|
+
return compilation.traitCompiler.extendedTemplateCheck(sf, extendedTemplateChecker);
|
|
41020
|
+
}
|
|
41021
|
+
for (const sf of this.inputProgram.getSourceFiles()) {
|
|
41022
|
+
diagnostics.push(...compilation.traitCompiler.extendedTemplateCheck(sf, extendedTemplateChecker));
|
|
41023
|
+
}
|
|
41024
|
+
return diagnostics;
|
|
41025
|
+
}
|
|
40722
41026
|
makeCompilation() {
|
|
40723
41027
|
const checker = this.inputProgram.getTypeChecker();
|
|
40724
41028
|
const reflector = new TypeScriptReflectionHost(checker);
|
|
@@ -40832,6 +41136,11 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40832
41136
|
this.currentProgram = program;
|
|
40833
41137
|
});
|
|
40834
41138
|
const templateTypeChecker = new TemplateTypeCheckerImpl(this.inputProgram, notifyingDriver, traitCompiler, this.getTypeCheckingConfig(), refEmitter, reflector, this.adapter, this.incrementalCompilation, scopeRegistry, typeCheckScopeRegistry, this.delegatingPerfRecorder);
|
|
41139
|
+
const templateChecks = [new InvalidBananaInBoxCheck()];
|
|
41140
|
+
if (this.options.strictNullChecks) {
|
|
41141
|
+
templateChecks.push(new NullishCoalescingNotNullableCheck());
|
|
41142
|
+
}
|
|
41143
|
+
const extendedTemplateChecker = new ExtendedTemplateCheckerImpl(templateTypeChecker, checker, templateChecks);
|
|
40835
41144
|
return {
|
|
40836
41145
|
isCore,
|
|
40837
41146
|
traitCompiler,
|
|
@@ -40846,6 +41155,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40846
41155
|
refEmitter,
|
|
40847
41156
|
templateTypeChecker,
|
|
40848
41157
|
resourceRegistry,
|
|
41158
|
+
extendedTemplateChecker
|
|
40849
41159
|
};
|
|
40850
41160
|
}
|
|
40851
41161
|
}
|
|
@@ -42731,7 +43041,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
42731
43041
|
}
|
|
42732
43042
|
const replacementSpan = makeReplacementSpanFromAst(this.node);
|
|
42733
43043
|
if (!(this.node.receiver instanceof ImplicitReceiver) &&
|
|
42734
|
-
(options === null || options === void 0 ? void 0 : options.includeCompletionsWithInsertText) &&
|
|
43044
|
+
!(this.node instanceof SafePropertyRead) && (options === null || options === void 0 ? void 0 : options.includeCompletionsWithInsertText) &&
|
|
42735
43045
|
options.includeAutomaticOptionalChainCompletions !== false) {
|
|
42736
43046
|
const symbol = this.templateTypeChecker.getSymbolOfNode(this.node.receiver, this.component);
|
|
42737
43047
|
if ((symbol === null || symbol === void 0 ? void 0 : symbol.kind) === SymbolKind.Expression) {
|
|
@@ -44425,7 +44735,6 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44425
44735
|
}
|
|
44426
44736
|
getSemanticDiagnostics(fileName) {
|
|
44427
44737
|
return this.withCompilerAndPerfTracing(PerfPhase.LsDiagnostics, (compiler) => {
|
|
44428
|
-
const ttc = compiler.getTemplateTypeChecker();
|
|
44429
44738
|
const diagnostics = [];
|
|
44430
44739
|
if (isTypeScriptFile(fileName)) {
|
|
44431
44740
|
const program = compiler.getCurrentProgram();
|
|
@@ -44461,7 +44770,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44461
44770
|
const components = compiler.getComponentsWithTemplateFile(fileName);
|
|
44462
44771
|
for (const component of components) {
|
|
44463
44772
|
if (ts.isClassDeclaration(component)) {
|
|
44464
|
-
diagnostics.push(...
|
|
44773
|
+
diagnostics.push(...compiler.getDiagnosticsForComponent(component));
|
|
44465
44774
|
}
|
|
44466
44775
|
}
|
|
44467
44776
|
}
|
|
@@ -44625,6 +44934,34 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44625
44934
|
return componentDeclarationLocations;
|
|
44626
44935
|
});
|
|
44627
44936
|
}
|
|
44937
|
+
getTemplateLocationForComponent(fileName, position) {
|
|
44938
|
+
return this.withCompilerAndPerfTracing(PerfPhase.LsComponentLocations, (compiler) => {
|
|
44939
|
+
const nearestNode = findTightestNodeAtPosition(this.programDriver.getProgram(), fileName, position);
|
|
44940
|
+
if (nearestNode === undefined) {
|
|
44941
|
+
return undefined;
|
|
44942
|
+
}
|
|
44943
|
+
const classDeclaration = getParentClassDeclaration(nearestNode);
|
|
44944
|
+
if (classDeclaration === undefined) {
|
|
44945
|
+
return undefined;
|
|
44946
|
+
}
|
|
44947
|
+
const resources = compiler.getComponentResources(classDeclaration);
|
|
44948
|
+
if (resources === null) {
|
|
44949
|
+
return undefined;
|
|
44950
|
+
}
|
|
44951
|
+
const { template } = resources;
|
|
44952
|
+
let templateFileName;
|
|
44953
|
+
let span;
|
|
44954
|
+
if (template.path !== null) {
|
|
44955
|
+
span = ts.createTextSpanFromBounds(0, 0);
|
|
44956
|
+
templateFileName = template.path;
|
|
44957
|
+
}
|
|
44958
|
+
else {
|
|
44959
|
+
span = ts.createTextSpanFromBounds(template.expression.getStart(), template.expression.getEnd());
|
|
44960
|
+
templateFileName = template.expression.getSourceFile().fileName;
|
|
44961
|
+
}
|
|
44962
|
+
return { fileName: templateFileName, textSpan: span, contextSpan: span };
|
|
44963
|
+
});
|
|
44964
|
+
}
|
|
44628
44965
|
getTcb(fileName, position) {
|
|
44629
44966
|
return this.withCompilerAndPerfTracing(PerfPhase.LsTcb, compiler => {
|
|
44630
44967
|
const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler);
|
|
@@ -44975,6 +45312,13 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44975
45312
|
function getComponentLocationsForTemplate(fileName) {
|
|
44976
45313
|
return ngLS.getComponentLocationsForTemplate(fileName);
|
|
44977
45314
|
}
|
|
45315
|
+
/**
|
|
45316
|
+
* Given a location inside a component, finds the location of the inline template or the file for
|
|
45317
|
+
* the `templateUrl`.
|
|
45318
|
+
*/
|
|
45319
|
+
function getTemplateLocationForComponent(fileName, position) {
|
|
45320
|
+
return ngLS.getTemplateLocationForComponent(fileName, position);
|
|
45321
|
+
}
|
|
44978
45322
|
return Object.assign(Object.assign({}, tsLS), { getSemanticDiagnostics,
|
|
44979
45323
|
getTypeDefinitionAtPosition,
|
|
44980
45324
|
getQuickInfoAtPosition,
|
|
@@ -44988,7 +45332,8 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44988
45332
|
getTcb,
|
|
44989
45333
|
getCompilerOptionsDiagnostics,
|
|
44990
45334
|
getComponentLocationsForTemplate,
|
|
44991
|
-
getSignatureHelpItems
|
|
45335
|
+
getSignatureHelpItems,
|
|
45336
|
+
getTemplateLocationForComponent });
|
|
44992
45337
|
}
|
|
44993
45338
|
function getExternalFiles(project) {
|
|
44994
45339
|
if (!project.hasRoots()) {
|