@angular/language-service 12.2.1 → 12.2.5
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 +556 -309
- package/bundles/language-service.js +611 -618
- package/package.json +1 -1
package/bundles/ivy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v12.2.
|
|
2
|
+
* @license Angular v12.2.5
|
|
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
|
|
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
|
|
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;
|
|
@@ -4740,13 +4740,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
4740
4740
|
return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
|
|
4741
4741
|
}
|
|
4742
4742
|
|
|
4743
|
-
/**
|
|
4744
|
-
* @license
|
|
4745
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4746
|
-
*
|
|
4747
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
4748
|
-
* found in the LICENSE file at https://angular.io/license
|
|
4749
|
-
*/
|
|
4750
4743
|
var R3FactoryDelegateType;
|
|
4751
4744
|
(function (R3FactoryDelegateType) {
|
|
4752
4745
|
R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
|
|
@@ -5145,8 +5138,249 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
5145
5138
|
* Use of this source code is governed by an MIT-style license that can be
|
|
5146
5139
|
* found in the LICENSE file at https://angular.io/license
|
|
5147
5140
|
*/
|
|
5148
|
-
|
|
5149
|
-
|
|
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));
|
|
5150
5384
|
}
|
|
5151
5385
|
let _anonymousTypeIndex = 0;
|
|
5152
5386
|
function identifierName(compileIdentifier) {
|
|
@@ -5176,18 +5410,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
5176
5410
|
}
|
|
5177
5411
|
return identifier;
|
|
5178
5412
|
}
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
CompileSummaryKind[CompileSummaryKind["Pipe"] = 0] = "Pipe";
|
|
5182
|
-
CompileSummaryKind[CompileSummaryKind["Directive"] = 1] = "Directive";
|
|
5183
|
-
CompileSummaryKind[CompileSummaryKind["NgModule"] = 2] = "NgModule";
|
|
5184
|
-
CompileSummaryKind[CompileSummaryKind["Injectable"] = 3] = "Injectable";
|
|
5185
|
-
})(CompileSummaryKind || (CompileSummaryKind = {}));
|
|
5186
|
-
function flatten(list) {
|
|
5187
|
-
return list.reduce((flat, item) => {
|
|
5188
|
-
const flatItem = Array.isArray(item) ? flatten(item) : item;
|
|
5189
|
-
return flat.concat(flatItem);
|
|
5190
|
-
}, []);
|
|
5413
|
+
function sanitizeIdentifier(name) {
|
|
5414
|
+
return name.replace(/\W/g, '_');
|
|
5191
5415
|
}
|
|
5192
5416
|
|
|
5193
5417
|
/**
|
|
@@ -5643,255 +5867,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
5643
5867
|
return statement.isEquivalent(literal('use strict').toStmt());
|
|
5644
5868
|
}
|
|
5645
5869
|
|
|
5646
|
-
/**
|
|
5647
|
-
* @license
|
|
5648
|
-
* Copyright Google LLC All Rights Reserved.
|
|
5649
|
-
*
|
|
5650
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
5651
|
-
* found in the LICENSE file at https://angular.io/license
|
|
5652
|
-
*/
|
|
5653
|
-
const $EOF = 0;
|
|
5654
|
-
const $BSPACE = 8;
|
|
5655
|
-
const $TAB = 9;
|
|
5656
|
-
const $LF = 10;
|
|
5657
|
-
const $VTAB = 11;
|
|
5658
|
-
const $FF = 12;
|
|
5659
|
-
const $CR = 13;
|
|
5660
|
-
const $SPACE = 32;
|
|
5661
|
-
const $BANG = 33;
|
|
5662
|
-
const $DQ = 34;
|
|
5663
|
-
const $HASH = 35;
|
|
5664
|
-
const $$ = 36;
|
|
5665
|
-
const $PERCENT = 37;
|
|
5666
|
-
const $AMPERSAND = 38;
|
|
5667
|
-
const $SQ = 39;
|
|
5668
|
-
const $LPAREN = 40;
|
|
5669
|
-
const $RPAREN = 41;
|
|
5670
|
-
const $STAR = 42;
|
|
5671
|
-
const $PLUS = 43;
|
|
5672
|
-
const $COMMA = 44;
|
|
5673
|
-
const $MINUS = 45;
|
|
5674
|
-
const $PERIOD = 46;
|
|
5675
|
-
const $SLASH = 47;
|
|
5676
|
-
const $COLON = 58;
|
|
5677
|
-
const $SEMICOLON = 59;
|
|
5678
|
-
const $LT = 60;
|
|
5679
|
-
const $EQ = 61;
|
|
5680
|
-
const $GT = 62;
|
|
5681
|
-
const $QUESTION = 63;
|
|
5682
|
-
const $0 = 48;
|
|
5683
|
-
const $7 = 55;
|
|
5684
|
-
const $9 = 57;
|
|
5685
|
-
const $A = 65;
|
|
5686
|
-
const $E = 69;
|
|
5687
|
-
const $F = 70;
|
|
5688
|
-
const $X = 88;
|
|
5689
|
-
const $Z = 90;
|
|
5690
|
-
const $LBRACKET = 91;
|
|
5691
|
-
const $BACKSLASH = 92;
|
|
5692
|
-
const $RBRACKET = 93;
|
|
5693
|
-
const $CARET = 94;
|
|
5694
|
-
const $_ = 95;
|
|
5695
|
-
const $a = 97;
|
|
5696
|
-
const $b = 98;
|
|
5697
|
-
const $e = 101;
|
|
5698
|
-
const $f = 102;
|
|
5699
|
-
const $n = 110;
|
|
5700
|
-
const $r = 114;
|
|
5701
|
-
const $t = 116;
|
|
5702
|
-
const $u = 117;
|
|
5703
|
-
const $v = 118;
|
|
5704
|
-
const $x = 120;
|
|
5705
|
-
const $z = 122;
|
|
5706
|
-
const $LBRACE = 123;
|
|
5707
|
-
const $BAR = 124;
|
|
5708
|
-
const $RBRACE = 125;
|
|
5709
|
-
const $NBSP = 160;
|
|
5710
|
-
const $BT = 96;
|
|
5711
|
-
function isWhitespace(code) {
|
|
5712
|
-
return (code >= $TAB && code <= $SPACE) || (code == $NBSP);
|
|
5713
|
-
}
|
|
5714
|
-
function isDigit(code) {
|
|
5715
|
-
return $0 <= code && code <= $9;
|
|
5716
|
-
}
|
|
5717
|
-
function isAsciiLetter(code) {
|
|
5718
|
-
return code >= $a && code <= $z || code >= $A && code <= $Z;
|
|
5719
|
-
}
|
|
5720
|
-
function isAsciiHexDigit(code) {
|
|
5721
|
-
return code >= $a && code <= $f || code >= $A && code <= $F || isDigit(code);
|
|
5722
|
-
}
|
|
5723
|
-
function isNewLine(code) {
|
|
5724
|
-
return code === $LF || code === $CR;
|
|
5725
|
-
}
|
|
5726
|
-
function isOctalDigit(code) {
|
|
5727
|
-
return $0 <= code && code <= $7;
|
|
5728
|
-
}
|
|
5729
|
-
|
|
5730
|
-
/**
|
|
5731
|
-
* @license
|
|
5732
|
-
* Copyright Google LLC All Rights Reserved.
|
|
5733
|
-
*
|
|
5734
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
5735
|
-
* found in the LICENSE file at https://angular.io/license
|
|
5736
|
-
*/
|
|
5737
|
-
class ParseLocation {
|
|
5738
|
-
constructor(file, offset, line, col) {
|
|
5739
|
-
this.file = file;
|
|
5740
|
-
this.offset = offset;
|
|
5741
|
-
this.line = line;
|
|
5742
|
-
this.col = col;
|
|
5743
|
-
}
|
|
5744
|
-
toString() {
|
|
5745
|
-
return this.offset != null ? `${this.file.url}@${this.line}:${this.col}` : this.file.url;
|
|
5746
|
-
}
|
|
5747
|
-
moveBy(delta) {
|
|
5748
|
-
const source = this.file.content;
|
|
5749
|
-
const len = source.length;
|
|
5750
|
-
let offset = this.offset;
|
|
5751
|
-
let line = this.line;
|
|
5752
|
-
let col = this.col;
|
|
5753
|
-
while (offset > 0 && delta < 0) {
|
|
5754
|
-
offset--;
|
|
5755
|
-
delta++;
|
|
5756
|
-
const ch = source.charCodeAt(offset);
|
|
5757
|
-
if (ch == $LF) {
|
|
5758
|
-
line--;
|
|
5759
|
-
const priorLine = source.substr(0, offset - 1).lastIndexOf(String.fromCharCode($LF));
|
|
5760
|
-
col = priorLine > 0 ? offset - priorLine : offset;
|
|
5761
|
-
}
|
|
5762
|
-
else {
|
|
5763
|
-
col--;
|
|
5764
|
-
}
|
|
5765
|
-
}
|
|
5766
|
-
while (offset < len && delta > 0) {
|
|
5767
|
-
const ch = source.charCodeAt(offset);
|
|
5768
|
-
offset++;
|
|
5769
|
-
delta--;
|
|
5770
|
-
if (ch == $LF) {
|
|
5771
|
-
line++;
|
|
5772
|
-
col = 0;
|
|
5773
|
-
}
|
|
5774
|
-
else {
|
|
5775
|
-
col++;
|
|
5776
|
-
}
|
|
5777
|
-
}
|
|
5778
|
-
return new ParseLocation(this.file, offset, line, col);
|
|
5779
|
-
}
|
|
5780
|
-
// Return the source around the location
|
|
5781
|
-
// Up to `maxChars` or `maxLines` on each side of the location
|
|
5782
|
-
getContext(maxChars, maxLines) {
|
|
5783
|
-
const content = this.file.content;
|
|
5784
|
-
let startOffset = this.offset;
|
|
5785
|
-
if (startOffset != null) {
|
|
5786
|
-
if (startOffset > content.length - 1) {
|
|
5787
|
-
startOffset = content.length - 1;
|
|
5788
|
-
}
|
|
5789
|
-
let endOffset = startOffset;
|
|
5790
|
-
let ctxChars = 0;
|
|
5791
|
-
let ctxLines = 0;
|
|
5792
|
-
while (ctxChars < maxChars && startOffset > 0) {
|
|
5793
|
-
startOffset--;
|
|
5794
|
-
ctxChars++;
|
|
5795
|
-
if (content[startOffset] == '\n') {
|
|
5796
|
-
if (++ctxLines == maxLines) {
|
|
5797
|
-
break;
|
|
5798
|
-
}
|
|
5799
|
-
}
|
|
5800
|
-
}
|
|
5801
|
-
ctxChars = 0;
|
|
5802
|
-
ctxLines = 0;
|
|
5803
|
-
while (ctxChars < maxChars && endOffset < content.length - 1) {
|
|
5804
|
-
endOffset++;
|
|
5805
|
-
ctxChars++;
|
|
5806
|
-
if (content[endOffset] == '\n') {
|
|
5807
|
-
if (++ctxLines == maxLines) {
|
|
5808
|
-
break;
|
|
5809
|
-
}
|
|
5810
|
-
}
|
|
5811
|
-
}
|
|
5812
|
-
return {
|
|
5813
|
-
before: content.substring(startOffset, this.offset),
|
|
5814
|
-
after: content.substring(this.offset, endOffset + 1),
|
|
5815
|
-
};
|
|
5816
|
-
}
|
|
5817
|
-
return null;
|
|
5818
|
-
}
|
|
5819
|
-
}
|
|
5820
|
-
class ParseSourceFile {
|
|
5821
|
-
constructor(content, url) {
|
|
5822
|
-
this.content = content;
|
|
5823
|
-
this.url = url;
|
|
5824
|
-
}
|
|
5825
|
-
}
|
|
5826
|
-
class ParseSourceSpan {
|
|
5827
|
-
/**
|
|
5828
|
-
* Create an object that holds information about spans of tokens/nodes captured during
|
|
5829
|
-
* lexing/parsing of text.
|
|
5830
|
-
*
|
|
5831
|
-
* @param start
|
|
5832
|
-
* The location of the start of the span (having skipped leading trivia).
|
|
5833
|
-
* Skipping leading trivia makes source-spans more "user friendly", since things like HTML
|
|
5834
|
-
* elements will appear to begin at the start of the opening tag, rather than at the start of any
|
|
5835
|
-
* leading trivia, which could include newlines.
|
|
5836
|
-
*
|
|
5837
|
-
* @param end
|
|
5838
|
-
* The location of the end of the span.
|
|
5839
|
-
*
|
|
5840
|
-
* @param fullStart
|
|
5841
|
-
* The start of the token without skipping the leading trivia.
|
|
5842
|
-
* This is used by tooling that splits tokens further, such as extracting Angular interpolations
|
|
5843
|
-
* from text tokens. Such tooling creates new source-spans relative to the original token's
|
|
5844
|
-
* source-span. If leading trivia characters have been skipped then the new source-spans may be
|
|
5845
|
-
* incorrectly offset.
|
|
5846
|
-
*
|
|
5847
|
-
* @param details
|
|
5848
|
-
* Additional information (such as identifier names) that should be associated with the span.
|
|
5849
|
-
*/
|
|
5850
|
-
constructor(start, end, fullStart = start, details = null) {
|
|
5851
|
-
this.start = start;
|
|
5852
|
-
this.end = end;
|
|
5853
|
-
this.fullStart = fullStart;
|
|
5854
|
-
this.details = details;
|
|
5855
|
-
}
|
|
5856
|
-
toString() {
|
|
5857
|
-
return this.start.file.content.substring(this.start.offset, this.end.offset);
|
|
5858
|
-
}
|
|
5859
|
-
}
|
|
5860
|
-
var ParseErrorLevel;
|
|
5861
|
-
(function (ParseErrorLevel) {
|
|
5862
|
-
ParseErrorLevel[ParseErrorLevel["WARNING"] = 0] = "WARNING";
|
|
5863
|
-
ParseErrorLevel[ParseErrorLevel["ERROR"] = 1] = "ERROR";
|
|
5864
|
-
})(ParseErrorLevel || (ParseErrorLevel = {}));
|
|
5865
|
-
class ParseError {
|
|
5866
|
-
constructor(span, msg, level = ParseErrorLevel.ERROR) {
|
|
5867
|
-
this.span = span;
|
|
5868
|
-
this.msg = msg;
|
|
5869
|
-
this.level = level;
|
|
5870
|
-
}
|
|
5871
|
-
contextualMessage() {
|
|
5872
|
-
const ctx = this.span.start.getContext(100, 3);
|
|
5873
|
-
return ctx ? `${this.msg} ("${ctx.before}[${ParseErrorLevel[this.level]} ->]${ctx.after}")` :
|
|
5874
|
-
this.msg;
|
|
5875
|
-
}
|
|
5876
|
-
toString() {
|
|
5877
|
-
const details = this.span.details ? `, ${this.span.details}` : '';
|
|
5878
|
-
return `${this.contextualMessage()}: ${this.span.start}${details}`;
|
|
5879
|
-
}
|
|
5880
|
-
}
|
|
5881
|
-
/**
|
|
5882
|
-
* Generates Source Span object for a given R3 Type for JIT mode.
|
|
5883
|
-
*
|
|
5884
|
-
* @param kind Component or Directive.
|
|
5885
|
-
* @param typeName name of the Component or Directive.
|
|
5886
|
-
* @param sourceUrl reference to Component or Directive source.
|
|
5887
|
-
* @returns instance of ParseSourceSpan that represent a given Component or Directive.
|
|
5888
|
-
*/
|
|
5889
|
-
function r3JitTypeSourceSpan(kind, typeName, sourceUrl) {
|
|
5890
|
-
const sourceFileName = `in ${kind} ${typeName} in ${sourceUrl}`;
|
|
5891
|
-
const sourceFile = new ParseSourceFile('', sourceFileName);
|
|
5892
|
-
return new ParseSourceSpan(new ParseLocation(sourceFile, -1, -1, -1), new ParseLocation(sourceFile, -1, -1, -1));
|
|
5893
|
-
}
|
|
5894
|
-
|
|
5895
5870
|
/**
|
|
5896
5871
|
* @license
|
|
5897
5872
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -8633,6 +8608,27 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
8633
8608
|
}
|
|
8634
8609
|
}
|
|
8635
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
|
+
|
|
8636
8632
|
/**
|
|
8637
8633
|
* @license
|
|
8638
8634
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -11544,16 +11540,16 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11544
11540
|
(code < $0 || code > $9);
|
|
11545
11541
|
}
|
|
11546
11542
|
function isDigitEntityEnd(code) {
|
|
11547
|
-
return code
|
|
11543
|
+
return code === $SEMICOLON || code === $EOF || !isAsciiHexDigit(code);
|
|
11548
11544
|
}
|
|
11549
11545
|
function isNamedEntityEnd(code) {
|
|
11550
|
-
return code
|
|
11546
|
+
return code === $SEMICOLON || code === $EOF || !isAsciiLetter(code);
|
|
11551
11547
|
}
|
|
11552
11548
|
function isExpansionCaseStart(peek) {
|
|
11553
11549
|
return peek !== $RBRACE;
|
|
11554
11550
|
}
|
|
11555
11551
|
function compareCharCodeCaseInsensitive(code1, code2) {
|
|
11556
|
-
return toUpperCaseCharCode(code1)
|
|
11552
|
+
return toUpperCaseCharCode(code1) === toUpperCaseCharCode(code2);
|
|
11557
11553
|
}
|
|
11558
11554
|
function toUpperCaseCharCode(code) {
|
|
11559
11555
|
return code >= $a && code <= $z ? code - $a + $A : code;
|
|
@@ -11563,7 +11559,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11563
11559
|
let lastDstToken = undefined;
|
|
11564
11560
|
for (let i = 0; i < srcTokens.length; i++) {
|
|
11565
11561
|
const token = srcTokens[i];
|
|
11566
|
-
if (lastDstToken && lastDstToken.type
|
|
11562
|
+
if (lastDstToken && lastDstToken.type === TokenType.TEXT && token.type === TokenType.TEXT) {
|
|
11567
11563
|
lastDstToken.parts[0] += token.parts[0];
|
|
11568
11564
|
lastDstToken.sourceSpan.end = token.sourceSpan.end;
|
|
11569
11565
|
}
|
|
@@ -11967,7 +11963,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11967
11963
|
if (this._peek.type === TokenType.EXPANSION_CASE_EXP_END) {
|
|
11968
11964
|
if (lastOnStack(expansionFormStack, TokenType.EXPANSION_CASE_EXP_START)) {
|
|
11969
11965
|
expansionFormStack.pop();
|
|
11970
|
-
if (expansionFormStack.length
|
|
11966
|
+
if (expansionFormStack.length === 0)
|
|
11971
11967
|
return exp;
|
|
11972
11968
|
}
|
|
11973
11969
|
else {
|
|
@@ -11993,9 +11989,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11993
11989
|
}
|
|
11994
11990
|
_consumeText(token) {
|
|
11995
11991
|
let text = token.parts[0];
|
|
11996
|
-
if (text.length > 0 && text[0]
|
|
11992
|
+
if (text.length > 0 && text[0] === '\n') {
|
|
11997
11993
|
const parent = this._getParentElement();
|
|
11998
|
-
if (parent != null && parent.children.length
|
|
11994
|
+
if (parent != null && parent.children.length === 0 &&
|
|
11999
11995
|
this.getTagDefinition(parent.name).ignoreFirstLf) {
|
|
12000
11996
|
text = text.substring(1);
|
|
12001
11997
|
}
|
|
@@ -12078,7 +12074,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
12078
12074
|
let unexpectedCloseTagDetected = false;
|
|
12079
12075
|
for (let stackIndex = this._elementStack.length - 1; stackIndex >= 0; stackIndex--) {
|
|
12080
12076
|
const el = this._elementStack[stackIndex];
|
|
12081
|
-
if (el.name
|
|
12077
|
+
if (el.name === fullName) {
|
|
12082
12078
|
// Record the parse span with the element that is being closed. Any elements that are
|
|
12083
12079
|
// removed from the element stack at this point are closed implicitly, so they won't get
|
|
12084
12080
|
// an end source span (as there is no explicit closing element).
|
|
@@ -13870,9 +13866,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
13870
13866
|
function isExponentSign(code) {
|
|
13871
13867
|
return code == $MINUS || code == $PLUS;
|
|
13872
13868
|
}
|
|
13873
|
-
function isQuote(code) {
|
|
13874
|
-
return code === $SQ || code === $DQ || code === $BT;
|
|
13875
|
-
}
|
|
13876
13869
|
function unescape(code) {
|
|
13877
13870
|
switch (code) {
|
|
13878
13871
|
case $n:
|
|
@@ -19945,7 +19938,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
19945
19938
|
* Use of this source code is governed by an MIT-style license that can be
|
|
19946
19939
|
* found in the LICENSE file at https://angular.io/license
|
|
19947
19940
|
*/
|
|
19948
|
-
const VERSION$1 = new Version('12.2.
|
|
19941
|
+
const VERSION$1 = new Version('12.2.5');
|
|
19949
19942
|
|
|
19950
19943
|
/**
|
|
19951
19944
|
* @license
|
|
@@ -20584,7 +20577,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20584
20577
|
function compileDeclareClassMetadata(metadata) {
|
|
20585
20578
|
const definitionMap = new DefinitionMap();
|
|
20586
20579
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
20587
|
-
definitionMap.set('version', literal('12.2.
|
|
20580
|
+
definitionMap.set('version', literal('12.2.5'));
|
|
20588
20581
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20589
20582
|
definitionMap.set('type', metadata.type);
|
|
20590
20583
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -20624,7 +20617,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20624
20617
|
function createDirectiveDefinitionMap(meta) {
|
|
20625
20618
|
const definitionMap = new DefinitionMap();
|
|
20626
20619
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
20627
|
-
definitionMap.set('version', literal('12.2.
|
|
20620
|
+
definitionMap.set('version', literal('12.2.5'));
|
|
20628
20621
|
// e.g. `type: MyDirective`
|
|
20629
20622
|
definitionMap.set('type', meta.internalType);
|
|
20630
20623
|
// e.g. `selector: 'some-dir'`
|
|
@@ -20841,7 +20834,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20841
20834
|
function compileDeclareFactoryFunction(meta) {
|
|
20842
20835
|
const definitionMap = new DefinitionMap();
|
|
20843
20836
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
20844
|
-
definitionMap.set('version', literal('12.2.
|
|
20837
|
+
definitionMap.set('version', literal('12.2.5'));
|
|
20845
20838
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20846
20839
|
definitionMap.set('type', meta.internalType);
|
|
20847
20840
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -20883,7 +20876,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20883
20876
|
function createInjectableDefinitionMap(meta) {
|
|
20884
20877
|
const definitionMap = new DefinitionMap();
|
|
20885
20878
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
20886
|
-
definitionMap.set('version', literal('12.2.
|
|
20879
|
+
definitionMap.set('version', literal('12.2.5'));
|
|
20887
20880
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20888
20881
|
definitionMap.set('type', meta.internalType);
|
|
20889
20882
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -20962,7 +20955,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20962
20955
|
function createInjectorDefinitionMap(meta) {
|
|
20963
20956
|
const definitionMap = new DefinitionMap();
|
|
20964
20957
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
20965
|
-
definitionMap.set('version', literal('12.2.
|
|
20958
|
+
definitionMap.set('version', literal('12.2.5'));
|
|
20966
20959
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20967
20960
|
definitionMap.set('type', meta.internalType);
|
|
20968
20961
|
definitionMap.set('providers', meta.providers);
|
|
@@ -20999,7 +20992,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20999
20992
|
function createNgModuleDefinitionMap(meta) {
|
|
21000
20993
|
const definitionMap = new DefinitionMap();
|
|
21001
20994
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
21002
|
-
definitionMap.set('version', literal('12.2.
|
|
20995
|
+
definitionMap.set('version', literal('12.2.5'));
|
|
21003
20996
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
21004
20997
|
definitionMap.set('type', meta.internalType);
|
|
21005
20998
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -21057,7 +21050,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21057
21050
|
function createPipeDefinitionMap(meta) {
|
|
21058
21051
|
const definitionMap = new DefinitionMap();
|
|
21059
21052
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
|
|
21060
|
-
definitionMap.set('version', literal('12.2.
|
|
21053
|
+
definitionMap.set('version', literal('12.2.5'));
|
|
21061
21054
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
21062
21055
|
// e.g. `type: MyPipe`
|
|
21063
21056
|
definitionMap.set('type', meta.internalType);
|
|
@@ -21089,7 +21082,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21089
21082
|
* Use of this source code is governed by an MIT-style license that can be
|
|
21090
21083
|
* found in the LICENSE file at https://angular.io/license
|
|
21091
21084
|
*/
|
|
21092
|
-
const VERSION$2 = new Version('12.2.
|
|
21085
|
+
const VERSION$2 = new Version('12.2.5');
|
|
21093
21086
|
|
|
21094
21087
|
/**
|
|
21095
21088
|
* @license
|
|
@@ -21301,6 +21294,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21301
21294
|
* ```
|
|
21302
21295
|
*/
|
|
21303
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";
|
|
21304
21306
|
/**
|
|
21305
21307
|
* The template type-checking engine would need to generate an inline type check block for a
|
|
21306
21308
|
* component, but the current type-checking environment doesn't support it.
|
|
@@ -26553,6 +26555,26 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
26553
26555
|
}
|
|
26554
26556
|
}
|
|
26555
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
|
+
}
|
|
26556
26578
|
index(ctx) {
|
|
26557
26579
|
for (const clazz of this.classes.keys()) {
|
|
26558
26580
|
const record = this.classes.get(clazz);
|
|
@@ -30560,6 +30582,9 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
30560
30582
|
const binder = new R3TargetBinder(scope.matcher);
|
|
30561
30583
|
ctx.addTemplate(new Reference$1(node), binder, meta.template.diagNodes, scope.pipes, scope.schemas, meta.template.sourceMapping, meta.template.file, meta.template.errors);
|
|
30562
30584
|
}
|
|
30585
|
+
extendedTemplateCheck(component, extendedTemplateChecker) {
|
|
30586
|
+
return extendedTemplateChecker.getDiagnosticsForComponent(component);
|
|
30587
|
+
}
|
|
30563
30588
|
resolve(node, analysis, symbol) {
|
|
30564
30589
|
if (this.semanticDepGraphUpdater !== null && analysis.baseClass instanceof Reference$1) {
|
|
30565
30590
|
symbol.baseClass = this.semanticDepGraphUpdater.getSymbol(analysis.baseClass.node);
|
|
@@ -39738,7 +39763,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
39738
39763
|
const fileRecord = this.state.get(sfPath);
|
|
39739
39764
|
const templateId = fileRecord.sourceManager.getTemplateId(clazz);
|
|
39740
39765
|
const mapping = fileRecord.sourceManager.getSourceMapping(templateId);
|
|
39741
|
-
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 });
|
|
39742
39767
|
}
|
|
39743
39768
|
getOrCreateCompletionEngine(component) {
|
|
39744
39769
|
if (this.completionCache.has(component)) {
|
|
@@ -40107,13 +40132,187 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40107
40132
|
* Use of this source code is governed by an MIT-style license that can be
|
|
40108
40133
|
* found in the LICENSE file at https://angular.io/license
|
|
40109
40134
|
*/
|
|
40110
|
-
|
|
40111
|
-
|
|
40112
|
-
|
|
40113
|
-
|
|
40114
|
-
|
|
40115
|
-
|
|
40116
|
-
|
|
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
|
+
}
|
|
40117
40316
|
|
|
40118
40317
|
/**
|
|
40119
40318
|
* @license
|
|
@@ -40231,6 +40430,10 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40231
40430
|
* with each fresh compilation.
|
|
40232
40431
|
*/
|
|
40233
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
|
+
}
|
|
40234
40437
|
this.constructionDiagnostics.push(...this.adapter.constructionDiagnostics);
|
|
40235
40438
|
const incompatibleTypeCheckOptionsDiagnostic = verifyCompatibleTypeCheckOptions(this.options);
|
|
40236
40439
|
if (incompatibleTypeCheckOptionsDiagnostic !== null) {
|
|
@@ -40340,7 +40543,12 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40340
40543
|
* Get all Angular-related diagnostics for this compilation.
|
|
40341
40544
|
*/
|
|
40342
40545
|
getDiagnostics() {
|
|
40343
|
-
|
|
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);
|
|
40344
40552
|
}
|
|
40345
40553
|
/**
|
|
40346
40554
|
* Get all Angular-related diagnostics for this compilation.
|
|
@@ -40348,10 +40556,26 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40348
40556
|
* If a `ts.SourceFile` is passed, only diagnostics related to that file are returned.
|
|
40349
40557
|
*/
|
|
40350
40558
|
getDiagnosticsForFile(file, optimizeFor) {
|
|
40351
|
-
|
|
40352
|
-
|
|
40353
|
-
|
|
40354
|
-
|
|
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);
|
|
40355
40579
|
}
|
|
40356
40580
|
/**
|
|
40357
40581
|
* Add Angular.io error guide links to diagnostics for this compilation.
|
|
@@ -40741,6 +40965,24 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40741
40965
|
}
|
|
40742
40966
|
return this.nonTemplateDiagnostics;
|
|
40743
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
|
+
}
|
|
40744
40986
|
makeCompilation() {
|
|
40745
40987
|
const checker = this.inputProgram.getTypeChecker();
|
|
40746
40988
|
const reflector = new TypeScriptReflectionHost(checker);
|
|
@@ -40838,7 +41080,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40838
41080
|
// TODO(alxhub): understand why the cast here is necessary (something to do with `null`
|
|
40839
41081
|
// not being assignable to `unknown` when wrapped in `Readonly`).
|
|
40840
41082
|
// clang-format off
|
|
40841
|
-
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),
|
|
40842
41084
|
// clang-format on
|
|
40843
41085
|
// Pipe handler must be before injectable handler in list so pipe factories are printed
|
|
40844
41086
|
// before injectable factories (so injectable factories can delegate to them)
|
|
@@ -40854,6 +41096,11 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40854
41096
|
this.currentProgram = program;
|
|
40855
41097
|
});
|
|
40856
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);
|
|
40857
41104
|
return {
|
|
40858
41105
|
isCore,
|
|
40859
41106
|
traitCompiler,
|
|
@@ -40868,6 +41115,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40868
41115
|
refEmitter,
|
|
40869
41116
|
templateTypeChecker,
|
|
40870
41117
|
resourceRegistry,
|
|
41118
|
+
extendedTemplateChecker
|
|
40871
41119
|
};
|
|
40872
41120
|
}
|
|
40873
41121
|
}
|
|
@@ -44431,7 +44679,6 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44431
44679
|
}
|
|
44432
44680
|
getSemanticDiagnostics(fileName) {
|
|
44433
44681
|
return this.withCompilerAndPerfTracing(PerfPhase.LsDiagnostics, (compiler) => {
|
|
44434
|
-
const ttc = compiler.getTemplateTypeChecker();
|
|
44435
44682
|
const diagnostics = [];
|
|
44436
44683
|
if (isTypeScriptFile(fileName)) {
|
|
44437
44684
|
const program = compiler.getCurrentProgram();
|
|
@@ -44467,7 +44714,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44467
44714
|
const components = compiler.getComponentsWithTemplateFile(fileName);
|
|
44468
44715
|
for (const component of components) {
|
|
44469
44716
|
if (ts.isClassDeclaration(component)) {
|
|
44470
|
-
diagnostics.push(...
|
|
44717
|
+
diagnostics.push(...compiler.getDiagnosticsForComponent(component));
|
|
44471
44718
|
}
|
|
44472
44719
|
}
|
|
44473
44720
|
}
|