Skip to content

Commit 105ff7b

Browse files
ark120202Perryvw
authored andcommitted
Move transpilation-related code to a subdirectory (#760)
* Move transpilation-related code to a subdirectory * Move `lualib_bundle` loading to `LuaLib.ts`
1 parent 45ea013 commit 105ff7b

File tree

12 files changed

+146
-137
lines changed

12 files changed

+146
-137
lines changed

src/LuaLib.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as path from "path";
2-
import { EmitHost } from "./Transpile";
2+
import { EmitHost } from "./transpilation";
33

44
export enum LuaLibFeature {
55
ArrayConcat = "ArrayConcat",
@@ -95,12 +95,12 @@ export function loadLuaLibFeatures(features: Iterable<LuaLibFeature>, emitHost:
9595
dependencies.forEach(load);
9696
}
9797

98-
const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`);
99-
const luaLibFeature = emitHost.readFile(featureFile);
98+
const featurePath = path.resolve(__dirname, `../dist/lualib/${feature}.lua`);
99+
const luaLibFeature = emitHost.readFile(featurePath);
100100
if (luaLibFeature !== undefined) {
101101
result += luaLibFeature + "\n";
102102
} else {
103-
throw new Error(`Could not read lualib feature ../dist/lualib/${feature}.lua`);
103+
throw new Error(`Could not load lualib feature from '${featurePath}'`);
104104
}
105105
}
106106

@@ -110,3 +110,18 @@ export function loadLuaLibFeatures(features: Iterable<LuaLibFeature>, emitHost:
110110

111111
return result;
112112
}
113+
114+
let luaLibBundleContent: string;
115+
export function getLuaLibBundle(emitHost: EmitHost): string {
116+
if (luaLibBundleContent === undefined) {
117+
const lualibPath = path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua");
118+
const result = emitHost.readFile(lualibPath);
119+
if (result !== undefined) {
120+
luaLibBundleContent = result;
121+
} else {
122+
throw new Error(`Could not load lualib bundle from '${lualibPath}'`);
123+
}
124+
}
125+
126+
return luaLibBundleContent;
127+
}

src/LuaPrinter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions";
55
import * as lua from "./LuaAST";
66
import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib";
77
import { isValidLuaIdentifier, luaKeywords } from "./transformation/utils/safe-names";
8-
import { EmitHost } from "./Transpile";
8+
import { EmitHost } from "./transpilation";
99
import { trimExtension } from "./utils";
1010

1111
// https://www.lua.org/pil/2.4.html

src/NoImplicitSelfTransformer.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/index.ts

Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,10 @@
1-
import * as fs from "fs";
2-
import * as path from "path";
3-
import * as ts from "typescript";
4-
import { parseConfigFileWithSystem } from "./cli/tsconfig";
5-
import { CompilerOptions } from "./CompilerOptions";
6-
import { emitTranspiledFiles, OutputFile } from "./Emit";
7-
import { transpile, TranspiledFile, TranspileResult } from "./Transpile";
8-
91
export { version } from "./cli/information";
102
export { parseCommandLine, ParsedCommandLine, updateParsedConfigFile } from "./cli/parse";
113
export * from "./cli/report";
124
export * from "./CompilerOptions";
13-
export * from "./Emit";
145
export * from "./LuaAST";
156
export { LuaLibFeature } from "./LuaLib";
167
export * from "./LuaPrinter";
178
export * from "./transformation/context";
189
export { TranspileError } from "./transformation/utils/errors";
19-
export * from "./Transpile";
20-
21-
export interface TranspileFilesResult {
22-
diagnostics: ts.Diagnostic[];
23-
emitResult: OutputFile[];
24-
}
25-
26-
export function transpileFiles(rootNames: string[], options: CompilerOptions = {}): TranspileFilesResult {
27-
const program = ts.createProgram(rootNames, options);
28-
const { transpiledFiles, diagnostics: transpileDiagnostics } = transpile({ program });
29-
const emitResult = emitTranspiledFiles(program, transpiledFiles);
30-
31-
const diagnostics = ts.sortAndDeduplicateDiagnostics([
32-
...ts.getPreEmitDiagnostics(program),
33-
...transpileDiagnostics,
34-
]);
35-
36-
return { diagnostics: [...diagnostics], emitResult };
37-
}
38-
39-
export function transpileProject(configFileName: string, optionsToExtend?: CompilerOptions): TranspileFilesResult {
40-
const parseResult = parseConfigFileWithSystem(configFileName, optionsToExtend);
41-
if (parseResult.errors.length > 0) {
42-
return { diagnostics: parseResult.errors, emitResult: [] };
43-
}
44-
45-
return transpileFiles(parseResult.fileNames, parseResult.options);
46-
}
47-
48-
const libCache: { [key: string]: ts.SourceFile } = {};
49-
50-
/** @internal */
51-
export function createVirtualProgram(input: Record<string, string>, options: CompilerOptions = {}): ts.Program {
52-
const compilerHost: ts.CompilerHost = {
53-
fileExists: () => true,
54-
getCanonicalFileName: fileName => fileName,
55-
getCurrentDirectory: () => "",
56-
getDefaultLibFileName: ts.getDefaultLibFileName,
57-
readFile: () => "",
58-
getNewLine: () => "\n",
59-
useCaseSensitiveFileNames: () => false,
60-
writeFile: () => {},
61-
62-
getSourceFile: filename => {
63-
if (filename in input) {
64-
return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false);
65-
}
66-
67-
if (filename.startsWith("lib.")) {
68-
if (libCache[filename]) return libCache[filename];
69-
const typeScriptDir = path.dirname(require.resolve("typescript"));
70-
const filePath = path.join(typeScriptDir, filename);
71-
const content = fs.readFileSync(filePath, "utf8");
72-
73-
libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false);
74-
75-
return libCache[filename];
76-
}
77-
},
78-
};
79-
80-
return ts.createProgram(Object.keys(input), options, compilerHost);
81-
}
82-
83-
export function transpileVirtualProject(files: Record<string, string>, options: CompilerOptions = {}): TranspileResult {
84-
const program = createVirtualProgram(files, options);
85-
const result = transpile({ program });
86-
const diagnostics = ts.sortAndDeduplicateDiagnostics([...ts.getPreEmitDiagnostics(program), ...result.diagnostics]);
87-
88-
return { ...result, diagnostics: [...diagnostics] };
89-
}
90-
91-
export interface TranspileStringResult {
92-
diagnostics: ts.Diagnostic[];
93-
file?: TranspiledFile;
94-
}
95-
96-
export function transpileString(main: string, options: CompilerOptions = {}): TranspileStringResult {
97-
const { diagnostics, transpiledFiles } = transpileVirtualProject({ "main.ts": main }, options);
98-
return { diagnostics, file: transpiledFiles.find(({ fileName }) => fileName === "main.ts") };
99-
}
10+
export * from "./transpilation";

src/bundle.ts renamed to src/transpilation/bundle.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import * as path from "path";
22
import { SourceNode } from "source-map";
33
import * as ts from "typescript";
4-
import { CompilerOptions } from "./CompilerOptions";
4+
import { CompilerOptions } from "../CompilerOptions";
5+
import { getLuaLibBundle } from "../LuaLib";
6+
import { escapeString } from "../LuaPrinter";
7+
import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils";
58
import { couldNotFindBundleEntryPoint } from "./diagnostics";
6-
import { escapeString } from "./LuaPrinter";
7-
import { EmitHost, TranspiledFile } from "./Transpile";
8-
import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "./utils";
9+
import { EmitHost, TranspiledFile } from "./transpile";
910

1011
const createModulePath = (baseDir: string, pathToResolve: string) =>
1112
escapeString(formatPathToLuaPath(trimExtension(path.relative(baseDir, pathToResolve))));
@@ -43,8 +44,7 @@ export function bundleTranspiledFiles(
4344
// If any of the modules contains a require for lualib_bundle, add it to the module table.
4445
const lualibRequired = transpiledFiles.some(f => f.lua?.includes(`require("lualib_bundle")`));
4546
if (lualibRequired) {
46-
const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"));
47-
moduleTableEntries.push(`["lualib_bundle"] = function() ${lualibBundle} end,\n`);
47+
moduleTableEntries.push(`["lualib_bundle"] = function() ${getLuaLibBundle(emitHost)} end,\n`);
4848
}
4949

5050
// Create ____modules table containing all entries from moduleTableEntries

src/Emit.ts renamed to src/transpilation/emit.ts

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import * as path from "path";
22
import * as ts from "typescript";
3-
import { LuaLibImportKind } from "./CompilerOptions";
4-
import { EmitHost, TranspiledFile } from "./Transpile";
5-
import { normalizeSlashes, trimExtension } from "./utils";
3+
import { LuaLibImportKind } from "../CompilerOptions";
4+
import { getLuaLibBundle } from "../LuaLib";
5+
import { normalizeSlashes, trimExtension } from "../utils";
6+
import { EmitHost, TranspiledFile } from "./transpile";
67

78
export interface OutputFile {
89
name: string;
910
text: string;
1011
}
1112

12-
let lualibContent: string;
1313
export function emitTranspiledFiles(
1414
program: ts.Program,
1515
transpiledFiles: TranspiledFile[],
@@ -56,21 +56,12 @@ export function emitTranspiledFiles(
5656
) {
5757
const lualibRequired = files.some(f => f.text?.includes(`require("lualib_bundle")`));
5858
if (lualibRequired) {
59-
if (lualibContent === undefined) {
60-
const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"));
61-
if (lualibBundle !== undefined) {
62-
lualibContent = lualibBundle;
63-
} else {
64-
throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua");
65-
}
66-
}
67-
6859
let outPath = path.resolve(rootDir, "lualib_bundle.lua");
6960
if (outDir !== rootDir) {
7061
outPath = path.join(outDir, path.relative(rootDir, outPath));
7162
}
7263

73-
files.push({ name: normalizeSlashes(outPath), text: lualibContent });
64+
files.push({ name: normalizeSlashes(outPath), text: getLuaLibBundle(emitHost) });
7465
}
7566
}
7667

src/transpilation/index.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import * as fs from "fs";
2+
import * as path from "path";
3+
import * as ts from "typescript";
4+
import { parseConfigFileWithSystem } from "../cli/tsconfig";
5+
import { CompilerOptions } from "../CompilerOptions";
6+
import { emitTranspiledFiles, OutputFile } from "./emit";
7+
import { transpile, TranspiledFile, TranspileResult } from "./transpile";
8+
9+
export * from "./emit";
10+
export * from "./transpile";
11+
12+
export interface TranspileFilesResult {
13+
diagnostics: ts.Diagnostic[];
14+
emitResult: OutputFile[];
15+
}
16+
17+
export function transpileFiles(rootNames: string[], options: CompilerOptions = {}): TranspileFilesResult {
18+
const program = ts.createProgram(rootNames, options);
19+
const { transpiledFiles, diagnostics: transpileDiagnostics } = transpile({ program });
20+
const emitResult = emitTranspiledFiles(program, transpiledFiles);
21+
22+
const diagnostics = ts.sortAndDeduplicateDiagnostics([
23+
...ts.getPreEmitDiagnostics(program),
24+
...transpileDiagnostics,
25+
]);
26+
27+
return { diagnostics: [...diagnostics], emitResult };
28+
}
29+
30+
export function transpileProject(configFileName: string, optionsToExtend?: CompilerOptions): TranspileFilesResult {
31+
const parseResult = parseConfigFileWithSystem(configFileName, optionsToExtend);
32+
if (parseResult.errors.length > 0) {
33+
return { diagnostics: parseResult.errors, emitResult: [] };
34+
}
35+
36+
return transpileFiles(parseResult.fileNames, parseResult.options);
37+
}
38+
39+
const libCache: { [key: string]: ts.SourceFile } = {};
40+
41+
/** @internal */
42+
export function createVirtualProgram(input: Record<string, string>, options: CompilerOptions = {}): ts.Program {
43+
const compilerHost: ts.CompilerHost = {
44+
fileExists: () => true,
45+
getCanonicalFileName: fileName => fileName,
46+
getCurrentDirectory: () => "",
47+
getDefaultLibFileName: ts.getDefaultLibFileName,
48+
readFile: () => "",
49+
getNewLine: () => "\n",
50+
useCaseSensitiveFileNames: () => false,
51+
writeFile: () => {},
52+
53+
getSourceFile: filename => {
54+
if (filename in input) {
55+
return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false);
56+
}
57+
58+
if (filename.startsWith("lib.")) {
59+
if (libCache[filename]) return libCache[filename];
60+
const typeScriptDir = path.dirname(require.resolve("typescript"));
61+
const filePath = path.join(typeScriptDir, filename);
62+
const content = fs.readFileSync(filePath, "utf8");
63+
64+
libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false);
65+
66+
return libCache[filename];
67+
}
68+
},
69+
};
70+
71+
return ts.createProgram(Object.keys(input), options, compilerHost);
72+
}
73+
74+
export function transpileVirtualProject(files: Record<string, string>, options: CompilerOptions = {}): TranspileResult {
75+
const program = createVirtualProgram(files, options);
76+
const result = transpile({ program });
77+
const diagnostics = ts.sortAndDeduplicateDiagnostics([...ts.getPreEmitDiagnostics(program), ...result.diagnostics]);
78+
79+
return { ...result, diagnostics: [...diagnostics] };
80+
}
81+
82+
export interface TranspileStringResult {
83+
diagnostics: ts.Diagnostic[];
84+
file?: TranspiledFile;
85+
}
86+
87+
export function transpileString(main: string, options: CompilerOptions = {}): TranspileStringResult {
88+
const { diagnostics, transpiledFiles } = transpileVirtualProject({ "main.ts": main }, options);
89+
return { diagnostics, file: transpiledFiles.find(({ fileName }) => fileName === "main.ts") };
90+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as ts from "typescript";
2-
import { Printer } from "./LuaPrinter";
3-
import { Visitors } from "./transformation/context";
2+
import { Printer } from "../LuaPrinter";
3+
import { Visitors } from "../transformation/context";
44

55
export interface Plugin {
66
/**
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
import * as path from "path";
22
import * as resolve from "resolve";
33
import * as ts from "typescript";
4-
import * as cliDiagnostics from "./cli/diagnostics";
5-
import { CompilerOptions, TransformerImport } from "./CompilerOptions";
4+
// TODO: Don't depend on CLI?
5+
import * as cliDiagnostics from "../cli/diagnostics";
6+
import { CompilerOptions, TransformerImport } from "../CompilerOptions";
67
import * as diagnosticFactories from "./diagnostics";
7-
import { noImplicitSelfTransformer } from "./NoImplicitSelfTransformer";
8+
9+
export const noImplicitSelfTransformer: ts.TransformerFactory<ts.SourceFile | ts.Bundle> = () => node => {
10+
const transformSourceFile: ts.Transformer<ts.SourceFile> = node => {
11+
const empty = ts.createNotEmittedStatement(undefined!);
12+
ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true);
13+
return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile);
14+
};
15+
16+
return ts.isBundle(node)
17+
? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile))
18+
: transformSourceFile(node);
19+
};
820

921
export function getCustomTransformers(
1022
program: ts.Program,

0 commit comments

Comments
 (0)