fix(ivy): let ngtsc evaluate default parameters in the callee context (#29888)

Previously, during the evaluation of a function call where no argument
was provided for a parameter that has a default value, the default value
would be taken from the context of the caller, instead of the callee.

This commit fixes the behavior by resolving the default value of a
parameter in the context of the callee.

PR Close #29888
This commit is contained in:
JoostK 2019-04-13 21:24:02 +02:00 committed by Ben Lesh
parent cb34514d05
commit c3c0df9d56
2 changed files with 10 additions and 4 deletions

View File

@ -427,20 +427,20 @@ export class StaticInterpreter {
const args = this.evaluateFunctionArguments(node, context);
const newScope: Scope = new Map<ts.ParameterDeclaration, ResolvedValue>();
const calleeContext = {...context, scope: newScope};
fn.parameters.forEach((param, index) => {
let arg = args[index];
if (param.node.dotDotDotToken !== undefined) {
arg = args.slice(index);
}
if (arg === undefined && param.initializer !== null) {
arg = this.visitExpression(param.initializer, context);
arg = this.visitExpression(param.initializer, calleeContext);
}
newScope.set(param.node, arg);
});
return ret.expression !== undefined ?
this.visitExpression(ret.expression, {...context, scope: newScope}) :
undefined;
return ret.expression !== undefined ? this.visitExpression(ret.expression, calleeContext) :
undefined;
}
private visitConditionalExpression(node: ts.ConditionalExpression, context: Context):

View File

@ -75,6 +75,12 @@ describe('ngtsc metadata', () => {
expect(evaluate(`function foo(bar) { return bar; }`, 'foo("test")')).toEqual('test');
});
it('function call default value works', () => {
expect(evaluate(`function foo(bar = 1) { return bar; }`, 'foo()')).toEqual(1);
expect(evaluate(`function foo(bar = 1) { return bar; }`, 'foo(2)')).toEqual(2);
expect(evaluate(`function foo(a, c = a) { return c; }; const a = 1;`, 'foo(2)')).toEqual(2);
});
it('function call spread works', () => {
expect(evaluate(`function foo(a, ...b) { return [a, b]; }`, 'foo(1, ...[2, 3])')).toEqual([
1, [2, 3]