Skip to content

Commit 5a6580c

Browse files
authored
Merge pull request #2 from dsherret/branch_v4.9.3_patch
Upgrade to TS 4.9.3
2 parents 93bd577 + ac0e526 commit 5a6580c

File tree

7 files changed

+332
-24
lines changed

7 files changed

+332
-24
lines changed

src/compiler/builderState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ namespace ts {
225225
}
226226

227227
// From ambient modules
228-
for (const ambientModule of program.getTypeChecker().getAmbientModules()) {
228+
for (const ambientModule of program.getTypeChecker().getAmbientModules(sourceFile)) {
229229
if (ambientModule.declarations && ambientModule.declarations.length > 1) {
230230
addReferenceFromAmbientModule(ambientModule);
231231
}

src/compiler/checker.ts

Lines changed: 104 additions & 20 deletions
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ namespace ts {
3838
// Host only
3939
["dom", "lib.dom.d.ts"],
4040
["dom.iterable", "lib.dom.iterable.d.ts"],
41+
["dom.asynciterable", "lib.dom.asynciterable.d.ts"],
42+
["dom.extras", "lib.dom.extras.d.ts"],
4143
["webworker", "lib.webworker.d.ts"],
4244
["webworker.importscripts", "lib.webworker.importscripts.d.ts"],
4345
["webworker.iterable", "lib.webworker.iterable.d.ts"],
@@ -86,7 +88,7 @@ namespace ts {
8688
["es2022.object", "lib.es2022.object.d.ts"],
8789
["es2022.sharedmemory", "lib.es2022.sharedmemory.d.ts"],
8890
["es2022.string", "lib.es2022.string.d.ts"],
89-
["esnext.array", "lib.es2022.array.d.ts"],
91+
["esnext.array", "lib.esnext.array.d.ts"],
9092
["esnext.symbol", "lib.es2019.symbol.d.ts"],
9193
["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
9294
["esnext.intl", "lib.esnext.intl.d.ts"],

src/compiler/deno.ts

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/* @internal */
2+
namespace ts.deno {
3+
export type IsNodeSourceFileCallback = (sourceFile: SourceFile) => boolean;
4+
5+
let isNodeSourceFile: IsNodeSourceFileCallback = () => false;
6+
7+
export function setIsNodeSourceFileCallback(callback: IsNodeSourceFileCallback) {
8+
isNodeSourceFile = callback;
9+
}
10+
11+
// When upgrading:
12+
// 1. Inspect all usages of "globals" and "globalThisSymbol" in checker.ts
13+
// - Beware that `globalThisType` might refer to the global `this` type
14+
// and not the global `globalThis` type
15+
// 2. Inspect the types in @types/node for anything that might need to go below
16+
// as well.
17+
18+
const nodeOnlyGlobalNames = new Set([
19+
"NodeRequire",
20+
"RequireResolve",
21+
"RequireResolve",
22+
"process",
23+
"console",
24+
"__filename",
25+
"__dirname",
26+
"require",
27+
"module",
28+
"exports",
29+
"gc",
30+
"BufferEncoding",
31+
"BufferConstructor",
32+
"WithImplicitCoercion",
33+
"Buffer",
34+
"Console",
35+
"ImportMeta",
36+
"setTimeout",
37+
"setInterval",
38+
"setImmediate",
39+
"Global",
40+
"AbortController",
41+
"AbortSignal",
42+
"Blob",
43+
"BroadcastChannel",
44+
"MessageChannel",
45+
"MessagePort",
46+
"Event",
47+
"EventTarget",
48+
"performance",
49+
"TextDecoder",
50+
"TextEncoder",
51+
"URL",
52+
"URLSearchParams",
53+
]) as Set<ts.__String>;
54+
55+
export function createDenoForkContext({
56+
mergeSymbol,
57+
globals,
58+
nodeGlobals,
59+
ambientModuleSymbolRegex,
60+
}: {
61+
mergeSymbol(target: Symbol, source: Symbol, unidirectional?: boolean): Symbol;
62+
globals: SymbolTable;
63+
nodeGlobals: SymbolTable;
64+
ambientModuleSymbolRegex: RegExp,
65+
}) {
66+
return {
67+
hasNodeSourceFile,
68+
getGlobalsForName,
69+
mergeGlobalSymbolTable,
70+
combinedGlobals: createNodeGlobalsSymbolTable(),
71+
};
72+
73+
function hasNodeSourceFile(node: Node | undefined) {
74+
if (!node) return false;
75+
const sourceFile = getSourceFileOfNode(node);
76+
return isNodeSourceFile(sourceFile);
77+
}
78+
79+
function getGlobalsForName(id: ts.__String) {
80+
// Node ambient modules are only accessible in the node code,
81+
// so put them on the node globals
82+
if (ambientModuleSymbolRegex.test(id as string))
83+
return nodeGlobals;
84+
return nodeOnlyGlobalNames.has(id) ? nodeGlobals : globals;
85+
}
86+
87+
function mergeGlobalSymbolTable(node: Node, source: SymbolTable, unidirectional = false) {
88+
const sourceFile = getSourceFileOfNode(node);
89+
const isNodeFile = hasNodeSourceFile(sourceFile);
90+
source.forEach((sourceSymbol, id) => {
91+
const target = isNodeFile ? getGlobalsForName(id) : globals;
92+
const targetSymbol = target.get(id);
93+
target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol);
94+
});
95+
}
96+
97+
function createNodeGlobalsSymbolTable() {
98+
return new Proxy(globals, {
99+
get(target, prop: string | symbol, receiver) {
100+
if (prop === "get") {
101+
return (key: ts.__String) => {
102+
return nodeGlobals.get(key) ?? globals.get(key);
103+
};
104+
} else if (prop === "has") {
105+
return (key: ts.__String) => {
106+
return nodeGlobals.has(key) || globals.has(key);
107+
};
108+
} else if (prop === "size") {
109+
let i = 0;
110+
forEachEntry(() => {
111+
i++;
112+
});
113+
return i;
114+
} else if (prop === "forEach") {
115+
return (action: (value: Symbol, key: ts.__String) => void) => {
116+
forEachEntry(([key, value]) => {
117+
action(value, key);
118+
});
119+
};
120+
} else if (prop === "entries") {
121+
return () => {
122+
return getEntries(kv => kv);
123+
};
124+
} else if (prop === "keys") {
125+
return () => {
126+
return getEntries(kv => kv[0]);
127+
};
128+
} else if (prop === "values") {
129+
return () => {
130+
return getEntries(kv => kv[1]);
131+
};
132+
} else if (prop === Symbol.iterator) {
133+
return () => {
134+
// Need to convert this to an array since typescript targets ES5
135+
// and providing back the iterator won't work here. I don't want
136+
// to change the target to ES6 because I'm not sure if that would
137+
// surface any issues.
138+
return arrayFrom(getEntries(kv => kv))[Symbol.iterator]();
139+
};
140+
} else {
141+
const value = (target as any)[prop];
142+
if (value instanceof Function) {
143+
return function (this: any, ...args: any[]) {
144+
return value.apply(this === receiver ? target : this, args);
145+
};
146+
}
147+
return value;
148+
}
149+
},
150+
});
151+
152+
function forEachEntry(action: (value: [__String, Symbol]) => void) {
153+
const iterator = getEntries((entry) => {
154+
action(entry);
155+
});
156+
// drain the iterator to do the action
157+
while (!iterator.next().done) {}
158+
}
159+
160+
function* getEntries<R>(
161+
transform: (value: [__String, Symbol]) => R
162+
) {
163+
const foundKeys = new Set<ts.__String>();
164+
for (const entries of [nodeGlobals.entries(), globals.entries()]) {
165+
let next = entries.next();
166+
while (!next.done) {
167+
if (!foundKeys.has(next.value[0])) {
168+
yield transform(next.value);
169+
foundKeys.add(next.value[0]);
170+
}
171+
next = entries.next();
172+
}
173+
}
174+
}
175+
}
176+
}
177+
178+
export interface NpmPackageReference {
179+
name: string;
180+
versionReq: string;
181+
subPath: string | undefined;
182+
}
183+
184+
export function tryParseNpmPackageReference(text: string) {
185+
try {
186+
return parseNpmPackageReference(text);
187+
} catch {
188+
return undefined;
189+
}
190+
}
191+
192+
export function parseNpmPackageReference(text: string) {
193+
if (!text.startsWith("npm:")) {
194+
throw new Error(`Not an npm specifier: ${text}`);
195+
}
196+
text = text.replace(/^npm:\/?/, "");
197+
const parts = text.split("/");
198+
const namePartLen = text.startsWith("@") ? 2 : 1;
199+
if (parts.length < namePartLen) {
200+
throw new Error(`Not a valid package: ${text}`);
201+
}
202+
const nameParts = parts.slice(0, namePartLen);
203+
const lastNamePart = nameParts.at(-1)!;
204+
const lastAtIndex = lastNamePart.lastIndexOf("@");
205+
let versionReq: string | undefined = undefined;
206+
if (lastAtIndex > 0) {
207+
versionReq = lastNamePart.substring(lastAtIndex + 1);
208+
nameParts[nameParts.length - 1] = lastNamePart.substring(0, lastAtIndex);
209+
}
210+
const name = nameParts.join("/");
211+
if (name.length === 0) {
212+
throw new Error(`Npm specifier did not have a name: ${text}`);
213+
}
214+
return {
215+
name,
216+
versionReq,
217+
subPath: parts.length > nameParts.length ? parts.slice(nameParts.length).join("/") : undefined,
218+
};
219+
}
220+
}

src/compiler/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
"binder.ts",
4242
"symbolWalker.ts",
4343
"checker.ts",
44+
"deno.ts",
4445
"visitorPublic.ts",
4546
"sourcemap.ts",
4647
"transformers/utilities.ts",

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4723,7 +4723,7 @@ namespace ts {
47234723
/* @internal */ forEachExportAndPropertyOfModule(moduleSymbol: Symbol, cb: (symbol: Symbol, key: __String) => void): void;
47244724
getJsxIntrinsicTagNamesAt(location: Node): Symbol[];
47254725
isOptionalParameter(node: ParameterDeclaration): boolean;
4726-
getAmbientModules(): Symbol[];
4726+
getAmbientModules(sourceFile?: SourceFile): Symbol[];
47274727

47284728
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
47294729
/**

src/services/completions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4214,7 +4214,8 @@ namespace ts.Completions {
42144214
if (globalSymbol && checker.getTypeOfSymbolAtLocation(globalSymbol, sourceFile) === type) {
42154215
return true;
42164216
}
4217-
const globalThisSymbol = checker.resolveName("globalThis", /*location*/ undefined, SymbolFlags.Value, /*excludeGlobals*/ false);
4217+
// deno: provide sourceFile so that it can figure out if it's a node or deno globalThis
4218+
const globalThisSymbol = checker.resolveName("globalThis", /*location*/ sourceFile, SymbolFlags.Value, /*excludeGlobals*/ false);
42184219
if (globalThisSymbol && checker.getTypeOfSymbolAtLocation(globalThisSymbol, sourceFile) === type) {
42194220
return true;
42204221
}

0 commit comments

Comments
 (0)