feat(ivy): let ngtsc statically evaluate `Array.concat` calls (#29887)
Previously, only static evaluation of `Array.slice` was implemented in ngtsc's static evaluator. This commit adds support for `Array.concat`. Closes #29835 PR Close #29887
This commit is contained in:
parent
696e520842
commit
725148a44d
|
@ -22,3 +22,21 @@ export class ArraySliceBuiltinFn extends BuiltinFn {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ArrayConcatBuiltinFn extends BuiltinFn {
|
||||
constructor(private node: ts.Node, private lhs: ResolvedValueArray) { super(); }
|
||||
|
||||
evaluate(args: ResolvedValueArray): ResolvedValue {
|
||||
const result: ResolvedValueArray = [...this.lhs];
|
||||
for (const arg of args) {
|
||||
if (arg instanceof DynamicValue) {
|
||||
result.push(DynamicValue.fromDynamicInput(this.node, arg));
|
||||
} else if (Array.isArray(arg)) {
|
||||
result.push(...arg);
|
||||
} else {
|
||||
result.push(arg);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import {Reference} from '../../imports';
|
|||
import {OwningModule} from '../../imports/src/references';
|
||||
import {Declaration, ReflectionHost} from '../../reflection';
|
||||
|
||||
import {ArraySliceBuiltinFn} from './builtin';
|
||||
import {ArrayConcatBuiltinFn, ArraySliceBuiltinFn} from './builtin';
|
||||
import {DynamicValue} from './dynamic';
|
||||
import {ForeignFunctionResolver, VisitedFilesCallback} from './interface';
|
||||
import {BuiltinFn, EnumValue, ResolvedValue, ResolvedValueArray, ResolvedValueMap} from './result';
|
||||
|
@ -340,6 +340,8 @@ export class StaticInterpreter {
|
|||
return lhs.length;
|
||||
} else if (rhs === 'slice') {
|
||||
return new ArraySliceBuiltinFn(node, lhs);
|
||||
} else if (rhs === 'concat') {
|
||||
return new ArrayConcatBuiltinFn(node, lhs);
|
||||
}
|
||||
if (typeof rhs !== 'number' || !Number.isInteger(rhs)) {
|
||||
return DynamicValue.fromUnknown(node);
|
||||
|
|
|
@ -130,6 +130,14 @@ describe('ngtsc metadata', () => {
|
|||
expect(evaluate(`const a = [1, 2, 3];`, 'a[\'slice\']()')).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('array `concat` function works', () => {
|
||||
expect(evaluate(`const a = [1, 2], b = [3, 4];`, 'a[\'concat\'](b)')).toEqual([1, 2, 3, 4]);
|
||||
expect(evaluate(`const a = [1, 2], b = 3;`, 'a[\'concat\'](b)')).toEqual([1, 2, 3]);
|
||||
expect(evaluate(`const a = [1, 2], b = 3, c = [4, 5];`, 'a[\'concat\'](b, c)')).toEqual([
|
||||
1, 2, 3, 4, 5
|
||||
]);
|
||||
});
|
||||
|
||||
it('negation works', () => {
|
||||
expect(evaluate(`const x = 3;`, '!x')).toEqual(false);
|
||||
expect(evaluate(`const x = 3;`, '!!x')).toEqual(true);
|
||||
|
|
Loading…
Reference in New Issue