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:
parent
cb34514d05
commit
c3c0df9d56
@ -427,20 +427,20 @@ export class StaticInterpreter {
|
|||||||
|
|
||||||
const args = this.evaluateFunctionArguments(node, context);
|
const args = this.evaluateFunctionArguments(node, context);
|
||||||
const newScope: Scope = new Map<ts.ParameterDeclaration, ResolvedValue>();
|
const newScope: Scope = new Map<ts.ParameterDeclaration, ResolvedValue>();
|
||||||
|
const calleeContext = {...context, scope: newScope};
|
||||||
fn.parameters.forEach((param, index) => {
|
fn.parameters.forEach((param, index) => {
|
||||||
let arg = args[index];
|
let arg = args[index];
|
||||||
if (param.node.dotDotDotToken !== undefined) {
|
if (param.node.dotDotDotToken !== undefined) {
|
||||||
arg = args.slice(index);
|
arg = args.slice(index);
|
||||||
}
|
}
|
||||||
if (arg === undefined && param.initializer !== null) {
|
if (arg === undefined && param.initializer !== null) {
|
||||||
arg = this.visitExpression(param.initializer, context);
|
arg = this.visitExpression(param.initializer, calleeContext);
|
||||||
}
|
}
|
||||||
newScope.set(param.node, arg);
|
newScope.set(param.node, arg);
|
||||||
});
|
});
|
||||||
|
|
||||||
return ret.expression !== undefined ?
|
return ret.expression !== undefined ? this.visitExpression(ret.expression, calleeContext) :
|
||||||
this.visitExpression(ret.expression, {...context, scope: newScope}) :
|
undefined;
|
||||||
undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private visitConditionalExpression(node: ts.ConditionalExpression, context: Context):
|
private visitConditionalExpression(node: ts.ConditionalExpression, context: Context):
|
||||||
|
@ -75,6 +75,12 @@ describe('ngtsc metadata', () => {
|
|||||||
expect(evaluate(`function foo(bar) { return bar; }`, 'foo("test")')).toEqual('test');
|
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', () => {
|
it('function call spread works', () => {
|
||||||
expect(evaluate(`function foo(a, ...b) { return [a, b]; }`, 'foo(1, ...[2, 3])')).toEqual([
|
expect(evaluate(`function foo(a, ...b) { return [a, b]; }`, 'foo(1, ...[2, 3])')).toEqual([
|
||||||
1, [2, 3]
|
1, [2, 3]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user