diff --git a/packages/compiler-cli/ngcc/src/utils.ts b/packages/compiler-cli/ngcc/src/utils.ts index d36ce1d9d2..7ca4d1923b 100644 --- a/packages/compiler-cli/ngcc/src/utils.ts +++ b/packages/compiler-cli/ngcc/src/utils.ts @@ -163,6 +163,8 @@ export function getTsHelperFnFromIdentifier(id: ts.Identifier): KnownDeclaration return KnownDeclaration.TsHelperSpreadArrays; case '__spreadArray': return KnownDeclaration.TsHelperSpreadArray; + case '__read': + return KnownDeclaration.TsHelperRead; 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 883d69f894..419fcf76d2 100644 --- a/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts @@ -2000,11 +2000,13 @@ exports.MissingClass2 = MissingClass2; function __spread(...args) { /* ... */ } function __spreadArrays(...args) { /* ... */ } function __spreadArray(to, from) { /* ... */ } + function __read(o) { /* ... */ } 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']); + var e = __read(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2021,6 +2023,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed TypeScript helpers (as function declarations)', () => { @@ -2031,11 +2034,13 @@ exports.MissingClass2 = MissingClass2; function __spread$2(...args) { /* ... */ } function __spreadArrays$3(...args) { /* ... */ } function __spreadArray$3(to, from) { /* ... */ } + function __read$3(o) { /* ... */ } 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']); + var e = __read$3(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2052,6 +2057,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead); }); it('should recognize TypeScript helpers (as variable declarations)', () => { @@ -2062,11 +2068,13 @@ exports.MissingClass2 = MissingClass2; var __spread = (this && this.__spread) || function (...args) { /* ... */ } var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ } var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ } + var __read = (this && this.__read) || function (o) { /* ... */ } 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']); + var e = __read(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2083,6 +2091,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed TypeScript helpers (as variable declarations)', () => { @@ -2093,11 +2102,13 @@ exports.MissingClass2 = MissingClass2; 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 __read$3 = (this && this.__read$3) || function (o) { /* ... */ } 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']); + var e = __read$3(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2114,6 +2125,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead); }); it('should recognize imported TypeScript helpers', () => { @@ -2127,6 +2139,7 @@ exports.MissingClass2 = MissingClass2; 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']); + var e = tslib_1.__read(['foo', 'bar']); `, }, { @@ -2136,6 +2149,7 @@ exports.MissingClass2 = MissingClass2; 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 __read(o: any, n?: number): any[]; `, }, ]; @@ -2155,6 +2169,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib'); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib'); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib'); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead, 'tslib'); }); it('should recognize undeclared, unimported TypeScript helpers (by name)', () => { @@ -2165,6 +2180,7 @@ exports.MissingClass2 = MissingClass2; var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); + var e = __read(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2191,6 +2207,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed, undeclared, unimported TypeScript helpers (by name)', () => { @@ -2201,6 +2218,7 @@ exports.MissingClass2 = MissingClass2; var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); + var e = __read$3(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2227,6 +2245,7 @@ exports.MissingClass2 = MissingClass2; testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead); }); it('should recognize enum declarations with string values', () => { @@ -2461,6 +2480,7 @@ exports.MissingClass2 = MissingClass2; 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 __read(o: any, n?: number): any[]; export declare function __unknownHelper(...args: any[]): any; `, }; @@ -2477,6 +2497,7 @@ exports.MissingClass2 = MissingClass2; ['__spread', KnownDeclaration.TsHelperSpread], ['__spreadArrays', KnownDeclaration.TsHelperSpreadArrays], ['__spreadArray', KnownDeclaration.TsHelperSpreadArray], + ['__read', KnownDeclaration.TsHelperRead], ['__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 4e112a86f8..4595d7db56 100644 --- a/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts @@ -2060,11 +2060,13 @@ runInEachFileSystem(() => { function __spread(...args) { /* ... */ } function __spreadArrays(...args) { /* ... */ } function __spreadArray(to, from) { /* ... */ } + function __read(o) { /* ... */ } 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']); + var e = __read(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2080,6 +2082,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed TypeScript helpers (as function declarations)', () => { @@ -2090,11 +2093,13 @@ runInEachFileSystem(() => { function __spread$2(...args) { /* ... */ } function __spreadArrays$3(...args) { /* ... */ } function __spreadArray$3(to, from) { /* ... */ } + function __read$3(o) { /* ... */ } 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']); + var e = __read$3(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2110,6 +2115,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead); }); it('should recognize TypeScript helpers (as variable declarations)', () => { @@ -2120,11 +2126,13 @@ runInEachFileSystem(() => { var __spread = (this && this.__spread) || function (...args) { /* ... */ } var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ } var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ } + var __read = (this && this._read) || function (o) { /* ... */ } 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']); + var e = __read(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2140,6 +2148,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed TypeScript helpers (as variable declarations)', () => { @@ -2150,11 +2159,13 @@ runInEachFileSystem(() => { 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 __read$3 = (this && this.__read$3) || function (o) { /* ... */ } 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']); + var e = __read$3(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2170,6 +2181,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead); }); it('should recognize imported TypeScript helpers (named imports)', () => { @@ -2177,12 +2189,13 @@ runInEachFileSystem(() => { { name: _('/test.js'), contents: ` - import {__assign, __spread, __spreadArrays, __spreadArray} from 'tslib'; + import {__assign, __spread, __spreadArrays, __spreadArray, __read} 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']); + var e = __read(['foo', 'bar']); `, }, { @@ -2192,6 +2205,7 @@ runInEachFileSystem(() => { 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 __read(o: any, n?: number): any[]; `, }, ]; @@ -2210,6 +2224,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib'); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib'); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib'); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead, 'tslib'); }); it('should recognize imported TypeScript helpers (star import)', () => { @@ -2223,6 +2238,7 @@ runInEachFileSystem(() => { 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']); + var e = tslib_1.__read(['foo', 'bar']); `, }, { @@ -2232,6 +2248,7 @@ runInEachFileSystem(() => { 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 __read(o: any, n?: number): any[]; `, }, ]; @@ -2250,6 +2267,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib'); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib'); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib'); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead, 'tslib'); }); it('should recognize undeclared, unimported TypeScript helpers (by name)', () => { @@ -2260,6 +2278,7 @@ runInEachFileSystem(() => { var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); + var e = __read(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2283,6 +2302,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed, undeclared, unimported TypeScript helpers (by name)', () => { @@ -2293,6 +2313,7 @@ runInEachFileSystem(() => { var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); + var e = __read$3(['foo', 'bar']); `, }; loadTestFiles([file]); @@ -2316,6 +2337,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize enum declarations with string values', () => { @@ -2479,6 +2501,7 @@ runInEachFileSystem(() => { 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 __read(o: any, n?: number): any[]; export declare function __unknownHelper(...args: any[]): any; `, }; @@ -2494,6 +2517,7 @@ runInEachFileSystem(() => { ['__spread', KnownDeclaration.TsHelperSpread], ['__spreadArrays', KnownDeclaration.TsHelperSpreadArrays], ['__spreadArray', KnownDeclaration.TsHelperSpreadArray], + ['__read', KnownDeclaration.TsHelperRead], ['__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 5f42d2a7bc..359219cbdf 100644 --- a/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts @@ -2332,11 +2332,13 @@ runInEachFileSystem(() => { function __spread(...args) { /* ... */ } function __spreadArrays(...args) { /* ... */ } function __spreadArray(to, from) { /* ... */ } + function __read(o) { /* ... */ } 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']); + var e = __read(['foo', 'bar']); }))); `, }; @@ -2352,6 +2354,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed TypeScript helpers (as function declarations)', () => { @@ -2367,11 +2370,13 @@ runInEachFileSystem(() => { function __spread$2(...args) { /* ... */ } function __spreadArrays$3(...args) { /* ... */ } function __spreadArray$3(to, from) { /* ... */ } + function __read$3(o) { /* ... */ } 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']); + var e = __read$3(['foo', 'bar']); }))); `, }; @@ -2387,6 +2392,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead); }); it('should recognize TypeScript helpers (as variable declarations)', () => { @@ -2402,11 +2408,13 @@ runInEachFileSystem(() => { var __spread = (this && this.__spread) || function (...args) { /* ... */ } var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ } var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ } + var __read = (this && this.__read) || function (o) { /* ... */ } 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']); + var e = __read(['foo', 'bar']); }))); `, }; @@ -2422,6 +2430,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed TypeScript helpers (as variable declarations)', () => { @@ -2437,11 +2446,13 @@ runInEachFileSystem(() => { 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 __read$3 = (this && this.__read$3) || function (o) { /* ... */ } 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']); + var e = __read$3(['foo', 'bar']); }))); `, }; @@ -2457,6 +2468,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead); }); it('should recognize imported TypeScript helpers', () => { @@ -2473,6 +2485,7 @@ runInEachFileSystem(() => { 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']); + var e = tslib_1.__read(['foo', 'bar']); }))); `, }, @@ -2483,6 +2496,7 @@ runInEachFileSystem(() => { 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 __read(o: any, n?: number): any[]; `, }, ]; @@ -2502,6 +2516,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib'); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib'); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib'); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead, 'tslib'); }); it('should recognize undeclared, unimported TypeScript helpers (by name)', () => { @@ -2517,6 +2532,7 @@ runInEachFileSystem(() => { var b = __spread(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']); var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']); + var e = __read(['foo', 'bar']); }))); `, }; @@ -2544,6 +2560,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read', KnownDeclaration.TsHelperRead); }); it('should recognize suffixed, undeclared, unimported TypeScript helpers (by name)', () => { @@ -2559,6 +2576,7 @@ runInEachFileSystem(() => { var b = __spread$2(['foo', 'bar'], ['baz', 'qux']); var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']); var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']); + var e = __read$3(['foo', 'bar']); }))); `, }; @@ -2586,6 +2604,7 @@ runInEachFileSystem(() => { testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread); testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays); testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray); + testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead); }); it('should recognize enum declarations with string values', () => { @@ -2861,6 +2880,7 @@ runInEachFileSystem(() => { 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 __read(o: any, n?: number): any[]; export declare function __unknownHelper(...args: any[]): any; `, }; @@ -2876,6 +2896,7 @@ runInEachFileSystem(() => { ['__spread', KnownDeclaration.TsHelperSpread], ['__spreadArrays', KnownDeclaration.TsHelperSpreadArrays], ['__spreadArray', KnownDeclaration.TsHelperSpreadArray], + ['__read', KnownDeclaration.TsHelperRead], ['__unknownHelper', null], ]); }); 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 3712eae54b..f17e38648b 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, SpreadArrayHelperFn, SpreadHelperFn} from './ts_helpers'; +import {AssignHelperFn, ReadHelperFn, SpreadArrayHelperFn, SpreadHelperFn} from './ts_helpers'; /** Resolved value for the JavaScript global `Object` declaration. */ export const jsGlobalObjectValue = new Map([['assign', new ObjectAssignBuiltinFn()]]); @@ -24,6 +24,9 @@ const spreadTsHelperFn = new SpreadHelperFn(); /** Resolved value for the `__spreadArray()` TypeScript helper declarations. */ const spreadArrayTsHelperFn = new SpreadArrayHelperFn(); +/** Resolved value for the `__read()` TypeScript helper declarations. */ +const readTsHelperFn = new ReadHelperFn(); + /** * Resolves the specified known declaration to a resolved value. For example, * the known JavaScript global `Object` will resolve to a `Map` that provides the @@ -40,6 +43,8 @@ export function resolveKnownDeclaration(decl: KnownDeclaration): ResolvedValue { return spreadTsHelperFn; case KnownDeclaration.TsHelperSpreadArray: return spreadArrayTsHelperFn; + case KnownDeclaration.TsHelperRead: + return readTsHelperFn; 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 27080f0915..109ef11292 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 @@ -59,3 +59,24 @@ export class SpreadArrayHelperFn extends KnownFn { return to.concat(from); } } + +// Used for `__read` TypeScript helper function. +export class ReadHelperFn extends KnownFn { + evaluate(node: ts.Node, args: ResolvedValueArray): ResolvedValue { + if (args.length !== 1) { + // The `__read` helper accepts a second argument `n` but that case is not supported. + return DynamicValue.fromUnknown(node); + } + + const [value] = args; + if (value instanceof DynamicValue) { + return DynamicValue.fromDynamicInput(node, value); + } + + if (!Array.isArray(value)) { + return DynamicValue.fromInvalidExpressionType(node, value); + } + + return value; + } +} 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 e4ead4720e..e597f6d0f3 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 @@ -647,6 +647,7 @@ runInEachFileSystem(() => { 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 __read(o: any, n?: number): any[]; `, }, ]); @@ -758,6 +759,28 @@ runInEachFileSystem(() => { expect(arr).toEqual([4, 5, 6]); }); + + it('should evaluate `__read()` (named import)', () => { + const arr: number[] = evaluateExpression( + ` + import {__read} from 'tslib'; + const a = [5, 6]; + `, + '__read(a)'); + + expect(arr).toEqual([5, 6]); + }); + + it('should evaluate `__read()` (star import)', () => { + const arr: number[] = evaluateExpression( + ` + import * as tslib from 'tslib'; + const a = [5, 6]; + `, + 'tslib.__read(a)'); + + expect(arr).toEqual([5, 6]); + }); }); describe('(with emitted TypeScript helpers as functions)', () => { @@ -768,6 +791,7 @@ runInEachFileSystem(() => { function __spread(...args) { /* ... */ } function __spreadArrays(...args) { /* ... */ } function __spreadArray(to, from) { /* ... */ } + function __read(o) { /* ... */ } `; const {checker, expression} = makeExpression(helpers + code, expr); @@ -823,6 +847,16 @@ runInEachFileSystem(() => { expect(arr).toEqual([4, 5, 6]); }); + + it('should evaluate `__read()`', () => { + const arr: number[] = evaluateExpression( + ` + const a = [5, 6]; + `, + '__read(a)'); + + expect(arr).toEqual([5, 6]); + }); }); describe('(with emitted TypeScript helpers as variables)', () => { @@ -833,6 +867,7 @@ runInEachFileSystem(() => { var __spread = (this && this.__spread) || function (...args) { /* ... */ } var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ } var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ } + var __read = (this && this.__read) || function (o) { /* ... */ } `; const {checker, expression} = makeExpression(helpers + code, expr); @@ -888,6 +923,16 @@ runInEachFileSystem(() => { expect(arr).toEqual([4, 5, 6]); }); + + it('should evaluate `__read()`', () => { + const arr: number[] = evaluateExpression( + ` + const a = [5, 6]; + `, + '__read(a)'); + + expect(arr).toEqual([5, 6]); + }); }); describe('(visited file tracking)', () => { @@ -1031,6 +1076,8 @@ runInEachFileSystem(() => { return KnownDeclaration.TsHelperSpreadArrays; case '__spreadArray': return KnownDeclaration.TsHelperSpreadArray; + case '__read': + return KnownDeclaration.TsHelperRead; 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 c3dbcf07ca..7b6adeadbb 100644 --- a/packages/compiler-cli/src/ngtsc/reflection/src/host.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/src/host.ts @@ -479,6 +479,11 @@ export enum KnownDeclaration { * Indicates the `__spreadArray` TypeScript helper function. */ TsHelperSpreadArray, + + /** + * Indicates the `__read` TypeScript helper function. + */ + TsHelperRead, } /**