Skip to content

Commit 66e9970

Browse files
JoostKthePunderWoman
authored andcommitted
feat(ngcc): support __read helper as used by TypeScript 4.2 (angular#41201)
This commit complements the support for the `__spreadArray` helper that was added in microsoft/TypeScript#41523. The prior helpers `__spread` and `__spreadArrays` used the `__read` helper internally, but the helper is now emitted as an argument to `__spreadArray` so ngcc now needs to support evaluating it statically. The real implementation of `__read` reads an iterable into an array, but for ngcc's static evaluation support it is sufficient to only deal with arrays as is. Additionally, the optional `n` parameter is not supported as that is only emitted for array destructuring syntax, which ngcc does not have to support. PR Close angular#41201
1 parent 7b1214e commit 66e9970

File tree

8 files changed

+148
-2
lines changed

8 files changed

+148
-2
lines changed

packages/compiler-cli/ngcc/src/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ export function getTsHelperFnFromIdentifier(id: ts.Identifier): KnownDeclaration
163163
return KnownDeclaration.TsHelperSpreadArrays;
164164
case '__spreadArray':
165165
return KnownDeclaration.TsHelperSpreadArray;
166+
case '__read':
167+
return KnownDeclaration.TsHelperRead;
166168
default:
167169
return null;
168170
}

packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,11 +2000,13 @@ exports.MissingClass2 = MissingClass2;
20002000
function __spread(...args) { /* ... */ }
20012001
function __spreadArrays(...args) { /* ... */ }
20022002
function __spreadArray(to, from) { /* ... */ }
2003+
function __read(o) { /* ... */ }
20032004
20042005
var a = __assign({foo: 'bar'}, {baz: 'qux'});
20052006
var b = __spread(['foo', 'bar'], ['baz', 'qux']);
20062007
var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']);
20072008
var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']);
2009+
var e = __read(['foo', 'bar']);
20082010
`,
20092011
};
20102012
loadTestFiles([file]);
@@ -2021,6 +2023,7 @@ exports.MissingClass2 = MissingClass2;
20212023
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread);
20222024
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays);
20232025
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray);
2026+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead);
20242027
});
20252028

20262029
it('should recognize suffixed TypeScript helpers (as function declarations)', () => {
@@ -2031,11 +2034,13 @@ exports.MissingClass2 = MissingClass2;
20312034
function __spread$2(...args) { /* ... */ }
20322035
function __spreadArrays$3(...args) { /* ... */ }
20332036
function __spreadArray$3(to, from) { /* ... */ }
2037+
function __read$3(o) { /* ... */ }
20342038
20352039
var a = __assign$1({foo: 'bar'}, {baz: 'qux'});
20362040
var b = __spread$2(['foo', 'bar'], ['baz', 'qux']);
20372041
var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']);
20382042
var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']);
2043+
var e = __read$3(['foo', 'bar']);
20392044
`,
20402045
};
20412046
loadTestFiles([file]);
@@ -2052,6 +2057,7 @@ exports.MissingClass2 = MissingClass2;
20522057
testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread);
20532058
testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays);
20542059
testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray);
2060+
testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead);
20552061
});
20562062

20572063
it('should recognize TypeScript helpers (as variable declarations)', () => {
@@ -2062,11 +2068,13 @@ exports.MissingClass2 = MissingClass2;
20622068
var __spread = (this && this.__spread) || function (...args) { /* ... */ }
20632069
var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ }
20642070
var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ }
2071+
var __read = (this && this.__read) || function (o) { /* ... */ }
20652072
20662073
var a = __assign({foo: 'bar'}, {baz: 'qux'});
20672074
var b = __spread(['foo', 'bar'], ['baz', 'qux']);
20682075
var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']);
20692076
var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']);
2077+
var e = __read(['foo', 'bar']);
20702078
`,
20712079
};
20722080
loadTestFiles([file]);
@@ -2083,6 +2091,7 @@ exports.MissingClass2 = MissingClass2;
20832091
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread);
20842092
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays);
20852093
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray);
2094+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead);
20862095
});
20872096

20882097
it('should recognize suffixed TypeScript helpers (as variable declarations)', () => {
@@ -2093,11 +2102,13 @@ exports.MissingClass2 = MissingClass2;
20932102
var __spread$2 = (this && this.__spread$2) || function (...args) { /* ... */ }
20942103
var __spreadArrays$3 = (this && this.__spreadArrays$3) || function (...args) { /* ... */ }
20952104
var __spreadArray$3 = (this && this.__spreadArray$3) || function (to, from) { /* ... */ }
2105+
var __read$3 = (this && this.__read$3) || function (o) { /* ... */ }
20962106
20972107
var a = __assign$1({foo: 'bar'}, {baz: 'qux'});
20982108
var b = __spread$2(['foo', 'bar'], ['baz', 'qux']);
20992109
var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']);
21002110
var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']);
2111+
var e = __read$3(['foo', 'bar']);
21012112
`,
21022113
};
21032114
loadTestFiles([file]);
@@ -2114,6 +2125,7 @@ exports.MissingClass2 = MissingClass2;
21142125
testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread);
21152126
testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays);
21162127
testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray);
2128+
testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead);
21172129
});
21182130

21192131
it('should recognize imported TypeScript helpers', () => {
@@ -2127,6 +2139,7 @@ exports.MissingClass2 = MissingClass2;
21272139
var b = tslib_1.__spread(['foo', 'bar'], ['baz', 'qux']);
21282140
var c = tslib_1.__spreadArrays(['foo', 'bar'], ['baz', 'qux']);
21292141
var d = tslib_1.__spreadArray(['foo', 'bar'], ['baz', 'qux']);
2142+
var e = tslib_1.__read(['foo', 'bar']);
21302143
`,
21312144
},
21322145
{
@@ -2136,6 +2149,7 @@ exports.MissingClass2 = MissingClass2;
21362149
export declare function __spread(...args: any[][]): any[];
21372150
export declare function __spreadArrays(...args: any[][]): any[];
21382151
export declare function __spreadArray(to: any[], from: any[]): any[];
2152+
export declare function __read(o: any, n?: number): any[];
21392153
`,
21402154
},
21412155
];
@@ -2155,6 +2169,7 @@ exports.MissingClass2 = MissingClass2;
21552169
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib');
21562170
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib');
21572171
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib');
2172+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead, 'tslib');
21582173
});
21592174

21602175
it('should recognize undeclared, unimported TypeScript helpers (by name)', () => {
@@ -2165,6 +2180,7 @@ exports.MissingClass2 = MissingClass2;
21652180
var b = __spread(['foo', 'bar'], ['baz', 'qux']);
21662181
var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']);
21672182
var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']);
2183+
var e = __read(['foo', 'bar']);
21682184
`,
21692185
};
21702186
loadTestFiles([file]);
@@ -2191,6 +2207,7 @@ exports.MissingClass2 = MissingClass2;
21912207
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread);
21922208
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays);
21932209
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray);
2210+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead);
21942211
});
21952212

21962213
it('should recognize suffixed, undeclared, unimported TypeScript helpers (by name)', () => {
@@ -2201,6 +2218,7 @@ exports.MissingClass2 = MissingClass2;
22012218
var b = __spread$2(['foo', 'bar'], ['baz', 'qux']);
22022219
var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']);
22032220
var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']);
2221+
var e = __read$3(['foo', 'bar']);
22042222
`,
22052223
};
22062224
loadTestFiles([file]);
@@ -2227,6 +2245,7 @@ exports.MissingClass2 = MissingClass2;
22272245
testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread);
22282246
testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays);
22292247
testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray);
2248+
testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead);
22302249
});
22312250

22322251
it('should recognize enum declarations with string values', () => {
@@ -2461,6 +2480,7 @@ exports.MissingClass2 = MissingClass2;
24612480
export declare function __spread(...args: any[][]): any[];
24622481
export declare function __spreadArrays(...args: any[][]): any[];
24632482
export declare function __spreadArray(to: any[], from: any[]): any[];
2483+
export declare function __read(o: any, n?: number): any[];
24642484
export declare function __unknownHelper(...args: any[]): any;
24652485
`,
24662486
};
@@ -2477,6 +2497,7 @@ exports.MissingClass2 = MissingClass2;
24772497
['__spread', KnownDeclaration.TsHelperSpread],
24782498
['__spreadArrays', KnownDeclaration.TsHelperSpreadArrays],
24792499
['__spreadArray', KnownDeclaration.TsHelperSpreadArray],
2500+
['__read', KnownDeclaration.TsHelperRead],
24802501
['__unknownHelper', null],
24812502
]);
24822503
});

packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2060,11 +2060,13 @@ runInEachFileSystem(() => {
20602060
function __spread(...args) { /* ... */ }
20612061
function __spreadArrays(...args) { /* ... */ }
20622062
function __spreadArray(to, from) { /* ... */ }
2063+
function __read(o) { /* ... */ }
20632064
20642065
var a = __assign({foo: 'bar'}, {baz: 'qux'});
20652066
var b = __spread(['foo', 'bar'], ['baz', 'qux']);
20662067
var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']);
20672068
var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']);
2069+
var e = __read(['foo', 'bar']);
20682070
`,
20692071
};
20702072
loadTestFiles([file]);
@@ -2080,6 +2082,7 @@ runInEachFileSystem(() => {
20802082
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread);
20812083
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays);
20822084
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray);
2085+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead);
20832086
});
20842087

20852088
it('should recognize suffixed TypeScript helpers (as function declarations)', () => {
@@ -2090,11 +2093,13 @@ runInEachFileSystem(() => {
20902093
function __spread$2(...args) { /* ... */ }
20912094
function __spreadArrays$3(...args) { /* ... */ }
20922095
function __spreadArray$3(to, from) { /* ... */ }
2096+
function __read$3(o) { /* ... */ }
20932097
20942098
var a = __assign$1({foo: 'bar'}, {baz: 'qux'});
20952099
var b = __spread$2(['foo', 'bar'], ['baz', 'qux']);
20962100
var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']);
20972101
var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']);
2102+
var e = __read$3(['foo', 'bar']);
20982103
`,
20992104
};
21002105
loadTestFiles([file]);
@@ -2110,6 +2115,7 @@ runInEachFileSystem(() => {
21102115
testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread);
21112116
testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays);
21122117
testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray);
2118+
testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead);
21132119
});
21142120

21152121
it('should recognize TypeScript helpers (as variable declarations)', () => {
@@ -2120,11 +2126,13 @@ runInEachFileSystem(() => {
21202126
var __spread = (this && this.__spread) || function (...args) { /* ... */ }
21212127
var __spreadArrays = (this && this.__spreadArrays) || function (...args) { /* ... */ }
21222128
var __spreadArray = (this && this.__spreadArray) || function (to, from) { /* ... */ }
2129+
var __read = (this && this._read) || function (o) { /* ... */ }
21232130
21242131
var a = __assign({foo: 'bar'}, {baz: 'qux'});
21252132
var b = __spread(['foo', 'bar'], ['baz', 'qux']);
21262133
var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']);
21272134
var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']);
2135+
var e = __read(['foo', 'bar']);
21282136
`,
21292137
};
21302138
loadTestFiles([file]);
@@ -2140,6 +2148,7 @@ runInEachFileSystem(() => {
21402148
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread);
21412149
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays);
21422150
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray);
2151+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead);
21432152
});
21442153

21452154
it('should recognize suffixed TypeScript helpers (as variable declarations)', () => {
@@ -2150,11 +2159,13 @@ runInEachFileSystem(() => {
21502159
var __spread$2 = (this && this.__spread$2) || function (...args) { /* ... */ }
21512160
var __spreadArrays$3 = (this && this.__spreadArrays$3) || function (...args) { /* ... */ }
21522161
var __spreadArray$3 = (this && this.__spreadArray$3) || function (to, from) { /* ... */ }
2162+
var __read$3 = (this && this.__read$3) || function (o) { /* ... */ }
21532163
21542164
var a = __assign$1({foo: 'bar'}, {baz: 'qux'});
21552165
var b = __spread$2(['foo', 'bar'], ['baz', 'qux']);
21562166
var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']);
21572167
var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']);
2168+
var e = __read$3(['foo', 'bar']);
21582169
`,
21592170
};
21602171
loadTestFiles([file]);
@@ -2170,19 +2181,21 @@ runInEachFileSystem(() => {
21702181
testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread);
21712182
testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays);
21722183
testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray);
2184+
testForHelper('e', '__read$3', KnownDeclaration.TsHelperRead);
21732185
});
21742186

21752187
it('should recognize imported TypeScript helpers (named imports)', () => {
21762188
const files: TestFile[] = [
21772189
{
21782190
name: _('/test.js'),
21792191
contents: `
2180-
import {__assign, __spread, __spreadArrays, __spreadArray} from 'tslib';
2192+
import {__assign, __spread, __spreadArrays, __spreadArray, __read} from 'tslib';
21812193
21822194
var a = __assign({foo: 'bar'}, {baz: 'qux'});
21832195
var b = __spread(['foo', 'bar'], ['baz', 'qux']);
21842196
var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']);
21852197
var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']);
2198+
var e = __read(['foo', 'bar']);
21862199
`,
21872200
},
21882201
{
@@ -2192,6 +2205,7 @@ runInEachFileSystem(() => {
21922205
export declare function __spread(...args: any[][]): any[];
21932206
export declare function __spreadArrays(...args: any[][]): any[];
21942207
export declare function __spreadArray(to: any[], from: any[]): any[];
2208+
export declare function __read(o: any, n?: number): any[];
21952209
`,
21962210
},
21972211
];
@@ -2210,6 +2224,7 @@ runInEachFileSystem(() => {
22102224
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib');
22112225
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib');
22122226
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib');
2227+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead, 'tslib');
22132228
});
22142229

22152230
it('should recognize imported TypeScript helpers (star import)', () => {
@@ -2223,6 +2238,7 @@ runInEachFileSystem(() => {
22232238
var b = tslib_1.__spread(['foo', 'bar'], ['baz', 'qux']);
22242239
var c = tslib_1.__spreadArrays(['foo', 'bar'], ['baz', 'qux']);
22252240
var d = tslib_1.__spreadArray(['foo', 'bar'], ['baz', 'qux']);
2241+
var e = tslib_1.__read(['foo', 'bar']);
22262242
`,
22272243
},
22282244
{
@@ -2232,6 +2248,7 @@ runInEachFileSystem(() => {
22322248
export declare function __spread(...args: any[][]): any[];
22332249
export declare function __spreadArrays(...args: any[][]): any[];
22342250
export declare function __spreadArray(to: any[], from: any[]): any[];
2251+
export declare function __read(o: any, n?: number): any[];
22352252
`,
22362253
},
22372254
];
@@ -2250,6 +2267,7 @@ runInEachFileSystem(() => {
22502267
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread, 'tslib');
22512268
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays, 'tslib');
22522269
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray, 'tslib');
2270+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead, 'tslib');
22532271
});
22542272

22552273
it('should recognize undeclared, unimported TypeScript helpers (by name)', () => {
@@ -2260,6 +2278,7 @@ runInEachFileSystem(() => {
22602278
var b = __spread(['foo', 'bar'], ['baz', 'qux']);
22612279
var c = __spreadArrays(['foo', 'bar'], ['baz', 'qux']);
22622280
var d = __spreadArray(['foo', 'bar'], ['baz', 'qux']);
2281+
var e = __read(['foo', 'bar']);
22632282
`,
22642283
};
22652284
loadTestFiles([file]);
@@ -2283,6 +2302,7 @@ runInEachFileSystem(() => {
22832302
testForHelper('b', '__spread', KnownDeclaration.TsHelperSpread);
22842303
testForHelper('c', '__spreadArrays', KnownDeclaration.TsHelperSpreadArrays);
22852304
testForHelper('d', '__spreadArray', KnownDeclaration.TsHelperSpreadArray);
2305+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead);
22862306
});
22872307

22882308
it('should recognize suffixed, undeclared, unimported TypeScript helpers (by name)', () => {
@@ -2293,6 +2313,7 @@ runInEachFileSystem(() => {
22932313
var b = __spread$2(['foo', 'bar'], ['baz', 'qux']);
22942314
var c = __spreadArrays$3(['foo', 'bar'], ['baz', 'qux']);
22952315
var d = __spreadArray$3(['foo', 'bar'], ['baz', 'qux']);
2316+
var e = __read$3(['foo', 'bar']);
22962317
`,
22972318
};
22982319
loadTestFiles([file]);
@@ -2316,6 +2337,7 @@ runInEachFileSystem(() => {
23162337
testForHelper('b', '__spread$2', KnownDeclaration.TsHelperSpread);
23172338
testForHelper('c', '__spreadArrays$3', KnownDeclaration.TsHelperSpreadArrays);
23182339
testForHelper('d', '__spreadArray$3', KnownDeclaration.TsHelperSpreadArray);
2340+
testForHelper('e', '__read', KnownDeclaration.TsHelperRead);
23192341
});
23202342

23212343
it('should recognize enum declarations with string values', () => {
@@ -2479,6 +2501,7 @@ runInEachFileSystem(() => {
24792501
export declare function __spread(...args: any[][]): any[];
24802502
export declare function __spreadArrays(...args: any[][]): any[];
24812503
export declare function __spreadArray(to: any[], from: any[]): any[];
2504+
export declare function __read(o: any, n?: number): any[];
24822505
export declare function __unknownHelper(...args: any[]): any;
24832506
`,
24842507
};
@@ -2494,6 +2517,7 @@ runInEachFileSystem(() => {
24942517
['__spread', KnownDeclaration.TsHelperSpread],
24952518
['__spreadArrays', KnownDeclaration.TsHelperSpreadArrays],
24962519
['__spreadArray', KnownDeclaration.TsHelperSpreadArray],
2520+
['__read', KnownDeclaration.TsHelperRead],
24972521
['__unknownHelper', null],
24982522
]);
24992523
});

0 commit comments

Comments
 (0)