Skip to content

Commit 6b9e7a8

Browse files
committed
Fix lualib_bundle.lua not being updated immediately when lualib source changes
1 parent f4f7a92 commit 6b9e7a8

8 files changed

Lines changed: 68 additions & 65 deletions

File tree

src/LuaLib.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,21 +129,25 @@ export function readLuaLibFeature(feature: LuaLibFeature, emitHost: EmitHost): s
129129
return luaLibFeature;
130130
}
131131

132-
export function loadInlineLualibFeatures(features: Iterable<LuaLibFeature>, emitHost: EmitHost): string {
132+
export function loadInlineLualibFeatures(
133+
features: Iterable<LuaLibFeature>,
134+
emitHost: EmitHost,
135+
luaLibModulesInfo: LuaLibModulesInfo = getLuaLibModuleInfo(emitHost),
136+
readFeature: (feature: LuaLibFeature) => string = feature => readLuaLibFeature(feature, emitHost)
137+
): string {
133138
let result = "";
134139

135140
const loadedFeatures = new Set<LuaLibFeature>();
136141

137-
const luaLibDependencyMap = getLuaLibModuleInfo(emitHost);
138142
function load(feature: LuaLibFeature): void {
139143
if (loadedFeatures.has(feature)) return;
140144
loadedFeatures.add(feature);
141145

142-
const dependencies = luaLibDependencyMap[feature]?.dependencies;
146+
const dependencies = luaLibModulesInfo[feature]?.dependencies;
143147
if (dependencies) {
144148
dependencies.forEach(load);
145149
}
146-
const luaLibFeature = readLuaLibFeature(feature, emitHost);
150+
const luaLibFeature = readFeature(feature);
147151
result += luaLibFeature + "\n";
148152
}
149153

src/lualib/Promise.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Promises implemented based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
44
// and https://promisesaplus.com/
55

6-
export enum __TS__PromiseState {
6+
export const enum PromiseState {
77
Pending,
88
Fulfilled,
99
Rejected,
@@ -28,7 +28,7 @@ function isPromiseLike<T>(thing: unknown): thing is PromiseLike<T> {
2828
}
2929

3030
export class __TS__Promise<T> implements Promise<T> {
31-
public state = __TS__PromiseState.Pending;
31+
public state = PromiseState.Pending;
3232
public value?: T;
3333
public rejectionReason?: any;
3434

@@ -42,7 +42,7 @@ export class __TS__Promise<T> implements Promise<T> {
4242
public static resolve<TData>(this: void, data: TData): Promise<TData> {
4343
// Create and return a promise instance that is already resolved
4444
const promise = new __TS__Promise<TData>(() => {});
45-
promise.state = __TS__PromiseState.Fulfilled;
45+
promise.state = PromiseState.Fulfilled;
4646
promise.value = data;
4747
return promise;
4848
}
@@ -51,7 +51,7 @@ export class __TS__Promise<T> implements Promise<T> {
5151
public static reject(this: void, reason: any): Promise<never> {
5252
// Create and return a promise instance that is already rejected
5353
const promise = new __TS__Promise<never>(() => {});
54-
promise.state = __TS__PromiseState.Rejected;
54+
promise.state = PromiseState.Rejected;
5555
promise.rejectionReason = reason;
5656
return promise;
5757
}
@@ -72,8 +72,8 @@ export class __TS__Promise<T> implements Promise<T> {
7272
): Promise<TResult1 | TResult2> {
7373
const { promise, resolve, reject } = promiseDeferred<T | TResult1 | TResult2>();
7474

75-
const isFulfilled = this.state === __TS__PromiseState.Fulfilled;
76-
const isRejected = this.state === __TS__PromiseState.Rejected;
75+
const isFulfilled = this.state === PromiseState.Fulfilled;
76+
const isRejected = this.state === PromiseState.Rejected;
7777

7878
if (onFulfilled) {
7979
const internalCallback = this.createPromiseResolvingCallback(onFulfilled, resolve, reject);
@@ -121,7 +121,7 @@ export class __TS__Promise<T> implements Promise<T> {
121121
if (onFinally) {
122122
this.finallyCallbacks.push(onFinally);
123123

124-
if (this.state !== __TS__PromiseState.Pending) {
124+
if (this.state !== PromiseState.Pending) {
125125
// If promise already resolved or rejected, immediately fire finally callback
126126
onFinally();
127127
}
@@ -139,8 +139,8 @@ export class __TS__Promise<T> implements Promise<T> {
139139
}
140140

141141
// Resolve this promise, if it is still pending. This function is passed to the constructor function.
142-
if (this.state === __TS__PromiseState.Pending) {
143-
this.state = __TS__PromiseState.Fulfilled;
142+
if (this.state === PromiseState.Pending) {
143+
this.state = PromiseState.Fulfilled;
144144
this.value = data;
145145

146146
for (const callback of this.fulfilledCallbacks) {
@@ -154,8 +154,8 @@ export class __TS__Promise<T> implements Promise<T> {
154154

155155
private reject(reason: any): void {
156156
// Reject this promise, if it is still pending. This function is passed to the constructor function.
157-
if (this.state === __TS__PromiseState.Pending) {
158-
this.state = __TS__PromiseState.Rejected;
157+
if (this.state === PromiseState.Pending) {
158+
this.state = PromiseState.Rejected;
159159
this.rejectionReason = reason;
160160

161161
for (const callback of this.rejectedCallbacks) {
@@ -189,11 +189,11 @@ export class __TS__Promise<T> implements Promise<T> {
189189
) {
190190
if (isPromiseLike<TResult>(data)) {
191191
const nextpromise = data as __TS__Promise<TResult>;
192-
if (nextpromise.state === __TS__PromiseState.Fulfilled) {
192+
if (nextpromise.state === PromiseState.Fulfilled) {
193193
// If a handler function returns an already fulfilled promise,
194194
// the promise returned by then gets fulfilled with that promise's value
195195
resolve(nextpromise.value);
196-
} else if (nextpromise.state === __TS__PromiseState.Rejected) {
196+
} else if (nextpromise.state === PromiseState.Rejected) {
197197
// If a handler function returns an already rejected promise,
198198
// the promise returned by then gets fulfilled with that promise's value
199199
reject(nextpromise.rejectionReason);

src/lualib/PromiseAll.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
2-
import { __TS__Promise, __TS__PromiseState } from "./Promise";
2+
import { __TS__Promise, PromiseState } from "./Promise";
33

44
// eslint-disable-next-line @typescript-eslint/promise-function-async
55
export function __TS__PromiseAll<T>(this: void, iterable: Iterable<T | PromiseLike<T>>): Promise<T[]> {
@@ -11,10 +11,10 @@ export function __TS__PromiseAll<T>(this: void, iterable: Iterable<T | PromiseLi
1111
let i = 0;
1212
for (const item of iterable) {
1313
if (item instanceof __TS__Promise) {
14-
if (item.state === __TS__PromiseState.Fulfilled) {
14+
if (item.state === PromiseState.Fulfilled) {
1515
// If value is a resolved promise, add its value to our results array
1616
results[i] = item.value;
17-
} else if (item.state === __TS__PromiseState.Rejected) {
17+
} else if (item.state === PromiseState.Rejected) {
1818
// If value is a rejected promise, return a rejected promise with the rejection reason
1919
return Promise.reject(item.rejectionReason);
2020
} else {

src/lualib/PromiseAllSettled.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
2-
import { __TS__Promise, __TS__PromiseState } from "./Promise";
2+
import { __TS__Promise, PromiseState } from "./Promise";
33

44
// eslint-disable-next-line @typescript-eslint/promise-function-async
55
export function __TS__PromiseAllSettled<T>(
@@ -14,10 +14,10 @@ export function __TS__PromiseAllSettled<T>(
1414
let i = 0;
1515
for (const item of iterable) {
1616
if (item instanceof __TS__Promise) {
17-
if (item.state === __TS__PromiseState.Fulfilled) {
17+
if (item.state === PromiseState.Fulfilled) {
1818
// If value is a resolved promise, add a fulfilled PromiseSettledResult
1919
results[i] = { status: "fulfilled", value: item.value };
20-
} else if (item.state === __TS__PromiseState.Rejected) {
20+
} else if (item.state === PromiseState.Rejected) {
2121
// If value is a rejected promise, add a rejected PromiseSettledResult
2222
results[i] = { status: "rejected", reason: item.rejectionReason };
2323
} else {

src/lualib/PromiseAny.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any
2-
import { __TS__Promise, __TS__PromiseState } from "./Promise";
2+
import { __TS__Promise, PromiseState } from "./Promise";
33

44
// eslint-disable-next-line @typescript-eslint/promise-function-async
55
export function __TS__PromiseAny<T>(this: void, iterable: Iterable<T | PromiseLike<T>>): Promise<T> {
@@ -8,10 +8,10 @@ export function __TS__PromiseAny<T>(this: void, iterable: Iterable<T | PromiseLi
88

99
for (const item of iterable) {
1010
if (item instanceof __TS__Promise) {
11-
if (item.state === __TS__PromiseState.Fulfilled) {
11+
if (item.state === PromiseState.Fulfilled) {
1212
// If value is a resolved promise, return a new resolved promise with its value
1313
return Promise.resolve(item.value);
14-
} else if (item.state === __TS__PromiseState.Rejected) {
14+
} else if (item.state === PromiseState.Rejected) {
1515
// If value is a rejected promise, add its value to our list of rejections
1616
rejections.push(item.rejectionReason);
1717
} else {

src/lualib/PromiseRace.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race
2-
import { __TS__PromiseState, __TS__Promise } from "./Promise";
2+
import { PromiseState, __TS__Promise } from "./Promise";
33

44
// eslint-disable-next-line @typescript-eslint/promise-function-async
55
export function __TS__PromiseRace<T>(this: void, iterable: Iterable<T | PromiseLike<T>>): Promise<T> {
66
const pending: Array<PromiseLike<T>> = [];
77

88
for (const item of iterable) {
99
if (item instanceof __TS__Promise) {
10-
if (item.state === __TS__PromiseState.Fulfilled) {
10+
if (item.state === PromiseState.Fulfilled) {
1111
// If value is a fulfilled promise, return a resolved promise with its value
1212
return Promise.resolve(item.value);
13-
} else if (item.state === __TS__PromiseState.Rejected) {
13+
} else if (item.state === PromiseState.Rejected) {
1414
// If value is a rejected promise, return rejected promise with its value
1515
return Promise.reject(item.rejectionReason);
1616
} else {

src/transpilation/lualib.ts

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@ import { ProcessedFile, EmitHost } from "./utils";
22
import { LuaLibFeature, LuaLibModulesInfo, loadInlineLualibFeatures } from "../LuaLib";
33
import * as path from "path";
44
import { LuaPrinter } from "../LuaPrinter";
5-
import * as ts from "typescript";
65
import * as lua from "../LuaAST";
6+
import { assume } from "../utils";
7+
import * as ts from "typescript";
78

8-
export function createLuaLibModuleInfo(files: ProcessedFile[]): LuaLibModulesInfo {
9+
export function generateExtraLualibFiles(
10+
emitHost: EmitHost,
11+
program: ts.Program,
12+
files: ProcessedFile[]
13+
): ProcessedFile[] {
914
const luaLibFiles: Map<LuaLibFeature, ProcessedFile> = new Map();
10-
1115
for (const file of files) {
1216
if (!file.luaAst) continue;
1317
const fileName = path.basename(file.fileName, ".ts");
@@ -24,7 +28,8 @@ export function createLuaLibModuleInfo(files: ProcessedFile[]): LuaLibModulesInf
2428
}
2529
}
2630

27-
const result: Partial<LuaLibModulesInfo> = {};
31+
// lualibModulesInfo
32+
const lualibModulesInfo: Partial<LuaLibModulesInfo> = {};
2833
for (const [feature, file] of luaLibFiles) {
2934
let dependencies: LuaLibFeature[] | undefined;
3035
const dependenciesForFeature = file.luaAst!.luaLibFeatures;
@@ -35,33 +40,40 @@ export function createLuaLibModuleInfo(files: ProcessedFile[]): LuaLibModulesInf
3540

3641
const exports = file.luaAst!.exports!;
3742
if (dependencies || exports) {
38-
result[feature] = {
43+
lualibModulesInfo[feature] = {
3944
dependencies,
4045
exports,
4146
};
4247
}
4348
}
49+
assume<LuaLibModulesInfo>(lualibModulesInfo);
4450

45-
return result as LuaLibModulesInfo;
46-
}
47-
48-
export function createLuaLibBundle(
49-
emitHost: EmitHost,
50-
program: ts.Program,
51-
luaLibModuleInfo: LuaLibModulesInfo
52-
): string {
53-
const allFeatures = Object.values(LuaLibFeature) as LuaLibFeature[];
54-
55-
let result = loadInlineLualibFeatures(allFeatures, emitHost);
56-
57-
const exports = allFeatures.flatMap(feature => luaLibModuleInfo[feature].exports);
51+
// lua bundle
52+
const allFeatures = Array.from(luaLibFiles.keys());
53+
let lualibBundle = loadInlineLualibFeatures(
54+
allFeatures,
55+
emitHost,
56+
lualibModulesInfo,
57+
feature => luaLibFiles.get(feature)?.code ?? ""
58+
);
59+
const exports = allFeatures.flatMap(feature => lualibModulesInfo[feature].exports);
5860
const statements: lua.TableFieldExpression[] = exports.map(exportName =>
5961
lua.createTableFieldExpression(lua.createIdentifier(exportName), lua.createStringLiteral(exportName))
6062
);
6163
const moduleReturn = lua.createReturnStatement([lua.createTableExpression(statements)]);
62-
6364
const printer = new LuaPrinter(emitHost, program, "lualib_bundle.lua");
64-
result += `\n${printer.printReturnStatement(moduleReturn)}\n`;
65+
lualibBundle += `\n${printer.printStatement(moduleReturn)}\n`;
6566

66-
return result;
67+
return [
68+
{
69+
code: lualibBundle,
70+
fileName: "lualib_bundle.lua",
71+
isRawFile: true,
72+
},
73+
{
74+
code: JSON.stringify(lualibModulesInfo, null, 2),
75+
fileName: "lualib_dependencies.json",
76+
isRawFile: true,
77+
},
78+
];
6779
}

src/transpilation/transpile.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { isNonNull } from "../utils";
77
import { getPlugins, Plugin } from "./plugins";
88
import { getTransformers } from "./transformers";
99
import { EmitHost, ProcessedFile } from "./utils";
10-
import { createLuaLibModuleInfo, createLuaLibBundle } from "./lualib";
10+
import { generateExtraLualibFiles } from "./lualib";
1111

1212
export interface TranspileOptions {
1313
program: ts.Program;
@@ -126,20 +126,7 @@ export function getProgramTranspileResult(
126126

127127
if (options.luaLibProject) {
128128
// add lualib dependencies json file
129-
const dependencyInfo = createLuaLibModuleInfo(transpiledFiles);
130-
transpiledFiles.push({
131-
code: JSON.stringify(dependencyInfo, null, 2),
132-
fileName: "lualib_dependencies.json",
133-
isRawFile: true,
134-
});
135-
136-
// add lualib bundle file
137-
const bundle = createLuaLibBundle(emitHost, program, dependencyInfo);
138-
transpiledFiles.push({
139-
code: bundle,
140-
fileName: "lualib_bundle.lua",
141-
isRawFile: true,
142-
});
129+
transpiledFiles.push(...generateExtraLualibFiles(emitHost, program, transpiledFiles));
143130
}
144131

145132
options.noEmit = oldNoEmit;

0 commit comments

Comments
 (0)