@angular/language-service 13.0.0-next.3 → 13.0.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/ivy.js +764 -733
- package/bundles/language-service.js +546 -1430
- package/package.json +1 -1
package/bundles/ivy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular v13.0.0-next.
|
|
2
|
+
* @license Angular v13.0.0-next.7
|
|
3
3
|
* Copyright Google LLC All Rights Reserved.
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -1193,9 +1193,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
1193
1193
|
key(index, type, sourceSpan) {
|
|
1194
1194
|
return new ReadKeyExpr(this, index, type, sourceSpan);
|
|
1195
1195
|
}
|
|
1196
|
-
callMethod(name, params, sourceSpan) {
|
|
1197
|
-
return new InvokeMethodExpr(this, name, params, null, sourceSpan);
|
|
1198
|
-
}
|
|
1199
1196
|
callFn(params, sourceSpan, pure) {
|
|
1200
1197
|
return new InvokeFunctionExpr(this, params, null, sourceSpan, pure);
|
|
1201
1198
|
}
|
|
@@ -1397,31 +1394,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
1397
1394
|
BuiltinMethod[BuiltinMethod["SubscribeObservable"] = 1] = "SubscribeObservable";
|
|
1398
1395
|
BuiltinMethod[BuiltinMethod["Bind"] = 2] = "Bind";
|
|
1399
1396
|
})(BuiltinMethod || (BuiltinMethod = {}));
|
|
1400
|
-
class InvokeMethodExpr extends Expression {
|
|
1401
|
-
constructor(receiver, method, args, type, sourceSpan) {
|
|
1402
|
-
super(type, sourceSpan);
|
|
1403
|
-
this.receiver = receiver;
|
|
1404
|
-
this.args = args;
|
|
1405
|
-
if (typeof method === 'string') {
|
|
1406
|
-
this.name = method;
|
|
1407
|
-
this.builtin = null;
|
|
1408
|
-
}
|
|
1409
|
-
else {
|
|
1410
|
-
this.name = null;
|
|
1411
|
-
this.builtin = method;
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
isEquivalent(e) {
|
|
1415
|
-
return e instanceof InvokeMethodExpr && this.receiver.isEquivalent(e.receiver) &&
|
|
1416
|
-
this.name === e.name && this.builtin === e.builtin && areAllEquivalent(this.args, e.args);
|
|
1417
|
-
}
|
|
1418
|
-
isConstant() {
|
|
1419
|
-
return false;
|
|
1420
|
-
}
|
|
1421
|
-
visitExpression(visitor, context) {
|
|
1422
|
-
return visitor.visitInvokeMethodExpr(this, context);
|
|
1423
|
-
}
|
|
1424
|
-
}
|
|
1425
1397
|
class InvokeFunctionExpr extends Expression {
|
|
1426
1398
|
constructor(fn, args, type, sourceSpan, pure = false) {
|
|
1427
1399
|
super(type, sourceSpan);
|
|
@@ -2298,7 +2270,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
2298
2270
|
this.visitWriteVarExpr = invalid;
|
|
2299
2271
|
this.visitWriteKeyExpr = invalid;
|
|
2300
2272
|
this.visitWritePropExpr = invalid;
|
|
2301
|
-
this.visitInvokeMethodExpr = invalid;
|
|
2302
2273
|
this.visitInvokeFunctionExpr = invalid;
|
|
2303
2274
|
this.visitTaggedTemplateExpr = invalid;
|
|
2304
2275
|
this.visitInstantiateExpr = invalid;
|
|
@@ -4395,21 +4366,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
4395
4366
|
}
|
|
4396
4367
|
return null;
|
|
4397
4368
|
}
|
|
4398
|
-
visitInvokeMethodExpr(expr, ctx) {
|
|
4399
|
-
expr.receiver.visitExpression(this, ctx);
|
|
4400
|
-
let name = expr.name;
|
|
4401
|
-
if (expr.builtin != null) {
|
|
4402
|
-
name = this.getBuiltinMethodName(expr.builtin);
|
|
4403
|
-
if (name == null) {
|
|
4404
|
-
// some builtins just mean to skip the call.
|
|
4405
|
-
return null;
|
|
4406
|
-
}
|
|
4407
|
-
}
|
|
4408
|
-
ctx.print(expr, `.${name}(`);
|
|
4409
|
-
this.visitAllExpressions(expr.args, ctx, `,`);
|
|
4410
|
-
ctx.print(expr, `)`);
|
|
4411
|
-
return null;
|
|
4412
|
-
}
|
|
4413
4369
|
visitInvokeFunctionExpr(expr, ctx) {
|
|
4414
4370
|
expr.fn.visitExpression(this, ctx);
|
|
4415
4371
|
ctx.print(expr, `(`);
|
|
@@ -5051,7 +5007,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
5051
5007
|
return createFactoryFunction(unwrappedType);
|
|
5052
5008
|
}
|
|
5053
5009
|
function createFactoryFunction(type) {
|
|
5054
|
-
return fn([new FnParam('t', DYNAMIC_TYPE)], [new ReturnStatement(type.
|
|
5010
|
+
return fn([new FnParam('t', DYNAMIC_TYPE)], [new ReturnStatement(type.prop('ɵfac').callFn([variable('t')]))]);
|
|
5055
5011
|
}
|
|
5056
5012
|
|
|
5057
5013
|
/**
|
|
@@ -6384,38 +6340,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
6384
6340
|
return visitor.visitNonNullAssert(this, context);
|
|
6385
6341
|
}
|
|
6386
6342
|
}
|
|
6387
|
-
class
|
|
6388
|
-
constructor(span, sourceSpan,
|
|
6389
|
-
super(span, sourceSpan
|
|
6390
|
-
this.receiver = receiver;
|
|
6391
|
-
this.name = name;
|
|
6392
|
-
this.args = args;
|
|
6393
|
-
this.argumentSpan = argumentSpan;
|
|
6394
|
-
}
|
|
6395
|
-
visit(visitor, context = null) {
|
|
6396
|
-
return visitor.visitMethodCall(this, context);
|
|
6397
|
-
}
|
|
6398
|
-
}
|
|
6399
|
-
class SafeMethodCall extends ASTWithName {
|
|
6400
|
-
constructor(span, sourceSpan, nameSpan, receiver, name, args, argumentSpan) {
|
|
6401
|
-
super(span, sourceSpan, nameSpan);
|
|
6343
|
+
class Call extends AST {
|
|
6344
|
+
constructor(span, sourceSpan, receiver, args, argumentSpan) {
|
|
6345
|
+
super(span, sourceSpan);
|
|
6402
6346
|
this.receiver = receiver;
|
|
6403
|
-
this.name = name;
|
|
6404
6347
|
this.args = args;
|
|
6405
6348
|
this.argumentSpan = argumentSpan;
|
|
6406
6349
|
}
|
|
6407
6350
|
visit(visitor, context = null) {
|
|
6408
|
-
return visitor.
|
|
6409
|
-
}
|
|
6410
|
-
}
|
|
6411
|
-
class FunctionCall extends AST {
|
|
6412
|
-
constructor(span, sourceSpan, target, args) {
|
|
6413
|
-
super(span, sourceSpan);
|
|
6414
|
-
this.target = target;
|
|
6415
|
-
this.args = args;
|
|
6416
|
-
}
|
|
6417
|
-
visit(visitor, context = null) {
|
|
6418
|
-
return visitor.visitFunctionCall(this, context);
|
|
6351
|
+
return visitor.visitCall(this, context);
|
|
6419
6352
|
}
|
|
6420
6353
|
}
|
|
6421
6354
|
/**
|
|
@@ -6501,12 +6434,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
6501
6434
|
this.visit(ast.exp, context);
|
|
6502
6435
|
this.visitAll(ast.args, context);
|
|
6503
6436
|
}
|
|
6504
|
-
visitFunctionCall(ast, context) {
|
|
6505
|
-
if (ast.target) {
|
|
6506
|
-
this.visit(ast.target, context);
|
|
6507
|
-
}
|
|
6508
|
-
this.visitAll(ast.args, context);
|
|
6509
|
-
}
|
|
6510
6437
|
visitImplicitReceiver(ast, context) { }
|
|
6511
6438
|
visitThisReceiver(ast, context) { }
|
|
6512
6439
|
visitInterpolation(ast, context) {
|
|
@@ -6528,10 +6455,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
6528
6455
|
this.visitAll(ast.values, context);
|
|
6529
6456
|
}
|
|
6530
6457
|
visitLiteralPrimitive(ast, context) { }
|
|
6531
|
-
visitMethodCall(ast, context) {
|
|
6532
|
-
this.visit(ast.receiver, context);
|
|
6533
|
-
this.visitAll(ast.args, context);
|
|
6534
|
-
}
|
|
6535
6458
|
visitPrefixNot(ast, context) {
|
|
6536
6459
|
this.visit(ast.expression, context);
|
|
6537
6460
|
}
|
|
@@ -6548,14 +6471,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
6548
6471
|
visitSafePropertyRead(ast, context) {
|
|
6549
6472
|
this.visit(ast.receiver, context);
|
|
6550
6473
|
}
|
|
6551
|
-
visitSafeMethodCall(ast, context) {
|
|
6552
|
-
this.visit(ast.receiver, context);
|
|
6553
|
-
this.visitAll(ast.args, context);
|
|
6554
|
-
}
|
|
6555
6474
|
visitSafeKeyedRead(ast, context) {
|
|
6556
6475
|
this.visit(ast.receiver, context);
|
|
6557
6476
|
this.visit(ast.key, context);
|
|
6558
6477
|
}
|
|
6478
|
+
visitCall(ast, context) {
|
|
6479
|
+
this.visit(ast.receiver, context);
|
|
6480
|
+
this.visitAll(ast.args, context);
|
|
6481
|
+
}
|
|
6559
6482
|
visitQuote(ast, context) { }
|
|
6560
6483
|
// This is not part of the AstVisitor interface, just a helper method
|
|
6561
6484
|
visitAll(asts, context) {
|
|
@@ -6586,15 +6509,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
6586
6509
|
visitSafePropertyRead(ast, context) {
|
|
6587
6510
|
return new SafePropertyRead(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name);
|
|
6588
6511
|
}
|
|
6589
|
-
visitMethodCall(ast, context) {
|
|
6590
|
-
return new MethodCall(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name, this.visitAll(ast.args), ast.argumentSpan);
|
|
6591
|
-
}
|
|
6592
|
-
visitSafeMethodCall(ast, context) {
|
|
6593
|
-
return new SafeMethodCall(ast.span, ast.sourceSpan, ast.nameSpan, ast.receiver.visit(this), ast.name, this.visitAll(ast.args), ast.argumentSpan);
|
|
6594
|
-
}
|
|
6595
|
-
visitFunctionCall(ast, context) {
|
|
6596
|
-
return new FunctionCall(ast.span, ast.sourceSpan, ast.target.visit(this), this.visitAll(ast.args));
|
|
6597
|
-
}
|
|
6598
6512
|
visitLiteralArray(ast, context) {
|
|
6599
6513
|
return new LiteralArray(ast.span, ast.sourceSpan, this.visitAll(ast.expressions));
|
|
6600
6514
|
}
|
|
@@ -6632,6 +6546,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
6632
6546
|
visitKeyedWrite(ast, context) {
|
|
6633
6547
|
return new KeyedWrite(ast.span, ast.sourceSpan, ast.receiver.visit(this), ast.key.visit(this), ast.value.visit(this));
|
|
6634
6548
|
}
|
|
6549
|
+
visitCall(ast, context) {
|
|
6550
|
+
return new Call(ast.span, ast.sourceSpan, ast.receiver.visit(this), this.visitAll(ast.args), ast.argumentSpan);
|
|
6551
|
+
}
|
|
6635
6552
|
visitAll(asts) {
|
|
6636
6553
|
const res = [];
|
|
6637
6554
|
for (let i = 0; i < asts.length; ++i) {
|
|
@@ -6689,30 +6606,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
6689
6606
|
}
|
|
6690
6607
|
return ast;
|
|
6691
6608
|
}
|
|
6692
|
-
visitMethodCall(ast, context) {
|
|
6693
|
-
const receiver = ast.receiver.visit(this);
|
|
6694
|
-
const args = this.visitAll(ast.args);
|
|
6695
|
-
if (receiver !== ast.receiver || args !== ast.args) {
|
|
6696
|
-
return new MethodCall(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name, args, ast.argumentSpan);
|
|
6697
|
-
}
|
|
6698
|
-
return ast;
|
|
6699
|
-
}
|
|
6700
|
-
visitSafeMethodCall(ast, context) {
|
|
6701
|
-
const receiver = ast.receiver.visit(this);
|
|
6702
|
-
const args = this.visitAll(ast.args);
|
|
6703
|
-
if (receiver !== ast.receiver || args !== ast.args) {
|
|
6704
|
-
return new SafeMethodCall(ast.span, ast.sourceSpan, ast.nameSpan, receiver, ast.name, args, ast.argumentSpan);
|
|
6705
|
-
}
|
|
6706
|
-
return ast;
|
|
6707
|
-
}
|
|
6708
|
-
visitFunctionCall(ast, context) {
|
|
6709
|
-
const target = ast.target && ast.target.visit(this);
|
|
6710
|
-
const args = this.visitAll(ast.args);
|
|
6711
|
-
if (target !== ast.target || args !== ast.args) {
|
|
6712
|
-
return new FunctionCall(ast.span, ast.sourceSpan, target, args);
|
|
6713
|
-
}
|
|
6714
|
-
return ast;
|
|
6715
|
-
}
|
|
6716
6609
|
visitLiteralArray(ast, context) {
|
|
6717
6610
|
const expressions = this.visitAll(ast.expressions);
|
|
6718
6611
|
if (expressions !== ast.expressions) {
|
|
@@ -6815,6 +6708,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
6815
6708
|
}
|
|
6816
6709
|
return ast;
|
|
6817
6710
|
}
|
|
6711
|
+
visitCall(ast, context) {
|
|
6712
|
+
const receiver = ast.receiver.visit(this);
|
|
6713
|
+
const args = this.visitAll(ast.args);
|
|
6714
|
+
if (receiver !== ast.receiver || args !== ast.args) {
|
|
6715
|
+
return new Call(ast.span, ast.sourceSpan, receiver, args, ast.argumentSpan);
|
|
6716
|
+
}
|
|
6717
|
+
return ast;
|
|
6718
|
+
}
|
|
6818
6719
|
visitQuote(ast, context) {
|
|
6819
6720
|
return ast;
|
|
6820
6721
|
}
|
|
@@ -7341,18 +7242,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7341
7242
|
visitPipe(ast, mode) {
|
|
7342
7243
|
throw new Error(`Illegal state: Pipes should have been converted into functions. Pipe: ${ast.name}`);
|
|
7343
7244
|
}
|
|
7344
|
-
visitFunctionCall(ast, mode) {
|
|
7345
|
-
const convertedArgs = this.visitAll(ast.args, _Mode.Expression);
|
|
7346
|
-
let fnResult;
|
|
7347
|
-
if (ast instanceof BuiltinFunctionCall) {
|
|
7348
|
-
fnResult = ast.converter(convertedArgs);
|
|
7349
|
-
}
|
|
7350
|
-
else {
|
|
7351
|
-
fnResult = this._visit(ast.target, _Mode.Expression)
|
|
7352
|
-
.callFn(convertedArgs, this.convertSourceSpan(ast.span));
|
|
7353
|
-
}
|
|
7354
|
-
return convertToStatementIfNeeded(mode, fnResult);
|
|
7355
|
-
}
|
|
7356
7245
|
visitImplicitReceiver(ast, mode) {
|
|
7357
7246
|
ensureExpressionMode(mode, ast);
|
|
7358
7247
|
this.usesImplicitReceiver = true;
|
|
@@ -7417,40 +7306,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7417
7306
|
}
|
|
7418
7307
|
return this._localResolver.getLocal(name);
|
|
7419
7308
|
}
|
|
7420
|
-
visitMethodCall(ast, mode) {
|
|
7421
|
-
if (ast.receiver instanceof ImplicitReceiver &&
|
|
7422
|
-
!(ast.receiver instanceof ThisReceiver) && ast.name === '$any') {
|
|
7423
|
-
const args = this.visitAll(ast.args, _Mode.Expression);
|
|
7424
|
-
if (args.length != 1) {
|
|
7425
|
-
throw new Error(`Invalid call to $any, expected 1 argument but received ${args.length || 'none'}`);
|
|
7426
|
-
}
|
|
7427
|
-
return args[0].cast(DYNAMIC_TYPE, this.convertSourceSpan(ast.span));
|
|
7428
|
-
}
|
|
7429
|
-
const leftMostSafe = this.leftMostSafeNode(ast);
|
|
7430
|
-
if (leftMostSafe) {
|
|
7431
|
-
return this.convertSafeAccess(ast, leftMostSafe, mode);
|
|
7432
|
-
}
|
|
7433
|
-
else {
|
|
7434
|
-
const args = this.visitAll(ast.args, _Mode.Expression);
|
|
7435
|
-
const prevUsesImplicitReceiver = this.usesImplicitReceiver;
|
|
7436
|
-
let result = null;
|
|
7437
|
-
const receiver = this._visit(ast.receiver, _Mode.Expression);
|
|
7438
|
-
if (receiver === this._implicitReceiver) {
|
|
7439
|
-
const varExpr = this._getLocal(ast.name, ast.receiver);
|
|
7440
|
-
if (varExpr) {
|
|
7441
|
-
// Restore the previous "usesImplicitReceiver" state since the implicit
|
|
7442
|
-
// receiver has been replaced with a resolved local expression.
|
|
7443
|
-
this.usesImplicitReceiver = prevUsesImplicitReceiver;
|
|
7444
|
-
result = varExpr.callFn(args);
|
|
7445
|
-
this.addImplicitReceiverAccess(ast.name);
|
|
7446
|
-
}
|
|
7447
|
-
}
|
|
7448
|
-
if (result == null) {
|
|
7449
|
-
result = receiver.callMethod(ast.name, args, this.convertSourceSpan(ast.span));
|
|
7450
|
-
}
|
|
7451
|
-
return convertToStatementIfNeeded(mode, result);
|
|
7452
|
-
}
|
|
7453
|
-
}
|
|
7454
7309
|
visitPrefixNot(ast, mode) {
|
|
7455
7310
|
return convertToStatementIfNeeded(mode, not(this._visit(ast.expression, _Mode.Expression)));
|
|
7456
7311
|
}
|
|
@@ -7476,7 +7331,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7476
7331
|
}
|
|
7477
7332
|
}
|
|
7478
7333
|
if (result == null) {
|
|
7479
|
-
result = receiver.prop(ast.name);
|
|
7334
|
+
result = receiver.prop(ast.name, this.convertSourceSpan(ast.span));
|
|
7480
7335
|
}
|
|
7481
7336
|
return convertToStatementIfNeeded(mode, result);
|
|
7482
7337
|
}
|
|
@@ -7509,16 +7364,13 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7509
7364
|
// If no local expression could be produced, use the original receiver's
|
|
7510
7365
|
// property as the target.
|
|
7511
7366
|
if (varExpr === null) {
|
|
7512
|
-
varExpr = receiver.prop(ast.name);
|
|
7367
|
+
varExpr = receiver.prop(ast.name, this.convertSourceSpan(ast.span));
|
|
7513
7368
|
}
|
|
7514
7369
|
return convertToStatementIfNeeded(mode, varExpr.set(this._visit(ast.value, _Mode.Expression)));
|
|
7515
7370
|
}
|
|
7516
7371
|
visitSafePropertyRead(ast, mode) {
|
|
7517
7372
|
return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
|
|
7518
7373
|
}
|
|
7519
|
-
visitSafeMethodCall(ast, mode) {
|
|
7520
|
-
return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
|
|
7521
|
-
}
|
|
7522
7374
|
visitSafeKeyedRead(ast, mode) {
|
|
7523
7375
|
return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
|
|
7524
7376
|
}
|
|
@@ -7529,6 +7381,29 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7529
7381
|
throw new Error(`Quotes are not supported for evaluation!
|
|
7530
7382
|
Statement: ${ast.uninterpretedExpression} located at ${ast.location}`);
|
|
7531
7383
|
}
|
|
7384
|
+
visitCall(ast, mode) {
|
|
7385
|
+
const convertedArgs = this.visitAll(ast.args, _Mode.Expression);
|
|
7386
|
+
if (ast instanceof BuiltinFunctionCall) {
|
|
7387
|
+
return convertToStatementIfNeeded(mode, ast.converter(convertedArgs));
|
|
7388
|
+
}
|
|
7389
|
+
const receiver = ast.receiver;
|
|
7390
|
+
if (receiver instanceof PropertyRead &&
|
|
7391
|
+
receiver.receiver instanceof ImplicitReceiver &&
|
|
7392
|
+
!(receiver.receiver instanceof ThisReceiver) && receiver.name === '$any') {
|
|
7393
|
+
if (convertedArgs.length !== 1) {
|
|
7394
|
+
throw new Error(`Invalid call to $any, expected 1 argument but received ${convertedArgs.length || 'none'}`);
|
|
7395
|
+
}
|
|
7396
|
+
return convertedArgs[0]
|
|
7397
|
+
.cast(DYNAMIC_TYPE, this.convertSourceSpan(ast.span));
|
|
7398
|
+
}
|
|
7399
|
+
const leftMostSafe = this.leftMostSafeNode(ast);
|
|
7400
|
+
if (leftMostSafe) {
|
|
7401
|
+
return this.convertSafeAccess(ast, leftMostSafe, mode);
|
|
7402
|
+
}
|
|
7403
|
+
const call = this._visit(receiver, _Mode.Expression)
|
|
7404
|
+
.callFn(convertedArgs, this.convertSourceSpan(ast.span));
|
|
7405
|
+
return convertToStatementIfNeeded(mode, call);
|
|
7406
|
+
}
|
|
7532
7407
|
_visit(ast, mode) {
|
|
7533
7408
|
const result = this._resultMap.get(ast);
|
|
7534
7409
|
if (result)
|
|
@@ -7585,10 +7460,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7585
7460
|
const condition = guardedExpression.isBlank();
|
|
7586
7461
|
// Convert the ast to an unguarded access to the receiver's member. The map will substitute
|
|
7587
7462
|
// leftMostNode with its unguarded version in the call to `this.visit()`.
|
|
7588
|
-
if (leftMostSafe instanceof
|
|
7589
|
-
this._nodeMap.set(leftMostSafe, new MethodCall(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.nameSpan, leftMostSafe.receiver, leftMostSafe.name, leftMostSafe.args, leftMostSafe.argumentSpan));
|
|
7590
|
-
}
|
|
7591
|
-
else if (leftMostSafe instanceof SafeKeyedRead) {
|
|
7463
|
+
if (leftMostSafe instanceof SafeKeyedRead) {
|
|
7592
7464
|
this._nodeMap.set(leftMostSafe, new KeyedRead(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.receiver, leftMostSafe.key));
|
|
7593
7465
|
}
|
|
7594
7466
|
else {
|
|
@@ -7644,8 +7516,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7644
7516
|
visitConditional(ast) {
|
|
7645
7517
|
return null;
|
|
7646
7518
|
},
|
|
7647
|
-
|
|
7648
|
-
return
|
|
7519
|
+
visitCall(ast) {
|
|
7520
|
+
return visit(this, ast.receiver);
|
|
7649
7521
|
},
|
|
7650
7522
|
visitImplicitReceiver(ast) {
|
|
7651
7523
|
return null;
|
|
@@ -7671,9 +7543,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7671
7543
|
visitLiteralPrimitive(ast) {
|
|
7672
7544
|
return null;
|
|
7673
7545
|
},
|
|
7674
|
-
visitMethodCall(ast) {
|
|
7675
|
-
return visit(this, ast.receiver);
|
|
7676
|
-
},
|
|
7677
7546
|
visitPipe(ast) {
|
|
7678
7547
|
return null;
|
|
7679
7548
|
},
|
|
@@ -7692,9 +7561,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7692
7561
|
visitQuote(ast) {
|
|
7693
7562
|
return null;
|
|
7694
7563
|
},
|
|
7695
|
-
visitSafeMethodCall(ast) {
|
|
7696
|
-
return visit(this, ast.receiver) || ast;
|
|
7697
|
-
},
|
|
7698
7564
|
visitSafePropertyRead(ast) {
|
|
7699
7565
|
return visit(this, ast.receiver) || ast;
|
|
7700
7566
|
},
|
|
@@ -7726,7 +7592,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7726
7592
|
visitConditional(ast) {
|
|
7727
7593
|
return visit(this, ast.condition) || visit(this, ast.trueExp) || visit(this, ast.falseExp);
|
|
7728
7594
|
},
|
|
7729
|
-
|
|
7595
|
+
visitCall(ast) {
|
|
7730
7596
|
return true;
|
|
7731
7597
|
},
|
|
7732
7598
|
visitImplicitReceiver(ast) {
|
|
@@ -7753,9 +7619,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7753
7619
|
visitLiteralPrimitive(ast) {
|
|
7754
7620
|
return false;
|
|
7755
7621
|
},
|
|
7756
|
-
visitMethodCall(ast) {
|
|
7757
|
-
return true;
|
|
7758
|
-
},
|
|
7759
7622
|
visitPipe(ast) {
|
|
7760
7623
|
return true;
|
|
7761
7624
|
},
|
|
@@ -7774,9 +7637,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7774
7637
|
visitQuote(ast) {
|
|
7775
7638
|
return false;
|
|
7776
7639
|
},
|
|
7777
|
-
visitSafeMethodCall(ast) {
|
|
7778
|
-
return true;
|
|
7779
|
-
},
|
|
7780
7640
|
visitSafePropertyRead(ast) {
|
|
7781
7641
|
return false;
|
|
7782
7642
|
},
|
|
@@ -7861,9 +7721,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
7861
7721
|
}
|
|
7862
7722
|
return null;
|
|
7863
7723
|
}
|
|
7864
|
-
class BuiltinFunctionCall extends
|
|
7724
|
+
class BuiltinFunctionCall extends Call {
|
|
7865
7725
|
constructor(span, sourceSpan, args, converter) {
|
|
7866
|
-
super(span, sourceSpan,
|
|
7726
|
+
super(span, sourceSpan, new EmptyExpr(span, sourceSpan), args, null);
|
|
7867
7727
|
this.converter = converter;
|
|
7868
7728
|
}
|
|
7869
7729
|
}
|
|
@@ -8443,7 +8303,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
8443
8303
|
const _polyfillHostRe = /-shadowcsshost/gim;
|
|
8444
8304
|
const _colonHostRe = /:host/gim;
|
|
8445
8305
|
const _colonHostContextRe = /:host-context/gim;
|
|
8446
|
-
const _commentRe =
|
|
8306
|
+
const _commentRe = /\/\*[\s\S]*?\*\//g;
|
|
8447
8307
|
function stripComments(input) {
|
|
8448
8308
|
return input.replace(_commentRe, '');
|
|
8449
8309
|
}
|
|
@@ -8654,9 +8514,10 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
8654
8514
|
}
|
|
8655
8515
|
}
|
|
8656
8516
|
class Text$2 extends NodeWithI18n {
|
|
8657
|
-
constructor(value, sourceSpan, i18n) {
|
|
8517
|
+
constructor(value, sourceSpan, tokens, i18n) {
|
|
8658
8518
|
super(sourceSpan, i18n);
|
|
8659
8519
|
this.value = value;
|
|
8520
|
+
this.tokens = tokens;
|
|
8660
8521
|
}
|
|
8661
8522
|
visit(visitor, context) {
|
|
8662
8523
|
return visitor.visitText(this, context);
|
|
@@ -8687,12 +8548,13 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
8687
8548
|
}
|
|
8688
8549
|
}
|
|
8689
8550
|
class Attribute extends NodeWithI18n {
|
|
8690
|
-
constructor(name, value, sourceSpan, keySpan, valueSpan, i18n) {
|
|
8551
|
+
constructor(name, value, sourceSpan, keySpan, valueSpan, valueTokens, i18n) {
|
|
8691
8552
|
super(sourceSpan, i18n);
|
|
8692
8553
|
this.name = name;
|
|
8693
8554
|
this.value = value;
|
|
8694
8555
|
this.keySpan = keySpan;
|
|
8695
8556
|
this.valueSpan = valueSpan;
|
|
8557
|
+
this.valueTokens = valueTokens;
|
|
8696
8558
|
}
|
|
8697
8559
|
visit(visitor, context) {
|
|
8698
8560
|
return visitor.visitAttribute(this, context);
|
|
@@ -10884,38 +10746,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
10884
10746
|
* Use of this source code is governed by an MIT-style license that can be
|
|
10885
10747
|
* found in the LICENSE file at https://angular.io/license
|
|
10886
10748
|
*/
|
|
10887
|
-
var TokenType;
|
|
10888
|
-
(function (TokenType) {
|
|
10889
|
-
TokenType[TokenType["TAG_OPEN_START"] = 0] = "TAG_OPEN_START";
|
|
10890
|
-
TokenType[TokenType["TAG_OPEN_END"] = 1] = "TAG_OPEN_END";
|
|
10891
|
-
TokenType[TokenType["TAG_OPEN_END_VOID"] = 2] = "TAG_OPEN_END_VOID";
|
|
10892
|
-
TokenType[TokenType["TAG_CLOSE"] = 3] = "TAG_CLOSE";
|
|
10893
|
-
TokenType[TokenType["INCOMPLETE_TAG_OPEN"] = 4] = "INCOMPLETE_TAG_OPEN";
|
|
10894
|
-
TokenType[TokenType["TEXT"] = 5] = "TEXT";
|
|
10895
|
-
TokenType[TokenType["ESCAPABLE_RAW_TEXT"] = 6] = "ESCAPABLE_RAW_TEXT";
|
|
10896
|
-
TokenType[TokenType["RAW_TEXT"] = 7] = "RAW_TEXT";
|
|
10897
|
-
TokenType[TokenType["COMMENT_START"] = 8] = "COMMENT_START";
|
|
10898
|
-
TokenType[TokenType["COMMENT_END"] = 9] = "COMMENT_END";
|
|
10899
|
-
TokenType[TokenType["CDATA_START"] = 10] = "CDATA_START";
|
|
10900
|
-
TokenType[TokenType["CDATA_END"] = 11] = "CDATA_END";
|
|
10901
|
-
TokenType[TokenType["ATTR_NAME"] = 12] = "ATTR_NAME";
|
|
10902
|
-
TokenType[TokenType["ATTR_QUOTE"] = 13] = "ATTR_QUOTE";
|
|
10903
|
-
TokenType[TokenType["ATTR_VALUE"] = 14] = "ATTR_VALUE";
|
|
10904
|
-
TokenType[TokenType["DOC_TYPE"] = 15] = "DOC_TYPE";
|
|
10905
|
-
TokenType[TokenType["EXPANSION_FORM_START"] = 16] = "EXPANSION_FORM_START";
|
|
10906
|
-
TokenType[TokenType["EXPANSION_CASE_VALUE"] = 17] = "EXPANSION_CASE_VALUE";
|
|
10907
|
-
TokenType[TokenType["EXPANSION_CASE_EXP_START"] = 18] = "EXPANSION_CASE_EXP_START";
|
|
10908
|
-
TokenType[TokenType["EXPANSION_CASE_EXP_END"] = 19] = "EXPANSION_CASE_EXP_END";
|
|
10909
|
-
TokenType[TokenType["EXPANSION_FORM_END"] = 20] = "EXPANSION_FORM_END";
|
|
10910
|
-
TokenType[TokenType["EOF"] = 21] = "EOF";
|
|
10911
|
-
})(TokenType || (TokenType = {}));
|
|
10912
|
-
class Token {
|
|
10913
|
-
constructor(type, parts, sourceSpan) {
|
|
10914
|
-
this.type = type;
|
|
10915
|
-
this.parts = parts;
|
|
10916
|
-
this.sourceSpan = sourceSpan;
|
|
10917
|
-
}
|
|
10918
|
-
}
|
|
10919
10749
|
class TokenError extends ParseError {
|
|
10920
10750
|
constructor(errorMsg, tokenType, span) {
|
|
10921
10751
|
super(span, errorMsg);
|
|
@@ -11022,14 +10852,16 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11022
10852
|
}
|
|
11023
10853
|
}
|
|
11024
10854
|
else if (!(this._tokenizeIcu && this._tokenizeExpansionForm())) {
|
|
11025
|
-
|
|
10855
|
+
// In (possibly interpolated) text the end of the text is given by `isTextEnd()`, while
|
|
10856
|
+
// the premature end of an interpolation is given by the start of a new HTML element.
|
|
10857
|
+
this._consumeWithInterpolation(5 /* TEXT */, 8 /* INTERPOLATION */, () => this._isTextEnd(), () => this._isTagStart());
|
|
11026
10858
|
}
|
|
11027
10859
|
}
|
|
11028
10860
|
catch (e) {
|
|
11029
10861
|
this.handleError(e);
|
|
11030
10862
|
}
|
|
11031
10863
|
}
|
|
11032
|
-
this._beginToken(
|
|
10864
|
+
this._beginToken(24 /* EOF */);
|
|
11033
10865
|
this._endToken([]);
|
|
11034
10866
|
}
|
|
11035
10867
|
/**
|
|
@@ -11068,7 +10900,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11068
10900
|
if (this._currentTokenType === null) {
|
|
11069
10901
|
throw new TokenError('Programming error - attempted to end a token which has no token type', null, this._cursor.getSpan(this._currentTokenStart));
|
|
11070
10902
|
}
|
|
11071
|
-
const token =
|
|
10903
|
+
const token = {
|
|
10904
|
+
type: this._currentTokenType,
|
|
10905
|
+
parts,
|
|
10906
|
+
sourceSpan: (end !== null && end !== void 0 ? end : this._cursor).getSpan(this._currentTokenStart, this._leadingTriviaCodePoints),
|
|
10907
|
+
};
|
|
11072
10908
|
this.tokens.push(token);
|
|
11073
10909
|
this._currentTokenStart = null;
|
|
11074
10910
|
this._currentTokenType = null;
|
|
@@ -11161,19 +10997,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11161
10997
|
this._cursor.advance();
|
|
11162
10998
|
}
|
|
11163
10999
|
}
|
|
11164
|
-
_readChar(
|
|
11165
|
-
|
|
11166
|
-
|
|
11167
|
-
|
|
11168
|
-
|
|
11169
|
-
|
|
11170
|
-
// may have been generated from an escape sequence.
|
|
11171
|
-
const char = String.fromCodePoint(this._cursor.peek());
|
|
11172
|
-
this._cursor.advance();
|
|
11173
|
-
return char;
|
|
11174
|
-
}
|
|
11000
|
+
_readChar() {
|
|
11001
|
+
// Don't rely upon reading directly from `_input` as the actual char value
|
|
11002
|
+
// may have been generated from an escape sequence.
|
|
11003
|
+
const char = String.fromCodePoint(this._cursor.peek());
|
|
11004
|
+
this._cursor.advance();
|
|
11005
|
+
return char;
|
|
11175
11006
|
}
|
|
11176
|
-
|
|
11007
|
+
_consumeEntity(textTokenType) {
|
|
11008
|
+
this._beginToken(9 /* ENCODED_ENTITY */);
|
|
11177
11009
|
const start = this._cursor.clone();
|
|
11178
11010
|
this._cursor.advance();
|
|
11179
11011
|
if (this._attemptCharCode($HASH)) {
|
|
@@ -11191,7 +11023,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11191
11023
|
this._cursor.advance();
|
|
11192
11024
|
try {
|
|
11193
11025
|
const charCode = parseInt(strNum, isHex ? 16 : 10);
|
|
11194
|
-
|
|
11026
|
+
this._endToken([String.fromCharCode(charCode), this._cursor.getChars(start)]);
|
|
11195
11027
|
}
|
|
11196
11028
|
catch (_a) {
|
|
11197
11029
|
throw this._createError(_unknownEntityErrorMsg(this._cursor.getChars(start)), this._cursor.getSpan());
|
|
@@ -11201,20 +11033,25 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11201
11033
|
const nameStart = this._cursor.clone();
|
|
11202
11034
|
this._attemptCharCodeUntilFn(isNamedEntityEnd);
|
|
11203
11035
|
if (this._cursor.peek() != $SEMICOLON) {
|
|
11036
|
+
// No semicolon was found so abort the encoded entity token that was in progress, and treat
|
|
11037
|
+
// this as a text token
|
|
11038
|
+
this._beginToken(textTokenType, start);
|
|
11204
11039
|
this._cursor = nameStart;
|
|
11205
|
-
|
|
11040
|
+
this._endToken(['&']);
|
|
11206
11041
|
}
|
|
11207
|
-
|
|
11208
|
-
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
|
|
11042
|
+
else {
|
|
11043
|
+
const name = this._cursor.getChars(nameStart);
|
|
11044
|
+
this._cursor.advance();
|
|
11045
|
+
const char = NAMED_ENTITIES[name];
|
|
11046
|
+
if (!char) {
|
|
11047
|
+
throw this._createError(_unknownEntityErrorMsg(name), this._cursor.getSpan(start));
|
|
11048
|
+
}
|
|
11049
|
+
this._endToken([char, `&${name};`]);
|
|
11212
11050
|
}
|
|
11213
|
-
return char;
|
|
11214
11051
|
}
|
|
11215
11052
|
}
|
|
11216
|
-
_consumeRawText(
|
|
11217
|
-
this._beginToken(
|
|
11053
|
+
_consumeRawText(consumeEntities, endMarkerPredicate) {
|
|
11054
|
+
this._beginToken(consumeEntities ? 6 /* ESCAPABLE_RAW_TEXT */ : 7 /* RAW_TEXT */);
|
|
11218
11055
|
const parts = [];
|
|
11219
11056
|
while (true) {
|
|
11220
11057
|
const tagCloseStart = this._cursor.clone();
|
|
@@ -11223,30 +11060,38 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11223
11060
|
if (foundEndMarker) {
|
|
11224
11061
|
break;
|
|
11225
11062
|
}
|
|
11226
|
-
|
|
11063
|
+
if (consumeEntities && this._cursor.peek() === $AMPERSAND) {
|
|
11064
|
+
this._endToken([this._processCarriageReturns(parts.join(''))]);
|
|
11065
|
+
parts.length = 0;
|
|
11066
|
+
this._consumeEntity(6 /* ESCAPABLE_RAW_TEXT */);
|
|
11067
|
+
this._beginToken(6 /* ESCAPABLE_RAW_TEXT */);
|
|
11068
|
+
}
|
|
11069
|
+
else {
|
|
11070
|
+
parts.push(this._readChar());
|
|
11071
|
+
}
|
|
11227
11072
|
}
|
|
11228
|
-
|
|
11073
|
+
this._endToken([this._processCarriageReturns(parts.join(''))]);
|
|
11229
11074
|
}
|
|
11230
11075
|
_consumeComment(start) {
|
|
11231
|
-
this._beginToken(
|
|
11076
|
+
this._beginToken(10 /* COMMENT_START */, start);
|
|
11232
11077
|
this._requireCharCode($MINUS);
|
|
11233
11078
|
this._endToken([]);
|
|
11234
11079
|
this._consumeRawText(false, () => this._attemptStr('-->'));
|
|
11235
|
-
this._beginToken(
|
|
11080
|
+
this._beginToken(11 /* COMMENT_END */);
|
|
11236
11081
|
this._requireStr('-->');
|
|
11237
11082
|
this._endToken([]);
|
|
11238
11083
|
}
|
|
11239
11084
|
_consumeCdata(start) {
|
|
11240
|
-
this._beginToken(
|
|
11085
|
+
this._beginToken(12 /* CDATA_START */, start);
|
|
11241
11086
|
this._requireStr('CDATA[');
|
|
11242
11087
|
this._endToken([]);
|
|
11243
11088
|
this._consumeRawText(false, () => this._attemptStr(']]>'));
|
|
11244
|
-
this._beginToken(
|
|
11089
|
+
this._beginToken(13 /* CDATA_END */);
|
|
11245
11090
|
this._requireStr(']]>');
|
|
11246
11091
|
this._endToken([]);
|
|
11247
11092
|
}
|
|
11248
11093
|
_consumeDocType(start) {
|
|
11249
|
-
this._beginToken(
|
|
11094
|
+
this._beginToken(18 /* DOC_TYPE */, start);
|
|
11250
11095
|
const contentStart = this._cursor.clone();
|
|
11251
11096
|
this._attemptUntilChar($GT);
|
|
11252
11097
|
const content = this._cursor.getChars(contentStart);
|
|
@@ -11300,12 +11145,12 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11300
11145
|
if (e instanceof _ControlFlowError) {
|
|
11301
11146
|
if (openTagToken) {
|
|
11302
11147
|
// We errored before we could close the opening tag, so it is incomplete.
|
|
11303
|
-
openTagToken.type =
|
|
11148
|
+
openTagToken.type = 4 /* INCOMPLETE_TAG_OPEN */;
|
|
11304
11149
|
}
|
|
11305
11150
|
else {
|
|
11306
11151
|
// When the start tag is invalid, assume we want a "<" as text.
|
|
11307
11152
|
// Back to back text tokens are merged at the end.
|
|
11308
|
-
this._beginToken(
|
|
11153
|
+
this._beginToken(5 /* TEXT */, start);
|
|
11309
11154
|
this._endToken(['<']);
|
|
11310
11155
|
}
|
|
11311
11156
|
return;
|
|
@@ -11320,8 +11165,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11320
11165
|
this._consumeRawTextWithTagClose(prefix, tagName, true);
|
|
11321
11166
|
}
|
|
11322
11167
|
}
|
|
11323
|
-
_consumeRawTextWithTagClose(prefix, tagName,
|
|
11324
|
-
this._consumeRawText(
|
|
11168
|
+
_consumeRawTextWithTagClose(prefix, tagName, consumeEntities) {
|
|
11169
|
+
this._consumeRawText(consumeEntities, () => {
|
|
11325
11170
|
if (!this._attemptCharCode($LT))
|
|
11326
11171
|
return false;
|
|
11327
11172
|
if (!this._attemptCharCode($SLASH))
|
|
@@ -11332,13 +11177,13 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11332
11177
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
11333
11178
|
return this._attemptCharCode($GT);
|
|
11334
11179
|
});
|
|
11335
|
-
this._beginToken(
|
|
11180
|
+
this._beginToken(3 /* TAG_CLOSE */);
|
|
11336
11181
|
this._requireCharCodeUntilFn(code => code === $GT, 3);
|
|
11337
11182
|
this._cursor.advance(); // Consume the `>`
|
|
11338
11183
|
this._endToken([prefix, tagName]);
|
|
11339
11184
|
}
|
|
11340
11185
|
_consumeTagOpenStart(start) {
|
|
11341
|
-
this._beginToken(
|
|
11186
|
+
this._beginToken(0 /* TAG_OPEN_START */, start);
|
|
11342
11187
|
const parts = this._consumePrefixAndName();
|
|
11343
11188
|
return this._endToken(parts);
|
|
11344
11189
|
}
|
|
@@ -11347,44 +11192,38 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11347
11192
|
if (attrNameStart === $SQ || attrNameStart === $DQ) {
|
|
11348
11193
|
throw this._createError(_unexpectedCharacterErrorMsg(attrNameStart), this._cursor.getSpan());
|
|
11349
11194
|
}
|
|
11350
|
-
this._beginToken(
|
|
11195
|
+
this._beginToken(14 /* ATTR_NAME */);
|
|
11351
11196
|
const prefixAndName = this._consumePrefixAndName();
|
|
11352
11197
|
this._endToken(prefixAndName);
|
|
11353
11198
|
}
|
|
11354
11199
|
_consumeAttributeValue() {
|
|
11355
|
-
let value;
|
|
11356
11200
|
if (this._cursor.peek() === $SQ || this._cursor.peek() === $DQ) {
|
|
11357
|
-
this._beginToken(TokenType.ATTR_QUOTE);
|
|
11358
11201
|
const quoteChar = this._cursor.peek();
|
|
11359
|
-
this.
|
|
11360
|
-
|
|
11361
|
-
|
|
11362
|
-
const
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
}
|
|
11366
|
-
value = parts.join('');
|
|
11367
|
-
this._endToken([this._processCarriageReturns(value)]);
|
|
11368
|
-
this._beginToken(TokenType.ATTR_QUOTE);
|
|
11369
|
-
this._cursor.advance();
|
|
11370
|
-
this._endToken([String.fromCodePoint(quoteChar)]);
|
|
11202
|
+
this._consumeQuote(quoteChar);
|
|
11203
|
+
// In an attribute then end of the attribute value and the premature end to an interpolation
|
|
11204
|
+
// are both triggered by the `quoteChar`.
|
|
11205
|
+
const endPredicate = () => this._cursor.peek() === quoteChar;
|
|
11206
|
+
this._consumeWithInterpolation(16 /* ATTR_VALUE_TEXT */, 17 /* ATTR_VALUE_INTERPOLATION */, endPredicate, endPredicate);
|
|
11207
|
+
this._consumeQuote(quoteChar);
|
|
11371
11208
|
}
|
|
11372
11209
|
else {
|
|
11373
|
-
this.
|
|
11374
|
-
|
|
11375
|
-
this._requireCharCodeUntilFn(isNameEnd, 1);
|
|
11376
|
-
value = this._cursor.getChars(valueStart);
|
|
11377
|
-
this._endToken([this._processCarriageReturns(value)]);
|
|
11210
|
+
const endPredicate = () => isNameEnd(this._cursor.peek());
|
|
11211
|
+
this._consumeWithInterpolation(16 /* ATTR_VALUE_TEXT */, 17 /* ATTR_VALUE_INTERPOLATION */, endPredicate, endPredicate);
|
|
11378
11212
|
}
|
|
11379
11213
|
}
|
|
11214
|
+
_consumeQuote(quoteChar) {
|
|
11215
|
+
this._beginToken(15 /* ATTR_QUOTE */);
|
|
11216
|
+
this._requireCharCode(quoteChar);
|
|
11217
|
+
this._endToken([String.fromCodePoint(quoteChar)]);
|
|
11218
|
+
}
|
|
11380
11219
|
_consumeTagOpenEnd() {
|
|
11381
|
-
const tokenType = this._attemptCharCode($SLASH) ?
|
|
11220
|
+
const tokenType = this._attemptCharCode($SLASH) ? 2 /* TAG_OPEN_END_VOID */ : 1 /* TAG_OPEN_END */;
|
|
11382
11221
|
this._beginToken(tokenType);
|
|
11383
11222
|
this._requireCharCode($GT);
|
|
11384
11223
|
this._endToken([]);
|
|
11385
11224
|
}
|
|
11386
11225
|
_consumeTagClose(start) {
|
|
11387
|
-
this._beginToken(
|
|
11226
|
+
this._beginToken(3 /* TAG_CLOSE */, start);
|
|
11388
11227
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
11389
11228
|
const prefixAndName = this._consumePrefixAndName();
|
|
11390
11229
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
@@ -11392,11 +11231,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11392
11231
|
this._endToken(prefixAndName);
|
|
11393
11232
|
}
|
|
11394
11233
|
_consumeExpansionFormStart() {
|
|
11395
|
-
this._beginToken(
|
|
11234
|
+
this._beginToken(19 /* EXPANSION_FORM_START */);
|
|
11396
11235
|
this._requireCharCode($LBRACE);
|
|
11397
11236
|
this._endToken([]);
|
|
11398
|
-
this._expansionCaseStack.push(
|
|
11399
|
-
this._beginToken(
|
|
11237
|
+
this._expansionCaseStack.push(19 /* EXPANSION_FORM_START */);
|
|
11238
|
+
this._beginToken(7 /* RAW_TEXT */);
|
|
11400
11239
|
const condition = this._readUntil($COMMA);
|
|
11401
11240
|
const normalizedCondition = this._processCarriageReturns(condition);
|
|
11402
11241
|
if (this._i18nNormalizeLineEndingsInICUs) {
|
|
@@ -11412,59 +11251,139 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11412
11251
|
}
|
|
11413
11252
|
this._requireCharCode($COMMA);
|
|
11414
11253
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
11415
|
-
this._beginToken(
|
|
11254
|
+
this._beginToken(7 /* RAW_TEXT */);
|
|
11416
11255
|
const type = this._readUntil($COMMA);
|
|
11417
11256
|
this._endToken([type]);
|
|
11418
11257
|
this._requireCharCode($COMMA);
|
|
11419
11258
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
11420
11259
|
}
|
|
11421
11260
|
_consumeExpansionCaseStart() {
|
|
11422
|
-
this._beginToken(
|
|
11261
|
+
this._beginToken(20 /* EXPANSION_CASE_VALUE */);
|
|
11423
11262
|
const value = this._readUntil($LBRACE).trim();
|
|
11424
11263
|
this._endToken([value]);
|
|
11425
11264
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
11426
|
-
this._beginToken(
|
|
11265
|
+
this._beginToken(21 /* EXPANSION_CASE_EXP_START */);
|
|
11427
11266
|
this._requireCharCode($LBRACE);
|
|
11428
11267
|
this._endToken([]);
|
|
11429
11268
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
11430
|
-
this._expansionCaseStack.push(
|
|
11269
|
+
this._expansionCaseStack.push(21 /* EXPANSION_CASE_EXP_START */);
|
|
11431
11270
|
}
|
|
11432
11271
|
_consumeExpansionCaseEnd() {
|
|
11433
|
-
this._beginToken(
|
|
11272
|
+
this._beginToken(22 /* EXPANSION_CASE_EXP_END */);
|
|
11434
11273
|
this._requireCharCode($RBRACE);
|
|
11435
11274
|
this._endToken([]);
|
|
11436
11275
|
this._attemptCharCodeUntilFn(isNotWhitespace);
|
|
11437
11276
|
this._expansionCaseStack.pop();
|
|
11438
11277
|
}
|
|
11439
11278
|
_consumeExpansionFormEnd() {
|
|
11440
|
-
this._beginToken(
|
|
11279
|
+
this._beginToken(23 /* EXPANSION_FORM_END */);
|
|
11441
11280
|
this._requireCharCode($RBRACE);
|
|
11442
11281
|
this._endToken([]);
|
|
11443
11282
|
this._expansionCaseStack.pop();
|
|
11444
11283
|
}
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11284
|
+
/**
|
|
11285
|
+
* Consume a string that may contain interpolation expressions.
|
|
11286
|
+
*
|
|
11287
|
+
* The first token consumed will be of `tokenType` and then there will be alternating
|
|
11288
|
+
* `interpolationTokenType` and `tokenType` tokens until the `endPredicate()` returns true.
|
|
11289
|
+
*
|
|
11290
|
+
* If an interpolation token ends prematurely it will have no end marker in its `parts` array.
|
|
11291
|
+
*
|
|
11292
|
+
* @param textTokenType the kind of tokens to interleave around interpolation tokens.
|
|
11293
|
+
* @param interpolationTokenType the kind of tokens that contain interpolation.
|
|
11294
|
+
* @param endPredicate a function that should return true when we should stop consuming.
|
|
11295
|
+
* @param endInterpolation a function that should return true if there is a premature end to an
|
|
11296
|
+
* interpolation expression - i.e. before we get to the normal interpolation closing marker.
|
|
11297
|
+
*/
|
|
11298
|
+
_consumeWithInterpolation(textTokenType, interpolationTokenType, endPredicate, endInterpolation) {
|
|
11299
|
+
this._beginToken(textTokenType);
|
|
11448
11300
|
const parts = [];
|
|
11449
|
-
|
|
11301
|
+
while (!endPredicate()) {
|
|
11302
|
+
const current = this._cursor.clone();
|
|
11450
11303
|
if (this._interpolationConfig && this._attemptStr(this._interpolationConfig.start)) {
|
|
11451
|
-
|
|
11452
|
-
|
|
11304
|
+
this._endToken([this._processCarriageReturns(parts.join(''))], current);
|
|
11305
|
+
parts.length = 0;
|
|
11306
|
+
this._consumeInterpolation(interpolationTokenType, current, endInterpolation);
|
|
11307
|
+
this._beginToken(textTokenType);
|
|
11453
11308
|
}
|
|
11454
|
-
else if (this.
|
|
11455
|
-
this.
|
|
11456
|
-
parts.
|
|
11457
|
-
this.
|
|
11309
|
+
else if (this._cursor.peek() === $AMPERSAND) {
|
|
11310
|
+
this._endToken([this._processCarriageReturns(parts.join(''))]);
|
|
11311
|
+
parts.length = 0;
|
|
11312
|
+
this._consumeEntity(textTokenType);
|
|
11313
|
+
this._beginToken(textTokenType);
|
|
11458
11314
|
}
|
|
11459
11315
|
else {
|
|
11460
|
-
parts.push(this._readChar(
|
|
11316
|
+
parts.push(this._readChar());
|
|
11461
11317
|
}
|
|
11462
|
-
}
|
|
11318
|
+
}
|
|
11463
11319
|
// It is possible that an interpolation was started but not ended inside this text token.
|
|
11464
11320
|
// Make sure that we reset the state of the lexer correctly.
|
|
11465
11321
|
this._inInterpolation = false;
|
|
11466
11322
|
this._endToken([this._processCarriageReturns(parts.join(''))]);
|
|
11467
11323
|
}
|
|
11324
|
+
/**
|
|
11325
|
+
* Consume a block of text that has been interpreted as an Angular interpolation.
|
|
11326
|
+
*
|
|
11327
|
+
* @param interpolationTokenType the type of the interpolation token to generate.
|
|
11328
|
+
* @param interpolationStart a cursor that points to the start of this interpolation.
|
|
11329
|
+
* @param prematureEndPredicate a function that should return true if the next characters indicate
|
|
11330
|
+
* an end to the interpolation before its normal closing marker.
|
|
11331
|
+
*/
|
|
11332
|
+
_consumeInterpolation(interpolationTokenType, interpolationStart, prematureEndPredicate) {
|
|
11333
|
+
const parts = [];
|
|
11334
|
+
this._beginToken(interpolationTokenType, interpolationStart);
|
|
11335
|
+
parts.push(this._interpolationConfig.start);
|
|
11336
|
+
// Find the end of the interpolation, ignoring content inside quotes.
|
|
11337
|
+
const expressionStart = this._cursor.clone();
|
|
11338
|
+
let inQuote = null;
|
|
11339
|
+
let inComment = false;
|
|
11340
|
+
while (this._cursor.peek() !== $EOF &&
|
|
11341
|
+
(prematureEndPredicate === null || !prematureEndPredicate())) {
|
|
11342
|
+
const current = this._cursor.clone();
|
|
11343
|
+
if (this._isTagStart()) {
|
|
11344
|
+
// We are starting what looks like an HTML element in the middle of this interpolation.
|
|
11345
|
+
// Reset the cursor to before the `<` character and end the interpolation token.
|
|
11346
|
+
// (This is actually wrong but here for backward compatibility).
|
|
11347
|
+
this._cursor = current;
|
|
11348
|
+
parts.push(this._getProcessedChars(expressionStart, current));
|
|
11349
|
+
this._endToken(parts);
|
|
11350
|
+
return;
|
|
11351
|
+
}
|
|
11352
|
+
if (inQuote === null) {
|
|
11353
|
+
if (this._attemptStr(this._interpolationConfig.end)) {
|
|
11354
|
+
// We are not in a string, and we hit the end interpolation marker
|
|
11355
|
+
parts.push(this._getProcessedChars(expressionStart, current));
|
|
11356
|
+
parts.push(this._interpolationConfig.end);
|
|
11357
|
+
this._endToken(parts);
|
|
11358
|
+
return;
|
|
11359
|
+
}
|
|
11360
|
+
else if (this._attemptStr('//')) {
|
|
11361
|
+
// Once we are in a comment we ignore any quotes
|
|
11362
|
+
inComment = true;
|
|
11363
|
+
}
|
|
11364
|
+
}
|
|
11365
|
+
const char = this._cursor.peek();
|
|
11366
|
+
this._cursor.advance();
|
|
11367
|
+
if (char === $BACKSLASH) {
|
|
11368
|
+
// Skip the next character because it was escaped.
|
|
11369
|
+
this._cursor.advance();
|
|
11370
|
+
}
|
|
11371
|
+
else if (char === inQuote) {
|
|
11372
|
+
// Exiting the current quoted string
|
|
11373
|
+
inQuote = null;
|
|
11374
|
+
}
|
|
11375
|
+
else if (!inComment && inQuote === null && isQuote(char)) {
|
|
11376
|
+
// Entering a new quoted string
|
|
11377
|
+
inQuote = char;
|
|
11378
|
+
}
|
|
11379
|
+
}
|
|
11380
|
+
// We hit EOF without finding a closing interpolation marker
|
|
11381
|
+
parts.push(this._getProcessedChars(expressionStart, this._cursor));
|
|
11382
|
+
this._endToken(parts);
|
|
11383
|
+
}
|
|
11384
|
+
_getProcessedChars(start, end) {
|
|
11385
|
+
return this._processCarriageReturns(end.getChars(start));
|
|
11386
|
+
}
|
|
11468
11387
|
_isTextEnd() {
|
|
11469
11388
|
if (this._isTagStart() || this._cursor.peek() === $EOF) {
|
|
11470
11389
|
return true;
|
|
@@ -11507,12 +11426,12 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11507
11426
|
_isInExpansionCase() {
|
|
11508
11427
|
return this._expansionCaseStack.length > 0 &&
|
|
11509
11428
|
this._expansionCaseStack[this._expansionCaseStack.length - 1] ===
|
|
11510
|
-
|
|
11429
|
+
21 /* EXPANSION_CASE_EXP_START */;
|
|
11511
11430
|
}
|
|
11512
11431
|
_isInExpansionForm() {
|
|
11513
11432
|
return this._expansionCaseStack.length > 0 &&
|
|
11514
11433
|
this._expansionCaseStack[this._expansionCaseStack.length - 1] ===
|
|
11515
|
-
|
|
11434
|
+
19 /* EXPANSION_FORM_START */;
|
|
11516
11435
|
}
|
|
11517
11436
|
isExpansionFormStart() {
|
|
11518
11437
|
if (this._cursor.peek() !== $LBRACE) {
|
|
@@ -11559,7 +11478,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11559
11478
|
let lastDstToken = undefined;
|
|
11560
11479
|
for (let i = 0; i < srcTokens.length; i++) {
|
|
11561
11480
|
const token = srcTokens[i];
|
|
11562
|
-
if (lastDstToken && lastDstToken.type ===
|
|
11481
|
+
if ((lastDstToken && lastDstToken.type === 5 /* TEXT */ && token.type === 5 /* TEXT */) ||
|
|
11482
|
+
(lastDstToken && lastDstToken.type === 16 /* ATTR_VALUE_TEXT */ &&
|
|
11483
|
+
token.type === 16 /* ATTR_VALUE_TEXT */)) {
|
|
11563
11484
|
lastDstToken.parts[0] += token.parts[0];
|
|
11564
11485
|
lastDstToken.sourceSpan.end = token.sourceSpan.end;
|
|
11565
11486
|
}
|
|
@@ -11852,28 +11773,28 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11852
11773
|
this._advance();
|
|
11853
11774
|
}
|
|
11854
11775
|
build() {
|
|
11855
|
-
while (this._peek.type !==
|
|
11856
|
-
if (this._peek.type ===
|
|
11857
|
-
this._peek.type ===
|
|
11776
|
+
while (this._peek.type !== 24 /* EOF */) {
|
|
11777
|
+
if (this._peek.type === 0 /* TAG_OPEN_START */ ||
|
|
11778
|
+
this._peek.type === 4 /* INCOMPLETE_TAG_OPEN */) {
|
|
11858
11779
|
this._consumeStartTag(this._advance());
|
|
11859
11780
|
}
|
|
11860
|
-
else if (this._peek.type ===
|
|
11781
|
+
else if (this._peek.type === 3 /* TAG_CLOSE */) {
|
|
11861
11782
|
this._consumeEndTag(this._advance());
|
|
11862
11783
|
}
|
|
11863
|
-
else if (this._peek.type ===
|
|
11784
|
+
else if (this._peek.type === 12 /* CDATA_START */) {
|
|
11864
11785
|
this._closeVoidElement();
|
|
11865
11786
|
this._consumeCdata(this._advance());
|
|
11866
11787
|
}
|
|
11867
|
-
else if (this._peek.type ===
|
|
11788
|
+
else if (this._peek.type === 10 /* COMMENT_START */) {
|
|
11868
11789
|
this._closeVoidElement();
|
|
11869
11790
|
this._consumeComment(this._advance());
|
|
11870
11791
|
}
|
|
11871
|
-
else if (this._peek.type ===
|
|
11872
|
-
this._peek.type ===
|
|
11792
|
+
else if (this._peek.type === 5 /* TEXT */ || this._peek.type === 7 /* RAW_TEXT */ ||
|
|
11793
|
+
this._peek.type === 6 /* ESCAPABLE_RAW_TEXT */) {
|
|
11873
11794
|
this._closeVoidElement();
|
|
11874
11795
|
this._consumeText(this._advance());
|
|
11875
11796
|
}
|
|
11876
|
-
else if (this._peek.type ===
|
|
11797
|
+
else if (this._peek.type === 19 /* EXPANSION_FORM_START */) {
|
|
11877
11798
|
this._consumeExpansion(this._advance());
|
|
11878
11799
|
}
|
|
11879
11800
|
else {
|
|
@@ -11899,11 +11820,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11899
11820
|
}
|
|
11900
11821
|
_consumeCdata(_startToken) {
|
|
11901
11822
|
this._consumeText(this._advance());
|
|
11902
|
-
this._advanceIf(
|
|
11823
|
+
this._advanceIf(13 /* CDATA_END */);
|
|
11903
11824
|
}
|
|
11904
11825
|
_consumeComment(token) {
|
|
11905
|
-
const text = this._advanceIf(
|
|
11906
|
-
this._advanceIf(
|
|
11826
|
+
const text = this._advanceIf(7 /* RAW_TEXT */);
|
|
11827
|
+
this._advanceIf(11 /* COMMENT_END */);
|
|
11907
11828
|
const value = text != null ? text.parts[0].trim() : null;
|
|
11908
11829
|
this._addToParent(new Comment$1(value, token.sourceSpan));
|
|
11909
11830
|
}
|
|
@@ -11912,14 +11833,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11912
11833
|
const type = this._advance();
|
|
11913
11834
|
const cases = [];
|
|
11914
11835
|
// read =
|
|
11915
|
-
while (this._peek.type ===
|
|
11836
|
+
while (this._peek.type === 20 /* EXPANSION_CASE_VALUE */) {
|
|
11916
11837
|
const expCase = this._parseExpansionCase();
|
|
11917
11838
|
if (!expCase)
|
|
11918
11839
|
return; // error
|
|
11919
11840
|
cases.push(expCase);
|
|
11920
11841
|
}
|
|
11921
11842
|
// read the final }
|
|
11922
|
-
if (this._peek.type !==
|
|
11843
|
+
if (this._peek.type !== 23 /* EXPANSION_FORM_END */) {
|
|
11923
11844
|
this.errors.push(TreeError.create(null, this._peek.sourceSpan, `Invalid ICU message. Missing '}'.`));
|
|
11924
11845
|
return;
|
|
11925
11846
|
}
|
|
@@ -11930,7 +11851,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11930
11851
|
_parseExpansionCase() {
|
|
11931
11852
|
const value = this._advance();
|
|
11932
11853
|
// read {
|
|
11933
|
-
if (this._peek.type !==
|
|
11854
|
+
if (this._peek.type !== 21 /* EXPANSION_CASE_EXP_START */) {
|
|
11934
11855
|
this.errors.push(TreeError.create(null, this._peek.sourceSpan, `Invalid ICU message. Missing '{'.`));
|
|
11935
11856
|
return null;
|
|
11936
11857
|
}
|
|
@@ -11940,7 +11861,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11940
11861
|
if (!exp)
|
|
11941
11862
|
return null;
|
|
11942
11863
|
const end = this._advance();
|
|
11943
|
-
exp.push(
|
|
11864
|
+
exp.push({ type: 24 /* EOF */, parts: [], sourceSpan: end.sourceSpan });
|
|
11944
11865
|
// parse everything in between { and }
|
|
11945
11866
|
const expansionCaseParser = new _TreeBuilder(exp, this.getTagDefinition);
|
|
11946
11867
|
expansionCaseParser.build();
|
|
@@ -11954,14 +11875,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11954
11875
|
}
|
|
11955
11876
|
_collectExpansionExpTokens(start) {
|
|
11956
11877
|
const exp = [];
|
|
11957
|
-
const expansionFormStack = [
|
|
11878
|
+
const expansionFormStack = [21 /* EXPANSION_CASE_EXP_START */];
|
|
11958
11879
|
while (true) {
|
|
11959
|
-
if (this._peek.type ===
|
|
11960
|
-
this._peek.type ===
|
|
11880
|
+
if (this._peek.type === 19 /* EXPANSION_FORM_START */ ||
|
|
11881
|
+
this._peek.type === 21 /* EXPANSION_CASE_EXP_START */) {
|
|
11961
11882
|
expansionFormStack.push(this._peek.type);
|
|
11962
11883
|
}
|
|
11963
|
-
if (this._peek.type ===
|
|
11964
|
-
if (lastOnStack(expansionFormStack,
|
|
11884
|
+
if (this._peek.type === 22 /* EXPANSION_CASE_EXP_END */) {
|
|
11885
|
+
if (lastOnStack(expansionFormStack, 21 /* EXPANSION_CASE_EXP_START */)) {
|
|
11965
11886
|
expansionFormStack.pop();
|
|
11966
11887
|
if (expansionFormStack.length === 0)
|
|
11967
11888
|
return exp;
|
|
@@ -11971,8 +11892,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11971
11892
|
return null;
|
|
11972
11893
|
}
|
|
11973
11894
|
}
|
|
11974
|
-
if (this._peek.type ===
|
|
11975
|
-
if (lastOnStack(expansionFormStack,
|
|
11895
|
+
if (this._peek.type === 23 /* EXPANSION_FORM_END */) {
|
|
11896
|
+
if (lastOnStack(expansionFormStack, 19 /* EXPANSION_FORM_START */)) {
|
|
11976
11897
|
expansionFormStack.pop();
|
|
11977
11898
|
}
|
|
11978
11899
|
else {
|
|
@@ -11980,7 +11901,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11980
11901
|
return null;
|
|
11981
11902
|
}
|
|
11982
11903
|
}
|
|
11983
|
-
if (this._peek.type ===
|
|
11904
|
+
if (this._peek.type === 24 /* EOF */) {
|
|
11984
11905
|
this.errors.push(TreeError.create(null, start.sourceSpan, `Invalid ICU message. Missing '}'.`));
|
|
11985
11906
|
return null;
|
|
11986
11907
|
}
|
|
@@ -11988,16 +11909,38 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
11988
11909
|
}
|
|
11989
11910
|
}
|
|
11990
11911
|
_consumeText(token) {
|
|
11912
|
+
const tokens = [token];
|
|
11913
|
+
const startSpan = token.sourceSpan;
|
|
11991
11914
|
let text = token.parts[0];
|
|
11992
11915
|
if (text.length > 0 && text[0] === '\n') {
|
|
11993
11916
|
const parent = this._getParentElement();
|
|
11994
11917
|
if (parent != null && parent.children.length === 0 &&
|
|
11995
11918
|
this.getTagDefinition(parent.name).ignoreFirstLf) {
|
|
11996
11919
|
text = text.substring(1);
|
|
11920
|
+
tokens[0] = { type: token.type, sourceSpan: token.sourceSpan, parts: [text] };
|
|
11921
|
+
}
|
|
11922
|
+
}
|
|
11923
|
+
while (this._peek.type === 8 /* INTERPOLATION */ || this._peek.type === 5 /* TEXT */ ||
|
|
11924
|
+
this._peek.type === 9 /* ENCODED_ENTITY */) {
|
|
11925
|
+
token = this._advance();
|
|
11926
|
+
tokens.push(token);
|
|
11927
|
+
if (token.type === 8 /* INTERPOLATION */) {
|
|
11928
|
+
// For backward compatibility we decode HTML entities that appear in interpolation
|
|
11929
|
+
// expressions. This is arguably a bug, but it could be a considerable breaking change to
|
|
11930
|
+
// fix it. It should be addressed in a larger project to refactor the entire parser/lexer
|
|
11931
|
+
// chain after View Engine has been removed.
|
|
11932
|
+
text += token.parts.join('').replace(/&([^;]+);/g, decodeEntity);
|
|
11933
|
+
}
|
|
11934
|
+
else if (token.type === 9 /* ENCODED_ENTITY */) {
|
|
11935
|
+
text += token.parts[0];
|
|
11936
|
+
}
|
|
11937
|
+
else {
|
|
11938
|
+
text += token.parts.join('');
|
|
11997
11939
|
}
|
|
11998
11940
|
}
|
|
11999
11941
|
if (text.length > 0) {
|
|
12000
|
-
|
|
11942
|
+
const endSpan = token.sourceSpan;
|
|
11943
|
+
this._addToParent(new Text$2(text, new ParseSourceSpan(startSpan.start, endSpan.end, startSpan.fullStart, startSpan.details), tokens));
|
|
12001
11944
|
}
|
|
12002
11945
|
}
|
|
12003
11946
|
_closeVoidElement() {
|
|
@@ -12009,14 +11952,14 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
12009
11952
|
_consumeStartTag(startTagToken) {
|
|
12010
11953
|
const [prefix, name] = startTagToken.parts;
|
|
12011
11954
|
const attrs = [];
|
|
12012
|
-
while (this._peek.type ===
|
|
11955
|
+
while (this._peek.type === 14 /* ATTR_NAME */) {
|
|
12013
11956
|
attrs.push(this._consumeAttr(this._advance()));
|
|
12014
11957
|
}
|
|
12015
11958
|
const fullName = this._getElementFullName(prefix, name, this._getParentElement());
|
|
12016
11959
|
let selfClosing = false;
|
|
12017
11960
|
// Note: There could have been a tokenizer error
|
|
12018
11961
|
// so that we don't get a token for the end tag...
|
|
12019
|
-
if (this._peek.type ===
|
|
11962
|
+
if (this._peek.type === 2 /* TAG_OPEN_END_VOID */) {
|
|
12020
11963
|
this._advance();
|
|
12021
11964
|
selfClosing = true;
|
|
12022
11965
|
const tagDef = this.getTagDefinition(fullName);
|
|
@@ -12024,7 +11967,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
12024
11967
|
this.errors.push(TreeError.create(fullName, startTagToken.sourceSpan, `Only void and foreign elements can be self closed "${startTagToken.parts[1]}"`));
|
|
12025
11968
|
}
|
|
12026
11969
|
}
|
|
12027
|
-
else if (this._peek.type ===
|
|
11970
|
+
else if (this._peek.type === 1 /* TAG_OPEN_END */) {
|
|
12028
11971
|
this._advance();
|
|
12029
11972
|
selfClosing = false;
|
|
12030
11973
|
}
|
|
@@ -12039,7 +11982,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
12039
11982
|
// element start tag also represents the end tag.
|
|
12040
11983
|
this._popElement(fullName, span);
|
|
12041
11984
|
}
|
|
12042
|
-
else if (startTagToken.type ===
|
|
11985
|
+
else if (startTagToken.type === 4 /* INCOMPLETE_TAG_OPEN */) {
|
|
12043
11986
|
// We already know the opening tag is not complete, so it is unlikely it has a corresponding
|
|
12044
11987
|
// close tag. Let's optimistically parse it as a full element and emit an error.
|
|
12045
11988
|
this._popElement(fullName, null);
|
|
@@ -12094,24 +12037,53 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
12094
12037
|
}
|
|
12095
12038
|
_consumeAttr(attrName) {
|
|
12096
12039
|
const fullName = mergeNsAndName(attrName.parts[0], attrName.parts[1]);
|
|
12097
|
-
let
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
if (this._peek.type === TokenType.ATTR_QUOTE) {
|
|
12040
|
+
let attrEnd = attrName.sourceSpan.end;
|
|
12041
|
+
// Consume any quote
|
|
12042
|
+
if (this._peek.type === 15 /* ATTR_QUOTE */) {
|
|
12101
12043
|
this._advance();
|
|
12102
12044
|
}
|
|
12103
|
-
|
|
12104
|
-
|
|
12105
|
-
|
|
12106
|
-
|
|
12107
|
-
|
|
12045
|
+
// Consume the attribute value
|
|
12046
|
+
let value = '';
|
|
12047
|
+
const valueTokens = [];
|
|
12048
|
+
let valueStartSpan = undefined;
|
|
12049
|
+
let valueEnd = undefined;
|
|
12050
|
+
// NOTE: We need to use a new variable `nextTokenType` here to hide the actual type of
|
|
12051
|
+
// `_peek.type` from TS. Otherwise TS will narrow the type of `_peek.type` preventing it from
|
|
12052
|
+
// being able to consider `ATTR_VALUE_INTERPOLATION` as an option. This is because TS is not
|
|
12053
|
+
// able to see that `_advance()` will actually mutate `_peek`.
|
|
12054
|
+
const nextTokenType = this._peek.type;
|
|
12055
|
+
if (nextTokenType === 16 /* ATTR_VALUE_TEXT */) {
|
|
12056
|
+
valueStartSpan = this._peek.sourceSpan;
|
|
12057
|
+
valueEnd = this._peek.sourceSpan.end;
|
|
12058
|
+
while (this._peek.type === 16 /* ATTR_VALUE_TEXT */ ||
|
|
12059
|
+
this._peek.type === 17 /* ATTR_VALUE_INTERPOLATION */ ||
|
|
12060
|
+
this._peek.type === 9 /* ENCODED_ENTITY */) {
|
|
12061
|
+
const valueToken = this._advance();
|
|
12062
|
+
valueTokens.push(valueToken);
|
|
12063
|
+
if (valueToken.type === 17 /* ATTR_VALUE_INTERPOLATION */) {
|
|
12064
|
+
// For backward compatibility we decode HTML entities that appear in interpolation
|
|
12065
|
+
// expressions. This is arguably a bug, but it could be a considerable breaking change to
|
|
12066
|
+
// fix it. It should be addressed in a larger project to refactor the entire parser/lexer
|
|
12067
|
+
// chain after View Engine has been removed.
|
|
12068
|
+
value += valueToken.parts.join('').replace(/&([^;]+);/g, decodeEntity);
|
|
12069
|
+
}
|
|
12070
|
+
else if (valueToken.type === 9 /* ENCODED_ENTITY */) {
|
|
12071
|
+
value += valueToken.parts[0];
|
|
12072
|
+
}
|
|
12073
|
+
else {
|
|
12074
|
+
value += valueToken.parts.join('');
|
|
12075
|
+
}
|
|
12076
|
+
valueEnd = attrEnd = valueToken.sourceSpan.end;
|
|
12077
|
+
}
|
|
12108
12078
|
}
|
|
12109
|
-
|
|
12079
|
+
// Consume any quote
|
|
12080
|
+
if (this._peek.type === 15 /* ATTR_QUOTE */) {
|
|
12110
12081
|
const quoteToken = this._advance();
|
|
12111
|
-
|
|
12082
|
+
attrEnd = quoteToken.sourceSpan.end;
|
|
12112
12083
|
}
|
|
12113
|
-
const
|
|
12114
|
-
|
|
12084
|
+
const valueSpan = valueStartSpan && valueEnd &&
|
|
12085
|
+
new ParseSourceSpan(valueStartSpan.start, valueEnd, valueStartSpan.fullStart);
|
|
12086
|
+
return new Attribute(fullName, value, new ParseSourceSpan(attrName.sourceSpan.start, attrEnd, attrName.sourceSpan.fullStart), attrName.sourceSpan, valueSpan, valueTokens.length > 0 ? valueTokens : undefined, undefined);
|
|
12115
12087
|
}
|
|
12116
12088
|
_getParentElement() {
|
|
12117
12089
|
return this._elementStack.length > 0 ? this._elementStack[this._elementStack.length - 1] : null;
|
|
@@ -12142,6 +12114,23 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
12142
12114
|
function lastOnStack(stack, element) {
|
|
12143
12115
|
return stack.length > 0 && stack[stack.length - 1] === element;
|
|
12144
12116
|
}
|
|
12117
|
+
/**
|
|
12118
|
+
* Decode the `entity` string, which we believe is the contents of an HTML entity.
|
|
12119
|
+
*
|
|
12120
|
+
* If the string is not actually a valid/known entity then just return the original `match` string.
|
|
12121
|
+
*/
|
|
12122
|
+
function decodeEntity(match, entity) {
|
|
12123
|
+
if (NAMED_ENTITIES[entity] !== undefined) {
|
|
12124
|
+
return NAMED_ENTITIES[entity] || match;
|
|
12125
|
+
}
|
|
12126
|
+
if (/^#x[a-f0-9]+$/i.test(entity)) {
|
|
12127
|
+
return String.fromCodePoint(parseInt(entity.slice(2), 16));
|
|
12128
|
+
}
|
|
12129
|
+
if (/^#\d+$/.test(entity)) {
|
|
12130
|
+
return String.fromCodePoint(parseInt(entity.slice(1), 10));
|
|
12131
|
+
}
|
|
12132
|
+
return match;
|
|
12133
|
+
}
|
|
12145
12134
|
|
|
12146
12135
|
/**
|
|
12147
12136
|
* @license
|
|
@@ -12217,7 +12206,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
12217
12206
|
const hasExpansionSibling = context &&
|
|
12218
12207
|
(context.prev instanceof Expansion || context.next instanceof Expansion);
|
|
12219
12208
|
if (isNotBlank || hasExpansionSibling) {
|
|
12220
|
-
|
|
12209
|
+
// Process the whitespace in the tokens of this Text node
|
|
12210
|
+
const tokens = text.tokens.map(token => token.type === 5 /* TEXT */ ? createWhitespaceProcessedTextToken(token) : token);
|
|
12211
|
+
// Process the whitespace of the value of this Text node
|
|
12212
|
+
const value = processWhitespace(text.value);
|
|
12213
|
+
return new Text$2(value, text.sourceSpan, tokens, text.i18n);
|
|
12221
12214
|
}
|
|
12222
12215
|
return null;
|
|
12223
12216
|
}
|
|
@@ -12231,6 +12224,12 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
12231
12224
|
return expansionCase;
|
|
12232
12225
|
}
|
|
12233
12226
|
}
|
|
12227
|
+
function createWhitespaceProcessedTextToken({ type, parts, sourceSpan }) {
|
|
12228
|
+
return { type, parts: [processWhitespace(parts[0])], sourceSpan };
|
|
12229
|
+
}
|
|
12230
|
+
function processWhitespace(text) {
|
|
12231
|
+
return replaceNgsp(text).replace(WS_REPLACE_REGEXP, ' ');
|
|
12232
|
+
}
|
|
12234
12233
|
function visitAllWithSiblings(visitor, nodes) {
|
|
12235
12234
|
const result = [];
|
|
12236
12235
|
nodes.forEach((ast, i) => {
|
|
@@ -13481,7 +13480,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
13481
13480
|
* Use of this source code is governed by an MIT-style license that can be
|
|
13482
13481
|
* found in the LICENSE file at https://angular.io/license
|
|
13483
13482
|
*/
|
|
13484
|
-
var TokenType
|
|
13483
|
+
var TokenType;
|
|
13485
13484
|
(function (TokenType) {
|
|
13486
13485
|
TokenType[TokenType["Character"] = 0] = "Character";
|
|
13487
13486
|
TokenType[TokenType["Identifier"] = 1] = "Identifier";
|
|
@@ -13491,7 +13490,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
13491
13490
|
TokenType[TokenType["Operator"] = 5] = "Operator";
|
|
13492
13491
|
TokenType[TokenType["Number"] = 6] = "Number";
|
|
13493
13492
|
TokenType[TokenType["Error"] = 7] = "Error";
|
|
13494
|
-
})(TokenType
|
|
13493
|
+
})(TokenType || (TokenType = {}));
|
|
13495
13494
|
const KEYWORDS = ['var', 'let', 'as', 'null', 'undefined', 'true', 'false', 'if', 'else', 'this'];
|
|
13496
13495
|
class Lexer {
|
|
13497
13496
|
tokenize(text) {
|
|
@@ -13505,7 +13504,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
13505
13504
|
return tokens;
|
|
13506
13505
|
}
|
|
13507
13506
|
}
|
|
13508
|
-
class Token
|
|
13507
|
+
class Token {
|
|
13509
13508
|
constructor(index, end, type, numValue, strValue) {
|
|
13510
13509
|
this.index = index;
|
|
13511
13510
|
this.end = end;
|
|
@@ -13514,64 +13513,64 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
13514
13513
|
this.strValue = strValue;
|
|
13515
13514
|
}
|
|
13516
13515
|
isCharacter(code) {
|
|
13517
|
-
return this.type == TokenType
|
|
13516
|
+
return this.type == TokenType.Character && this.numValue == code;
|
|
13518
13517
|
}
|
|
13519
13518
|
isNumber() {
|
|
13520
|
-
return this.type == TokenType
|
|
13519
|
+
return this.type == TokenType.Number;
|
|
13521
13520
|
}
|
|
13522
13521
|
isString() {
|
|
13523
|
-
return this.type == TokenType
|
|
13522
|
+
return this.type == TokenType.String;
|
|
13524
13523
|
}
|
|
13525
13524
|
isOperator(operator) {
|
|
13526
|
-
return this.type == TokenType
|
|
13525
|
+
return this.type == TokenType.Operator && this.strValue == operator;
|
|
13527
13526
|
}
|
|
13528
13527
|
isIdentifier() {
|
|
13529
|
-
return this.type == TokenType
|
|
13528
|
+
return this.type == TokenType.Identifier;
|
|
13530
13529
|
}
|
|
13531
13530
|
isPrivateIdentifier() {
|
|
13532
|
-
return this.type == TokenType
|
|
13531
|
+
return this.type == TokenType.PrivateIdentifier;
|
|
13533
13532
|
}
|
|
13534
13533
|
isKeyword() {
|
|
13535
|
-
return this.type == TokenType
|
|
13534
|
+
return this.type == TokenType.Keyword;
|
|
13536
13535
|
}
|
|
13537
13536
|
isKeywordLet() {
|
|
13538
|
-
return this.type == TokenType
|
|
13537
|
+
return this.type == TokenType.Keyword && this.strValue == 'let';
|
|
13539
13538
|
}
|
|
13540
13539
|
isKeywordAs() {
|
|
13541
|
-
return this.type == TokenType
|
|
13540
|
+
return this.type == TokenType.Keyword && this.strValue == 'as';
|
|
13542
13541
|
}
|
|
13543
13542
|
isKeywordNull() {
|
|
13544
|
-
return this.type == TokenType
|
|
13543
|
+
return this.type == TokenType.Keyword && this.strValue == 'null';
|
|
13545
13544
|
}
|
|
13546
13545
|
isKeywordUndefined() {
|
|
13547
|
-
return this.type == TokenType
|
|
13546
|
+
return this.type == TokenType.Keyword && this.strValue == 'undefined';
|
|
13548
13547
|
}
|
|
13549
13548
|
isKeywordTrue() {
|
|
13550
|
-
return this.type == TokenType
|
|
13549
|
+
return this.type == TokenType.Keyword && this.strValue == 'true';
|
|
13551
13550
|
}
|
|
13552
13551
|
isKeywordFalse() {
|
|
13553
|
-
return this.type == TokenType
|
|
13552
|
+
return this.type == TokenType.Keyword && this.strValue == 'false';
|
|
13554
13553
|
}
|
|
13555
13554
|
isKeywordThis() {
|
|
13556
|
-
return this.type == TokenType
|
|
13555
|
+
return this.type == TokenType.Keyword && this.strValue == 'this';
|
|
13557
13556
|
}
|
|
13558
13557
|
isError() {
|
|
13559
|
-
return this.type == TokenType
|
|
13558
|
+
return this.type == TokenType.Error;
|
|
13560
13559
|
}
|
|
13561
13560
|
toNumber() {
|
|
13562
|
-
return this.type == TokenType
|
|
13561
|
+
return this.type == TokenType.Number ? this.numValue : -1;
|
|
13563
13562
|
}
|
|
13564
13563
|
toString() {
|
|
13565
13564
|
switch (this.type) {
|
|
13566
|
-
case TokenType
|
|
13567
|
-
case TokenType
|
|
13568
|
-
case TokenType
|
|
13569
|
-
case TokenType
|
|
13570
|
-
case TokenType
|
|
13571
|
-
case TokenType
|
|
13572
|
-
case TokenType
|
|
13565
|
+
case TokenType.Character:
|
|
13566
|
+
case TokenType.Identifier:
|
|
13567
|
+
case TokenType.Keyword:
|
|
13568
|
+
case TokenType.Operator:
|
|
13569
|
+
case TokenType.PrivateIdentifier:
|
|
13570
|
+
case TokenType.String:
|
|
13571
|
+
case TokenType.Error:
|
|
13573
13572
|
return this.strValue;
|
|
13574
|
-
case TokenType
|
|
13573
|
+
case TokenType.Number:
|
|
13575
13574
|
return this.numValue.toString();
|
|
13576
13575
|
default:
|
|
13577
13576
|
return null;
|
|
@@ -13579,30 +13578,30 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
13579
13578
|
}
|
|
13580
13579
|
}
|
|
13581
13580
|
function newCharacterToken(index, end, code) {
|
|
13582
|
-
return new Token
|
|
13581
|
+
return new Token(index, end, TokenType.Character, code, String.fromCharCode(code));
|
|
13583
13582
|
}
|
|
13584
13583
|
function newIdentifierToken(index, end, text) {
|
|
13585
|
-
return new Token
|
|
13584
|
+
return new Token(index, end, TokenType.Identifier, 0, text);
|
|
13586
13585
|
}
|
|
13587
13586
|
function newPrivateIdentifierToken(index, end, text) {
|
|
13588
|
-
return new Token
|
|
13587
|
+
return new Token(index, end, TokenType.PrivateIdentifier, 0, text);
|
|
13589
13588
|
}
|
|
13590
13589
|
function newKeywordToken(index, end, text) {
|
|
13591
|
-
return new Token
|
|
13590
|
+
return new Token(index, end, TokenType.Keyword, 0, text);
|
|
13592
13591
|
}
|
|
13593
13592
|
function newOperatorToken(index, end, text) {
|
|
13594
|
-
return new Token
|
|
13593
|
+
return new Token(index, end, TokenType.Operator, 0, text);
|
|
13595
13594
|
}
|
|
13596
13595
|
function newStringToken(index, end, text) {
|
|
13597
|
-
return new Token
|
|
13596
|
+
return new Token(index, end, TokenType.String, 0, text);
|
|
13598
13597
|
}
|
|
13599
13598
|
function newNumberToken(index, end, n) {
|
|
13600
|
-
return new Token
|
|
13599
|
+
return new Token(index, end, TokenType.Number, n, '');
|
|
13601
13600
|
}
|
|
13602
13601
|
function newErrorToken(index, end, message) {
|
|
13603
|
-
return new Token
|
|
13602
|
+
return new Token(index, end, TokenType.Error, 0, message);
|
|
13604
13603
|
}
|
|
13605
|
-
const EOF = new Token
|
|
13604
|
+
const EOF = new Token(-1, -1, TokenType.Character, 0, '');
|
|
13606
13605
|
class _Scanner {
|
|
13607
13606
|
constructor(input) {
|
|
13608
13607
|
this.input = input;
|
|
@@ -14509,7 +14508,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14509
14508
|
// '==','!=','===','!=='
|
|
14510
14509
|
const start = this.inputIndex;
|
|
14511
14510
|
let result = this.parseRelational();
|
|
14512
|
-
while (this.next.type == TokenType
|
|
14511
|
+
while (this.next.type == TokenType.Operator) {
|
|
14513
14512
|
const operator = this.next.strValue;
|
|
14514
14513
|
switch (operator) {
|
|
14515
14514
|
case '==':
|
|
@@ -14529,7 +14528,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14529
14528
|
// '<', '>', '<=', '>='
|
|
14530
14529
|
const start = this.inputIndex;
|
|
14531
14530
|
let result = this.parseAdditive();
|
|
14532
|
-
while (this.next.type == TokenType
|
|
14531
|
+
while (this.next.type == TokenType.Operator) {
|
|
14533
14532
|
const operator = this.next.strValue;
|
|
14534
14533
|
switch (operator) {
|
|
14535
14534
|
case '<':
|
|
@@ -14549,7 +14548,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14549
14548
|
// '+', '-'
|
|
14550
14549
|
const start = this.inputIndex;
|
|
14551
14550
|
let result = this.parseMultiplicative();
|
|
14552
|
-
while (this.next.type == TokenType
|
|
14551
|
+
while (this.next.type == TokenType.Operator) {
|
|
14553
14552
|
const operator = this.next.strValue;
|
|
14554
14553
|
switch (operator) {
|
|
14555
14554
|
case '+':
|
|
@@ -14567,7 +14566,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14567
14566
|
// '*', '%', '/'
|
|
14568
14567
|
const start = this.inputIndex;
|
|
14569
14568
|
let result = this.parsePrefix();
|
|
14570
|
-
while (this.next.type == TokenType
|
|
14569
|
+
while (this.next.type == TokenType.Operator) {
|
|
14571
14570
|
const operator = this.next.strValue;
|
|
14572
14571
|
switch (operator) {
|
|
14573
14572
|
case '*':
|
|
@@ -14583,7 +14582,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14583
14582
|
return result;
|
|
14584
14583
|
}
|
|
14585
14584
|
parsePrefix() {
|
|
14586
|
-
if (this.next.type == TokenType
|
|
14585
|
+
if (this.next.type == TokenType.Operator) {
|
|
14587
14586
|
const start = this.inputIndex;
|
|
14588
14587
|
const operator = this.next.strValue;
|
|
14589
14588
|
let result;
|
|
@@ -14609,22 +14608,24 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14609
14608
|
let result = this.parsePrimary();
|
|
14610
14609
|
while (true) {
|
|
14611
14610
|
if (this.consumeOptionalCharacter($PERIOD)) {
|
|
14612
|
-
result = this.
|
|
14611
|
+
result = this.parseAccessMemberOrCall(result, start, false);
|
|
14613
14612
|
}
|
|
14614
14613
|
else if (this.consumeOptionalOperator('?.')) {
|
|
14615
14614
|
result = this.consumeOptionalCharacter($LBRACKET) ?
|
|
14616
14615
|
this.parseKeyedReadOrWrite(result, start, true) :
|
|
14617
|
-
this.
|
|
14616
|
+
this.parseAccessMemberOrCall(result, start, true);
|
|
14618
14617
|
}
|
|
14619
14618
|
else if (this.consumeOptionalCharacter($LBRACKET)) {
|
|
14620
14619
|
result = this.parseKeyedReadOrWrite(result, start, false);
|
|
14621
14620
|
}
|
|
14622
14621
|
else if (this.consumeOptionalCharacter($LPAREN)) {
|
|
14622
|
+
const argumentStart = this.inputIndex;
|
|
14623
14623
|
this.rparensExpected++;
|
|
14624
14624
|
const args = this.parseCallArguments();
|
|
14625
|
+
const argumentSpan = this.span(argumentStart, this.inputIndex).toAbsolute(this.absoluteOffset);
|
|
14625
14626
|
this.rparensExpected--;
|
|
14626
14627
|
this.expectCharacter($RPAREN);
|
|
14627
|
-
result = new
|
|
14628
|
+
result = new Call(this.span(start), this.sourceSpan(start), result, args, argumentSpan);
|
|
14628
14629
|
}
|
|
14629
14630
|
else if (this.consumeOptionalOperator('!')) {
|
|
14630
14631
|
result = new NonNullAssert(this.span(start), this.sourceSpan(start), result);
|
|
@@ -14674,7 +14675,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14674
14675
|
return this.parseLiteralMap();
|
|
14675
14676
|
}
|
|
14676
14677
|
else if (this.next.isIdentifier()) {
|
|
14677
|
-
return this.
|
|
14678
|
+
return this.parseAccessMemberOrCall(new ImplicitReceiver(this.span(start), this.sourceSpan(start)), start, false);
|
|
14678
14679
|
}
|
|
14679
14680
|
else if (this.next.isNumber()) {
|
|
14680
14681
|
const value = this.next.toNumber();
|
|
@@ -14742,17 +14743,41 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14742
14743
|
}
|
|
14743
14744
|
return new LiteralMap(this.span(start), this.sourceSpan(start), keys, values);
|
|
14744
14745
|
}
|
|
14745
|
-
|
|
14746
|
+
parseAccessMemberOrCall(readReceiver, start, isSafe) {
|
|
14746
14747
|
const nameStart = this.inputIndex;
|
|
14747
14748
|
const id = this.withContext(ParseContextFlags.Writable, () => {
|
|
14748
14749
|
var _a;
|
|
14749
14750
|
const id = (_a = this.expectIdentifierOrKeyword()) !== null && _a !== void 0 ? _a : '';
|
|
14750
14751
|
if (id.length === 0) {
|
|
14751
|
-
this.error(`Expected identifier for property access`,
|
|
14752
|
+
this.error(`Expected identifier for property access`, readReceiver.span.end);
|
|
14752
14753
|
}
|
|
14753
14754
|
return id;
|
|
14754
14755
|
});
|
|
14755
14756
|
const nameSpan = this.sourceSpan(nameStart);
|
|
14757
|
+
let receiver;
|
|
14758
|
+
if (isSafe) {
|
|
14759
|
+
if (this.consumeOptionalOperator('=')) {
|
|
14760
|
+
this.error('The \'?.\' operator cannot be used in the assignment');
|
|
14761
|
+
receiver = new EmptyExpr(this.span(start), this.sourceSpan(start));
|
|
14762
|
+
}
|
|
14763
|
+
else {
|
|
14764
|
+
receiver = new SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
|
|
14765
|
+
}
|
|
14766
|
+
}
|
|
14767
|
+
else {
|
|
14768
|
+
if (this.consumeOptionalOperator('=')) {
|
|
14769
|
+
if (!this.parseAction) {
|
|
14770
|
+
this.error('Bindings cannot contain assignments');
|
|
14771
|
+
return new EmptyExpr(this.span(start), this.sourceSpan(start));
|
|
14772
|
+
}
|
|
14773
|
+
const value = this.parseConditional();
|
|
14774
|
+
receiver = new PropertyWrite(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id, value);
|
|
14775
|
+
}
|
|
14776
|
+
else {
|
|
14777
|
+
receiver =
|
|
14778
|
+
new PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
|
|
14779
|
+
}
|
|
14780
|
+
}
|
|
14756
14781
|
if (this.consumeOptionalCharacter($LPAREN)) {
|
|
14757
14782
|
const argumentStart = this.inputIndex;
|
|
14758
14783
|
this.rparensExpected++;
|
|
@@ -14762,34 +14787,9 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
14762
14787
|
this.rparensExpected--;
|
|
14763
14788
|
const span = this.span(start);
|
|
14764
14789
|
const sourceSpan = this.sourceSpan(start);
|
|
14765
|
-
return
|
|
14766
|
-
new SafeMethodCall(span, sourceSpan, nameSpan, receiver, id, args, argumentSpan) :
|
|
14767
|
-
new MethodCall(span, sourceSpan, nameSpan, receiver, id, args, argumentSpan);
|
|
14768
|
-
}
|
|
14769
|
-
else {
|
|
14770
|
-
if (isSafe) {
|
|
14771
|
-
if (this.consumeOptionalOperator('=')) {
|
|
14772
|
-
this.error('The \'?.\' operator cannot be used in the assignment');
|
|
14773
|
-
return new EmptyExpr(this.span(start), this.sourceSpan(start));
|
|
14774
|
-
}
|
|
14775
|
-
else {
|
|
14776
|
-
return new SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, receiver, id);
|
|
14777
|
-
}
|
|
14778
|
-
}
|
|
14779
|
-
else {
|
|
14780
|
-
if (this.consumeOptionalOperator('=')) {
|
|
14781
|
-
if (!this.parseAction) {
|
|
14782
|
-
this.error('Bindings cannot contain assignments');
|
|
14783
|
-
return new EmptyExpr(this.span(start), this.sourceSpan(start));
|
|
14784
|
-
}
|
|
14785
|
-
const value = this.parseConditional();
|
|
14786
|
-
return new PropertyWrite(this.span(start), this.sourceSpan(start), nameSpan, receiver, id, value);
|
|
14787
|
-
}
|
|
14788
|
-
else {
|
|
14789
|
-
return new PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, receiver, id);
|
|
14790
|
-
}
|
|
14791
|
-
}
|
|
14790
|
+
return new Call(span, sourceSpan, receiver, args, argumentSpan);
|
|
14792
14791
|
}
|
|
14792
|
+
return receiver;
|
|
14793
14793
|
}
|
|
14794
14794
|
parseCallArguments() {
|
|
14795
14795
|
if (this.next.isCharacter($RPAREN))
|
|
@@ -15085,9 +15085,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
15085
15085
|
visitPropertyRead(ast, context) { }
|
|
15086
15086
|
visitPropertyWrite(ast, context) { }
|
|
15087
15087
|
visitSafePropertyRead(ast, context) { }
|
|
15088
|
-
|
|
15089
|
-
visitSafeMethodCall(ast, context) { }
|
|
15090
|
-
visitFunctionCall(ast, context) { }
|
|
15088
|
+
visitCall(ast, context) { }
|
|
15091
15089
|
visitLiteralArray(ast, context) {
|
|
15092
15090
|
this.visitAll(ast.expressions, context);
|
|
15093
15091
|
}
|
|
@@ -16515,11 +16513,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
16515
16513
|
return context.visitNodeFn(el, node);
|
|
16516
16514
|
}
|
|
16517
16515
|
visitAttribute(attribute, context) {
|
|
16518
|
-
const node =
|
|
16516
|
+
const node = attribute.valueTokens === undefined || attribute.valueTokens.length === 1 ?
|
|
16517
|
+
new Text$1(attribute.value, attribute.valueSpan || attribute.sourceSpan) :
|
|
16518
|
+
this._visitTextWithInterpolation(attribute.valueTokens, attribute.valueSpan || attribute.sourceSpan, context, attribute.i18n);
|
|
16519
16519
|
return context.visitNodeFn(attribute, node);
|
|
16520
16520
|
}
|
|
16521
16521
|
visitText(text, context) {
|
|
16522
|
-
const node =
|
|
16522
|
+
const node = text.tokens.length === 1 ?
|
|
16523
|
+
new Text$1(text.value, text.sourceSpan) :
|
|
16524
|
+
this._visitTextWithInterpolation(text.tokens, text.sourceSpan, context, text.i18n);
|
|
16523
16525
|
return context.visitNodeFn(text, node);
|
|
16524
16526
|
}
|
|
16525
16527
|
visitComment(comment, context) {
|
|
@@ -16558,61 +16560,58 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
16558
16560
|
throw new Error('Unreachable code');
|
|
16559
16561
|
}
|
|
16560
16562
|
/**
|
|
16561
|
-
*
|
|
16563
|
+
* Convert, text and interpolated tokens up into text and placeholder pieces.
|
|
16562
16564
|
*
|
|
16563
|
-
* @param
|
|
16565
|
+
* @param tokens The text and interpolated tokens.
|
|
16564
16566
|
* @param sourceSpan The span of the whole of the `text` string.
|
|
16565
16567
|
* @param context The current context of the visitor, used to compute and store placeholders.
|
|
16566
16568
|
* @param previousI18n Any i18n metadata associated with this `text` from a previous pass.
|
|
16567
16569
|
*/
|
|
16568
|
-
_visitTextWithInterpolation(
|
|
16569
|
-
const { strings, expressions } = this._expressionParser.splitInterpolation(text, sourceSpan.start.toString(), this._interpolationConfig);
|
|
16570
|
-
// No expressions, return a single text.
|
|
16571
|
-
if (expressions.length === 0) {
|
|
16572
|
-
return new Text$1(text, sourceSpan);
|
|
16573
|
-
}
|
|
16570
|
+
_visitTextWithInterpolation(tokens, sourceSpan, context, previousI18n) {
|
|
16574
16571
|
// Return a sequence of `Text` and `Placeholder` nodes grouped in a `Container`.
|
|
16575
16572
|
const nodes = [];
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16573
|
+
// We will only create a container if there are actually interpolations,
|
|
16574
|
+
// so this flag tracks that.
|
|
16575
|
+
let hasInterpolation = false;
|
|
16576
|
+
for (const token of tokens) {
|
|
16577
|
+
switch (token.type) {
|
|
16578
|
+
case 8 /* INTERPOLATION */:
|
|
16579
|
+
case 17 /* ATTR_VALUE_INTERPOLATION */:
|
|
16580
|
+
hasInterpolation = true;
|
|
16581
|
+
const expression = token.parts[1];
|
|
16582
|
+
const baseName = extractPlaceholderName(expression) || 'INTERPOLATION';
|
|
16583
|
+
const phName = context.placeholderRegistry.getPlaceholderName(baseName, expression);
|
|
16584
|
+
context.placeholderToContent[phName] = {
|
|
16585
|
+
text: token.parts.join(''),
|
|
16586
|
+
sourceSpan: token.sourceSpan
|
|
16587
|
+
};
|
|
16588
|
+
nodes.push(new Placeholder(expression, phName, token.sourceSpan));
|
|
16589
|
+
break;
|
|
16590
|
+
default:
|
|
16591
|
+
if (token.parts[0].length > 0) {
|
|
16592
|
+
// This token is text or an encoded entity.
|
|
16593
|
+
// If it is following on from a previous text node then merge it into that node
|
|
16594
|
+
// Otherwise, if it is following an interpolation, then add a new node.
|
|
16595
|
+
const previous = nodes[nodes.length - 1];
|
|
16596
|
+
if (previous instanceof Text$1) {
|
|
16597
|
+
previous.value += token.parts[0];
|
|
16598
|
+
previous.sourceSpan = new ParseSourceSpan(previous.sourceSpan.start, token.sourceSpan.end, previous.sourceSpan.fullStart, previous.sourceSpan.details);
|
|
16599
|
+
}
|
|
16600
|
+
else {
|
|
16601
|
+
nodes.push(new Text$1(token.parts[0], token.sourceSpan));
|
|
16602
|
+
}
|
|
16603
|
+
}
|
|
16604
|
+
break;
|
|
16605
|
+
}
|
|
16579
16606
|
}
|
|
16580
|
-
|
|
16581
|
-
|
|
16582
|
-
|
|
16583
|
-
|
|
16584
|
-
|
|
16585
|
-
|
|
16586
|
-
|
|
16587
|
-
* Create a new `Text` node from the `textPiece` and add it to the `nodes` collection.
|
|
16588
|
-
*
|
|
16589
|
-
* @param nodes The nodes to which the created `Text` node should be added.
|
|
16590
|
-
* @param textPiece The text and relative span information for this `Text` node.
|
|
16591
|
-
* @param interpolationSpan The span of the whole interpolated text.
|
|
16592
|
-
*/
|
|
16593
|
-
_addText(nodes, textPiece, interpolationSpan) {
|
|
16594
|
-
if (textPiece.text.length > 0) {
|
|
16595
|
-
// No need to add empty strings
|
|
16596
|
-
const stringSpan = getOffsetSourceSpan(interpolationSpan, textPiece);
|
|
16597
|
-
nodes.push(new Text$1(textPiece.text, stringSpan));
|
|
16607
|
+
if (hasInterpolation) {
|
|
16608
|
+
// Whitespace removal may have invalidated the interpolation source-spans.
|
|
16609
|
+
reusePreviousSourceSpans(nodes, previousI18n);
|
|
16610
|
+
return new Container(nodes, sourceSpan);
|
|
16611
|
+
}
|
|
16612
|
+
else {
|
|
16613
|
+
return nodes[0];
|
|
16598
16614
|
}
|
|
16599
|
-
}
|
|
16600
|
-
/**
|
|
16601
|
-
* Create a new `Placeholder` node from the `expression` and add it to the `nodes` collection.
|
|
16602
|
-
*
|
|
16603
|
-
* @param nodes The nodes to which the created `Text` node should be added.
|
|
16604
|
-
* @param context The current context of the visitor, used to compute and store placeholders.
|
|
16605
|
-
* @param expression The expression text and relative span information for this `Placeholder`
|
|
16606
|
-
* node.
|
|
16607
|
-
* @param interpolationSpan The span of the whole interpolated text.
|
|
16608
|
-
*/
|
|
16609
|
-
_addPlaceholder(nodes, context, expression, interpolationSpan) {
|
|
16610
|
-
const sourceSpan = getOffsetSourceSpan(interpolationSpan, expression);
|
|
16611
|
-
const baseName = extractPlaceholderName(expression.text) || 'INTERPOLATION';
|
|
16612
|
-
const phName = context.placeholderRegistry.getPlaceholderName(baseName, expression.text);
|
|
16613
|
-
const text = this._interpolationConfig.start + expression.text + this._interpolationConfig.end;
|
|
16614
|
-
context.placeholderToContent[phName] = { text, sourceSpan };
|
|
16615
|
-
nodes.push(new Placeholder(expression.text, phName, sourceSpan));
|
|
16616
16615
|
}
|
|
16617
16616
|
}
|
|
16618
16617
|
/**
|
|
@@ -16634,7 +16633,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
16634
16633
|
}
|
|
16635
16634
|
if (previousI18n instanceof Container) {
|
|
16636
16635
|
// The `previousI18n` is a `Container`, which means that this is a second i18n extraction pass
|
|
16637
|
-
// after whitespace has been removed from the AST
|
|
16636
|
+
// after whitespace has been removed from the AST nodes.
|
|
16638
16637
|
assertEquivalentNodes(previousI18n.children, nodes);
|
|
16639
16638
|
// Reuse the source-spans from the first pass.
|
|
16640
16639
|
for (let i = 0; i < nodes.length; i++) {
|
|
@@ -16663,12 +16662,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
16663
16662
|
throw new Error('The types of the i18n message children changed between first and second pass.');
|
|
16664
16663
|
}
|
|
16665
16664
|
}
|
|
16666
|
-
/**
|
|
16667
|
-
* Create a new `ParseSourceSpan` from the `sourceSpan`, offset by the `start` and `end` values.
|
|
16668
|
-
*/
|
|
16669
|
-
function getOffsetSourceSpan(sourceSpan, { start, end }) {
|
|
16670
|
-
return new ParseSourceSpan(sourceSpan.fullStart.moveBy(start), sourceSpan.fullStart.moveBy(end));
|
|
16671
|
-
}
|
|
16672
16665
|
const _CUSTOM_PH_EXP = /\/\/[\s\S]*i18n[\s\S]*\([\s\S]*ph[\s\S]*=[\s\S]*("|')([\s\S]*?)\1[\s\S]*\)/g;
|
|
16673
16666
|
function extractPlaceholderName(input) {
|
|
16674
16667
|
return input.split(_CUSTOM_PH_EXP)[2];
|
|
@@ -16988,7 +16981,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
16988
16981
|
context[context.length - 1].text += text.value;
|
|
16989
16982
|
}
|
|
16990
16983
|
else {
|
|
16991
|
-
|
|
16984
|
+
const sourceSpan = new ParseSourceSpan(text.sourceSpan.fullStart, text.sourceSpan.end, text.sourceSpan.fullStart, text.sourceSpan.details);
|
|
16985
|
+
context.push(new LiteralPiece(text.value, sourceSpan));
|
|
16992
16986
|
}
|
|
16993
16987
|
}
|
|
16994
16988
|
visitContainer(container, context) {
|
|
@@ -17032,7 +17026,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
17032
17026
|
function getSourceSpan(message) {
|
|
17033
17027
|
const startNode = message.nodes[0];
|
|
17034
17028
|
const endNode = message.nodes[message.nodes.length - 1];
|
|
17035
|
-
return new ParseSourceSpan(startNode.sourceSpan.
|
|
17029
|
+
return new ParseSourceSpan(startNode.sourceSpan.fullStart, endNode.sourceSpan.end, startNode.sourceSpan.fullStart, startNode.sourceSpan.details);
|
|
17036
17030
|
}
|
|
17037
17031
|
/**
|
|
17038
17032
|
* Convert the list of serialized MessagePieces into two arrays.
|
|
@@ -18266,11 +18260,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
18266
18260
|
const convertedArgs = isVarLength ?
|
|
18267
18261
|
this.visitAll([new LiteralArray(pipe.span, pipe.sourceSpan, args)]) :
|
|
18268
18262
|
this.visitAll(args);
|
|
18269
|
-
const pipeBindExpr = new
|
|
18263
|
+
const pipeBindExpr = new Call(pipe.span, pipe.sourceSpan, target, [
|
|
18270
18264
|
new LiteralPrimitive(pipe.span, pipe.sourceSpan, slot),
|
|
18271
18265
|
new LiteralPrimitive(pipe.span, pipe.sourceSpan, pureFunctionSlot),
|
|
18272
18266
|
...convertedArgs,
|
|
18273
|
-
]);
|
|
18267
|
+
], null);
|
|
18274
18268
|
this._pipeBindExprs.push(pipeBindExpr);
|
|
18275
18269
|
return pipeBindExpr;
|
|
18276
18270
|
}
|
|
@@ -19065,7 +19059,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
19065
19059
|
return fn([], [new ReturnStatement(list)]);
|
|
19066
19060
|
case 2 /* ClosureResolved */:
|
|
19067
19061
|
// directives: function () { return [MyDir].map(ng.resolveForwardRef); }
|
|
19068
|
-
const resolvedList = list.
|
|
19062
|
+
const resolvedList = list.prop('map').callFn([importExpr(Identifiers.resolveForwardRef)]);
|
|
19069
19063
|
return fn([], [new ReturnStatement(resolvedList)]);
|
|
19070
19064
|
}
|
|
19071
19065
|
}
|
|
@@ -19938,7 +19932,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
19938
19932
|
* Use of this source code is governed by an MIT-style license that can be
|
|
19939
19933
|
* found in the LICENSE file at https://angular.io/license
|
|
19940
19934
|
*/
|
|
19941
|
-
const VERSION$1 = new Version('13.0.0-next.
|
|
19935
|
+
const VERSION$1 = new Version('13.0.0-next.7');
|
|
19942
19936
|
|
|
19943
19937
|
/**
|
|
19944
19938
|
* @license
|
|
@@ -20436,14 +20430,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20436
20430
|
this.maybeMap(context, ast, ast.name);
|
|
20437
20431
|
return super.visitPropertyWrite(ast, context);
|
|
20438
20432
|
}
|
|
20439
|
-
visitMethodCall(ast, context) {
|
|
20440
|
-
this.maybeMap(context, ast, ast.name);
|
|
20441
|
-
return super.visitMethodCall(ast, context);
|
|
20442
|
-
}
|
|
20443
|
-
visitSafeMethodCall(ast, context) {
|
|
20444
|
-
this.maybeMap(context, ast, ast.name);
|
|
20445
|
-
return super.visitSafeMethodCall(ast, context);
|
|
20446
|
-
}
|
|
20447
20433
|
maybeMap(scope, ast, name) {
|
|
20448
20434
|
// If the receiver of the expression isn't the `ImplicitReceiver`, this isn't the root of an
|
|
20449
20435
|
// `AST` expression that maps to a `Variable` or `Reference`.
|
|
@@ -20577,7 +20563,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20577
20563
|
function compileDeclareClassMetadata(metadata) {
|
|
20578
20564
|
const definitionMap = new DefinitionMap();
|
|
20579
20565
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
|
|
20580
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20566
|
+
definitionMap.set('version', literal('13.0.0-next.7'));
|
|
20581
20567
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20582
20568
|
definitionMap.set('type', metadata.type);
|
|
20583
20569
|
definitionMap.set('decorators', metadata.decorators);
|
|
@@ -20617,7 +20603,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20617
20603
|
function createDirectiveDefinitionMap(meta) {
|
|
20618
20604
|
const definitionMap = new DefinitionMap();
|
|
20619
20605
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
|
|
20620
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20606
|
+
definitionMap.set('version', literal('13.0.0-next.7'));
|
|
20621
20607
|
// e.g. `type: MyDirective`
|
|
20622
20608
|
definitionMap.set('type', meta.internalType);
|
|
20623
20609
|
// e.g. `selector: 'some-dir'`
|
|
@@ -20834,7 +20820,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20834
20820
|
function compileDeclareFactoryFunction(meta) {
|
|
20835
20821
|
const definitionMap = new DefinitionMap();
|
|
20836
20822
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
|
|
20837
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20823
|
+
definitionMap.set('version', literal('13.0.0-next.7'));
|
|
20838
20824
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20839
20825
|
definitionMap.set('type', meta.internalType);
|
|
20840
20826
|
definitionMap.set('deps', compileDependencies(meta.deps));
|
|
@@ -20876,7 +20862,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20876
20862
|
function createInjectableDefinitionMap(meta) {
|
|
20877
20863
|
const definitionMap = new DefinitionMap();
|
|
20878
20864
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
|
|
20879
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20865
|
+
definitionMap.set('version', literal('13.0.0-next.7'));
|
|
20880
20866
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20881
20867
|
definitionMap.set('type', meta.internalType);
|
|
20882
20868
|
// Only generate providedIn property if it has a non-null value
|
|
@@ -20955,7 +20941,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20955
20941
|
function createInjectorDefinitionMap(meta) {
|
|
20956
20942
|
const definitionMap = new DefinitionMap();
|
|
20957
20943
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
|
|
20958
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20944
|
+
definitionMap.set('version', literal('13.0.0-next.7'));
|
|
20959
20945
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20960
20946
|
definitionMap.set('type', meta.internalType);
|
|
20961
20947
|
definitionMap.set('providers', meta.providers);
|
|
@@ -20992,7 +20978,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
20992
20978
|
function createNgModuleDefinitionMap(meta) {
|
|
20993
20979
|
const definitionMap = new DefinitionMap();
|
|
20994
20980
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
|
|
20995
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
20981
|
+
definitionMap.set('version', literal('13.0.0-next.7'));
|
|
20996
20982
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
20997
20983
|
definitionMap.set('type', meta.internalType);
|
|
20998
20984
|
// We only generate the keys in the metadata if the arrays contain values.
|
|
@@ -21050,7 +21036,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21050
21036
|
function createPipeDefinitionMap(meta) {
|
|
21051
21037
|
const definitionMap = new DefinitionMap();
|
|
21052
21038
|
definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
|
|
21053
|
-
definitionMap.set('version', literal('13.0.0-next.
|
|
21039
|
+
definitionMap.set('version', literal('13.0.0-next.7'));
|
|
21054
21040
|
definitionMap.set('ngImport', importExpr(Identifiers.core));
|
|
21055
21041
|
// e.g. `type: MyPipe`
|
|
21056
21042
|
definitionMap.set('type', meta.internalType);
|
|
@@ -21082,7 +21068,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21082
21068
|
* Use of this source code is governed by an MIT-style license that can be
|
|
21083
21069
|
* found in the LICENSE file at https://angular.io/license
|
|
21084
21070
|
*/
|
|
21085
|
-
const VERSION$2 = new Version('13.0.0-next.
|
|
21071
|
+
const VERSION$2 = new Version('13.0.0-next.7');
|
|
21086
21072
|
|
|
21087
21073
|
/**
|
|
21088
21074
|
* @license
|
|
@@ -21294,6 +21280,15 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
21294
21280
|
* ```
|
|
21295
21281
|
*/
|
|
21296
21282
|
ErrorCode[ErrorCode["INVALID_BANANA_IN_BOX"] = 8101] = "INVALID_BANANA_IN_BOX";
|
|
21283
|
+
/**
|
|
21284
|
+
* The left side of a nullish coalescing operation is not nullable.
|
|
21285
|
+
*
|
|
21286
|
+
* ```
|
|
21287
|
+
* {{ foo ?? bar }}
|
|
21288
|
+
* ```
|
|
21289
|
+
* When the type of foo doesn't include `null` or `undefined`.
|
|
21290
|
+
*/
|
|
21291
|
+
ErrorCode[ErrorCode["NULLISH_COALESCING_NOT_NULLABLE"] = 8102] = "NULLISH_COALESCING_NOT_NULLABLE";
|
|
21297
21292
|
/**
|
|
21298
21293
|
* The template type-checking engine would need to generate an inline type check block for a
|
|
21299
21294
|
* component, but the current type-checking environment doesn't support it.
|
|
@@ -23210,11 +23205,11 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
23210
23205
|
getAdjacentNameOfClass(clazz) {
|
|
23211
23206
|
return clazz.name;
|
|
23212
23207
|
}
|
|
23213
|
-
isStaticallyExported(
|
|
23214
|
-
// First check if there's an `export` modifier directly on the
|
|
23215
|
-
let topLevel =
|
|
23216
|
-
if (ts$1.isVariableDeclaration(
|
|
23217
|
-
topLevel =
|
|
23208
|
+
isStaticallyExported(decl) {
|
|
23209
|
+
// First check if there's an `export` modifier directly on the declaration.
|
|
23210
|
+
let topLevel = decl;
|
|
23211
|
+
if (ts$1.isVariableDeclaration(decl) && ts$1.isVariableDeclarationList(decl.parent)) {
|
|
23212
|
+
topLevel = decl.parent.parent;
|
|
23218
23213
|
}
|
|
23219
23214
|
if (topLevel.modifiers !== undefined &&
|
|
23220
23215
|
topLevel.modifiers.some(modifier => modifier.kind === ts$1.SyntaxKind.ExportKeyword)) {
|
|
@@ -23233,8 +23228,8 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
23233
23228
|
if (topLevel.parent === undefined || !ts$1.isSourceFile(topLevel.parent)) {
|
|
23234
23229
|
return false;
|
|
23235
23230
|
}
|
|
23236
|
-
const localExports = this.
|
|
23237
|
-
return localExports.has(
|
|
23231
|
+
const localExports = this.getLocalExportedDeclarationsOfSourceFile(decl.getSourceFile());
|
|
23232
|
+
return localExports.has(decl);
|
|
23238
23233
|
}
|
|
23239
23234
|
getDirectImportOfIdentifier(id) {
|
|
23240
23235
|
const symbol = this.checker.getSymbolAtLocation(id);
|
|
@@ -23437,16 +23432,16 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
23437
23432
|
};
|
|
23438
23433
|
}
|
|
23439
23434
|
/**
|
|
23440
|
-
* Get the set of
|
|
23435
|
+
* Get the set of declarations declared in `file` which are exported.
|
|
23441
23436
|
*/
|
|
23442
|
-
|
|
23437
|
+
getLocalExportedDeclarationsOfSourceFile(file) {
|
|
23443
23438
|
const cacheSf = file;
|
|
23444
|
-
if (cacheSf[
|
|
23439
|
+
if (cacheSf[LocalExportedDeclarations] !== undefined) {
|
|
23445
23440
|
// TS does not currently narrow symbol-keyed fields, hence the non-null assert is needed.
|
|
23446
|
-
return cacheSf[
|
|
23441
|
+
return cacheSf[LocalExportedDeclarations];
|
|
23447
23442
|
}
|
|
23448
23443
|
const exportSet = new Set();
|
|
23449
|
-
cacheSf[
|
|
23444
|
+
cacheSf[LocalExportedDeclarations] = exportSet;
|
|
23450
23445
|
const sfSymbol = this.checker.getSymbolAtLocation(cacheSf);
|
|
23451
23446
|
if (sfSymbol === undefined || sfSymbol.exports === undefined) {
|
|
23452
23447
|
return exportSet;
|
|
@@ -23471,8 +23466,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
23471
23466
|
exportedSymbol = this.checker.getAliasedSymbol(exportedSymbol);
|
|
23472
23467
|
}
|
|
23473
23468
|
if (exportedSymbol.valueDeclaration !== undefined &&
|
|
23474
|
-
exportedSymbol.valueDeclaration.getSourceFile() === file
|
|
23475
|
-
this.isClass(exportedSymbol.valueDeclaration)) {
|
|
23469
|
+
exportedSymbol.valueDeclaration.getSourceFile() === file) {
|
|
23476
23470
|
exportSet.add(exportedSymbol.valueDeclaration);
|
|
23477
23471
|
}
|
|
23478
23472
|
item = iter.next();
|
|
@@ -23631,7 +23625,7 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
23631
23625
|
(decl.propertyName !== undefined ? decl.propertyName : decl.name).text :
|
|
23632
23626
|
originalId.text;
|
|
23633
23627
|
}
|
|
23634
|
-
const
|
|
23628
|
+
const LocalExportedDeclarations = Symbol('LocalExportedDeclarations');
|
|
23635
23629
|
|
|
23636
23630
|
/**
|
|
23637
23631
|
* @license
|
|
@@ -26858,11 +26852,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
26858
26852
|
const target = this.factory.createPropertyAccess(expr.receiver.visitExpression(this, context), expr.name);
|
|
26859
26853
|
return this.factory.createAssignment(target, expr.value.visitExpression(this, context));
|
|
26860
26854
|
}
|
|
26861
|
-
visitInvokeMethodExpr(ast, context) {
|
|
26862
|
-
const target = ast.receiver.visitExpression(this, context);
|
|
26863
|
-
return this.setSourceMapRange(this.factory.createCallExpression(ast.name !== null ? this.factory.createPropertyAccess(target, ast.name) : target, ast.args.map(arg => arg.visitExpression(this, context)),
|
|
26864
|
-
/* pure */ false), ast.sourceSpan);
|
|
26865
|
-
}
|
|
26866
26855
|
visitInvokeFunctionExpr(ast, context) {
|
|
26867
26856
|
return this.setSourceMapRange(this.factory.createCallExpression(ast.fn.visitExpression(this, context), ast.args.map(arg => arg.visitExpression(this, context)), ast.pure), ast.sourceSpan);
|
|
26868
26857
|
}
|
|
@@ -27157,9 +27146,6 @@ define(['exports', 'typescript/lib/tsserverlibrary', 'os', 'typescript', 'fs', '
|
|
|
27157
27146
|
visitWritePropExpr(expr, context) {
|
|
27158
27147
|
throw new Error('Method not implemented.');
|
|
27159
27148
|
}
|
|
27160
|
-
visitInvokeMethodExpr(ast, context) {
|
|
27161
|
-
throw new Error('Method not implemented.');
|
|
27162
|
-
}
|
|
27163
27149
|
visitInvokeFunctionExpr(ast, context) {
|
|
27164
27150
|
throw new Error('Method not implemented.');
|
|
27165
27151
|
}
|
|
@@ -32868,10 +32854,6 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
32868
32854
|
visit(ast) {
|
|
32869
32855
|
ast.visit(this);
|
|
32870
32856
|
}
|
|
32871
|
-
visitMethodCall(ast, context) {
|
|
32872
|
-
this.visitIdentifier(ast, IdentifierKind.Method);
|
|
32873
|
-
super.visitMethodCall(ast, context);
|
|
32874
|
-
}
|
|
32875
32857
|
visitPropertyRead(ast, context) {
|
|
32876
32858
|
this.visitIdentifier(ast, IdentifierKind.Property);
|
|
32877
32859
|
super.visitPropertyRead(ast, context);
|
|
@@ -34992,15 +34974,14 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
34992
34974
|
}
|
|
34993
34975
|
// Completion works inside property reads and method calls.
|
|
34994
34976
|
let tsExpr = null;
|
|
34995
|
-
if (expr instanceof PropertyRead || expr instanceof
|
|
34996
|
-
expr instanceof PropertyWrite) {
|
|
34977
|
+
if (expr instanceof PropertyRead || expr instanceof PropertyWrite) {
|
|
34997
34978
|
// Non-safe navigation operations are trivial: `foo.bar` or `foo.bar()`
|
|
34998
34979
|
tsExpr = findFirstMatchingNode(this.tcb, {
|
|
34999
34980
|
filter: ts$1.isPropertyAccessExpression,
|
|
35000
34981
|
withSpan: expr.nameSpan,
|
|
35001
34982
|
});
|
|
35002
34983
|
}
|
|
35003
|
-
else if (expr instanceof SafePropertyRead
|
|
34984
|
+
else if (expr instanceof SafePropertyRead) {
|
|
35004
34985
|
// Safe navigation operations are a little more complex, and involve a ternary. Completion
|
|
35005
34986
|
// happens in the "true" case of the ternary.
|
|
35006
34987
|
const ternaryExpr = findFirstMatchingNode(this.tcb, {
|
|
@@ -35011,11 +34992,10 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
35011
34992
|
return null;
|
|
35012
34993
|
}
|
|
35013
34994
|
const whenTrue = ternaryExpr.expression.whenTrue;
|
|
35014
|
-
if (
|
|
34995
|
+
if (ts$1.isPropertyAccessExpression(whenTrue)) {
|
|
35015
34996
|
tsExpr = whenTrue;
|
|
35016
34997
|
}
|
|
35017
|
-
else if (
|
|
35018
|
-
ts$1.isPropertyAccessExpression(whenTrue.expression)) {
|
|
34998
|
+
else if (ts$1.isCallExpression(whenTrue) && ts$1.isPropertyAccessExpression(whenTrue.expression)) {
|
|
35019
34999
|
tsExpr = whenTrue.expression;
|
|
35020
35000
|
}
|
|
35021
35001
|
}
|
|
@@ -35524,15 +35504,20 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
35524
35504
|
resolutionContext: type.getSourceFile().fileName,
|
|
35525
35505
|
};
|
|
35526
35506
|
}
|
|
35527
|
-
//
|
|
35507
|
+
// The declaration needs to be exported as a top-level export to be able to emit an import
|
|
35528
35508
|
// statement for it. If the declaration is not exported, null is returned to prevent emit.
|
|
35529
|
-
if (
|
|
35509
|
+
if (!this.isTopLevelExport(declaration.node)) {
|
|
35530
35510
|
return null;
|
|
35531
35511
|
}
|
|
35532
35512
|
return new Reference$1(declaration.node, owningModule);
|
|
35533
35513
|
}
|
|
35534
|
-
|
|
35535
|
-
|
|
35514
|
+
isTopLevelExport(decl) {
|
|
35515
|
+
if (decl.parent === undefined || !ts$1.isSourceFile(decl.parent)) {
|
|
35516
|
+
// The declaration has to exist at the top-level, as the reference emitters are not capable of
|
|
35517
|
+
// generating imports to classes declared in a namespace.
|
|
35518
|
+
return false;
|
|
35519
|
+
}
|
|
35520
|
+
return this.reflector.isStaticallyExported(decl);
|
|
35536
35521
|
}
|
|
35537
35522
|
isLocalTypeParameter(decl) {
|
|
35538
35523
|
// Checking for local type parameters only occurs during resolution of type parameters, so it is
|
|
@@ -36414,13 +36399,6 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
36414
36399
|
addParseSpanInfo(node, ast.sourceSpan);
|
|
36415
36400
|
return node;
|
|
36416
36401
|
}
|
|
36417
|
-
visitFunctionCall(ast) {
|
|
36418
|
-
const receiver = wrapForDiagnostics(this.translate(ast.target));
|
|
36419
|
-
const args = ast.args.map(expr => this.translate(expr));
|
|
36420
|
-
const node = ts$1.createCall(receiver, undefined, args);
|
|
36421
|
-
addParseSpanInfo(node, ast.sourceSpan);
|
|
36422
|
-
return node;
|
|
36423
|
-
}
|
|
36424
36402
|
visitImplicitReceiver(ast) {
|
|
36425
36403
|
throw new Error('Method not implemented.');
|
|
36426
36404
|
}
|
|
@@ -36483,15 +36461,6 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
36483
36461
|
addParseSpanInfo(node, ast.sourceSpan);
|
|
36484
36462
|
return node;
|
|
36485
36463
|
}
|
|
36486
|
-
visitMethodCall(ast) {
|
|
36487
|
-
const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
|
36488
|
-
const method = ts$1.createPropertyAccess(receiver, ast.name);
|
|
36489
|
-
addParseSpanInfo(method, ast.nameSpan);
|
|
36490
|
-
const args = ast.args.map(expr => this.translate(expr));
|
|
36491
|
-
const node = ts$1.createCall(method, undefined, args);
|
|
36492
|
-
addParseSpanInfo(node, ast.sourceSpan);
|
|
36493
|
-
return node;
|
|
36494
|
-
}
|
|
36495
36464
|
visitNonNullAssert(ast) {
|
|
36496
36465
|
const expr = wrapForDiagnostics(this.translate(ast.expression));
|
|
36497
36466
|
const node = ts$1.createNonNullExpression(expr);
|
|
@@ -36541,33 +36510,6 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
36541
36510
|
visitQuote(ast) {
|
|
36542
36511
|
return NULL_AS_ANY;
|
|
36543
36512
|
}
|
|
36544
|
-
visitSafeMethodCall(ast) {
|
|
36545
|
-
// See the comments in SafePropertyRead above for an explanation of the cases here.
|
|
36546
|
-
let node;
|
|
36547
|
-
const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
|
36548
|
-
const args = ast.args.map(expr => this.translate(expr));
|
|
36549
|
-
if (this.config.strictSafeNavigationTypes) {
|
|
36550
|
-
// "a?.method(...)" becomes (null as any ? a!.method(...) : undefined)
|
|
36551
|
-
const method = ts$1.createPropertyAccess(ts$1.createNonNullExpression(receiver), ast.name);
|
|
36552
|
-
addParseSpanInfo(method, ast.nameSpan);
|
|
36553
|
-
const call = ts$1.createCall(method, undefined, args);
|
|
36554
|
-
node = ts$1.createParen(ts$1.createConditional(NULL_AS_ANY, call, UNDEFINED));
|
|
36555
|
-
}
|
|
36556
|
-
else if (VeSafeLhsInferenceBugDetector.veWillInferAnyFor(ast)) {
|
|
36557
|
-
// "a?.method(...)" becomes (a as any).method(...)
|
|
36558
|
-
const method = ts$1.createPropertyAccess(tsCastToAny(receiver), ast.name);
|
|
36559
|
-
addParseSpanInfo(method, ast.nameSpan);
|
|
36560
|
-
node = ts$1.createCall(method, undefined, args);
|
|
36561
|
-
}
|
|
36562
|
-
else {
|
|
36563
|
-
// "a?.method(...)" becomes (a!.method(...) as any)
|
|
36564
|
-
const method = ts$1.createPropertyAccess(ts$1.createNonNullExpression(receiver), ast.name);
|
|
36565
|
-
addParseSpanInfo(method, ast.nameSpan);
|
|
36566
|
-
node = tsCastToAny(ts$1.createCall(method, undefined, args));
|
|
36567
|
-
}
|
|
36568
|
-
addParseSpanInfo(node, ast.sourceSpan);
|
|
36569
|
-
return node;
|
|
36570
|
-
}
|
|
36571
36513
|
visitSafePropertyRead(ast) {
|
|
36572
36514
|
let node;
|
|
36573
36515
|
const receiver = wrapForDiagnostics(this.translate(ast.receiver));
|
|
@@ -36624,6 +36566,33 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
36624
36566
|
addParseSpanInfo(node, ast.sourceSpan);
|
|
36625
36567
|
return node;
|
|
36626
36568
|
}
|
|
36569
|
+
visitCall(ast) {
|
|
36570
|
+
const args = ast.args.map(expr => this.translate(expr));
|
|
36571
|
+
const expr = wrapForDiagnostics(this.translate(ast.receiver));
|
|
36572
|
+
let node;
|
|
36573
|
+
// Safe property/keyed reads will produce a ternary whose value is nullable.
|
|
36574
|
+
// We have to generate a similar ternary around the call.
|
|
36575
|
+
if (ast.receiver instanceof SafePropertyRead || ast.receiver instanceof SafeKeyedRead) {
|
|
36576
|
+
if (this.config.strictSafeNavigationTypes) {
|
|
36577
|
+
// "a?.method(...)" becomes (null as any ? a!.method(...) : undefined)
|
|
36578
|
+
const call = ts$1.createCall(ts$1.createNonNullExpression(expr), undefined, args);
|
|
36579
|
+
node = ts$1.createParen(ts$1.createConditional(NULL_AS_ANY, call, UNDEFINED));
|
|
36580
|
+
}
|
|
36581
|
+
else if (VeSafeLhsInferenceBugDetector.veWillInferAnyFor(ast)) {
|
|
36582
|
+
// "a?.method(...)" becomes (a as any).method(...)
|
|
36583
|
+
node = ts$1.createCall(tsCastToAny(expr), undefined, args);
|
|
36584
|
+
}
|
|
36585
|
+
else {
|
|
36586
|
+
// "a?.method(...)" becomes (a!.method(...) as any)
|
|
36587
|
+
node = tsCastToAny(ts$1.createCall(ts$1.createNonNullExpression(expr), undefined, args));
|
|
36588
|
+
}
|
|
36589
|
+
}
|
|
36590
|
+
else {
|
|
36591
|
+
node = ts$1.createCall(expr, undefined, args);
|
|
36592
|
+
}
|
|
36593
|
+
addParseSpanInfo(node, ast.sourceSpan);
|
|
36594
|
+
return node;
|
|
36595
|
+
}
|
|
36627
36596
|
}
|
|
36628
36597
|
/**
|
|
36629
36598
|
* Checks whether View Engine will infer a type of 'any' for the left-hand side of a safe navigation
|
|
@@ -36641,7 +36610,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
36641
36610
|
class VeSafeLhsInferenceBugDetector {
|
|
36642
36611
|
static veWillInferAnyFor(ast) {
|
|
36643
36612
|
const visitor = VeSafeLhsInferenceBugDetector.SINGLETON;
|
|
36644
|
-
return ast instanceof
|
|
36613
|
+
return ast instanceof Call ? ast.visit(visitor) : ast.receiver.visit(visitor);
|
|
36645
36614
|
}
|
|
36646
36615
|
visitUnary(ast) {
|
|
36647
36616
|
return ast.expr.visit(this);
|
|
@@ -36655,7 +36624,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
36655
36624
|
visitConditional(ast) {
|
|
36656
36625
|
return ast.condition.visit(this) || ast.trueExp.visit(this) || ast.falseExp.visit(this);
|
|
36657
36626
|
}
|
|
36658
|
-
|
|
36627
|
+
visitCall(ast) {
|
|
36659
36628
|
return true;
|
|
36660
36629
|
}
|
|
36661
36630
|
visitImplicitReceiver(ast) {
|
|
@@ -36682,9 +36651,6 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
36682
36651
|
visitLiteralPrimitive(ast) {
|
|
36683
36652
|
return false;
|
|
36684
36653
|
}
|
|
36685
|
-
visitMethodCall(ast) {
|
|
36686
|
-
return true;
|
|
36687
|
-
}
|
|
36688
36654
|
visitPipe(ast) {
|
|
36689
36655
|
return true;
|
|
36690
36656
|
}
|
|
@@ -36703,9 +36669,6 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
36703
36669
|
visitQuote(ast) {
|
|
36704
36670
|
return false;
|
|
36705
36671
|
}
|
|
36706
|
-
visitSafeMethodCall(ast) {
|
|
36707
|
-
return true;
|
|
36708
|
-
}
|
|
36709
36672
|
visitSafePropertyRead(ast) {
|
|
36710
36673
|
return false;
|
|
36711
36674
|
}
|
|
@@ -38287,15 +38250,15 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
38287
38250
|
else if (ast instanceof ImplicitReceiver) {
|
|
38288
38251
|
// AST instances representing variables and references look very similar to property reads
|
|
38289
38252
|
// or method calls from the component context: both have the shape
|
|
38290
|
-
// PropertyRead(ImplicitReceiver, 'propName') or
|
|
38253
|
+
// PropertyRead(ImplicitReceiver, 'propName') or Call(ImplicitReceiver, 'methodName').
|
|
38291
38254
|
//
|
|
38292
|
-
// `translate` will first try to `resolve` the outer PropertyRead/
|
|
38255
|
+
// `translate` will first try to `resolve` the outer PropertyRead/Call. If this works,
|
|
38293
38256
|
// it's because the `BoundTarget` found an expression target for the whole expression, and
|
|
38294
38257
|
// therefore `translate` will never attempt to `resolve` the ImplicitReceiver of that
|
|
38295
|
-
// PropertyRead/
|
|
38258
|
+
// PropertyRead/Call.
|
|
38296
38259
|
//
|
|
38297
38260
|
// Therefore if `resolve` is called on an `ImplicitReceiver`, it's because no outer
|
|
38298
|
-
// PropertyRead/
|
|
38261
|
+
// PropertyRead/Call resolved to a variable or reference, and therefore this is a
|
|
38299
38262
|
// property read or method call on the component context itself.
|
|
38300
38263
|
return ts$1.createIdentifier('ctx');
|
|
38301
38264
|
}
|
|
@@ -38326,11 +38289,12 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
38326
38289
|
addParseSpanInfo(result, ast.sourceSpan);
|
|
38327
38290
|
return result;
|
|
38328
38291
|
}
|
|
38329
|
-
else if (ast instanceof
|
|
38330
|
-
|
|
38292
|
+
else if (ast instanceof Call &&
|
|
38293
|
+
(ast.receiver instanceof PropertyRead || ast.receiver instanceof SafePropertyRead) &&
|
|
38294
|
+
!(ast.receiver.receiver instanceof ThisReceiver)) {
|
|
38331
38295
|
// Resolve the special `$any(expr)` syntax to insert a cast of the argument to type `any`.
|
|
38332
38296
|
// `$any(expr)` -> `expr as any`
|
|
38333
|
-
if (ast.name === '$any' && ast.args.length === 1) {
|
|
38297
|
+
if (ast.receiver.name === '$any' && ast.args.length === 1) {
|
|
38334
38298
|
const expr = this.translate(ast.args[0]);
|
|
38335
38299
|
const exprAsAny = ts$1.createAsExpression(expr, ts$1.createKeywordTypeNode(ts$1.SyntaxKind.AnyKeyword));
|
|
38336
38300
|
const result = ts$1.createParen(exprAsAny);
|
|
@@ -38346,7 +38310,7 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
38346
38310
|
return null;
|
|
38347
38311
|
}
|
|
38348
38312
|
const method = wrapForDiagnostics(receiver);
|
|
38349
|
-
addParseSpanInfo(method, ast.nameSpan);
|
|
38313
|
+
addParseSpanInfo(method, ast.receiver.nameSpan);
|
|
38350
38314
|
const args = ast.args.map(arg => this.translate(arg));
|
|
38351
38315
|
const node = ts$1.createCall(method, undefined, args);
|
|
38352
38316
|
addParseSpanInfo(node, ast.sourceSpan);
|
|
@@ -39471,11 +39435,15 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
39471
39435
|
if (expressionTarget !== null) {
|
|
39472
39436
|
return this.getSymbol(expressionTarget);
|
|
39473
39437
|
}
|
|
39474
|
-
|
|
39438
|
+
let withSpan = expression.sourceSpan;
|
|
39439
|
+
// The `name` part of a `PropertyWrite` and a non-safe `Call` does not have its own
|
|
39475
39440
|
// AST so there is no way to retrieve a `Symbol` for just the `name` via a specific node.
|
|
39476
|
-
|
|
39477
|
-
expression.nameSpan
|
|
39478
|
-
|
|
39441
|
+
if (expression instanceof PropertyWrite) {
|
|
39442
|
+
withSpan = expression.nameSpan;
|
|
39443
|
+
}
|
|
39444
|
+
else if (expression instanceof Call && expression.receiver instanceof PropertyRead) {
|
|
39445
|
+
withSpan = expression.receiver.nameSpan;
|
|
39446
|
+
}
|
|
39479
39447
|
let node = null;
|
|
39480
39448
|
// Property reads in templates usually map to a `PropertyAccessExpression`
|
|
39481
39449
|
// (e.g. `ctx.foo`) so try looking for one first.
|
|
@@ -39497,9 +39465,10 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
39497
39465
|
// - If our expression is a pipe binding ("a | test:b:c"), we want the Symbol for the
|
|
39498
39466
|
// `transform` on the pipe.
|
|
39499
39467
|
// - Otherwise, we retrieve the symbol for the node itself with no special considerations
|
|
39500
|
-
if ((expression instanceof SafePropertyRead ||
|
|
39468
|
+
if ((expression instanceof SafePropertyRead ||
|
|
39469
|
+
(expression instanceof Call && expression.receiver instanceof SafePropertyRead)) &&
|
|
39501
39470
|
ts$1.isConditionalExpression(node)) {
|
|
39502
|
-
const whenTrueSymbol = (expression instanceof
|
|
39471
|
+
const whenTrueSymbol = (expression instanceof Call && ts$1.isCallExpression(node.whenTrue)) ?
|
|
39503
39472
|
this.getSymbolOfTsNode(node.whenTrue.expression) :
|
|
39504
39473
|
this.getSymbolOfTsNode(node.whenTrue);
|
|
39505
39474
|
if (whenTrueSymbol === null) {
|
|
@@ -40165,12 +40134,11 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40165
40134
|
*/
|
|
40166
40135
|
class ExtendedTemplateCheckerImpl {
|
|
40167
40136
|
constructor(templateTypeChecker, typeChecker, templateChecks) {
|
|
40168
|
-
this.templateTypeChecker = templateTypeChecker;
|
|
40169
|
-
this.typeChecker = typeChecker;
|
|
40170
40137
|
this.templateChecks = templateChecks;
|
|
40138
|
+
this.ctx = { templateTypeChecker: templateTypeChecker, typeChecker: typeChecker };
|
|
40171
40139
|
}
|
|
40172
40140
|
getDiagnosticsForComponent(component) {
|
|
40173
|
-
const template = this.templateTypeChecker.getTemplate(component);
|
|
40141
|
+
const template = this.ctx.templateTypeChecker.getTemplate(component);
|
|
40174
40142
|
// Skip checks if component has no template. This can happen if the user writes a
|
|
40175
40143
|
// `@Component()` but doesn't add the template, could happen in the language service
|
|
40176
40144
|
// when users are in the middle of typing code.
|
|
@@ -40178,66 +40146,100 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40178
40146
|
return [];
|
|
40179
40147
|
}
|
|
40180
40148
|
const diagnostics = [];
|
|
40181
|
-
const ctx = {
|
|
40182
|
-
templateTypeChecker: this.templateTypeChecker,
|
|
40183
|
-
typeChecker: this.typeChecker,
|
|
40184
|
-
component
|
|
40185
|
-
};
|
|
40186
40149
|
for (const check of this.templateChecks) {
|
|
40187
|
-
diagnostics.push(...
|
|
40150
|
+
diagnostics.push(...check.run(this.ctx, component, template));
|
|
40188
40151
|
}
|
|
40189
40152
|
return diagnostics;
|
|
40190
40153
|
}
|
|
40191
40154
|
}
|
|
40192
|
-
|
|
40193
|
-
|
|
40194
|
-
|
|
40195
|
-
|
|
40196
|
-
|
|
40197
|
-
|
|
40198
|
-
|
|
40199
|
-
|
|
40200
|
-
|
|
40201
|
-
|
|
40202
|
-
|
|
40203
|
-
|
|
40204
|
-
|
|
40205
|
-
|
|
40206
|
-
|
|
40207
|
-
|
|
40208
|
-
|
|
40209
|
-
|
|
40210
|
-
|
|
40211
|
-
// outputs: [
|
|
40212
|
-
// BoundEvent {
|
|
40213
|
-
// name: 'foo',
|
|
40214
|
-
// /.../
|
|
40215
|
-
// }
|
|
40216
|
-
// ]
|
|
40217
|
-
// }
|
|
40218
|
-
// ],
|
|
40219
|
-
// /.../
|
|
40220
|
-
// }
|
|
40221
|
-
// ```
|
|
40222
|
-
//
|
|
40223
|
-
// In this case a duplicated diagnostic could be generated for the output `foo`.
|
|
40224
|
-
// TODO(danieltrevino): handle duplicated diagnostics when they are being generated
|
|
40225
|
-
// to avoid extra work (could be directly in the visitor).
|
|
40226
|
-
// https://github.com/angular/angular/pull/42984#discussion_r684823926
|
|
40227
|
-
function deduplicateDiagnostics(diagnostics) {
|
|
40228
|
-
const result = [];
|
|
40229
|
-
for (const newDiag of diagnostics) {
|
|
40230
|
-
const isDuplicateDiag = result.some(existingDiag => areDiagnosticsEqual(newDiag, existingDiag));
|
|
40231
|
-
if (!isDuplicateDiag) {
|
|
40232
|
-
result.push(newDiag);
|
|
40233
|
-
}
|
|
40155
|
+
|
|
40156
|
+
/**
|
|
40157
|
+
* @license
|
|
40158
|
+
* Copyright Google LLC All Rights Reserved.
|
|
40159
|
+
*
|
|
40160
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
40161
|
+
* found in the LICENSE file at https://angular.io/license
|
|
40162
|
+
*/
|
|
40163
|
+
/**
|
|
40164
|
+
* This abstract class provides a base implementation for the run method.
|
|
40165
|
+
*/
|
|
40166
|
+
class TemplateCheckWithVisitor {
|
|
40167
|
+
/**
|
|
40168
|
+
* Base implementation for run function, visits all nodes in template and calls
|
|
40169
|
+
* `visitNode()` for each one.
|
|
40170
|
+
*/
|
|
40171
|
+
run(ctx, component, template) {
|
|
40172
|
+
const visitor = new TemplateVisitor$1(ctx, component, this);
|
|
40173
|
+
return visitor.getDiagnostics(template);
|
|
40234
40174
|
}
|
|
40235
|
-
return result;
|
|
40236
40175
|
}
|
|
40237
|
-
|
|
40238
|
-
|
|
40239
|
-
|
|
40240
|
-
|
|
40176
|
+
/**
|
|
40177
|
+
* Visits all nodes in a template (TmplAstNode and AST) and calls `visitNode` for each one.
|
|
40178
|
+
*/
|
|
40179
|
+
class TemplateVisitor$1 extends RecursiveAstVisitor {
|
|
40180
|
+
constructor(ctx, component, check) {
|
|
40181
|
+
super();
|
|
40182
|
+
this.ctx = ctx;
|
|
40183
|
+
this.component = component;
|
|
40184
|
+
this.check = check;
|
|
40185
|
+
this.diagnostics = [];
|
|
40186
|
+
}
|
|
40187
|
+
visit(node, context) {
|
|
40188
|
+
this.diagnostics.push(...this.check.visitNode(this.ctx, this.component, node));
|
|
40189
|
+
node.visit(this);
|
|
40190
|
+
}
|
|
40191
|
+
visitAllNodes(nodes) {
|
|
40192
|
+
for (const node of nodes) {
|
|
40193
|
+
this.visit(node);
|
|
40194
|
+
}
|
|
40195
|
+
}
|
|
40196
|
+
visitAst(ast) {
|
|
40197
|
+
if (ast instanceof ASTWithSource) {
|
|
40198
|
+
ast = ast.ast;
|
|
40199
|
+
}
|
|
40200
|
+
this.visit(ast);
|
|
40201
|
+
}
|
|
40202
|
+
visitElement(element) {
|
|
40203
|
+
this.visitAllNodes(element.attributes);
|
|
40204
|
+
this.visitAllNodes(element.inputs);
|
|
40205
|
+
this.visitAllNodes(element.outputs);
|
|
40206
|
+
this.visitAllNodes(element.references);
|
|
40207
|
+
this.visitAllNodes(element.children);
|
|
40208
|
+
}
|
|
40209
|
+
visitTemplate(template) {
|
|
40210
|
+
this.visitAllNodes(template.attributes);
|
|
40211
|
+
if (template.tagName === 'ng-template') {
|
|
40212
|
+
// Only visit input/outputs/templateAttrs if this isn't an inline template node
|
|
40213
|
+
// generated for a structural directive (like `<div *ngIf></div>`). These nodes
|
|
40214
|
+
// would be visited when the underlying element of an inline template node is processed.
|
|
40215
|
+
this.visitAllNodes(template.inputs);
|
|
40216
|
+
this.visitAllNodes(template.outputs);
|
|
40217
|
+
this.visitAllNodes(template.templateAttrs);
|
|
40218
|
+
}
|
|
40219
|
+
this.visitAllNodes(template.variables);
|
|
40220
|
+
this.visitAllNodes(template.references);
|
|
40221
|
+
this.visitAllNodes(template.children);
|
|
40222
|
+
}
|
|
40223
|
+
visitContent(content) { }
|
|
40224
|
+
visitVariable(variable) { }
|
|
40225
|
+
visitReference(reference) { }
|
|
40226
|
+
visitTextAttribute(attribute) { }
|
|
40227
|
+
visitBoundAttribute(attribute) {
|
|
40228
|
+
this.visitAst(attribute.value);
|
|
40229
|
+
}
|
|
40230
|
+
visitBoundEvent(attribute) {
|
|
40231
|
+
this.visitAst(attribute.handler);
|
|
40232
|
+
}
|
|
40233
|
+
visitText(text) { }
|
|
40234
|
+
visitBoundText(text) {
|
|
40235
|
+
this.visitAst(text.value);
|
|
40236
|
+
}
|
|
40237
|
+
visitIcu(icu) { }
|
|
40238
|
+
getDiagnostics(template) {
|
|
40239
|
+
this.diagnostics = [];
|
|
40240
|
+
this.visitAllNodes(template);
|
|
40241
|
+
return this.diagnostics;
|
|
40242
|
+
}
|
|
40241
40243
|
}
|
|
40242
40244
|
|
|
40243
40245
|
/**
|
|
@@ -40252,42 +40254,63 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
40252
40254
|
* Parentheses should be inside the brackets "[()]".
|
|
40253
40255
|
* Will return diagnostic information when "([])" is found.
|
|
40254
40256
|
*/
|
|
40255
|
-
class InvalidBananaInBoxCheck {
|
|
40257
|
+
class InvalidBananaInBoxCheck extends TemplateCheckWithVisitor {
|
|
40256
40258
|
constructor() {
|
|
40257
|
-
|
|
40259
|
+
super(...arguments);
|
|
40260
|
+
this.code = ErrorCode.INVALID_BANANA_IN_BOX;
|
|
40258
40261
|
}
|
|
40259
|
-
|
|
40260
|
-
|
|
40261
|
-
|
|
40262
|
+
visitNode(ctx, component, node) {
|
|
40263
|
+
if (!(node instanceof BoundEvent))
|
|
40264
|
+
return [];
|
|
40265
|
+
const name = node.name;
|
|
40266
|
+
if (!name.startsWith('[') || !name.endsWith(']'))
|
|
40267
|
+
return [];
|
|
40268
|
+
const boundSyntax = node.sourceSpan.toString();
|
|
40269
|
+
const expectedBoundSyntax = boundSyntax.replace(`(${name})`, `[(${name.slice(1, -1)})]`);
|
|
40270
|
+
const diagnostic = ctx.templateTypeChecker.makeTemplateDiagnostic(component, node.sourceSpan, ts$1.DiagnosticCategory.Warning, ErrorCode.INVALID_BANANA_IN_BOX, `In the two-way binding syntax the parentheses should be inside the brackets, ex. '${expectedBoundSyntax}'.
|
|
40271
|
+
Find more at https://angular.io/guide/two-way-binding`);
|
|
40272
|
+
return [diagnostic];
|
|
40262
40273
|
}
|
|
40263
40274
|
}
|
|
40264
|
-
|
|
40265
|
-
|
|
40266
|
-
|
|
40267
|
-
|
|
40268
|
-
|
|
40275
|
+
|
|
40276
|
+
/**
|
|
40277
|
+
* @license
|
|
40278
|
+
* Copyright Google LLC All Rights Reserved.
|
|
40279
|
+
*
|
|
40280
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
40281
|
+
* found in the LICENSE file at https://angular.io/license
|
|
40282
|
+
*/
|
|
40283
|
+
/**
|
|
40284
|
+
* Ensures the left side of a nullish coalescing operation is nullable.
|
|
40285
|
+
* Returns diagnostics for the cases where the operator is useless.
|
|
40286
|
+
* This check should only be use if `strictNullChecks` is enabled,
|
|
40287
|
+
* otherwise it would produce inaccurate results.
|
|
40288
|
+
*/
|
|
40289
|
+
class NullishCoalescingNotNullableCheck extends TemplateCheckWithVisitor {
|
|
40290
|
+
constructor() {
|
|
40291
|
+
super(...arguments);
|
|
40292
|
+
this.code = ErrorCode.NULLISH_COALESCING_NOT_NULLABLE;
|
|
40269
40293
|
}
|
|
40270
|
-
|
|
40271
|
-
|
|
40272
|
-
|
|
40273
|
-
|
|
40274
|
-
|
|
40275
|
-
|
|
40276
|
-
visitBoundEvent(boundEvent) {
|
|
40277
|
-
const name = boundEvent.name;
|
|
40278
|
-
if (name.startsWith('[') && name.endsWith(']')) {
|
|
40279
|
-
const boundSyntax = boundEvent.sourceSpan.toString();
|
|
40280
|
-
const expectedBoundSyntax = boundSyntax.replace(`(${name})`, `[(${name.slice(1, -1)})]`);
|
|
40281
|
-
this.diagnostics.push(this.ctx.templateTypeChecker.makeTemplateDiagnostic(this.ctx.component, boundEvent.sourceSpan, ts$1.DiagnosticCategory.Warning, ErrorCode.INVALID_BANANA_IN_BOX, `In the two-way binding syntax the parentheses should be inside the brackets, ex. '${expectedBoundSyntax}'.
|
|
40282
|
-
Find more at https://angular.io/guide/two-way-binding`));
|
|
40294
|
+
visitNode(ctx, component, node) {
|
|
40295
|
+
if (!(node instanceof Binary) || node.operation !== '??')
|
|
40296
|
+
return [];
|
|
40297
|
+
const symbolLeft = ctx.templateTypeChecker.getSymbolOfNode(node.left, component);
|
|
40298
|
+
if (symbolLeft === null || symbolLeft.kind !== SymbolKind.Expression) {
|
|
40299
|
+
return [];
|
|
40283
40300
|
}
|
|
40284
|
-
|
|
40285
|
-
|
|
40286
|
-
this.
|
|
40287
|
-
|
|
40288
|
-
|
|
40301
|
+
const typeLeft = symbolLeft.tsType;
|
|
40302
|
+
// If the left operand's type is different from its non-nullable self, then it must
|
|
40303
|
+
// contain a null or undefined so this nullish coalescing operator is useful. No diagnostic to
|
|
40304
|
+
// report.
|
|
40305
|
+
if (typeLeft.getNonNullableType() !== typeLeft)
|
|
40306
|
+
return [];
|
|
40307
|
+
const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
|
|
40308
|
+
if (symbol.kind !== SymbolKind.Expression) {
|
|
40309
|
+
return [];
|
|
40289
40310
|
}
|
|
40290
|
-
|
|
40311
|
+
const span = ctx.templateTypeChecker.getTemplateMappingAtShimLocation(symbol.shimLocation).span;
|
|
40312
|
+
const diagnostic = ctx.templateTypeChecker.makeTemplateDiagnostic(component, span, ts$1.DiagnosticCategory.Warning, ErrorCode.NULLISH_COALESCING_NOT_NULLABLE, `The left side of this nullish coalescing operation does not include 'null' or 'undefined' in its type, therefore the '??' operator can be safely removed.`);
|
|
40313
|
+
return [diagnostic];
|
|
40291
40314
|
}
|
|
40292
40315
|
}
|
|
40293
40316
|
|
|
@@ -41074,6 +41097,9 @@ Either add the @Injectable() decorator to '${provider.node.name
|
|
|
41074
41097
|
});
|
|
41075
41098
|
const templateTypeChecker = new TemplateTypeCheckerImpl(this.inputProgram, notifyingDriver, traitCompiler, this.getTypeCheckingConfig(), refEmitter, reflector, this.adapter, this.incrementalCompilation, scopeRegistry, typeCheckScopeRegistry, this.delegatingPerfRecorder);
|
|
41076
41099
|
const templateChecks = [new InvalidBananaInBoxCheck()];
|
|
41100
|
+
if (this.options.strictNullChecks) {
|
|
41101
|
+
templateChecks.push(new NullishCoalescingNotNullableCheck());
|
|
41102
|
+
}
|
|
41077
41103
|
const extendedTemplateChecker = new ExtendedTemplateCheckerImpl(templateTypeChecker, checker, templateChecks);
|
|
41078
41104
|
return {
|
|
41079
41105
|
isCore,
|
|
@@ -41591,11 +41617,10 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
41591
41617
|
if (isTemplateNodeWithKeyAndValue(node)) {
|
|
41592
41618
|
return toTextSpan(node.keySpan);
|
|
41593
41619
|
}
|
|
41594
|
-
else if (node instanceof PropertyWrite || node instanceof
|
|
41595
|
-
node instanceof
|
|
41596
|
-
// The `name` part of a `PropertyWrite
|
|
41597
|
-
//
|
|
41598
|
-
// node.
|
|
41620
|
+
else if (node instanceof PropertyWrite || node instanceof BindingPipe ||
|
|
41621
|
+
node instanceof PropertyRead) {
|
|
41622
|
+
// The `name` part of a `PropertyWrite` and `BindingPipe` does not have its own AST
|
|
41623
|
+
// so there is no way to retrieve a `Symbol` for just the `name` via a specific node.
|
|
41599
41624
|
return toTextSpan(node.nameSpan);
|
|
41600
41625
|
}
|
|
41601
41626
|
else {
|
|
@@ -42498,7 +42523,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
42498
42523
|
var TargetNodeKind;
|
|
42499
42524
|
(function (TargetNodeKind) {
|
|
42500
42525
|
TargetNodeKind[TargetNodeKind["RawExpression"] = 0] = "RawExpression";
|
|
42501
|
-
TargetNodeKind[TargetNodeKind["
|
|
42526
|
+
TargetNodeKind[TargetNodeKind["CallExpressionInArgContext"] = 1] = "CallExpressionInArgContext";
|
|
42502
42527
|
TargetNodeKind[TargetNodeKind["RawTemplateNode"] = 2] = "RawTemplateNode";
|
|
42503
42528
|
TargetNodeKind[TargetNodeKind["ElementInTagContext"] = 3] = "ElementInTagContext";
|
|
42504
42529
|
TargetNodeKind[TargetNodeKind["ElementInBodyContext"] = 4] = "ElementInBodyContext";
|
|
@@ -42544,10 +42569,9 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
42544
42569
|
}
|
|
42545
42570
|
// Given the candidate node, determine the full targeted context.
|
|
42546
42571
|
let nodeInContext;
|
|
42547
|
-
if (
|
|
42548
|
-
isWithin(position, candidate.argumentSpan)) {
|
|
42572
|
+
if (candidate instanceof Call && isWithin(position, candidate.argumentSpan)) {
|
|
42549
42573
|
nodeInContext = {
|
|
42550
|
-
kind: TargetNodeKind.
|
|
42574
|
+
kind: TargetNodeKind.CallExpressionInArgContext,
|
|
42551
42575
|
node: candidate,
|
|
42552
42576
|
};
|
|
42553
42577
|
}
|
|
@@ -42950,8 +42974,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
42950
42974
|
* expressions.
|
|
42951
42975
|
*/
|
|
42952
42976
|
isPropertyExpressionCompletion() {
|
|
42953
|
-
return this.node instanceof PropertyRead || this.node instanceof
|
|
42954
|
-
this.node instanceof SafePropertyRead || this.node instanceof SafeMethodCall ||
|
|
42977
|
+
return this.node instanceof PropertyRead || this.node instanceof SafePropertyRead ||
|
|
42955
42978
|
this.node instanceof PropertyWrite || this.node instanceof EmptyExpr ||
|
|
42956
42979
|
// BoundEvent nodes only count as property completions if in an EventValue context.
|
|
42957
42980
|
(this.node instanceof BoundEvent && this.nodeContext === CompletionNodeContext.EventValue);
|
|
@@ -42975,7 +42998,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
42975
42998
|
}
|
|
42976
42999
|
const replacementSpan = makeReplacementSpanFromAst(this.node);
|
|
42977
43000
|
if (!(this.node.receiver instanceof ImplicitReceiver) &&
|
|
42978
|
-
(options === null || options === void 0 ? void 0 : options.includeCompletionsWithInsertText) &&
|
|
43001
|
+
!(this.node instanceof SafePropertyRead) && (options === null || options === void 0 ? void 0 : options.includeCompletionsWithInsertText) &&
|
|
42979
43002
|
options.includeAutomaticOptionalChainCompletions !== false) {
|
|
42980
43003
|
const symbol = this.templateTypeChecker.getSymbolOfNode(this.node.receiver, this.component);
|
|
42981
43004
|
if ((symbol === null || symbol === void 0 ? void 0 : symbol.kind) === SymbolKind.Expression) {
|
|
@@ -43705,9 +43728,8 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
43705
43728
|
return { text: node.valueSpan.toString(), span: toTextSpan(node.valueSpan) };
|
|
43706
43729
|
}
|
|
43707
43730
|
}
|
|
43708
|
-
if (node instanceof PropertyRead || node instanceof
|
|
43709
|
-
node instanceof SafePropertyRead || node instanceof
|
|
43710
|
-
node instanceof BindingPipe) {
|
|
43731
|
+
if (node instanceof PropertyRead || node instanceof PropertyWrite ||
|
|
43732
|
+
node instanceof SafePropertyRead || node instanceof BindingPipe) {
|
|
43711
43733
|
return { text: node.name, span: toTextSpan(node.nameSpan) };
|
|
43712
43734
|
}
|
|
43713
43735
|
else if (node instanceof LiteralPrimitive) {
|
|
@@ -44046,19 +44068,27 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44046
44068
|
* found in the LICENSE file at https://angular.io/license
|
|
44047
44069
|
*/
|
|
44048
44070
|
class QuickInfoBuilder {
|
|
44049
|
-
constructor(tsLS, compiler, component, node) {
|
|
44071
|
+
constructor(tsLS, compiler, component, node, parent) {
|
|
44050
44072
|
this.tsLS = tsLS;
|
|
44051
44073
|
this.compiler = compiler;
|
|
44052
44074
|
this.component = component;
|
|
44053
44075
|
this.node = node;
|
|
44076
|
+
this.parent = parent;
|
|
44054
44077
|
this.typeChecker = this.compiler.getCurrentProgram().getTypeChecker();
|
|
44055
44078
|
}
|
|
44056
44079
|
get() {
|
|
44057
44080
|
const symbol = this.compiler.getTemplateTypeChecker().getSymbolOfNode(this.node, this.component);
|
|
44058
|
-
if (symbol
|
|
44059
|
-
return
|
|
44081
|
+
if (symbol !== null) {
|
|
44082
|
+
return this.getQuickInfoForSymbol(symbol);
|
|
44083
|
+
}
|
|
44084
|
+
if (isDollarAny(this.node)) {
|
|
44085
|
+
return createDollarAnyQuickInfo(this.node);
|
|
44086
|
+
}
|
|
44087
|
+
// If the cursor lands on the receiver of a method call, we have to look
|
|
44088
|
+
// at the entire call in order to figure out if it's a call to `$any`.
|
|
44089
|
+
if (this.parent !== null && isDollarAny(this.parent) && this.parent.receiver === this.node) {
|
|
44090
|
+
return createDollarAnyQuickInfo(this.parent);
|
|
44060
44091
|
}
|
|
44061
|
-
return this.getQuickInfoForSymbol(symbol);
|
|
44062
44092
|
}
|
|
44063
44093
|
getQuickInfoForSymbol(symbol) {
|
|
44064
44094
|
switch (symbol.kind) {
|
|
@@ -44181,11 +44211,13 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44181
44211
|
return a.text === b.text && a.kind === b.kind;
|
|
44182
44212
|
}
|
|
44183
44213
|
function isDollarAny(node) {
|
|
44184
|
-
return node instanceof
|
|
44185
|
-
|
|
44214
|
+
return node instanceof Call && node.receiver instanceof PropertyRead &&
|
|
44215
|
+
node.receiver.receiver instanceof ImplicitReceiver &&
|
|
44216
|
+
!(node.receiver.receiver instanceof ThisReceiver) && node.receiver.name === '$any' &&
|
|
44217
|
+
node.args.length === 1;
|
|
44186
44218
|
}
|
|
44187
44219
|
function createDollarAnyQuickInfo(node) {
|
|
44188
|
-
return createQuickInfo('$any', DisplayInfoKind.METHOD, getTextSpanOfNode(node),
|
|
44220
|
+
return createQuickInfo('$any', DisplayInfoKind.METHOD, getTextSpanOfNode(node.receiver),
|
|
44189
44221
|
/** containerName */ undefined, 'any', [{
|
|
44190
44222
|
kind: SYMBOL_TEXT,
|
|
44191
44223
|
text: 'function to cast an expression to the `any` type',
|
|
@@ -44560,7 +44592,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44560
44592
|
return undefined;
|
|
44561
44593
|
}
|
|
44562
44594
|
if (targetInfo.context.kind !== TargetNodeKind.RawExpression &&
|
|
44563
|
-
targetInfo.context.kind !== TargetNodeKind.
|
|
44595
|
+
targetInfo.context.kind !== TargetNodeKind.CallExpressionInArgContext) {
|
|
44564
44596
|
// Signature completions are only available in expressions.
|
|
44565
44597
|
return undefined;
|
|
44566
44598
|
}
|
|
@@ -44569,38 +44601,37 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44569
44601
|
return undefined;
|
|
44570
44602
|
}
|
|
44571
44603
|
// Determine a shim position to use in the request to the TypeScript Language Service.
|
|
44572
|
-
// Additionally, extract the `
|
|
44573
|
-
//
|
|
44604
|
+
// Additionally, extract the `Call` node for which signature help is being queried, as this
|
|
44605
|
+
// is needed to construct the correct span for the results later.
|
|
44574
44606
|
let shimPosition;
|
|
44575
44607
|
let expr;
|
|
44576
44608
|
switch (targetInfo.context.kind) {
|
|
44577
44609
|
case TargetNodeKind.RawExpression:
|
|
44578
44610
|
// For normal expressions, just use the primary TCB position of the expression.
|
|
44579
44611
|
shimPosition = symbol.shimLocation.positionInShimFile;
|
|
44580
|
-
// Walk up the parents of this expression and try to find a
|
|
44581
|
-
// for which signature information is being fetched.
|
|
44612
|
+
// Walk up the parents of this expression and try to find a
|
|
44613
|
+
// `Call` for which signature information is being fetched.
|
|
44582
44614
|
let callExpr = null;
|
|
44583
44615
|
const parents = targetInfo.context.parents;
|
|
44584
44616
|
for (let i = parents.length - 1; i >= 0; i--) {
|
|
44585
44617
|
const parent = parents[i];
|
|
44586
|
-
if (parent instanceof
|
|
44618
|
+
if (parent instanceof Call) {
|
|
44587
44619
|
callExpr = parent;
|
|
44588
44620
|
break;
|
|
44589
44621
|
}
|
|
44590
44622
|
}
|
|
44591
|
-
// If no
|
|
44623
|
+
// If no Call node could be found, then this query cannot be safely
|
|
44592
44624
|
// answered as a correct span for the results will not be obtainable.
|
|
44593
44625
|
if (callExpr === null) {
|
|
44594
44626
|
return undefined;
|
|
44595
44627
|
}
|
|
44596
44628
|
expr = callExpr;
|
|
44597
44629
|
break;
|
|
44598
|
-
case TargetNodeKind.
|
|
44599
|
-
// The `Symbol` points to a `
|
|
44600
|
-
//
|
|
44601
|
-
//
|
|
44602
|
-
//
|
|
44603
|
-
// arguments: `foo(|)`.
|
|
44630
|
+
case TargetNodeKind.CallExpressionInArgContext:
|
|
44631
|
+
// The `Symbol` points to a `Call` expression in the TCB (where it will be represented as a
|
|
44632
|
+
// `ts.CallExpression`) *and* the template position was within the argument list of the method
|
|
44633
|
+
// call. This happens when there was no narrower expression inside the argument list that
|
|
44634
|
+
// matched the template position, such as when the call has no arguments: `foo(|)`.
|
|
44604
44635
|
//
|
|
44605
44636
|
// The `Symbol`'s shim position is to the start of the call expression (`|foo()`) and
|
|
44606
44637
|
// therefore wouldn't return accurate signature help from the TS language service. For that, a
|
|
@@ -44636,8 +44667,7 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44636
44667
|
}
|
|
44637
44668
|
// The TS language service results are almost returnable as-is. However, they contain an
|
|
44638
44669
|
// `applicableSpan` which marks the entire argument list, and that span is in the context of the
|
|
44639
|
-
// TCB's `ts.CallExpression`. It needs to be replaced with the span for the `
|
|
44640
|
-
// `SafeMethodCall`) argument list.
|
|
44670
|
+
// TCB's `ts.CallExpression`. It needs to be replaced with the span for the `Call` argument list.
|
|
44641
44671
|
return Object.assign(Object.assign({}, res), { applicableSpan: {
|
|
44642
44672
|
start: expr.argumentSpan.start,
|
|
44643
44673
|
length: expr.argumentSpan.end - expr.argumentSpan.start,
|
|
@@ -44752,7 +44782,8 @@ https://v9.angular.io/guide/template-typecheck#template-type-checking`,
|
|
|
44752
44782
|
const node = positionDetails.context.kind === TargetNodeKind.TwoWayBindingContext ?
|
|
44753
44783
|
positionDetails.context.nodes[0] :
|
|
44754
44784
|
positionDetails.context.node;
|
|
44755
|
-
return new QuickInfoBuilder(this.tsLS, compiler, templateInfo.component, node
|
|
44785
|
+
return new QuickInfoBuilder(this.tsLS, compiler, templateInfo.component, node, positionDetails.parent)
|
|
44786
|
+
.get();
|
|
44756
44787
|
}
|
|
44757
44788
|
getReferencesAtPosition(fileName, position) {
|
|
44758
44789
|
return this.withCompilerAndPerfTracing(PerfPhase.LsReferencesAndRenames, (compiler) => {
|