Skip to content

Commit 13c72b7

Browse files
committed
Merge remote-tracking branch 'upstream/master' into es2019
2 parents b3c1795 + f944ed6 commit 13c72b7

99 files changed

Lines changed: 1046 additions & 156 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Jakefile.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ else if (process.env.PATH !== undefined) {
2323
const host = process.env.TYPESCRIPT_HOST || process.env.host || "node";
2424

2525
const defaultTestTimeout = 40000;
26+
const useBuilt =
27+
process.env.USE_BUILT === "true" ? true :
28+
process.env.LKG === "true" ? false :
29+
false;
2630

2731
let useDebugMode = true;
2832

@@ -296,7 +300,7 @@ task(TaskNames.buildFoldEnd, [], function () {
296300

297301
desc("Compiles tslint rules to js");
298302
task(TaskNames.buildRules, [], function () {
299-
tsbuild(ConfigFileFor.lint, false, () => complete());
303+
tsbuild(ConfigFileFor.lint, !useBuilt, () => complete());
300304
}, { async: true });
301305

302306
desc("Cleans the compiler output, declare files, and tests");
@@ -368,7 +372,7 @@ file(ConfigFileFor.tsserverLibrary, [], function () {
368372
// tsserverlibrary.js
369373
// tsserverlibrary.d.ts
370374
file(Paths.tsserverLibraryFile, [TaskNames.coreBuild, ConfigFileFor.tsserverLibrary], function() {
371-
tsbuild(ConfigFileFor.tsserverLibrary, false, () => {
375+
tsbuild(ConfigFileFor.tsserverLibrary, !useBuilt, () => {
372376
if (needsUpdate([Paths.tsserverLibraryOutFile, Paths.tsserverLibraryDefinitionOutFile], [Paths.tsserverLibraryFile, Paths.tsserverLibraryDefinitionFile])) {
373377
const copyright = readFileSync(Paths.copyright);
374378

@@ -427,7 +431,7 @@ file(ConfigFileFor.typescriptServices, [], function () {
427431
// typescriptServices.js
428432
// typescriptServices.d.ts
429433
file(Paths.servicesFile, [TaskNames.coreBuild, ConfigFileFor.typescriptServices], function() {
430-
tsbuild(ConfigFileFor.typescriptServices, false, () => {
434+
tsbuild(ConfigFileFor.typescriptServices, !useBuilt, () => {
431435
if (needsUpdate([Paths.servicesOutFile, Paths.servicesDefinitionOutFile], [Paths.servicesFile, Paths.servicesDefinitionFile])) {
432436
const copyright = readFileSync(Paths.copyright);
433437

src/compiler/commandLineParser.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ namespace ts {
3939
["es2017.string", "lib.es2017.string.d.ts"],
4040
["es2017.intl", "lib.es2017.intl.d.ts"],
4141
["es2017.typedarrays", "lib.es2017.typedarrays.d.ts"],
42+
["es2018.asynciterable", "lib.es2018.asynciterable.d.ts"],
4243
["es2018.intl", "lib.es2018.intl.d.ts"],
4344
["es2018.promise", "lib.es2018.promise.d.ts"],
4445
["es2018.regexp", "lib.es2018.regexp.d.ts"],
@@ -47,7 +48,7 @@ namespace ts {
4748
["es2019.symbol", "lib.es2019.symbol.d.ts"],
4849
["esnext.array", "lib.es2019.array.d.ts"],
4950
["esnext.symbol", "lib.es2019.symbol.d.ts"],
50-
["esnext.asynciterable", "lib.esnext.asynciterable.d.ts"],
51+
["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
5152
["esnext.intl", "lib.esnext.intl.d.ts"],
5253
["esnext.bigint", "lib.esnext.bigint.d.ts"]
5354
];

src/compiler/core.ts

Lines changed: 134 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -118,42 +118,105 @@ namespace ts {
118118
export const MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap();
119119

120120
// Keep the class inside a function so it doesn't get compiled if it's not used.
121-
function shimMap(): new <T>() => Map<T> {
121+
export function shimMap(): new <T>() => Map<T> {
122+
123+
interface MapEntry<T> {
124+
readonly key?: string;
125+
value?: T;
126+
127+
// Linked list references for iterators.
128+
nextEntry?: MapEntry<T>;
129+
previousEntry?: MapEntry<T>;
130+
131+
/**
132+
* Specifies if iterators should skip the next entry.
133+
* This will be set when an entry is deleted.
134+
* See https://github.com/Microsoft/TypeScript/pull/27292 for more information.
135+
*/
136+
skipNext?: boolean;
137+
}
122138

123139
class MapIterator<T, U extends (string | T | [string, T])> {
124-
private data: MapLike<T>;
125-
private keys: ReadonlyArray<string>;
126-
private index = 0;
127-
private selector: (data: MapLike<T>, key: string) => U;
128-
constructor(data: MapLike<T>, selector: (data: MapLike<T>, key: string) => U) {
129-
this.data = data;
140+
private currentEntry?: MapEntry<T>;
141+
private selector: (key: string, value: T) => U;
142+
143+
constructor(currentEntry: MapEntry<T>, selector: (key: string, value: T) => U) {
144+
this.currentEntry = currentEntry;
130145
this.selector = selector;
131-
this.keys = Object.keys(data);
132146
}
133147

134148
public next(): { value: U, done: false } | { value: never, done: true } {
135-
const index = this.index;
136-
if (index < this.keys.length) {
137-
this.index++;
138-
return { value: this.selector(this.data, this.keys[index]), done: false };
149+
// Navigate to the next entry.
150+
while (this.currentEntry) {
151+
const skipNext = !!this.currentEntry.skipNext;
152+
this.currentEntry = this.currentEntry.nextEntry;
153+
154+
if (!skipNext) {
155+
break;
156+
}
157+
}
158+
159+
if (this.currentEntry) {
160+
return { value: this.selector(this.currentEntry.key!, this.currentEntry.value!), done: false };
161+
}
162+
else {
163+
return { value: undefined as never, done: true };
139164
}
140-
return { value: undefined as never, done: true };
141165
}
142166
}
143167

144168
return class <T> implements Map<T> {
145-
private data = createDictionaryObject<T>();
169+
private data = createDictionaryObject<MapEntry<T>>();
146170
public size = 0;
147171

172+
// Linked list references for iterators.
173+
// See https://github.com/Microsoft/TypeScript/pull/27292
174+
// for more information.
175+
176+
/**
177+
* The first entry in the linked list.
178+
* Note that this is only a stub that serves as starting point
179+
* for iterators and doesn't contain a key and a value.
180+
*/
181+
private readonly firstEntry: MapEntry<T>;
182+
private lastEntry: MapEntry<T>;
183+
184+
constructor() {
185+
// Create a first (stub) map entry that will not contain a key
186+
// and value but serves as starting point for iterators.
187+
this.firstEntry = {};
188+
// When the map is empty, the last entry is the same as the
189+
// first one.
190+
this.lastEntry = this.firstEntry;
191+
}
192+
148193
get(key: string): T | undefined {
149-
return this.data[key];
194+
const entry = this.data[key] as MapEntry<T> | undefined;
195+
return entry && entry.value!;
150196
}
151197

152198
set(key: string, value: T): this {
153199
if (!this.has(key)) {
154200
this.size++;
201+
202+
// Create a new entry that will be appended at the
203+
// end of the linked list.
204+
const newEntry: MapEntry<T> = {
205+
key,
206+
value
207+
};
208+
this.data[key] = newEntry;
209+
210+
// Adjust the references.
211+
const previousLastEntry = this.lastEntry;
212+
previousLastEntry.nextEntry = newEntry;
213+
newEntry.previousEntry = previousLastEntry;
214+
this.lastEntry = newEntry;
155215
}
156-
this.data[key] = value;
216+
else {
217+
this.data[key].value = value;
218+
}
219+
157220
return this;
158221
}
159222

@@ -165,32 +228,81 @@ namespace ts {
165228
delete(key: string): boolean {
166229
if (this.has(key)) {
167230
this.size--;
231+
const entry = this.data[key];
168232
delete this.data[key];
233+
234+
// Adjust the linked list references of the neighbor entries.
235+
const previousEntry = entry.previousEntry!;
236+
previousEntry.nextEntry = entry.nextEntry;
237+
if (entry.nextEntry) {
238+
entry.nextEntry.previousEntry = previousEntry;
239+
}
240+
241+
// When the deleted entry was the last one, we need to
242+
// adust the lastEntry reference.
243+
if (this.lastEntry === entry) {
244+
this.lastEntry = previousEntry;
245+
}
246+
247+
// Adjust the forward reference of the deleted entry
248+
// in case an iterator still references it. This allows us
249+
// to throw away the entry, but when an active iterator
250+
// (which points to the current entry) continues, it will
251+
// navigate to the entry that originally came before the
252+
// current one and skip it.
253+
entry.previousEntry = undefined;
254+
entry.nextEntry = previousEntry;
255+
entry.skipNext = true;
256+
169257
return true;
170258
}
171259
return false;
172260
}
173261

174262
clear(): void {
175-
this.data = createDictionaryObject<T>();
263+
this.data = createDictionaryObject<MapEntry<T>>();
176264
this.size = 0;
265+
266+
// Reset the linked list. Note that we must adjust the forward
267+
// references of the deleted entries to ensure iterators stuck
268+
// in the middle of the list don't continue with deleted entries,
269+
// but can continue with new entries added after the clear()
270+
// operation.
271+
const firstEntry = this.firstEntry;
272+
let currentEntry = firstEntry.nextEntry;
273+
while (currentEntry) {
274+
const nextEntry = currentEntry.nextEntry;
275+
currentEntry.previousEntry = undefined;
276+
currentEntry.nextEntry = firstEntry;
277+
currentEntry.skipNext = true;
278+
279+
currentEntry = nextEntry;
280+
}
281+
firstEntry.nextEntry = undefined;
282+
this.lastEntry = firstEntry;
177283
}
178284

179285
keys(): Iterator<string> {
180-
return new MapIterator(this.data, (_data, key) => key);
286+
return new MapIterator(this.firstEntry, key => key);
181287
}
182288

183289
values(): Iterator<T> {
184-
return new MapIterator(this.data, (data, key) => data[key]);
290+
return new MapIterator(this.firstEntry, (_key, value) => value);
185291
}
186292

187293
entries(): Iterator<[string, T]> {
188-
return new MapIterator(this.data, (data, key) => [key, data[key]] as [string, T]);
294+
return new MapIterator(this.firstEntry, (key, value) => [key, value] as [string, T]);
189295
}
190296

191297
forEach(action: (value: T, key: string) => void): void {
192-
for (const key in this.data) {
193-
action(this.data[key], key);
298+
const iterator = this.entries();
299+
while (true) {
300+
const { value: entry, done } = iterator.next();
301+
if (done) {
302+
break;
303+
}
304+
305+
action(entry[1], entry[0]);
194306
}
195307
}
196308
};

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ namespace ts {
609609
export interface Node extends TextRange {
610610
kind: SyntaxKind;
611611
flags: NodeFlags;
612-
/* @internal */ modifierFlagsCache?: ModifierFlags;
612+
/* @internal */ modifierFlagsCache: ModifierFlags;
613613
/* @internal */ transformFlags: TransformFlags; // Flags for transforms, possibly undefined
614614
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
615615
modifiers?: ModifiersArray; // Array of modifiers

src/compiler/utilities.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3792,8 +3792,8 @@ namespace ts {
37923792
}
37933793

37943794
export function getModifierFlags(node: Node): ModifierFlags {
3795-
if (node.modifierFlagsCache! & ModifierFlags.HasComputedFlags) {
3796-
return node.modifierFlagsCache! & ~ModifierFlags.HasComputedFlags;
3795+
if (node.modifierFlagsCache & ModifierFlags.HasComputedFlags) {
3796+
return node.modifierFlagsCache & ~ModifierFlags.HasComputedFlags;
37973797
}
37983798

37993799
const flags = getModifierFlagsNoCache(node);

src/lib/es2018.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/// <reference lib="es2017" />
2+
/// <reference lib="es2018.asynciterable" />
23
/// <reference lib="es2018.promise" />
34
/// <reference lib="es2018.regexp" />
45
/// <reference lib="es2018.intl" />

src/lib/esnext.d.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
/// <reference lib="es2019" />
2-
/// <reference lib="esnext.asynciterable" />
3-
/// <reference lib="esnext.array" />
42
/// <reference lib="esnext.bigint" />
53
/// <reference lib="esnext.intl" />

src/lib/libs.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@
3030
"es2017.string",
3131
"es2017.intl",
3232
"es2017.typedarrays",
33+
"es2018.asynciterable",
3334
"es2018.regexp",
3435
"es2018.promise",
3536
"es2018.intl",
3637
"es2019.array",
3738
"es2019.string",
3839
"es2019.symbol",
39-
"esnext.asynciterable",
4040
"esnext.bigint",
4141
"esnext.intl",
4242
// Default libraries

src/services/services.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,20 @@ namespace ts {
1616
public pos: number;
1717
public end: number;
1818
public flags: NodeFlags;
19+
public modifierFlagsCache: ModifierFlags;
20+
public transformFlags: TransformFlags;
1921
public parent: Node;
2022
public symbol!: Symbol; // Actually optional, but it was too annoying to access `node.symbol!` everywhere since in many cases we know it must be defined
2123
public jsDoc?: JSDoc[];
2224
public original?: Node;
23-
public transformFlags: TransformFlags;
2425
private _children: Node[] | undefined;
2526

2627
constructor(kind: SyntaxKind, pos: number, end: number) {
2728
this.pos = pos;
2829
this.end = end;
2930
this.flags = NodeFlags.None;
30-
this.transformFlags = undefined!; // TODO: GH#18217
31+
this.modifierFlagsCache = ModifierFlags.None;
32+
this.transformFlags = TransformFlags.None;
3133
this.parent = undefined!;
3234
this.kind = kind;
3335
}
@@ -200,16 +202,19 @@ namespace ts {
200202
public pos: number;
201203
public end: number;
202204
public flags: NodeFlags;
205+
public modifierFlagsCache: ModifierFlags;
206+
public transformFlags: TransformFlags;
203207
public parent: Node;
204208
public symbol!: Symbol;
205209
public jsDocComments?: JSDoc[];
206-
public transformFlags!: TransformFlags;
207210

208211
constructor(pos: number, end: number) {
209212
// Set properties in same order as NodeObject
210213
this.pos = pos;
211214
this.end = end;
212215
this.flags = NodeFlags.None;
216+
this.modifierFlagsCache = ModifierFlags.None;
217+
this.transformFlags = TransformFlags.None;
213218
this.parent = undefined!;
214219
}
215220

0 commit comments

Comments
 (0)