@angular/language-service 12.2.6 → 12.2.7

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.6
2
+ * @license Angular v12.2.7
3
3
  * Copyright Google LLC All Rights Reserved.
4
4
  * License: MIT
5
5
  */
@@ -8443,7 +8443,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
8443
8443
  const _polyfillHostRe = /-shadowcsshost/gim;
8444
8444
  const _colonHostRe = /:host/gim;
8445
8445
  const _colonHostContextRe = /:host-context/gim;
8446
- const _commentRe = /\/\*\s*[\s\S]*?\*\//g;
8446
+ const _commentRe = /\/\*[\s\S]*?\*\//g;
8447
8447
  function stripComments(input) {
8448
8448
  return input.replace(_commentRe, '');
8449
8449
  }
@@ -8654,9 +8654,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
8654
8654
  }
8655
8655
  }
8656
8656
  class Text$2 extends NodeWithI18n {
8657
- constructor(value, sourceSpan, i18n) {
8657
+ constructor(value, sourceSpan, tokens, i18n) {
8658
8658
  super(sourceSpan, i18n);
8659
8659
  this.value = value;
8660
+ this.tokens = tokens;
8660
8661
  }
8661
8662
  visit(visitor, context) {
8662
8663
  return visitor.visitText(this, context);
@@ -8687,12 +8688,13 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
8687
8688
  }
8688
8689
  }
8689
8690
  class Attribute extends NodeWithI18n {
8690
- constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
8691
+ constructor(name, value, sourceSpan, keySpan, valueSpan, valueTokens, i18n) {
8691
8692
  super(sourceSpan, i18n);
8692
8693
  this.name = name;
8693
8694
  this.value = value;
8694
8695
  this.keySpan = keySpan;
8695
8696
  this.valueSpan = valueSpan;
8697
+ this.valueTokens = valueTokens;
8696
8698
  }
8697
8699
  visit(visitor, context) {
8698
8700
  return visitor.visitAttribute(this, context);
@@ -10884,38 +10886,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
10884
10886
  * Use of this source code is governed by an MIT-style license that can be
10885
10887
  * found in the LICENSE file at https://angular.io/license
10886
10888
  */
10887
- var TokenType;
10888
- (function (TokenType) {
10889
- TokenType[TokenType["TAG_OPEN_START"] = 0] = "TAG_OPEN_START";
10890
- TokenType[TokenType["TAG_OPEN_END"] = 1] = "TAG_OPEN_END";
10891
- TokenType[TokenType["TAG_OPEN_END_VOID"] = 2] = "TAG_OPEN_END_VOID";
10892
- TokenType[TokenType["TAG_CLOSE"] = 3] = "TAG_CLOSE";
10893
- TokenType[TokenType["INCOMPLETE_TAG_OPEN"] = 4] = "INCOMPLETE_TAG_OPEN";
10894
- TokenType[TokenType["TEXT"] = 5] = "TEXT";
10895
- TokenType[TokenType["ESCAPABLE_RAW_TEXT"] = 6] = "ESCAPABLE_RAW_TEXT";
10896
- TokenType[TokenType["RAW_TEXT"] = 7] = "RAW_TEXT";
10897
- TokenType[TokenType["COMMENT_START"] = 8] = "COMMENT_START";
10898
- TokenType[TokenType["COMMENT_END"] = 9] = "COMMENT_END";
10899
- TokenType[TokenType["CDATA_START"] = 10] = "CDATA_START";
10900
- TokenType[TokenType["CDATA_END"] = 11] = "CDATA_END";
10901
- TokenType[TokenType["ATTR_NAME"] = 12] = "ATTR_NAME";
10902
- TokenType[TokenType["ATTR_QUOTE"] = 13] = "ATTR_QUOTE";
10903
- TokenType[TokenType["ATTR_VALUE"] = 14] = "ATTR_VALUE";
10904
- TokenType[TokenType["DOC_TYPE"] = 15] = "DOC_TYPE";
10905
- TokenType[TokenType["EXPANSION_FORM_START"] = 16] = "EXPANSION_FORM_START";
10906
- TokenType[TokenType["EXPANSION_CASE_VALUE"] = 17] = "EXPANSION_CASE_VALUE";
10907
- TokenType[TokenType["EXPANSION_CASE_EXP_START"] = 18] = "EXPANSION_CASE_EXP_START";
10908
- TokenType[TokenType["EXPANSION_CASE_EXP_END"] = 19] = "EXPANSION_CASE_EXP_END";
10909
- TokenType[TokenType["EXPANSION_FORM_END"] = 20] = "EXPANSION_FORM_END";
10910
- TokenType[TokenType["EOF"] = 21] = "EOF";
10911
- })(TokenType || (TokenType = {}));
10912
- class Token {
10913
- constructor(type, parts, sourceSpan) {
10914
- this.type = type;
10915
- this.parts = parts;
10916
- this.sourceSpan = sourceSpan;
10917
- }
10918
- }
10919
10889
  class TokenError extends ParseError {
10920
10890
  constructor(errorMsg, tokenType, span) {
10921
10891
  super(span, errorMsg);
@@ -11022,14 +10992,16 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11022
10992
  }
11023
10993
  }
11024
10994
  else if (!(this._tokenizeIcu && this._tokenizeExpansionForm())) {
11025
- this._consumeText();
10995
+ // In (possibly interpolated) text the end of the text is given by `isTextEnd()`, while
10996
+ // the premature end of an interpolation is given by the start of a new HTML element.
10997
+ this._consumeWithInterpolation(5 /* TEXT */, 8 /* INTERPOLATION */, () => this._isTextEnd(), () => this._isTagStart());
11026
10998
  }
11027
10999
  }
11028
11000
  catch (e) {
11029
11001
  this.handleError(e);
11030
11002
  }
11031
11003
  }
11032
- this._beginToken(TokenType.EOF);
11004
+ this._beginToken(24 /* EOF */);
11033
11005
  this._endToken([]);
11034
11006
  }
11035
11007
  /**
@@ -11068,7 +11040,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11068
11040
  if (this._currentTokenType === null) {
11069
11041
  throw new TokenError('Programming error - attempted to end a token which has no token type', null, this._cursor.getSpan(this._currentTokenStart));
11070
11042
  }
11071
- const token = new Token(this._currentTokenType, parts, this._cursor.getSpan(this._currentTokenStart, this._leadingTriviaCodePoints));
11043
+ const token = {
11044
+ type: this._currentTokenType,
11045
+ parts,
11046
+ sourceSpan: (end !== null && end !== void 0 ? end : this._cursor).getSpan(this._currentTokenStart, this._leadingTriviaCodePoints),
11047
+ };
11072
11048
  this.tokens.push(token);
11073
11049
  this._currentTokenStart = null;
11074
11050
  this._currentTokenType = null;
@@ -11161,19 +11137,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11161
11137
  this._cursor.advance();
11162
11138
  }
11163
11139
  }
11164
- _readChar(decodeEntities) {
11165
- if (decodeEntities && this._cursor.peek() === $AMPERSAND) {
11166
- return this._decodeEntity();
11167
- }
11168
- else {
11169
- // Don't rely upon reading directly from `_input` as the actual char value
11170
- // may have been generated from an escape sequence.
11171
- const char = String.fromCodePoint(this._cursor.peek());
11172
- this._cursor.advance();
11173
- return char;
11174
- }
11140
+ _readChar() {
11141
+ // Don't rely upon reading directly from `_input` as the actual char value
11142
+ // may have been generated from an escape sequence.
11143
+ const char = String.fromCodePoint(this._cursor.peek());
11144
+ this._cursor.advance();
11145
+ return char;
11175
11146
  }
11176
- _decodeEntity() {
11147
+ _consumeEntity(textTokenType) {
11148
+ this._beginToken(9 /* ENCODED_ENTITY */);
11177
11149
  const start = this._cursor.clone();
11178
11150
  this._cursor.advance();
11179
11151
  if (this._attemptCharCode($HASH)) {
@@ -11191,7 +11163,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11191
11163
  this._cursor.advance();
11192
11164
  try {
11193
11165
  const charCode = parseInt(strNum, isHex ? 16 : 10);
11194
- return String.fromCharCode(charCode);
11166
+ this._endToken([String.fromCharCode(charCode), this._cursor.getChars(start)]);
11195
11167
  }
11196
11168
  catch (_a) {
11197
11169
  throw this._createError(_unknownEntityErrorMsg(this._cursor.getChars(start)), this._cursor.getSpan());
@@ -11201,20 +11173,25 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11201
11173
  const nameStart = this._cursor.clone();
11202
11174
  this._attemptCharCodeUntilFn(isNamedEntityEnd);
11203
11175
  if (this._cursor.peek() != $SEMICOLON) {
11176
+ // No semicolon was found so abort the encoded entity token that was in progress, and treat
11177
+ // this as a text token
11178
+ this._beginToken(textTokenType, start);
11204
11179
  this._cursor = nameStart;
11205
- return '&';
11180
+ this._endToken(['&']);
11206
11181
  }
11207
- const name = this._cursor.getChars(nameStart);
11208
- this._cursor.advance();
11209
- const char = NAMED_ENTITIES[name];
11210
- if (!char) {
11211
- throw this._createError(_unknownEntityErrorMsg(name), this._cursor.getSpan(start));
11182
+ else {
11183
+ const name = this._cursor.getChars(nameStart);
11184
+ this._cursor.advance();
11185
+ const char = NAMED_ENTITIES[name];
11186
+ if (!char) {
11187
+ throw this._createError(_unknownEntityErrorMsg(name), this._cursor.getSpan(start));
11188
+ }
11189
+ this._endToken([char, `&${name};`]);
11212
11190
  }
11213
- return char;
11214
11191
  }
11215
11192
  }
11216
- _consumeRawText(decodeEntities, endMarkerPredicate) {
11217
- this._beginToken(decodeEntities ? TokenType.ESCAPABLE_RAW_TEXT : TokenType.RAW_TEXT);
11193
+ _consumeRawText(consumeEntities, endMarkerPredicate) {
11194
+ this._beginToken(consumeEntities ? 6 /* ESCAPABLE_RAW_TEXT */ : 7 /* RAW_TEXT */);
11218
11195
  const parts = [];
11219
11196
  while (true) {
11220
11197
  const tagCloseStart = this._cursor.clone();
@@ -11223,30 +11200,38 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11223
11200
  if (foundEndMarker) {
11224
11201
  break;
11225
11202
  }
11226
- parts.push(this._readChar(decodeEntities));
11203
+ if (consumeEntities && this._cursor.peek() === $AMPERSAND) {
11204
+ this._endToken([this._processCarriageReturns(parts.join(''))]);
11205
+ parts.length = 0;
11206
+ this._consumeEntity(6 /* ESCAPABLE_RAW_TEXT */);
11207
+ this._beginToken(6 /* ESCAPABLE_RAW_TEXT */);
11208
+ }
11209
+ else {
11210
+ parts.push(this._readChar());
11211
+ }
11227
11212
  }
11228
- return this._endToken([this._processCarriageReturns(parts.join(''))]);
11213
+ this._endToken([this._processCarriageReturns(parts.join(''))]);
11229
11214
  }
11230
11215
  _consumeComment(start) {
11231
- this._beginToken(TokenType.COMMENT_START, start);
11216
+ this._beginToken(10 /* COMMENT_START */, start);
11232
11217
  this._requireCharCode($MINUS);
11233
11218
  this._endToken([]);
11234
11219
  this._consumeRawText(false, () => this._attemptStr('-->'));
11235
- this._beginToken(TokenType.COMMENT_END);
11220
+ this._beginToken(11 /* COMMENT_END */);
11236
11221
  this._requireStr('-->');
11237
11222
  this._endToken([]);
11238
11223
  }
11239
11224
  _consumeCdata(start) {
11240
- this._beginToken(TokenType.CDATA_START, start);
11225
+ this._beginToken(12 /* CDATA_START */, start);
11241
11226
  this._requireStr('CDATA[');
11242
11227
  this._endToken([]);
11243
11228
  this._consumeRawText(false, () => this._attemptStr(']]>'));
11244
- this._beginToken(TokenType.CDATA_END);
11229
+ this._beginToken(13 /* CDATA_END */);
11245
11230
  this._requireStr(']]>');
11246
11231
  this._endToken([]);
11247
11232
  }
11248
11233
  _consumeDocType(start) {
11249
- this._beginToken(TokenType.DOC_TYPE, start);
11234
+ this._beginToken(18 /* DOC_TYPE */, start);
11250
11235
  const contentStart = this._cursor.clone();
11251
11236
  this._attemptUntilChar($GT);
11252
11237
  const content = this._cursor.getChars(contentStart);
@@ -11300,12 +11285,12 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11300
11285
  if (e instanceof _ControlFlowError) {
11301
11286
  if (openTagToken) {
11302
11287
  // We errored before we could close the opening tag, so it is incomplete.
11303
- openTagToken.type = TokenType.INCOMPLETE_TAG_OPEN;
11288
+ openTagToken.type = 4 /* INCOMPLETE_TAG_OPEN */;
11304
11289
  }
11305
11290
  else {
11306
11291
  // When the start tag is invalid, assume we want a "<" as text.
11307
11292
  // Back to back text tokens are merged at the end.
11308
- this._beginToken(TokenType.TEXT, start);
11293
+ this._beginToken(5 /* TEXT */, start);
11309
11294
  this._endToken(['<']);
11310
11295
  }
11311
11296
  return;
@@ -11320,8 +11305,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11320
11305
  this._consumeRawTextWithTagClose(prefix, tagName, true);
11321
11306
  }
11322
11307
  }
11323
- _consumeRawTextWithTagClose(prefix, tagName, decodeEntities) {
11324
- this._consumeRawText(decodeEntities, () => {
11308
+ _consumeRawTextWithTagClose(prefix, tagName, consumeEntities) {
11309
+ this._consumeRawText(consumeEntities, () => {
11325
11310
  if (!this._attemptCharCode($LT))
11326
11311
  return false;
11327
11312
  if (!this._attemptCharCode($SLASH))
@@ -11332,13 +11317,13 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11332
11317
  this._attemptCharCodeUntilFn(isNotWhitespace);
11333
11318
  return this._attemptCharCode($GT);
11334
11319
  });
11335
- this._beginToken(TokenType.TAG_CLOSE);
11320
+ this._beginToken(3 /* TAG_CLOSE */);
11336
11321
  this._requireCharCodeUntilFn(code => code === $GT, 3);
11337
11322
  this._cursor.advance(); // Consume the `>`
11338
11323
  this._endToken([prefix, tagName]);
11339
11324
  }
11340
11325
  _consumeTagOpenStart(start) {
11341
- this._beginToken(TokenType.TAG_OPEN_START, start);
11326
+ this._beginToken(0 /* TAG_OPEN_START */, start);
11342
11327
  const parts = this._consumePrefixAndName();
11343
11328
  return this._endToken(parts);
11344
11329
  }
@@ -11347,44 +11332,38 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11347
11332
  if (attrNameStart === $SQ || attrNameStart === $DQ) {
11348
11333
  throw this._createError(_unexpectedCharacterErrorMsg(attrNameStart), this._cursor.getSpan());
11349
11334
  }
11350
- this._beginToken(TokenType.ATTR_NAME);
11335
+ this._beginToken(14 /* ATTR_NAME */);
11351
11336
  const prefixAndName = this._consumePrefixAndName();
11352
11337
  this._endToken(prefixAndName);
11353
11338
  }
11354
11339
  _consumeAttributeValue() {
11355
- let value;
11356
11340
  if (this._cursor.peek() === $SQ || this._cursor.peek() === $DQ) {
11357
- this._beginToken(TokenType.ATTR_QUOTE);
11358
11341
  const quoteChar = this._cursor.peek();
11359
- this._cursor.advance();
11360
- this._endToken([String.fromCodePoint(quoteChar)]);
11361
- this._beginToken(TokenType.ATTR_VALUE);
11362
- const parts = [];
11363
- while (this._cursor.peek() !== quoteChar) {
11364
- parts.push(this._readChar(true));
11365
- }
11366
- value = parts.join('');
11367
- this._endToken([this._processCarriageReturns(value)]);
11368
- this._beginToken(TokenType.ATTR_QUOTE);
11369
- this._cursor.advance();
11370
- this._endToken([String.fromCodePoint(quoteChar)]);
11342
+ this._consumeQuote(quoteChar);
11343
+ // In an attribute then end of the attribute value and the premature end to an interpolation
11344
+ // are both triggered by the `quoteChar`.
11345
+ const endPredicate = () => this._cursor.peek() === quoteChar;
11346
+ this._consumeWithInterpolation(16 /* ATTR_VALUE_TEXT */, 17 /* ATTR_VALUE_INTERPOLATION */, endPredicate, endPredicate);
11347
+ this._consumeQuote(quoteChar);
11371
11348
  }
11372
11349
  else {
11373
- this._beginToken(TokenType.ATTR_VALUE);
11374
- const valueStart = this._cursor.clone();
11375
- this._requireCharCodeUntilFn(isNameEnd, 1);
11376
- value = this._cursor.getChars(valueStart);
11377
- this._endToken([this._processCarriageReturns(value)]);
11350
+ const endPredicate = () => isNameEnd(this._cursor.peek());
11351
+ this._consumeWithInterpolation(16 /* ATTR_VALUE_TEXT */, 17 /* ATTR_VALUE_INTERPOLATION */, endPredicate, endPredicate);
11378
11352
  }
11379
11353
  }
11354
+ _consumeQuote(quoteChar) {
11355
+ this._beginToken(15 /* ATTR_QUOTE */);
11356
+ this._requireCharCode(quoteChar);
11357
+ this._endToken([String.fromCodePoint(quoteChar)]);
11358
+ }
11380
11359
  _consumeTagOpenEnd() {
11381
- const tokenType = this._attemptCharCode($SLASH) ? TokenType.TAG_OPEN_END_VOID : TokenType.TAG_OPEN_END;
11360
+ const tokenType = this._attemptCharCode($SLASH) ? 2 /* TAG_OPEN_END_VOID */ : 1 /* TAG_OPEN_END */;
11382
11361
  this._beginToken(tokenType);
11383
11362
  this._requireCharCode($GT);
11384
11363
  this._endToken([]);
11385
11364
  }
11386
11365
  _consumeTagClose(start) {
11387
- this._beginToken(TokenType.TAG_CLOSE, start);
11366
+ this._beginToken(3 /* TAG_CLOSE */, start);
11388
11367
  this._attemptCharCodeUntilFn(isNotWhitespace);
11389
11368
  const prefixAndName = this._consumePrefixAndName();
11390
11369
  this._attemptCharCodeUntilFn(isNotWhitespace);
@@ -11392,11 +11371,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11392
11371
  this._endToken(prefixAndName);
11393
11372
  }
11394
11373
  _consumeExpansionFormStart() {
11395
- this._beginToken(TokenType.EXPANSION_FORM_START);
11374
+ this._beginToken(19 /* EXPANSION_FORM_START */);
11396
11375
  this._requireCharCode($LBRACE);
11397
11376
  this._endToken([]);
11398
- this._expansionCaseStack.push(TokenType.EXPANSION_FORM_START);
11399
- this._beginToken(TokenType.RAW_TEXT);
11377
+ this._expansionCaseStack.push(19 /* EXPANSION_FORM_START */);
11378
+ this._beginToken(7 /* RAW_TEXT */);
11400
11379
  const condition = this._readUntil($COMMA);
11401
11380
  const normalizedCondition = this._processCarriageReturns(condition);
11402
11381
  if (this._i18nNormalizeLineEndingsInICUs) {
@@ -11412,59 +11391,139 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11412
11391
  }
11413
11392
  this._requireCharCode($COMMA);
11414
11393
  this._attemptCharCodeUntilFn(isNotWhitespace);
11415
- this._beginToken(TokenType.RAW_TEXT);
11394
+ this._beginToken(7 /* RAW_TEXT */);
11416
11395
  const type = this._readUntil($COMMA);
11417
11396
  this._endToken([type]);
11418
11397
  this._requireCharCode($COMMA);
11419
11398
  this._attemptCharCodeUntilFn(isNotWhitespace);
11420
11399
  }
11421
11400
  _consumeExpansionCaseStart() {
11422
- this._beginToken(TokenType.EXPANSION_CASE_VALUE);
11401
+ this._beginToken(20 /* EXPANSION_CASE_VALUE */);
11423
11402
  const value = this._readUntil($LBRACE).trim();
11424
11403
  this._endToken([value]);
11425
11404
  this._attemptCharCodeUntilFn(isNotWhitespace);
11426
- this._beginToken(TokenType.EXPANSION_CASE_EXP_START);
11405
+ this._beginToken(21 /* EXPANSION_CASE_EXP_START */);
11427
11406
  this._requireCharCode($LBRACE);
11428
11407
  this._endToken([]);
11429
11408
  this._attemptCharCodeUntilFn(isNotWhitespace);
11430
- this._expansionCaseStack.push(TokenType.EXPANSION_CASE_EXP_START);
11409
+ this._expansionCaseStack.push(21 /* EXPANSION_CASE_EXP_START */);
11431
11410
  }
11432
11411
  _consumeExpansionCaseEnd() {
11433
- this._beginToken(TokenType.EXPANSION_CASE_EXP_END);
11412
+ this._beginToken(22 /* EXPANSION_CASE_EXP_END */);
11434
11413
  this._requireCharCode($RBRACE);
11435
11414
  this._endToken([]);
11436
11415
  this._attemptCharCodeUntilFn(isNotWhitespace);
11437
11416
  this._expansionCaseStack.pop();
11438
11417
  }
11439
11418
  _consumeExpansionFormEnd() {
11440
- this._beginToken(TokenType.EXPANSION_FORM_END);
11419
+ this._beginToken(23 /* EXPANSION_FORM_END */);
11441
11420
  this._requireCharCode($RBRACE);
11442
11421
  this._endToken([]);
11443
11422
  this._expansionCaseStack.pop();
11444
11423
  }
11445
- _consumeText() {
11446
- const start = this._cursor.clone();
11447
- this._beginToken(TokenType.TEXT, start);
11424
+ /**
11425
+ * Consume a string that may contain interpolation expressions.
11426
+ *
11427
+ * The first token consumed will be of `tokenType` and then there will be alternating
11428
+ * `interpolationTokenType` and `tokenType` tokens until the `endPredicate()` returns true.
11429
+ *
11430
+ * If an interpolation token ends prematurely it will have no end marker in its `parts` array.
11431
+ *
11432
+ * @param textTokenType the kind of tokens to interleave around interpolation tokens.
11433
+ * @param interpolationTokenType the kind of tokens that contain interpolation.
11434
+ * @param endPredicate a function that should return true when we should stop consuming.
11435
+ * @param endInterpolation a function that should return true if there is a premature end to an
11436
+ * interpolation expression - i.e. before we get to the normal interpolation closing marker.
11437
+ */
11438
+ _consumeWithInterpolation(textTokenType, interpolationTokenType, endPredicate, endInterpolation) {
11439
+ this._beginToken(textTokenType);
11448
11440
  const parts = [];
11449
- do {
11441
+ while (!endPredicate()) {
11442
+ const current = this._cursor.clone();
11450
11443
  if (this._interpolationConfig && this._attemptStr(this._interpolationConfig.start)) {
11451
- parts.push(this._interpolationConfig.start);
11452
- this._inInterpolation = true;
11444
+ this._endToken([this._processCarriageReturns(parts.join(''))], current);
11445
+ parts.length = 0;
11446
+ this._consumeInterpolation(interpolationTokenType, current, endInterpolation);
11447
+ this._beginToken(textTokenType);
11453
11448
  }
11454
- else if (this._interpolationConfig && this._inInterpolation &&
11455
- this._attemptStr(this._interpolationConfig.end)) {
11456
- parts.push(this._interpolationConfig.end);
11457
- this._inInterpolation = false;
11449
+ else if (this._cursor.peek() === $AMPERSAND) {
11450
+ this._endToken([this._processCarriageReturns(parts.join(''))]);
11451
+ parts.length = 0;
11452
+ this._consumeEntity(textTokenType);
11453
+ this._beginToken(textTokenType);
11458
11454
  }
11459
11455
  else {
11460
- parts.push(this._readChar(true));
11456
+ parts.push(this._readChar());
11461
11457
  }
11462
- } while (!this._isTextEnd());
11458
+ }
11463
11459
  // It is possible that an interpolation was started but not ended inside this text token.
11464
11460
  // Make sure that we reset the state of the lexer correctly.
11465
11461
  this._inInterpolation = false;
11466
11462
  this._endToken([this._processCarriageReturns(parts.join(''))]);
11467
11463
  }
11464
+ /**
11465
+ * Consume a block of text that has been interpreted as an Angular interpolation.
11466
+ *
11467
+ * @param interpolationTokenType the type of the interpolation token to generate.
11468
+ * @param interpolationStart a cursor that points to the start of this interpolation.
11469
+ * @param prematureEndPredicate a function that should return true if the next characters indicate
11470
+ * an end to the interpolation before its normal closing marker.
11471
+ */
11472
+ _consumeInterpolation(interpolationTokenType, interpolationStart, prematureEndPredicate) {
11473
+ const parts = [];
11474
+ this._beginToken(interpolationTokenType, interpolationStart);
11475
+ parts.push(this._interpolationConfig.start);
11476
+ // Find the end of the interpolation, ignoring content inside quotes.
11477
+ const expressionStart = this._cursor.clone();
11478
+ let inQuote = null;
11479
+ let inComment = false;
11480
+ while (this._cursor.peek() !== $EOF &&
11481
+ (prematureEndPredicate === null || !prematureEndPredicate())) {
11482
+ const current = this._cursor.clone();
11483
+ if (this._isTagStart()) {
11484
+ // We are starting what looks like an HTML element in the middle of this interpolation.
11485
+ // Reset the cursor to before the `<` character and end the interpolation token.
11486
+ // (This is actually wrong but here for backward compatibility).
11487
+ this._cursor = current;
11488
+ parts.push(this._getProcessedChars(expressionStart, current));
11489
+ this._endToken(parts);
11490
+ return;
11491
+ }
11492
+ if (inQuote === null) {
11493
+ if (this._attemptStr(this._interpolationConfig.end)) {
11494
+ // We are not in a string, and we hit the end interpolation marker
11495
+ parts.push(this._getProcessedChars(expressionStart, current));
11496
+ parts.push(this._interpolationConfig.end);
11497
+ this._endToken(parts);
11498
+ return;
11499
+ }
11500
+ else if (this._attemptStr('//')) {
11501
+ // Once we are in a comment we ignore any quotes
11502
+ inComment = true;
11503
+ }
11504
+ }
11505
+ const char = this._cursor.peek();
11506
+ this._cursor.advance();
11507
+ if (char === $BACKSLASH) {
11508
+ // Skip the next character because it was escaped.
11509
+ this._cursor.advance();
11510
+ }
11511
+ else if (char === inQuote) {
11512
+ // Exiting the current quoted string
11513
+ inQuote = null;
11514
+ }
11515
+ else if (!inComment && inQuote === null && isQuote(char)) {
11516
+ // Entering a new quoted string
11517
+ inQuote = char;
11518
+ }
11519
+ }
11520
+ // We hit EOF without finding a closing interpolation marker
11521
+ parts.push(this._getProcessedChars(expressionStart, this._cursor));
11522
+ this._endToken(parts);
11523
+ }
11524
+ _getProcessedChars(start, end) {
11525
+ return this._processCarriageReturns(end.getChars(start));
11526
+ }
11468
11527
  _isTextEnd() {
11469
11528
  if (this._isTagStart() || this._cursor.peek() === $EOF) {
11470
11529
  return true;
@@ -11507,12 +11566,12 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11507
11566
  _isInExpansionCase() {
11508
11567
  return this._expansionCaseStack.length > 0 &&
11509
11568
  this._expansionCaseStack[this._expansionCaseStack.length - 1] ===
11510
- TokenType.EXPANSION_CASE_EXP_START;
11569
+ 21 /* EXPANSION_CASE_EXP_START */;
11511
11570
  }
11512
11571
  _isInExpansionForm() {
11513
11572
  return this._expansionCaseStack.length > 0 &&
11514
11573
  this._expansionCaseStack[this._expansionCaseStack.length - 1] ===
11515
- TokenType.EXPANSION_FORM_START;
11574
+ 19 /* EXPANSION_FORM_START */;
11516
11575
  }
11517
11576
  isExpansionFormStart() {
11518
11577
  if (this._cursor.peek() !== $LBRACE) {
@@ -11559,7 +11618,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11559
11618
  let lastDstToken = undefined;
11560
11619
  for (let i = 0; i < srcTokens.length; i++) {
11561
11620
  const token = srcTokens[i];
11562
- if (lastDstToken && lastDstToken.type === TokenType.TEXT && token.type === TokenType.TEXT) {
11621
+ if ((lastDstToken && lastDstToken.type === 5 /* TEXT */ && token.type === 5 /* TEXT */) ||
11622
+ (lastDstToken && lastDstToken.type === 16 /* ATTR_VALUE_TEXT */ &&
11623
+ token.type === 16 /* ATTR_VALUE_TEXT */)) {
11563
11624
  lastDstToken.parts[0] += token.parts[0];
11564
11625
  lastDstToken.sourceSpan.end = token.sourceSpan.end;
11565
11626
  }
@@ -11852,28 +11913,28 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11852
11913
  this._advance();
11853
11914
  }
11854
11915
  build() {
11855
- while (this._peek.type !== TokenType.EOF) {
11856
- if (this._peek.type === TokenType.TAG_OPEN_START ||
11857
- this._peek.type === TokenType.INCOMPLETE_TAG_OPEN) {
11916
+ while (this._peek.type !== 24 /* EOF */) {
11917
+ if (this._peek.type === 0 /* TAG_OPEN_START */ ||
11918
+ this._peek.type === 4 /* INCOMPLETE_TAG_OPEN */) {
11858
11919
  this._consumeStartTag(this._advance());
11859
11920
  }
11860
- else if (this._peek.type === TokenType.TAG_CLOSE) {
11921
+ else if (this._peek.type === 3 /* TAG_CLOSE */) {
11861
11922
  this._consumeEndTag(this._advance());
11862
11923
  }
11863
- else if (this._peek.type === TokenType.CDATA_START) {
11924
+ else if (this._peek.type === 12 /* CDATA_START */) {
11864
11925
  this._closeVoidElement();
11865
11926
  this._consumeCdata(this._advance());
11866
11927
  }
11867
- else if (this._peek.type === TokenType.COMMENT_START) {
11928
+ else if (this._peek.type === 10 /* COMMENT_START */) {
11868
11929
  this._closeVoidElement();
11869
11930
  this._consumeComment(this._advance());
11870
11931
  }
11871
- else if (this._peek.type === TokenType.TEXT || this._peek.type === TokenType.RAW_TEXT ||
11872
- this._peek.type === TokenType.ESCAPABLE_RAW_TEXT) {
11932
+ else if (this._peek.type === 5 /* TEXT */ || this._peek.type === 7 /* RAW_TEXT */ ||
11933
+ this._peek.type === 6 /* ESCAPABLE_RAW_TEXT */) {
11873
11934
  this._closeVoidElement();
11874
11935
  this._consumeText(this._advance());
11875
11936
  }
11876
- else if (this._peek.type === TokenType.EXPANSION_FORM_START) {
11937
+ else if (this._peek.type === 19 /* EXPANSION_FORM_START */) {
11877
11938
  this._consumeExpansion(this._advance());
11878
11939
  }
11879
11940
  else {
@@ -11899,11 +11960,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11899
11960
  }
11900
11961
  _consumeCdata(_startToken) {
11901
11962
  this._consumeText(this._advance());
11902
- this._advanceIf(TokenType.CDATA_END);
11963
+ this._advanceIf(13 /* CDATA_END */);
11903
11964
  }
11904
11965
  _consumeComment(token) {
11905
- const text = this._advanceIf(TokenType.RAW_TEXT);
11906
- this._advanceIf(TokenType.COMMENT_END);
11966
+ const text = this._advanceIf(7 /* RAW_TEXT */);
11967
+ this._advanceIf(11 /* COMMENT_END */);
11907
11968
  const value = text != null ? text.parts[0].trim() : null;
11908
11969
  this._addToParent(new Comment$1(value, token.sourceSpan));
11909
11970
  }
@@ -11912,14 +11973,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11912
11973
  const type = this._advance();
11913
11974
  const cases = [];
11914
11975
  // read =
11915
- while (this._peek.type === TokenType.EXPANSION_CASE_VALUE) {
11976
+ while (this._peek.type === 20 /* EXPANSION_CASE_VALUE */) {
11916
11977
  const expCase = this._parseExpansionCase();
11917
11978
  if (!expCase)
11918
11979
  return; // error
11919
11980
  cases.push(expCase);
11920
11981
  }
11921
11982
  // read the final }
11922
- if (this._peek.type !== TokenType.EXPANSION_FORM_END) {
11983
+ if (this._peek.type !== 23 /* EXPANSION_FORM_END */) {
11923
11984
  this.errors.push(TreeError.create(null, this._peek.sourceSpan, `Invalid ICU message. Missing '}'.`));
11924
11985
  return;
11925
11986
  }
@@ -11930,7 +11991,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11930
11991
  _parseExpansionCase() {
11931
11992
  const value = this._advance();
11932
11993
  // read {
11933
- if (this._peek.type !== TokenType.EXPANSION_CASE_EXP_START) {
11994
+ if (this._peek.type !== 21 /* EXPANSION_CASE_EXP_START */) {
11934
11995
  this.errors.push(TreeError.create(null, this._peek.sourceSpan, `Invalid ICU message. Missing '{'.`));
11935
11996
  return null;
11936
11997
  }
@@ -11940,7 +12001,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11940
12001
  if (!exp)
11941
12002
  return null;
11942
12003
  const end = this._advance();
11943
- exp.push(new Token(TokenType.EOF, [], end.sourceSpan));
12004
+ exp.push({ type: 24 /* EOF */, parts: [], sourceSpan: end.sourceSpan });
11944
12005
  // parse everything in between { and }
11945
12006
  const expansionCaseParser = new _TreeBuilder(exp, this.getTagDefinition);
11946
12007
  expansionCaseParser.build();
@@ -11954,14 +12015,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11954
12015
  }
11955
12016
  _collectExpansionExpTokens(start) {
11956
12017
  const exp = [];
11957
- const expansionFormStack = [TokenType.EXPANSION_CASE_EXP_START];
12018
+ const expansionFormStack = [21 /* EXPANSION_CASE_EXP_START */];
11958
12019
  while (true) {
11959
- if (this._peek.type === TokenType.EXPANSION_FORM_START ||
11960
- this._peek.type === TokenType.EXPANSION_CASE_EXP_START) {
12020
+ if (this._peek.type === 19 /* EXPANSION_FORM_START */ ||
12021
+ this._peek.type === 21 /* EXPANSION_CASE_EXP_START */) {
11961
12022
  expansionFormStack.push(this._peek.type);
11962
12023
  }
11963
- if (this._peek.type === TokenType.EXPANSION_CASE_EXP_END) {
11964
- if (lastOnStack(expansionFormStack, TokenType.EXPANSION_CASE_EXP_START)) {
12024
+ if (this._peek.type === 22 /* EXPANSION_CASE_EXP_END */) {
12025
+ if (lastOnStack(expansionFormStack, 21 /* EXPANSION_CASE_EXP_START */)) {
11965
12026
  expansionFormStack.pop();
11966
12027
  if (expansionFormStack.length === 0)
11967
12028
  return exp;
@@ -11971,8 +12032,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11971
12032
  return null;
11972
12033
  }
11973
12034
  }
11974
- if (this._peek.type === TokenType.EXPANSION_FORM_END) {
11975
- if (lastOnStack(expansionFormStack, TokenType.EXPANSION_FORM_START)) {
12035
+ if (this._peek.type === 23 /* EXPANSION_FORM_END */) {
12036
+ if (lastOnStack(expansionFormStack, 19 /* EXPANSION_FORM_START */)) {
11976
12037
  expansionFormStack.pop();
11977
12038
  }
11978
12039
  else {
@@ -11980,7 +12041,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11980
12041
  return null;
11981
12042
  }
11982
12043
  }
11983
- if (this._peek.type === TokenType.EOF) {
12044
+ if (this._peek.type === 24 /* EOF */) {
11984
12045
  this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
11985
12046
  return null;
11986
12047
  }
@@ -11988,16 +12049,38 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
11988
12049
  }
11989
12050
  }
11990
12051
  _consumeText(token) {
12052
+ const tokens = [token];
12053
+ const startSpan = token.sourceSpan;
11991
12054
  let text = token.parts[0];
11992
12055
  if (text.length > 0 && text[0] === '\n') {
11993
12056
  const parent = this._getParentElement();
11994
12057
  if (parent != null && parent.children.length === 0 &&
11995
12058
  this.getTagDefinition(parent.name).ignoreFirstLf) {
11996
12059
  text = text.substring(1);
12060
+ tokens[0] = { type: token.type, sourceSpan: token.sourceSpan, parts: [text] };
12061
+ }
12062
+ }
12063
+ while (this._peek.type === 8 /* INTERPOLATION */ || this._peek.type === 5 /* TEXT */ ||
12064
+ this._peek.type === 9 /* ENCODED_ENTITY */) {
12065
+ token = this._advance();
12066
+ tokens.push(token);
12067
+ if (token.type === 8 /* INTERPOLATION */) {
12068
+ // For backward compatibility we decode HTML entities that appear in interpolation
12069
+ // expressions. This is arguably a bug, but it could be a considerable breaking change to
12070
+ // fix it. It should be addressed in a larger project to refactor the entire parser/lexer
12071
+ // chain after View Engine has been removed.
12072
+ text += token.parts.join('').replace(/&([^;]+);/g, decodeEntity);
12073
+ }
12074
+ else if (token.type === 9 /* ENCODED_ENTITY */) {
12075
+ text += token.parts[0];
12076
+ }
12077
+ else {
12078
+ text += token.parts.join('');
11997
12079
  }
11998
12080
  }
11999
12081
  if (text.length > 0) {
12000
- this._addToParent(new Text$2(text, token.sourceSpan));
12082
+ const endSpan = token.sourceSpan;
12083
+ this._addToParent(new Text$2(text, new ParseSourceSpan(startSpan.start, endSpan.end, startSpan.fullStart, startSpan.details), tokens));
12001
12084
  }
12002
12085
  }
12003
12086
  _closeVoidElement() {
@@ -12009,14 +12092,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
12009
12092
  _consumeStartTag(startTagToken) {
12010
12093
  const [prefix, name] = startTagToken.parts;
12011
12094
  const attrs = [];
12012
- while (this._peek.type === TokenType.ATTR_NAME) {
12095
+ while (this._peek.type === 14 /* ATTR_NAME */) {
12013
12096
  attrs.push(this._consumeAttr(this._advance()));
12014
12097
  }
12015
12098
  const fullName = this._getElementFullName(prefix, name, this._getParentElement());
12016
12099
  let selfClosing = false;
12017
12100
  // Note: There could have been a tokenizer error
12018
12101
  // so that we don't get a token for the end tag...
12019
- if (this._peek.type === TokenType.TAG_OPEN_END_VOID) {
12102
+ if (this._peek.type === 2 /* TAG_OPEN_END_VOID */) {
12020
12103
  this._advance();
12021
12104
  selfClosing = true;
12022
12105
  const tagDef = this.getTagDefinition(fullName);
@@ -12024,7 +12107,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
12024
12107
  this.errors.push(TreeError.create(fullName, startTagToken.sourceSpan, `Only void and foreign elements can be self closed "${startTagToken.parts[1]}"`));
12025
12108
  }
12026
12109
  }
12027
- else if (this._peek.type === TokenType.TAG_OPEN_END) {
12110
+ else if (this._peek.type === 1 /* TAG_OPEN_END */) {
12028
12111
  this._advance();
12029
12112
  selfClosing = false;
12030
12113
  }
@@ -12039,7 +12122,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
12039
12122
  // element start tag also represents the end tag.
12040
12123
  this._popElement(fullName, span);
12041
12124
  }
12042
- else if (startTagToken.type === TokenType.INCOMPLETE_TAG_OPEN) {
12125
+ else if (startTagToken.type === 4 /* INCOMPLETE_TAG_OPEN */) {
12043
12126
  // We already know the opening tag is not complete, so it is unlikely it has a corresponding
12044
12127
  // close tag. Let's optimistically parse it as a full element and emit an error.
12045
12128
  this._popElement(fullName, null);
@@ -12094,24 +12177,53 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
12094
12177
  }
12095
12178
  _consumeAttr(attrName) {
12096
12179
  const fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]);
12097
- let end = attrName.sourceSpan.end;
12098
- let value = '';
12099
- let valueSpan = undefined;
12100
- if (this._peek.type === TokenType.ATTR_QUOTE) {
12180
+ let attrEnd = attrName.sourceSpan.end;
12181
+ // Consume any quote
12182
+ if (this._peek.type === 15 /* ATTR_QUOTE */) {
12101
12183
  this._advance();
12102
12184
  }
12103
- if (this._peek.type === TokenType.ATTR_VALUE) {
12104
- const valueToken = this._advance();
12105
- value = valueToken.parts[0];
12106
- end = valueToken.sourceSpan.end;
12107
- valueSpan = valueToken.sourceSpan;
12185
+ // Consume the attribute value
12186
+ let value = '';
12187
+ const valueTokens = [];
12188
+ let valueStartSpan = undefined;
12189
+ let valueEnd = undefined;
12190
+ // NOTE: We need to use a new variable `nextTokenType` here to hide the actual type of
12191
+ // `_peek.type` from TS. Otherwise TS will narrow the type of `_peek.type` preventing it from
12192
+ // being able to consider `ATTR_VALUE_INTERPOLATION` as an option. This is because TS is not
12193
+ // able to see that `_advance()` will actually mutate `_peek`.
12194
+ const nextTokenType = this._peek.type;
12195
+ if (nextTokenType === 16 /* ATTR_VALUE_TEXT */) {
12196
+ valueStartSpan = this._peek.sourceSpan;
12197
+ valueEnd = this._peek.sourceSpan.end;
12198
+ while (this._peek.type === 16 /* ATTR_VALUE_TEXT */ ||
12199
+ this._peek.type === 17 /* ATTR_VALUE_INTERPOLATION */ ||
12200
+ this._peek.type === 9 /* ENCODED_ENTITY */) {
12201
+ const valueToken = this._advance();
12202
+ valueTokens.push(valueToken);
12203
+ if (valueToken.type === 17 /* ATTR_VALUE_INTERPOLATION */) {
12204
+ // For backward compatibility we decode HTML entities that appear in interpolation
12205
+ // expressions. This is arguably a bug, but it could be a considerable breaking change to
12206
+ // fix it. It should be addressed in a larger project to refactor the entire parser/lexer
12207
+ // chain after View Engine has been removed.
12208
+ value += valueToken.parts.join('').replace(/&([^;]+);/g, decodeEntity);
12209
+ }
12210
+ else if (valueToken.type === 9 /* ENCODED_ENTITY */) {
12211
+ value += valueToken.parts[0];
12212
+ }
12213
+ else {
12214
+ value += valueToken.parts.join('');
12215
+ }
12216
+ valueEnd = attrEnd = valueToken.sourceSpan.end;
12217
+ }
12108
12218
  }
12109
- if (this._peek.type === TokenType.ATTR_QUOTE) {
12219
+ // Consume any quote
12220
+ if (this._peek.type === 15 /* ATTR_QUOTE */) {
12110
12221
  const quoteToken = this._advance();
12111
- end = quoteToken.sourceSpan.end;
12222
+ attrEnd = quoteToken.sourceSpan.end;
12112
12223
  }
12113
- const keySpan = new ParseSourceSpan(attrName.sourceSpan.start, attrName.sourceSpan.end);
12114
- return new Attribute(fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, end, attrName.sourceSpan.fullStart), keySpan, valueSpan);
12224
+ const valueSpan = valueStartSpan && valueEnd &&
12225
+ new ParseSourceSpan(valueStartSpan.start, valueEnd, valueStartSpan.fullStart);
12226
+ return new Attribute(fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, attrEnd, attrName.sourceSpan.fullStart), attrName.sourceSpan, valueSpan, valueTokens.length > 0 ? valueTokens : undefined, undefined);
12115
12227
  }
12116
12228
  _getParentElement() {
12117
12229
  return this._elementStack.length > 0 ? this._elementStack[this._elementStack.length - 1] : null;
@@ -12142,6 +12254,23 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
12142
12254
  function lastOnStack(stack, element) {
12143
12255
  return stack.length > 0 && stack[stack.length - 1] === element;
12144
12256
  }
12257
+ /**
12258
+ * Decode the `entity` string, which we believe is the contents of an HTML entity.
12259
+ *
12260
+ * If the string is not actually a valid/known entity then just return the original `match` string.
12261
+ */
12262
+ function decodeEntity(match, entity) {
12263
+ if (NAMED_ENTITIES[entity] !== undefined) {
12264
+ return NAMED_ENTITIES[entity] || match;
12265
+ }
12266
+ if (/^#x[a-f0-9]+$/i.test(entity)) {
12267
+ return String.fromCodePoint(parseInt(entity.slice(2), 16));
12268
+ }
12269
+ if (/^#\d+$/.test(entity)) {
12270
+ return String.fromCodePoint(parseInt(entity.slice(1), 10));
12271
+ }
12272
+ return match;
12273
+ }
12145
12274
 
12146
12275
  /**
12147
12276
  * @license
@@ -12217,7 +12346,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
12217
12346
  const hasExpansionSibling = context &&
12218
12347
  (context.prev instanceof Expansion || context.next instanceof Expansion);
12219
12348
  if (isNotBlank || hasExpansionSibling) {
12220
- return new Text$2(replaceNgsp(text.value).replace(WS_REPLACE_REGEXP, ' '), text.sourceSpan, text.i18n);
12349
+ // Process the whitespace in the tokens of this Text node
12350
+ const tokens = text.tokens.map(token => token.type === 5 /* TEXT */ ? createWhitespaceProcessedTextToken(token) : token);
12351
+ // Process the whitespace of the value of this Text node
12352
+ const value = processWhitespace(text.value);
12353
+ return new Text$2(value, text.sourceSpan, tokens, text.i18n);
12221
12354
  }
12222
12355
  return null;
12223
12356
  }
@@ -12231,6 +12364,12 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
12231
12364
  return expansionCase;
12232
12365
  }
12233
12366
  }
12367
+ function createWhitespaceProcessedTextToken({ type, parts, sourceSpan }) {
12368
+ return { type, parts: [processWhitespace(parts[0])], sourceSpan };
12369
+ }
12370
+ function processWhitespace(text) {
12371
+ return replaceNgsp(text).replace(WS_REPLACE_REGEXP, ' ');
12372
+ }
12234
12373
  function visitAllWithSiblings(visitor, nodes) {
12235
12374
  const result = [];
12236
12375
  nodes.forEach((ast, i) => {
@@ -13481,7 +13620,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
13481
13620
  * Use of this source code is governed by an MIT-style license that can be
13482
13621
  * found in the LICENSE file at https://angular.io/license
13483
13622
  */
13484
- var TokenType$1;
13623
+ var TokenType;
13485
13624
  (function (TokenType) {
13486
13625
  TokenType[TokenType["Character"] = 0] = "Character";
13487
13626
  TokenType[TokenType["Identifier"] = 1] = "Identifier";
@@ -13491,7 +13630,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
13491
13630
  TokenType[TokenType["Operator"] = 5] = "Operator";
13492
13631
  TokenType[TokenType["Number"] = 6] = "Number";
13493
13632
  TokenType[TokenType["Error"] = 7] = "Error";
13494
- })(TokenType$1 || (TokenType$1 = {}));
13633
+ })(TokenType || (TokenType = {}));
13495
13634
  const KEYWORDS = ['var', 'let', 'as', 'null', 'undefined', 'true', 'false', 'if', 'else', 'this'];
13496
13635
  class Lexer {
13497
13636
  tokenize(text) {
@@ -13505,7 +13644,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
13505
13644
  return tokens;
13506
13645
  }
13507
13646
  }
13508
- class Token$1 {
13647
+ class Token {
13509
13648
  constructor(index, end, type, numValue, strValue) {
13510
13649
  this.index = index;
13511
13650
  this.end = end;
@@ -13514,64 +13653,64 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
13514
13653
  this.strValue = strValue;
13515
13654
  }
13516
13655
  isCharacter(code) {
13517
- return this.type == TokenType$1.Character && this.numValue == code;
13656
+ return this.type == TokenType.Character && this.numValue == code;
13518
13657
  }
13519
13658
  isNumber() {
13520
- return this.type == TokenType$1.Number;
13659
+ return this.type == TokenType.Number;
13521
13660
  }
13522
13661
  isString() {
13523
- return this.type == TokenType$1.String;
13662
+ return this.type == TokenType.String;
13524
13663
  }
13525
13664
  isOperator(operator) {
13526
- return this.type == TokenType$1.Operator && this.strValue == operator;
13665
+ return this.type == TokenType.Operator && this.strValue == operator;
13527
13666
  }
13528
13667
  isIdentifier() {
13529
- return this.type == TokenType$1.Identifier;
13668
+ return this.type == TokenType.Identifier;
13530
13669
  }
13531
13670
  isPrivateIdentifier() {
13532
- return this.type == TokenType$1.PrivateIdentifier;
13671
+ return this.type == TokenType.PrivateIdentifier;
13533
13672
  }
13534
13673
  isKeyword() {
13535
- return this.type == TokenType$1.Keyword;
13674
+ return this.type == TokenType.Keyword;
13536
13675
  }
13537
13676
  isKeywordLet() {
13538
- return this.type == TokenType$1.Keyword && this.strValue == 'let';
13677
+ return this.type == TokenType.Keyword && this.strValue == 'let';
13539
13678
  }
13540
13679
  isKeywordAs() {
13541
- return this.type == TokenType$1.Keyword && this.strValue == 'as';
13680
+ return this.type == TokenType.Keyword && this.strValue == 'as';
13542
13681
  }
13543
13682
  isKeywordNull() {
13544
- return this.type == TokenType$1.Keyword && this.strValue == 'null';
13683
+ return this.type == TokenType.Keyword && this.strValue == 'null';
13545
13684
  }
13546
13685
  isKeywordUndefined() {
13547
- return this.type == TokenType$1.Keyword && this.strValue == 'undefined';
13686
+ return this.type == TokenType.Keyword && this.strValue == 'undefined';
13548
13687
  }
13549
13688
  isKeywordTrue() {
13550
- return this.type == TokenType$1.Keyword && this.strValue == 'true';
13689
+ return this.type == TokenType.Keyword && this.strValue == 'true';
13551
13690
  }
13552
13691
  isKeywordFalse() {
13553
- return this.type == TokenType$1.Keyword && this.strValue == 'false';
13692
+ return this.type == TokenType.Keyword && this.strValue == 'false';
13554
13693
  }
13555
13694
  isKeywordThis() {
13556
- return this.type == TokenType$1.Keyword && this.strValue == 'this';
13695
+ return this.type == TokenType.Keyword && this.strValue == 'this';
13557
13696
  }
13558
13697
  isError() {
13559
- return this.type == TokenType$1.Error;
13698
+ return this.type == TokenType.Error;
13560
13699
  }
13561
13700
  toNumber() {
13562
- return this.type == TokenType$1.Number ? this.numValue : -1;
13701
+ return this.type == TokenType.Number ? this.numValue : -1;
13563
13702
  }
13564
13703
  toString() {
13565
13704
  switch (this.type) {
13566
- case TokenType$1.Character:
13567
- case TokenType$1.Identifier:
13568
- case TokenType$1.Keyword:
13569
- case TokenType$1.Operator:
13570
- case TokenType$1.PrivateIdentifier:
13571
- case TokenType$1.String:
13572
- case TokenType$1.Error:
13705
+ case TokenType.Character:
13706
+ case TokenType.Identifier:
13707
+ case TokenType.Keyword:
13708
+ case TokenType.Operator:
13709
+ case TokenType.PrivateIdentifier:
13710
+ case TokenType.String:
13711
+ case TokenType.Error:
13573
13712
  return this.strValue;
13574
- case TokenType$1.Number:
13713
+ case TokenType.Number:
13575
13714
  return this.numValue.toString();
13576
13715
  default:
13577
13716
  return null;
@@ -13579,30 +13718,30 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
13579
13718
  }
13580
13719
  }
13581
13720
  function newCharacterToken(index, end, code) {
13582
- return new Token$1(index, end, TokenType$1.Character, code, String.fromCharCode(code));
13721
+ return new Token(index, end, TokenType.Character, code, String.fromCharCode(code));
13583
13722
  }
13584
13723
  function newIdentifierToken(index, end, text) {
13585
- return new Token$1(index, end, TokenType$1.Identifier, 0, text);
13724
+ return new Token(index, end, TokenType.Identifier, 0, text);
13586
13725
  }
13587
13726
  function newPrivateIdentifierToken(index, end, text) {
13588
- return new Token$1(index, end, TokenType$1.PrivateIdentifier, 0, text);
13727
+ return new Token(index, end, TokenType.PrivateIdentifier, 0, text);
13589
13728
  }
13590
13729
  function newKeywordToken(index, end, text) {
13591
- return new Token$1(index, end, TokenType$1.Keyword, 0, text);
13730
+ return new Token(index, end, TokenType.Keyword, 0, text);
13592
13731
  }
13593
13732
  function newOperatorToken(index, end, text) {
13594
- return new Token$1(index, end, TokenType$1.Operator, 0, text);
13733
+ return new Token(index, end, TokenType.Operator, 0, text);
13595
13734
  }
13596
13735
  function newStringToken(index, end, text) {
13597
- return new Token$1(index, end, TokenType$1.String, 0, text);
13736
+ return new Token(index, end, TokenType.String, 0, text);
13598
13737
  }
13599
13738
  function newNumberToken(index, end, n) {
13600
- return new Token$1(index, end, TokenType$1.Number, n, '');
13739
+ return new Token(index, end, TokenType.Number, n, '');
13601
13740
  }
13602
13741
  function newErrorToken(index, end, message) {
13603
- return new Token$1(index, end, TokenType$1.Error, 0, message);
13742
+ return new Token(index, end, TokenType.Error, 0, message);
13604
13743
  }
13605
- const EOF = new Token$1(-1, -1, TokenType$1.Character, 0, '');
13744
+ const EOF = new Token(-1, -1, TokenType.Character, 0, '');
13606
13745
  class _Scanner {
13607
13746
  constructor(input) {
13608
13747
  this.input = input;
@@ -14509,7 +14648,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
14509
14648
  // '==','!=','===','!=='
14510
14649
  const start = this.inputIndex;
14511
14650
  let result = this.parseRelational();
14512
- while (this.next.type == TokenType$1.Operator) {
14651
+ while (this.next.type == TokenType.Operator) {
14513
14652
  const operator = this.next.strValue;
14514
14653
  switch (operator) {
14515
14654
  case '==':
@@ -14529,7 +14668,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
14529
14668
  // '<', '>', '<=', '>='
14530
14669
  const start = this.inputIndex;
14531
14670
  let result = this.parseAdditive();
14532
- while (this.next.type == TokenType$1.Operator) {
14671
+ while (this.next.type == TokenType.Operator) {
14533
14672
  const operator = this.next.strValue;
14534
14673
  switch (operator) {
14535
14674
  case '<':
@@ -14549,7 +14688,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
14549
14688
  // '+', '-'
14550
14689
  const start = this.inputIndex;
14551
14690
  let result = this.parseMultiplicative();
14552
- while (this.next.type == TokenType$1.Operator) {
14691
+ while (this.next.type == TokenType.Operator) {
14553
14692
  const operator = this.next.strValue;
14554
14693
  switch (operator) {
14555
14694
  case '+':
@@ -14567,7 +14706,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
14567
14706
  // '*', '%', '/'
14568
14707
  const start = this.inputIndex;
14569
14708
  let result = this.parsePrefix();
14570
- while (this.next.type == TokenType$1.Operator) {
14709
+ while (this.next.type == TokenType.Operator) {
14571
14710
  const operator = this.next.strValue;
14572
14711
  switch (operator) {
14573
14712
  case '*':
@@ -14583,7 +14722,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
14583
14722
  return result;
14584
14723
  }
14585
14724
  parsePrefix() {
14586
- if (this.next.type == TokenType$1.Operator) {
14725
+ if (this.next.type == TokenType.Operator) {
14587
14726
  const start = this.inputIndex;
14588
14727
  const operator = this.next.strValue;
14589
14728
  let result;
@@ -16515,11 +16654,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
16515
16654
  return context.visitNodeFn(el, node);
16516
16655
  }
16517
16656
  visitAttribute(attribute, context) {
16518
- const node = this._visitTextWithInterpolation(attribute.value, attribute.valueSpan || attribute.sourceSpan, context, attribute.i18n);
16657
+ const node = attribute.valueTokens === undefined || attribute.valueTokens.length === 1 ?
16658
+ new Text$1(attribute.value, attribute.valueSpan || attribute.sourceSpan) :
16659
+ this._visitTextWithInterpolation(attribute.valueTokens, attribute.valueSpan || attribute.sourceSpan, context, attribute.i18n);
16519
16660
  return context.visitNodeFn(attribute, node);
16520
16661
  }
16521
16662
  visitText(text, context) {
16522
- const node = this._visitTextWithInterpolation(text.value, text.sourceSpan, context, text.i18n);
16663
+ const node = text.tokens.length === 1 ?
16664
+ new Text$1(text.value, text.sourceSpan) :
16665
+ this._visitTextWithInterpolation(text.tokens, text.sourceSpan, context, text.i18n);
16523
16666
  return context.visitNodeFn(text, node);
16524
16667
  }
16525
16668
  visitComment(comment, context) {
@@ -16558,61 +16701,58 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
16558
16701
  throw new Error('Unreachable code');
16559
16702
  }
16560
16703
  /**
16561
- * Split the, potentially interpolated, text up into text and placeholder pieces.
16704
+ * Convert, text and interpolated tokens up into text and placeholder pieces.
16562
16705
  *
16563
- * @param text The potentially interpolated string to be split.
16706
+ * @param tokens The text and interpolated tokens.
16564
16707
  * @param sourceSpan The span of the whole of the `text` string.
16565
16708
  * @param context The current context of the visitor, used to compute and store placeholders.
16566
16709
  * @param previousI18n Any i18n metadata associated with this `text` from a previous pass.
16567
16710
  */
16568
- _visitTextWithInterpolation(text, sourceSpan, context, previousI18n) {
16569
- const { strings, expressions } = this._expressionParser.splitInterpolation(text, sourceSpan.start.toString(), this._interpolationConfig);
16570
- // No expressions, return a single text.
16571
- if (expressions.length === 0) {
16572
- return new Text$1(text, sourceSpan);
16573
- }
16711
+ _visitTextWithInterpolation(tokens, sourceSpan, context, previousI18n) {
16574
16712
  // Return a sequence of `Text` and `Placeholder` nodes grouped in a `Container`.
16575
16713
  const nodes = [];
16576
- for (let i = 0; i < strings.length - 1; i++) {
16577
- this._addText(nodes, strings[i], sourceSpan);
16578
- this._addPlaceholder(nodes, context, expressions[i], sourceSpan);
16714
+ // We will only create a container if there are actually interpolations,
16715
+ // so this flag tracks that.
16716
+ let hasInterpolation = false;
16717
+ for (const token of tokens) {
16718
+ switch (token.type) {
16719
+ case 8 /* INTERPOLATION */:
16720
+ case 17 /* ATTR_VALUE_INTERPOLATION */:
16721
+ hasInterpolation = true;
16722
+ const expression = token.parts[1];
16723
+ const baseName = extractPlaceholderName(expression) || 'INTERPOLATION';
16724
+ const phName = context.placeholderRegistry.getPlaceholderName(baseName, expression);
16725
+ context.placeholderToContent[phName] = {
16726
+ text: token.parts.join(''),
16727
+ sourceSpan: token.sourceSpan
16728
+ };
16729
+ nodes.push(new Placeholder(expression, phName, token.sourceSpan));
16730
+ break;
16731
+ default:
16732
+ if (token.parts[0].length > 0) {
16733
+ // This token is text or an encoded entity.
16734
+ // If it is following on from a previous text node then merge it into that node
16735
+ // Otherwise, if it is following an interpolation, then add a new node.
16736
+ const previous = nodes[nodes.length - 1];
16737
+ if (previous instanceof Text$1) {
16738
+ previous.value += token.parts[0];
16739
+ previous.sourceSpan = new ParseSourceSpan(previous.sourceSpan.start, token.sourceSpan.end, previous.sourceSpan.fullStart, previous.sourceSpan.details);
16740
+ }
16741
+ else {
16742
+ nodes.push(new Text$1(token.parts[0], token.sourceSpan));
16743
+ }
16744
+ }
16745
+ break;
16746
+ }
16579
16747
  }
16580
- // The last index contains no expression
16581
- this._addText(nodes, strings[strings.length - 1], sourceSpan);
16582
- // Whitespace removal may have invalidated the interpolation source-spans.
16583
- reusePreviousSourceSpans(nodes, previousI18n);
16584
- return new Container(nodes, sourceSpan);
16585
- }
16586
- /**
16587
- * Create a new `Text` node from the `textPiece` and add it to the `nodes` collection.
16588
- *
16589
- * @param nodes The nodes to which the created `Text` node should be added.
16590
- * @param textPiece The text and relative span information for this `Text` node.
16591
- * @param interpolationSpan The span of the whole interpolated text.
16592
- */
16593
- _addText(nodes, textPiece, interpolationSpan) {
16594
- if (textPiece.text.length > 0) {
16595
- // No need to add empty strings
16596
- const stringSpan = getOffsetSourceSpan(interpolationSpan, textPiece);
16597
- nodes.push(new Text$1(textPiece.text, stringSpan));
16748
+ if (hasInterpolation) {
16749
+ // Whitespace removal may have invalidated the interpolation source-spans.
16750
+ reusePreviousSourceSpans(nodes, previousI18n);
16751
+ return new Container(nodes, sourceSpan);
16752
+ }
16753
+ else {
16754
+ return nodes[0];
16598
16755
  }
16599
- }
16600
- /**
16601
- * Create a new `Placeholder` node from the `expression` and add it to the `nodes` collection.
16602
- *
16603
- * @param nodes The nodes to which the created `Text` node should be added.
16604
- * @param context The current context of the visitor, used to compute and store placeholders.
16605
- * @param expression The expression text and relative span information for this `Placeholder`
16606
- * node.
16607
- * @param interpolationSpan The span of the whole interpolated text.
16608
- */
16609
- _addPlaceholder(nodes, context, expression, interpolationSpan) {
16610
- const sourceSpan = getOffsetSourceSpan(interpolationSpan, expression);
16611
- const baseName = extractPlaceholderName(expression.text) || 'INTERPOLATION';
16612
- const phName = context.placeholderRegistry.getPlaceholderName(baseName, expression.text);
16613
- const text = this._interpolationConfig.start + expression.text + this._interpolationConfig.end;
16614
- context.placeholderToContent[phName] = { text, sourceSpan };
16615
- nodes.push(new Placeholder(expression.text, phName, sourceSpan));
16616
16756
  }
16617
16757
  }
16618
16758
  /**
@@ -16634,7 +16774,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
16634
16774
  }
16635
16775
  if (previousI18n instanceof Container) {
16636
16776
  // The `previousI18n` is a `Container`, which means that this is a second i18n extraction pass
16637
- // after whitespace has been removed from the AST ndoes.
16777
+ // after whitespace has been removed from the AST nodes.
16638
16778
  assertEquivalentNodes(previousI18n.children, nodes);
16639
16779
  // Reuse the source-spans from the first pass.
16640
16780
  for (let i = 0; i < nodes.length; i++) {
@@ -16663,12 +16803,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
16663
16803
  throw new Error('The types of the i18n message children changed between first and second pass.');
16664
16804
  }
16665
16805
  }
16666
- /**
16667
- * Create a new `ParseSourceSpan` from the `sourceSpan`, offset by the `start` and `end` values.
16668
- */
16669
- function getOffsetSourceSpan(sourceSpan, { start, end }) {
16670
- return new ParseSourceSpan(sourceSpan.fullStart.moveBy(start), sourceSpan.fullStart.moveBy(end));
16671
- }
16672
16806
  const _CUSTOM_PH_EXP = /\/\/[\s\S]*i18n[\s\S]*\([\s\S]*ph[\s\S]*=[\s\S]*("|')([\s\S]*?)\1[\s\S]*\)/g;
16673
16807
  function extractPlaceholderName(input) {
16674
16808
  return input.split(_CUSTOM_PH_EXP)[2];
@@ -16988,7 +17122,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
16988
17122
  context[context.length - 1].text += text.value;
16989
17123
  }
16990
17124
  else {
16991
- context.push(new LiteralPiece(text.value, text.sourceSpan));
17125
+ const sourceSpan = new ParseSourceSpan(text.sourceSpan.fullStart, text.sourceSpan.end, text.sourceSpan.fullStart, text.sourceSpan.details);
17126
+ context.push(new LiteralPiece(text.value, sourceSpan));
16992
17127
  }
16993
17128
  }
16994
17129
  visitContainer(container, context) {
@@ -17032,7 +17167,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
17032
17167
  function getSourceSpan(message) {
17033
17168
  const startNode = message.nodes[0];
17034
17169
  const endNode = message.nodes[message.nodes.length - 1];
17035
- return new ParseSourceSpan(startNode.sourceSpan.start, endNode.sourceSpan.end, startNode.sourceSpan.fullStart, startNode.sourceSpan.details);
17170
+ return new ParseSourceSpan(startNode.sourceSpan.fullStart, endNode.sourceSpan.end, startNode.sourceSpan.fullStart, startNode.sourceSpan.details);
17036
17171
  }
17037
17172
  /**
17038
17173
  * Convert the list of serialized MessagePieces into two arrays.
@@ -19938,7 +20073,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19938
20073
  * Use of this source code is governed by an MIT-style license that can be
19939
20074
  * found in the LICENSE file at https://angular.io/license
19940
20075
  */
19941
- const VERSION$1 = new Version('12.2.6');
20076
+ const VERSION$1 = new Version('12.2.7');
19942
20077
 
19943
20078
  /**
19944
20079
  * @license
@@ -20577,7 +20712,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20577
20712
  function compileDeclareClassMetadata(metadata) {
20578
20713
  const definitionMap = new DefinitionMap();
20579
20714
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
20580
- definitionMap.set('version', literal('12.2.6'));
20715
+ definitionMap.set('version', literal('12.2.7'));
20581
20716
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20582
20717
  definitionMap.set('type', metadata.type);
20583
20718
  definitionMap.set('decorators', metadata.decorators);
@@ -20617,7 +20752,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20617
20752
  function createDirectiveDefinitionMap(meta) {
20618
20753
  const definitionMap = new DefinitionMap();
20619
20754
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
20620
- definitionMap.set('version', literal('12.2.6'));
20755
+ definitionMap.set('version', literal('12.2.7'));
20621
20756
  // e.g. `type: MyDirective`
20622
20757
  definitionMap.set('type', meta.internalType);
20623
20758
  // e.g. `selector: 'some-dir'`
@@ -20834,7 +20969,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20834
20969
  function compileDeclareFactoryFunction(meta) {
20835
20970
  const definitionMap = new DefinitionMap();
20836
20971
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
20837
- definitionMap.set('version', literal('12.2.6'));
20972
+ definitionMap.set('version', literal('12.2.7'));
20838
20973
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20839
20974
  definitionMap.set('type', meta.internalType);
20840
20975
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -20876,7 +21011,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20876
21011
  function createInjectableDefinitionMap(meta) {
20877
21012
  const definitionMap = new DefinitionMap();
20878
21013
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
20879
- definitionMap.set('version', literal('12.2.6'));
21014
+ definitionMap.set('version', literal('12.2.7'));
20880
21015
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20881
21016
  definitionMap.set('type', meta.internalType);
20882
21017
  // Only generate providedIn property if it has a non-null value
@@ -20955,7 +21090,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20955
21090
  function createInjectorDefinitionMap(meta) {
20956
21091
  const definitionMap = new DefinitionMap();
20957
21092
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
20958
- definitionMap.set('version', literal('12.2.6'));
21093
+ definitionMap.set('version', literal('12.2.7'));
20959
21094
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20960
21095
  definitionMap.set('type', meta.internalType);
20961
21096
  definitionMap.set('providers', meta.providers);
@@ -20992,7 +21127,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20992
21127
  function createNgModuleDefinitionMap(meta) {
20993
21128
  const definitionMap = new DefinitionMap();
20994
21129
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
20995
- definitionMap.set('version', literal('12.2.6'));
21130
+ definitionMap.set('version', literal('12.2.7'));
20996
21131
  definitionMap.set('ngImport', importExpr(Identifiers.core));
20997
21132
  definitionMap.set('type', meta.internalType);
20998
21133
  // We only generate the keys in the metadata if the arrays contain values.
@@ -21050,7 +21185,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21050
21185
  function createPipeDefinitionMap(meta) {
21051
21186
  const definitionMap = new DefinitionMap();
21052
21187
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
21053
- definitionMap.set('version', literal('12.2.6'));
21188
+ definitionMap.set('version', literal('12.2.7'));
21054
21189
  definitionMap.set('ngImport', importExpr(Identifiers.core));
21055
21190
  // e.g. `type: MyPipe`
21056
21191
  definitionMap.set('type', meta.internalType);
@@ -21082,7 +21217,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21082
21217
  * Use of this source code is governed by an MIT-style license that can be
21083
21218
  * found in the LICENSE file at https://angular.io/license
21084
21219
  */
21085
- const VERSION$2 = new Version('12.2.6');
21220
+ const VERSION$2 = new Version('12.2.7');
21086
21221
 
21087
21222
  /**
21088
21223
  * @license
@@ -23219,11 +23354,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
23219
23354
  getAdjacentNameOfClass(clazz) {
23220
23355
  return clazz.name;
23221
23356
  }
23222
- isStaticallyExported(clazz) {
23223
- // First check if there's an `export` modifier directly on the class declaration.
23224
- let topLevel = clazz;
23225
- if (ts$1.isVariableDeclaration(clazz) && ts$1.isVariableDeclarationList(clazz.parent)) {
23226
- topLevel = clazz.parent.parent;
23357
+ isStaticallyExported(decl) {
23358
+ // First check if there's an `export` modifier directly on the declaration.
23359
+ let topLevel = decl;
23360
+ if (ts$1.isVariableDeclaration(decl) && ts$1.isVariableDeclarationList(decl.parent)) {
23361
+ topLevel = decl.parent.parent;
23227
23362
  }
23228
23363
  if (topLevel.modifiers !== undefined &&
23229
23364
  topLevel.modifiers.some(modifier => modifier.kind === ts$1.SyntaxKind.ExportKeyword)) {
@@ -23242,8 +23377,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
23242
23377
  if (topLevel.parent === undefined || !ts$1.isSourceFile(topLevel.parent)) {
23243
23378
  return false;
23244
23379
  }
23245
- const localExports = this.getLocalExportedClassesOfSourceFile(clazz.getSourceFile());
23246
- return localExports.has(clazz);
23380
+ const localExports = this.getLocalExportedDeclarationsOfSourceFile(decl.getSourceFile());
23381
+ return localExports.has(decl);
23247
23382
  }
23248
23383
  getDirectImportOfIdentifier(id) {
23249
23384
  const symbol = this.checker.getSymbolAtLocation(id);
@@ -23446,16 +23581,16 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
23446
23581
  };
23447
23582
  }
23448
23583
  /**
23449
- * Get the set of classes declared in `file` which are exported.
23584
+ * Get the set of declarations declared in `file` which are exported.
23450
23585
  */
23451
- getLocalExportedClassesOfSourceFile(file) {
23586
+ getLocalExportedDeclarationsOfSourceFile(file) {
23452
23587
  const cacheSf = file;
23453
- if (cacheSf[LocalExportedClasses] !== undefined) {
23588
+ if (cacheSf[LocalExportedDeclarations] !== undefined) {
23454
23589
  // TS does not currently narrow symbol-keyed fields, hence the non-null assert is needed.
23455
- return cacheSf[LocalExportedClasses];
23590
+ return cacheSf[LocalExportedDeclarations];
23456
23591
  }
23457
23592
  const exportSet = new Set();
23458
- cacheSf[LocalExportedClasses] = exportSet;
23593
+ cacheSf[LocalExportedDeclarations] = exportSet;
23459
23594
  const sfSymbol = this.checker.getSymbolAtLocation(cacheSf);
23460
23595
  if (sfSymbol === undefined || sfSymbol.exports === undefined) {
23461
23596
  return exportSet;
@@ -23480,8 +23615,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
23480
23615
  exportedSymbol = this.checker.getAliasedSymbol(exportedSymbol);
23481
23616
  }
23482
23617
  if (exportedSymbol.valueDeclaration !== undefined &&
23483
- exportedSymbol.valueDeclaration.getSourceFile() === file &&
23484
- this.isClass(exportedSymbol.valueDeclaration)) {
23618
+ exportedSymbol.valueDeclaration.getSourceFile() === file) {
23485
23619
  exportSet.add(exportedSymbol.valueDeclaration);
23486
23620
  }
23487
23621
  item = iter.next();
@@ -23640,7 +23774,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
23640
23774
  (decl.propertyName !== undefined ? decl.propertyName : decl.name).text :
23641
23775
  originalId.text;
23642
23776
  }
23643
- const LocalExportedClasses = Symbol('LocalExportedClasses');
23777
+ const LocalExportedDeclarations = Symbol('LocalExportedDeclarations');
23644
23778
 
23645
23779
  /**
23646
23780
  * @license
@@ -35493,15 +35627,20 @@ Either add the @Injectable() decorator to '${provider.node.name
35493
35627
  resolutionContext: type.getSourceFile().fileName,
35494
35628
  };
35495
35629
  }
35496
- // If no owning module is known, the reference needs to be exported to be able to emit an import
35630
+ // The declaration needs to be exported as a top-level export to be able to emit an import
35497
35631
  // statement for it. If the declaration is not exported, null is returned to prevent emit.
35498
- if (owningModule === null && !this.isStaticallyExported(declaration.node)) {
35632
+ if (!this.isTopLevelExport(declaration.node)) {
35499
35633
  return null;
35500
35634
  }
35501
35635
  return new Reference$1(declaration.node, owningModule);
35502
35636
  }
35503
- isStaticallyExported(decl) {
35504
- return isNamedClassDeclaration(decl) && this.reflector.isStaticallyExported(decl);
35637
+ isTopLevelExport(decl) {
35638
+ if (decl.parent === undefined || !ts$1.isSourceFile(decl.parent)) {
35639
+ // The declaration has to exist at the top-level, as the reference emitters are not capable of
35640
+ // generating imports to classes declared in a namespace.
35641
+ return false;
35642
+ }
35643
+ return this.reflector.isStaticallyExported(decl);
35505
35644
  }
35506
35645
  isLocalTypeParameter(decl) {
35507
35646
  // Checking for local type parameters only occurs during resolution of type parameters, so it is
@@ -40295,7 +40434,7 @@ Either add the @Injectable() decorator to '${provider.node.name
40295
40434
  if (!(node instanceof Binary) || node.operation !== '??')
40296
40435
  return [];
40297
40436
  const symbolLeft = ctx.templateTypeChecker.getSymbolOfNode(node.left, component);
40298
- if (symbolLeft.kind !== SymbolKind.Expression) {
40437
+ if (symbolLeft === null || symbolLeft.kind !== SymbolKind.Expression) {
40299
40438
  return [];
40300
40439
  }
40301
40440
  const typeLeft = symbolLeft.tsType;