diff --git a/packages/compiler-cli/ngcc/src/utils.ts b/packages/compiler-cli/ngcc/src/utils.ts index 91cc0f9538..d36ce1d9d2 100644 --- a/packages/compiler-cli/ngcc/src/utils.ts +++ b/packages/compiler-cli/ngcc/src/utils.ts @@ -161,6 +161,8 @@ export function getTsHelperFnFromIdentifier(id: ts.Identifier): KnownDeclaration return KnownDeclaration.TsHelperSpread; case '__spreadArrays': return KnownDeclaration.TsHelperSpreadArrays; + case '__spreadArray': + return KnownDeclaration.TsHelperSpreadArray; default: return null; } diff --git a/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts b/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts index fb8315506f..883d69f894 100644 --- a/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts @@ -1999,10 +1999,12 @@ exports.MissingClass2 = MissingClass2; function __assign(t, ...sources) { /* ... */ } function __spread(...args) { /* ... */ } function __spreadArrays(...args) { /* ... */ } + function __spreadArray(to, from) { /* ... */ } var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2018,6 +2020,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed TypeScript helpers (as function declarations)', () => { @@ -2027,10 +2030,12 @@ exports.MissingClass2 = MissingClass2; function __assign$1(t, ...sources) { /* ... */ } function __spread$2(...args) { /* ... */ } function __spreadArrays$3(...args) { /* ... */ } + function __spreadArray$3(to, from) { /* ... */ } var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2046,6 +2051,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize TypeScript helpers (as variable declarations)', () => { @@ -2055,10 +2061,12 @@ exports.MissingClass2 = MissingClass2; var __assign = (this && this.__assign) || function (t, ...sources) { /* ... */ } var __spread = (this && this.__spread) || function (...args) { /* ... */ } var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ } + var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ } var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2074,6 +2082,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed TypeScript helpers (as variable declarations)', () => { @@ -2083,10 +2092,12 @@ exports.MissingClass2 = MissingClass2; var __assign$1 = (this && this.__assign$1) || function (t, ...sources) { /* ... */ } var __spread$2 = (this && this.__spread$2) || function (...args) { /* ... */ } var __spreadArrays$3 = (this && this.__spreadArrays$3) || function (...args) { /* ... */ } + var __spreadArray$3 = (this && this.__spreadArray$3) || function (to, from) { /* ... */ } var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2102,6 +2113,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize imported TypeScript helpers', () => { @@ -2114,6 +2126,7 @@ exports.MissingClass2 = MissingClass2; var a = tslib_1.__assign({foo: 'bar'}, {baz: 'qux'}); var b = tslib_1.__spread(['foo', 'bar'], ['baz', 'qux']); var c = tslib_1.__spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = tslib_1.__spreadArray(['foo', 'bar'], ['baz', 'qux']); `, }, { @@ -2122,6 +2135,7 @@ exports.MissingClass2 = MissingClass2; export declare function __assign(t: any, ...sources: any[]): any; export declare function __spread(...args: any[][]): any[]; export declare function __spreadArrays(...args: any[][]): any[]; + export declare function __spreadArray(to: any[], from: any[]): any[]; `, }, ]; @@ -2140,6 +2154,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign, 'tslib'); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib'); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib'); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib'); }); it('should recognize undeclared, unimported TypeScript helpers (by name)', () => { @@ -2149,6 +2164,7 @@ exports.MissingClass2 = MissingClass2; var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2174,6 +2190,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed, undeclared, unimported TypeScript helpers (by name)', () => { @@ -2183,6 +2200,7 @@ exports.MissingClass2 = MissingClass2; var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2208,6 +2226,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize enum declarations with string values', () => { @@ -2441,6 +2460,7 @@ exports.MissingClass2 = MissingClass2; export declare function __assign(t: any, ...sources: any[]): any; export declare function __spread(...args: any[][]): any[]; export declare function __spreadArrays(...args: any[][]): any[]; + export declare function __spreadArray(to: any[], from: any[]): any[]; export declare function __unknownHelper(...args: any[]): any; `, }; @@ -2456,6 +2476,7 @@ exports.MissingClass2 = MissingClass2; ['__assign', KnownDeclaration.TsHelperAssign], ['__spread', KnownDeclaration.TsHelperSpread], ['__spreadArrays', KnownDeclaration.TsHelperSpreadArrays], + ['__spreadArray', KnownDeclaration.TsHelperSpreadArray], ['__unknownHelper', null], ]); }); diff --git a/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts b/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts index d258f63c4f..4e112a86f8 100644 --- a/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts @@ -2059,10 +2059,12 @@ runInEachFileSystem(() => { function __assign(t, ...sources) { /* ... */ } function __spread(...args) { /* ... */ } function __spreadArrays(...args) { /* ... */ } + function __spreadArray(to, from) { /* ... */ } var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2077,6 +2079,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed TypeScript helpers (as function declarations)', () => { @@ -2086,10 +2089,12 @@ runInEachFileSystem(() => { function __assign$1(t, ...sources) { /* ... */ } function __spread$2(...args) { /* ... */ } function __spreadArrays$3(...args) { /* ... */ } + function __spreadArray$3(to, from) { /* ... */ } var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2104,6 +2109,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize TypeScript helpers (as variable declarations)', () => { @@ -2113,11 +2119,13 @@ runInEachFileSystem(() => { var __assign = (this && this.__assign) || function (t, ...sources) { /* ... */ } var __spread = (this && this.__spread) || function (...args) { /* ... */ } var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ } + var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ } var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); - `, + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); + `, }; loadTestFiles([file]); const bundle = makeTestBundleProgram(file.name); @@ -2131,6 +2139,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed TypeScript helpers (as variable declarations)', () => { @@ -2140,10 +2149,12 @@ runInEachFileSystem(() => { var __assign$1 = (this && this.__assign$1) || function (t, ...sources) { /* ... */ } var __spread$2 = (this && this.__spread$2) || function (...args) { /* ... */ } var __spreadArrays$3 = (this && this.__spreadArrays$3) || function (...args) { /* ... */ } + var __spreadArray$3 = (this && this.__spreadArray$3) || function (to, from) { /* ... */ } var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2158,6 +2169,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize imported TypeScript helpers (named imports)', () => { @@ -2165,11 +2177,12 @@ runInEachFileSystem(() => { { name: _('/test.js'), contents: ` - import {__assign, __spread, __spreadArrays} from 'tslib'; + import {__assign, __spread, __spreadArrays, __spreadArray} from 'tslib'; var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); `, }, { @@ -2178,6 +2191,7 @@ runInEachFileSystem(() => { export declare function __assign(t: any, ...sources: any[]): any; export declare function __spread(...args: any[][]): any[]; export declare function __spreadArrays(...args: any[][]): any[]; + export declare function __spreadArray(to: any[], from: any[]): any[]; `, }, ]; @@ -2195,6 +2209,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign, 'tslib'); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib'); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib'); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib'); }); it('should recognize imported TypeScript helpers (star import)', () => { @@ -2207,6 +2222,7 @@ runInEachFileSystem(() => { var a = tslib_1.__assign({foo: 'bar'}, {baz: 'qux'}); var b = tslib_1.__spread(['foo', 'bar'], ['baz', 'qux']); var c = tslib_1.__spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = tslib_1.__spreadArray(['foo', 'bar'], ['baz', 'qux']); `, }, { @@ -2215,6 +2231,7 @@ runInEachFileSystem(() => { export declare function __assign(t: any, ...sources: any[]): any; export declare function __spread(...args: any[][]): any[]; export declare function __spreadArrays(...args: any[][]): any[]; + export declare function __spreadArray(to: any[], from: any[]): any[]; `, }, ]; @@ -2232,6 +2249,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign, 'tslib'); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib'); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib'); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib'); }); it('should recognize undeclared, unimported TypeScript helpers (by name)', () => { @@ -2241,6 +2259,7 @@ runInEachFileSystem(() => { var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2263,6 +2282,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed, undeclared, unimported TypeScript helpers (by name)', () => { @@ -2272,6 +2292,7 @@ runInEachFileSystem(() => { var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); `, }; loadTestFiles([file]); @@ -2294,6 +2315,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize enum declarations with string values', () => { @@ -2456,6 +2478,7 @@ runInEachFileSystem(() => { export declare function __assign(t: any, ...sources: any[]): any; export declare function __spread(...args: any[][]): any[]; export declare function __spreadArrays(...args: any[][]): any[]; + export declare function __spreadArray(to: any[], from: any[]): any[]; export declare function __unknownHelper(...args: any[]): any; `, }; @@ -2470,6 +2493,7 @@ runInEachFileSystem(() => { ['__assign', KnownDeclaration.TsHelperAssign], ['__spread', KnownDeclaration.TsHelperSpread], ['__spreadArrays', KnownDeclaration.TsHelperSpreadArrays], + ['__spreadArray', KnownDeclaration.TsHelperSpreadArray], ['__unknownHelper', null], ]); }); diff --git a/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts b/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts index 870d49edae..5f42d2a7bc 100644 --- a/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts @@ -2331,10 +2331,12 @@ runInEachFileSystem(() => { function __assign(t, ...sources) { /* ... */ } function __spread(...args) { /* ... */ } function __spreadArrays(...args) { /* ... */ } + function __spreadArray(to, from) { /* ... */ } var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); }))); `, }; @@ -2349,6 +2351,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed TypeScript helpers (as function declarations)', () => { @@ -2363,10 +2366,12 @@ runInEachFileSystem(() => { function __assign$1(t, ...sources) { /* ... */ } function __spread$2(...args) { /* ... */ } function __spreadArrays$3(...args) { /* ... */ } + function __spreadArray$3(to, from) { /* ... */ } var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); }))); `, }; @@ -2381,6 +2386,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize TypeScript helpers (as variable declarations)', () => { @@ -2395,10 +2401,12 @@ runInEachFileSystem(() => { var __assign = (this && this.__assign) || function (t, ...sources) { /* ... */ } var __spread = (this && this.__spread) || function (...args) { /* ... */ } var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ } + var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ } var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); }))); `, }; @@ -2413,6 +2421,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed TypeScript helpers (as variable declarations)', () => { @@ -2427,10 +2436,12 @@ runInEachFileSystem(() => { var __assign$1 = (this && this.__assign$1) || function (t, ...sources) { /* ... */ } var __spread$2 = (this && this.__spread$2) || function (...args) { /* ... */ } var __spreadArrays$3 = (this && this.__spreadArrays$3) || function (...args) { /* ... */ } + var __spreadArray$3 = (this && this.__spreadArray$3) || function (to, from) { /* ... */ } var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); }))); `, }; @@ -2445,6 +2456,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize imported TypeScript helpers', () => { @@ -2460,6 +2472,7 @@ runInEachFileSystem(() => { var a = tslib_1.__assign({foo: 'bar'}, {baz: 'qux'}); var b = tslib_1.__spread(['foo', 'bar'], ['baz', 'qux']); var c = tslib_1.__spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = tslib_1.__spreadArray(['foo', 'bar'], ['baz', 'qux']); }))); `, }, @@ -2469,6 +2482,7 @@ runInEachFileSystem(() => { export declare function __assign(t: any, ...sources: any[]): any; export declare function __spread(...args: any[][]): any[]; export declare function __spreadArrays(...args: any[][]): any[]; + export declare function __spreadArray(to: any[], from: any[]): any[]; `, }, ]; @@ -2487,6 +2501,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign, 'tslib'); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib'); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib'); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib'); }); it('should recognize undeclared, unimported TypeScript helpers (by name)', () => { @@ -2501,6 +2516,7 @@ runInEachFileSystem(() => { var a = __assign({foo: 'bar'}, {baz: 'qux'}); var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); }))); `, }; @@ -2527,6 +2543,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize suffixed, undeclared, unimported TypeScript helpers (by name)', () => { @@ -2541,6 +2558,7 @@ runInEachFileSystem(() => { var a = __assign$1({foo: 'bar'}, {baz: 'qux'}); var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); + var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); }))); `, }; @@ -2567,6 +2585,7 @@ runInEachFileSystem(() => { testForHelper('a', '__assign$1', KnownDeclaration.TsHelperAssign); testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); + testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); }); it('should recognize enum declarations with string values', () => { @@ -2841,6 +2860,7 @@ runInEachFileSystem(() => { export declare function __assign(t: any, ...sources: any[]): any; export declare function __spread(...args: any[][]): any[]; export declare function __spreadArrays(...args: any[][]): any[]; + export declare function __spreadArray(to: any[], from: any[]): any[]; export declare function __unknownHelper(...args: any[]): any; `, }; @@ -2855,6 +2875,7 @@ runInEachFileSystem(() => { ['__assign', KnownDeclaration.TsHelperAssign], ['__spread', KnownDeclaration.TsHelperSpread], ['__spreadArrays', KnownDeclaration.TsHelperSpreadArrays], + ['__spreadArray', KnownDeclaration.TsHelperSpreadArray], ['__unknownHelper', null], ]); }); diff --git a/packages/compiler-cli/ngcc/test/utils_spec.ts b/packages/compiler-cli/ngcc/test/utils_spec.ts index 14aa5fbabe..6d288c7497 100644 --- a/packages/compiler-cli/ngcc/test/utils_spec.ts +++ b/packages/compiler-cli/ngcc/test/utils_spec.ts @@ -108,6 +108,22 @@ describe('getTsHelperFnFromDeclaration()', () => { expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperSpreadArrays); }); + it('should recognize the `__spreadArray` helper as function declaration', () => { + const decl1 = createFunctionDeclaration('__spreadArray'); + const decl2 = createFunctionDeclaration('__spreadArray$42'); + + expect(getTsHelperFnFromDeclaration(decl1)).toBe(KnownDeclaration.TsHelperSpreadArray); + expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperSpreadArray); + }); + + it('should recognize the `__spreadArray` helper as variable declaration', () => { + const decl1 = createVariableDeclaration('__spreadArray'); + const decl2 = createVariableDeclaration('__spreadArray$42'); + + expect(getTsHelperFnFromDeclaration(decl1)).toBe(KnownDeclaration.TsHelperSpreadArray); + expect(getTsHelperFnFromDeclaration(decl2)).toBe(KnownDeclaration.TsHelperSpreadArray); + }); + it('should return null for unrecognized helpers', () => { const decl1 = createFunctionDeclaration('__foo'); const decl2 = createVariableDeclaration('spread'); @@ -158,6 +174,14 @@ describe('getTsHelperFnFromIdentifier()', () => { expect(getTsHelperFnFromIdentifier(id2)).toBe(KnownDeclaration.TsHelperSpreadArrays); }); + it('should recognize the `__spreadArray` helper', () => { + const id1 = ts.createIdentifier('__spreadArray'); + const id2 = ts.createIdentifier('__spreadArray$42'); + + expect(getTsHelperFnFromIdentifier(id1)).toBe(KnownDeclaration.TsHelperSpreadArray); + expect(getTsHelperFnFromIdentifier(id2)).toBe(KnownDeclaration.TsHelperSpreadArray); + }); + it('should return null for unrecognized helpers', () => { const id1 = ts.createIdentifier('__foo'); const id2 = ts.createIdentifier('spread'); diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/src/known_declaration.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/known_declaration.ts index afc2e4d62b..3712eae54b 100644 --- a/packages/compiler-cli/src/ngtsc/partial_evaluator/src/known_declaration.ts +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/known_declaration.ts @@ -10,7 +10,7 @@ import {KnownDeclaration} from '../../reflection/src/host'; import {ObjectAssignBuiltinFn} from './builtin'; import {ResolvedValue} from './result'; -import {AssignHelperFn, SpreadHelperFn} from './ts_helpers'; +import {AssignHelperFn, SpreadArrayHelperFn, SpreadHelperFn} from './ts_helpers'; /** Resolved value for the JavaScript global `Object` declaration. */ export const jsGlobalObjectValue = new Map([['assign', new ObjectAssignBuiltinFn()]]); @@ -21,6 +21,9 @@ const assignTsHelperFn = new AssignHelperFn(); /** Resolved value for the `__spread()` and `__spreadArrays()` TypeScript helper declarations. */ const spreadTsHelperFn = new SpreadHelperFn(); +/** Resolved value for the `__spreadArray()` TypeScript helper declarations. */ +const spreadArrayTsHelperFn = new SpreadArrayHelperFn(); + /** * Resolves the specified known declaration to a resolved value. For example, * the known JavaScript global `Object` will resolve to a `Map` that provides the @@ -35,6 +38,8 @@ export function resolveKnownDeclaration(decl: KnownDeclaration): ResolvedValue { case KnownDeclaration.TsHelperSpread: case KnownDeclaration.TsHelperSpreadArrays: return spreadTsHelperFn; + case KnownDeclaration.TsHelperSpreadArray: + return spreadArrayTsHelperFn; default: throw new Error(`Cannot resolve known declaration. Received: ${KnownDeclaration[decl]}.`); } diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/src/ts_helpers.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/ts_helpers.ts index 2466eee6d2..27080f0915 100644 --- a/packages/compiler-cli/src/ngtsc/partial_evaluator/src/ts_helpers.ts +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/ts_helpers.ts @@ -10,7 +10,7 @@ import * as ts from 'typescript'; import {ObjectAssignBuiltinFn} from './builtin'; import {DynamicValue} from './dynamic'; -import {KnownFn, ResolvedValueArray} from './result'; +import {KnownFn, ResolvedValue, ResolvedValueArray} from './result'; // Use the same implementation we use for `Object.assign()`. Semantically these functions are the @@ -35,3 +35,27 @@ export class SpreadHelperFn extends KnownFn { return result; } } + +// Used for `__spreadArray` TypeScript helper function. +export class SpreadArrayHelperFn extends KnownFn { + evaluate(node: ts.Node, args: ResolvedValueArray): ResolvedValue { + if (args.length !== 2) { + return DynamicValue.fromUnknown(node); + } + + const [to, from] = args; + if (to instanceof DynamicValue) { + return DynamicValue.fromDynamicInput(node, to); + } else if (from instanceof DynamicValue) { + return DynamicValue.fromDynamicInput(node, from); + } + + if (!Array.isArray(to)) { + return DynamicValue.fromInvalidExpressionType(node, to); + } else if (!Array.isArray(from)) { + return DynamicValue.fromInvalidExpressionType(node, from); + } + + return to.concat(from); + } +} diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts index 37d1c56d00..e4ead4720e 100644 --- a/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts @@ -646,6 +646,7 @@ runInEachFileSystem(() => { export declare function __assign(t: any, ...sources: any[]): any; export declare function __spread(...args: any[][]): any[]; export declare function __spreadArrays(...args: any[][]): any[]; + export declare function __spreadArray(to: any[], from: any[]): any[]; `, }, ]); @@ -733,6 +734,30 @@ runInEachFileSystem(() => { expect(arr).toEqual([4, 5, 6]); }); + + it('should evaluate `__spreadArray()` (named import)', () => { + const arr: number[] = evaluateExpression( + ` + import {__spreadArray} from 'tslib'; + const a = [4]; + const b = [5, 6]; + `, + '__spreadArray(a, b)'); + + expect(arr).toEqual([4, 5, 6]); + }); + + it('should evaluate `__spreadArray()` (star import)', () => { + const arr: number[] = evaluateExpression( + ` + import * as tslib from 'tslib'; + const a = [4]; + const b = [5, 6]; + `, + 'tslib.__spreadArray(a, b)'); + + expect(arr).toEqual([4, 5, 6]); + }); }); describe('(with emitted TypeScript helpers as functions)', () => { @@ -742,6 +767,7 @@ runInEachFileSystem(() => { function __assign(t, ...sources) { /* ... */ } function __spread(...args) { /* ... */ } function __spreadArrays(...args) { /* ... */ } + function __spreadArray(to, from) { /* ... */ } `; const {checker, expression} = makeExpression(helpers + code, expr); @@ -786,6 +812,17 @@ runInEachFileSystem(() => { expect(arr).toEqual([4, 5, 6]); }); + + it('should evaluate `__spreadArray()`', () => { + const arr: number[] = evaluateExpression( + ` + const a = [4]; + const b = [5, 6]; + `, + '__spreadArray(a, b)'); + + expect(arr).toEqual([4, 5, 6]); + }); }); describe('(with emitted TypeScript helpers as variables)', () => { @@ -795,6 +832,7 @@ runInEachFileSystem(() => { var __assign = (this && this.__assign) || function (t, ...sources) { /* ... */ } var __spread = (this && this.__spread) || function (...args) { /* ... */ } var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ } + var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ } `; const {checker, expression} = makeExpression(helpers + code, expr); @@ -839,6 +877,17 @@ runInEachFileSystem(() => { expect(arr).toEqual([4, 5, 6]); }); + + it('should evaluate `__spreadArray()`', () => { + const arr: number[] = evaluateExpression( + ` + const a = [4]; + const b = [5, 6]; + `, + '__spreadArray(a, b)'); + + expect(arr).toEqual([4, 5, 6]); + }); }); describe('(visited file tracking)', () => { @@ -980,6 +1029,8 @@ runInEachFileSystem(() => { return KnownDeclaration.TsHelperSpread; case '__spreadArrays': return KnownDeclaration.TsHelperSpreadArrays; + case '__spreadArray': + return KnownDeclaration.TsHelperSpreadArray; default: return null; } diff --git a/packages/compiler-cli/src/ngtsc/reflection/src/host.ts b/packages/compiler-cli/src/ngtsc/reflection/src/host.ts index cbf28be5b8..c3dbcf07ca 100644 --- a/packages/compiler-cli/src/ngtsc/reflection/src/host.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/src/host.ts @@ -474,6 +474,11 @@ export enum KnownDeclaration { * Indicates the `__spreadArrays` TypeScript helper function. */ TsHelperSpreadArrays, + + /** + * Indicates the `__spreadArray` TypeScript helper function. + */ + TsHelperSpreadArray, } /**