@angular/language-service 13.1.0-next.0 → 13.1.0-next.1

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v13.1.0-next.0
2
+ * @license Angular v13.1.0-next.1
3
3
  * Copyright Google LLC All Rights Reserved.
4
4
  * License: MIT
5
5
  */
@@ -3206,229 +3206,146 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
3206
3206
  * Use of this source code is governed by an MIT-style license that can be
3207
3207
  * found in the LICENSE file at https://angular.io/license
3208
3208
  */
3209
- /**
3210
- * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently
3211
- * require the implementation of a visitor for Comments as they are only collected at
3212
- * the top-level of the R3 AST, and only if `Render3ParseOptions['collectCommentNodes']`
3213
- * is true.
3214
- */
3215
- class Comment$1 {
3216
- constructor(value, sourceSpan) {
3217
- this.value = value;
3218
- this.sourceSpan = sourceSpan;
3219
- }
3220
- visit(_visitor) {
3221
- throw new Error('visit() not implemented for Comment');
3222
- }
3223
- }
3224
- class Text$2 {
3225
- constructor(value, sourceSpan) {
3226
- this.value = value;
3227
- this.sourceSpan = sourceSpan;
3228
- }
3229
- visit(visitor) {
3230
- return visitor.visitText(this);
3231
- }
3232
- }
3233
- class BoundText {
3234
- constructor(value, sourceSpan, i18n) {
3235
- this.value = value;
3236
- this.sourceSpan = sourceSpan;
3237
- this.i18n = i18n;
3238
- }
3239
- visit(visitor) {
3240
- return visitor.visitBoundText(this);
3241
- }
3242
- }
3243
- /**
3244
- * Represents a text attribute in the template.
3245
- *
3246
- * `valueSpan` may not be present in cases where there is no value `<div a></div>`.
3247
- * `keySpan` may also not be present for synthetic attributes from ICU expansions.
3248
- */
3249
- class TextAttribute {
3250
- constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
3251
- this.name = name;
3252
- this.value = value;
3253
- this.sourceSpan = sourceSpan;
3254
- this.keySpan = keySpan;
3255
- this.valueSpan = valueSpan;
3256
- this.i18n = i18n;
3257
- }
3258
- visit(visitor) {
3259
- return visitor.visitTextAttribute(this);
3260
- }
3261
- }
3262
- class BoundAttribute {
3263
- constructor(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan, i18n) {
3264
- this.name = name;
3265
- this.type = type;
3266
- this.securityContext = securityContext;
3267
- this.value = value;
3268
- this.unit = unit;
3269
- this.sourceSpan = sourceSpan;
3270
- this.keySpan = keySpan;
3271
- this.valueSpan = valueSpan;
3272
- this.i18n = i18n;
3209
+ // https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
3210
+ const VERSION = 3;
3211
+ const JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,';
3212
+ class SourceMapGenerator {
3213
+ constructor(file = null) {
3214
+ this.file = file;
3215
+ this.sourcesContent = new Map();
3216
+ this.lines = [];
3217
+ this.lastCol0 = 0;
3218
+ this.hasMappings = false;
3273
3219
  }
3274
- static fromBoundElementProperty(prop, i18n) {
3275
- if (prop.keySpan === undefined) {
3276
- throw new Error(`Unexpected state: keySpan must be defined for bound attributes but was not for ${prop.name}: ${prop.sourceSpan}`);
3220
+ // The content is `null` when the content is expected to be loaded using the URL
3221
+ addSource(url, content = null) {
3222
+ if (!this.sourcesContent.has(url)) {
3223
+ this.sourcesContent.set(url, content);
3277
3224
  }
3278
- return new BoundAttribute(prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n);
3279
- }
3280
- visit(visitor) {
3281
- return visitor.visitBoundAttribute(this);
3225
+ return this;
3282
3226
  }
3283
- }
3284
- class BoundEvent {
3285
- constructor(name, type, handler, target, phase, sourceSpan, handlerSpan, keySpan) {
3286
- this.name = name;
3287
- this.type = type;
3288
- this.handler = handler;
3289
- this.target = target;
3290
- this.phase = phase;
3291
- this.sourceSpan = sourceSpan;
3292
- this.handlerSpan = handlerSpan;
3293
- this.keySpan = keySpan;
3227
+ addLine() {
3228
+ this.lines.push([]);
3229
+ this.lastCol0 = 0;
3230
+ return this;
3294
3231
  }
3295
- static fromParsedEvent(event) {
3296
- const target = event.type === 0 /* Regular */ ? event.targetOrPhase : null;
3297
- const phase = event.type === 1 /* Animation */ ? event.targetOrPhase : null;
3298
- if (event.keySpan === undefined) {
3299
- throw new Error(`Unexpected state: keySpan must be defined for bound event but was not for ${event.name}: ${event.sourceSpan}`);
3232
+ addMapping(col0, sourceUrl, sourceLine0, sourceCol0) {
3233
+ if (!this.currentLine) {
3234
+ throw new Error(`A line must be added before mappings can be added`);
3300
3235
  }
3301
- return new BoundEvent(event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan, event.keySpan);
3302
- }
3303
- visit(visitor) {
3304
- return visitor.visitBoundEvent(this);
3305
- }
3306
- }
3307
- class Element$1 {
3308
- constructor(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3309
- this.name = name;
3310
- this.attributes = attributes;
3311
- this.inputs = inputs;
3312
- this.outputs = outputs;
3313
- this.children = children;
3314
- this.references = references;
3315
- this.sourceSpan = sourceSpan;
3316
- this.startSourceSpan = startSourceSpan;
3317
- this.endSourceSpan = endSourceSpan;
3318
- this.i18n = i18n;
3319
- }
3320
- visit(visitor) {
3321
- return visitor.visitElement(this);
3322
- }
3323
- }
3324
- class Template {
3325
- constructor(tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
3326
- this.tagName = tagName;
3327
- this.attributes = attributes;
3328
- this.inputs = inputs;
3329
- this.outputs = outputs;
3330
- this.templateAttrs = templateAttrs;
3331
- this.children = children;
3332
- this.references = references;
3333
- this.variables = variables;
3334
- this.sourceSpan = sourceSpan;
3335
- this.startSourceSpan = startSourceSpan;
3336
- this.endSourceSpan = endSourceSpan;
3337
- this.i18n = i18n;
3338
- }
3339
- visit(visitor) {
3340
- return visitor.visitTemplate(this);
3341
- }
3342
- }
3343
- class Content {
3344
- constructor(selector, attributes, sourceSpan, i18n) {
3345
- this.selector = selector;
3346
- this.attributes = attributes;
3347
- this.sourceSpan = sourceSpan;
3348
- this.i18n = i18n;
3349
- this.name = 'ng-content';
3350
- }
3351
- visit(visitor) {
3352
- return visitor.visitContent(this);
3353
- }
3354
- }
3355
- class Variable {
3356
- constructor(name, value, sourceSpan, keySpan, valueSpan) {
3357
- this.name = name;
3358
- this.value = value;
3359
- this.sourceSpan = sourceSpan;
3360
- this.keySpan = keySpan;
3361
- this.valueSpan = valueSpan;
3362
- }
3363
- visit(visitor) {
3364
- return visitor.visitVariable(this);
3365
- }
3366
- }
3367
- class Reference$1 {
3368
- constructor(name, value, sourceSpan, keySpan, valueSpan) {
3369
- this.name = name;
3370
- this.value = value;
3371
- this.sourceSpan = sourceSpan;
3372
- this.keySpan = keySpan;
3373
- this.valueSpan = valueSpan;
3236
+ if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) {
3237
+ throw new Error(`Unknown source file "${sourceUrl}"`);
3238
+ }
3239
+ if (col0 == null) {
3240
+ throw new Error(`The column in the generated code must be provided`);
3241
+ }
3242
+ if (col0 < this.lastCol0) {
3243
+ throw new Error(`Mapping should be added in output order`);
3244
+ }
3245
+ if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) {
3246
+ throw new Error(`The source location must be provided when a source url is provided`);
3247
+ }
3248
+ this.hasMappings = true;
3249
+ this.lastCol0 = col0;
3250
+ this.currentLine.push({ col0, sourceUrl, sourceLine0, sourceCol0 });
3251
+ return this;
3374
3252
  }
3375
- visit(visitor) {
3376
- return visitor.visitReference(this);
3253
+ /**
3254
+ * @internal strip this from published d.ts files due to
3255
+ * https://github.com/microsoft/TypeScript/issues/36216
3256
+ */
3257
+ get currentLine() {
3258
+ return this.lines.slice(-1)[0];
3377
3259
  }
3378
- }
3379
- class Icu$1 {
3380
- constructor(vars, placeholders, sourceSpan, i18n) {
3381
- this.vars = vars;
3382
- this.placeholders = placeholders;
3383
- this.sourceSpan = sourceSpan;
3384
- this.i18n = i18n;
3260
+ toJSON() {
3261
+ if (!this.hasMappings) {
3262
+ return null;
3263
+ }
3264
+ const sourcesIndex = new Map();
3265
+ const sources = [];
3266
+ const sourcesContent = [];
3267
+ Array.from(this.sourcesContent.keys()).forEach((url, i) => {
3268
+ sourcesIndex.set(url, i);
3269
+ sources.push(url);
3270
+ sourcesContent.push(this.sourcesContent.get(url) || null);
3271
+ });
3272
+ let mappings = '';
3273
+ let lastCol0 = 0;
3274
+ let lastSourceIndex = 0;
3275
+ let lastSourceLine0 = 0;
3276
+ let lastSourceCol0 = 0;
3277
+ this.lines.forEach(segments => {
3278
+ lastCol0 = 0;
3279
+ mappings += segments
3280
+ .map(segment => {
3281
+ // zero-based starting column of the line in the generated code
3282
+ let segAsStr = toBase64VLQ(segment.col0 - lastCol0);
3283
+ lastCol0 = segment.col0;
3284
+ if (segment.sourceUrl != null) {
3285
+ // zero-based index into the “sources” list
3286
+ segAsStr +=
3287
+ toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex);
3288
+ lastSourceIndex = sourcesIndex.get(segment.sourceUrl);
3289
+ // the zero-based starting line in the original source
3290
+ segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0);
3291
+ lastSourceLine0 = segment.sourceLine0;
3292
+ // the zero-based starting column in the original source
3293
+ segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0);
3294
+ lastSourceCol0 = segment.sourceCol0;
3295
+ }
3296
+ return segAsStr;
3297
+ })
3298
+ .join(',');
3299
+ mappings += ';';
3300
+ });
3301
+ mappings = mappings.slice(0, -1);
3302
+ return {
3303
+ 'file': this.file || '',
3304
+ 'version': VERSION,
3305
+ 'sourceRoot': '',
3306
+ 'sources': sources,
3307
+ 'sourcesContent': sourcesContent,
3308
+ 'mappings': mappings,
3309
+ };
3385
3310
  }
3386
- visit(visitor) {
3387
- return visitor.visitIcu(this);
3311
+ toJsComment() {
3312
+ return this.hasMappings ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0)) :
3313
+ '';
3388
3314
  }
3389
3315
  }
3390
- class RecursiveVisitor {
3391
- visitElement(element) {
3392
- visitAll$1(this, element.attributes);
3393
- visitAll$1(this, element.inputs);
3394
- visitAll$1(this, element.outputs);
3395
- visitAll$1(this, element.children);
3396
- visitAll$1(this, element.references);
3397
- }
3398
- visitTemplate(template) {
3399
- visitAll$1(this, template.attributes);
3400
- visitAll$1(this, template.inputs);
3401
- visitAll$1(this, template.outputs);
3402
- visitAll$1(this, template.children);
3403
- visitAll$1(this, template.references);
3404
- visitAll$1(this, template.variables);
3316
+ function toBase64String(value) {
3317
+ let b64 = '';
3318
+ const encoded = utf8Encode(value);
3319
+ for (let i = 0; i < encoded.length;) {
3320
+ const i1 = encoded[i++];
3321
+ const i2 = i < encoded.length ? encoded[i++] : null;
3322
+ const i3 = i < encoded.length ? encoded[i++] : null;
3323
+ b64 += toBase64Digit(i1 >> 2);
3324
+ b64 += toBase64Digit(((i1 & 3) << 4) | (i2 === null ? 0 : i2 >> 4));
3325
+ b64 += i2 === null ? '=' : toBase64Digit(((i2 & 15) << 2) | (i3 === null ? 0 : i3 >> 6));
3326
+ b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63);
3405
3327
  }
3406
- visitContent(content) { }
3407
- visitVariable(variable) { }
3408
- visitReference(reference) { }
3409
- visitTextAttribute(attribute) { }
3410
- visitBoundAttribute(attribute) { }
3411
- visitBoundEvent(attribute) { }
3412
- visitText(text) { }
3413
- visitBoundText(text) { }
3414
- visitIcu(icu) { }
3328
+ return b64;
3415
3329
  }
3416
- function visitAll$1(visitor, nodes) {
3417
- const result = [];
3418
- if (visitor.visit) {
3419
- for (const node of nodes) {
3420
- visitor.visit(node) || node.visit(visitor);
3421
- }
3422
- }
3423
- else {
3424
- for (const node of nodes) {
3425
- const newNode = node.visit(visitor);
3426
- if (newNode) {
3427
- result.push(newNode);
3428
- }
3330
+ function toBase64VLQ(value) {
3331
+ value = value < 0 ? ((-value) << 1) + 1 : value << 1;
3332
+ let out = '';
3333
+ do {
3334
+ let digit = value & 31;
3335
+ value = value >> 5;
3336
+ if (value > 0) {
3337
+ digit = digit | 32;
3429
3338
  }
3339
+ out += toBase64Digit(digit);
3340
+ } while (value > 0);
3341
+ return out;
3342
+ }
3343
+ const B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
3344
+ function toBase64Digit(value) {
3345
+ if (value < 0 || value >= 64) {
3346
+ throw new Error(`Can only encode value in the range [0, 63]`);
3430
3347
  }
3431
- return result;
3348
+ return B64_DIGITS[value];
3432
3349
  }
3433
3350
 
3434
3351
  /**
@@ -3438,502 +3355,551 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
3438
3355
  * Use of this source code is governed by an MIT-style license that can be
3439
3356
  * found in the LICENSE file at https://angular.io/license
3440
3357
  */
3441
- class Message {
3442
- /**
3443
- * @param nodes message AST
3444
- * @param placeholders maps placeholder names to static content and their source spans
3445
- * @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
3446
- * @param meaning
3447
- * @param description
3448
- * @param customId
3449
- */
3450
- constructor(nodes, placeholders, placeholderToMessage, meaning, description, customId) {
3451
- this.nodes = nodes;
3452
- this.placeholders = placeholders;
3453
- this.placeholderToMessage = placeholderToMessage;
3454
- this.meaning = meaning;
3455
- this.description = description;
3456
- this.customId = customId;
3457
- this.id = this.customId;
3458
- /** The ids to use if there are no custom id and if `i18nLegacyMessageIdFormat` is not empty */
3459
- this.legacyIds = [];
3460
- this.messageString = serializeMessage(this.nodes);
3461
- if (nodes.length) {
3462
- this.sources = [{
3463
- filePath: nodes[0].sourceSpan.start.file.url,
3464
- startLine: nodes[0].sourceSpan.start.line + 1,
3465
- startCol: nodes[0].sourceSpan.start.col + 1,
3466
- endLine: nodes[nodes.length - 1].sourceSpan.end.line + 1,
3467
- endCol: nodes[0].sourceSpan.start.col + 1
3468
- }];
3469
- }
3470
- else {
3471
- this.sources = [];
3472
- }
3473
- }
3474
- }
3475
- class Text$1 {
3476
- constructor(value, sourceSpan) {
3477
- this.value = value;
3478
- this.sourceSpan = sourceSpan;
3479
- }
3480
- visit(visitor, context) {
3481
- return visitor.visitText(this, context);
3358
+ const _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
3359
+ const _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
3360
+ const _INDENT_WITH = ' ';
3361
+ const CATCH_ERROR_VAR = variable('error', null, null);
3362
+ const CATCH_STACK_VAR = variable('stack', null, null);
3363
+ class _EmittedLine {
3364
+ constructor(indent) {
3365
+ this.indent = indent;
3366
+ this.partsLength = 0;
3367
+ this.parts = [];
3368
+ this.srcSpans = [];
3482
3369
  }
3483
3370
  }
3484
- // TODO(vicb): do we really need this node (vs an array) ?
3485
- class Container {
3486
- constructor(children, sourceSpan) {
3487
- this.children = children;
3488
- this.sourceSpan = sourceSpan;
3489
- }
3490
- visit(visitor, context) {
3491
- return visitor.visitContainer(this, context);
3371
+ class EmitterVisitorContext {
3372
+ constructor(_indent) {
3373
+ this._indent = _indent;
3374
+ this._classes = [];
3375
+ this._preambleLineCount = 0;
3376
+ this._lines = [new _EmittedLine(_indent)];
3492
3377
  }
3493
- }
3494
- class Icu {
3495
- constructor(expression, type, cases, sourceSpan) {
3496
- this.expression = expression;
3497
- this.type = type;
3498
- this.cases = cases;
3499
- this.sourceSpan = sourceSpan;
3378
+ static createRoot() {
3379
+ return new EmitterVisitorContext(0);
3500
3380
  }
3501
- visit(visitor, context) {
3502
- return visitor.visitIcu(this, context);
3381
+ /**
3382
+ * @internal strip this from published d.ts files due to
3383
+ * https://github.com/microsoft/TypeScript/issues/36216
3384
+ */
3385
+ get _currentLine() {
3386
+ return this._lines[this._lines.length - 1];
3503
3387
  }
3504
- }
3505
- class TagPlaceholder {
3506
- constructor(tag, attrs, startName, closeName, children, isVoid,
3507
- // TODO sourceSpan should cover all (we need a startSourceSpan and endSourceSpan)
3508
- sourceSpan, startSourceSpan, endSourceSpan) {
3509
- this.tag = tag;
3510
- this.attrs = attrs;
3511
- this.startName = startName;
3512
- this.closeName = closeName;
3513
- this.children = children;
3514
- this.isVoid = isVoid;
3515
- this.sourceSpan = sourceSpan;
3516
- this.startSourceSpan = startSourceSpan;
3517
- this.endSourceSpan = endSourceSpan;
3388
+ println(from, lastPart = '') {
3389
+ this.print(from || null, lastPart, true);
3518
3390
  }
3519
- visit(visitor, context) {
3520
- return visitor.visitTagPlaceholder(this, context);
3391
+ lineIsEmpty() {
3392
+ return this._currentLine.parts.length === 0;
3521
3393
  }
3522
- }
3523
- class Placeholder {
3524
- constructor(value, name, sourceSpan) {
3525
- this.value = value;
3526
- this.name = name;
3527
- this.sourceSpan = sourceSpan;
3394
+ lineLength() {
3395
+ return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;
3528
3396
  }
3529
- visit(visitor, context) {
3530
- return visitor.visitPlaceholder(this, context);
3397
+ print(from, part, newLine = false) {
3398
+ if (part.length > 0) {
3399
+ this._currentLine.parts.push(part);
3400
+ this._currentLine.partsLength += part.length;
3401
+ this._currentLine.srcSpans.push(from && from.sourceSpan || null);
3402
+ }
3403
+ if (newLine) {
3404
+ this._lines.push(new _EmittedLine(this._indent));
3405
+ }
3531
3406
  }
3532
- }
3533
- class IcuPlaceholder {
3534
- constructor(value, name, sourceSpan) {
3535
- this.value = value;
3536
- this.name = name;
3537
- this.sourceSpan = sourceSpan;
3407
+ removeEmptyLastLine() {
3408
+ if (this.lineIsEmpty()) {
3409
+ this._lines.pop();
3410
+ }
3538
3411
  }
3539
- visit(visitor, context) {
3540
- return visitor.visitIcuPlaceholder(this, context);
3412
+ incIndent() {
3413
+ this._indent++;
3414
+ if (this.lineIsEmpty()) {
3415
+ this._currentLine.indent = this._indent;
3416
+ }
3541
3417
  }
3542
- }
3543
- /**
3544
- * Serialize the message to the Localize backtick string format that would appear in compiled code.
3545
- */
3546
- function serializeMessage(messageNodes) {
3547
- const visitor = new LocalizeMessageStringVisitor();
3548
- const str = messageNodes.map(n => n.visit(visitor)).join('');
3549
- return str;
3550
- }
3551
- class LocalizeMessageStringVisitor {
3552
- visitText(text) {
3553
- return text.value;
3418
+ decIndent() {
3419
+ this._indent--;
3420
+ if (this.lineIsEmpty()) {
3421
+ this._currentLine.indent = this._indent;
3422
+ }
3554
3423
  }
3555
- visitContainer(container) {
3556
- return container.children.map(child => child.visit(this)).join('');
3424
+ pushClass(clazz) {
3425
+ this._classes.push(clazz);
3557
3426
  }
3558
- visitIcu(icu) {
3559
- const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
3560
- return `{${icu.expressionPlaceholder}, ${icu.type}, ${strCases.join(' ')}}`;
3427
+ popClass() {
3428
+ return this._classes.pop();
3561
3429
  }
3562
- visitTagPlaceholder(ph) {
3563
- const children = ph.children.map(child => child.visit(this)).join('');
3564
- return `{$${ph.startName}}${children}{$${ph.closeName}}`;
3430
+ get currentClass() {
3431
+ return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null;
3565
3432
  }
3566
- visitPlaceholder(ph) {
3567
- return `{$${ph.name}}`;
3433
+ toSource() {
3434
+ return this.sourceLines
3435
+ .map(l => l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : '')
3436
+ .join('\n');
3568
3437
  }
3569
- visitIcuPlaceholder(ph) {
3570
- return `{$${ph.name}}`;
3438
+ toSourceMapGenerator(genFilePath, startsAtLine = 0) {
3439
+ const map = new SourceMapGenerator(genFilePath);
3440
+ let firstOffsetMapped = false;
3441
+ const mapFirstOffsetIfNeeded = () => {
3442
+ if (!firstOffsetMapped) {
3443
+ // Add a single space so that tools won't try to load the file from disk.
3444
+ // Note: We are using virtual urls like `ng:///`, so we have to
3445
+ // provide a content here.
3446
+ map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);
3447
+ firstOffsetMapped = true;
3448
+ }
3449
+ };
3450
+ for (let i = 0; i < startsAtLine; i++) {
3451
+ map.addLine();
3452
+ mapFirstOffsetIfNeeded();
3453
+ }
3454
+ this.sourceLines.forEach((line, lineIdx) => {
3455
+ map.addLine();
3456
+ const spans = line.srcSpans;
3457
+ const parts = line.parts;
3458
+ let col0 = line.indent * _INDENT_WITH.length;
3459
+ let spanIdx = 0;
3460
+ // skip leading parts without source spans
3461
+ while (spanIdx < spans.length && !spans[spanIdx]) {
3462
+ col0 += parts[spanIdx].length;
3463
+ spanIdx++;
3464
+ }
3465
+ if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {
3466
+ firstOffsetMapped = true;
3467
+ }
3468
+ else {
3469
+ mapFirstOffsetIfNeeded();
3470
+ }
3471
+ while (spanIdx < spans.length) {
3472
+ const span = spans[spanIdx];
3473
+ const source = span.start.file;
3474
+ const sourceLine = span.start.line;
3475
+ const sourceCol = span.start.col;
3476
+ map.addSource(source.url, source.content)
3477
+ .addMapping(col0, source.url, sourceLine, sourceCol);
3478
+ col0 += parts[spanIdx].length;
3479
+ spanIdx++;
3480
+ // assign parts without span or the same span to the previous segment
3481
+ while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) {
3482
+ col0 += parts[spanIdx].length;
3483
+ spanIdx++;
3484
+ }
3485
+ }
3486
+ });
3487
+ return map;
3571
3488
  }
3572
- }
3573
-
3574
- /**
3575
- * @license
3576
- * Copyright Google LLC All Rights Reserved.
3577
- *
3578
- * Use of this source code is governed by an MIT-style license that can be
3579
- * found in the LICENSE file at https://angular.io/license
3580
- */
3581
- // XMB/XTB placeholders can only contain A-Z, 0-9 and _
3582
- function toPublicName(internalName) {
3583
- return internalName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
3584
- }
3585
-
3586
- /**
3587
- * @license
3588
- * Copyright Google LLC All Rights Reserved.
3589
- *
3590
- * Use of this source code is governed by an MIT-style license that can be
3591
- * found in the LICENSE file at https://angular.io/license
3592
- */
3593
- /* Closure variables holding messages must be named `MSG_[A-Z0-9]+` */
3594
- const CLOSURE_TRANSLATION_VAR_PREFIX = 'MSG_';
3595
- /**
3596
- * Prefix for non-`goog.getMsg` i18n-related vars.
3597
- * Note: the prefix uses lowercase characters intentionally due to a Closure behavior that
3598
- * considers variables like `I18N_0` as constants and throws an error when their value changes.
3599
- */
3600
- const TRANSLATION_VAR_PREFIX = 'i18n_';
3601
- /** Name of the i18n attributes **/
3602
- const I18N_ATTR = 'i18n';
3603
- const I18N_ATTR_PREFIX = 'i18n-';
3604
- /** Prefix of var expressions used in ICUs */
3605
- const I18N_ICU_VAR_PREFIX = 'VAR_';
3606
- /** Prefix of ICU expressions for post processing */
3607
- const I18N_ICU_MAPPING_PREFIX = 'I18N_EXP_';
3608
- /** Placeholder wrapper for i18n expressions **/
3609
- const I18N_PLACEHOLDER_SYMBOL = '�';
3610
- function isI18nAttribute(name) {
3611
- return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
3612
- }
3613
- function isI18nRootNode(meta) {
3614
- return meta instanceof Message;
3615
- }
3616
- function isSingleI18nIcu(meta) {
3617
- return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu;
3618
- }
3619
- function hasI18nMeta(node) {
3620
- return !!node.i18n;
3621
- }
3622
- function hasI18nAttrs(element) {
3623
- return element.attrs.some((attr) => isI18nAttribute(attr.name));
3624
- }
3625
- function icuFromI18nMessage(message) {
3626
- return message.nodes[0];
3627
- }
3628
- function wrapI18nPlaceholder(content, contextId = 0) {
3629
- const blockId = contextId > 0 ? `:${contextId}` : '';
3630
- return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`;
3631
- }
3632
- function assembleI18nBoundString(strings, bindingStartIndex = 0, contextId = 0) {
3633
- if (!strings.length)
3634
- return '';
3635
- let acc = '';
3636
- const lastIdx = strings.length - 1;
3637
- for (let i = 0; i < lastIdx; i++) {
3638
- acc += `${strings[i]}${wrapI18nPlaceholder(bindingStartIndex + i, contextId)}`;
3489
+ setPreambleLineCount(count) {
3490
+ return this._preambleLineCount = count;
3639
3491
  }
3640
- acc += strings[lastIdx];
3641
- return acc;
3642
- }
3643
- function getSeqNumberGenerator(startsAt = 0) {
3644
- let current = startsAt;
3645
- return () => current++;
3646
- }
3647
- function placeholdersToParams(placeholders) {
3648
- const params = {};
3649
- placeholders.forEach((values, key) => {
3650
- params[key] = literal$1(values.length > 1 ? `[${values.join('|')}]` : values[0]);
3651
- });
3652
- return params;
3653
- }
3654
- function updatePlaceholderMap(map, name, ...values) {
3655
- const current = map.get(name) || [];
3656
- current.push(...values);
3657
- map.set(name, current);
3658
- }
3659
- function assembleBoundTextPlaceholders(meta, bindingStartIndex = 0, contextId = 0) {
3660
- const startIdx = bindingStartIndex;
3661
- const placeholders = new Map();
3662
- const node = meta instanceof Message ? meta.nodes.find(node => node instanceof Container) : meta;
3663
- if (node) {
3664
- node
3665
- .children
3666
- .filter((child) => child instanceof Placeholder)
3667
- .forEach((child, idx) => {
3668
- const content = wrapI18nPlaceholder(startIdx + idx, contextId);
3669
- updatePlaceholderMap(placeholders, child.name, content);
3670
- });
3492
+ spanOf(line, column) {
3493
+ const emittedLine = this._lines[line - this._preambleLineCount];
3494
+ if (emittedLine) {
3495
+ let columnsLeft = column - _createIndent(emittedLine.indent).length;
3496
+ for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {
3497
+ const part = emittedLine.parts[partIndex];
3498
+ if (part.length > columnsLeft) {
3499
+ return emittedLine.srcSpans[partIndex];
3500
+ }
3501
+ columnsLeft -= part.length;
3502
+ }
3503
+ }
3504
+ return null;
3671
3505
  }
3672
- return placeholders;
3673
- }
3674
- /**
3675
- * Format the placeholder names in a map of placeholders to expressions.
3676
- *
3677
- * The placeholder names are converted from "internal" format (e.g. `START_TAG_DIV_1`) to "external"
3678
- * format (e.g. `startTagDiv_1`).
3679
- *
3680
- * @param params A map of placeholder names to expressions.
3681
- * @param useCamelCase whether to camelCase the placeholder name when formatting.
3682
- * @returns A new map of formatted placeholder names to expressions.
3683
- */
3684
- function i18nFormatPlaceholderNames(params = {}, useCamelCase) {
3685
- const _params = {};
3686
- if (params && Object.keys(params).length) {
3687
- Object.keys(params).forEach(key => _params[formatI18nPlaceholderName(key, useCamelCase)] = params[key]);
3506
+ /**
3507
+ * @internal strip this from published d.ts files due to
3508
+ * https://github.com/microsoft/TypeScript/issues/36216
3509
+ */
3510
+ get sourceLines() {
3511
+ if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {
3512
+ return this._lines.slice(0, -1);
3513
+ }
3514
+ return this._lines;
3688
3515
  }
3689
- return _params;
3690
3516
  }
3691
- /**
3692
- * Converts internal placeholder names to public-facing format
3693
- * (for example to use in goog.getMsg call).
3694
- * Example: `START_TAG_DIV_1` is converted to `startTagDiv_1`.
3695
- *
3696
- * @param name The placeholder name that should be formatted
3697
- * @returns Formatted placeholder name
3698
- */
3699
- function formatI18nPlaceholderName(name, useCamelCase = true) {
3700
- const publicName = toPublicName(name);
3701
- if (!useCamelCase) {
3702
- return publicName;
3517
+ class AbstractEmitterVisitor {
3518
+ constructor(_escapeDollarInStrings) {
3519
+ this._escapeDollarInStrings = _escapeDollarInStrings;
3703
3520
  }
3704
- const chunks = publicName.split('_');
3705
- if (chunks.length === 1) {
3706
- // if no "_" found - just lowercase the value
3707
- return name.toLowerCase();
3521
+ printLeadingComments(stmt, ctx) {
3522
+ if (stmt.leadingComments === undefined) {
3523
+ return;
3524
+ }
3525
+ for (const comment of stmt.leadingComments) {
3526
+ if (comment instanceof JSDocComment) {
3527
+ ctx.print(stmt, `/*${comment.toString()}*/`, comment.trailingNewline);
3528
+ }
3529
+ else {
3530
+ if (comment.multiline) {
3531
+ ctx.print(stmt, `/* ${comment.text} */`, comment.trailingNewline);
3532
+ }
3533
+ else {
3534
+ comment.text.split('\n').forEach((line) => {
3535
+ ctx.println(stmt, `// ${line}`);
3536
+ });
3537
+ }
3538
+ }
3539
+ }
3708
3540
  }
3709
- let postfix;
3710
- // eject last element if it's a number
3711
- if (/^\d+$/.test(chunks[chunks.length - 1])) {
3712
- postfix = chunks.pop();
3541
+ visitExpressionStmt(stmt, ctx) {
3542
+ this.printLeadingComments(stmt, ctx);
3543
+ stmt.expr.visitExpression(this, ctx);
3544
+ ctx.println(stmt, ';');
3545
+ return null;
3713
3546
  }
3714
- let raw = chunks.shift().toLowerCase();
3715
- if (chunks.length) {
3716
- raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join('');
3547
+ visitReturnStmt(stmt, ctx) {
3548
+ this.printLeadingComments(stmt, ctx);
3549
+ ctx.print(stmt, `return `);
3550
+ stmt.value.visitExpression(this, ctx);
3551
+ ctx.println(stmt, ';');
3552
+ return null;
3717
3553
  }
3718
- return postfix ? `${raw}_${postfix}` : raw;
3719
- }
3720
- /**
3721
- * Generates a prefix for translation const name.
3722
- *
3723
- * @param extra Additional local prefix that should be injected into translation var name
3724
- * @returns Complete translation const prefix
3725
- */
3726
- function getTranslationConstPrefix(extra) {
3727
- return `${CLOSURE_TRANSLATION_VAR_PREFIX}${extra}`.toUpperCase();
3728
- }
3729
- /**
3730
- * Generate AST to declare a variable. E.g. `var I18N_1;`.
3731
- * @param variable the name of the variable to declare.
3732
- */
3733
- function declareI18nVariable(variable) {
3734
- return new DeclareVarStmt(variable.name, undefined, INFERRED_TYPE, undefined, variable.sourceSpan);
3735
- }
3736
-
3737
- /**
3738
- * @license
3739
- * Copyright Google LLC All Rights Reserved.
3740
- *
3741
- * Use of this source code is governed by an MIT-style license that can be
3742
- * found in the LICENSE file at https://angular.io/license
3743
- */
3744
- /**
3745
- * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in
3746
- * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may
3747
- * bot work in some cases when object keys are mangled by minifier.
3748
- *
3749
- * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with
3750
- * inputs that contain potentially unsafe chars.
3751
- */
3752
- const UNSAFE_OBJECT_KEY_NAME_REGEXP = /[-.]/;
3753
- /** Name of the temporary to use during data binding */
3754
- const TEMPORARY_NAME = '_t';
3755
- /** Name of the context parameter passed into a template function */
3756
- const CONTEXT_NAME = 'ctx';
3757
- /** Name of the RenderFlag passed into a template function */
3758
- const RENDER_FLAGS = 'rf';
3759
- /** The prefix reference variables */
3760
- const REFERENCE_PREFIX = '_r';
3761
- /** The name of the implicit context reference */
3762
- const IMPLICIT_REFERENCE = '$implicit';
3763
- /** Non bindable attribute name **/
3764
- const NON_BINDABLE_ATTR = 'ngNonBindable';
3765
- /** Name for the variable keeping track of the context returned by `ɵɵrestoreView`. */
3766
- const RESTORED_VIEW_CONTEXT_NAME = 'restoredCtx';
3767
- /**
3768
- * Creates an allocator for a temporary variable.
3769
- *
3770
- * A variable declaration is added to the statements the first time the allocator is invoked.
3771
- */
3772
- function temporaryAllocator(statements, name) {
3773
- let temp = null;
3774
- return () => {
3775
- if (!temp) {
3776
- statements.push(new DeclareVarStmt(TEMPORARY_NAME, undefined, DYNAMIC_TYPE));
3777
- temp = variable(name);
3554
+ visitIfStmt(stmt, ctx) {
3555
+ this.printLeadingComments(stmt, ctx);
3556
+ ctx.print(stmt, `if (`);
3557
+ stmt.condition.visitExpression(this, ctx);
3558
+ ctx.print(stmt, `) {`);
3559
+ const hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0;
3560
+ if (stmt.trueCase.length <= 1 && !hasElseCase) {
3561
+ ctx.print(stmt, ` `);
3562
+ this.visitAllStatements(stmt.trueCase, ctx);
3563
+ ctx.removeEmptyLastLine();
3564
+ ctx.print(stmt, ` `);
3778
3565
  }
3779
- return temp;
3780
- };
3781
- }
3782
- function unsupported(feature) {
3783
- if (this) {
3784
- throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
3566
+ else {
3567
+ ctx.println();
3568
+ ctx.incIndent();
3569
+ this.visitAllStatements(stmt.trueCase, ctx);
3570
+ ctx.decIndent();
3571
+ if (hasElseCase) {
3572
+ ctx.println(stmt, `} else {`);
3573
+ ctx.incIndent();
3574
+ this.visitAllStatements(stmt.falseCase, ctx);
3575
+ ctx.decIndent();
3576
+ }
3577
+ }
3578
+ ctx.println(stmt, `}`);
3579
+ return null;
3785
3580
  }
3786
- throw new Error(`Feature ${feature} is not supported yet`);
3787
- }
3788
- function invalid(arg) {
3789
- throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
3790
- }
3791
- function asLiteral(value) {
3792
- if (Array.isArray(value)) {
3793
- return literalArr(value.map(asLiteral));
3581
+ visitThrowStmt(stmt, ctx) {
3582
+ this.printLeadingComments(stmt, ctx);
3583
+ ctx.print(stmt, `throw `);
3584
+ stmt.error.visitExpression(this, ctx);
3585
+ ctx.println(stmt, `;`);
3586
+ return null;
3794
3587
  }
3795
- return literal$1(value, INFERRED_TYPE);
3796
- }
3797
- function conditionallyCreateMapObjectLiteral(keys, keepDeclared) {
3798
- if (Object.getOwnPropertyNames(keys).length > 0) {
3799
- return mapToExpression(keys, keepDeclared);
3588
+ visitWriteVarExpr(expr, ctx) {
3589
+ const lineWasEmpty = ctx.lineIsEmpty();
3590
+ if (!lineWasEmpty) {
3591
+ ctx.print(expr, '(');
3592
+ }
3593
+ ctx.print(expr, `${expr.name} = `);
3594
+ expr.value.visitExpression(this, ctx);
3595
+ if (!lineWasEmpty) {
3596
+ ctx.print(expr, ')');
3597
+ }
3598
+ return null;
3800
3599
  }
3801
- return null;
3802
- }
3803
- function mapToExpression(map, keepDeclared) {
3804
- return literalMap(Object.getOwnPropertyNames(map).map(key => {
3805
- // canonical syntax: `dirProp: publicProp`
3806
- // if there is no `:`, use dirProp = elProp
3807
- const value = map[key];
3808
- let declaredName;
3809
- let publicName;
3810
- let minifiedName;
3811
- let needsDeclaredName;
3812
- if (Array.isArray(value)) {
3813
- [publicName, declaredName] = value;
3814
- minifiedName = key;
3815
- needsDeclaredName = publicName !== declaredName;
3600
+ visitWriteKeyExpr(expr, ctx) {
3601
+ const lineWasEmpty = ctx.lineIsEmpty();
3602
+ if (!lineWasEmpty) {
3603
+ ctx.print(expr, '(');
3604
+ }
3605
+ expr.receiver.visitExpression(this, ctx);
3606
+ ctx.print(expr, `[`);
3607
+ expr.index.visitExpression(this, ctx);
3608
+ ctx.print(expr, `] = `);
3609
+ expr.value.visitExpression(this, ctx);
3610
+ if (!lineWasEmpty) {
3611
+ ctx.print(expr, ')');
3612
+ }
3613
+ return null;
3614
+ }
3615
+ visitWritePropExpr(expr, ctx) {
3616
+ const lineWasEmpty = ctx.lineIsEmpty();
3617
+ if (!lineWasEmpty) {
3618
+ ctx.print(expr, '(');
3619
+ }
3620
+ expr.receiver.visitExpression(this, ctx);
3621
+ ctx.print(expr, `.${expr.name} = `);
3622
+ expr.value.visitExpression(this, ctx);
3623
+ if (!lineWasEmpty) {
3624
+ ctx.print(expr, ')');
3625
+ }
3626
+ return null;
3627
+ }
3628
+ visitInvokeFunctionExpr(expr, ctx) {
3629
+ expr.fn.visitExpression(this, ctx);
3630
+ ctx.print(expr, `(`);
3631
+ this.visitAllExpressions(expr.args, ctx, ',');
3632
+ ctx.print(expr, `)`);
3633
+ return null;
3634
+ }
3635
+ visitTaggedTemplateExpr(expr, ctx) {
3636
+ expr.tag.visitExpression(this, ctx);
3637
+ ctx.print(expr, '`' + expr.template.elements[0].rawText);
3638
+ for (let i = 1; i < expr.template.elements.length; i++) {
3639
+ ctx.print(expr, '${');
3640
+ expr.template.expressions[i - 1].visitExpression(this, ctx);
3641
+ ctx.print(expr, `}${expr.template.elements[i].rawText}`);
3642
+ }
3643
+ ctx.print(expr, '`');
3644
+ return null;
3645
+ }
3646
+ visitWrappedNodeExpr(ast, ctx) {
3647
+ throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');
3648
+ }
3649
+ visitTypeofExpr(expr, ctx) {
3650
+ ctx.print(expr, 'typeof ');
3651
+ expr.expr.visitExpression(this, ctx);
3652
+ }
3653
+ visitReadVarExpr(ast, ctx) {
3654
+ let varName = ast.name;
3655
+ if (ast.builtin != null) {
3656
+ switch (ast.builtin) {
3657
+ case BuiltinVar.Super:
3658
+ varName = 'super';
3659
+ break;
3660
+ case BuiltinVar.This:
3661
+ varName = 'this';
3662
+ break;
3663
+ case BuiltinVar.CatchError:
3664
+ varName = CATCH_ERROR_VAR.name;
3665
+ break;
3666
+ case BuiltinVar.CatchStack:
3667
+ varName = CATCH_STACK_VAR.name;
3668
+ break;
3669
+ default:
3670
+ throw new Error(`Unknown builtin variable ${ast.builtin}`);
3671
+ }
3672
+ }
3673
+ ctx.print(ast, varName);
3674
+ return null;
3675
+ }
3676
+ visitInstantiateExpr(ast, ctx) {
3677
+ ctx.print(ast, `new `);
3678
+ ast.classExpr.visitExpression(this, ctx);
3679
+ ctx.print(ast, `(`);
3680
+ this.visitAllExpressions(ast.args, ctx, ',');
3681
+ ctx.print(ast, `)`);
3682
+ return null;
3683
+ }
3684
+ visitLiteralExpr(ast, ctx) {
3685
+ const value = ast.value;
3686
+ if (typeof value === 'string') {
3687
+ ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings));
3816
3688
  }
3817
3689
  else {
3818
- [declaredName, publicName] = splitAtColon(key, [key, value]);
3819
- minifiedName = declaredName;
3820
- // Only include the declared name if extracted from the key, i.e. the key contains a colon.
3821
- // Otherwise the declared name should be omitted even if it is different from the public name,
3822
- // as it may have already been minified.
3823
- needsDeclaredName = publicName !== declaredName && key.includes(':');
3690
+ ctx.print(ast, `${value}`);
3691
+ }
3692
+ return null;
3693
+ }
3694
+ visitLocalizedString(ast, ctx) {
3695
+ const head = ast.serializeI18nHead();
3696
+ ctx.print(ast, '$localize `' + head.raw);
3697
+ for (let i = 1; i < ast.messageParts.length; i++) {
3698
+ ctx.print(ast, '${');
3699
+ ast.expressions[i - 1].visitExpression(this, ctx);
3700
+ ctx.print(ast, `}${ast.serializeI18nTemplatePart(i).raw}`);
3701
+ }
3702
+ ctx.print(ast, '`');
3703
+ return null;
3704
+ }
3705
+ visitConditionalExpr(ast, ctx) {
3706
+ ctx.print(ast, `(`);
3707
+ ast.condition.visitExpression(this, ctx);
3708
+ ctx.print(ast, '? ');
3709
+ ast.trueCase.visitExpression(this, ctx);
3710
+ ctx.print(ast, ': ');
3711
+ ast.falseCase.visitExpression(this, ctx);
3712
+ ctx.print(ast, `)`);
3713
+ return null;
3714
+ }
3715
+ visitNotExpr(ast, ctx) {
3716
+ ctx.print(ast, '!');
3717
+ ast.condition.visitExpression(this, ctx);
3718
+ return null;
3719
+ }
3720
+ visitAssertNotNullExpr(ast, ctx) {
3721
+ ast.condition.visitExpression(this, ctx);
3722
+ return null;
3723
+ }
3724
+ visitUnaryOperatorExpr(ast, ctx) {
3725
+ let opStr;
3726
+ switch (ast.operator) {
3727
+ case UnaryOperator.Plus:
3728
+ opStr = '+';
3729
+ break;
3730
+ case UnaryOperator.Minus:
3731
+ opStr = '-';
3732
+ break;
3733
+ default:
3734
+ throw new Error(`Unknown operator ${ast.operator}`);
3735
+ }
3736
+ if (ast.parens)
3737
+ ctx.print(ast, `(`);
3738
+ ctx.print(ast, opStr);
3739
+ ast.expr.visitExpression(this, ctx);
3740
+ if (ast.parens)
3741
+ ctx.print(ast, `)`);
3742
+ return null;
3743
+ }
3744
+ visitBinaryOperatorExpr(ast, ctx) {
3745
+ let opStr;
3746
+ switch (ast.operator) {
3747
+ case BinaryOperator.Equals:
3748
+ opStr = '==';
3749
+ break;
3750
+ case BinaryOperator.Identical:
3751
+ opStr = '===';
3752
+ break;
3753
+ case BinaryOperator.NotEquals:
3754
+ opStr = '!=';
3755
+ break;
3756
+ case BinaryOperator.NotIdentical:
3757
+ opStr = '!==';
3758
+ break;
3759
+ case BinaryOperator.And:
3760
+ opStr = '&&';
3761
+ break;
3762
+ case BinaryOperator.BitwiseAnd:
3763
+ opStr = '&';
3764
+ break;
3765
+ case BinaryOperator.Or:
3766
+ opStr = '||';
3767
+ break;
3768
+ case BinaryOperator.Plus:
3769
+ opStr = '+';
3770
+ break;
3771
+ case BinaryOperator.Minus:
3772
+ opStr = '-';
3773
+ break;
3774
+ case BinaryOperator.Divide:
3775
+ opStr = '/';
3776
+ break;
3777
+ case BinaryOperator.Multiply:
3778
+ opStr = '*';
3779
+ break;
3780
+ case BinaryOperator.Modulo:
3781
+ opStr = '%';
3782
+ break;
3783
+ case BinaryOperator.Lower:
3784
+ opStr = '<';
3785
+ break;
3786
+ case BinaryOperator.LowerEquals:
3787
+ opStr = '<=';
3788
+ break;
3789
+ case BinaryOperator.Bigger:
3790
+ opStr = '>';
3791
+ break;
3792
+ case BinaryOperator.BiggerEquals:
3793
+ opStr = '>=';
3794
+ break;
3795
+ case BinaryOperator.NullishCoalesce:
3796
+ opStr = '??';
3797
+ break;
3798
+ default:
3799
+ throw new Error(`Unknown operator ${ast.operator}`);
3824
3800
  }
3825
- return {
3826
- key: minifiedName,
3827
- // put quotes around keys that contain potentially unsafe characters
3828
- quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName),
3829
- value: (keepDeclared && needsDeclaredName) ?
3830
- literalArr([asLiteral(publicName), asLiteral(declaredName)]) :
3831
- asLiteral(publicName)
3832
- };
3833
- }));
3834
- }
3835
- /**
3836
- * Remove trailing null nodes as they are implied.
3837
- */
3838
- function trimTrailingNulls(parameters) {
3839
- while (isNull(parameters[parameters.length - 1])) {
3840
- parameters.pop();
3801
+ if (ast.parens)
3802
+ ctx.print(ast, `(`);
3803
+ ast.lhs.visitExpression(this, ctx);
3804
+ ctx.print(ast, ` ${opStr} `);
3805
+ ast.rhs.visitExpression(this, ctx);
3806
+ if (ast.parens)
3807
+ ctx.print(ast, `)`);
3808
+ return null;
3841
3809
  }
3842
- return parameters;
3843
- }
3844
- function getQueryPredicate(query, constantPool) {
3845
- if (Array.isArray(query.predicate)) {
3846
- let predicate = [];
3847
- query.predicate.forEach((selector) => {
3848
- // Each item in predicates array may contain strings with comma-separated refs
3849
- // (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
3850
- // as separate array entities
3851
- const selectors = selector.split(',').map(token => literal$1(token.trim()));
3852
- predicate.push(...selectors);
3853
- });
3854
- return constantPool.getConstLiteral(literalArr(predicate), true);
3810
+ visitReadPropExpr(ast, ctx) {
3811
+ ast.receiver.visitExpression(this, ctx);
3812
+ ctx.print(ast, `.`);
3813
+ ctx.print(ast, ast.name);
3814
+ return null;
3855
3815
  }
3856
- else {
3857
- return query.predicate;
3816
+ visitReadKeyExpr(ast, ctx) {
3817
+ ast.receiver.visitExpression(this, ctx);
3818
+ ctx.print(ast, `[`);
3819
+ ast.index.visitExpression(this, ctx);
3820
+ ctx.print(ast, `]`);
3821
+ return null;
3858
3822
  }
3859
- }
3860
- /**
3861
- * A representation for an object literal used during codegen of definition objects. The generic
3862
- * type `T` allows to reference a documented type of the generated structure, such that the
3863
- * property names that are set can be resolved to their documented declaration.
3864
- */
3865
- class DefinitionMap {
3866
- constructor() {
3867
- this.values = [];
3823
+ visitLiteralArrayExpr(ast, ctx) {
3824
+ ctx.print(ast, `[`);
3825
+ this.visitAllExpressions(ast.entries, ctx, ',');
3826
+ ctx.print(ast, `]`);
3827
+ return null;
3868
3828
  }
3869
- set(key, value) {
3870
- if (value) {
3871
- this.values.push({ key: key, value, quoted: false });
3872
- }
3829
+ visitLiteralMapExpr(ast, ctx) {
3830
+ ctx.print(ast, `{`);
3831
+ this.visitAllObjects(entry => {
3832
+ ctx.print(ast, `${escapeIdentifier(entry.key, this._escapeDollarInStrings, entry.quoted)}:`);
3833
+ entry.value.visitExpression(this, ctx);
3834
+ }, ast.entries, ctx, ',');
3835
+ ctx.print(ast, `}`);
3836
+ return null;
3873
3837
  }
3874
- toLiteralMap() {
3875
- return literalMap(this.values);
3838
+ visitCommaExpr(ast, ctx) {
3839
+ ctx.print(ast, '(');
3840
+ this.visitAllExpressions(ast.parts, ctx, ',');
3841
+ ctx.print(ast, ')');
3842
+ return null;
3876
3843
  }
3877
- }
3878
- /**
3879
- * Extract a map of properties to values for a given element or template node, which can be used
3880
- * by the directive matching machinery.
3881
- *
3882
- * @param elOrTpl the element or template in question
3883
- * @return an object set up for directive matching. For attributes on the element/template, this
3884
- * object maps a property name to its (static) value. For any bindings, this map simply maps the
3885
- * property name to an empty string.
3886
- */
3887
- function getAttrsForDirectiveMatching(elOrTpl) {
3888
- const attributesMap = {};
3889
- if (elOrTpl instanceof Template && elOrTpl.tagName !== 'ng-template') {
3890
- elOrTpl.templateAttrs.forEach(a => attributesMap[a.name] = '');
3844
+ visitAllExpressions(expressions, ctx, separator) {
3845
+ this.visitAllObjects(expr => expr.visitExpression(this, ctx), expressions, ctx, separator);
3891
3846
  }
3892
- else {
3893
- elOrTpl.attributes.forEach(a => {
3894
- if (!isI18nAttribute(a.name)) {
3895
- attributesMap[a.name] = a.value;
3847
+ visitAllObjects(handler, expressions, ctx, separator) {
3848
+ let incrementedIndent = false;
3849
+ for (let i = 0; i < expressions.length; i++) {
3850
+ if (i > 0) {
3851
+ if (ctx.lineLength() > 80) {
3852
+ ctx.print(null, separator, true);
3853
+ if (!incrementedIndent) {
3854
+ // continuation are marked with double indent.
3855
+ ctx.incIndent();
3856
+ ctx.incIndent();
3857
+ incrementedIndent = true;
3858
+ }
3859
+ }
3860
+ else {
3861
+ ctx.print(null, separator, false);
3862
+ }
3896
3863
  }
3897
- });
3898
- elOrTpl.inputs.forEach(i => {
3899
- attributesMap[i.name] = '';
3900
- });
3901
- elOrTpl.outputs.forEach(o => {
3902
- attributesMap[o.name] = '';
3903
- });
3904
- }
3905
- return attributesMap;
3906
- }
3907
- /** Returns a call expression to a chained instruction, e.g. `property(params[0])(params[1])`. */
3908
- function chainedInstruction(reference, calls, span) {
3909
- let expression = importExpr(reference, null, span);
3910
- if (calls.length > 0) {
3911
- for (let i = 0; i < calls.length; i++) {
3912
- expression = expression.callFn(calls[i], span);
3864
+ handler(expressions[i]);
3865
+ }
3866
+ if (incrementedIndent) {
3867
+ // continuation are marked with double indent.
3868
+ ctx.decIndent();
3869
+ ctx.decIndent();
3913
3870
  }
3914
3871
  }
3915
- else {
3916
- // Add a blank invocation, in case the `calls` array is empty.
3917
- expression = expression.callFn([], span);
3872
+ visitAllStatements(statements, ctx) {
3873
+ statements.forEach((stmt) => stmt.visitStatement(this, ctx));
3918
3874
  }
3919
- return expression;
3920
3875
  }
3921
- /**
3922
- * Gets the number of arguments expected to be passed to a generated instruction in the case of
3923
- * interpolation instructions.
3924
- * @param interpolation An interpolation ast
3925
- */
3926
- function getInterpolationArgsLength(interpolation) {
3927
- const { expressions, strings } = interpolation;
3928
- if (expressions.length === 1 && strings.length === 2 && strings[0] === '' && strings[1] === '') {
3929
- // If the interpolation has one interpolated value, but the prefix and suffix are both empty
3930
- // strings, we only pass one argument, to a special instruction like `propertyInterpolate` or
3931
- // `textInterpolate`.
3932
- return 1;
3876
+ function escapeIdentifier(input, escapeDollar, alwaysQuote = true) {
3877
+ if (input == null) {
3878
+ return null;
3933
3879
  }
3934
- else {
3935
- return expressions.length + strings.length;
3880
+ const body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, (...match) => {
3881
+ if (match[0] == '$') {
3882
+ return escapeDollar ? '\\$' : '$';
3883
+ }
3884
+ else if (match[0] == '\n') {
3885
+ return '\\n';
3886
+ }
3887
+ else if (match[0] == '\r') {
3888
+ return '\\r';
3889
+ }
3890
+ else {
3891
+ return `\\${match[0]}`;
3892
+ }
3893
+ });
3894
+ const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);
3895
+ return requiresQuotes ? `'${body}'` : body;
3896
+ }
3897
+ function _createIndent(count) {
3898
+ let res = '';
3899
+ for (let i = 0; i < count; i++) {
3900
+ res += _INDENT_WITH;
3936
3901
  }
3902
+ return res;
3937
3903
  }
3938
3904
 
3939
3905
  /**
@@ -3943,74 +3909,73 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
3943
3909
  * Use of this source code is governed by an MIT-style license that can be
3944
3910
  * found in the LICENSE file at https://angular.io/license
3945
3911
  */
3946
- /**
3947
- * Creates an array literal expression from the given array, mapping all values to an expression
3948
- * using the provided mapping function. If the array is empty or null, then null is returned.
3949
- *
3950
- * @param values The array to transfer into literal array expression.
3951
- * @param mapper The logic to use for creating an expression for the array's values.
3952
- * @returns An array literal expression representing `values`, or null if `values` is empty or
3953
- * is itself null.
3954
- */
3955
- function toOptionalLiteralArray(values, mapper) {
3956
- if (values === null || values.length === 0) {
3957
- return null;
3912
+ function typeWithParameters(type, numParams) {
3913
+ if (numParams === 0) {
3914
+ return expressionType(type);
3958
3915
  }
3959
- return literalArr(values.map(value => mapper(value)));
3916
+ const params = [];
3917
+ for (let i = 0; i < numParams; i++) {
3918
+ params.push(DYNAMIC_TYPE);
3919
+ }
3920
+ return expressionType(type, undefined, params);
3921
+ }
3922
+ const ANIMATE_SYMBOL_PREFIX = '@';
3923
+ function prepareSyntheticPropertyName(name) {
3924
+ return `${ANIMATE_SYMBOL_PREFIX}${name}`;
3925
+ }
3926
+ function prepareSyntheticListenerName(name, phase) {
3927
+ return `${ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;
3928
+ }
3929
+ function getSafePropertyAccessString(accessor, name) {
3930
+ const escapedName = escapeIdentifier(name, false, false);
3931
+ return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;
3932
+ }
3933
+ function prepareSyntheticListenerFunctionName(name, phase) {
3934
+ return `animation_${name}_${phase}`;
3935
+ }
3936
+ function jitOnlyGuardedExpression(expr) {
3937
+ return guardedExpression('ngJitMode', expr);
3938
+ }
3939
+ function devOnlyGuardedExpression(expr) {
3940
+ return guardedExpression('ngDevMode', expr);
3941
+ }
3942
+ function guardedExpression(guard, expr) {
3943
+ const guardExpr = new ExternalExpr({ name: guard, moduleName: null });
3944
+ const guardNotDefined = new BinaryOperatorExpr(BinaryOperator.Identical, new TypeofExpr(guardExpr), literal$1('undefined'));
3945
+ const guardUndefinedOrTrue = new BinaryOperatorExpr(BinaryOperator.Or, guardNotDefined, guardExpr, /* type */ undefined,
3946
+ /* sourceSpan */ undefined, true);
3947
+ return new BinaryOperatorExpr(BinaryOperator.And, guardUndefinedOrTrue, expr);
3948
+ }
3949
+ function wrapReference(value) {
3950
+ const wrapped = new WrappedNodeExpr(value);
3951
+ return { value: wrapped, type: wrapped };
3952
+ }
3953
+ function refsToArray(refs, shouldForwardDeclare) {
3954
+ const values = literalArr(refs.map(ref => ref.value));
3955
+ return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
3956
+ }
3957
+ function createMayBeForwardRefExpression(expression, forwardRef) {
3958
+ return { expression, forwardRef };
3960
3959
  }
3961
3960
  /**
3962
- * Creates an object literal expression from the given object, mapping all values to an expression
3963
- * using the provided mapping function. If the object has no keys, then null is returned.
3961
+ * Convert a `MaybeForwardRefExpression` to an `Expression`, possibly wrapping its expression in a
3962
+ * `forwardRef()` call.
3964
3963
  *
3965
- * @param object The object to transfer into an object literal expression.
3966
- * @param mapper The logic to use for creating an expression for the object's values.
3967
- * @returns An object literal expression representing `object`, or null if `object` does not have
3968
- * any keys.
3964
+ * If `MaybeForwardRefExpression.forwardRef` is `ForwardRefHandling.Unwrapped` then the expression
3965
+ * was originally wrapped in a `forwardRef()` call to prevent the value from being eagerly evaluated
3966
+ * in the code.
3967
+ *
3968
+ * See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and
3969
+ * `packages/compiler/src/jit_compiler_facade.ts` for more information.
3969
3970
  */
3970
- function toOptionalLiteralMap(object, mapper) {
3971
- const entries = Object.keys(object).map(key => {
3972
- const value = object[key];
3973
- return { key, value: mapper(value), quoted: true };
3974
- });
3975
- if (entries.length > 0) {
3976
- return literalMap(entries);
3977
- }
3978
- else {
3979
- return null;
3980
- }
3981
- }
3982
- function compileDependencies(deps) {
3983
- if (deps === 'invalid') {
3984
- // The `deps` can be set to the string "invalid" by the `unwrapConstructorDependencies()`
3985
- // function, which tries to convert `ConstructorDeps` into `R3DependencyMetadata[]`.
3986
- return literal$1('invalid');
3987
- }
3988
- else if (deps === null) {
3989
- return literal$1(null);
3990
- }
3991
- else {
3992
- return literalArr(deps.map(compileDependency));
3993
- }
3994
- }
3995
- function compileDependency(dep) {
3996
- const depMeta = new DefinitionMap();
3997
- depMeta.set('token', dep.token);
3998
- if (dep.attributeNameType !== null) {
3999
- depMeta.set('attribute', literal$1(true));
4000
- }
4001
- if (dep.host) {
4002
- depMeta.set('host', literal$1(true));
4003
- }
4004
- if (dep.optional) {
4005
- depMeta.set('optional', literal$1(true));
3971
+ function convertFromMaybeForwardRefExpression({ expression, forwardRef }) {
3972
+ switch (forwardRef) {
3973
+ case 0 /* None */:
3974
+ case 1 /* Wrapped */:
3975
+ return expression;
3976
+ case 2 /* Unwrapped */:
3977
+ return generateForwardRef(expression);
4006
3978
  }
4007
- if (dep.self) {
4008
- depMeta.set('self', literal$1(true));
4009
- }
4010
- if (dep.skipSelf) {
4011
- depMeta.set('skipSelf', literal$1(true));
4012
- }
4013
- return depMeta.toLiteralMap();
4014
3979
  }
4015
3980
  /**
4016
3981
  * Generate an expression that has the given `expr` wrapped in the following form:
@@ -4023,153 +3988,197 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4023
3988
  return importExpr(Identifiers$1.forwardRef).callFn([fn([], [new ReturnStatement(expr)])]);
4024
3989
  }
4025
3990
 
3991
+ var R3FactoryDelegateType;
3992
+ (function (R3FactoryDelegateType) {
3993
+ R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
3994
+ R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function";
3995
+ })(R3FactoryDelegateType || (R3FactoryDelegateType = {}));
3996
+ var FactoryTarget$1;
3997
+ (function (FactoryTarget) {
3998
+ FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
3999
+ FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
4000
+ FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
4001
+ FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
4002
+ FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
4003
+ })(FactoryTarget$1 || (FactoryTarget$1 = {}));
4026
4004
  /**
4027
- * @license
4028
- * Copyright Google LLC All Rights Reserved.
4029
- *
4030
- * Use of this source code is governed by an MIT-style license that can be
4031
- * found in the LICENSE file at https://angular.io/license
4005
+ * Construct a factory function expression for the given `R3FactoryMetadata`.
4032
4006
  */
4033
- // https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
4034
- const VERSION = 3;
4035
- const JS_B64_PREFIX = '# sourceMappingURL=data:application/json;base64,';
4036
- class SourceMapGenerator {
4037
- constructor(file = null) {
4038
- this.file = file;
4039
- this.sourcesContent = new Map();
4040
- this.lines = [];
4041
- this.lastCol0 = 0;
4042
- this.hasMappings = false;
4043
- }
4044
- // The content is `null` when the content is expected to be loaded using the URL
4045
- addSource(url, content = null) {
4046
- if (!this.sourcesContent.has(url)) {
4047
- this.sourcesContent.set(url, content);
4007
+ function compileFactoryFunction(meta) {
4008
+ const t = variable('t');
4009
+ let baseFactoryVar = null;
4010
+ // The type to instantiate via constructor invocation. If there is no delegated factory, meaning
4011
+ // this type is always created by constructor invocation, then this is the type-to-create
4012
+ // parameter provided by the user (t) if specified, or the current type if not. If there is a
4013
+ // delegated factory (which is used to create the current type) then this is only the type-to-
4014
+ // create parameter (t).
4015
+ const typeForCtor = !isDelegatedFactoryMetadata(meta) ?
4016
+ new BinaryOperatorExpr(BinaryOperator.Or, t, meta.internalType) :
4017
+ t;
4018
+ let ctorExpr = null;
4019
+ if (meta.deps !== null) {
4020
+ // There is a constructor (either explicitly or implicitly defined).
4021
+ if (meta.deps !== 'invalid') {
4022
+ ctorExpr = new InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));
4048
4023
  }
4049
- return this;
4050
4024
  }
4051
- addLine() {
4052
- this.lines.push([]);
4053
- this.lastCol0 = 0;
4054
- return this;
4025
+ else {
4026
+ // There is no constructor, use the base class' factory to construct typeForCtor.
4027
+ baseFactoryVar = variable(`ɵ${meta.name}_BaseFactory`);
4028
+ ctorExpr = baseFactoryVar.callFn([typeForCtor]);
4055
4029
  }
4056
- addMapping(col0, sourceUrl, sourceLine0, sourceCol0) {
4057
- if (!this.currentLine) {
4058
- throw new Error(`A line must be added before mappings can be added`);
4059
- }
4060
- if (sourceUrl != null && !this.sourcesContent.has(sourceUrl)) {
4061
- throw new Error(`Unknown source file "${sourceUrl}"`);
4062
- }
4063
- if (col0 == null) {
4064
- throw new Error(`The column in the generated code must be provided`);
4065
- }
4066
- if (col0 < this.lastCol0) {
4067
- throw new Error(`Mapping should be added in output order`);
4068
- }
4069
- if (sourceUrl && (sourceLine0 == null || sourceCol0 == null)) {
4070
- throw new Error(`The source location must be provided when a source url is provided`);
4071
- }
4072
- this.hasMappings = true;
4073
- this.lastCol0 = col0;
4074
- this.currentLine.push({ col0, sourceUrl, sourceLine0, sourceCol0 });
4075
- return this;
4030
+ const body = [];
4031
+ let retExpr = null;
4032
+ function makeConditionalFactory(nonCtorExpr) {
4033
+ const r = variable('r');
4034
+ body.push(r.set(NULL_EXPR).toDeclStmt());
4035
+ const ctorStmt = ctorExpr !== null ? r.set(ctorExpr).toStmt() :
4036
+ importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt();
4037
+ body.push(ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()]));
4038
+ return r;
4076
4039
  }
4077
- /**
4078
- * @internal strip this from published d.ts files due to
4079
- * https://github.com/microsoft/TypeScript/issues/36216
4080
- */
4081
- get currentLine() {
4082
- return this.lines.slice(-1)[0];
4040
+ if (isDelegatedFactoryMetadata(meta)) {
4041
+ // This type is created with a delegated factory. If a type parameter is not specified, call
4042
+ // the factory instead.
4043
+ const delegateArgs = injectDependencies(meta.delegateDeps, meta.target);
4044
+ // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.
4045
+ const factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ?
4046
+ InstantiateExpr :
4047
+ InvokeFunctionExpr)(meta.delegate, delegateArgs);
4048
+ retExpr = makeConditionalFactory(factoryExpr);
4083
4049
  }
4084
- toJSON() {
4085
- if (!this.hasMappings) {
4086
- return null;
4050
+ else if (isExpressionFactoryMetadata(meta)) {
4051
+ // TODO(alxhub): decide whether to lower the value here or in the caller
4052
+ retExpr = makeConditionalFactory(meta.expression);
4053
+ }
4054
+ else {
4055
+ retExpr = ctorExpr;
4056
+ }
4057
+ if (retExpr === null) {
4058
+ // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.
4059
+ body.push(importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt());
4060
+ }
4061
+ else if (baseFactoryVar !== null) {
4062
+ // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it.
4063
+ const getInheritedFactoryCall = importExpr(Identifiers$1.getInheritedFactory).callFn([meta.internalType]);
4064
+ // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))`
4065
+ const baseFactory = new BinaryOperatorExpr(BinaryOperator.Or, baseFactoryVar, baseFactoryVar.set(getInheritedFactoryCall));
4066
+ body.push(new ReturnStatement(baseFactory.callFn([typeForCtor])));
4067
+ }
4068
+ else {
4069
+ // This is straightforward factory, just return it.
4070
+ body.push(new ReturnStatement(retExpr));
4071
+ }
4072
+ let factoryFn = fn([new FnParam('t', DYNAMIC_TYPE)], body, INFERRED_TYPE, undefined, `${meta.name}_Factory`);
4073
+ if (baseFactoryVar !== null) {
4074
+ // There is a base factory variable so wrap its declaration along with the factory function into
4075
+ // an IIFE.
4076
+ factoryFn = fn([], [
4077
+ new DeclareVarStmt(baseFactoryVar.name), new ReturnStatement(factoryFn)
4078
+ ]).callFn([], /* sourceSpan */ undefined, /* pure */ true);
4079
+ }
4080
+ return {
4081
+ expression: factoryFn,
4082
+ statements: [],
4083
+ type: createFactoryType(meta),
4084
+ };
4085
+ }
4086
+ function createFactoryType(meta) {
4087
+ const ctorDepsType = meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : NONE_TYPE;
4088
+ return expressionType(importExpr(Identifiers$1.FactoryDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType]));
4089
+ }
4090
+ function injectDependencies(deps, target) {
4091
+ return deps.map((dep, index) => compileInjectDependency(dep, target, index));
4092
+ }
4093
+ function compileInjectDependency(dep, target, index) {
4094
+ // Interpret the dependency according to its resolved type.
4095
+ if (dep.token === null) {
4096
+ return importExpr(Identifiers$1.invalidFactoryDep).callFn([literal$1(index)]);
4097
+ }
4098
+ else if (dep.attributeNameType === null) {
4099
+ // Build up the injection flags according to the metadata.
4100
+ const flags = 0 /* Default */ | (dep.self ? 2 /* Self */ : 0) |
4101
+ (dep.skipSelf ? 4 /* SkipSelf */ : 0) | (dep.host ? 1 /* Host */ : 0) |
4102
+ (dep.optional ? 8 /* Optional */ : 0) |
4103
+ (target === FactoryTarget$1.Pipe ? 16 /* ForPipe */ : 0);
4104
+ // If this dependency is optional or otherwise has non-default flags, then additional
4105
+ // parameters describing how to inject the dependency must be passed to the inject function
4106
+ // that's being used.
4107
+ let flagsParam = (flags !== 0 /* Default */ || dep.optional) ? literal$1(flags) : null;
4108
+ // Build up the arguments to the injectFn call.
4109
+ const injectArgs = [dep.token];
4110
+ if (flagsParam) {
4111
+ injectArgs.push(flagsParam);
4087
4112
  }
4088
- const sourcesIndex = new Map();
4089
- const sources = [];
4090
- const sourcesContent = [];
4091
- Array.from(this.sourcesContent.keys()).forEach((url, i) => {
4092
- sourcesIndex.set(url, i);
4093
- sources.push(url);
4094
- sourcesContent.push(this.sourcesContent.get(url) || null);
4095
- });
4096
- let mappings = '';
4097
- let lastCol0 = 0;
4098
- let lastSourceIndex = 0;
4099
- let lastSourceLine0 = 0;
4100
- let lastSourceCol0 = 0;
4101
- this.lines.forEach(segments => {
4102
- lastCol0 = 0;
4103
- mappings += segments
4104
- .map(segment => {
4105
- // zero-based starting column of the line in the generated code
4106
- let segAsStr = toBase64VLQ(segment.col0 - lastCol0);
4107
- lastCol0 = segment.col0;
4108
- if (segment.sourceUrl != null) {
4109
- // zero-based index into the “sources” list
4110
- segAsStr +=
4111
- toBase64VLQ(sourcesIndex.get(segment.sourceUrl) - lastSourceIndex);
4112
- lastSourceIndex = sourcesIndex.get(segment.sourceUrl);
4113
- // the zero-based starting line in the original source
4114
- segAsStr += toBase64VLQ(segment.sourceLine0 - lastSourceLine0);
4115
- lastSourceLine0 = segment.sourceLine0;
4116
- // the zero-based starting column in the original source
4117
- segAsStr += toBase64VLQ(segment.sourceCol0 - lastSourceCol0);
4118
- lastSourceCol0 = segment.sourceCol0;
4119
- }
4120
- return segAsStr;
4121
- })
4122
- .join(',');
4123
- mappings += ';';
4124
- });
4125
- mappings = mappings.slice(0, -1);
4126
- return {
4127
- 'file': this.file || '',
4128
- 'version': VERSION,
4129
- 'sourceRoot': '',
4130
- 'sources': sources,
4131
- 'sourcesContent': sourcesContent,
4132
- 'mappings': mappings,
4133
- };
4113
+ const injectFn = getInjectFn(target);
4114
+ return importExpr(injectFn).callFn(injectArgs);
4115
+ }
4116
+ else {
4117
+ // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()`
4118
+ // type dependency. For the generated JS we still want to use the `dep.token` value in case the
4119
+ // name given for the attribute is not a string literal. For example given `@Attribute(foo())`,
4120
+ // we want to generate `ɵɵinjectAttribute(foo())`.
4121
+ //
4122
+ // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate
4123
+ // typings.
4124
+ return importExpr(Identifiers$1.injectAttribute).callFn([dep.token]);
4134
4125
  }
4135
- toJsComment() {
4136
- return this.hasMappings ? '//' + JS_B64_PREFIX + toBase64String(JSON.stringify(this, null, 0)) :
4137
- '';
4126
+ }
4127
+ function createCtorDepsType(deps) {
4128
+ let hasTypes = false;
4129
+ const attributeTypes = deps.map(dep => {
4130
+ const type = createCtorDepType(dep);
4131
+ if (type !== null) {
4132
+ hasTypes = true;
4133
+ return type;
4134
+ }
4135
+ else {
4136
+ return literal$1(null);
4137
+ }
4138
+ });
4139
+ if (hasTypes) {
4140
+ return expressionType(literalArr(attributeTypes));
4141
+ }
4142
+ else {
4143
+ return NONE_TYPE;
4138
4144
  }
4139
4145
  }
4140
- function toBase64String(value) {
4141
- let b64 = '';
4142
- const encoded = utf8Encode(value);
4143
- for (let i = 0; i < encoded.length;) {
4144
- const i1 = encoded[i++];
4145
- const i2 = i < encoded.length ? encoded[i++] : null;
4146
- const i3 = i < encoded.length ? encoded[i++] : null;
4147
- b64 += toBase64Digit(i1 >> 2);
4148
- b64 += toBase64Digit(((i1 & 3) << 4) | (i2 === null ? 0 : i2 >> 4));
4149
- b64 += i2 === null ? '=' : toBase64Digit(((i2 & 15) << 2) | (i3 === null ? 0 : i3 >> 6));
4150
- b64 += i2 === null || i3 === null ? '=' : toBase64Digit(i3 & 63);
4146
+ function createCtorDepType(dep) {
4147
+ const entries = [];
4148
+ if (dep.attributeNameType !== null) {
4149
+ entries.push({ key: 'attribute', value: dep.attributeNameType, quoted: false });
4151
4150
  }
4152
- return b64;
4151
+ if (dep.optional) {
4152
+ entries.push({ key: 'optional', value: literal$1(true), quoted: false });
4153
+ }
4154
+ if (dep.host) {
4155
+ entries.push({ key: 'host', value: literal$1(true), quoted: false });
4156
+ }
4157
+ if (dep.self) {
4158
+ entries.push({ key: 'self', value: literal$1(true), quoted: false });
4159
+ }
4160
+ if (dep.skipSelf) {
4161
+ entries.push({ key: 'skipSelf', value: literal$1(true), quoted: false });
4162
+ }
4163
+ return entries.length > 0 ? literalMap(entries) : null;
4153
4164
  }
4154
- function toBase64VLQ(value) {
4155
- value = value < 0 ? ((-value) << 1) + 1 : value << 1;
4156
- let out = '';
4157
- do {
4158
- let digit = value & 31;
4159
- value = value >> 5;
4160
- if (value > 0) {
4161
- digit = digit | 32;
4162
- }
4163
- out += toBase64Digit(digit);
4164
- } while (value > 0);
4165
- return out;
4165
+ function isDelegatedFactoryMetadata(meta) {
4166
+ return meta.delegateType !== undefined;
4166
4167
  }
4167
- const B64_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
4168
- function toBase64Digit(value) {
4169
- if (value < 0 || value >= 64) {
4170
- throw new Error(`Can only encode value in the range [0, 63]`);
4168
+ function isExpressionFactoryMetadata(meta) {
4169
+ return meta.expression !== undefined;
4170
+ }
4171
+ function getInjectFn(target) {
4172
+ switch (target) {
4173
+ case FactoryTarget$1.Component:
4174
+ case FactoryTarget$1.Directive:
4175
+ case FactoryTarget$1.Pipe:
4176
+ return Identifiers$1.directiveInject;
4177
+ case FactoryTarget$1.NgModule:
4178
+ case FactoryTarget$1.Injectable:
4179
+ default:
4180
+ return Identifiers$1.inject;
4171
4181
  }
4172
- return B64_DIGITS[value];
4173
4182
  }
4174
4183
 
4175
4184
  /**
@@ -4179,551 +4188,532 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4179
4188
  * Use of this source code is governed by an MIT-style license that can be
4180
4189
  * found in the LICENSE file at https://angular.io/license
4181
4190
  */
4182
- const _SINGLE_QUOTE_ESCAPE_STRING_RE = /'|\\|\n|\r|\$/g;
4183
- const _LEGAL_IDENTIFIER_RE = /^[$A-Z_][0-9A-Z_$]*$/i;
4184
- const _INDENT_WITH = ' ';
4185
- const CATCH_ERROR_VAR = variable('error', null, null);
4186
- const CATCH_STACK_VAR = variable('stack', null, null);
4187
- class _EmittedLine {
4188
- constructor(indent) {
4189
- this.indent = indent;
4190
- this.partsLength = 0;
4191
- this.parts = [];
4192
- this.srcSpans = [];
4193
- }
4194
- }
4195
- class EmitterVisitorContext {
4196
- constructor(_indent) {
4197
- this._indent = _indent;
4198
- this._classes = [];
4199
- this._preambleLineCount = 0;
4200
- this._lines = [new _EmittedLine(_indent)];
4191
+ /**
4192
+ * This is an R3 `Node`-like wrapper for a raw `html.Comment` node. We do not currently
4193
+ * require the implementation of a visitor for Comments as they are only collected at
4194
+ * the top-level of the R3 AST, and only if `Render3ParseOptions['collectCommentNodes']`
4195
+ * is true.
4196
+ */
4197
+ class Comment$1 {
4198
+ constructor(value, sourceSpan) {
4199
+ this.value = value;
4200
+ this.sourceSpan = sourceSpan;
4201
4201
  }
4202
- static createRoot() {
4203
- return new EmitterVisitorContext(0);
4202
+ visit(_visitor) {
4203
+ throw new Error('visit() not implemented for Comment');
4204
4204
  }
4205
- /**
4206
- * @internal strip this from published d.ts files due to
4207
- * https://github.com/microsoft/TypeScript/issues/36216
4208
- */
4209
- get _currentLine() {
4210
- return this._lines[this._lines.length - 1];
4205
+ }
4206
+ class Text$2 {
4207
+ constructor(value, sourceSpan) {
4208
+ this.value = value;
4209
+ this.sourceSpan = sourceSpan;
4211
4210
  }
4212
- println(from, lastPart = '') {
4213
- this.print(from || null, lastPart, true);
4211
+ visit(visitor) {
4212
+ return visitor.visitText(this);
4214
4213
  }
4215
- lineIsEmpty() {
4216
- return this._currentLine.parts.length === 0;
4214
+ }
4215
+ class BoundText {
4216
+ constructor(value, sourceSpan, i18n) {
4217
+ this.value = value;
4218
+ this.sourceSpan = sourceSpan;
4219
+ this.i18n = i18n;
4217
4220
  }
4218
- lineLength() {
4219
- return this._currentLine.indent * _INDENT_WITH.length + this._currentLine.partsLength;
4221
+ visit(visitor) {
4222
+ return visitor.visitBoundText(this);
4220
4223
  }
4221
- print(from, part, newLine = false) {
4222
- if (part.length > 0) {
4223
- this._currentLine.parts.push(part);
4224
- this._currentLine.partsLength += part.length;
4225
- this._currentLine.srcSpans.push(from && from.sourceSpan || null);
4226
- }
4227
- if (newLine) {
4228
- this._lines.push(new _EmittedLine(this._indent));
4229
- }
4224
+ }
4225
+ /**
4226
+ * Represents a text attribute in the template.
4227
+ *
4228
+ * `valueSpan` may not be present in cases where there is no value `<div a></div>`.
4229
+ * `keySpan` may also not be present for synthetic attributes from ICU expansions.
4230
+ */
4231
+ class TextAttribute {
4232
+ constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
4233
+ this.name = name;
4234
+ this.value = value;
4235
+ this.sourceSpan = sourceSpan;
4236
+ this.keySpan = keySpan;
4237
+ this.valueSpan = valueSpan;
4238
+ this.i18n = i18n;
4230
4239
  }
4231
- removeEmptyLastLine() {
4232
- if (this.lineIsEmpty()) {
4233
- this._lines.pop();
4234
- }
4240
+ visit(visitor) {
4241
+ return visitor.visitTextAttribute(this);
4235
4242
  }
4236
- incIndent() {
4237
- this._indent++;
4238
- if (this.lineIsEmpty()) {
4239
- this._currentLine.indent = this._indent;
4240
- }
4243
+ }
4244
+ class BoundAttribute {
4245
+ constructor(name, type, securityContext, value, unit, sourceSpan, keySpan, valueSpan, i18n) {
4246
+ this.name = name;
4247
+ this.type = type;
4248
+ this.securityContext = securityContext;
4249
+ this.value = value;
4250
+ this.unit = unit;
4251
+ this.sourceSpan = sourceSpan;
4252
+ this.keySpan = keySpan;
4253
+ this.valueSpan = valueSpan;
4254
+ this.i18n = i18n;
4241
4255
  }
4242
- decIndent() {
4243
- this._indent--;
4244
- if (this.lineIsEmpty()) {
4245
- this._currentLine.indent = this._indent;
4256
+ static fromBoundElementProperty(prop, i18n) {
4257
+ if (prop.keySpan === undefined) {
4258
+ throw new Error(`Unexpected state: keySpan must be defined for bound attributes but was not for ${prop.name}: ${prop.sourceSpan}`);
4246
4259
  }
4260
+ return new BoundAttribute(prop.name, prop.type, prop.securityContext, prop.value, prop.unit, prop.sourceSpan, prop.keySpan, prop.valueSpan, i18n);
4247
4261
  }
4248
- pushClass(clazz) {
4249
- this._classes.push(clazz);
4250
- }
4251
- popClass() {
4252
- return this._classes.pop();
4253
- }
4254
- get currentClass() {
4255
- return this._classes.length > 0 ? this._classes[this._classes.length - 1] : null;
4262
+ visit(visitor) {
4263
+ return visitor.visitBoundAttribute(this);
4256
4264
  }
4257
- toSource() {
4258
- return this.sourceLines
4259
- .map(l => l.parts.length > 0 ? _createIndent(l.indent) + l.parts.join('') : '')
4260
- .join('\n');
4265
+ }
4266
+ class BoundEvent {
4267
+ constructor(name, type, handler, target, phase, sourceSpan, handlerSpan, keySpan) {
4268
+ this.name = name;
4269
+ this.type = type;
4270
+ this.handler = handler;
4271
+ this.target = target;
4272
+ this.phase = phase;
4273
+ this.sourceSpan = sourceSpan;
4274
+ this.handlerSpan = handlerSpan;
4275
+ this.keySpan = keySpan;
4261
4276
  }
4262
- toSourceMapGenerator(genFilePath, startsAtLine = 0) {
4263
- const map = new SourceMapGenerator(genFilePath);
4264
- let firstOffsetMapped = false;
4265
- const mapFirstOffsetIfNeeded = () => {
4266
- if (!firstOffsetMapped) {
4267
- // Add a single space so that tools won't try to load the file from disk.
4268
- // Note: We are using virtual urls like `ng:///`, so we have to
4269
- // provide a content here.
4270
- map.addSource(genFilePath, ' ').addMapping(0, genFilePath, 0, 0);
4271
- firstOffsetMapped = true;
4272
- }
4273
- };
4274
- for (let i = 0; i < startsAtLine; i++) {
4275
- map.addLine();
4276
- mapFirstOffsetIfNeeded();
4277
+ static fromParsedEvent(event) {
4278
+ const target = event.type === 0 /* Regular */ ? event.targetOrPhase : null;
4279
+ const phase = event.type === 1 /* Animation */ ? event.targetOrPhase : null;
4280
+ if (event.keySpan === undefined) {
4281
+ throw new Error(`Unexpected state: keySpan must be defined for bound event but was not for ${event.name}: ${event.sourceSpan}`);
4277
4282
  }
4278
- this.sourceLines.forEach((line, lineIdx) => {
4279
- map.addLine();
4280
- const spans = line.srcSpans;
4281
- const parts = line.parts;
4282
- let col0 = line.indent * _INDENT_WITH.length;
4283
- let spanIdx = 0;
4284
- // skip leading parts without source spans
4285
- while (spanIdx < spans.length && !spans[spanIdx]) {
4286
- col0 += parts[spanIdx].length;
4287
- spanIdx++;
4288
- }
4289
- if (spanIdx < spans.length && lineIdx === 0 && col0 === 0) {
4290
- firstOffsetMapped = true;
4291
- }
4292
- else {
4293
- mapFirstOffsetIfNeeded();
4294
- }
4295
- while (spanIdx < spans.length) {
4296
- const span = spans[spanIdx];
4297
- const source = span.start.file;
4298
- const sourceLine = span.start.line;
4299
- const sourceCol = span.start.col;
4300
- map.addSource(source.url, source.content)
4301
- .addMapping(col0, source.url, sourceLine, sourceCol);
4302
- col0 += parts[spanIdx].length;
4303
- spanIdx++;
4304
- // assign parts without span or the same span to the previous segment
4305
- while (spanIdx < spans.length && (span === spans[spanIdx] || !spans[spanIdx])) {
4306
- col0 += parts[spanIdx].length;
4307
- spanIdx++;
4308
- }
4309
- }
4310
- });
4311
- return map;
4283
+ return new BoundEvent(event.name, event.type, event.handler, target, phase, event.sourceSpan, event.handlerSpan, event.keySpan);
4312
4284
  }
4313
- setPreambleLineCount(count) {
4314
- return this._preambleLineCount = count;
4285
+ visit(visitor) {
4286
+ return visitor.visitBoundEvent(this);
4315
4287
  }
4316
- spanOf(line, column) {
4317
- const emittedLine = this._lines[line - this._preambleLineCount];
4318
- if (emittedLine) {
4319
- let columnsLeft = column - _createIndent(emittedLine.indent).length;
4320
- for (let partIndex = 0; partIndex < emittedLine.parts.length; partIndex++) {
4321
- const part = emittedLine.parts[partIndex];
4322
- if (part.length > columnsLeft) {
4323
- return emittedLine.srcSpans[partIndex];
4324
- }
4325
- columnsLeft -= part.length;
4326
- }
4327
- }
4328
- return null;
4288
+ }
4289
+ class Element$1 {
4290
+ constructor(name, attributes, inputs, outputs, children, references, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
4291
+ this.name = name;
4292
+ this.attributes = attributes;
4293
+ this.inputs = inputs;
4294
+ this.outputs = outputs;
4295
+ this.children = children;
4296
+ this.references = references;
4297
+ this.sourceSpan = sourceSpan;
4298
+ this.startSourceSpan = startSourceSpan;
4299
+ this.endSourceSpan = endSourceSpan;
4300
+ this.i18n = i18n;
4329
4301
  }
4330
- /**
4331
- * @internal strip this from published d.ts files due to
4332
- * https://github.com/microsoft/TypeScript/issues/36216
4333
- */
4334
- get sourceLines() {
4335
- if (this._lines.length && this._lines[this._lines.length - 1].parts.length === 0) {
4336
- return this._lines.slice(0, -1);
4337
- }
4338
- return this._lines;
4302
+ visit(visitor) {
4303
+ return visitor.visitElement(this);
4339
4304
  }
4340
4305
  }
4341
- class AbstractEmitterVisitor {
4342
- constructor(_escapeDollarInStrings) {
4343
- this._escapeDollarInStrings = _escapeDollarInStrings;
4306
+ class Template {
4307
+ constructor(tagName, attributes, inputs, outputs, templateAttrs, children, references, variables, sourceSpan, startSourceSpan, endSourceSpan, i18n) {
4308
+ this.tagName = tagName;
4309
+ this.attributes = attributes;
4310
+ this.inputs = inputs;
4311
+ this.outputs = outputs;
4312
+ this.templateAttrs = templateAttrs;
4313
+ this.children = children;
4314
+ this.references = references;
4315
+ this.variables = variables;
4316
+ this.sourceSpan = sourceSpan;
4317
+ this.startSourceSpan = startSourceSpan;
4318
+ this.endSourceSpan = endSourceSpan;
4319
+ this.i18n = i18n;
4344
4320
  }
4345
- printLeadingComments(stmt, ctx) {
4346
- if (stmt.leadingComments === undefined) {
4347
- return;
4348
- }
4349
- for (const comment of stmt.leadingComments) {
4350
- if (comment instanceof JSDocComment) {
4351
- ctx.print(stmt, `/*${comment.toString()}*/`, comment.trailingNewline);
4352
- }
4353
- else {
4354
- if (comment.multiline) {
4355
- ctx.print(stmt, `/* ${comment.text} */`, comment.trailingNewline);
4356
- }
4357
- else {
4358
- comment.text.split('\n').forEach((line) => {
4359
- ctx.println(stmt, `// ${line}`);
4360
- });
4361
- }
4362
- }
4363
- }
4321
+ visit(visitor) {
4322
+ return visitor.visitTemplate(this);
4364
4323
  }
4365
- visitExpressionStmt(stmt, ctx) {
4366
- this.printLeadingComments(stmt, ctx);
4367
- stmt.expr.visitExpression(this, ctx);
4368
- ctx.println(stmt, ';');
4369
- return null;
4324
+ }
4325
+ class Content {
4326
+ constructor(selector, attributes, sourceSpan, i18n) {
4327
+ this.selector = selector;
4328
+ this.attributes = attributes;
4329
+ this.sourceSpan = sourceSpan;
4330
+ this.i18n = i18n;
4331
+ this.name = 'ng-content';
4370
4332
  }
4371
- visitReturnStmt(stmt, ctx) {
4372
- this.printLeadingComments(stmt, ctx);
4373
- ctx.print(stmt, `return `);
4374
- stmt.value.visitExpression(this, ctx);
4375
- ctx.println(stmt, ';');
4376
- return null;
4333
+ visit(visitor) {
4334
+ return visitor.visitContent(this);
4377
4335
  }
4378
- visitIfStmt(stmt, ctx) {
4379
- this.printLeadingComments(stmt, ctx);
4380
- ctx.print(stmt, `if (`);
4381
- stmt.condition.visitExpression(this, ctx);
4382
- ctx.print(stmt, `) {`);
4383
- const hasElseCase = stmt.falseCase != null && stmt.falseCase.length > 0;
4384
- if (stmt.trueCase.length <= 1 && !hasElseCase) {
4385
- ctx.print(stmt, ` `);
4386
- this.visitAllStatements(stmt.trueCase, ctx);
4387
- ctx.removeEmptyLastLine();
4388
- ctx.print(stmt, ` `);
4389
- }
4390
- else {
4391
- ctx.println();
4392
- ctx.incIndent();
4393
- this.visitAllStatements(stmt.trueCase, ctx);
4394
- ctx.decIndent();
4395
- if (hasElseCase) {
4396
- ctx.println(stmt, `} else {`);
4397
- ctx.incIndent();
4398
- this.visitAllStatements(stmt.falseCase, ctx);
4399
- ctx.decIndent();
4400
- }
4401
- }
4402
- ctx.println(stmt, `}`);
4403
- return null;
4336
+ }
4337
+ class Variable {
4338
+ constructor(name, value, sourceSpan, keySpan, valueSpan) {
4339
+ this.name = name;
4340
+ this.value = value;
4341
+ this.sourceSpan = sourceSpan;
4342
+ this.keySpan = keySpan;
4343
+ this.valueSpan = valueSpan;
4404
4344
  }
4405
- visitThrowStmt(stmt, ctx) {
4406
- this.printLeadingComments(stmt, ctx);
4407
- ctx.print(stmt, `throw `);
4408
- stmt.error.visitExpression(this, ctx);
4409
- ctx.println(stmt, `;`);
4410
- return null;
4345
+ visit(visitor) {
4346
+ return visitor.visitVariable(this);
4411
4347
  }
4412
- visitWriteVarExpr(expr, ctx) {
4413
- const lineWasEmpty = ctx.lineIsEmpty();
4414
- if (!lineWasEmpty) {
4415
- ctx.print(expr, '(');
4416
- }
4417
- ctx.print(expr, `${expr.name} = `);
4418
- expr.value.visitExpression(this, ctx);
4419
- if (!lineWasEmpty) {
4420
- ctx.print(expr, ')');
4421
- }
4422
- return null;
4348
+ }
4349
+ class Reference$1 {
4350
+ constructor(name, value, sourceSpan, keySpan, valueSpan) {
4351
+ this.name = name;
4352
+ this.value = value;
4353
+ this.sourceSpan = sourceSpan;
4354
+ this.keySpan = keySpan;
4355
+ this.valueSpan = valueSpan;
4423
4356
  }
4424
- visitWriteKeyExpr(expr, ctx) {
4425
- const lineWasEmpty = ctx.lineIsEmpty();
4426
- if (!lineWasEmpty) {
4427
- ctx.print(expr, '(');
4428
- }
4429
- expr.receiver.visitExpression(this, ctx);
4430
- ctx.print(expr, `[`);
4431
- expr.index.visitExpression(this, ctx);
4432
- ctx.print(expr, `] = `);
4433
- expr.value.visitExpression(this, ctx);
4434
- if (!lineWasEmpty) {
4435
- ctx.print(expr, ')');
4436
- }
4437
- return null;
4357
+ visit(visitor) {
4358
+ return visitor.visitReference(this);
4438
4359
  }
4439
- visitWritePropExpr(expr, ctx) {
4440
- const lineWasEmpty = ctx.lineIsEmpty();
4441
- if (!lineWasEmpty) {
4442
- ctx.print(expr, '(');
4443
- }
4444
- expr.receiver.visitExpression(this, ctx);
4445
- ctx.print(expr, `.${expr.name} = `);
4446
- expr.value.visitExpression(this, ctx);
4447
- if (!lineWasEmpty) {
4448
- ctx.print(expr, ')');
4449
- }
4450
- return null;
4360
+ }
4361
+ class Icu$1 {
4362
+ constructor(vars, placeholders, sourceSpan, i18n) {
4363
+ this.vars = vars;
4364
+ this.placeholders = placeholders;
4365
+ this.sourceSpan = sourceSpan;
4366
+ this.i18n = i18n;
4451
4367
  }
4452
- visitInvokeFunctionExpr(expr, ctx) {
4453
- expr.fn.visitExpression(this, ctx);
4454
- ctx.print(expr, `(`);
4455
- this.visitAllExpressions(expr.args, ctx, ',');
4456
- ctx.print(expr, `)`);
4457
- return null;
4368
+ visit(visitor) {
4369
+ return visitor.visitIcu(this);
4458
4370
  }
4459
- visitTaggedTemplateExpr(expr, ctx) {
4460
- expr.tag.visitExpression(this, ctx);
4461
- ctx.print(expr, '`' + expr.template.elements[0].rawText);
4462
- for (let i = 1; i < expr.template.elements.length; i++) {
4463
- ctx.print(expr, '${');
4464
- expr.template.expressions[i - 1].visitExpression(this, ctx);
4465
- ctx.print(expr, `}${expr.template.elements[i].rawText}`);
4466
- }
4467
- ctx.print(expr, '`');
4468
- return null;
4371
+ }
4372
+ class RecursiveVisitor {
4373
+ visitElement(element) {
4374
+ visitAll$1(this, element.attributes);
4375
+ visitAll$1(this, element.inputs);
4376
+ visitAll$1(this, element.outputs);
4377
+ visitAll$1(this, element.children);
4378
+ visitAll$1(this, element.references);
4469
4379
  }
4470
- visitWrappedNodeExpr(ast, ctx) {
4471
- throw new Error('Abstract emitter cannot visit WrappedNodeExpr.');
4380
+ visitTemplate(template) {
4381
+ visitAll$1(this, template.attributes);
4382
+ visitAll$1(this, template.inputs);
4383
+ visitAll$1(this, template.outputs);
4384
+ visitAll$1(this, template.children);
4385
+ visitAll$1(this, template.references);
4386
+ visitAll$1(this, template.variables);
4472
4387
  }
4473
- visitTypeofExpr(expr, ctx) {
4474
- ctx.print(expr, 'typeof ');
4475
- expr.expr.visitExpression(this, ctx);
4388
+ visitContent(content) { }
4389
+ visitVariable(variable) { }
4390
+ visitReference(reference) { }
4391
+ visitTextAttribute(attribute) { }
4392
+ visitBoundAttribute(attribute) { }
4393
+ visitBoundEvent(attribute) { }
4394
+ visitText(text) { }
4395
+ visitBoundText(text) { }
4396
+ visitIcu(icu) { }
4397
+ }
4398
+ function visitAll$1(visitor, nodes) {
4399
+ const result = [];
4400
+ if (visitor.visit) {
4401
+ for (const node of nodes) {
4402
+ visitor.visit(node) || node.visit(visitor);
4403
+ }
4476
4404
  }
4477
- visitReadVarExpr(ast, ctx) {
4478
- let varName = ast.name;
4479
- if (ast.builtin != null) {
4480
- switch (ast.builtin) {
4481
- case BuiltinVar.Super:
4482
- varName = 'super';
4483
- break;
4484
- case BuiltinVar.This:
4485
- varName = 'this';
4486
- break;
4487
- case BuiltinVar.CatchError:
4488
- varName = CATCH_ERROR_VAR.name;
4489
- break;
4490
- case BuiltinVar.CatchStack:
4491
- varName = CATCH_STACK_VAR.name;
4492
- break;
4493
- default:
4494
- throw new Error(`Unknown builtin variable ${ast.builtin}`);
4405
+ else {
4406
+ for (const node of nodes) {
4407
+ const newNode = node.visit(visitor);
4408
+ if (newNode) {
4409
+ result.push(newNode);
4495
4410
  }
4496
4411
  }
4497
- ctx.print(ast, varName);
4498
- return null;
4499
- }
4500
- visitInstantiateExpr(ast, ctx) {
4501
- ctx.print(ast, `new `);
4502
- ast.classExpr.visitExpression(this, ctx);
4503
- ctx.print(ast, `(`);
4504
- this.visitAllExpressions(ast.args, ctx, ',');
4505
- ctx.print(ast, `)`);
4506
- return null;
4507
4412
  }
4508
- visitLiteralExpr(ast, ctx) {
4509
- const value = ast.value;
4510
- if (typeof value === 'string') {
4511
- ctx.print(ast, escapeIdentifier(value, this._escapeDollarInStrings));
4413
+ return result;
4414
+ }
4415
+
4416
+ /**
4417
+ * @license
4418
+ * Copyright Google LLC All Rights Reserved.
4419
+ *
4420
+ * Use of this source code is governed by an MIT-style license that can be
4421
+ * found in the LICENSE file at https://angular.io/license
4422
+ */
4423
+ class Message {
4424
+ /**
4425
+ * @param nodes message AST
4426
+ * @param placeholders maps placeholder names to static content and their source spans
4427
+ * @param placeholderToMessage maps placeholder names to messages (used for nested ICU messages)
4428
+ * @param meaning
4429
+ * @param description
4430
+ * @param customId
4431
+ */
4432
+ constructor(nodes, placeholders, placeholderToMessage, meaning, description, customId) {
4433
+ this.nodes = nodes;
4434
+ this.placeholders = placeholders;
4435
+ this.placeholderToMessage = placeholderToMessage;
4436
+ this.meaning = meaning;
4437
+ this.description = description;
4438
+ this.customId = customId;
4439
+ this.id = this.customId;
4440
+ /** The ids to use if there are no custom id and if `i18nLegacyMessageIdFormat` is not empty */
4441
+ this.legacyIds = [];
4442
+ this.messageString = serializeMessage(this.nodes);
4443
+ if (nodes.length) {
4444
+ this.sources = [{
4445
+ filePath: nodes[0].sourceSpan.start.file.url,
4446
+ startLine: nodes[0].sourceSpan.start.line + 1,
4447
+ startCol: nodes[0].sourceSpan.start.col + 1,
4448
+ endLine: nodes[nodes.length - 1].sourceSpan.end.line + 1,
4449
+ endCol: nodes[0].sourceSpan.start.col + 1
4450
+ }];
4512
4451
  }
4513
4452
  else {
4514
- ctx.print(ast, `${value}`);
4453
+ this.sources = [];
4515
4454
  }
4516
- return null;
4517
4455
  }
4518
- visitLocalizedString(ast, ctx) {
4519
- const head = ast.serializeI18nHead();
4520
- ctx.print(ast, '$localize `' + head.raw);
4521
- for (let i = 1; i < ast.messageParts.length; i++) {
4522
- ctx.print(ast, '${');
4523
- ast.expressions[i - 1].visitExpression(this, ctx);
4524
- ctx.print(ast, `}${ast.serializeI18nTemplatePart(i).raw}`);
4525
- }
4526
- ctx.print(ast, '`');
4527
- return null;
4456
+ }
4457
+ class Text$1 {
4458
+ constructor(value, sourceSpan) {
4459
+ this.value = value;
4460
+ this.sourceSpan = sourceSpan;
4528
4461
  }
4529
- visitConditionalExpr(ast, ctx) {
4530
- ctx.print(ast, `(`);
4531
- ast.condition.visitExpression(this, ctx);
4532
- ctx.print(ast, '? ');
4533
- ast.trueCase.visitExpression(this, ctx);
4534
- ctx.print(ast, ': ');
4535
- ast.falseCase.visitExpression(this, ctx);
4536
- ctx.print(ast, `)`);
4537
- return null;
4462
+ visit(visitor, context) {
4463
+ return visitor.visitText(this, context);
4538
4464
  }
4539
- visitNotExpr(ast, ctx) {
4540
- ctx.print(ast, '!');
4541
- ast.condition.visitExpression(this, ctx);
4542
- return null;
4465
+ }
4466
+ // TODO(vicb): do we really need this node (vs an array) ?
4467
+ class Container {
4468
+ constructor(children, sourceSpan) {
4469
+ this.children = children;
4470
+ this.sourceSpan = sourceSpan;
4543
4471
  }
4544
- visitAssertNotNullExpr(ast, ctx) {
4545
- ast.condition.visitExpression(this, ctx);
4546
- return null;
4472
+ visit(visitor, context) {
4473
+ return visitor.visitContainer(this, context);
4547
4474
  }
4548
- visitUnaryOperatorExpr(ast, ctx) {
4549
- let opStr;
4550
- switch (ast.operator) {
4551
- case UnaryOperator.Plus:
4552
- opStr = '+';
4553
- break;
4554
- case UnaryOperator.Minus:
4555
- opStr = '-';
4556
- break;
4557
- default:
4558
- throw new Error(`Unknown operator ${ast.operator}`);
4559
- }
4560
- if (ast.parens)
4561
- ctx.print(ast, `(`);
4562
- ctx.print(ast, opStr);
4563
- ast.expr.visitExpression(this, ctx);
4564
- if (ast.parens)
4565
- ctx.print(ast, `)`);
4566
- return null;
4475
+ }
4476
+ class Icu {
4477
+ constructor(expression, type, cases, sourceSpan) {
4478
+ this.expression = expression;
4479
+ this.type = type;
4480
+ this.cases = cases;
4481
+ this.sourceSpan = sourceSpan;
4567
4482
  }
4568
- visitBinaryOperatorExpr(ast, ctx) {
4569
- let opStr;
4570
- switch (ast.operator) {
4571
- case BinaryOperator.Equals:
4572
- opStr = '==';
4573
- break;
4574
- case BinaryOperator.Identical:
4575
- opStr = '===';
4576
- break;
4577
- case BinaryOperator.NotEquals:
4578
- opStr = '!=';
4579
- break;
4580
- case BinaryOperator.NotIdentical:
4581
- opStr = '!==';
4582
- break;
4583
- case BinaryOperator.And:
4584
- opStr = '&&';
4585
- break;
4586
- case BinaryOperator.BitwiseAnd:
4587
- opStr = '&';
4588
- break;
4589
- case BinaryOperator.Or:
4590
- opStr = '||';
4591
- break;
4592
- case BinaryOperator.Plus:
4593
- opStr = '+';
4594
- break;
4595
- case BinaryOperator.Minus:
4596
- opStr = '-';
4597
- break;
4598
- case BinaryOperator.Divide:
4599
- opStr = '/';
4600
- break;
4601
- case BinaryOperator.Multiply:
4602
- opStr = '*';
4603
- break;
4604
- case BinaryOperator.Modulo:
4605
- opStr = '%';
4606
- break;
4607
- case BinaryOperator.Lower:
4608
- opStr = '<';
4609
- break;
4610
- case BinaryOperator.LowerEquals:
4611
- opStr = '<=';
4612
- break;
4613
- case BinaryOperator.Bigger:
4614
- opStr = '>';
4615
- break;
4616
- case BinaryOperator.BiggerEquals:
4617
- opStr = '>=';
4618
- break;
4619
- case BinaryOperator.NullishCoalesce:
4620
- opStr = '??';
4621
- break;
4622
- default:
4623
- throw new Error(`Unknown operator ${ast.operator}`);
4624
- }
4625
- if (ast.parens)
4626
- ctx.print(ast, `(`);
4627
- ast.lhs.visitExpression(this, ctx);
4628
- ctx.print(ast, ` ${opStr} `);
4629
- ast.rhs.visitExpression(this, ctx);
4630
- if (ast.parens)
4631
- ctx.print(ast, `)`);
4632
- return null;
4483
+ visit(visitor, context) {
4484
+ return visitor.visitIcu(this, context);
4633
4485
  }
4634
- visitReadPropExpr(ast, ctx) {
4635
- ast.receiver.visitExpression(this, ctx);
4636
- ctx.print(ast, `.`);
4637
- ctx.print(ast, ast.name);
4638
- return null;
4486
+ }
4487
+ class TagPlaceholder {
4488
+ constructor(tag, attrs, startName, closeName, children, isVoid,
4489
+ // TODO sourceSpan should cover all (we need a startSourceSpan and endSourceSpan)
4490
+ sourceSpan, startSourceSpan, endSourceSpan) {
4491
+ this.tag = tag;
4492
+ this.attrs = attrs;
4493
+ this.startName = startName;
4494
+ this.closeName = closeName;
4495
+ this.children = children;
4496
+ this.isVoid = isVoid;
4497
+ this.sourceSpan = sourceSpan;
4498
+ this.startSourceSpan = startSourceSpan;
4499
+ this.endSourceSpan = endSourceSpan;
4639
4500
  }
4640
- visitReadKeyExpr(ast, ctx) {
4641
- ast.receiver.visitExpression(this, ctx);
4642
- ctx.print(ast, `[`);
4643
- ast.index.visitExpression(this, ctx);
4644
- ctx.print(ast, `]`);
4645
- return null;
4501
+ visit(visitor, context) {
4502
+ return visitor.visitTagPlaceholder(this, context);
4646
4503
  }
4647
- visitLiteralArrayExpr(ast, ctx) {
4648
- ctx.print(ast, `[`);
4649
- this.visitAllExpressions(ast.entries, ctx, ',');
4650
- ctx.print(ast, `]`);
4651
- return null;
4504
+ }
4505
+ class Placeholder {
4506
+ constructor(value, name, sourceSpan) {
4507
+ this.value = value;
4508
+ this.name = name;
4509
+ this.sourceSpan = sourceSpan;
4652
4510
  }
4653
- visitLiteralMapExpr(ast, ctx) {
4654
- ctx.print(ast, `{`);
4655
- this.visitAllObjects(entry => {
4656
- ctx.print(ast, `${escapeIdentifier(entry.key, this._escapeDollarInStrings, entry.quoted)}:`);
4657
- entry.value.visitExpression(this, ctx);
4658
- }, ast.entries, ctx, ',');
4659
- ctx.print(ast, `}`);
4660
- return null;
4511
+ visit(visitor, context) {
4512
+ return visitor.visitPlaceholder(this, context);
4661
4513
  }
4662
- visitCommaExpr(ast, ctx) {
4663
- ctx.print(ast, '(');
4664
- this.visitAllExpressions(ast.parts, ctx, ',');
4665
- ctx.print(ast, ')');
4666
- return null;
4514
+ }
4515
+ class IcuPlaceholder {
4516
+ constructor(value, name, sourceSpan) {
4517
+ this.value = value;
4518
+ this.name = name;
4519
+ this.sourceSpan = sourceSpan;
4667
4520
  }
4668
- visitAllExpressions(expressions, ctx, separator) {
4669
- this.visitAllObjects(expr => expr.visitExpression(this, ctx), expressions, ctx, separator);
4521
+ visit(visitor, context) {
4522
+ return visitor.visitIcuPlaceholder(this, context);
4670
4523
  }
4671
- visitAllObjects(handler, expressions, ctx, separator) {
4672
- let incrementedIndent = false;
4673
- for (let i = 0; i < expressions.length; i++) {
4674
- if (i > 0) {
4675
- if (ctx.lineLength() > 80) {
4676
- ctx.print(null, separator, true);
4677
- if (!incrementedIndent) {
4678
- // continuation are marked with double indent.
4679
- ctx.incIndent();
4680
- ctx.incIndent();
4681
- incrementedIndent = true;
4682
- }
4683
- }
4684
- else {
4685
- ctx.print(null, separator, false);
4686
- }
4687
- }
4688
- handler(expressions[i]);
4689
- }
4690
- if (incrementedIndent) {
4691
- // continuation are marked with double indent.
4692
- ctx.decIndent();
4693
- ctx.decIndent();
4694
- }
4524
+ }
4525
+ /**
4526
+ * Serialize the message to the Localize backtick string format that would appear in compiled code.
4527
+ */
4528
+ function serializeMessage(messageNodes) {
4529
+ const visitor = new LocalizeMessageStringVisitor();
4530
+ const str = messageNodes.map(n => n.visit(visitor)).join('');
4531
+ return str;
4532
+ }
4533
+ class LocalizeMessageStringVisitor {
4534
+ visitText(text) {
4535
+ return text.value;
4695
4536
  }
4696
- visitAllStatements(statements, ctx) {
4697
- statements.forEach((stmt) => stmt.visitStatement(this, ctx));
4537
+ visitContainer(container) {
4538
+ return container.children.map(child => child.visit(this)).join('');
4539
+ }
4540
+ visitIcu(icu) {
4541
+ const strCases = Object.keys(icu.cases).map((k) => `${k} {${icu.cases[k].visit(this)}}`);
4542
+ return `{${icu.expressionPlaceholder}, ${icu.type}, ${strCases.join(' ')}}`;
4543
+ }
4544
+ visitTagPlaceholder(ph) {
4545
+ const children = ph.children.map(child => child.visit(this)).join('');
4546
+ return `{$${ph.startName}}${children}{$${ph.closeName}}`;
4547
+ }
4548
+ visitPlaceholder(ph) {
4549
+ return `{$${ph.name}}`;
4550
+ }
4551
+ visitIcuPlaceholder(ph) {
4552
+ return `{$${ph.name}}`;
4698
4553
  }
4699
4554
  }
4700
- function escapeIdentifier(input, escapeDollar, alwaysQuote = true) {
4701
- if (input == null) {
4702
- return null;
4555
+
4556
+ /**
4557
+ * @license
4558
+ * Copyright Google LLC All Rights Reserved.
4559
+ *
4560
+ * Use of this source code is governed by an MIT-style license that can be
4561
+ * found in the LICENSE file at https://angular.io/license
4562
+ */
4563
+ // XMB/XTB placeholders can only contain A-Z, 0-9 and _
4564
+ function toPublicName(internalName) {
4565
+ return internalName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
4566
+ }
4567
+
4568
+ /**
4569
+ * @license
4570
+ * Copyright Google LLC All Rights Reserved.
4571
+ *
4572
+ * Use of this source code is governed by an MIT-style license that can be
4573
+ * found in the LICENSE file at https://angular.io/license
4574
+ */
4575
+ /* Closure variables holding messages must be named `MSG_[A-Z0-9]+` */
4576
+ const CLOSURE_TRANSLATION_VAR_PREFIX = 'MSG_';
4577
+ /**
4578
+ * Prefix for non-`goog.getMsg` i18n-related vars.
4579
+ * Note: the prefix uses lowercase characters intentionally due to a Closure behavior that
4580
+ * considers variables like `I18N_0` as constants and throws an error when their value changes.
4581
+ */
4582
+ const TRANSLATION_VAR_PREFIX = 'i18n_';
4583
+ /** Name of the i18n attributes **/
4584
+ const I18N_ATTR = 'i18n';
4585
+ const I18N_ATTR_PREFIX = 'i18n-';
4586
+ /** Prefix of var expressions used in ICUs */
4587
+ const I18N_ICU_VAR_PREFIX = 'VAR_';
4588
+ /** Prefix of ICU expressions for post processing */
4589
+ const I18N_ICU_MAPPING_PREFIX = 'I18N_EXP_';
4590
+ /** Placeholder wrapper for i18n expressions **/
4591
+ const I18N_PLACEHOLDER_SYMBOL = '�';
4592
+ function isI18nAttribute(name) {
4593
+ return name === I18N_ATTR || name.startsWith(I18N_ATTR_PREFIX);
4594
+ }
4595
+ function isI18nRootNode(meta) {
4596
+ return meta instanceof Message;
4597
+ }
4598
+ function isSingleI18nIcu(meta) {
4599
+ return isI18nRootNode(meta) && meta.nodes.length === 1 && meta.nodes[0] instanceof Icu;
4600
+ }
4601
+ function hasI18nMeta(node) {
4602
+ return !!node.i18n;
4603
+ }
4604
+ function hasI18nAttrs(element) {
4605
+ return element.attrs.some((attr) => isI18nAttribute(attr.name));
4606
+ }
4607
+ function icuFromI18nMessage(message) {
4608
+ return message.nodes[0];
4609
+ }
4610
+ function wrapI18nPlaceholder(content, contextId = 0) {
4611
+ const blockId = contextId > 0 ? `:${contextId}` : '';
4612
+ return `${I18N_PLACEHOLDER_SYMBOL}${content}${blockId}${I18N_PLACEHOLDER_SYMBOL}`;
4613
+ }
4614
+ function assembleI18nBoundString(strings, bindingStartIndex = 0, contextId = 0) {
4615
+ if (!strings.length)
4616
+ return '';
4617
+ let acc = '';
4618
+ const lastIdx = strings.length - 1;
4619
+ for (let i = 0; i < lastIdx; i++) {
4620
+ acc += `${strings[i]}${wrapI18nPlaceholder(bindingStartIndex + i, contextId)}`;
4703
4621
  }
4704
- const body = input.replace(_SINGLE_QUOTE_ESCAPE_STRING_RE, (...match) => {
4705
- if (match[0] == '$') {
4706
- return escapeDollar ? '\\$' : '$';
4707
- }
4708
- else if (match[0] == '\n') {
4709
- return '\\n';
4710
- }
4711
- else if (match[0] == '\r') {
4712
- return '\\r';
4713
- }
4714
- else {
4715
- return `\\${match[0]}`;
4716
- }
4622
+ acc += strings[lastIdx];
4623
+ return acc;
4624
+ }
4625
+ function getSeqNumberGenerator(startsAt = 0) {
4626
+ let current = startsAt;
4627
+ return () => current++;
4628
+ }
4629
+ function placeholdersToParams(placeholders) {
4630
+ const params = {};
4631
+ placeholders.forEach((values, key) => {
4632
+ params[key] = literal$1(values.length > 1 ? `[${values.join('|')}]` : values[0]);
4717
4633
  });
4718
- const requiresQuotes = alwaysQuote || !_LEGAL_IDENTIFIER_RE.test(body);
4719
- return requiresQuotes ? `'${body}'` : body;
4634
+ return params;
4720
4635
  }
4721
- function _createIndent(count) {
4722
- let res = '';
4723
- for (let i = 0; i < count; i++) {
4724
- res += _INDENT_WITH;
4636
+ function updatePlaceholderMap(map, name, ...values) {
4637
+ const current = map.get(name) || [];
4638
+ current.push(...values);
4639
+ map.set(name, current);
4640
+ }
4641
+ function assembleBoundTextPlaceholders(meta, bindingStartIndex = 0, contextId = 0) {
4642
+ const startIdx = bindingStartIndex;
4643
+ const placeholders = new Map();
4644
+ const node = meta instanceof Message ? meta.nodes.find(node => node instanceof Container) : meta;
4645
+ if (node) {
4646
+ node
4647
+ .children
4648
+ .filter((child) => child instanceof Placeholder)
4649
+ .forEach((child, idx) => {
4650
+ const content = wrapI18nPlaceholder(startIdx + idx, contextId);
4651
+ updatePlaceholderMap(placeholders, child.name, content);
4652
+ });
4653
+ }
4654
+ return placeholders;
4655
+ }
4656
+ /**
4657
+ * Format the placeholder names in a map of placeholders to expressions.
4658
+ *
4659
+ * The placeholder names are converted from "internal" format (e.g. `START_TAG_DIV_1`) to "external"
4660
+ * format (e.g. `startTagDiv_1`).
4661
+ *
4662
+ * @param params A map of placeholder names to expressions.
4663
+ * @param useCamelCase whether to camelCase the placeholder name when formatting.
4664
+ * @returns A new map of formatted placeholder names to expressions.
4665
+ */
4666
+ function i18nFormatPlaceholderNames(params = {}, useCamelCase) {
4667
+ const _params = {};
4668
+ if (params && Object.keys(params).length) {
4669
+ Object.keys(params).forEach(key => _params[formatI18nPlaceholderName(key, useCamelCase)] = params[key]);
4670
+ }
4671
+ return _params;
4672
+ }
4673
+ /**
4674
+ * Converts internal placeholder names to public-facing format
4675
+ * (for example to use in goog.getMsg call).
4676
+ * Example: `START_TAG_DIV_1` is converted to `startTagDiv_1`.
4677
+ *
4678
+ * @param name The placeholder name that should be formatted
4679
+ * @returns Formatted placeholder name
4680
+ */
4681
+ function formatI18nPlaceholderName(name, useCamelCase = true) {
4682
+ const publicName = toPublicName(name);
4683
+ if (!useCamelCase) {
4684
+ return publicName;
4685
+ }
4686
+ const chunks = publicName.split('_');
4687
+ if (chunks.length === 1) {
4688
+ // if no "_" found - just lowercase the value
4689
+ return name.toLowerCase();
4690
+ }
4691
+ let postfix;
4692
+ // eject last element if it's a number
4693
+ if (/^\d+$/.test(chunks[chunks.length - 1])) {
4694
+ postfix = chunks.pop();
4725
4695
  }
4726
- return res;
4696
+ let raw = chunks.shift().toLowerCase();
4697
+ if (chunks.length) {
4698
+ raw += chunks.map(c => c.charAt(0).toUpperCase() + c.slice(1).toLowerCase()).join('');
4699
+ }
4700
+ return postfix ? `${raw}_${postfix}` : raw;
4701
+ }
4702
+ /**
4703
+ * Generates a prefix for translation const name.
4704
+ *
4705
+ * @param extra Additional local prefix that should be injected into translation var name
4706
+ * @returns Complete translation const prefix
4707
+ */
4708
+ function getTranslationConstPrefix(extra) {
4709
+ return `${CLOSURE_TRANSLATION_VAR_PREFIX}${extra}`.toUpperCase();
4710
+ }
4711
+ /**
4712
+ * Generate AST to declare a variable. E.g. `var I18N_1;`.
4713
+ * @param variable the name of the variable to declare.
4714
+ */
4715
+ function declareI18nVariable(variable) {
4716
+ return new DeclareVarStmt(variable.name, undefined, INFERRED_TYPE, undefined, variable.sourceSpan);
4727
4717
  }
4728
4718
 
4729
4719
  /**
@@ -4733,242 +4723,205 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4733
4723
  * Use of this source code is governed by an MIT-style license that can be
4734
4724
  * found in the LICENSE file at https://angular.io/license
4735
4725
  */
4736
- function typeWithParameters(type, numParams) {
4737
- if (numParams === 0) {
4738
- return expressionType(type);
4739
- }
4740
- const params = [];
4741
- for (let i = 0; i < numParams; i++) {
4742
- params.push(DYNAMIC_TYPE);
4743
- }
4744
- return expressionType(type, undefined, params);
4745
- }
4746
- const ANIMATE_SYMBOL_PREFIX = '@';
4747
- function prepareSyntheticPropertyName(name) {
4748
- return `${ANIMATE_SYMBOL_PREFIX}${name}`;
4749
- }
4750
- function prepareSyntheticListenerName(name, phase) {
4751
- return `${ANIMATE_SYMBOL_PREFIX}${name}.${phase}`;
4752
- }
4753
- function getSafePropertyAccessString(accessor, name) {
4754
- const escapedName = escapeIdentifier(name, false, false);
4755
- return escapedName !== name ? `${accessor}[${escapedName}]` : `${accessor}.${name}`;
4756
- }
4757
- function prepareSyntheticListenerFunctionName(name, phase) {
4758
- return `animation_${name}_${phase}`;
4726
+ /**
4727
+ * Checks whether an object key contains potentially unsafe chars, thus the key should be wrapped in
4728
+ * quotes. Note: we do not wrap all keys into quotes, as it may have impact on minification and may
4729
+ * bot work in some cases when object keys are mangled by minifier.
4730
+ *
4731
+ * TODO(FW-1136): this is a temporary solution, we need to come up with a better way of working with
4732
+ * inputs that contain potentially unsafe chars.
4733
+ */
4734
+ const UNSAFE_OBJECT_KEY_NAME_REGEXP = /[-.]/;
4735
+ /** Name of the temporary to use during data binding */
4736
+ const TEMPORARY_NAME = '_t';
4737
+ /** Name of the context parameter passed into a template function */
4738
+ const CONTEXT_NAME = 'ctx';
4739
+ /** Name of the RenderFlag passed into a template function */
4740
+ const RENDER_FLAGS = 'rf';
4741
+ /** The prefix reference variables */
4742
+ const REFERENCE_PREFIX = '_r';
4743
+ /** The name of the implicit context reference */
4744
+ const IMPLICIT_REFERENCE = '$implicit';
4745
+ /** Non bindable attribute name **/
4746
+ const NON_BINDABLE_ATTR = 'ngNonBindable';
4747
+ /** Name for the variable keeping track of the context returned by `ɵɵrestoreView`. */
4748
+ const RESTORED_VIEW_CONTEXT_NAME = 'restoredCtx';
4749
+ /**
4750
+ * Creates an allocator for a temporary variable.
4751
+ *
4752
+ * A variable declaration is added to the statements the first time the allocator is invoked.
4753
+ */
4754
+ function temporaryAllocator(statements, name) {
4755
+ let temp = null;
4756
+ return () => {
4757
+ if (!temp) {
4758
+ statements.push(new DeclareVarStmt(TEMPORARY_NAME, undefined, DYNAMIC_TYPE));
4759
+ temp = variable(name);
4760
+ }
4761
+ return temp;
4762
+ };
4759
4763
  }
4760
- function jitOnlyGuardedExpression(expr) {
4761
- return guardedExpression('ngJitMode', expr);
4764
+ function unsupported(feature) {
4765
+ if (this) {
4766
+ throw new Error(`Builder ${this.constructor.name} doesn't support ${feature} yet`);
4767
+ }
4768
+ throw new Error(`Feature ${feature} is not supported yet`);
4762
4769
  }
4763
- function devOnlyGuardedExpression(expr) {
4764
- return guardedExpression('ngDevMode', expr);
4770
+ function invalid(arg) {
4771
+ throw new Error(`Invalid state: Visitor ${this.constructor.name} doesn't handle ${arg.constructor.name}`);
4765
4772
  }
4766
- function guardedExpression(guard, expr) {
4767
- const guardExpr = new ExternalExpr({ name: guard, moduleName: null });
4768
- const guardNotDefined = new BinaryOperatorExpr(BinaryOperator.Identical, new TypeofExpr(guardExpr), literal$1('undefined'));
4769
- const guardUndefinedOrTrue = new BinaryOperatorExpr(BinaryOperator.Or, guardNotDefined, guardExpr, /* type */ undefined,
4770
- /* sourceSpan */ undefined, true);
4771
- return new BinaryOperatorExpr(BinaryOperator.And, guardUndefinedOrTrue, expr);
4773
+ function asLiteral(value) {
4774
+ if (Array.isArray(value)) {
4775
+ return literalArr(value.map(asLiteral));
4776
+ }
4777
+ return literal$1(value, INFERRED_TYPE);
4772
4778
  }
4773
- function wrapReference(value) {
4774
- const wrapped = new WrappedNodeExpr(value);
4775
- return { value: wrapped, type: wrapped };
4779
+ function conditionallyCreateMapObjectLiteral(keys, keepDeclared) {
4780
+ if (Object.getOwnPropertyNames(keys).length > 0) {
4781
+ return mapToExpression(keys, keepDeclared);
4782
+ }
4783
+ return null;
4776
4784
  }
4777
- function refsToArray(refs, shouldForwardDeclare) {
4778
- const values = literalArr(refs.map(ref => ref.value));
4779
- return shouldForwardDeclare ? fn([], [new ReturnStatement(values)]) : values;
4785
+ function mapToExpression(map, keepDeclared) {
4786
+ return literalMap(Object.getOwnPropertyNames(map).map(key => {
4787
+ // canonical syntax: `dirProp: publicProp`
4788
+ // if there is no `:`, use dirProp = elProp
4789
+ const value = map[key];
4790
+ let declaredName;
4791
+ let publicName;
4792
+ let minifiedName;
4793
+ let needsDeclaredName;
4794
+ if (Array.isArray(value)) {
4795
+ [publicName, declaredName] = value;
4796
+ minifiedName = key;
4797
+ needsDeclaredName = publicName !== declaredName;
4798
+ }
4799
+ else {
4800
+ [declaredName, publicName] = splitAtColon(key, [key, value]);
4801
+ minifiedName = declaredName;
4802
+ // Only include the declared name if extracted from the key, i.e. the key contains a colon.
4803
+ // Otherwise the declared name should be omitted even if it is different from the public name,
4804
+ // as it may have already been minified.
4805
+ needsDeclaredName = publicName !== declaredName && key.includes(':');
4806
+ }
4807
+ return {
4808
+ key: minifiedName,
4809
+ // put quotes around keys that contain potentially unsafe characters
4810
+ quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(minifiedName),
4811
+ value: (keepDeclared && needsDeclaredName) ?
4812
+ literalArr([asLiteral(publicName), asLiteral(declaredName)]) :
4813
+ asLiteral(publicName)
4814
+ };
4815
+ }));
4780
4816
  }
4781
-
4782
- var R3FactoryDelegateType;
4783
- (function (R3FactoryDelegateType) {
4784
- R3FactoryDelegateType[R3FactoryDelegateType["Class"] = 0] = "Class";
4785
- R3FactoryDelegateType[R3FactoryDelegateType["Function"] = 1] = "Function";
4786
- })(R3FactoryDelegateType || (R3FactoryDelegateType = {}));
4787
- var FactoryTarget$1;
4788
- (function (FactoryTarget) {
4789
- FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
4790
- FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
4791
- FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
4792
- FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
4793
- FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
4794
- })(FactoryTarget$1 || (FactoryTarget$1 = {}));
4795
4817
  /**
4796
- * Construct a factory function expression for the given `R3FactoryMetadata`.
4818
+ * Remove trailing null nodes as they are implied.
4797
4819
  */
4798
- function compileFactoryFunction(meta) {
4799
- const t = variable('t');
4800
- let baseFactoryVar = null;
4801
- // The type to instantiate via constructor invocation. If there is no delegated factory, meaning
4802
- // this type is always created by constructor invocation, then this is the type-to-create
4803
- // parameter provided by the user (t) if specified, or the current type if not. If there is a
4804
- // delegated factory (which is used to create the current type) then this is only the type-to-
4805
- // create parameter (t).
4806
- const typeForCtor = !isDelegatedFactoryMetadata(meta) ?
4807
- new BinaryOperatorExpr(BinaryOperator.Or, t, meta.internalType) :
4808
- t;
4809
- let ctorExpr = null;
4810
- if (meta.deps !== null) {
4811
- // There is a constructor (either explicitly or implicitly defined).
4812
- if (meta.deps !== 'invalid') {
4813
- ctorExpr = new InstantiateExpr(typeForCtor, injectDependencies(meta.deps, meta.target));
4814
- }
4815
- }
4816
- else {
4817
- // There is no constructor, use the base class' factory to construct typeForCtor.
4818
- baseFactoryVar = variable(`ɵ${meta.name}_BaseFactory`);
4819
- ctorExpr = baseFactoryVar.callFn([typeForCtor]);
4820
- }
4821
- const body = [];
4822
- let retExpr = null;
4823
- function makeConditionalFactory(nonCtorExpr) {
4824
- const r = variable('r');
4825
- body.push(r.set(NULL_EXPR).toDeclStmt());
4826
- const ctorStmt = ctorExpr !== null ? r.set(ctorExpr).toStmt() :
4827
- importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt();
4828
- body.push(ifStmt(t, [ctorStmt], [r.set(nonCtorExpr).toStmt()]));
4829
- return r;
4830
- }
4831
- if (isDelegatedFactoryMetadata(meta)) {
4832
- // This type is created with a delegated factory. If a type parameter is not specified, call
4833
- // the factory instead.
4834
- const delegateArgs = injectDependencies(meta.delegateDeps, meta.target);
4835
- // Either call `new delegate(...)` or `delegate(...)` depending on meta.delegateType.
4836
- const factoryExpr = new (meta.delegateType === R3FactoryDelegateType.Class ?
4837
- InstantiateExpr :
4838
- InvokeFunctionExpr)(meta.delegate, delegateArgs);
4839
- retExpr = makeConditionalFactory(factoryExpr);
4820
+ function trimTrailingNulls(parameters) {
4821
+ while (isNull(parameters[parameters.length - 1])) {
4822
+ parameters.pop();
4840
4823
  }
4841
- else if (isExpressionFactoryMetadata(meta)) {
4842
- // TODO(alxhub): decide whether to lower the value here or in the caller
4843
- retExpr = makeConditionalFactory(meta.expression);
4824
+ return parameters;
4825
+ }
4826
+ function getQueryPredicate(query, constantPool) {
4827
+ if (Array.isArray(query.predicate)) {
4828
+ let predicate = [];
4829
+ query.predicate.forEach((selector) => {
4830
+ // Each item in predicates array may contain strings with comma-separated refs
4831
+ // (for ex. 'ref, ref1, ..., refN'), thus we extract individual refs and store them
4832
+ // as separate array entities
4833
+ const selectors = selector.split(',').map(token => literal$1(token.trim()));
4834
+ predicate.push(...selectors);
4835
+ });
4836
+ return constantPool.getConstLiteral(literalArr(predicate), true);
4844
4837
  }
4845
4838
  else {
4846
- retExpr = ctorExpr;
4847
- }
4848
- if (retExpr === null) {
4849
- // The expression cannot be formed so render an `ɵɵinvalidFactory()` call.
4850
- body.push(importExpr(Identifiers$1.invalidFactory).callFn([]).toStmt());
4839
+ // The original predicate may have been wrapped in a `forwardRef()` call.
4840
+ switch (query.predicate.forwardRef) {
4841
+ case 0 /* None */:
4842
+ case 2 /* Unwrapped */:
4843
+ return query.predicate.expression;
4844
+ case 1 /* Wrapped */:
4845
+ return importExpr(Identifiers$1.resolveForwardRef).callFn([query.predicate.expression]);
4846
+ }
4851
4847
  }
4852
- else if (baseFactoryVar !== null) {
4853
- // This factory uses a base factory, so call `ɵɵgetInheritedFactory()` to compute it.
4854
- const getInheritedFactoryCall = importExpr(Identifiers$1.getInheritedFactory).callFn([meta.internalType]);
4855
- // Memoize the base factoryFn: `baseFactory || (baseFactory = ɵɵgetInheritedFactory(...))`
4856
- const baseFactory = new BinaryOperatorExpr(BinaryOperator.Or, baseFactoryVar, baseFactoryVar.set(getInheritedFactoryCall));
4857
- body.push(new ReturnStatement(baseFactory.callFn([typeForCtor])));
4848
+ }
4849
+ /**
4850
+ * A representation for an object literal used during codegen of definition objects. The generic
4851
+ * type `T` allows to reference a documented type of the generated structure, such that the
4852
+ * property names that are set can be resolved to their documented declaration.
4853
+ */
4854
+ class DefinitionMap {
4855
+ constructor() {
4856
+ this.values = [];
4858
4857
  }
4859
- else {
4860
- // This is straightforward factory, just return it.
4861
- body.push(new ReturnStatement(retExpr));
4858
+ set(key, value) {
4859
+ if (value) {
4860
+ this.values.push({ key: key, value, quoted: false });
4861
+ }
4862
4862
  }
4863
- let factoryFn = fn([new FnParam('t', DYNAMIC_TYPE)], body, INFERRED_TYPE, undefined, `${meta.name}_Factory`);
4864
- if (baseFactoryVar !== null) {
4865
- // There is a base factory variable so wrap its declaration along with the factory function into
4866
- // an IIFE.
4867
- factoryFn = fn([], [
4868
- new DeclareVarStmt(baseFactoryVar.name), new ReturnStatement(factoryFn)
4869
- ]).callFn([], /* sourceSpan */ undefined, /* pure */ true);
4863
+ toLiteralMap() {
4864
+ return literalMap(this.values);
4870
4865
  }
4871
- return {
4872
- expression: factoryFn,
4873
- statements: [],
4874
- type: createFactoryType(meta),
4875
- };
4876
- }
4877
- function createFactoryType(meta) {
4878
- const ctorDepsType = meta.deps !== null && meta.deps !== 'invalid' ? createCtorDepsType(meta.deps) : NONE_TYPE;
4879
- return expressionType(importExpr(Identifiers$1.FactoryDeclaration, [typeWithParameters(meta.type.type, meta.typeArgumentCount), ctorDepsType]));
4880
- }
4881
- function injectDependencies(deps, target) {
4882
- return deps.map((dep, index) => compileInjectDependency(dep, target, index));
4883
4866
  }
4884
- function compileInjectDependency(dep, target, index) {
4885
- // Interpret the dependency according to its resolved type.
4886
- if (dep.token === null) {
4887
- return importExpr(Identifiers$1.invalidFactoryDep).callFn([literal$1(index)]);
4888
- }
4889
- else if (dep.attributeNameType === null) {
4890
- // Build up the injection flags according to the metadata.
4891
- const flags = 0 /* Default */ | (dep.self ? 2 /* Self */ : 0) |
4892
- (dep.skipSelf ? 4 /* SkipSelf */ : 0) | (dep.host ? 1 /* Host */ : 0) |
4893
- (dep.optional ? 8 /* Optional */ : 0) |
4894
- (target === FactoryTarget$1.Pipe ? 16 /* ForPipe */ : 0);
4895
- // If this dependency is optional or otherwise has non-default flags, then additional
4896
- // parameters describing how to inject the dependency must be passed to the inject function
4897
- // that's being used.
4898
- let flagsParam = (flags !== 0 /* Default */ || dep.optional) ? literal$1(flags) : null;
4899
- // Build up the arguments to the injectFn call.
4900
- const injectArgs = [dep.token];
4901
- if (flagsParam) {
4902
- injectArgs.push(flagsParam);
4903
- }
4904
- const injectFn = getInjectFn(target);
4905
- return importExpr(injectFn).callFn(injectArgs);
4867
+ /**
4868
+ * Extract a map of properties to values for a given element or template node, which can be used
4869
+ * by the directive matching machinery.
4870
+ *
4871
+ * @param elOrTpl the element or template in question
4872
+ * @return an object set up for directive matching. For attributes on the element/template, this
4873
+ * object maps a property name to its (static) value. For any bindings, this map simply maps the
4874
+ * property name to an empty string.
4875
+ */
4876
+ function getAttrsForDirectiveMatching(elOrTpl) {
4877
+ const attributesMap = {};
4878
+ if (elOrTpl instanceof Template && elOrTpl.tagName !== 'ng-template') {
4879
+ elOrTpl.templateAttrs.forEach(a => attributesMap[a.name] = '');
4906
4880
  }
4907
4881
  else {
4908
- // The `dep.attributeTypeName` value is defined, which indicates that this is an `@Attribute()`
4909
- // type dependency. For the generated JS we still want to use the `dep.token` value in case the
4910
- // name given for the attribute is not a string literal. For example given `@Attribute(foo())`,
4911
- // we want to generate `ɵɵinjectAttribute(foo())`.
4912
- //
4913
- // The `dep.attributeTypeName` is only actually used (in `createCtorDepType()`) to generate
4914
- // typings.
4915
- return importExpr(Identifiers$1.injectAttribute).callFn([dep.token]);
4882
+ elOrTpl.attributes.forEach(a => {
4883
+ if (!isI18nAttribute(a.name)) {
4884
+ attributesMap[a.name] = a.value;
4885
+ }
4886
+ });
4887
+ elOrTpl.inputs.forEach(i => {
4888
+ attributesMap[i.name] = '';
4889
+ });
4890
+ elOrTpl.outputs.forEach(o => {
4891
+ attributesMap[o.name] = '';
4892
+ });
4916
4893
  }
4894
+ return attributesMap;
4917
4895
  }
4918
- function createCtorDepsType(deps) {
4919
- let hasTypes = false;
4920
- const attributeTypes = deps.map(dep => {
4921
- const type = createCtorDepType(dep);
4922
- if (type !== null) {
4923
- hasTypes = true;
4924
- return type;
4925
- }
4926
- else {
4927
- return literal$1(null);
4896
+ /** Returns a call expression to a chained instruction, e.g. `property(params[0])(params[1])`. */
4897
+ function chainedInstruction(reference, calls, span) {
4898
+ let expression = importExpr(reference, null, span);
4899
+ if (calls.length > 0) {
4900
+ for (let i = 0; i < calls.length; i++) {
4901
+ expression = expression.callFn(calls[i], span);
4928
4902
  }
4929
- });
4930
- if (hasTypes) {
4931
- return expressionType(literalArr(attributeTypes));
4932
4903
  }
4933
4904
  else {
4934
- return NONE_TYPE;
4905
+ // Add a blank invocation, in case the `calls` array is empty.
4906
+ expression = expression.callFn([], span);
4935
4907
  }
4908
+ return expression;
4936
4909
  }
4937
- function createCtorDepType(dep) {
4938
- const entries = [];
4939
- if (dep.attributeNameType !== null) {
4940
- entries.push({ key: 'attribute', value: dep.attributeNameType, quoted: false });
4941
- }
4942
- if (dep.optional) {
4943
- entries.push({ key: 'optional', value: literal$1(true), quoted: false });
4944
- }
4945
- if (dep.host) {
4946
- entries.push({ key: 'host', value: literal$1(true), quoted: false });
4947
- }
4948
- if (dep.self) {
4949
- entries.push({ key: 'self', value: literal$1(true), quoted: false });
4950
- }
4951
- if (dep.skipSelf) {
4952
- entries.push({ key: 'skipSelf', value: literal$1(true), quoted: false });
4910
+ /**
4911
+ * Gets the number of arguments expected to be passed to a generated instruction in the case of
4912
+ * interpolation instructions.
4913
+ * @param interpolation An interpolation ast
4914
+ */
4915
+ function getInterpolationArgsLength(interpolation) {
4916
+ const { expressions, strings } = interpolation;
4917
+ if (expressions.length === 1 && strings.length === 2 && strings[0] === '' && strings[1] === '') {
4918
+ // If the interpolation has one interpolated value, but the prefix and suffix are both empty
4919
+ // strings, we only pass one argument, to a special instruction like `propertyInterpolate` or
4920
+ // `textInterpolate`.
4921
+ return 1;
4953
4922
  }
4954
- return entries.length > 0 ? literalMap(entries) : null;
4955
- }
4956
- function isDelegatedFactoryMetadata(meta) {
4957
- return meta.delegateType !== undefined;
4958
- }
4959
- function isExpressionFactoryMetadata(meta) {
4960
- return meta.expression !== undefined;
4961
- }
4962
- function getInjectFn(target) {
4963
- switch (target) {
4964
- case FactoryTarget$1.Component:
4965
- case FactoryTarget$1.Directive:
4966
- case FactoryTarget$1.Pipe:
4967
- return Identifiers$1.directiveInject;
4968
- case FactoryTarget$1.NgModule:
4969
- case FactoryTarget$1.Injectable:
4970
- default:
4971
- return Identifiers$1.inject;
4923
+ else {
4924
+ return expressions.length + strings.length;
4972
4925
  }
4973
4926
  }
4974
4927
 
@@ -4979,9 +4932,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
4979
4932
  * Use of this source code is governed by an MIT-style license that can be
4980
4933
  * found in the LICENSE file at https://angular.io/license
4981
4934
  */
4982
- function createR3ProviderExpression(expression, isForwardRef) {
4983
- return { expression, isForwardRef };
4984
- }
4985
4935
  function compileInjectable(meta, resolveForwardRefs) {
4986
4936
  let result = null;
4987
4937
  const factoryMeta = {
@@ -5067,8 +5017,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
5067
5017
  injectableProps.set('factory', result.expression);
5068
5018
  // Only generate providedIn property if it has a non-null value
5069
5019
  if (meta.providedIn.expression.value !== null) {
5070
- injectableProps.set('providedIn', meta.providedIn.isForwardRef ? generateForwardRef(meta.providedIn.expression) :
5071
- meta.providedIn.expression);
5020
+ injectableProps.set('providedIn', convertFromMaybeForwardRefExpression(meta.providedIn));
5072
5021
  }
5073
5022
  const expression = importExpr(Identifiers$1.ɵɵdefineInjectable)
5074
5023
  .callFn([injectableProps.toLiteralMap()], undefined, true);
@@ -7482,6 +7431,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
7482
7431
  Statement: ${ast.uninterpretedExpression} located at ${ast.location}`);
7483
7432
  }
7484
7433
  visitCall(ast, mode) {
7434
+ const leftMostSafe = this.leftMostSafeNode(ast);
7435
+ if (leftMostSafe) {
7436
+ return this.convertSafeAccess(ast, leftMostSafe, mode);
7437
+ }
7485
7438
  const convertedArgs = this.visitAll(ast.args, _Mode.Expression);
7486
7439
  if (ast instanceof BuiltinFunctionCall) {
7487
7440
  return convertToStatementIfNeeded(mode, ast.converter(convertedArgs));
@@ -7496,10 +7449,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
7496
7449
  return convertToStatementIfNeeded(mode, convertedArgs[0]
7497
7450
  .cast(DYNAMIC_TYPE, this.convertSourceSpan(ast.span)));
7498
7451
  }
7499
- const leftMostSafe = this.leftMostSafeNode(ast);
7500
- if (leftMostSafe) {
7501
- return this.convertSafeAccess(ast, leftMostSafe, mode);
7502
- }
7503
7452
  const call = this._visit(receiver, _Mode.Expression)
7504
7453
  .callFn(convertedArgs, this.convertSourceSpan(ast.span));
7505
7454
  return convertToStatementIfNeeded(mode, call);
@@ -19842,8 +19791,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19842
19791
  function convertToR3QueryMetadata(facade) {
19843
19792
  return {
19844
19793
  ...facade,
19845
- predicate: Array.isArray(facade.predicate) ? facade.predicate :
19846
- new WrappedNodeExpr(facade.predicate),
19794
+ predicate: convertQueryPredicate(facade.predicate),
19847
19795
  read: facade.read ? new WrappedNodeExpr(facade.read) : null,
19848
19796
  static: facade.static,
19849
19797
  emitDistinctChangesOnly: facade.emitDistinctChangesOnly,
@@ -19853,14 +19801,20 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19853
19801
  return {
19854
19802
  propertyName: declaration.propertyName,
19855
19803
  first: declaration.first ?? false,
19856
- predicate: Array.isArray(declaration.predicate) ? declaration.predicate :
19857
- new WrappedNodeExpr(declaration.predicate),
19804
+ predicate: convertQueryPredicate(declaration.predicate),
19858
19805
  descendants: declaration.descendants ?? false,
19859
19806
  read: declaration.read ? new WrappedNodeExpr(declaration.read) : null,
19860
19807
  static: declaration.static ?? false,
19861
19808
  emitDistinctChangesOnly: declaration.emitDistinctChangesOnly ?? true,
19862
19809
  };
19863
19810
  }
19811
+ function convertQueryPredicate(predicate) {
19812
+ return Array.isArray(predicate) ?
19813
+ // The predicate is an array of strings so pass it through.
19814
+ predicate :
19815
+ // The predicate is a type - assume that we will need to unwrap any `forwardRef()` calls.
19816
+ createMayBeForwardRefExpression(new WrappedNodeExpr(predicate), 1 /* Wrapped */);
19817
+ }
19864
19818
  function convertDirectiveFacadeToMetadata(facade) {
19865
19819
  const inputsFromMetadata = parseInputOutputs(facade.inputs || []);
19866
19820
  const outputsFromMetadata = parseInputOutputs(facade.outputs || []);
@@ -19982,7 +19936,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19982
19936
  function parseJitTemplate(template, typeName, sourceMapUrl, preserveWhitespaces, interpolation) {
19983
19937
  const interpolationConfig = interpolation ? InterpolationConfig.fromArray(interpolation) : DEFAULT_INTERPOLATION_CONFIG;
19984
19938
  // Parse the template and check for errors.
19985
- const parsed = parseTemplate(template, sourceMapUrl, { preserveWhitespaces: preserveWhitespaces, interpolationConfig });
19939
+ const parsed = parseTemplate(template, sourceMapUrl, { preserveWhitespaces, interpolationConfig });
19986
19940
  if (parsed.errors !== null) {
19987
19941
  const errors = parsed.errors.map(err => err.toString()).join(', ');
19988
19942
  throw new Error(`Errors during JIT compilation of template for ${typeName}: ${errors}`);
@@ -19995,11 +19949,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
19995
19949
  * In JIT mode we do not want the compiler to wrap the expression in a `forwardRef()` call because,
19996
19950
  * if it is referencing a type that has not yet been defined, it will have already been wrapped in
19997
19951
  * a `forwardRef()` - either by the application developer or during partial-compilation. Thus we can
19998
- * set `isForwardRef` to `false`.
19952
+ * use `ForwardRefHandling.None`.
19999
19953
  */
20000
19954
  function convertToProviderExpression(obj, property) {
20001
19955
  if (obj.hasOwnProperty(property)) {
20002
- return createR3ProviderExpression(new WrappedNodeExpr(obj[property]), /* isForwardRef */ false);
19956
+ return createMayBeForwardRefExpression(new WrappedNodeExpr(obj[property]), 0 /* None */);
20003
19957
  }
20004
19958
  else {
20005
19959
  return undefined;
@@ -20014,11 +19968,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20014
19968
  }
20015
19969
  }
20016
19970
  function computeProvidedIn(providedIn) {
20017
- const expression = (providedIn == null || typeof providedIn === 'string') ?
20018
- new LiteralExpr(providedIn ?? null) :
20019
- new WrappedNodeExpr(providedIn);
20020
- // See `convertToProviderExpression()` for why `isForwardRef` is false.
20021
- return createR3ProviderExpression(expression, /* isForwardRef */ false);
19971
+ const expression = typeof providedIn === 'function' ? new WrappedNodeExpr(providedIn) :
19972
+ new LiteralExpr(providedIn ?? null);
19973
+ // See `convertToProviderExpression()` for why this uses `ForwardRefHandling.None`.
19974
+ return createMayBeForwardRefExpression(expression, 0 /* None */);
20022
19975
  }
20023
19976
  function convertR3DependencyMetadataArray(facades) {
20024
19977
  return facades == null ? null : facades.map(convertR3DependencyMetadata);
@@ -20124,7 +20077,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20124
20077
  * Use of this source code is governed by an MIT-style license that can be
20125
20078
  * found in the LICENSE file at https://angular.io/license
20126
20079
  */
20127
- new Version('13.1.0-next.0');
20080
+ new Version('13.1.0-next.1');
20128
20081
 
20129
20082
  /**
20130
20083
  * @license
@@ -20753,7 +20706,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20753
20706
  function compileDeclareClassMetadata(metadata) {
20754
20707
  const definitionMap = new DefinitionMap();
20755
20708
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$6));
20756
- definitionMap.set('version', literal$1('13.1.0-next.0'));
20709
+ definitionMap.set('version', literal$1('13.1.0-next.1'));
20757
20710
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
20758
20711
  definitionMap.set('type', metadata.type);
20759
20712
  definitionMap.set('decorators', metadata.decorators);
@@ -20762,6 +20715,83 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20762
20715
  return importExpr(Identifiers$1.declareClassMetadata).callFn([definitionMap.toLiteralMap()]);
20763
20716
  }
20764
20717
 
20718
+ /**
20719
+ * @license
20720
+ * Copyright Google LLC All Rights Reserved.
20721
+ *
20722
+ * Use of this source code is governed by an MIT-style license that can be
20723
+ * found in the LICENSE file at https://angular.io/license
20724
+ */
20725
+ /**
20726
+ * Creates an array literal expression from the given array, mapping all values to an expression
20727
+ * using the provided mapping function. If the array is empty or null, then null is returned.
20728
+ *
20729
+ * @param values The array to transfer into literal array expression.
20730
+ * @param mapper The logic to use for creating an expression for the array's values.
20731
+ * @returns An array literal expression representing `values`, or null if `values` is empty or
20732
+ * is itself null.
20733
+ */
20734
+ function toOptionalLiteralArray(values, mapper) {
20735
+ if (values === null || values.length === 0) {
20736
+ return null;
20737
+ }
20738
+ return literalArr(values.map(value => mapper(value)));
20739
+ }
20740
+ /**
20741
+ * Creates an object literal expression from the given object, mapping all values to an expression
20742
+ * using the provided mapping function. If the object has no keys, then null is returned.
20743
+ *
20744
+ * @param object The object to transfer into an object literal expression.
20745
+ * @param mapper The logic to use for creating an expression for the object's values.
20746
+ * @returns An object literal expression representing `object`, or null if `object` does not have
20747
+ * any keys.
20748
+ */
20749
+ function toOptionalLiteralMap(object, mapper) {
20750
+ const entries = Object.keys(object).map(key => {
20751
+ const value = object[key];
20752
+ return { key, value: mapper(value), quoted: true };
20753
+ });
20754
+ if (entries.length > 0) {
20755
+ return literalMap(entries);
20756
+ }
20757
+ else {
20758
+ return null;
20759
+ }
20760
+ }
20761
+ function compileDependencies(deps) {
20762
+ if (deps === 'invalid') {
20763
+ // The `deps` can be set to the string "invalid" by the `unwrapConstructorDependencies()`
20764
+ // function, which tries to convert `ConstructorDeps` into `R3DependencyMetadata[]`.
20765
+ return literal$1('invalid');
20766
+ }
20767
+ else if (deps === null) {
20768
+ return literal$1(null);
20769
+ }
20770
+ else {
20771
+ return literalArr(deps.map(compileDependency));
20772
+ }
20773
+ }
20774
+ function compileDependency(dep) {
20775
+ const depMeta = new DefinitionMap();
20776
+ depMeta.set('token', dep.token);
20777
+ if (dep.attributeNameType !== null) {
20778
+ depMeta.set('attribute', literal$1(true));
20779
+ }
20780
+ if (dep.host) {
20781
+ depMeta.set('host', literal$1(true));
20782
+ }
20783
+ if (dep.optional) {
20784
+ depMeta.set('optional', literal$1(true));
20785
+ }
20786
+ if (dep.self) {
20787
+ depMeta.set('self', literal$1(true));
20788
+ }
20789
+ if (dep.skipSelf) {
20790
+ depMeta.set('skipSelf', literal$1(true));
20791
+ }
20792
+ return depMeta.toLiteralMap();
20793
+ }
20794
+
20765
20795
  /**
20766
20796
  * @license
20767
20797
  * Copyright Google LLC All Rights Reserved.
@@ -20793,7 +20823,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20793
20823
  function createDirectiveDefinitionMap(meta) {
20794
20824
  const definitionMap = new DefinitionMap();
20795
20825
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$5));
20796
- definitionMap.set('version', literal$1('13.1.0-next.0'));
20826
+ definitionMap.set('version', literal$1('13.1.0-next.1'));
20797
20827
  // e.g. `type: MyDirective`
20798
20828
  definitionMap.set('type', meta.internalType);
20799
20829
  // e.g. `selector: 'some-dir'`
@@ -20832,7 +20862,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
20832
20862
  if (query.first) {
20833
20863
  meta.set('first', literal$1(true));
20834
20864
  }
20835
- meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) : query.predicate);
20865
+ meta.set('predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) :
20866
+ convertFromMaybeForwardRefExpression(query.predicate));
20836
20867
  if (!query.emitDistinctChangesOnly) {
20837
20868
  // `emitDistinctChangesOnly` is special because we expect it to be `true`.
20838
20869
  // Therefore we explicitly emit the field, and explicitly place it only when it's `false`.
@@ -21010,7 +21041,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21010
21041
  function compileDeclareFactoryFunction(meta) {
21011
21042
  const definitionMap = new DefinitionMap();
21012
21043
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$4));
21013
- definitionMap.set('version', literal$1('13.1.0-next.0'));
21044
+ definitionMap.set('version', literal$1('13.1.0-next.1'));
21014
21045
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21015
21046
  definitionMap.set('type', meta.internalType);
21016
21047
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -21052,24 +21083,24 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21052
21083
  function createInjectableDefinitionMap(meta) {
21053
21084
  const definitionMap = new DefinitionMap();
21054
21085
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$3));
21055
- definitionMap.set('version', literal$1('13.1.0-next.0'));
21086
+ definitionMap.set('version', literal$1('13.1.0-next.1'));
21056
21087
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21057
21088
  definitionMap.set('type', meta.internalType);
21058
21089
  // Only generate providedIn property if it has a non-null value
21059
21090
  if (meta.providedIn !== undefined) {
21060
- const providedIn = convertFromProviderExpression(meta.providedIn);
21091
+ const providedIn = convertFromMaybeForwardRefExpression(meta.providedIn);
21061
21092
  if (providedIn.value !== null) {
21062
21093
  definitionMap.set('providedIn', providedIn);
21063
21094
  }
21064
21095
  }
21065
21096
  if (meta.useClass !== undefined) {
21066
- definitionMap.set('useClass', convertFromProviderExpression(meta.useClass));
21097
+ definitionMap.set('useClass', convertFromMaybeForwardRefExpression(meta.useClass));
21067
21098
  }
21068
21099
  if (meta.useExisting !== undefined) {
21069
- definitionMap.set('useExisting', convertFromProviderExpression(meta.useExisting));
21100
+ definitionMap.set('useExisting', convertFromMaybeForwardRefExpression(meta.useExisting));
21070
21101
  }
21071
21102
  if (meta.useValue !== undefined) {
21072
- definitionMap.set('useValue', convertFromProviderExpression(meta.useValue));
21103
+ definitionMap.set('useValue', convertFromMaybeForwardRefExpression(meta.useValue));
21073
21104
  }
21074
21105
  // Factories do not contain `ForwardRef`s since any types are already wrapped in a function call
21075
21106
  // so the types will not be eagerly evaluated. Therefore we do not need to process this expression
@@ -21082,27 +21113,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21082
21113
  }
21083
21114
  return definitionMap;
21084
21115
  }
21085
- /**
21086
- * Convert an `R3ProviderExpression` to an `Expression`, possibly wrapping its expression in a
21087
- * `forwardRef()` call.
21088
- *
21089
- * If `R3ProviderExpression.isForwardRef` is true then the expression was originally wrapped in a
21090
- * `forwardRef()` call to prevent the value from being eagerly evaluated in the code.
21091
- *
21092
- * Normally, the linker will statically process the code, putting the `expression` inside a factory
21093
- * function so the `forwardRef()` wrapper is not evaluated before it has been defined. But if the
21094
- * partial declaration is evaluated by the JIT compiler the `forwardRef()` call is still needed to
21095
- * prevent eager evaluation of the `expression`.
21096
- *
21097
- * So in partial declarations, expressions that could be forward-refs are wrapped in `forwardRef()`
21098
- * calls, and this is then unwrapped in the linker as necessary.
21099
- *
21100
- * See `packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts` and
21101
- * `packages/compiler/src/jit_compiler_facade.ts` for more information.
21102
- */
21103
- function convertFromProviderExpression({ expression, isForwardRef }) {
21104
- return isForwardRef ? generateForwardRef(expression) : expression;
21105
- }
21106
21116
 
21107
21117
  /**
21108
21118
  * @license
@@ -21131,7 +21141,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21131
21141
  function createInjectorDefinitionMap(meta) {
21132
21142
  const definitionMap = new DefinitionMap();
21133
21143
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$2));
21134
- definitionMap.set('version', literal$1('13.1.0-next.0'));
21144
+ definitionMap.set('version', literal$1('13.1.0-next.1'));
21135
21145
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21136
21146
  definitionMap.set('type', meta.internalType);
21137
21147
  definitionMap.set('providers', meta.providers);
@@ -21168,7 +21178,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21168
21178
  function createNgModuleDefinitionMap(meta) {
21169
21179
  const definitionMap = new DefinitionMap();
21170
21180
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION$1));
21171
- definitionMap.set('version', literal$1('13.1.0-next.0'));
21181
+ definitionMap.set('version', literal$1('13.1.0-next.1'));
21172
21182
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21173
21183
  definitionMap.set('type', meta.internalType);
21174
21184
  // We only generate the keys in the metadata if the arrays contain values.
@@ -21226,7 +21236,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21226
21236
  function createPipeDefinitionMap(meta) {
21227
21237
  const definitionMap = new DefinitionMap();
21228
21238
  definitionMap.set('minVersion', literal$1(MINIMUM_PARTIAL_LINKER_VERSION));
21229
- definitionMap.set('version', literal$1('13.1.0-next.0'));
21239
+ definitionMap.set('version', literal$1('13.1.0-next.1'));
21230
21240
  definitionMap.set('ngImport', importExpr(Identifiers$1.core));
21231
21241
  // e.g. `type: MyPipe`
21232
21242
  definitionMap.set('type', meta.internalType);
@@ -21258,7 +21268,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
21258
21268
  * Use of this source code is governed by an MIT-style license that can be
21259
21269
  * found in the LICENSE file at https://angular.io/license
21260
21270
  */
21261
- new Version('13.1.0-next.0');
21271
+ new Version('13.1.0-next.1');
21262
21272
 
21263
21273
  /**
21264
21274
  * @license
@@ -29507,7 +29517,8 @@ Either add the @Injectable() decorator to '${provider.node.name
29507
29517
  throw new FatalDiagnosticError(ErrorCode.DECORATOR_ARITY_WRONG, exprNode, `@${name} must have arguments`);
29508
29518
  }
29509
29519
  const first = name === 'ViewChild' || name === 'ContentChild';
29510
- const node = tryUnwrapForwardRef(args[0], reflector) ?? args[0];
29520
+ const forwardReferenceTarget = tryUnwrapForwardRef(args[0], reflector);
29521
+ const node = forwardReferenceTarget ?? args[0];
29511
29522
  const arg = evaluator.evaluate(node);
29512
29523
  /** Whether or not this query should collect only static results (see view/api.ts) */
29513
29524
  let isStatic = false;
@@ -29515,7 +29526,7 @@ Either add the @Injectable() decorator to '${provider.node.name
29515
29526
  let predicate = null;
29516
29527
  if (arg instanceof Reference || arg instanceof DynamicValue) {
29517
29528
  // References and predicates that could not be evaluated statically are emitted as is.
29518
- predicate = new WrappedNodeExpr(node);
29529
+ predicate = createMayBeForwardRefExpression(new WrappedNodeExpr(node), forwardReferenceTarget !== null ? 2 /* Unwrapped */ : 0 /* None */);
29519
29530
  }
29520
29531
  else if (typeof arg === 'string') {
29521
29532
  predicate = [arg];
@@ -31581,7 +31592,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31581
31592
  type,
31582
31593
  typeArgumentCount,
31583
31594
  internalType,
31584
- providedIn: createR3ProviderExpression(new LiteralExpr(null), false),
31595
+ providedIn: createMayBeForwardRefExpression(new LiteralExpr(null), 0 /* None */),
31585
31596
  };
31586
31597
  }
31587
31598
  else if (decorator.args.length === 1) {
@@ -31596,7 +31607,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31596
31607
  const meta = reflectObjectLiteral(metaNode);
31597
31608
  const providedIn = meta.has('providedIn') ?
31598
31609
  getProviderExpression(meta.get('providedIn'), reflector) :
31599
- createR3ProviderExpression(new LiteralExpr(null), false);
31610
+ createMayBeForwardRefExpression(new LiteralExpr(null), 0 /* None */);
31600
31611
  let deps = undefined;
31601
31612
  if ((meta.has('useClass') || meta.has('useFactory')) && meta.has('deps')) {
31602
31613
  const depsExpr = meta.get('deps');
@@ -31635,7 +31646,7 @@ Either add the @Injectable() decorator to '${provider.node.name
31635
31646
  */
31636
31647
  function getProviderExpression(expression, reflector) {
31637
31648
  const forwardRefValue = tryUnwrapForwardRef(expression, reflector);
31638
- return createR3ProviderExpression(new WrappedNodeExpr(forwardRefValue ?? expression), forwardRefValue !== null);
31649
+ return createMayBeForwardRefExpression(new WrappedNodeExpr(forwardRefValue ?? expression), forwardRefValue !== null ? 2 /* Unwrapped */ : 0 /* None */);
31639
31650
  }
31640
31651
  function extractInjectableCtorDeps(clazz, meta, decorator, reflector, isCore, strictCtorDeps) {
31641
31652
  if (decorator.args === null) {
@@ -37294,17 +37305,7 @@ Either add the @Injectable() decorator to '${provider.node.name
37294
37305
  const inputs = getBoundInputs(this.dir, this.node, this.tcb);
37295
37306
  for (const input of inputs) {
37296
37307
  // For bound inputs, the property is assigned the binding expression.
37297
- let expr = translateInput(input.attribute, this.tcb, this.scope);
37298
- if (!this.tcb.env.config.checkTypeOfInputBindings) {
37299
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
37300
- // before the assignment.
37301
- expr = tsCastToAny(expr);
37302
- }
37303
- else if (!this.tcb.env.config.strictNullInputBindings) {
37304
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
37305
- // wrapping the expression in a non-null assertion.
37306
- expr = ts__default["default"].createNonNullExpression(expr);
37307
- }
37308
+ const expr = widenBinding(translateInput(input.attribute, this.tcb, this.scope), this.tcb);
37308
37309
  let assignment = wrapForDiagnostics(expr);
37309
37310
  for (const fieldName of input.fieldNames) {
37310
37311
  let target;
@@ -37493,17 +37494,7 @@ Either add the @Injectable() decorator to '${provider.node.name
37493
37494
  // Skip this binding as it was claimed by a directive.
37494
37495
  continue;
37495
37496
  }
37496
- let expr = tcbExpression(binding.value, this.tcb, this.scope);
37497
- if (!this.tcb.env.config.checkTypeOfInputBindings) {
37498
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
37499
- // before the assignment.
37500
- expr = tsCastToAny(expr);
37501
- }
37502
- else if (!this.tcb.env.config.strictNullInputBindings) {
37503
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
37504
- // wrapping the expression in a non-null assertion.
37505
- expr = ts__default["default"].createNonNullExpression(expr);
37506
- }
37497
+ const expr = widenBinding(tcbExpression(binding.value, this.tcb, this.scope), this.tcb);
37507
37498
  if (this.tcb.env.config.checkTypeOfDomBindings && binding.type === 0 /* Property */) {
37508
37499
  if (binding.name !== 'style' && binding.name !== 'class') {
37509
37500
  if (elId === null) {
@@ -38317,17 +38308,7 @@ Either add the @Injectable() decorator to '${provider.node.name
38317
38308
  const propertyName = ts__default["default"].createStringLiteral(input.field);
38318
38309
  if (input.type === 'binding') {
38319
38310
  // For bound inputs, the property is assigned the binding expression.
38320
- let expr = input.expression;
38321
- if (!tcb.env.config.checkTypeOfInputBindings) {
38322
- // If checking the type of bindings is disabled, cast the resulting expression to 'any'
38323
- // before the assignment.
38324
- expr = tsCastToAny(expr);
38325
- }
38326
- else if (!tcb.env.config.strictNullInputBindings) {
38327
- // If strict null checks are disabled, erase `null` and `undefined` from the type by
38328
- // wrapping the expression in a non-null assertion.
38329
- expr = ts__default["default"].createNonNullExpression(expr);
38330
- }
38311
+ const expr = widenBinding(input.expression, tcb);
38331
38312
  const assignment = ts__default["default"].createPropertyAssignment(propertyName, wrapForDiagnostics(expr));
38332
38313
  addParseSpanInfo(assignment, input.sourceSpan);
38333
38314
  return assignment;
@@ -38380,6 +38361,33 @@ Either add the @Injectable() decorator to '${provider.node.name
38380
38361
  return ts__default["default"].createStringLiteral(attr.value);
38381
38362
  }
38382
38363
  }
38364
+ /**
38365
+ * Potentially widens the type of `expr` according to the type-checking configuration.
38366
+ */
38367
+ function widenBinding(expr, tcb) {
38368
+ if (!tcb.env.config.checkTypeOfInputBindings) {
38369
+ // If checking the type of bindings is disabled, cast the resulting expression to 'any'
38370
+ // before the assignment.
38371
+ return tsCastToAny(expr);
38372
+ }
38373
+ else if (!tcb.env.config.strictNullInputBindings) {
38374
+ if (ts__default["default"].isObjectLiteralExpression(expr) || ts__default["default"].isArrayLiteralExpression(expr)) {
38375
+ // Object literals and array literals should not be wrapped in non-null assertions as that
38376
+ // would cause literals to be prematurely widened, resulting in type errors when assigning
38377
+ // into a literal type.
38378
+ return expr;
38379
+ }
38380
+ else {
38381
+ // If strict null checks are disabled, erase `null` and `undefined` from the type by
38382
+ // wrapping the expression in a non-null assertion.
38383
+ return ts__default["default"].createNonNullExpression(expr);
38384
+ }
38385
+ }
38386
+ else {
38387
+ // No widening is requested, use the expression as is.
38388
+ return expr;
38389
+ }
38390
+ }
38383
38391
  const EVENT_PARAMETER = '$event';
38384
38392
  /**
38385
38393
  * Creates an arrow function to be used as handler function for event bindings. The handler
@@ -45411,7 +45419,7 @@ https://angular.io/guide/ivy for more information.
45411
45419
  if (scriptInfo.scriptKind === ts__namespace.ScriptKind.External) {
45412
45420
  // script info for typecheck file is marked as external, see
45413
45421
  // getOrCreateTypeCheckScriptInfo() in
45414
- // packages/language-service/ivy/language_service.ts
45422
+ // packages/language-service/src/language_service.ts
45415
45423
  typecheckFiles.push(scriptInfo.fileName);
45416
45424
  }
45417
45425
  }