Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@ class ArraySlice<T> {
return this.array[this.start + adjustedIndex];
}

[Symbol.iterator] = function* (
this: ArraySlice<T>,
): Generator<T, void, void> {
*[Symbol.iterator](this: ArraySlice<T>): Generator<T, void, void> {
for (let i = this.start; i <= this.end; ++i) {
yield this.array[i];
}
};
}

slide(delta: number = 1): IndexableArraySlice<T> {
return ArraySlice.get(this.array, this.start + delta, this.end + delta);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ class ArraySlice {
return this.array[this.start + adjustedIndex];
}

[Symbol.iterator] = function* () {
*[Symbol.iterator]() {
for (let i = this.start; i <= this.end; ++i) {
yield this.array[i];
}
};
}

slide(delta = 1) {
return ArraySlice.get(this.array, this.start + delta, this.end + delta);
Expand Down Expand Up @@ -907,14 +907,14 @@ exports[`App can equip single goody: TypeScript Array.prototype.slidingWindows 1
// Running at: https://example.com/

declare global {
interface ReadonlyArray<T> {
interface Array<T> {
slidingWindows(
this: ReadonlyArray<T>,
windowSize: number,
): Generator<ArraySlice<T>, void, void>;
}

interface Array<T> {
interface ReadonlyArray<T> {
slidingWindows(
this: ReadonlyArray<T>,
windowSize: number,
Expand Down Expand Up @@ -946,13 +946,11 @@ class ArraySlice<T> {
return this.array[this.start + adjustedIndex];
}

[Symbol.iterator] = function* (
this: ArraySlice<T>,
): Generator<T, void, void> {
*[Symbol.iterator](this: ArraySlice<T>): Generator<T, void, void> {
for (let i = this.start; i <= this.end; ++i) {
yield this.array[i];
}
};
}

slide(delta: number = 1): IndexableArraySlice<T> {
return ArraySlice.get(this.array, this.start + delta, this.end + delta);
Expand Down Expand Up @@ -1180,15 +1178,13 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
every(
this: Iterator<T>,
callbackfn: (value: T, index: number) => unknown,
): boolean;

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1235,15 +1231,13 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
filter(
this: Iterator<T>,
callbackfn: (value: T, index: number) => unknown,
): Generator<T, void, void>;

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1289,15 +1283,13 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
find(
this: Iterator<T>,
callbackFn: (element: T, index: number) => boolean,
): T | undefined;

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1344,15 +1336,13 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
forEach(
this: Iterator<T>,
callbackFn: (element: T, index: number) => void,
): void;

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1396,15 +1386,13 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
map<TOut>(
this: Iterator<T>,
callbackFn: (element: T, index: number) => TOut,
): Generator<TOut, void, void>;

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1448,16 +1436,14 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
max(
this: Iterator<T>,
compareFn?: (a: T, b: T) => number,
options?: { nanBehavior?: "avoid" | "compare" },
): T | undefined;

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1535,16 +1521,14 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
min(
this: Iterator<T>,
compareFn?: (a: T, b: T) => number,
options?: { nanBehavior?: "avoid" | "compare" },
): T | undefined;

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1622,15 +1606,13 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
some(
this: Iterator<T>,
callbackfn: (value: T, index: number) => unknown,
): boolean;

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1677,12 +1659,10 @@ declare global {
returnThis<T>(this: T): T;
}

interface Iterator<T> {
toIterable(this: Iterator<T>): IterableIterator<T>;
}

interface Iterator<T> {
toArray(this: Iterator<T>): T[];

toIterable(this: Iterator<T>): IterableIterator<T>;
}
}

Expand Down Expand Up @@ -1814,14 +1794,14 @@ exports[`App can equip single goody: TypeScript Number.prototype.digits 1`] = `
// Running at: https://example.com/

declare global {
interface NumberConstructor {
isIntegerOrIntegerObject(num: unknown): boolean;
}

interface Number {
digits(this: Number): Generator<number, void, void>;
digits(this: Number, radix: number): Generator<number, void, void>;
}

interface NumberConstructor {
isIntegerOrIntegerObject(num: unknown): boolean;
}
}

Number.isIntegerOrIntegerObject = function (num: unknown): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ exports[`App can render goody: JavaScript Array.prototype.slidingWindows 1`] = `
return this.array[this.start + adjustedIndex];
}

[Symbol.iterator] = function* () {
*[Symbol.iterator]() {
for (let i = this.start; i <= this.end; ++i) {
yield this.array[i];
}
};
}

slide(delta = 1) {
return ArraySlice.get(this.array, this.start + delta, this.end + delta);
Expand Down Expand Up @@ -560,14 +560,14 @@ del set_up_adventure_pack"

exports[`App can render goody: TypeScript Array.prototype.slidingWindows 1`] = `
"declare global {
interface ReadonlyArray<T> {
interface Array<T> {
slidingWindows(
this: ReadonlyArray<T>,
windowSize: number,
): Generator<ArraySlice<T>, void, void>;
}

interface Array<T> {
interface ReadonlyArray<T> {
slidingWindows(
this: ReadonlyArray<T>,
windowSize: number,
Expand Down Expand Up @@ -599,13 +599,11 @@ class ArraySlice<T> {
return this.array[this.start + adjustedIndex];
}

[Symbol.iterator] = function* (
this: ArraySlice<T>,
): Generator<T, void, void> {
*[Symbol.iterator](this: ArraySlice<T>): Generator<T, void, void> {
for (let i = this.start; i <= this.end; ++i) {
yield this.array[i];
}
};
}

slide(delta: number = 1): IndexableArraySlice<T> {
return ArraySlice.get(this.array, this.start + delta, this.end + delta);
Expand Down
11 changes: 6 additions & 5 deletions tools/adventure-pack/src/app/goodyToText.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Goody } from "./Goody";
import { mergeJavaCode } from "./mergeJavaCode";
import { stringifyTypeScriptModuleDeclarations } from "./stringifyTypeScriptModuleDeclarations";

export function goodyToText(goody: Goody): string {
switch (goody.language) {
Expand Down Expand Up @@ -28,14 +29,14 @@ export function goodyToText(goody: Goody): string {
return goody.code.trim();
}
case "typescript": {
const moduleDeclarations = stringifyTypeScriptModuleDeclarations(
goody.moduleDeclarations,
);

return (
goody.imports.map((im) => `import ${JSON.stringify(im)};\n`).join("") +
"\n" +
(goody.globalModuleDeclarations.length > 0
? `declare global {\n ${goody.globalModuleDeclarations
.join("\n\n")
.trim()}\n}\n\n`
: "") +
(moduleDeclarations.length > 0 ? moduleDeclarations + "\n\n" : "") +
goody.code
).trim();
}
Expand Down
42 changes: 31 additions & 11 deletions tools/adventure-pack/src/app/mergeCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import type { Goody } from "./Goody";
import type { Language } from "./Language";
import { mergeJavaCode } from "./mergeJavaCode";
import type { JavaGoody } from "./parsers/javaGoodyParser";
import { sortTypeScriptModuleAndInterfaceDeclarations } from "./sortTypeScriptModuleAndInterfaceDeclarations";
import { stringifyTypeScriptModuleDeclarations } from "./stringifyTypeScriptModuleDeclarations";

function topo({
goodies,
Expand Down Expand Up @@ -110,19 +112,37 @@ export function mergeCode({
);
}

const globalModuleDeclarations =
language === "typescript"
? orderedGoodies.flatMap((goody) =>
goody.language === "typescript"
? goody.globalModuleDeclarations
: [],
)
: [];
const moduleDeclarations = (() => {
if (language !== "typescript") {
return "";
}

const mergedDeclarations: Record<string, Record<string, string[]>> = {};
for (const goody of orderedGoodies) {
invariant(
goody.language === "typescript",
"Goody language must match language!",
);

for (const [moduleName, interfaceDeclarations] of Object.entries(
goody.moduleDeclarations,
)) {
for (const [interfaceName, codeGroups] of Object.entries(
interfaceDeclarations,
)) {
((mergedDeclarations[moduleName] ??= {})[interfaceName] ??=
[]).push(...codeGroups);
}
}
}

return stringifyTypeScriptModuleDeclarations(
sortTypeScriptModuleAndInterfaceDeclarations(mergedDeclarations),
);
})();

return [
globalModuleDeclarations.length > 0
? `declare global {\n${globalModuleDeclarations.join("\n\n")}\n}`
: "",
moduleDeclarations,

...orderedGoodies.map((goody) => {
invariant(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import { nonBlankStringParser } from "./nonBlankStringParser";

export const typeScriptGoodyParser = goodyBaseParser.extend({
code: nonBlankStringParser,
// TODO: generalize to simply declarations
globalModuleDeclarations: z.array(nonBlankStringParser),
moduleDeclarations: z.record(
z.string(),
z.record(z.string(), z.array(nonBlankStringParser)),
),
language: z.literal("typescript"),
});

Expand Down
Loading