fix(ngcc): handle new __spreadArrays
tslib helper (#33617)
We already have special cases for the `__spread` helper function and with this change we handle the new tslib helper introduced in version 1.10 `__spreadArrays`. For more context see: https://github.com/microsoft/tslib/releases/tag/1.10.0 Fixes: #33614 PR Close #33617
This commit is contained in:
parent
2a4061a3fd
commit
d749dd3ea1
@ -627,10 +627,13 @@ function getTsHelperFn(node: ts.NamedDeclaration): TsHelperFn|null {
|
|||||||
stripDollarSuffix(node.name.text) :
|
stripDollarSuffix(node.name.text) :
|
||||||
null;
|
null;
|
||||||
|
|
||||||
if (name === '__spread') {
|
switch (name) {
|
||||||
return TsHelperFn.Spread;
|
case '__spread':
|
||||||
} else {
|
return TsHelperFn.Spread;
|
||||||
return null;
|
case '__spreadArrays':
|
||||||
|
return TsHelperFn.SpreadArrays;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1651,7 +1651,7 @@ runInEachFileSystem(() => {
|
|||||||
it('should recognize TypeScript __spread helper function declaration', () => {
|
it('should recognize TypeScript __spread helper function declaration', () => {
|
||||||
const file: TestFile = {
|
const file: TestFile = {
|
||||||
name: _('/declaration.d.ts'),
|
name: _('/declaration.d.ts'),
|
||||||
contents: `export declare function __spread(...args: any[]): any[];`,
|
contents: `export declare function __spread(...args: any[][]): any[];`,
|
||||||
};
|
};
|
||||||
loadTestFiles([file]);
|
loadTestFiles([file]);
|
||||||
const {program} = makeTestBundleProgram(file.name);
|
const {program} = makeTestBundleProgram(file.name);
|
||||||
@ -1711,6 +1711,78 @@ runInEachFileSystem(() => {
|
|||||||
expect(definition.helper).toBe(TsHelperFn.Spread);
|
expect(definition.helper).toBe(TsHelperFn.Spread);
|
||||||
expect(definition.parameters.length).toEqual(0);
|
expect(definition.parameters.length).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should recognize TypeScript __spreadArrays helper function declaration', () => {
|
||||||
|
const file: TestFile = {
|
||||||
|
name: _('/declaration.d.ts'),
|
||||||
|
contents: `export declare function __spreadArrays(...args: any[][]): any[];`,
|
||||||
|
};
|
||||||
|
loadTestFiles([file]);
|
||||||
|
const {program} = makeTestBundleProgram(file.name);
|
||||||
|
const host = new Esm5ReflectionHost(new MockLogger(), false, program.getTypeChecker());
|
||||||
|
|
||||||
|
const node =
|
||||||
|
getDeclaration(program, file.name, '__spreadArrays', isNamedFunctionDeclaration) !;
|
||||||
|
|
||||||
|
const definition = host.getDefinitionOfFunction(node) !;
|
||||||
|
expect(definition.node).toBe(node);
|
||||||
|
expect(definition.body).toBeNull();
|
||||||
|
expect(definition.helper).toBe(TsHelperFn.SpreadArrays);
|
||||||
|
expect(definition.parameters.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recognize TypeScript __spreadArrays helper function implementation', () => {
|
||||||
|
const file: TestFile = {
|
||||||
|
name: _('/implementation.js'),
|
||||||
|
contents: `
|
||||||
|
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||||
|
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||||
|
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||||
|
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||||
|
r[k] = a[j];
|
||||||
|
return r;
|
||||||
|
};`,
|
||||||
|
};
|
||||||
|
loadTestFiles([file]);
|
||||||
|
const {program} = makeTestBundleProgram(file.name);
|
||||||
|
const host = new Esm5ReflectionHost(new MockLogger(), false, program.getTypeChecker());
|
||||||
|
|
||||||
|
const node =
|
||||||
|
getDeclaration(program, file.name, '__spreadArrays', ts.isVariableDeclaration) !;
|
||||||
|
|
||||||
|
const definition = host.getDefinitionOfFunction(node) !;
|
||||||
|
expect(definition.node).toBe(node);
|
||||||
|
expect(definition.body).toBeNull();
|
||||||
|
expect(definition.helper).toBe(TsHelperFn.SpreadArrays);
|
||||||
|
expect(definition.parameters.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should recognize TypeScript __spreadArrays helper function implementation when suffixed',
|
||||||
|
() => {
|
||||||
|
const file: TestFile = {
|
||||||
|
name: _('/implementation.js'),
|
||||||
|
contents: `
|
||||||
|
var __spreadArrays$2 = (this && this.__spreadArrays$2) || function () {
|
||||||
|
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||||
|
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||||
|
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||||
|
r[k] = a[j];
|
||||||
|
return r;
|
||||||
|
};`,
|
||||||
|
};
|
||||||
|
loadTestFiles([file]);
|
||||||
|
const {program} = makeTestBundleProgram(file.name);
|
||||||
|
const host = new Esm5ReflectionHost(new MockLogger(), false, program.getTypeChecker());
|
||||||
|
|
||||||
|
const node =
|
||||||
|
getDeclaration(program, file.name, '__spreadArrays$2', ts.isVariableDeclaration) !;
|
||||||
|
|
||||||
|
const definition = host.getDefinitionOfFunction(node) !;
|
||||||
|
expect(definition.node).toBe(node);
|
||||||
|
expect(definition.body).toBeNull();
|
||||||
|
expect(definition.helper).toBe(TsHelperFn.SpreadArrays);
|
||||||
|
expect(definition.parameters.length).toEqual(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getImportOfIdentifier()', () => {
|
describe('getImportOfIdentifier()', () => {
|
||||||
|
@ -15,10 +15,12 @@ import {ResolvedValue, ResolvedValueArray} from './result';
|
|||||||
|
|
||||||
export function evaluateTsHelperInline(
|
export function evaluateTsHelperInline(
|
||||||
helper: TsHelperFn, node: ts.Node, args: ResolvedValueArray): ResolvedValue {
|
helper: TsHelperFn, node: ts.Node, args: ResolvedValueArray): ResolvedValue {
|
||||||
if (helper === TsHelperFn.Spread) {
|
switch (helper) {
|
||||||
return evaluateTsSpreadHelper(node, args);
|
case TsHelperFn.Spread:
|
||||||
} else {
|
case TsHelperFn.SpreadArrays:
|
||||||
throw new Error(`Cannot evaluate unknown helper ${helper} inline`);
|
return evaluateTsSpreadHelper(node, args);
|
||||||
|
default:
|
||||||
|
throw new Error(`Cannot evaluate unknown helper ${helper} inline`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +514,28 @@ runInEachFileSystem(() => {
|
|||||||
{
|
{
|
||||||
name: _('/node_modules/tslib/index.d.ts'),
|
name: _('/node_modules/tslib/index.d.ts'),
|
||||||
contents: `
|
contents: `
|
||||||
export declare function __spread(...args: any[]): any[];
|
export declare function __spread(...args: any[][]): any[];
|
||||||
|
`
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const reflectionHost = new TsLibAwareReflectionHost(checker);
|
||||||
|
const evaluator = new PartialEvaluator(reflectionHost, checker);
|
||||||
|
const value = evaluator.evaluate(expression);
|
||||||
|
expect(value).toEqual([1, 2, 3]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should evaluate TypeScript __spreadArrays helper', () => {
|
||||||
|
const {checker, expression} = makeExpression(
|
||||||
|
`
|
||||||
|
import * as tslib from 'tslib';
|
||||||
|
const a = [1];
|
||||||
|
const b = [2, 3];
|
||||||
|
`,
|
||||||
|
'tslib.__spreadArrays(a, b)', [
|
||||||
|
{
|
||||||
|
name: _('/node_modules/tslib/index.d.ts'),
|
||||||
|
contents: `
|
||||||
|
export declare function __spreadArrays(...args: any[][]): any[];
|
||||||
`
|
`
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
@ -612,10 +633,13 @@ runInEachFileSystem(() => {
|
|||||||
function getTsHelperFn(node: ts.FunctionDeclaration): TsHelperFn|null {
|
function getTsHelperFn(node: ts.FunctionDeclaration): TsHelperFn|null {
|
||||||
const name = node.name !== undefined && ts.isIdentifier(node.name) && node.name.text;
|
const name = node.name !== undefined && ts.isIdentifier(node.name) && node.name.text;
|
||||||
|
|
||||||
if (name === '__spread') {
|
switch (name) {
|
||||||
return TsHelperFn.Spread;
|
case '__spread':
|
||||||
} else {
|
return TsHelperFn.Spread;
|
||||||
return null;
|
case '__spreadArrays':
|
||||||
|
return TsHelperFn.SpreadArrays;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -336,6 +336,10 @@ export enum TsHelperFn {
|
|||||||
* Indicates the `__spread` function.
|
* Indicates the `__spread` function.
|
||||||
*/
|
*/
|
||||||
Spread,
|
Spread,
|
||||||
|
/**
|
||||||
|
* Indicates the `__spreadArrays` function.
|
||||||
|
*/
|
||||||
|
SpreadArrays,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user