Skip to content

Commit 16e8eb7

Browse files
Major Improvements 2
1 parent e0ecdf2 commit 16e8eb7

29 files changed

+7767
-1476
lines changed

build/alias.ts

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
const aliasArray: [string, string[]][] = [
2+
[
3+
"TypedNumberArray",
4+
[
5+
"Int8Array",
6+
"Uint8Array",
7+
"Uint8ClampedArray",
8+
"Int16Array",
9+
"Uint16Array",
10+
"Int32Array",
11+
"Uint32Array",
12+
"Float32Array",
13+
"Float64Array",
14+
],
15+
],
16+
["TypedBigIntArray", ["BigInt64Array", "BigUint64Array"]],
17+
];
18+
19+
export const alias = new Map(
20+
aliasArray.flatMap(([originalType, replacementTypes]) => [
21+
[
22+
originalType,
23+
new Map(
24+
replacementTypes.map((replacement) => [
25+
replacement,
26+
new Map([
27+
[originalType, replacement],
28+
[`${originalType}Constructor`, `${replacement}Constructor`],
29+
]),
30+
])
31+
),
32+
],
33+
[
34+
`${originalType}Constructor`,
35+
new Map(
36+
replacementTypes.map((replacement) => [
37+
`${replacement}Constructor`,
38+
new Map([
39+
[originalType, replacement],
40+
[`${originalType}Constructor`, `${replacement}Constructor`],
41+
]),
42+
])
43+
),
44+
],
45+
])
46+
);

build/logic/generate.ts

+81-36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import path from "path";
22
import ts from "typescript";
3+
import { alias } from "../alias";
34
import { upsert } from "../util/upsert";
45
import { projectDir } from "./projectDir";
56

@@ -24,7 +25,7 @@ export function generate(
2425

2526
let result = "";
2627

27-
const replacementTargets = scanBetterFile(libFile);
28+
const replacementTargets = scanBetterFile(printer, libFile);
2829

2930
if (replacementTargets.size === 0) {
3031
for (const statement of originalFile.statements) {
@@ -188,7 +189,10 @@ type ReplacementTarget = (
188189
/**
189190
* Scan better lib file to determine which statements need to be replaced.
190191
*/
191-
function scanBetterFile(libFile: string): Map<string, ReplacementTarget[]> {
192+
function scanBetterFile(
193+
printer: ts.Printer,
194+
libFile: string
195+
): Map<string, ReplacementTarget[]> {
192196
const replacementTargets = new Map<string, ReplacementTarget[]>();
193197
{
194198
const betterLibFile = path.join(betterLibDir, `lib.${libFile}`);
@@ -198,43 +202,58 @@ function scanBetterFile(libFile: string): Map<string, ReplacementTarget[]> {
198202
// Scan better file to determine which statements need to be replaced.
199203
for (const statement of betterFile.statements) {
200204
const name = getStatementDeclName(statement) ?? "";
201-
if (ts.isInterfaceDeclaration(statement)) {
202-
const members = new Map<
203-
string,
204-
{
205-
member: ts.TypeElement;
206-
text: string;
207-
}[]
208-
>();
209-
for (const member of statement.members) {
210-
const memberName = member.name?.getText(betterFile) ?? "";
211-
upsert(members, memberName, (members = []) => {
212-
members.push({
213-
member,
214-
text: member.getFullText(betterFile),
205+
const aliasesMap =
206+
alias.get(name) ?? new Map([[name, new Map<string, string>()]]);
207+
for (const [targetName, typeMap] of aliasesMap) {
208+
const transformedStatement = replaceAliases(statement, typeMap);
209+
if (ts.isInterfaceDeclaration(transformedStatement)) {
210+
const members = new Map<
211+
string,
212+
{
213+
member: ts.TypeElement;
214+
text: string;
215+
}[]
216+
>();
217+
for (const member of transformedStatement.members) {
218+
const memberName = member.name?.getText(betterFile) ?? "";
219+
upsert(members, memberName, (members = []) => {
220+
const leadingSpacesMatch = /^\s*/.exec(
221+
member.getFullText(betterFile)
222+
);
223+
const leadingSpaces =
224+
leadingSpacesMatch !== null ? leadingSpacesMatch[0] : "";
225+
members.push({
226+
member,
227+
text:
228+
leadingSpaces +
229+
printer.printNode(
230+
ts.EmitHint.Unspecified,
231+
member,
232+
betterFile
233+
),
234+
});
235+
return members;
215236
});
216-
return members;
217-
});
218-
}
219-
220-
upsert(replacementTargets, name, (targets = []) => {
221-
targets.push({
222-
type: "interface",
223-
members,
224-
originalStatement: statement,
225-
sourceFile: betterFile,
237+
}
238+
upsert(replacementTargets, targetName, (targets = []) => {
239+
targets.push({
240+
type: "interface",
241+
members,
242+
originalStatement: transformedStatement,
243+
sourceFile: betterFile,
244+
});
245+
return targets;
226246
});
227-
return targets;
228-
});
229-
} else {
230-
upsert(replacementTargets, name, (statements = []) => {
231-
statements.push({
232-
type: "non-interface",
233-
statement,
234-
sourceFile: betterFile,
247+
} else {
248+
upsert(replacementTargets, targetName, (statements = []) => {
249+
statements.push({
250+
type: "non-interface",
251+
statement: transformedStatement,
252+
sourceFile: betterFile,
253+
});
254+
return statements;
235255
});
236-
return statements;
237-
});
256+
}
238257
}
239258
}
240259
}
@@ -372,3 +391,29 @@ function commentOut(code: string): string {
372391
const result = lines.map((line) => `// ${line}`);
373392
return result.join("\n") + "\n";
374393
}
394+
395+
function replaceAliases(
396+
statement: ts.Statement,
397+
typeMap: Map<string, string>
398+
): ts.Statement {
399+
if (typeMap.size === 0) return statement;
400+
return ts.transform(statement, [
401+
(context) => (sourceStatement) => {
402+
const visitor = (node: ts.Node): ts.Node => {
403+
if (ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName)) {
404+
const replacementType = typeMap.get(node.typeName.text);
405+
if (replacementType === undefined) {
406+
return node;
407+
}
408+
return ts.factory.updateTypeReferenceNode(
409+
node,
410+
ts.factory.createIdentifier(replacementType),
411+
node.typeArguments
412+
);
413+
}
414+
return ts.visitEachChild(node, visitor, context);
415+
};
416+
return ts.visitNode(sourceStatement, visitor);
417+
},
418+
]).transformed[0];
419+
}

docs/diff.md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The following files are improved in better-typescript-lib:
1515
- [es2018.asyncgenerator.d.ts](./diff/es2018.asyncgenerator.d.ts.md)
1616
- [es2018.asynciterable.d.ts](./diff/es2018.asynciterable.d.ts.md)
1717
- [es2019.object.d.ts](./diff/es2019.object.d.ts.md)
18+
- [es2020.bigint.d.ts](./diff/es2020.bigint.d.ts.md)
1819
- [es2021.promise.d.ts](./diff/es2021.promise.d.ts.md)
1920
- [es2021.string.d.ts](./diff/es2021.string.d.ts.md)
2021
- [es2022.object.d.ts](./diff/es2022.object.d.ts.md)

docs/diff/es2015.collection.d.ts.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Index: es2015.collection.d.ts
1313
- callbackfn: (value: V, key: K, map: Map<K, V>) => void,
1414
- thisArg?: any
1515
+ forEach<This = undefined>(
16-
+ callbackfn: (this: This, value: V, key: K, map: Map<K, V>) => void,
16+
+ callbackfn: (this: This, value: V, key: K, map: this) => void,
1717
+ thisArg?: This
1818
): void;
1919
get(key: K): V | undefined;
@@ -35,7 +35,7 @@ Index: es2015.collection.d.ts
3535
- callbackfn: (value: V, key: K, map: ReadonlyMap<K, V>) => void,
3636
- thisArg?: any
3737
+ forEach<This = undefined>(
38-
+ callbackfn: (this: This, value: V, key: K, map: ReadonlyMap<K, V>) => void,
38+
+ callbackfn: (this: This, value: V, key: K, map: this) => void,
3939
+ thisArg?: This
4040
): void;
4141
get(key: K): V | undefined;
@@ -66,7 +66,7 @@ Index: es2015.collection.d.ts
6666
- callbackfn: (value: T, value2: T, set: Set<T>) => void,
6767
- thisArg?: any
6868
+ forEach<This = undefined>(
69-
+ callbackfn: (this: This, value: T, value2: T, set: Set<T>) => void,
69+
+ callbackfn: (this: This, value: T, value2: T, set: this) => void,
7070
+ thisArg?: This
7171
): void;
7272
has(value: T): boolean;
@@ -86,7 +86,7 @@ Index: es2015.collection.d.ts
8686
- callbackfn: (value: T, value2: T, set: ReadonlySet<T>) => void,
8787
- thisArg?: any
8888
+ forEach<This = undefined>(
89-
+ callbackfn: (this: This, value: T, value2: T, set: ReadonlySet<T>) => void,
89+
+ callbackfn: (this: This, value: T, value2: T, set: this) => void,
9090
+ thisArg?: This
9191
): void;
9292
has(value: T): boolean;

0 commit comments

Comments
 (0)