@angular/language-service 12.2.0-next.3 → 12.2.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/bundles/ivy.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v12.2.0-next.3
2
+ * @license Angular v12.2.2
3
3
  * Copyright Google LLC All Rights Reserved.
4
4
  * License: MIT
5
5
  */
@@ -455,7 +455,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
455
455
  return [null, elementName];
456
456
  }
457
457
  const colonIndex = elementName.indexOf(':', 1);
458
- if (colonIndex == -1) {
458
+ if (colonIndex === -1) {
459
459
  throw new Error(`Unsupported format "${elementName}" expecting ":namespace:name"`);
460
460
  }
461
461
  return [elementName.slice(1, colonIndex), elementName.slice(colonIndex + 1)];
@@ -506,7 +506,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
506
506
  }
507
507
  getContentType(prefix) {
508
508
  if (typeof this.contentType === 'object') {
509
- const overrideType = prefix == null ? undefined : this.contentType[prefix];
509
+ const overrideType = prefix === undefined ? undefined : this.contentType[prefix];
510
510
  return overrideType !== null && overrideType !== void 0 ? overrideType : this.contentType.default;
511
511
  }
512
512
  return this.contentType;
@@ -2871,11 +2871,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
2871
2871
  class RecursiveVisitor {
2872
2872
  visitElement(element) {
2873
2873
  visitAll(this, element.attributes);
2874
+ visitAll(this, element.inputs);
2875
+ visitAll(this, element.outputs);
2874
2876
  visitAll(this, element.children);
2875
2877
  visitAll(this, element.references);
2876
2878
  }
2877
2879
  visitTemplate(template) {
2878
2880
  visitAll(this, template.attributes);
2881
+ visitAll(this, template.inputs);
2882
+ visitAll(this, template.outputs);
2879
2883
  visitAll(this, template.children);
2880
2884
  visitAll(this, template.references);
2881
2885
  visitAll(this, template.variables);
@@ -4736,13 +4740,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4736
4740
  return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
4737
4741
  }
4738
4742
 
4739
- /**
4740
- * @license
4741
- * Copyright Google LLC All Rights Reserved.
4742
- *
4743
- * Use of this source code is governed by an MIT-style license that can be
4744
- * found in the LICENSE file at https://angular.io/license
4745
- */
4746
4743
  var R3FactoryDelegateType;
4747
4744
  (function (R3FactoryDelegateType) {
4748
4745
  R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
@@ -5141,8 +5138,249 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
5141
5138
  * Use of this source code is governed by an MIT-style license that can be
5142
5139
  * found in the LICENSE file at https://angular.io/license
5143
5140
  */
5144
- function sanitizeIdentifier(name) {
5145
- return name.replace(/\W/g, '_');
5141
+ const $EOF = 0;
5142
+ const $BSPACE = 8;
5143
+ const $TAB = 9;
5144
+ const $LF = 10;
5145
+ const $VTAB = 11;
5146
+ const $FF = 12;
5147
+ const $CR = 13;
5148
+ const $SPACE = 32;
5149
+ const $BANG = 33;
5150
+ const $DQ = 34;
5151
+ const $HASH = 35;
5152
+ const $$ = 36;
5153
+ const $PERCENT = 37;
5154
+ const $AMPERSAND = 38;
5155
+ const $SQ = 39;
5156
+ const $LPAREN = 40;
5157
+ const $RPAREN = 41;
5158
+ const $STAR = 42;
5159
+ const $PLUS = 43;
5160
+ const $COMMA = 44;
5161
+ const $MINUS = 45;
5162
+ const $PERIOD = 46;
5163
+ const $SLASH = 47;
5164
+ const $COLON = 58;
5165
+ const $SEMICOLON = 59;
5166
+ const $LT = 60;
5167
+ const $EQ = 61;
5168
+ const $GT = 62;
5169
+ const $QUESTION = 63;
5170
+ const $0 = 48;
5171
+ const $7 = 55;
5172
+ const $9 = 57;
5173
+ const $A = 65;
5174
+ const $E = 69;
5175
+ const $F = 70;
5176
+ const $X = 88;
5177
+ const $Z = 90;
5178
+ const $LBRACKET = 91;
5179
+ const $BACKSLASH = 92;
5180
+ const $RBRACKET = 93;
5181
+ const $CARET = 94;
5182
+ const $_ = 95;
5183
+ const $a = 97;
5184
+ const $b = 98;
5185
+ const $e = 101;
5186
+ const $f = 102;
5187
+ const $n = 110;
5188
+ const $r = 114;
5189
+ const $t = 116;
5190
+ const $u = 117;
5191
+ const $v = 118;
5192
+ const $x = 120;
5193
+ const $z = 122;
5194
+ const $LBRACE = 123;
5195
+ const $BAR = 124;
5196
+ const $RBRACE = 125;
5197
+ const $NBSP = 160;
5198
+ const $BT = 96;
5199
+ function isWhitespace(code) {
5200
+ return (code >= $TAB && code <= $SPACE) || (code == $NBSP);
5201
+ }
5202
+ function isDigit(code) {
5203
+ return $0 <= code && code <= $9;
5204
+ }
5205
+ function isAsciiLetter(code) {
5206
+ return code >= $a && code <= $z || code >= $A && code <= $Z;
5207
+ }
5208
+ function isAsciiHexDigit(code) {
5209
+ return code >= $a && code <= $f || code >= $A && code <= $F || isDigit(code);
5210
+ }
5211
+ function isNewLine(code) {
5212
+ return code === $LF || code === $CR;
5213
+ }
5214
+ function isOctalDigit(code) {
5215
+ return $0 <= code && code <= $7;
5216
+ }
5217
+ function isQuote(code) {
5218
+ return code === $SQ || code === $DQ || code === $BT;
5219
+ }
5220
+
5221
+ /**
5222
+ * @license
5223
+ * Copyright Google LLC All Rights Reserved.
5224
+ *
5225
+ * Use of this source code is governed by an MIT-style license that can be
5226
+ * found in the LICENSE file at https://angular.io/license
5227
+ */
5228
+ class ParseLocation {
5229
+ constructor(file, offset, line, col) {
5230
+ this.file = file;
5231
+ this.offset = offset;
5232
+ this.line = line;
5233
+ this.col = col;
5234
+ }
5235
+ toString() {
5236
+ return this.offset != null ? `${this.file.url}@${this.line}:${this.col}` : this.file.url;
5237
+ }
5238
+ moveBy(delta) {
5239
+ const source = this.file.content;
5240
+ const len = source.length;
5241
+ let offset = this.offset;
5242
+ let line = this.line;
5243
+ let col = this.col;
5244
+ while (offset > 0 && delta < 0) {
5245
+ offset--;
5246
+ delta++;
5247
+ const ch = source.charCodeAt(offset);
5248
+ if (ch == $LF) {
5249
+ line--;
5250
+ const priorLine = source.substr(0, offset - 1).lastIndexOf(String.fromCharCode($LF));
5251
+ col = priorLine > 0 ? offset - priorLine : offset;
5252
+ }
5253
+ else {
5254
+ col--;
5255
+ }
5256
+ }
5257
+ while (offset < len && delta > 0) {
5258
+ const ch = source.charCodeAt(offset);
5259
+ offset++;
5260
+ delta--;
5261
+ if (ch == $LF) {
5262
+ line++;
5263
+ col = 0;
5264
+ }
5265
+ else {
5266
+ col++;
5267
+ }
5268
+ }
5269
+ return new ParseLocation(this.file, offset, line, col);
5270
+ }
5271
+ // Return the source around the location
5272
+ // Up to `maxChars` or `maxLines` on each side of the location
5273
+ getContext(maxChars, maxLines) {
5274
+ const content = this.file.content;
5275
+ let startOffset = this.offset;
5276
+ if (startOffset != null) {
5277
+ if (startOffset > content.length - 1) {
5278
+ startOffset = content.length - 1;
5279
+ }
5280
+ let endOffset = startOffset;
5281
+ let ctxChars = 0;
5282
+ let ctxLines = 0;
5283
+ while (ctxChars < maxChars && startOffset > 0) {
5284
+ startOffset--;
5285
+ ctxChars++;
5286
+ if (content[startOffset] == '\n') {
5287
+ if (++ctxLines == maxLines) {
5288
+ break;
5289
+ }
5290
+ }
5291
+ }
5292
+ ctxChars = 0;
5293
+ ctxLines = 0;
5294
+ while (ctxChars < maxChars && endOffset < content.length - 1) {
5295
+ endOffset++;
5296
+ ctxChars++;
5297
+ if (content[endOffset] == '\n') {
5298
+ if (++ctxLines == maxLines) {
5299
+ break;
5300
+ }
5301
+ }
5302
+ }
5303
+ return {
5304
+ before: content.substring(startOffset, this.offset),
5305
+ after: content.substring(this.offset, endOffset + 1),
5306
+ };
5307
+ }
5308
+ return null;
5309
+ }
5310
+ }
5311
+ class ParseSourceFile {
5312
+ constructor(content, url) {
5313
+ this.content = content;
5314
+ this.url = url;
5315
+ }
5316
+ }
5317
+ class ParseSourceSpan {
5318
+ /**
5319
+ * Create an object that holds information about spans of tokens/nodes captured during
5320
+ * lexing/parsing of text.
5321
+ *
5322
+ * @param start
5323
+ * The location of the start of the span (having skipped leading trivia).
5324
+ * Skipping leading trivia makes source-spans more "user friendly", since things like HTML
5325
+ * elements will appear to begin at the start of the opening tag, rather than at the start of any
5326
+ * leading trivia, which could include newlines.
5327
+ *
5328
+ * @param end
5329
+ * The location of the end of the span.
5330
+ *
5331
+ * @param fullStart
5332
+ * The start of the token without skipping the leading trivia.
5333
+ * This is used by tooling that splits tokens further, such as extracting Angular interpolations
5334
+ * from text tokens. Such tooling creates new source-spans relative to the original token's
5335
+ * source-span. If leading trivia characters have been skipped then the new source-spans may be
5336
+ * incorrectly offset.
5337
+ *
5338
+ * @param details
5339
+ * Additional information (such as identifier names) that should be associated with the span.
5340
+ */
5341
+ constructor(start, end, fullStart = start, details = null) {
5342
+ this.start = start;
5343
+ this.end = end;
5344
+ this.fullStart = fullStart;
5345
+ this.details = details;
5346
+ }
5347
+ toString() {
5348
+ return this.start.file.content.substring(this.start.offset, this.end.offset);
5349
+ }
5350
+ }
5351
+ var ParseErrorLevel;
5352
+ (function (ParseErrorLevel) {
5353
+ ParseErrorLevel[ParseErrorLevel["WARNING"] = 0] = "WARNING";
5354
+ ParseErrorLevel[ParseErrorLevel["ERROR"] = 1] = "ERROR";
5355
+ })(ParseErrorLevel || (ParseErrorLevel = {}));
5356
+ class ParseError {
5357
+ constructor(span, msg, level = ParseErrorLevel.ERROR) {
5358
+ this.span = span;
5359
+ this.msg = msg;
5360
+ this.level = level;
5361
+ }
5362
+ contextualMessage() {
5363
+ const ctx = this.span.start.getContext(100, 3);
5364
+ return ctx ? `${this.msg} ("${ctx.before}[${ParseErrorLevel[this.level]} ->]${ctx.after}")` :
5365
+ this.msg;
5366
+ }
5367
+ toString() {
5368
+ const details = this.span.details ? `, ${this.span.details}` : '';
5369
+ return `${this.contextualMessage()}: ${this.span.start}${details}`;
5370
+ }
5371
+ }
5372
+ /**
5373
+ * Generates Source Span object for a given R3 Type for JIT mode.
5374
+ *
5375
+ * @param kind Component or Directive.
5376
+ * @param typeName name of the Component or Directive.
5377
+ * @param sourceUrl reference to Component or Directive source.
5378
+ * @returns instance of ParseSourceSpan that represent a given Component or Directive.
5379
+ */
5380
+ function r3JitTypeSourceSpan(kind, typeName, sourceUrl) {
5381
+ const sourceFileName = `in ${kind} ${typeName} in ${sourceUrl}`;
5382
+ const sourceFile = new ParseSourceFile('', sourceFileName);
5383
+ return new ParseSourceSpan(new ParseLocation(sourceFile, -1, -1, -1), new ParseLocation(sourceFile, -1, -1, -1));
5146
5384
  }
5147
5385
  let _anonymousTypeIndex = 0;
5148
5386
  function identifierName(compileIdentifier) {
@@ -5172,18 +5410,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
5172
5410
  }
5173
5411
  return identifier;
5174
5412
  }
5175
- var CompileSummaryKind;
5176
- (function (CompileSummaryKind) {
5177
- CompileSummaryKind[CompileSummaryKind["Pipe"] = 0] = "Pipe";
5178
- CompileSummaryKind[CompileSummaryKind["Directive"] = 1] = "Directive";
5179
- CompileSummaryKind[CompileSummaryKind["NgModule"] = 2] = "NgModule";
5180
- CompileSummaryKind[CompileSummaryKind["Injectable"] = 3] = "Injectable";
5181
- })(CompileSummaryKind || (CompileSummaryKind = {}));
5182
- function flatten(list) {
5183
- return list.reduce((flat, item) => {
5184
- const flatItem = Array.isArray(item) ? flatten(item) : item;
5185
- return flat.concat(flatItem);
5186
- }, []);
5413
+ function sanitizeIdentifier(name) {
5414
+ return name.replace(/\W/g, '_');
5187
5415
  }
5188
5416
 
5189
5417
  /**
@@ -5639,255 +5867,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
5639
5867
  return statement.isEquivalent(literal('use strict').toStmt());
5640
5868
  }
5641
5869
 
5642
- /**
5643
- * @license
5644
- * Copyright Google LLC All Rights Reserved.
5645
- *
5646
- * Use of this source code is governed by an MIT-style license that can be
5647
- * found in the LICENSE file at https://angular.io/license
5648
- */
5649
- const $EOF = 0;
5650
- const $BSPACE = 8;
5651
- const $TAB = 9;
5652
- const $LF = 10;
5653
- const $VTAB = 11;
5654
- const $FF = 12;
5655
- const $CR = 13;
5656
- const $SPACE = 32;
5657
- const $BANG = 33;
5658
- const $DQ = 34;
5659
- const $HASH = 35;
5660
- const $$ = 36;
5661
- const $PERCENT = 37;
5662
- const $AMPERSAND = 38;
5663
- const $SQ = 39;
5664
- const $LPAREN = 40;
5665
- const $RPAREN = 41;
5666
- const $STAR = 42;
5667
- const $PLUS = 43;
5668
- const $COMMA = 44;
5669
- const $MINUS = 45;
5670
- const $PERIOD = 46;
5671
- const $SLASH = 47;
5672
- const $COLON = 58;
5673
- const $SEMICOLON = 59;
5674
- const $LT = 60;
5675
- const $EQ = 61;
5676
- const $GT = 62;
5677
- const $QUESTION = 63;
5678
- const $0 = 48;
5679
- const $7 = 55;
5680
- const $9 = 57;
5681
- const $A = 65;
5682
- const $E = 69;
5683
- const $F = 70;
5684
- const $X = 88;
5685
- const $Z = 90;
5686
- const $LBRACKET = 91;
5687
- const $BACKSLASH = 92;
5688
- const $RBRACKET = 93;
5689
- const $CARET = 94;
5690
- const $_ = 95;
5691
- const $a = 97;
5692
- const $b = 98;
5693
- const $e = 101;
5694
- const $f = 102;
5695
- const $n = 110;
5696
- const $r = 114;
5697
- const $t = 116;
5698
- const $u = 117;
5699
- const $v = 118;
5700
- const $x = 120;
5701
- const $z = 122;
5702
- const $LBRACE = 123;
5703
- const $BAR = 124;
5704
- const $RBRACE = 125;
5705
- const $NBSP = 160;
5706
- const $BT = 96;
5707
- function isWhitespace(code) {
5708
- return (code >= $TAB && code <= $SPACE) || (code == $NBSP);
5709
- }
5710
- function isDigit(code) {
5711
- return $0 <= code && code <= $9;
5712
- }
5713
- function isAsciiLetter(code) {
5714
- return code >= $a && code <= $z || code >= $A && code <= $Z;
5715
- }
5716
- function isAsciiHexDigit(code) {
5717
- return code >= $a && code <= $f || code >= $A && code <= $F || isDigit(code);
5718
- }
5719
- function isNewLine(code) {
5720
- return code === $LF || code === $CR;
5721
- }
5722
- function isOctalDigit(code) {
5723
- return $0 <= code && code <= $7;
5724
- }
5725
-
5726
- /**
5727
- * @license
5728
- * Copyright Google LLC All Rights Reserved.
5729
- *
5730
- * Use of this source code is governed by an MIT-style license that can be
5731
- * found in the LICENSE file at https://angular.io/license
5732
- */
5733
- class ParseLocation {
5734
- constructor(file, offset, line, col) {
5735
- this.file = file;
5736
- this.offset = offset;
5737
- this.line = line;
5738
- this.col = col;
5739
- }
5740
- toString() {
5741
- return this.offset != null ? `${this.file.url}@${this.line}:${this.col}` : this.file.url;
5742
- }
5743
- moveBy(delta) {
5744
- const source = this.file.content;
5745
- const len = source.length;
5746
- let offset = this.offset;
5747
- let line = this.line;
5748
- let col = this.col;
5749
- while (offset > 0 && delta < 0) {
5750
- offset--;
5751
- delta++;
5752
- const ch = source.charCodeAt(offset);
5753
- if (ch == $LF) {
5754
- line--;
5755
- const priorLine = source.substr(0, offset - 1).lastIndexOf(String.fromCharCode($LF));
5756
- col = priorLine > 0 ? offset - priorLine : offset;
5757
- }
5758
- else {
5759
- col--;
5760
- }
5761
- }
5762
- while (offset < len && delta > 0) {
5763
- const ch = source.charCodeAt(offset);
5764
- offset++;
5765
- delta--;
5766
- if (ch == $LF) {
5767
- line++;
5768
- col = 0;
5769
- }
5770
- else {
5771
- col++;
5772
- }
5773
- }
5774
- return new ParseLocation(this.file, offset, line, col);
5775
- }
5776
- // Return the source around the location
5777
- // Up to `maxChars` or `maxLines` on each side of the location
5778
- getContext(maxChars, maxLines) {
5779
- const content = this.file.content;
5780
- let startOffset = this.offset;
5781
- if (startOffset != null) {
5782
- if (startOffset > content.length - 1) {
5783
- startOffset = content.length - 1;
5784
- }
5785
- let endOffset = startOffset;
5786
- let ctxChars = 0;
5787
- let ctxLines = 0;
5788
- while (ctxChars < maxChars && startOffset > 0) {
5789
- startOffset--;
5790
- ctxChars++;
5791
- if (content[startOffset] == '\n') {
5792
- if (++ctxLines == maxLines) {
5793
- break;
5794
- }
5795
- }
5796
- }
5797
- ctxChars = 0;
5798
- ctxLines = 0;
5799
- while (ctxChars < maxChars && endOffset < content.length - 1) {
5800
- endOffset++;
5801
- ctxChars++;
5802
- if (content[endOffset] == '\n') {
5803
- if (++ctxLines == maxLines) {
5804
- break;
5805
- }
5806
- }
5807
- }
5808
- return {
5809
- before: content.substring(startOffset, this.offset),
5810
- after: content.substring(this.offset, endOffset + 1),
5811
- };
5812
- }
5813
- return null;
5814
- }
5815
- }
5816
- class ParseSourceFile {
5817
- constructor(content, url) {
5818
- this.content = content;
5819
- this.url = url;
5820
- }
5821
- }
5822
- class ParseSourceSpan {
5823
- /**
5824
- * Create an object that holds information about spans of tokens/nodes captured during
5825
- * lexing/parsing of text.
5826
- *
5827
- * @param start
5828
- * The location of the start of the span (having skipped leading trivia).
5829
- * Skipping leading trivia makes source-spans more "user friendly", since things like HTML
5830
- * elements will appear to begin at the start of the opening tag, rather than at the start of any
5831
- * leading trivia, which could include newlines.
5832
- *
5833
- * @param end
5834
- * The location of the end of the span.
5835
- *
5836
- * @param fullStart
5837
- * The start of the token without skipping the leading trivia.
5838
- * This is used by tooling that splits tokens further, such as extracting Angular interpolations
5839
- * from text tokens. Such tooling creates new source-spans relative to the original token's
5840
- * source-span. If leading trivia characters have been skipped then the new source-spans may be
5841
- * incorrectly offset.
5842
- *
5843
- * @param details
5844
- * Additional information (such as identifier names) that should be associated with the span.
5845
- */
5846
- constructor(start, end, fullStart = start, details = null) {
5847
- this.start = start;
5848
- this.end = end;
5849
- this.fullStart = fullStart;
5850
- this.details = details;
5851
- }
5852
- toString() {
5853
- return this.start.file.content.substring(this.start.offset, this.end.offset);
5854
- }
5855
- }
5856
- var ParseErrorLevel;
5857
- (function (ParseErrorLevel) {
5858
- ParseErrorLevel[ParseErrorLevel["WARNING"] = 0] = "WARNING";
5859
- ParseErrorLevel[ParseErrorLevel["ERROR"] = 1] = "ERROR";
5860
- })(ParseErrorLevel || (ParseErrorLevel = {}));
5861
- class ParseError {
5862
- constructor(span, msg, level = ParseErrorLevel.ERROR) {
5863
- this.span = span;
5864
- this.msg = msg;
5865
- this.level = level;
5866
- }
5867
- contextualMessage() {
5868
- const ctx = this.span.start.getContext(100, 3);
5869
- return ctx ? `${this.msg} ("${ctx.before}[${ParseErrorLevel[this.level]} ->]${ctx.after}")` :
5870
- this.msg;
5871
- }
5872
- toString() {
5873
- const details = this.span.details ? `, ${this.span.details}` : '';
5874
- return `${this.contextualMessage()}: ${this.span.start}${details}`;
5875
- }
5876
- }
5877
- /**
5878
- * Generates Source Span object for a given R3 Type for JIT mode.
5879
- *
5880
- * @param kind Component or Directive.
5881
- * @param typeName name of the Component or Directive.
5882
- * @param sourceUrl reference to Component or Directive source.
5883
- * @returns instance of ParseSourceSpan that represent a given Component or Directive.
5884
- */
5885
- function r3JitTypeSourceSpan(kind, typeName, sourceUrl) {
5886
- const sourceFileName = `in ${kind} ${typeName} in ${sourceUrl}`;
5887
- const sourceFile = new ParseSourceFile('', sourceFileName);
5888
- return new ParseSourceSpan(new ParseLocation(sourceFile, -1, -1, -1), new ParseLocation(sourceFile, -1, -1, -1));
5889
- }
5890
-
5891
5870
  /**
5892
5871
  * @license
5893
5872
  * Copyright Google LLC All Rights Reserved.
@@ -8460,7 +8439,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
8460
8439
  // Support for `>>>`, `deep`, `::ng-deep` is then also deprecated and will be removed in the future.
8461
8440
  // see https://github.com/angular/angular/pull/17677
8462
8441
  const _shadowDeepSelectors = /(?:>>>)|(?:\/deep\/)|(?:::ng-deep)/g;
8463
- const _selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$';
8442
+ const _selectorReSuffix = '([>\\s~+[.,{:][\\s\\S]*)?$';
8464
8443
  const _polyfillHostRe = /-shadowcsshost/gim;
8465
8444
  const _colonHostRe = /:host/gim;
8466
8445
  const _colonHostContextRe = /:host-context/gim;
@@ -8629,6 +8608,27 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
8629
8608
  }
8630
8609
  }
8631
8610
 
8611
+ /**
8612
+ * @license
8613
+ * Copyright Google LLC All Rights Reserved.
8614
+ *
8615
+ * Use of this source code is governed by an MIT-style license that can be
8616
+ * found in the LICENSE file at https://angular.io/license
8617
+ */
8618
+ var CompileSummaryKind;
8619
+ (function (CompileSummaryKind) {
8620
+ CompileSummaryKind[CompileSummaryKind["Pipe"] = 0] = "Pipe";
8621
+ CompileSummaryKind[CompileSummaryKind["Directive"] = 1] = "Directive";
8622
+ CompileSummaryKind[CompileSummaryKind["NgModule"] = 2] = "NgModule";
8623
+ CompileSummaryKind[CompileSummaryKind["Injectable"] = 3] = "Injectable";
8624
+ })(CompileSummaryKind || (CompileSummaryKind = {}));
8625
+ function flatten(list) {
8626
+ return list.reduce((flat, item) => {
8627
+ const flatItem = Array.isArray(item) ? flatten(item) : item;
8628
+ return flat.concat(flatItem);
8629
+ }, []);
8630
+ }
8631
+
8632
8632
  /**
8633
8633
  * @license
8634
8634
  * Copyright Google LLC All Rights Reserved.
@@ -11540,16 +11540,16 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11540
11540
  (code < $0 || code > $9);
11541
11541
  }
11542
11542
  function isDigitEntityEnd(code) {
11543
- return code == $SEMICOLON || code == $EOF || !isAsciiHexDigit(code);
11543
+ return code === $SEMICOLON || code === $EOF || !isAsciiHexDigit(code);
11544
11544
  }
11545
11545
  function isNamedEntityEnd(code) {
11546
- return code == $SEMICOLON || code == $EOF || !isAsciiLetter(code);
11546
+ return code === $SEMICOLON || code === $EOF || !isAsciiLetter(code);
11547
11547
  }
11548
11548
  function isExpansionCaseStart(peek) {
11549
11549
  return peek !== $RBRACE;
11550
11550
  }
11551
11551
  function compareCharCodeCaseInsensitive(code1, code2) {
11552
- return toUpperCaseCharCode(code1) == toUpperCaseCharCode(code2);
11552
+ return toUpperCaseCharCode(code1) === toUpperCaseCharCode(code2);
11553
11553
  }
11554
11554
  function toUpperCaseCharCode(code) {
11555
11555
  return code >= $a && code <= $z ? code - $a + $A : code;
@@ -11559,7 +11559,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11559
11559
  let lastDstToken = undefined;
11560
11560
  for (let i = 0; i < srcTokens.length; i++) {
11561
11561
  const token = srcTokens[i];
11562
- if (lastDstToken && lastDstToken.type == TokenType.TEXT && token.type == TokenType.TEXT) {
11562
+ if (lastDstToken && lastDstToken.type === TokenType.TEXT && token.type === TokenType.TEXT) {
11563
11563
  lastDstToken.parts[0] += token.parts[0];
11564
11564
  lastDstToken.sourceSpan.end = token.sourceSpan.end;
11565
11565
  }
@@ -11963,7 +11963,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11963
11963
  if (this._peek.type === TokenType.EXPANSION_CASE_EXP_END) {
11964
11964
  if (lastOnStack(expansionFormStack, TokenType.EXPANSION_CASE_EXP_START)) {
11965
11965
  expansionFormStack.pop();
11966
- if (expansionFormStack.length == 0)
11966
+ if (expansionFormStack.length === 0)
11967
11967
  return exp;
11968
11968
  }
11969
11969
  else {
@@ -11989,9 +11989,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11989
11989
  }
11990
11990
  _consumeText(token) {
11991
11991
  let text = token.parts[0];
11992
- if (text.length > 0 && text[0] == '\n') {
11992
+ if (text.length > 0 && text[0] === '\n') {
11993
11993
  const parent = this._getParentElement();
11994
- if (parent != null && parent.children.length == 0 &&
11994
+ if (parent != null && parent.children.length === 0 &&
11995
11995
  this.getTagDefinition(parent.name).ignoreFirstLf) {
11996
11996
  text = text.substring(1);
11997
11997
  }
@@ -12074,7 +12074,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
12074
12074
  let unexpectedCloseTagDetected = false;
12075
12075
  for (let stackIndex = this._elementStack.length - 1; stackIndex >= 0; stackIndex--) {
12076
12076
  const el = this._elementStack[stackIndex];
12077
- if (el.name == fullName) {
12077
+ if (el.name === fullName) {
12078
12078
  // Record the parse span with the element that is being closed. Any elements that are
12079
12079
  // removed from the element stack at this point are closed implicitly, so they won't get
12080
12080
  // an end source span (as there is no explicit closing element).
@@ -13866,9 +13866,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
13866
13866
  function isExponentSign(code) {
13867
13867
  return code == $MINUS || code == $PLUS;
13868
13868
  }
13869
- function isQuote(code) {
13870
- return code === $SQ || code === $DQ || code === $BT;
13871
- }
13872
13869
  function unescape(code) {
13873
13870
  switch (code) {
13874
13871
  case $n:
@@ -19941,7 +19938,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19941
19938
  * Use of this source code is governed by an MIT-style license that can be
19942
19939
  * found in the LICENSE file at https://angular.io/license
19943
19940
  */
19944
- const VERSION$1 = new Version('12.2.0-next.3');
19941
+ const VERSION$1 = new Version('12.2.2');
19945
19942
 
19946
19943
  /**
19947
19944
  * @license
@@ -20580,7 +20577,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20580
20577
  function compileDeclareClassMetadata(metadata) {
20581
20578
  const definitionMap = new DefinitionMap();
20582
20579
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
20583
- definitionMap.set('version', literal('12.2.0-next.3'));
20580
+ definitionMap.set('version', literal('12.2.2'));
20584
20581
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20585
20582
  definitionMap.set('type', metadata.type);
20586
20583
  definitionMap.set('decorators', metadata.decorators);
@@ -20620,7 +20617,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20620
20617
  function createDirectiveDefinitionMap(meta) {
20621
20618
  const definitionMap = new DefinitionMap();
20622
20619
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
20623
- definitionMap.set('version', literal('12.2.0-next.3'));
20620
+ definitionMap.set('version', literal('12.2.2'));
20624
20621
  // e.g. `type: MyDirective`
20625
20622
  definitionMap.set('type', meta.internalType);
20626
20623
  // e.g. `selector: 'some-dir'`
@@ -20837,7 +20834,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20837
20834
  function compileDeclareFactoryFunction(meta) {
20838
20835
  const definitionMap = new DefinitionMap();
20839
20836
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
20840
- definitionMap.set('version', literal('12.2.0-next.3'));
20837
+ definitionMap.set('version', literal('12.2.2'));
20841
20838
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20842
20839
  definitionMap.set('type', meta.internalType);
20843
20840
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -20879,7 +20876,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20879
20876
  function createInjectableDefinitionMap(meta) {
20880
20877
  const definitionMap = new DefinitionMap();
20881
20878
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
20882
- definitionMap.set('version', literal('12.2.0-next.3'));
20879
+ definitionMap.set('version', literal('12.2.2'));
20883
20880
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20884
20881
  definitionMap.set('type', meta.internalType);
20885
20882
  // Only generate providedIn property if it has a non-null value
@@ -20958,7 +20955,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20958
20955
  function createInjectorDefinitionMap(meta) {
20959
20956
  const definitionMap = new DefinitionMap();
20960
20957
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
20961
- definitionMap.set('version', literal('12.2.0-next.3'));
20958
+ definitionMap.set('version', literal('12.2.2'));
20962
20959
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20963
20960
  definitionMap.set('type', meta.internalType);
20964
20961
  definitionMap.set('providers', meta.providers);
@@ -20995,7 +20992,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20995
20992
  function createNgModuleDefinitionMap(meta) {
20996
20993
  const definitionMap = new DefinitionMap();
20997
20994
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
20998
- definitionMap.set('version', literal('12.2.0-next.3'));
20995
+ definitionMap.set('version', literal('12.2.2'));
20999
20996
  definitionMap.set('ngImport', importExpr(Identifiers.core));
21000
20997
  definitionMap.set('type', meta.internalType);
21001
20998
  // We only generate the keys in the metadata if the arrays contain values.
@@ -21053,7 +21050,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21053
21050
  function createPipeDefinitionMap(meta) {
21054
21051
  const definitionMap = new DefinitionMap();
21055
21052
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
21056
- definitionMap.set('version', literal('12.2.0-next.3'));
21053
+ definitionMap.set('version', literal('12.2.2'));
21057
21054
  definitionMap.set('ngImport', importExpr(Identifiers.core));
21058
21055
  // e.g. `type: MyPipe`
21059
21056
  definitionMap.set('type', meta.internalType);
@@ -21085,7 +21082,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21085
21082
  * Use of this source code is governed by an MIT-style license that can be
21086
21083
  * found in the LICENSE file at https://angular.io/license
21087
21084
  */
21088
- const VERSION$2 = new Version('12.2.0-next.3');
21085
+ const VERSION$2 = new Version('12.2.2');
21089
21086
 
21090
21087
  /**
21091
21088
  * @license
@@ -21288,6 +21285,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21288
21285
  * in which the input and output are going to different places.
21289
21286
  */
21290
21287
  ErrorCode[ErrorCode["SPLIT_TWO_WAY_BINDING"] = 8007] = "SPLIT_TWO_WAY_BINDING";
21288
+ /**
21289
+ * A two way binding in a template has an incorrect syntax,
21290
+ * parentheses outside brackets. For example:
21291
+ *
21292
+ * ```
21293
+ * <div ([foo])="bar" />
21294
+ * ```
21295
+ */
21296
+ ErrorCode[ErrorCode["INVALID_BANANA_IN_BOX"] = 8101] = "INVALID_BANANA_IN_BOX";
21291
21297
  /**
21292
21298
  * The template type-checking engine would need to generate an inline type check block for a
21293
21299
  * component, but the current type-checking environment doesn't support it.
@@ -23770,7 +23776,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
23770
23776
  * Use of this source code is governed by an MIT-style license that can be
23771
23777
  * found in the LICENSE file at https://angular.io/license
23772
23778
  */
23773
- function extractReferencesFromType(checker, def, ngModuleImportedFrom, resolutionContext) {
23779
+ function extractReferencesFromType(checker, def, bestGuessOwningModule) {
23774
23780
  if (!ts$1.isTupleTypeNode(def)) {
23775
23781
  return [];
23776
23782
  }
@@ -23783,12 +23789,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
23783
23789
  if (!isNamedClassDeclaration(node)) {
23784
23790
  throw new Error(`Expected named ClassDeclaration: ${nodeDebugInfo(node)}`);
23785
23791
  }
23786
- const specifier = (from !== null && !from.startsWith('.') ? from : ngModuleImportedFrom);
23787
- if (specifier !== null) {
23788
- return new Reference$1(node, { specifier, resolutionContext });
23792
+ if (from !== null && !from.startsWith('.')) {
23793
+ // The symbol was imported using an absolute module specifier so return a reference that
23794
+ // uses that absolute module specifier as its best guess owning module.
23795
+ return new Reference$1(node, { specifier: from, resolutionContext: def.getSourceFile().fileName });
23789
23796
  }
23790
23797
  else {
23791
- return new Reference$1(node);
23798
+ // For local symbols or symbols that were imported using a relative module import it is
23799
+ // assumed that the symbol is exported from the provided best guess owning module.
23800
+ return new Reference$1(node, bestGuessOwningModule);
23792
23801
  }
23793
23802
  });
23794
23803
  }
@@ -23983,7 +23992,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
23983
23992
  */
23984
23993
  getNgModuleMetadata(ref) {
23985
23994
  const clazz = ref.node;
23986
- const resolutionContext = clazz.getSourceFile().fileName;
23987
23995
  // This operation is explicitly not memoized, as it depends on `ref.ownedByModuleGuess`.
23988
23996
  // TODO(alxhub): investigate caching of .d.ts module metadata.
23989
23997
  const ngModuleDef = this.reflector.getMembersOfClass(clazz).find(member => member.name === 'ɵmod' && member.isStatic);
@@ -24001,9 +24009,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
24001
24009
  const [_, declarationMetadata, importMetadata, exportMetadata] = ngModuleDef.type.typeArguments;
24002
24010
  return {
24003
24011
  ref,
24004
- declarations: extractReferencesFromType(this.checker, declarationMetadata, ref.ownedByModuleGuess, resolutionContext),
24005
- exports: extractReferencesFromType(this.checker, exportMetadata, ref.ownedByModuleGuess, resolutionContext),
24006
- imports: extractReferencesFromType(this.checker, importMetadata, ref.ownedByModuleGuess, resolutionContext),
24012
+ declarations: extractReferencesFromType(this.checker, declarationMetadata, ref.bestGuessOwningModule),
24013
+ exports: extractReferencesFromType(this.checker, exportMetadata, ref.bestGuessOwningModule),
24014
+ imports: extractReferencesFromType(this.checker, importMetadata, ref.bestGuessOwningModule),
24007
24015
  schemas: [],
24008
24016
  rawDeclarations: null,
24009
24017
  };
@@ -26189,6 +26197,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
26189
26197
  * Ivy traits.
26190
26198
  */
26191
26199
  this.fileToClasses = new Map();
26200
+ /**
26201
+ * Tracks which source files have been analyzed but did not contain any traits. This set allows
26202
+ * the compiler to skip analyzing these files in an incremental rebuild.
26203
+ */
26204
+ this.filesWithoutTraits = new Set();
26192
26205
  this.reexportMap = new Map();
26193
26206
  this.handlersByName = new Map();
26194
26207
  for (const handler of handlers) {
@@ -26211,11 +26224,16 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
26211
26224
  const promises = [];
26212
26225
  const priorWork = this.incrementalBuild.priorAnalysisFor(sf);
26213
26226
  if (priorWork !== null) {
26214
- for (const priorRecord of priorWork) {
26215
- this.adopt(priorRecord);
26216
- }
26217
26227
  this.perf.eventCount(PerfEvent.SourceFileReuseAnalysis);
26218
- this.perf.eventCount(PerfEvent.TraitReuseAnalysis, priorWork.length);
26228
+ if (priorWork.length > 0) {
26229
+ for (const priorRecord of priorWork) {
26230
+ this.adopt(priorRecord);
26231
+ }
26232
+ this.perf.eventCount(PerfEvent.TraitReuseAnalysis, priorWork.length);
26233
+ }
26234
+ else {
26235
+ this.filesWithoutTraits.add(sf);
26236
+ }
26219
26237
  // Skip the rest of analysis, as this file's prior traits are being reused.
26220
26238
  return;
26221
26239
  }
@@ -26260,6 +26278,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
26260
26278
  }
26261
26279
  result.set(sf, records);
26262
26280
  }
26281
+ for (const sf of this.filesWithoutTraits) {
26282
+ result.set(sf, []);
26283
+ }
26263
26284
  return result;
26264
26285
  }
26265
26286
  /**
@@ -34534,6 +34555,128 @@ Either add the @Injectable() decorator to '${provider.node.name
34534
34555
  SymbolKind[SymbolKind["Pipe"] = 10] = "Pipe";
34535
34556
  })(SymbolKind || (SymbolKind = {}));
34536
34557
 
34558
+ /**
34559
+ * @license
34560
+ * Copyright Google LLC All Rights Reserved.
34561
+ *
34562
+ * Use of this source code is governed by an MIT-style license that can be
34563
+ * found in the LICENSE file at https://angular.io/license
34564
+ */
34565
+ /**
34566
+ * Constructs a `ts.Diagnostic` for a given `ParseSourceSpan` within a template.
34567
+ */
34568
+ function makeTemplateDiagnostic(templateId, mapping, span, category, code, messageText, relatedMessages) {
34569
+ if (mapping.type === 'direct') {
34570
+ let relatedInformation = undefined;
34571
+ if (relatedMessages !== undefined) {
34572
+ relatedInformation = [];
34573
+ for (const relatedMessage of relatedMessages) {
34574
+ relatedInformation.push({
34575
+ category: ts$1.DiagnosticCategory.Message,
34576
+ code: 0,
34577
+ file: relatedMessage.sourceFile,
34578
+ start: relatedMessage.start,
34579
+ length: relatedMessage.end - relatedMessage.start,
34580
+ messageText: relatedMessage.text,
34581
+ });
34582
+ }
34583
+ }
34584
+ // For direct mappings, the error is shown inline as ngtsc was able to pinpoint a string
34585
+ // constant within the `@Component` decorator for the template. This allows us to map the error
34586
+ // directly into the bytes of the source file.
34587
+ return {
34588
+ source: 'ngtsc',
34589
+ code,
34590
+ category,
34591
+ messageText,
34592
+ file: mapping.node.getSourceFile(),
34593
+ componentFile: mapping.node.getSourceFile(),
34594
+ templateId,
34595
+ start: span.start.offset,
34596
+ length: span.end.offset - span.start.offset,
34597
+ relatedInformation,
34598
+ };
34599
+ }
34600
+ else if (mapping.type === 'indirect' || mapping.type === 'external') {
34601
+ // For indirect mappings (template was declared inline, but ngtsc couldn't map it directly
34602
+ // to a string constant in the decorator), the component's file name is given with a suffix
34603
+ // indicating it's not the TS file being displayed, but a template.
34604
+ // For external temoplates, the HTML filename is used.
34605
+ const componentSf = mapping.componentClass.getSourceFile();
34606
+ const componentName = mapping.componentClass.name.text;
34607
+ // TODO(alxhub): remove cast when TS in g3 supports this narrowing.
34608
+ const fileName = mapping.type === 'indirect' ?
34609
+ `${componentSf.fileName} (${componentName} template)` :
34610
+ mapping.templateUrl;
34611
+ // TODO(alxhub): investigate creating a fake `ts.SourceFile` here instead of invoking the TS
34612
+ // parser against the template (HTML is just really syntactically invalid TypeScript code ;).
34613
+ // Also investigate caching the file to avoid running the parser multiple times.
34614
+ const sf = ts$1.createSourceFile(fileName, mapping.template, ts$1.ScriptTarget.Latest, false, ts$1.ScriptKind.JSX);
34615
+ let relatedInformation = [];
34616
+ if (relatedMessages !== undefined) {
34617
+ for (const relatedMessage of relatedMessages) {
34618
+ relatedInformation.push({
34619
+ category: ts$1.DiagnosticCategory.Message,
34620
+ code: 0,
34621
+ file: relatedMessage.sourceFile,
34622
+ start: relatedMessage.start,
34623
+ length: relatedMessage.end - relatedMessage.start,
34624
+ messageText: relatedMessage.text,
34625
+ });
34626
+ }
34627
+ }
34628
+ relatedInformation.push({
34629
+ category: ts$1.DiagnosticCategory.Message,
34630
+ code: 0,
34631
+ file: componentSf,
34632
+ // mapping.node represents either the 'template' or 'templateUrl' expression. getStart()
34633
+ // and getEnd() are used because they don't include surrounding whitespace.
34634
+ start: mapping.node.getStart(),
34635
+ length: mapping.node.getEnd() - mapping.node.getStart(),
34636
+ messageText: `Error occurs in the template of component ${componentName}.`,
34637
+ });
34638
+ return {
34639
+ source: 'ngtsc',
34640
+ category,
34641
+ code,
34642
+ messageText,
34643
+ file: sf,
34644
+ componentFile: componentSf,
34645
+ templateId,
34646
+ start: span.start.offset,
34647
+ length: span.end.offset - span.start.offset,
34648
+ // Show a secondary message indicating the component whose template contains the error.
34649
+ relatedInformation,
34650
+ };
34651
+ }
34652
+ else {
34653
+ throw new Error(`Unexpected source mapping type: ${mapping.type}`);
34654
+ }
34655
+ }
34656
+
34657
+ /**
34658
+ * @license
34659
+ * Copyright Google LLC All Rights Reserved.
34660
+ *
34661
+ * Use of this source code is governed by an MIT-style license that can be
34662
+ * found in the LICENSE file at https://angular.io/license
34663
+ */
34664
+ const TEMPLATE_ID = Symbol('ngTemplateId');
34665
+ const NEXT_TEMPLATE_ID = Symbol('ngNextTemplateId');
34666
+ function getTemplateId(clazz) {
34667
+ const node = clazz;
34668
+ if (node[TEMPLATE_ID] === undefined) {
34669
+ node[TEMPLATE_ID] = allocateTemplateId(node.getSourceFile());
34670
+ }
34671
+ return node[TEMPLATE_ID];
34672
+ }
34673
+ function allocateTemplateId(sf) {
34674
+ if (sf[NEXT_TEMPLATE_ID] === undefined) {
34675
+ sf[NEXT_TEMPLATE_ID] = 1;
34676
+ }
34677
+ return (`tcb${sf[NEXT_TEMPLATE_ID]++}`);
34678
+ }
34679
+
34537
34680
  /**
34538
34681
  * @license
34539
34682
  * Copyright Google LLC All Rights Reserved.
@@ -34762,6 +34905,18 @@ Either add the @Injectable() decorator to '${provider.node.name
34762
34905
  };
34763
34906
  }
34764
34907
  }
34908
+ if (node instanceof PropertyRead && node.receiver instanceof ImplicitReceiver) {
34909
+ const nodeLocation = findFirstMatchingNode(this.tcb, {
34910
+ filter: ts$1.isPropertyAccessExpression,
34911
+ withSpan: node.sourceSpan,
34912
+ });
34913
+ if (nodeLocation) {
34914
+ nodeContext = {
34915
+ shimPath: this.shimPath,
34916
+ positionInShimFile: nodeLocation.getStart(),
34917
+ };
34918
+ }
34919
+ }
34765
34920
  return {
34766
34921
  componentContext: this.componentContext,
34767
34922
  templateContext,
@@ -34811,6 +34966,41 @@ Either add the @Injectable() decorator to '${provider.node.name
34811
34966
  this.expressionCompletionCache.set(expr, res);
34812
34967
  return res;
34813
34968
  }
34969
+ getLiteralCompletionLocation(expr) {
34970
+ if (this.expressionCompletionCache.has(expr)) {
34971
+ return this.expressionCompletionCache.get(expr);
34972
+ }
34973
+ let tsExpr = null;
34974
+ if (expr instanceof TextAttribute) {
34975
+ const strNode = findFirstMatchingNode(this.tcb, {
34976
+ filter: ts$1.isParenthesizedExpression,
34977
+ withSpan: expr.sourceSpan,
34978
+ });
34979
+ if (strNode !== null && ts$1.isStringLiteral(strNode.expression)) {
34980
+ tsExpr = strNode.expression;
34981
+ }
34982
+ }
34983
+ else {
34984
+ tsExpr = findFirstMatchingNode(this.tcb, {
34985
+ filter: (n) => ts$1.isStringLiteral(n) || ts$1.isNumericLiteral(n),
34986
+ withSpan: expr.sourceSpan,
34987
+ });
34988
+ }
34989
+ if (tsExpr === null) {
34990
+ return null;
34991
+ }
34992
+ let positionInShimFile = tsExpr.getEnd();
34993
+ if (ts$1.isStringLiteral(tsExpr)) {
34994
+ // In the shimFile, if `tsExpr` is a string, the position should be in the quotes.
34995
+ positionInShimFile -= 1;
34996
+ }
34997
+ const res = {
34998
+ shimPath: this.shimPath,
34999
+ positionInShimFile,
35000
+ };
35001
+ this.expressionCompletionCache.set(expr, res);
35002
+ return res;
35003
+ }
34814
35004
  /**
34815
35005
  * Get global completions within the given template context - either a `TmplAstTemplate` embedded
34816
35006
  * view, or `null` for the root context.
@@ -34841,128 +35031,6 @@ Either add the @Injectable() decorator to '${provider.node.name
34841
35031
  }
34842
35032
  }
34843
35033
 
34844
- /**
34845
- * @license
34846
- * Copyright Google LLC All Rights Reserved.
34847
- *
34848
- * Use of this source code is governed by an MIT-style license that can be
34849
- * found in the LICENSE file at https://angular.io/license
34850
- */
34851
- /**
34852
- * Constructs a `ts.Diagnostic` for a given `ParseSourceSpan` within a template.
34853
- */
34854
- function makeTemplateDiagnostic(templateId, mapping, span, category, code, messageText, relatedMessages) {
34855
- if (mapping.type === 'direct') {
34856
- let relatedInformation = undefined;
34857
- if (relatedMessages !== undefined) {
34858
- relatedInformation = [];
34859
- for (const relatedMessage of relatedMessages) {
34860
- relatedInformation.push({
34861
- category: ts$1.DiagnosticCategory.Message,
34862
- code: 0,
34863
- file: relatedMessage.sourceFile,
34864
- start: relatedMessage.start,
34865
- length: relatedMessage.end - relatedMessage.start,
34866
- messageText: relatedMessage.text,
34867
- });
34868
- }
34869
- }
34870
- // For direct mappings, the error is shown inline as ngtsc was able to pinpoint a string
34871
- // constant within the `@Component` decorator for the template. This allows us to map the error
34872
- // directly into the bytes of the source file.
34873
- return {
34874
- source: 'ngtsc',
34875
- code,
34876
- category,
34877
- messageText,
34878
- file: mapping.node.getSourceFile(),
34879
- componentFile: mapping.node.getSourceFile(),
34880
- templateId,
34881
- start: span.start.offset,
34882
- length: span.end.offset - span.start.offset,
34883
- relatedInformation,
34884
- };
34885
- }
34886
- else if (mapping.type === 'indirect' || mapping.type === 'external') {
34887
- // For indirect mappings (template was declared inline, but ngtsc couldn't map it directly
34888
- // to a string constant in the decorator), the component's file name is given with a suffix
34889
- // indicating it's not the TS file being displayed, but a template.
34890
- // For external temoplates, the HTML filename is used.
34891
- const componentSf = mapping.componentClass.getSourceFile();
34892
- const componentName = mapping.componentClass.name.text;
34893
- // TODO(alxhub): remove cast when TS in g3 supports this narrowing.
34894
- const fileName = mapping.type === 'indirect' ?
34895
- `${componentSf.fileName} (${componentName} template)` :
34896
- mapping.templateUrl;
34897
- // TODO(alxhub): investigate creating a fake `ts.SourceFile` here instead of invoking the TS
34898
- // parser against the template (HTML is just really syntactically invalid TypeScript code ;).
34899
- // Also investigate caching the file to avoid running the parser multiple times.
34900
- const sf = ts$1.createSourceFile(fileName, mapping.template, ts$1.ScriptTarget.Latest, false, ts$1.ScriptKind.JSX);
34901
- let relatedInformation = [];
34902
- if (relatedMessages !== undefined) {
34903
- for (const relatedMessage of relatedMessages) {
34904
- relatedInformation.push({
34905
- category: ts$1.DiagnosticCategory.Message,
34906
- code: 0,
34907
- file: relatedMessage.sourceFile,
34908
- start: relatedMessage.start,
34909
- length: relatedMessage.end - relatedMessage.start,
34910
- messageText: relatedMessage.text,
34911
- });
34912
- }
34913
- }
34914
- relatedInformation.push({
34915
- category: ts$1.DiagnosticCategory.Message,
34916
- code: 0,
34917
- file: componentSf,
34918
- // mapping.node represents either the 'template' or 'templateUrl' expression. getStart()
34919
- // and getEnd() are used because they don't include surrounding whitespace.
34920
- start: mapping.node.getStart(),
34921
- length: mapping.node.getEnd() - mapping.node.getStart(),
34922
- messageText: `Error occurs in the template of component ${componentName}.`,
34923
- });
34924
- return {
34925
- source: 'ngtsc',
34926
- category,
34927
- code,
34928
- messageText,
34929
- file: sf,
34930
- componentFile: componentSf,
34931
- templateId,
34932
- start: span.start.offset,
34933
- length: span.end.offset - span.start.offset,
34934
- // Show a secondary message indicating the component whose template contains the error.
34935
- relatedInformation,
34936
- };
34937
- }
34938
- else {
34939
- throw new Error(`Unexpected source mapping type: ${mapping.type}`);
34940
- }
34941
- }
34942
-
34943
- /**
34944
- * @license
34945
- * Copyright Google LLC All Rights Reserved.
34946
- *
34947
- * Use of this source code is governed by an MIT-style license that can be
34948
- * found in the LICENSE file at https://angular.io/license
34949
- */
34950
- const TEMPLATE_ID = Symbol('ngTemplateId');
34951
- const NEXT_TEMPLATE_ID = Symbol('ngNextTemplateId');
34952
- function getTemplateId(clazz) {
34953
- const node = clazz;
34954
- if (node[TEMPLATE_ID] === undefined) {
34955
- node[TEMPLATE_ID] = allocateTemplateId(node.getSourceFile());
34956
- }
34957
- return node[TEMPLATE_ID];
34958
- }
34959
- function allocateTemplateId(sf) {
34960
- if (sf[NEXT_TEMPLATE_ID] === undefined) {
34961
- sf[NEXT_TEMPLATE_ID] = 1;
34962
- }
34963
- return (`tcb${sf[NEXT_TEMPLATE_ID]++}`);
34964
- }
34965
-
34966
35034
  /**
34967
35035
  * @license
34968
35036
  * Copyright Google LLC All Rights Reserved.
@@ -39637,6 +39705,13 @@ Either add the @Injectable() decorator to '${provider.node.name
39637
39705
  }
39638
39706
  return this.perf.inPhase(PerfPhase.TtcAutocompletion, () => engine.getExpressionCompletionLocation(ast));
39639
39707
  }
39708
+ getLiteralCompletionLocation(node, component) {
39709
+ const engine = this.getOrCreateCompletionEngine(component);
39710
+ if (engine === null) {
39711
+ return null;
39712
+ }
39713
+ return this.perf.inPhase(PerfPhase.TtcAutocompletion, () => engine.getLiteralCompletionLocation(node));
39714
+ }
39640
39715
  invalidateClass(clazz) {
39641
39716
  this.completionCache.delete(clazz);
39642
39717
  this.symbolBuilderCache.delete(clazz);
@@ -39651,6 +39726,13 @@ Either add the @Injectable() decorator to '${provider.node.name
39651
39726
  fileData.isComplete = false;
39652
39727
  this.isComplete = false;
39653
39728
  }
39729
+ makeTemplateDiagnostic(clazz, sourceSpan, category, errorCode, message, relatedInformation) {
39730
+ const sfPath = absoluteFromSourceFile(clazz.getSourceFile());
39731
+ const fileRecord = this.state.get(sfPath);
39732
+ const templateId = fileRecord.sourceManager.getTemplateId(clazz);
39733
+ const mapping = fileRecord.sourceManager.getSourceMapping(templateId);
39734
+ return makeTemplateDiagnostic(templateId, mapping, sourceSpan, category, errorCode, message, relatedInformation);
39735
+ }
39654
39736
  getOrCreateCompletionEngine(component) {
39655
39737
  if (this.completionCache.has(component)) {
39656
39738
  return this.completionCache.get(component);
@@ -40011,21 +40093,6 @@ Either add the @Injectable() decorator to '${provider.node.name
40011
40093
  }
40012
40094
  }
40013
40095
 
40014
- /**
40015
- * @license
40016
- * Copyright Google LLC All Rights Reserved.
40017
- *
40018
- * Use of this source code is governed by an MIT-style license that can be
40019
- * found in the LICENSE file at https://angular.io/license
40020
- */
40021
- // This file exists as a target for g3 patches which change the Angular compiler's behavior.
40022
- // Separating the patched code in a separate file eliminates the possibility of conflicts with the
40023
- // patch diffs when making changes to the rest of the compiler codebase.
40024
- // In ngtsc we no longer want to compile undecorated classes with Angular features.
40025
- // Migrations for these patterns ran as part of `ng update` and we want to ensure
40026
- // that projects do not regress. See https://hackmd.io/@alx/ryfYYuvzH for more details.
40027
- const compileUndecoratedClassesWithAngularFeatures = false;
40028
-
40029
40096
  /**
40030
40097
  * @license
40031
40098
  * Copyright Google LLC All Rights Reserved.
@@ -40749,7 +40816,7 @@ Either add the @Injectable() decorator to '${provider.node.name
40749
40816
  // TODO(alxhub): understand why the cast here is necessary (something to do with `null`
40750
40817
  // not being assignable to `unknown` when wrapped in `Readonly`).
40751
40818
  // clang-format off
40752
- new DirectiveDecoratorHandler(reflector, evaluator, metaRegistry, scopeRegistry, metaReader, injectableRegistry, isCore, semanticDepGraphUpdater, this.closureCompilerEnabled, compileUndecoratedClassesWithAngularFeatures, this.delegatingPerfRecorder),
40819
+ new DirectiveDecoratorHandler(reflector, evaluator, metaRegistry, scopeRegistry, metaReader, injectableRegistry, isCore, semanticDepGraphUpdater, this.closureCompilerEnabled, /** compileUndecoratedClassesWithAngularFeatures */ false, this.delegatingPerfRecorder),
40753
40820
  // clang-format on
40754
40821
  // Pipe handler must be before injectable handler in list so pipe factories are printed
40755
40822
  // before injectable factories (so injectable factories can delegate to them)
@@ -42548,10 +42615,58 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
42548
42615
  else if (this.isPipeCompletion()) {
42549
42616
  return this.getPipeCompletions();
42550
42617
  }
42618
+ else if (this.isLiteralCompletion()) {
42619
+ return this.getLiteralCompletions(options);
42620
+ }
42551
42621
  else {
42552
42622
  return undefined;
42553
42623
  }
42554
42624
  }
42625
+ isLiteralCompletion() {
42626
+ return this.node instanceof LiteralPrimitive ||
42627
+ (this.node instanceof TextAttribute &&
42628
+ this.nodeContext === CompletionNodeContext.ElementAttributeValue);
42629
+ }
42630
+ getLiteralCompletions(options) {
42631
+ const location = this.compiler.getTemplateTypeChecker().getLiteralCompletionLocation(this.node, this.component);
42632
+ if (location === null) {
42633
+ return undefined;
42634
+ }
42635
+ const tsResults = this.tsLS.getCompletionsAtPosition(location.shimPath, location.positionInShimFile, options);
42636
+ if (tsResults === undefined) {
42637
+ return undefined;
42638
+ }
42639
+ let replacementSpan;
42640
+ if (this.node instanceof TextAttribute && this.node.value.length > 0 && this.node.valueSpan) {
42641
+ replacementSpan = {
42642
+ start: this.node.valueSpan.start.offset,
42643
+ length: this.node.value.length,
42644
+ };
42645
+ }
42646
+ if (this.node instanceof LiteralPrimitive) {
42647
+ if (typeof this.node.value === 'string' && this.node.value.length > 0) {
42648
+ replacementSpan = {
42649
+ // The sourceSpan of `LiteralPrimitive` includes the open quote and the completion entries
42650
+ // don't, so skip the open quote here.
42651
+ start: this.node.sourceSpan.start + 1,
42652
+ length: this.node.value.length,
42653
+ };
42654
+ }
42655
+ else if (typeof this.node.value === 'number') {
42656
+ replacementSpan = {
42657
+ start: this.node.sourceSpan.start,
42658
+ length: this.node.value.toString().length,
42659
+ };
42660
+ }
42661
+ }
42662
+ let ngResults = [];
42663
+ for (const result of tsResults.entries) {
42664
+ if (this.isValidNodeContextCompletion(result)) {
42665
+ ngResults.push(Object.assign(Object.assign({}, result), { replacementSpan }));
42666
+ }
42667
+ }
42668
+ return Object.assign(Object.assign({}, tsResults), { entries: ngResults });
42669
+ }
42555
42670
  /**
42556
42671
  * Analogue for `ts.LanguageService.getCompletionEntryDetails`.
42557
42672
  */
@@ -43114,6 +43229,9 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
43114
43229
  if (target.node instanceof BoundEvent) {
43115
43230
  return CompletionNodeContext.EventValue;
43116
43231
  }
43232
+ else if (target.node instanceof TextAttribute) {
43233
+ return CompletionNodeContext.ElementAttributeValue;
43234
+ }
43117
43235
  else {
43118
43236
  return CompletionNodeContext.None;
43119
43237
  }