@angular/language-service 11.1.1 → 11.1.2

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 ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ /// <amd-module name="@angular/language-service/api" />
9
+ /**
10
+ * @module
11
+ * @description
12
+ * Entry point for all public APIs of the language service package.
13
+ */
14
+ import * as ts from 'typescript';
15
+ export declare type GetTcbResponse = {
16
+ /**
17
+ * The filename of the SourceFile this typecheck block belongs to.
18
+ * The filename is entirely opaque and unstable, useful only for debugging
19
+ * purposes.
20
+ */
21
+ fileName: string;
22
+ /** The content of the SourceFile this typecheck block belongs to. */
23
+ content: string;
24
+ /**
25
+ * Spans over node(s) in the typecheck block corresponding to the
26
+ * TS code generated for template node under the current cursor position.
27
+ *
28
+ * When the cursor position is over a source for which there is no generated
29
+ * code, `selections` is empty.
30
+ */
31
+ selections: ts.TextSpan[];
32
+ } | undefined;
33
+ /**
34
+ * `NgLanguageService` describes an instance of an Angular language service,
35
+ * whose API surface is a strict superset of TypeScript's language service.
36
+ */
37
+ export interface NgLanguageService extends ts.LanguageService {
38
+ getTcb(fileName: string, position: number): GetTcbResponse;
39
+ }
package/api.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ (function (factory) {
9
+ if (typeof module === "object" && typeof module.exports === "object") {
10
+ var v = factory(require, exports);
11
+ if (v !== undefined) module.exports = v;
12
+ }
13
+ else if (typeof define === "function" && define.amd) {
14
+ define("@angular/language-service/api", ["require", "exports"], factory);
15
+ }
16
+ })(function (require, exports) {
17
+ "use strict";
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ });
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbGFuZ3VhZ2Utc2VydmljZS9hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbi8qKlxuICogQG1vZHVsZVxuICogQGRlc2NyaXB0aW9uXG4gKiBFbnRyeSBwb2ludCBmb3IgYWxsIHB1YmxpYyBBUElzIG9mIHRoZSBsYW5ndWFnZSBzZXJ2aWNlIHBhY2thZ2UuXG4gKi9cblxuaW1wb3J0ICogYXMgdHMgZnJvbSAndHlwZXNjcmlwdCc7XG5cbmV4cG9ydCB0eXBlIEdldFRjYlJlc3BvbnNlID0ge1xuICAvKipcbiAgICogVGhlIGZpbGVuYW1lIG9mIHRoZSBTb3VyY2VGaWxlIHRoaXMgdHlwZWNoZWNrIGJsb2NrIGJlbG9uZ3MgdG8uXG4gICAqIFRoZSBmaWxlbmFtZSBpcyBlbnRpcmVseSBvcGFxdWUgYW5kIHVuc3RhYmxlLCB1c2VmdWwgb25seSBmb3IgZGVidWdnaW5nXG4gICAqIHB1cnBvc2VzLlxuICAgKi9cbiAgZmlsZU5hbWU6IHN0cmluZyxcbiAgLyoqIFRoZSBjb250ZW50IG9mIHRoZSBTb3VyY2VGaWxlIHRoaXMgdHlwZWNoZWNrIGJsb2NrIGJlbG9uZ3MgdG8uICovXG4gIGNvbnRlbnQ6IHN0cmluZyxcbiAgLyoqXG4gICAqIFNwYW5zIG92ZXIgbm9kZShzKSBpbiB0aGUgdHlwZWNoZWNrIGJsb2NrIGNvcnJlc3BvbmRpbmcgdG8gdGhlXG4gICAqIFRTIGNvZGUgZ2VuZXJhdGVkIGZvciB0ZW1wbGF0ZSBub2RlIHVuZGVyIHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvbi5cbiAgICpcbiAgICogV2hlbiB0aGUgY3Vyc29yIHBvc2l0aW9uIGlzIG92ZXIgYSBzb3VyY2UgZm9yIHdoaWNoIHRoZXJlIGlzIG5vIGdlbmVyYXRlZFxuICAgKiBjb2RlLCBgc2VsZWN0aW9uc2AgaXMgZW1wdHkuXG4gICAqL1xuICBzZWxlY3Rpb25zOiB0cy5UZXh0U3BhbltdLFxufXx1bmRlZmluZWQ7XG5cbi8qKlxuICogYE5nTGFuZ3VhZ2VTZXJ2aWNlYCBkZXNjcmliZXMgYW4gaW5zdGFuY2Ugb2YgYW4gQW5ndWxhciBsYW5ndWFnZSBzZXJ2aWNlLFxuICogd2hvc2UgQVBJIHN1cmZhY2UgaXMgYSBzdHJpY3Qgc3VwZXJzZXQgb2YgVHlwZVNjcmlwdCdzIGxhbmd1YWdlIHNlcnZpY2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmdMYW5ndWFnZVNlcnZpY2UgZXh0ZW5kcyB0cy5MYW5ndWFnZVNlcnZpY2Uge1xuICBnZXRUY2IoZmlsZU5hbWU6IHN0cmluZywgcG9zaXRpb246IG51bWJlcik6IEdldFRjYlJlc3BvbnNlO1xufVxuIl19
package/bundles/ivy.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v11.1.1
2
+ * @license Angular v11.1.2
3
3
  * Copyright Google LLC All Rights Reserved.
4
4
  * License: MIT
5
5
  */
@@ -9357,7 +9357,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
9357
9357
  this._advance();
9358
9358
  selfClosing = false;
9359
9359
  }
9360
- const end = this._peek.sourceSpan.start;
9360
+ const end = this._peek.sourceSpan.fullStart;
9361
9361
  const span = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
9362
9362
  // Create a separate `startSpan` because `span` will be modified when there is an `end` span.
9363
9363
  const startSpan = new ParseSourceSpan(startTagToken.sourceSpan.start, end, startTagToken.sourceSpan.fullStart);
@@ -9689,8 +9689,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
9689
9689
  }
9690
9690
  parseInterpolation(value, sourceSpan) {
9691
9691
  const sourceInfo = sourceSpan.start.toString();
9692
+ const absoluteOffset = sourceSpan.fullStart.offset;
9692
9693
  try {
9693
- const ast = this._exprParser.parseInterpolation(value, sourceInfo, sourceSpan.start.offset, this._interpolationConfig);
9694
+ const ast = this._exprParser.parseInterpolation(value, sourceInfo, absoluteOffset, this._interpolationConfig);
9694
9695
  if (ast)
9695
9696
  this._reportExpressionParserErrors(ast.errors, sourceSpan);
9696
9697
  this._checkPipes(ast, sourceSpan);
@@ -9698,7 +9699,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
9698
9699
  }
9699
9700
  catch (e) {
9700
9701
  this._reportError(`${e}`, sourceSpan);
9701
- return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, sourceSpan.start.offset);
9702
+ return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
9702
9703
  }
9703
9704
  }
9704
9705
  /**
@@ -9708,8 +9709,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
9708
9709
  */
9709
9710
  parseInterpolationExpression(expression, sourceSpan) {
9710
9711
  const sourceInfo = sourceSpan.start.toString();
9712
+ const absoluteOffset = sourceSpan.start.offset;
9711
9713
  try {
9712
- const ast = this._exprParser.parseInterpolationExpression(expression, sourceInfo, sourceSpan.start.offset);
9714
+ const ast = this._exprParser.parseInterpolationExpression(expression, sourceInfo, absoluteOffset);
9713
9715
  if (ast)
9714
9716
  this._reportExpressionParserErrors(ast.errors, sourceSpan);
9715
9717
  this._checkPipes(ast, sourceSpan);
@@ -9717,7 +9719,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
9717
9719
  }
9718
9720
  catch (e) {
9719
9721
  this._reportError(`${e}`, sourceSpan);
9720
- return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, sourceSpan.start.offset);
9722
+ return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
9721
9723
  }
9722
9724
  }
9723
9725
  /**
@@ -11354,13 +11356,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11354
11356
  }
11355
11357
  const fullEnd = exprEnd + interpEnd.length;
11356
11358
  const text = input.substring(exprStart, exprEnd);
11357
- if (text.trim().length > 0) {
11358
- expressions.push({ text, start: fullStart, end: fullEnd });
11359
- }
11360
- else {
11359
+ if (text.trim().length === 0) {
11361
11360
  this._reportError('Blank expressions are not allowed in interpolated strings', input, `at column ${i} in`, location);
11362
- expressions.push({ text: '$implicit', start: fullStart, end: fullEnd });
11363
11361
  }
11362
+ expressions.push({ text, start: fullStart, end: fullEnd });
11364
11363
  offsets.push(exprStart);
11365
11364
  i = fullEnd;
11366
11365
  atInterpolation = false;
@@ -11655,8 +11654,12 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11655
11654
  this.error(`Unexpected token '${this.next}'`);
11656
11655
  }
11657
11656
  }
11658
- if (exprs.length == 0)
11659
- return new EmptyExpr(this.span(start), this.sourceSpan(start));
11657
+ if (exprs.length == 0) {
11658
+ // We have no expressions so create an empty expression that spans the entire input length
11659
+ const artificialStart = this.offset;
11660
+ const artificialEnd = this.offset + this.inputLength;
11661
+ return new EmptyExpr(this.span(artificialStart, artificialEnd), this.sourceSpan(artificialStart, artificialEnd));
11662
+ }
11660
11663
  if (exprs.length == 1)
11661
11664
  return exprs[0];
11662
11665
  return new Chain(this.span(start), this.sourceSpan(start), exprs);
@@ -17008,7 +17011,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
17008
17011
  * Use of this source code is governed by an MIT-style license that can be
17009
17012
  * found in the LICENSE file at https://angular.io/license
17010
17013
  */
17011
- const VERSION$1 = new Version('11.1.1');
17014
+ const VERSION$1 = new Version('11.1.2');
17012
17015
 
17013
17016
  /**
17014
17017
  * @license
@@ -17665,7 +17668,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
17665
17668
  */
17666
17669
  function createDirectiveDefinitionMap(meta) {
17667
17670
  const definitionMap = new DefinitionMap();
17668
- definitionMap.set('version', literal('11.1.1'));
17671
+ definitionMap.set('version', literal('11.1.2'));
17669
17672
  // e.g. `type: MyDirective`
17670
17673
  definitionMap.set('type', meta.internalType);
17671
17674
  // e.g. `selector: 'some-dir'`
@@ -21113,7 +21116,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21113
21116
  * Use of this source code is governed by an MIT-style license that can be
21114
21117
  * found in the LICENSE file at https://angular.io/license
21115
21118
  */
21116
- const VERSION$2 = new Version('11.1.1');
21119
+ const VERSION$2 = new Version('11.1.2');
21117
21120
 
21118
21121
  /**
21119
21122
  * @license
@@ -29097,18 +29100,21 @@ Either add the @Injectable() decorator to '${provider.node.name
29097
29100
  });
29098
29101
  // Unfortunately, the primary parse of the template above may not contain accurate source map
29099
29102
  // information. If used directly, it would result in incorrect code locations in template
29100
- // errors, etc. There are two main problems:
29103
+ // errors, etc. There are three main problems:
29101
29104
  //
29102
29105
  // 1. `preserveWhitespaces: false` annihilates the correctness of template source mapping, as
29103
29106
  // the whitespace transformation changes the contents of HTML text nodes before they're
29104
29107
  // parsed into Angular expressions.
29105
- // 2. By default, the template parser strips leading trivia characters (like spaces, tabs, and
29108
+ // 2. `preserveLineEndings: false` causes growing misalignments in templates that use '\r\n'
29109
+ // line endings, by normalizing them to '\n'.
29110
+ // 3. By default, the template parser strips leading trivia characters (like spaces, tabs, and
29106
29111
  // newlines). This also destroys source mapping information.
29107
29112
  //
29108
29113
  // In order to guarantee the correctness of diagnostics, templates are parsed a second time
29109
29114
  // with the above options set to preserve source mappings.
29110
29115
  const { nodes: diagNodes } = parseTemplate(templateStr, template.sourceMapUrl, {
29111
29116
  preserveWhitespaces: true,
29117
+ preserveLineEndings: true,
29112
29118
  interpolationConfig: template.interpolationConfig,
29113
29119
  range: templateRange !== null && templateRange !== void 0 ? templateRange : undefined,
29114
29120
  escapedString,
@@ -36713,12 +36719,6 @@ Either add the @Injectable() decorator to '${provider.node.name
36713
36719
  const shimData = this.pendingShimForComponent(ref.node);
36714
36720
  const templateId = fileData.sourceManager.getTemplateId(ref.node);
36715
36721
  const templateDiagnostics = [];
36716
- const sfPath = absoluteFromSourceFile(ref.node.getSourceFile());
36717
- const overrideTemplate = this.host.getTemplateOverride(sfPath, ref.node);
36718
- if (overrideTemplate !== null) {
36719
- template = overrideTemplate.nodes;
36720
- parseErrors = overrideTemplate.errors;
36721
- }
36722
36722
  if (parseErrors !== null) {
36723
36723
  templateDiagnostics.push(...this.getTemplateDiagnostics(parseErrors, templateId, sourceMapping));
36724
36724
  }
@@ -37625,38 +37625,22 @@ Either add the @Injectable() decorator to '${provider.node.name
37625
37625
  /**
37626
37626
  * Stores directives and pipes that are in scope for each component.
37627
37627
  *
37628
- * Unlike other caches, the scope of a component is not affected by its template, so this
37629
- * cache does not need to be invalidate if the template is overridden. It will be destroyed when
37630
- * the `ts.Program` changes and the `TemplateTypeCheckerImpl` as a whole is destroyed and
37631
- * replaced.
37628
+ * Unlike other caches, the scope of a component is not affected by its template. It will be
37629
+ * destroyed when the `ts.Program` changes and the `TemplateTypeCheckerImpl` as a whole is
37630
+ * destroyed and replaced.
37632
37631
  */
37633
37632
  this.scopeCache = new Map();
37634
37633
  /**
37635
37634
  * Stores potential element tags for each component (a union of DOM tags as well as directive
37636
37635
  * tags).
37637
37636
  *
37638
- * Unlike other caches, the scope of a component is not affected by its template, so this
37639
- * cache does not need to be invalidate if the template is overridden. It will be destroyed when
37640
- * the `ts.Program` changes and the `TemplateTypeCheckerImpl` as a whole is destroyed and
37641
- * replaced.
37637
+ * Unlike other caches, the scope of a component is not affected by its template. It will be
37638
+ * destroyed when the `ts.Program` changes and the `TemplateTypeCheckerImpl` as a whole is
37639
+ * destroyed and replaced.
37642
37640
  */
37643
37641
  this.elementTagCache = new Map();
37644
37642
  this.isComplete = false;
37645
37643
  }
37646
- resetOverrides() {
37647
- for (const fileRecord of this.state.values()) {
37648
- if (fileRecord.templateOverrides !== null) {
37649
- fileRecord.templateOverrides = null;
37650
- fileRecord.shimData.clear();
37651
- fileRecord.isComplete = false;
37652
- }
37653
- }
37654
- // Ideally only those components with overridden templates would have their caches invalidated,
37655
- // but the `TemplateTypeCheckerImpl` does not track the class for components with overrides. As
37656
- // a quick workaround, clear the entire cache instead.
37657
- this.completionCache.clear();
37658
- this.symbolBuilderCache.clear();
37659
- }
37660
37644
  getTemplate(component) {
37661
37645
  const { data } = this.getLatestComponentState(component);
37662
37646
  if (data === null) {
@@ -37693,28 +37677,6 @@ Either add the @Injectable() decorator to '${provider.node.name
37693
37677
  }
37694
37678
  return { data, tcb, shimPath };
37695
37679
  }
37696
- overrideComponentTemplate(component, template) {
37697
- const { nodes, errors } = parseTemplate(template, 'override.html', {
37698
- preserveWhitespaces: true,
37699
- leadingTriviaChars: [],
37700
- });
37701
- const filePath = absoluteFromSourceFile(component.getSourceFile());
37702
- const fileRecord = this.getFileData(filePath);
37703
- const id = fileRecord.sourceManager.getTemplateId(component);
37704
- if (fileRecord.templateOverrides === null) {
37705
- fileRecord.templateOverrides = new Map();
37706
- }
37707
- fileRecord.templateOverrides.set(id, { nodes, errors });
37708
- // Clear data for the shim in question, so it'll be regenerated on the next request.
37709
- const shimFile = this.typeCheckingStrategy.shimPathForComponent(component);
37710
- fileRecord.shimData.delete(shimFile);
37711
- fileRecord.isComplete = false;
37712
- this.isComplete = false;
37713
- // Overriding a component's template invalidates its cached results.
37714
- this.completionCache.delete(component);
37715
- this.symbolBuilderCache.delete(component);
37716
- return { nodes, errors };
37717
- }
37718
37680
  isTrackedTypeCheckFile(filePath) {
37719
37681
  return this.getFileAndShimRecordsForPath(filePath) !== null;
37720
37682
  }
@@ -37815,7 +37777,6 @@ Either add the @Injectable() decorator to '${provider.node.name
37815
37777
  return engine.getExpressionCompletionLocation(ast);
37816
37778
  }
37817
37779
  invalidateClass(clazz) {
37818
- var _a;
37819
37780
  this.completionCache.delete(clazz);
37820
37781
  this.symbolBuilderCache.delete(clazz);
37821
37782
  this.scopeCache.delete(clazz);
@@ -37827,7 +37788,6 @@ Either add the @Injectable() decorator to '${provider.node.name
37827
37788
  const templateId = fileData.sourceManager.getTemplateId(clazz);
37828
37789
  fileData.shimData.delete(shimPath);
37829
37790
  fileData.isComplete = false;
37830
- (_a = fileData.templateOverrides) === null || _a === void 0 ? void 0 : _a.delete(templateId);
37831
37791
  this.isComplete = false;
37832
37792
  }
37833
37793
  getOrCreateCompletionEngine(component) {
@@ -37846,18 +37806,13 @@ Either add the @Injectable() decorator to '${provider.node.name
37846
37806
  const sfPath = absoluteFromSourceFile(sf);
37847
37807
  if (this.state.has(sfPath)) {
37848
37808
  const existingResults = this.state.get(sfPath);
37849
- if (existingResults.templateOverrides !== null) {
37850
- // Cannot adopt prior results if template overrides have been requested.
37851
- return;
37852
- }
37853
37809
  if (existingResults.isComplete) {
37854
37810
  // All data for this file has already been generated, so no need to adopt anything.
37855
37811
  return;
37856
37812
  }
37857
37813
  }
37858
37814
  const previousResults = this.priorBuild.priorTypeCheckingResultsFor(sf);
37859
- if (previousResults === null || !previousResults.isComplete ||
37860
- previousResults.templateOverrides !== null) {
37815
+ if (previousResults === null || !previousResults.isComplete) {
37861
37816
  return;
37862
37817
  }
37863
37818
  this.state.set(sfPath, previousResults);
@@ -37948,7 +37903,6 @@ Either add the @Injectable() decorator to '${provider.node.name
37948
37903
  if (!this.state.has(path)) {
37949
37904
  this.state.set(path, {
37950
37905
  hasInlines: false,
37951
- templateOverrides: null,
37952
37906
  sourceManager: new TemplateSourceManager(),
37953
37907
  isComplete: false,
37954
37908
  shimData: new Map(),
@@ -38101,17 +38055,6 @@ Either add the @Injectable() decorator to '${provider.node.name
38101
38055
  // The component needs to be checked unless the shim which would contain it already exists.
38102
38056
  return !fileData.shimData.has(shimPath);
38103
38057
  }
38104
- getTemplateOverride(sfPath, node) {
38105
- const fileData = this.impl.getFileData(sfPath);
38106
- if (fileData.templateOverrides === null) {
38107
- return null;
38108
- }
38109
- const templateId = fileData.sourceManager.getTemplateId(node);
38110
- if (fileData.templateOverrides.has(templateId)) {
38111
- return fileData.templateOverrides.get(templateId);
38112
- }
38113
- return null;
38114
- }
38115
38058
  recordShimData(sfPath, data) {
38116
38059
  const fileData = this.impl.getFileData(sfPath);
38117
38060
  fileData.shimData.set(data.path, data);
@@ -38151,17 +38094,6 @@ Either add the @Injectable() decorator to '${provider.node.name
38151
38094
  // Only need to generate a TCB for the class if no shim exists for it currently.
38152
38095
  return !this.fileData.shimData.has(shimPath);
38153
38096
  }
38154
- getTemplateOverride(sfPath, node) {
38155
- this.assertPath(sfPath);
38156
- if (this.fileData.templateOverrides === null) {
38157
- return null;
38158
- }
38159
- const templateId = this.fileData.sourceManager.getTemplateId(node);
38160
- if (this.fileData.templateOverrides.has(templateId)) {
38161
- return this.fileData.templateOverrides.get(templateId);
38162
- }
38163
- return null;
38164
- }
38165
38097
  recordShimData(sfPath, data) {
38166
38098
  this.assertPath(sfPath);
38167
38099
  // Previous type-checking state may have required the use of inlines (assuming they were
@@ -38263,6 +38195,13 @@ Either add the @Injectable() decorator to '${provider.node.name
38263
38195
  newProgram,
38264
38196
  };
38265
38197
  }
38198
+ function resourceChangeTicket(compiler, modifiedResourceFiles) {
38199
+ return {
38200
+ kind: CompilationTicketKind.IncrementalResource,
38201
+ compiler,
38202
+ modifiedResourceFiles,
38203
+ };
38204
+ }
38266
38205
  /**
38267
38206
  * The heart of the Angular Ivy compiler.
38268
38207
  *
@@ -39595,9 +39534,6 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
39595
39534
  function isTypeScriptFile(fileName) {
39596
39535
  return fileName.endsWith('.ts');
39597
39536
  }
39598
- function isExternalTemplate(fileName) {
39599
- return !isTypeScriptFile(fileName);
39600
- }
39601
39537
  function isWithin(position, span) {
39602
39538
  let start, end;
39603
39539
  if (span instanceof ParseSourceSpan) {
@@ -39653,7 +39589,12 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
39653
39589
  this.ignoreForEmit = new Set();
39654
39590
  this.factoryTracker = null; // no .ngfactory shims
39655
39591
  this.unifiedModulesHost = null; // only used in Bazel
39656
- this.templateVersion = new Map();
39592
+ /**
39593
+ * Map of resource filenames to the version of the file last read via `readResource`.
39594
+ *
39595
+ * Used to implement `getModifiedResourceFiles`.
39596
+ */
39597
+ this.lastReadResourceVersion = new Map();
39657
39598
  this.rootDirs = getRootDirs(this, project.getCompilationSettings());
39658
39599
  }
39659
39600
  isShim(sf) {
@@ -39701,13 +39642,17 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
39701
39642
  throw new Error(`Failed to get script snapshot while trying to read ${fileName}`);
39702
39643
  }
39703
39644
  const version = this.project.getScriptVersion(fileName);
39704
- this.templateVersion.set(fileName, version);
39645
+ this.lastReadResourceVersion.set(fileName, version);
39705
39646
  return snapshot.getText(0, snapshot.getLength());
39706
39647
  }
39707
- isTemplateDirty(fileName) {
39708
- const lastVersion = this.templateVersion.get(fileName);
39709
- const latestVersion = this.project.getScriptVersion(fileName);
39710
- return lastVersion !== latestVersion;
39648
+ getModifiedResourceFiles() {
39649
+ const modifiedFiles = new Set();
39650
+ for (const [fileName, oldVersion] of this.lastReadResourceVersion) {
39651
+ if (this.project.getScriptVersion(fileName) !== oldVersion) {
39652
+ modifiedFiles.add(fileName);
39653
+ }
39654
+ }
39655
+ return modifiedFiles.size > 0 ? modifiedFiles : undefined;
39711
39656
  }
39712
39657
  }
39713
39658
  /**
@@ -39787,49 +39732,27 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
39787
39732
  this.lastKnownProgram = null;
39788
39733
  }
39789
39734
  getOrCreate() {
39735
+ var _a;
39790
39736
  const program = this.programStrategy.getProgram();
39791
- if (this.compiler === null || program !== this.lastKnownProgram) {
39792
- let ticket;
39793
- if (this.compiler === null || this.lastKnownProgram === null) {
39794
- ticket = freshCompilationTicket(program, this.options, this.incrementalStrategy, this.programStrategy, true, true);
39737
+ const modifiedResourceFiles = (_a = this.adapter.getModifiedResourceFiles()) !== null && _a !== void 0 ? _a : new Set();
39738
+ if (this.compiler !== null && program === this.lastKnownProgram) {
39739
+ if (modifiedResourceFiles.size > 0) {
39740
+ // Only resource files have changed since the last NgCompiler was created.
39741
+ const ticket = resourceChangeTicket(this.compiler, modifiedResourceFiles);
39742
+ this.compiler = NgCompiler.fromTicket(ticket, this.adapter);
39795
39743
  }
39796
- else {
39797
- ticket = incrementalFromCompilerTicket(this.compiler, program, this.incrementalStrategy, this.programStrategy, new Set());
39798
- }
39799
- this.compiler = NgCompiler.fromTicket(ticket, this.adapter);
39800
- this.lastKnownProgram = program;
39801
- }
39802
- return this.compiler;
39803
- }
39804
- /**
39805
- * Create a new instance of the Ivy compiler if the program has changed since
39806
- * the last time the compiler was instantiated. If the program has not changed,
39807
- * return the existing instance.
39808
- * @param fileName override the template if this is an external template file
39809
- * @param options angular compiler options
39810
- */
39811
- getOrCreateWithChangedFile(fileName) {
39812
- const compiler = this.getOrCreate();
39813
- if (isExternalTemplate(fileName)) {
39814
- this.overrideTemplate(fileName, compiler);
39744
+ return this.compiler;
39815
39745
  }
39816
- return compiler;
39817
- }
39818
- overrideTemplate(fileName, compiler) {
39819
- if (!this.adapter.isTemplateDirty(fileName)) {
39820
- return;
39746
+ let ticket;
39747
+ if (this.compiler === null || this.lastKnownProgram === null) {
39748
+ ticket = freshCompilationTicket(program, this.options, this.incrementalStrategy, this.programStrategy, true, true);
39821
39749
  }
39822
- // 1. Get the latest snapshot
39823
- const latestTemplate = this.adapter.readResource(fileName);
39824
- // 2. Find all components that use the template
39825
- const ttc = compiler.getTemplateTypeChecker();
39826
- const components = compiler.getComponentsWithTemplateFile(fileName);
39827
- // 3. Update component template
39828
- for (const component of components) {
39829
- if (ts.isClassDeclaration(component)) {
39830
- ttc.overrideComponentTemplate(component, latestTemplate);
39831
- }
39750
+ else {
39751
+ ticket = incrementalFromCompilerTicket(this.compiler, program, this.incrementalStrategy, this.programStrategy, modifiedResourceFiles);
39832
39752
  }
39753
+ this.compiler = NgCompiler.fromTicket(ticket, this.adapter);
39754
+ this.lastKnownProgram = program;
39755
+ return this.compiler;
39833
39756
  }
39834
39757
  registerLastKnownProgram() {
39835
39758
  this.lastKnownProgram = this.programStrategy.getProgram();
@@ -40440,12 +40363,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
40440
40363
  return undefined;
40441
40364
  }
40442
40365
  const { componentContext, templateContext } = completions;
40443
- let replacementSpan = undefined;
40444
- // Non-empty nodes get replaced with the completion.
40445
- if (!(this.node instanceof EmptyExpr || this.node instanceof LiteralPrimitive ||
40446
- this.node instanceof BoundEvent)) {
40447
- replacementSpan = makeReplacementSpanFromAst(this.node);
40448
- }
40366
+ const replacementSpan = makeReplacementSpanFromAst(this.node);
40449
40367
  // Merge TS completion results with results from the template scope.
40450
40368
  let entries = [];
40451
40369
  const tsLsCompletions = this.tsLS.getCompletionsAtPosition(componentContext.shimPath, componentContext.positionInShimFile, options);
@@ -40776,6 +40694,11 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
40776
40694
  };
40777
40695
  }
40778
40696
  function makeReplacementSpanFromAst(node) {
40697
+ if ((node instanceof EmptyExpr || node instanceof LiteralPrimitive ||
40698
+ node instanceof BoundEvent)) {
40699
+ // empty nodes do not replace any existing text
40700
+ return undefined;
40701
+ }
40779
40702
  return {
40780
40703
  start: node.nameSpan.start,
40781
40704
  length: node.nameSpan.end - node.nameSpan.start,
@@ -41746,7 +41669,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
41746
41669
  return this.options;
41747
41670
  }
41748
41671
  getSemanticDiagnostics(fileName) {
41749
- const compiler = this.compilerFactory.getOrCreateWithChangedFile(fileName);
41672
+ const compiler = this.compilerFactory.getOrCreate();
41750
41673
  const ttc = compiler.getTemplateTypeChecker();
41751
41674
  const diagnostics = [];
41752
41675
  if (isTypeScriptFile(fileName)) {
@@ -41768,19 +41691,19 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
41768
41691
  return diagnostics;
41769
41692
  }
41770
41693
  getDefinitionAndBoundSpan(fileName, position) {
41771
- const compiler = this.compilerFactory.getOrCreateWithChangedFile(fileName);
41694
+ const compiler = this.compilerFactory.getOrCreate();
41772
41695
  const results = new DefinitionBuilder(this.tsLS, compiler).getDefinitionAndBoundSpan(fileName, position);
41773
41696
  this.compilerFactory.registerLastKnownProgram();
41774
41697
  return results;
41775
41698
  }
41776
41699
  getTypeDefinitionAtPosition(fileName, position) {
41777
- const compiler = this.compilerFactory.getOrCreateWithChangedFile(fileName);
41700
+ const compiler = this.compilerFactory.getOrCreate();
41778
41701
  const results = new DefinitionBuilder(this.tsLS, compiler).getTypeDefinitionsAtPosition(fileName, position);
41779
41702
  this.compilerFactory.registerLastKnownProgram();
41780
41703
  return results;
41781
41704
  }
41782
41705
  getQuickInfoAtPosition(fileName, position) {
41783
- const compiler = this.compilerFactory.getOrCreateWithChangedFile(fileName);
41706
+ const compiler = this.compilerFactory.getOrCreate();
41784
41707
  const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler);
41785
41708
  if (templateInfo === undefined) {
41786
41709
  return undefined;
@@ -41800,13 +41723,13 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
41800
41723
  return results;
41801
41724
  }
41802
41725
  getReferencesAtPosition(fileName, position) {
41803
- const compiler = this.compilerFactory.getOrCreateWithChangedFile(fileName);
41726
+ const compiler = this.compilerFactory.getOrCreate();
41804
41727
  const results = new ReferenceBuilder(this.strategy, this.tsLS, compiler).get(fileName, position);
41805
41728
  this.compilerFactory.registerLastKnownProgram();
41806
41729
  return results;
41807
41730
  }
41808
41731
  getCompletionBuilder(fileName, position) {
41809
- const compiler = this.compilerFactory.getOrCreateWithChangedFile(fileName);
41732
+ const compiler = this.compilerFactory.getOrCreate();
41810
41733
  const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler);
41811
41734
  if (templateInfo === undefined) {
41812
41735
  return null;
@@ -42082,6 +42005,9 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
42082
42005
  diagnostics.push(...ngLS.getCompilerOptionsDiagnostics());
42083
42006
  return diagnostics;
42084
42007
  }
42008
+ function getTcb(fileName, position) {
42009
+ return undefined;
42010
+ }
42085
42011
  return Object.assign(Object.assign({}, tsLS), { getSemanticDiagnostics,
42086
42012
  getTypeDefinitionAtPosition,
42087
42013
  getQuickInfoAtPosition,
@@ -42091,7 +42017,8 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
42091
42017
  getCompletionsAtPosition,
42092
42018
  getCompletionEntryDetails,
42093
42019
  getCompletionEntrySymbol,
42094
- getCompilerOptionsDiagnostics });
42020
+ getCompilerOptionsDiagnostics,
42021
+ getTcb });
42095
42022
  }
42096
42023
  function getExternalFiles(project) {
42097
42024
  if (!project.hasRoots()) {