@angular/language-service 12.2.0 → 12.2.4

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
2
+ * @license Angular v12.2.4
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.
@@ -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');
19941
+ const VERSION$1 = new Version('12.2.4');
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'));
20580
+ definitionMap.set('version', literal('12.2.4'));
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'));
20620
+ definitionMap.set('version', literal('12.2.4'));
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'));
20837
+ definitionMap.set('version', literal('12.2.4'));
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'));
20879
+ definitionMap.set('version', literal('12.2.4'));
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'));
20958
+ definitionMap.set('version', literal('12.2.4'));
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'));
20995
+ definitionMap.set('version', literal('12.2.4'));
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'));
21053
+ definitionMap.set('version', literal('12.2.4'));
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');
21085
+ const VERSION$2 = new Version('12.2.4');
21089
21086
 
21090
21087
  /**
21091
21088
  * @license
@@ -21288,6 +21285,24 @@ 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";
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";
21291
21306
  /**
21292
21307
  * The template type-checking engine would need to generate an inline type check block for a
21293
21308
  * component, but the current type-checking environment doesn't support it.
@@ -26540,6 +26555,26 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
26540
26555
  }
26541
26556
  }
26542
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
+ }
26543
26578
  index(ctx) {
26544
26579
  for (const clazz of this.classes.keys()) {
26545
26580
  const record = this.classes.get(clazz);
@@ -30547,6 +30582,9 @@ Either add the @Injectable() decorator to '${provider.node.name
30547
30582
  const binder = new R3TargetBinder(scope.matcher);
30548
30583
  ctx.addTemplate(new Reference$1(node), binder, meta.template.diagNodes, scope.pipes, scope.schemas, meta.template.sourceMapping, meta.template.file, meta.template.errors);
30549
30584
  }
30585
+ extendedTemplateCheck(component, extendedTemplateChecker) {
30586
+ return extendedTemplateChecker.getDiagnosticsForComponent(component);
30587
+ }
30550
30588
  resolve(node, analysis, symbol) {
30551
30589
  if (this.semanticDepGraphUpdater !== null && analysis.baseClass instanceof Reference$1) {
30552
30590
  symbol.baseClass = this.semanticDepGraphUpdater.getSymbol(analysis.baseClass.node);
@@ -39725,7 +39763,7 @@ Either add the @Injectable() decorator to '${provider.node.name
39725
39763
  const fileRecord = this.state.get(sfPath);
39726
39764
  const templateId = fileRecord.sourceManager.getTemplateId(clazz);
39727
39765
  const mapping = fileRecord.sourceManager.getSourceMapping(templateId);
39728
- return makeTemplateDiagnostic(templateId, mapping, sourceSpan, category, errorCode, message, relatedInformation);
39766
+ return Object.assign(Object.assign({}, makeTemplateDiagnostic(templateId, mapping, sourceSpan, category, ngErrorCode(errorCode), message, relatedInformation)), { __ngCode: errorCode });
39729
39767
  }
39730
39768
  getOrCreateCompletionEngine(component) {
39731
39769
  if (this.completionCache.has(component)) {
@@ -40094,13 +40132,187 @@ Either add the @Injectable() decorator to '${provider.node.name
40094
40132
  * Use of this source code is governed by an MIT-style license that can be
40095
40133
  * found in the LICENSE file at https://angular.io/license
40096
40134
  */
40097
- // This file exists as a target for g3 patches which change the Angular compiler's behavior.
40098
- // Separating the patched code in a separate file eliminates the possibility of conflicts with the
40099
- // patch diffs when making changes to the rest of the compiler codebase.
40100
- // In ngtsc we no longer want to compile undecorated classes with Angular features.
40101
- // Migrations for these patterns ran as part of `ng update` and we want to ensure
40102
- // that projects do not regress. See https://hackmd.io/@alx/ryfYYuvzH for more details.
40103
- const compileUndecoratedClassesWithAngularFeatures = false;
40135
+ class ExtendedTemplateCheckerImpl {
40136
+ constructor(templateTypeChecker, typeChecker, templateChecks) {
40137
+ this.templateChecks = templateChecks;
40138
+ this.ctx = { templateTypeChecker: templateTypeChecker, typeChecker: typeChecker };
40139
+ }
40140
+ getDiagnosticsForComponent(component) {
40141
+ const template = this.ctx.templateTypeChecker.getTemplate(component);
40142
+ // Skip checks if component has no template. This can happen if the user writes a
40143
+ // `@Component()` but doesn't add the template, could happen in the language service
40144
+ // when users are in the middle of typing code.
40145
+ if (template === null) {
40146
+ return [];
40147
+ }
40148
+ const diagnostics = [];
40149
+ for (const check of this.templateChecks) {
40150
+ diagnostics.push(...check.run(this.ctx, component, template));
40151
+ }
40152
+ return diagnostics;
40153
+ }
40154
+ }
40155
+
40156
+ /**
40157
+ * @license
40158
+ * Copyright Google LLC All Rights Reserved.
40159
+ *
40160
+ * Use of this source code is governed by an MIT-style license that can be
40161
+ * found in the LICENSE file at https://angular.io/license
40162
+ */
40163
+ /**
40164
+ * This abstract class provides a base implementation for the run method.
40165
+ */
40166
+ class TemplateCheckWithVisitor {
40167
+ /**
40168
+ * Base implementation for run function, visits all nodes in template and calls
40169
+ * `visitNode()` for each one.
40170
+ */
40171
+ run(ctx, component, template) {
40172
+ const visitor = new TemplateVisitor$1(ctx, component, this);
40173
+ return visitor.getDiagnostics(template);
40174
+ }
40175
+ }
40176
+ /**
40177
+ * Visits all nodes in a template (TmplAstNode and AST) and calls `visitNode` for each one.
40178
+ */
40179
+ class TemplateVisitor$1 extends RecursiveAstVisitor {
40180
+ constructor(ctx, component, check) {
40181
+ super();
40182
+ this.ctx = ctx;
40183
+ this.component = component;
40184
+ this.check = check;
40185
+ this.diagnostics = [];
40186
+ }
40187
+ visit(node, context) {
40188
+ this.diagnostics.push(...this.check.visitNode(this.ctx, this.component, node));
40189
+ node.visit(this);
40190
+ }
40191
+ visitAllNodes(nodes) {
40192
+ for (const node of nodes) {
40193
+ this.visit(node);
40194
+ }
40195
+ }
40196
+ visitAst(ast) {
40197
+ if (ast instanceof ASTWithSource) {
40198
+ ast = ast.ast;
40199
+ }
40200
+ this.visit(ast);
40201
+ }
40202
+ visitElement(element) {
40203
+ this.visitAllNodes(element.attributes);
40204
+ this.visitAllNodes(element.inputs);
40205
+ this.visitAllNodes(element.outputs);
40206
+ this.visitAllNodes(element.references);
40207
+ this.visitAllNodes(element.children);
40208
+ }
40209
+ visitTemplate(template) {
40210
+ this.visitAllNodes(template.attributes);
40211
+ if (template.tagName === 'ng-template') {
40212
+ // Only visit input/outputs/templateAttrs if this isn't an inline template node
40213
+ // generated for a structural directive (like `<div *ngIf></div>`). These nodes
40214
+ // would be visited when the underlying element of an inline template node is processed.
40215
+ this.visitAllNodes(template.inputs);
40216
+ this.visitAllNodes(template.outputs);
40217
+ this.visitAllNodes(template.templateAttrs);
40218
+ }
40219
+ this.visitAllNodes(template.variables);
40220
+ this.visitAllNodes(template.references);
40221
+ this.visitAllNodes(template.children);
40222
+ }
40223
+ visitContent(content) { }
40224
+ visitVariable(variable) { }
40225
+ visitReference(reference) { }
40226
+ visitTextAttribute(attribute) { }
40227
+ visitBoundAttribute(attribute) {
40228
+ this.visitAst(attribute.value);
40229
+ }
40230
+ visitBoundEvent(attribute) {
40231
+ this.visitAst(attribute.handler);
40232
+ }
40233
+ visitText(text) { }
40234
+ visitBoundText(text) {
40235
+ this.visitAst(text.value);
40236
+ }
40237
+ visitIcu(icu) { }
40238
+ getDiagnostics(template) {
40239
+ this.diagnostics = [];
40240
+ this.visitAllNodes(template);
40241
+ return this.diagnostics;
40242
+ }
40243
+ }
40244
+
40245
+ /**
40246
+ * @license
40247
+ * Copyright Google LLC All Rights Reserved.
40248
+ *
40249
+ * Use of this source code is governed by an MIT-style license that can be
40250
+ * found in the LICENSE file at https://angular.io/license
40251
+ */
40252
+ /**
40253
+ * Ensures the two-way binding syntax is correct.
40254
+ * Parentheses should be inside the brackets "[()]".
40255
+ * Will return diagnostic information when "([])" is found.
40256
+ */
40257
+ class InvalidBananaInBoxCheck extends TemplateCheckWithVisitor {
40258
+ constructor() {
40259
+ super(...arguments);
40260
+ this.code = ErrorCode.INVALID_BANANA_IN_BOX;
40261
+ }
40262
+ visitNode(ctx, component, node) {
40263
+ if (!(node instanceof BoundEvent))
40264
+ return [];
40265
+ const name = node.name;
40266
+ if (!name.startsWith('[') || !name.endsWith(']'))
40267
+ return [];
40268
+ const boundSyntax = node.sourceSpan.toString();
40269
+ const expectedBoundSyntax = boundSyntax.replace(`(${name})`, `[(${name.slice(1, -1)})]`);
40270
+ 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}'.
40271
+ Find more at https://angular.io/guide/two-way-binding`);
40272
+ return [diagnostic];
40273
+ }
40274
+ }
40275
+
40276
+ /**
40277
+ * @license
40278
+ * Copyright Google LLC All Rights Reserved.
40279
+ *
40280
+ * Use of this source code is governed by an MIT-style license that can be
40281
+ * found in the LICENSE file at https://angular.io/license
40282
+ */
40283
+ /**
40284
+ * Ensures the left side of a nullish coalescing operation is nullable.
40285
+ * Returns diagnostics for the cases where the operator is useless.
40286
+ * This check should only be use if `strictNullChecks` is enabled,
40287
+ * otherwise it would produce inaccurate results.
40288
+ */
40289
+ class NullishCoalescingNotNullableCheck extends TemplateCheckWithVisitor {
40290
+ constructor() {
40291
+ super(...arguments);
40292
+ this.code = ErrorCode.NULLISH_COALESCING_NOT_NULLABLE;
40293
+ }
40294
+ visitNode(ctx, component, node) {
40295
+ if (!(node instanceof Binary) || node.operation !== '??')
40296
+ return [];
40297
+ const symbolLeft = ctx.templateTypeChecker.getSymbolOfNode(node.left, component);
40298
+ if (symbolLeft.kind !== SymbolKind.Expression) {
40299
+ return [];
40300
+ }
40301
+ const typeLeft = symbolLeft.tsType;
40302
+ // If the left operand's type is different from its non-nullable self, then it must
40303
+ // contain a null or undefined so this nullish coalescing operator is useful. No diagnostic to
40304
+ // report.
40305
+ if (typeLeft.getNonNullableType() !== typeLeft)
40306
+ return [];
40307
+ const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
40308
+ if (symbol.kind !== SymbolKind.Expression) {
40309
+ return [];
40310
+ }
40311
+ const span = ctx.templateTypeChecker.getTemplateMappingAtShimLocation(symbol.shimLocation).span;
40312
+ 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.`);
40313
+ return [diagnostic];
40314
+ }
40315
+ }
40104
40316
 
40105
40317
  /**
40106
40318
  * @license
@@ -40218,6 +40430,10 @@ Either add the @Injectable() decorator to '${provider.node.name
40218
40430
  * with each fresh compilation.
40219
40431
  */
40220
40432
  this.delegatingPerfRecorder = new DelegatingPerfRecorder(this.perfRecorder);
40433
+ if (this.options._extendedTemplateDiagnostics === true &&
40434
+ this.options.strictTemplates === false) {
40435
+ throw new Error('The \'_extendedTemplateDiagnostics\' option requires \'strictTemplates\' to also be enabled.');
40436
+ }
40221
40437
  this.constructionDiagnostics.push(...this.adapter.constructionDiagnostics);
40222
40438
  const incompatibleTypeCheckOptionsDiagnostic = verifyCompatibleTypeCheckOptions(this.options);
40223
40439
  if (incompatibleTypeCheckOptionsDiagnostic !== null) {
@@ -40327,7 +40543,12 @@ Either add the @Injectable() decorator to '${provider.node.name
40327
40543
  * Get all Angular-related diagnostics for this compilation.
40328
40544
  */
40329
40545
  getDiagnostics() {
40330
- return this.addMessageTextDetails([...this.getNonTemplateDiagnostics(), ...this.getTemplateDiagnostics()]);
40546
+ const diagnostics = [];
40547
+ diagnostics.push(...this.getNonTemplateDiagnostics(), ...this.getTemplateDiagnostics());
40548
+ if (this.options._extendedTemplateDiagnostics) {
40549
+ diagnostics.push(...this.getExtendedTemplateDiagnostics());
40550
+ }
40551
+ return this.addMessageTextDetails(diagnostics);
40331
40552
  }
40332
40553
  /**
40333
40554
  * Get all Angular-related diagnostics for this compilation.
@@ -40335,10 +40556,26 @@ Either add the @Injectable() decorator to '${provider.node.name
40335
40556
  * If a `ts.SourceFile` is passed, only diagnostics related to that file are returned.
40336
40557
  */
40337
40558
  getDiagnosticsForFile(file, optimizeFor) {
40338
- return this.addMessageTextDetails([
40339
- ...this.getNonTemplateDiagnostics().filter(diag => diag.file === file),
40340
- ...this.getTemplateDiagnosticsForFile(file, optimizeFor)
40341
- ]);
40559
+ const diagnostics = [];
40560
+ diagnostics.push(...this.getNonTemplateDiagnostics().filter(diag => diag.file === file), ...this.getTemplateDiagnosticsForFile(file, optimizeFor));
40561
+ if (this.options._extendedTemplateDiagnostics) {
40562
+ diagnostics.push(...this.getExtendedTemplateDiagnostics(file));
40563
+ }
40564
+ return this.addMessageTextDetails(diagnostics);
40565
+ }
40566
+ /**
40567
+ * Get all `ts.Diagnostic`s currently available that pertain to the given component.
40568
+ */
40569
+ getDiagnosticsForComponent(component) {
40570
+ const compilation = this.ensureAnalyzed();
40571
+ const ttc = compilation.templateTypeChecker;
40572
+ const diagnostics = [];
40573
+ diagnostics.push(...ttc.getDiagnosticsForComponent(component));
40574
+ if (this.options._extendedTemplateDiagnostics) {
40575
+ const extendedTemplateChecker = compilation.extendedTemplateChecker;
40576
+ diagnostics.push(...extendedTemplateChecker.getDiagnosticsForComponent(component));
40577
+ }
40578
+ return this.addMessageTextDetails(diagnostics);
40342
40579
  }
40343
40580
  /**
40344
40581
  * Add Angular.io error guide links to diagnostics for this compilation.
@@ -40728,6 +40965,24 @@ Either add the @Injectable() decorator to '${provider.node.name
40728
40965
  }
40729
40966
  return this.nonTemplateDiagnostics;
40730
40967
  }
40968
+ /**
40969
+ * Calls the `extendedTemplateCheck` phase of the trait compiler
40970
+ * @param sf optional parameter to get diagnostics for a certain file
40971
+ * or all files in the program if `sf` is undefined
40972
+ * @returns generated extended template diagnostics
40973
+ */
40974
+ getExtendedTemplateDiagnostics(sf) {
40975
+ const diagnostics = [];
40976
+ const compilation = this.ensureAnalyzed();
40977
+ const extendedTemplateChecker = compilation.extendedTemplateChecker;
40978
+ if (sf !== undefined) {
40979
+ return compilation.traitCompiler.extendedTemplateCheck(sf, extendedTemplateChecker);
40980
+ }
40981
+ for (const sf of this.inputProgram.getSourceFiles()) {
40982
+ diagnostics.push(...compilation.traitCompiler.extendedTemplateCheck(sf, extendedTemplateChecker));
40983
+ }
40984
+ return diagnostics;
40985
+ }
40731
40986
  makeCompilation() {
40732
40987
  const checker = this.inputProgram.getTypeChecker();
40733
40988
  const reflector = new TypeScriptReflectionHost(checker);
@@ -40825,7 +41080,7 @@ Either add the @Injectable() decorator to '${provider.node.name
40825
41080
  // TODO(alxhub): understand why the cast here is necessary (something to do with `null`
40826
41081
  // not being assignable to `unknown` when wrapped in `Readonly`).
40827
41082
  // clang-format off
40828
- new DirectiveDecoratorHandler(reflector, evaluator, metaRegistry, scopeRegistry, metaReader, injectableRegistry, isCore, semanticDepGraphUpdater, this.closureCompilerEnabled, compileUndecoratedClassesWithAngularFeatures, this.delegatingPerfRecorder),
41083
+ new DirectiveDecoratorHandler(reflector, evaluator, metaRegistry, scopeRegistry, metaReader, injectableRegistry, isCore, semanticDepGraphUpdater, this.closureCompilerEnabled, /** compileUndecoratedClassesWithAngularFeatures */ false, this.delegatingPerfRecorder),
40829
41084
  // clang-format on
40830
41085
  // Pipe handler must be before injectable handler in list so pipe factories are printed
40831
41086
  // before injectable factories (so injectable factories can delegate to them)
@@ -40841,6 +41096,11 @@ Either add the @Injectable() decorator to '${provider.node.name
40841
41096
  this.currentProgram = program;
40842
41097
  });
40843
41098
  const templateTypeChecker = new TemplateTypeCheckerImpl(this.inputProgram, notifyingDriver, traitCompiler, this.getTypeCheckingConfig(), refEmitter, reflector, this.adapter, this.incrementalCompilation, scopeRegistry, typeCheckScopeRegistry, this.delegatingPerfRecorder);
41099
+ const templateChecks = [new InvalidBananaInBoxCheck()];
41100
+ if (this.options.strictNullChecks) {
41101
+ templateChecks.push(new NullishCoalescingNotNullableCheck());
41102
+ }
41103
+ const extendedTemplateChecker = new ExtendedTemplateCheckerImpl(templateTypeChecker, checker, templateChecks);
40844
41104
  return {
40845
41105
  isCore,
40846
41106
  traitCompiler,
@@ -40855,6 +41115,7 @@ Either add the @Injectable() decorator to '${provider.node.name
40855
41115
  refEmitter,
40856
41116
  templateTypeChecker,
40857
41117
  resourceRegistry,
41118
+ extendedTemplateChecker
40858
41119
  };
40859
41120
  }
40860
41121
  }
@@ -44418,7 +44679,6 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
44418
44679
  }
44419
44680
  getSemanticDiagnostics(fileName) {
44420
44681
  return this.withCompilerAndPerfTracing(PerfPhase.LsDiagnostics, (compiler) => {
44421
- const ttc = compiler.getTemplateTypeChecker();
44422
44682
  const diagnostics = [];
44423
44683
  if (isTypeScriptFile(fileName)) {
44424
44684
  const program = compiler.getCurrentProgram();
@@ -44454,7 +44714,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
44454
44714
  const components = compiler.getComponentsWithTemplateFile(fileName);
44455
44715
  for (const component of components) {
44456
44716
  if (ts.isClassDeclaration(component)) {
44457
- diagnostics.push(...ttc.getDiagnosticsForComponent(component));
44717
+ diagnostics.push(...compiler.getDiagnosticsForComponent(component));
44458
44718
  }
44459
44719
  }
44460
44720
  }