fix(tsc-wrapped): collect new expressions with no arguments (#15908)
Fixes #15906
This commit is contained in:
parent
d263595c63
commit
70b1d6dd9d
|
@ -154,7 +154,8 @@ export class Evaluator {
|
||||||
case ts.SyntaxKind.CallExpression:
|
case ts.SyntaxKind.CallExpression:
|
||||||
const callExpression = <ts.CallExpression>node;
|
const callExpression = <ts.CallExpression>node;
|
||||||
// We can fold a <array>.concat(<v>).
|
// We can fold a <array>.concat(<v>).
|
||||||
if (isMethodCallOf(callExpression, 'concat') && callExpression.arguments.length === 1) {
|
if (isMethodCallOf(callExpression, 'concat') &&
|
||||||
|
arrayOrEmpty(callExpression.arguments).length === 1) {
|
||||||
const arrayNode = (<ts.PropertyAccessExpression>callExpression.expression).expression;
|
const arrayNode = (<ts.PropertyAccessExpression>callExpression.expression).expression;
|
||||||
if (this.isFoldableWorker(arrayNode, folding) &&
|
if (this.isFoldableWorker(arrayNode, folding) &&
|
||||||
this.isFoldableWorker(callExpression.arguments[0], folding)) {
|
this.isFoldableWorker(callExpression.arguments[0], folding)) {
|
||||||
|
@ -167,7 +168,8 @@ export class Evaluator {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can fold a call to CONST_EXPR
|
// We can fold a call to CONST_EXPR
|
||||||
if (isCallOf(callExpression, 'CONST_EXPR') && callExpression.arguments.length === 1)
|
if (isCallOf(callExpression, 'CONST_EXPR') &&
|
||||||
|
arrayOrEmpty(callExpression.arguments).length === 1)
|
||||||
return this.isFoldableWorker(callExpression.arguments[0], folding);
|
return this.isFoldableWorker(callExpression.arguments[0], folding);
|
||||||
return false;
|
return false;
|
||||||
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
|
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||||
|
@ -295,14 +297,15 @@ export class Evaluator {
|
||||||
return recordEntry({__symbolic: 'spread', expression: spreadExpression}, node);
|
return recordEntry({__symbolic: 'spread', expression: spreadExpression}, node);
|
||||||
case ts.SyntaxKind.CallExpression:
|
case ts.SyntaxKind.CallExpression:
|
||||||
const callExpression = <ts.CallExpression>node;
|
const callExpression = <ts.CallExpression>node;
|
||||||
if (isCallOf(callExpression, 'forwardRef') && callExpression.arguments.length === 1) {
|
if (isCallOf(callExpression, 'forwardRef') &&
|
||||||
|
arrayOrEmpty(callExpression.arguments).length === 1) {
|
||||||
const firstArgument = callExpression.arguments[0];
|
const firstArgument = callExpression.arguments[0];
|
||||||
if (firstArgument.kind == ts.SyntaxKind.ArrowFunction) {
|
if (firstArgument.kind == ts.SyntaxKind.ArrowFunction) {
|
||||||
const arrowFunction = <ts.ArrowFunction>firstArgument;
|
const arrowFunction = <ts.ArrowFunction>firstArgument;
|
||||||
return recordEntry(this.evaluateNode(arrowFunction.body), node);
|
return recordEntry(this.evaluateNode(arrowFunction.body), node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const args = callExpression.arguments.map(arg => this.evaluateNode(arg));
|
const args = arrayOrEmpty(callExpression.arguments).map(arg => this.evaluateNode(arg));
|
||||||
if (!this.options.verboseInvalidExpression && args.some(isMetadataError)) {
|
if (!this.options.verboseInvalidExpression && args.some(isMetadataError)) {
|
||||||
return args.find(isMetadataError);
|
return args.find(isMetadataError);
|
||||||
}
|
}
|
||||||
|
@ -315,7 +318,8 @@ export class Evaluator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Always fold a CONST_EXPR even if the argument is not foldable.
|
// Always fold a CONST_EXPR even if the argument is not foldable.
|
||||||
if (isCallOf(callExpression, 'CONST_EXPR') && callExpression.arguments.length === 1) {
|
if (isCallOf(callExpression, 'CONST_EXPR') &&
|
||||||
|
arrayOrEmpty(callExpression.arguments).length === 1) {
|
||||||
return recordEntry(args[0], node);
|
return recordEntry(args[0], node);
|
||||||
}
|
}
|
||||||
const expression = this.evaluateNode(callExpression.expression);
|
const expression = this.evaluateNode(callExpression.expression);
|
||||||
|
@ -329,7 +333,7 @@ export class Evaluator {
|
||||||
return recordEntry(result, node);
|
return recordEntry(result, node);
|
||||||
case ts.SyntaxKind.NewExpression:
|
case ts.SyntaxKind.NewExpression:
|
||||||
const newExpression = <ts.NewExpression>node;
|
const newExpression = <ts.NewExpression>node;
|
||||||
const newArgs = newExpression.arguments.map(arg => this.evaluateNode(arg));
|
const newArgs = arrayOrEmpty(newExpression.arguments).map(arg => this.evaluateNode(arg));
|
||||||
if (!this.options.verboseInvalidExpression && newArgs.some(isMetadataError)) {
|
if (!this.options.verboseInvalidExpression && newArgs.some(isMetadataError)) {
|
||||||
return recordEntry(newArgs.find(isMetadataError), node);
|
return recordEntry(newArgs.find(isMetadataError), node);
|
||||||
}
|
}
|
||||||
|
@ -575,3 +579,9 @@ export class Evaluator {
|
||||||
function isPropertyAssignment(node: ts.Node): node is ts.PropertyAssignment {
|
function isPropertyAssignment(node: ts.Node): node is ts.PropertyAssignment {
|
||||||
return node.kind == ts.SyntaxKind.PropertyAssignment;
|
return node.kind == ts.SyntaxKind.PropertyAssignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const empty = [] as ts.NodeArray<any>;
|
||||||
|
|
||||||
|
function arrayOrEmpty<T extends ts.Node>(v: ts.NodeArray<T>): ts.NodeArray<T> {
|
||||||
|
return v || empty;
|
||||||
|
}
|
|
@ -215,8 +215,21 @@ describe('Evaluator', () => {
|
||||||
0, {__symbolic: 'spread', expression: {__symbolic: 'reference', name: 'arrImport'}}, 5
|
0, {__symbolic: 'spread', expression: {__symbolic: 'reference', name: 'arrImport'}}, 5
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should be able to handle a new expression with no arguments', () => {
|
||||||
|
const source = sourceFileOf(`
|
||||||
|
export var a = new f;
|
||||||
|
`);
|
||||||
|
const expr = findVar(source, 'a');
|
||||||
|
expect(evaluator.evaluateNode(expr.initializer))
|
||||||
|
.toEqual({__symbolic: 'new', expression: {__symbolic: 'reference', name: 'f'}});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function sourceFileOf(text: string): ts.SourceFile {
|
||||||
|
return ts.createSourceFile('test.ts', text, ts.ScriptTarget.Latest, true);
|
||||||
|
}
|
||||||
|
|
||||||
const FILES: Directory = {
|
const FILES: Directory = {
|
||||||
'directives.ts': `
|
'directives.ts': `
|
||||||
export function Pipe(options: { name?: string, pure?: boolean}) {
|
export function Pipe(options: { name?: string, pure?: boolean}) {
|
||||||
|
|
Loading…
Reference in New Issue