@grey-ts/transpiler 1.4.2 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +91 -76
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import * as fs3 from "node:fs";
|
|
5
|
-
import
|
|
5
|
+
import path6 from "node:path";
|
|
6
6
|
|
|
7
7
|
// src/transpiler.ts
|
|
8
8
|
import * as fs2 from "node:fs";
|
|
9
|
-
import * as
|
|
9
|
+
import * as path5 from "node:path";
|
|
10
10
|
import ts14 from "typescript";
|
|
11
11
|
|
|
12
12
|
// src/nodeHandler.ts
|
|
13
|
+
import * as path from "node:path";
|
|
13
14
|
import ts from "typescript";
|
|
14
|
-
|
|
15
15
|
class NodeHandler {
|
|
16
16
|
static handlers = new Map;
|
|
17
17
|
static transpileContext;
|
|
@@ -29,13 +29,30 @@ class NodeHandler {
|
|
|
29
29
|
}
|
|
30
30
|
try {
|
|
31
31
|
const result = handler(node, this.transpileContext);
|
|
32
|
-
|
|
32
|
+
const extra = this.transpileContext.extraOutput.get(node);
|
|
33
|
+
if (!extra)
|
|
34
|
+
return result;
|
|
35
|
+
return [
|
|
36
|
+
...extra.before ? [extra.before] : [],
|
|
37
|
+
result,
|
|
38
|
+
...extra.after ? [extra.after] : []
|
|
39
|
+
].join(`
|
|
40
|
+
`);
|
|
33
41
|
} catch (error) {
|
|
34
42
|
console.error(error);
|
|
35
43
|
this.printLineAndCol(node);
|
|
36
44
|
return ts.isBlock(node.parent) || ts.isSourceFile(node.parent) ? "" : "null";
|
|
37
45
|
}
|
|
38
46
|
}
|
|
47
|
+
static addExtraOutput(node, before, after) {
|
|
48
|
+
if (!this.transpileContext.extraOutput.has(node))
|
|
49
|
+
this.transpileContext.extraOutput.set(node, { before: "", after: "" });
|
|
50
|
+
const extra = this.transpileContext.extraOutput.get(node);
|
|
51
|
+
if (before)
|
|
52
|
+
extra.before += before;
|
|
53
|
+
if (after)
|
|
54
|
+
extra.after += after;
|
|
55
|
+
}
|
|
39
56
|
static printLineAndCol(node) {
|
|
40
57
|
const source = node.getSourceFile();
|
|
41
58
|
const lineAndChar = source.getLineAndCharacterOfPosition(node.pos);
|
|
@@ -47,6 +64,29 @@ NodeHandler.register(ts.SyntaxKind.InterfaceDeclaration, () => "");
|
|
|
47
64
|
NodeHandler.register(ts.SyntaxKind.ModuleDeclaration, () => "");
|
|
48
65
|
NodeHandler.register(ts.SyntaxKind.EndOfFileToken, () => "");
|
|
49
66
|
NodeHandler.register(ts.SyntaxKind.EmptyStatement, () => "");
|
|
67
|
+
NodeHandler.register(ts.SyntaxKind.SourceFile, (sourceFile, ctx) => {
|
|
68
|
+
if (ctx.visitedFiles.has(sourceFile.fileName))
|
|
69
|
+
return "";
|
|
70
|
+
ctx.visitedFiles.add(sourceFile.fileName);
|
|
71
|
+
if (sourceFile.isDeclarationFile)
|
|
72
|
+
return "";
|
|
73
|
+
if (program.isSourceFileDefaultLibrary(sourceFile) || program.isSourceFileFromExternalLibrary(sourceFile))
|
|
74
|
+
return "";
|
|
75
|
+
const prevFile = ctx.currentFilePath;
|
|
76
|
+
ctx.currentFilePath = sourceFile.fileName;
|
|
77
|
+
ctx.currentFolder = path.dirname(sourceFile.fileName);
|
|
78
|
+
ctx.namedImports[sourceFile.fileName] = {};
|
|
79
|
+
ctx.namespaceImports[sourceFile.fileName] = new Set;
|
|
80
|
+
sourceFile.forEachChild((node) => {
|
|
81
|
+
const result = NodeHandler.handle(node);
|
|
82
|
+
if (!result)
|
|
83
|
+
return;
|
|
84
|
+
ctx.output.push(result);
|
|
85
|
+
});
|
|
86
|
+
ctx.currentFilePath = prevFile;
|
|
87
|
+
ctx.currentFolder = path.dirname(prevFile);
|
|
88
|
+
return "";
|
|
89
|
+
});
|
|
50
90
|
|
|
51
91
|
// src/parser.ts
|
|
52
92
|
import ts2 from "typescript";
|
|
@@ -57,7 +97,7 @@ var parser_default = parseCode;
|
|
|
57
97
|
|
|
58
98
|
// src/utils.ts
|
|
59
99
|
import fs from "node:fs";
|
|
60
|
-
import
|
|
100
|
+
import path2 from "node:path";
|
|
61
101
|
import ts3 from "typescript";
|
|
62
102
|
|
|
63
103
|
// src/replaceKeywords.ts
|
|
@@ -326,7 +366,7 @@ function getSourceFiles(absPath) {
|
|
|
326
366
|
const file = filePaths.shift();
|
|
327
367
|
const stat = fs.statSync(file);
|
|
328
368
|
if (stat.isDirectory()) {
|
|
329
|
-
filePaths.push(...fs.readdirSync(file).map((name) =>
|
|
369
|
+
filePaths.push(...fs.readdirSync(file).map((name) => path2.join(file, name)));
|
|
330
370
|
continue;
|
|
331
371
|
}
|
|
332
372
|
const existing = program.getSourceFile(file);
|
|
@@ -376,8 +416,8 @@ function replacePropertyAccess(original, symbol) {
|
|
|
376
416
|
return replaceValue;
|
|
377
417
|
}
|
|
378
418
|
function findProjectRoot(dir, fileToSearch = "package.json") {
|
|
379
|
-
while (!fs.existsSync(
|
|
380
|
-
const parent =
|
|
419
|
+
while (!fs.existsSync(path2.join(dir, fileToSearch))) {
|
|
420
|
+
const parent = path2.dirname(dir);
|
|
381
421
|
if (parent === dir)
|
|
382
422
|
throw new Error(`No ${fileToSearch} found`);
|
|
383
423
|
dir = parent;
|
|
@@ -441,6 +481,8 @@ NodeHandler.register(ts5.SyntaxKind.ClassDeclaration, (node) => {
|
|
|
441
481
|
for (const member of node.members) {
|
|
442
482
|
if (ts5.isFunctionLike(member) && "body" in member && !member.body)
|
|
443
483
|
continue;
|
|
484
|
+
if (ts5.isSemicolonClassElement(member))
|
|
485
|
+
continue;
|
|
444
486
|
if (member.name) {
|
|
445
487
|
const memberName = NodeHandler.handle(member.name);
|
|
446
488
|
if (declaredNames.has(memberName))
|
|
@@ -518,7 +560,7 @@ end function`;
|
|
|
518
560
|
import ts7 from "typescript";
|
|
519
561
|
|
|
520
562
|
// src/call_transformers/callTransformer.ts
|
|
521
|
-
import
|
|
563
|
+
import path3 from "node:path";
|
|
522
564
|
import ts6 from "typescript";
|
|
523
565
|
class CallTransformer {
|
|
524
566
|
static handlers = new Map;
|
|
@@ -555,10 +597,10 @@ CallTransformer.register("GreyHack.include", (name, args, node, ctx) => {
|
|
|
555
597
|
const fileArg = node.arguments[0];
|
|
556
598
|
if (!ts6.isStringLiteralLike(fileArg))
|
|
557
599
|
throw "You can't include variables";
|
|
558
|
-
const absPath =
|
|
600
|
+
const absPath = path3.resolve(ctx.currentFolder, fileArg.text);
|
|
559
601
|
const sources = getSourceFiles(absPath);
|
|
560
602
|
for (const source of sources) {
|
|
561
|
-
|
|
603
|
+
NodeHandler.handle(source);
|
|
562
604
|
}
|
|
563
605
|
return "";
|
|
564
606
|
});
|
|
@@ -678,7 +720,7 @@ NodeHandler.register(ts7.SyntaxKind.CallExpression, (node, ctx) => {
|
|
|
678
720
|
const transformed = CallTransformer.handle(symbolFullName, name, args, node, ctx);
|
|
679
721
|
if (transformed !== null)
|
|
680
722
|
return transformed;
|
|
681
|
-
if (!args.length)
|
|
723
|
+
if (!args.length && !ts7.isParenthesizedExpression(node.expression))
|
|
682
724
|
return name;
|
|
683
725
|
return `${name}(${args.join(", ")})`;
|
|
684
726
|
});
|
|
@@ -702,7 +744,7 @@ function shouldHaveOuterPrefix(node, operator) {
|
|
|
702
744
|
const leftSymbol = checker.getSymbolAtLocation(node.left);
|
|
703
745
|
if (!leftSymbol?.valueDeclaration)
|
|
704
746
|
return false;
|
|
705
|
-
return leftSymbol.valueDeclaration.
|
|
747
|
+
return leftSymbol.valueDeclaration.end < functionAncestor.pos || leftSymbol.valueDeclaration.pos > functionAncestor.end;
|
|
706
748
|
}
|
|
707
749
|
function isAssignmentChain(node, operator) {
|
|
708
750
|
if (!assignmentOperators.has(operator))
|
|
@@ -904,10 +946,10 @@ NodeHandler.register(ts8.SyntaxKind.Block, (node) => {
|
|
|
904
946
|
const output = node.statements.map((val) => {
|
|
905
947
|
let statement = NodeHandler.handle(val);
|
|
906
948
|
statement = statement.split(`
|
|
907
|
-
`).map((line) => "\t" + line).join(`
|
|
949
|
+
`).filter((s) => !!s).map((line) => "\t" + line).join(`
|
|
908
950
|
`);
|
|
909
951
|
return statement;
|
|
910
|
-
}).join(`
|
|
952
|
+
}).filter((s) => !!s).join(`
|
|
911
953
|
`);
|
|
912
954
|
return output;
|
|
913
955
|
});
|
|
@@ -926,7 +968,13 @@ NodeHandler.register(ts8.SyntaxKind.ArrowFunction, (node) => {
|
|
|
926
968
|
const params = node.parameters.map((param) => NodeHandler.handle(param));
|
|
927
969
|
const body = ts8.isBlock(node.body) ? NodeHandler.handle(node.body) : ` return ${NodeHandler.handle(node.body)}`;
|
|
928
970
|
if (ts8.isCallOrNewExpression(node.parent) || ts8.isParenthesizedExpression(node.parent)) {
|
|
929
|
-
|
|
971
|
+
const mainNode = ts8.findAncestor(node.parent, (n) => n.parent && (ts8.isBlock(n.parent) || ts8.isSourceFile(n.parent)));
|
|
972
|
+
if (!mainNode) {
|
|
973
|
+
return "@" + createAnonFunction(body, params).name;
|
|
974
|
+
}
|
|
975
|
+
const anon = createAnonFunction(body, params, false);
|
|
976
|
+
NodeHandler.addExtraOutput(mainNode, anon.str, null);
|
|
977
|
+
return "@" + anon.name;
|
|
930
978
|
}
|
|
931
979
|
if (ts8.hasOnlyExpressionInitializer(node.parent) || ts8.isBinaryExpression(node.parent) || ts8.isReturnStatement(node.parent)) {
|
|
932
980
|
return `function(${params.join(", ")})
|
|
@@ -1007,35 +1055,23 @@ NodeHandler.register(ts9.SyntaxKind.RegularExpressionLiteral, (node) => {
|
|
|
1007
1055
|
});
|
|
1008
1056
|
|
|
1009
1057
|
// src/visitors/imports.ts
|
|
1010
|
-
import
|
|
1058
|
+
import path4 from "node:path";
|
|
1011
1059
|
import ts10 from "typescript";
|
|
1012
|
-
function importFile(filePath, ctx
|
|
1013
|
-
let srcPath =
|
|
1014
|
-
if (!
|
|
1060
|
+
function importFile(filePath, ctx) {
|
|
1061
|
+
let srcPath = path4.resolve(ctx.currentFolder, filePath);
|
|
1062
|
+
if (!path4.extname(srcPath))
|
|
1015
1063
|
srcPath += ".ts";
|
|
1016
1064
|
const source = program.getSourceFile(srcPath);
|
|
1017
1065
|
if (!source) {
|
|
1018
1066
|
console.error(`Failed to find source ${srcPath}`);
|
|
1019
1067
|
return "";
|
|
1020
1068
|
}
|
|
1021
|
-
return
|
|
1069
|
+
return NodeHandler.handle(source);
|
|
1022
1070
|
}
|
|
1023
1071
|
NodeHandler.register(ts10.SyntaxKind.ImportDeclaration, (node, ctx) => {
|
|
1024
1072
|
if (!node.importClause) {
|
|
1025
1073
|
const moduleName = node.moduleSpecifier.text;
|
|
1026
|
-
|
|
1027
|
-
if (!transpiledFile)
|
|
1028
|
-
return "";
|
|
1029
|
-
const rndName = "func_" + (Date.now() * Math.random()).toString().slice(0, 6);
|
|
1030
|
-
return [
|
|
1031
|
-
`${rndName} = function`,
|
|
1032
|
-
transpiledFile.split(`
|
|
1033
|
-
`).map((line) => "\t" + line).join(`
|
|
1034
|
-
`),
|
|
1035
|
-
"end function",
|
|
1036
|
-
`${rndName}()`
|
|
1037
|
-
].join(`
|
|
1038
|
-
`);
|
|
1074
|
+
return importFile(moduleName, ctx);
|
|
1039
1075
|
}
|
|
1040
1076
|
if (node.importClause.phaseModifier)
|
|
1041
1077
|
return "";
|
|
@@ -1756,27 +1792,34 @@ end function`,
|
|
|
1756
1792
|
return when_false
|
|
1757
1793
|
end function`
|
|
1758
1794
|
};
|
|
1759
|
-
|
|
1795
|
+
var anonFunctionsCreated = 0;
|
|
1796
|
+
function createAnonFunction(body, params, insertToUtils = true) {
|
|
1760
1797
|
const defaultParams = new Array(3).fill(0).map((_, i) => `param${i}`);
|
|
1761
|
-
const nextName = `func_${
|
|
1798
|
+
const nextName = `func_${anonFunctionsCreated}`;
|
|
1762
1799
|
const paramString = Object.assign(defaultParams, params).join(",");
|
|
1763
1800
|
const result = `${nextName} = function(${paramString})
|
|
1764
1801
|
${body}
|
|
1765
1802
|
end function`;
|
|
1766
|
-
|
|
1803
|
+
anonFunctionsCreated++;
|
|
1804
|
+
if (insertToUtils)
|
|
1805
|
+
utilitiesToInsert.set(nextName, result);
|
|
1767
1806
|
return { name: nextName, str: result };
|
|
1768
1807
|
}
|
|
1769
|
-
function
|
|
1770
|
-
|
|
1771
|
-
currentFolder:
|
|
1772
|
-
currentFilePath:
|
|
1808
|
+
function createContext(currentFileName = "file.ts") {
|
|
1809
|
+
return {
|
|
1810
|
+
currentFolder: process.cwd(),
|
|
1811
|
+
currentFilePath: path5.resolve(process.cwd(), currentFileName),
|
|
1773
1812
|
namedImports: {},
|
|
1774
1813
|
namespaceImports: {},
|
|
1775
|
-
visitedFiles:
|
|
1776
|
-
output: []
|
|
1814
|
+
visitedFiles: new Set,
|
|
1815
|
+
output: [],
|
|
1816
|
+
extraOutput: new Map
|
|
1777
1817
|
};
|
|
1818
|
+
}
|
|
1819
|
+
function transpileProgram(entryFileRelativePath) {
|
|
1820
|
+
const ctx = createContext(entryFileRelativePath);
|
|
1778
1821
|
NodeHandler.transpileContext = ctx;
|
|
1779
|
-
ctx.currentFolder =
|
|
1822
|
+
ctx.currentFolder = path5.dirname(ctx.currentFilePath);
|
|
1780
1823
|
if (!fs2.existsSync(ctx.currentFilePath)) {
|
|
1781
1824
|
console.error(`Error: file '${ctx.currentFilePath}' doesn't exist`);
|
|
1782
1825
|
process.exit(1);
|
|
@@ -1784,7 +1827,7 @@ function transpileProgram(entryFileRelativePath) {
|
|
|
1784
1827
|
let start = Date.now();
|
|
1785
1828
|
const tsconfigPath = findProjectRoot(process.cwd(), "tsconfig.json") + "/tsconfig.json";
|
|
1786
1829
|
const res = ts14.readConfigFile(tsconfigPath, ts14.sys.readFile);
|
|
1787
|
-
const parsed = ts14.parseJsonConfigFileContent(res.config, ts14.sys,
|
|
1830
|
+
const parsed = ts14.parseJsonConfigFileContent(res.config, ts14.sys, path5.dirname(tsconfigPath));
|
|
1788
1831
|
if (!parsed.options.types)
|
|
1789
1832
|
parsed.options.types = [];
|
|
1790
1833
|
if (!parsed.options.types.includes("@grey-ts/types")) {
|
|
@@ -1803,7 +1846,7 @@ function transpileProgram(entryFileRelativePath) {
|
|
|
1803
1846
|
console.error(`Error: failed to find '${ctx.currentFilePath}' from the included sources`);
|
|
1804
1847
|
process.exit(1);
|
|
1805
1848
|
}
|
|
1806
|
-
|
|
1849
|
+
NodeHandler.handle(entry);
|
|
1807
1850
|
if (utilitiesToInsert.size) {
|
|
1808
1851
|
ctx.output.unshift(...utilitiesToInsert.values());
|
|
1809
1852
|
utilitiesToInsert.clear();
|
|
@@ -1811,34 +1854,6 @@ function transpileProgram(entryFileRelativePath) {
|
|
|
1811
1854
|
console.log(`Transpiling took ${Date.now() - start} ms`);
|
|
1812
1855
|
return ctx.output;
|
|
1813
1856
|
}
|
|
1814
|
-
function transpileSourceFile(sourceFile, ctx, returnResult) {
|
|
1815
|
-
if (ctx.visitedFiles[sourceFile.fileName])
|
|
1816
|
-
return "";
|
|
1817
|
-
ctx.visitedFiles[sourceFile.fileName] = true;
|
|
1818
|
-
if (sourceFile.isDeclarationFile)
|
|
1819
|
-
return "";
|
|
1820
|
-
if (program.isSourceFileDefaultLibrary(sourceFile) || program.isSourceFileFromExternalLibrary(sourceFile))
|
|
1821
|
-
return "";
|
|
1822
|
-
const prevFile = ctx.currentFilePath;
|
|
1823
|
-
ctx.currentFilePath = sourceFile.fileName;
|
|
1824
|
-
ctx.currentFolder = path4.dirname(sourceFile.fileName);
|
|
1825
|
-
ctx.namedImports[sourceFile.fileName] = {};
|
|
1826
|
-
ctx.namespaceImports[sourceFile.fileName] = new Set;
|
|
1827
|
-
const output = [];
|
|
1828
|
-
sourceFile.forEachChild((node) => {
|
|
1829
|
-
const result = NodeHandler.handle(node);
|
|
1830
|
-
if (!result)
|
|
1831
|
-
return;
|
|
1832
|
-
if (!returnResult)
|
|
1833
|
-
ctx.output.push(result);
|
|
1834
|
-
else
|
|
1835
|
-
output.push(result);
|
|
1836
|
-
});
|
|
1837
|
-
ctx.currentFilePath = prevFile;
|
|
1838
|
-
ctx.currentFolder = path4.dirname(prevFile);
|
|
1839
|
-
return output.join(`
|
|
1840
|
-
`);
|
|
1841
|
-
}
|
|
1842
1857
|
|
|
1843
1858
|
// src/index.ts
|
|
1844
1859
|
var noMoreFlags = false;
|
|
@@ -1870,7 +1885,7 @@ function createOutputFile(fileIndex, basename, content) {
|
|
|
1870
1885
|
if (fileIndex > 0)
|
|
1871
1886
|
basename = `${basename}-${fileIndex}`;
|
|
1872
1887
|
const outFileName = args.length > 1 ? args[1] : `${basename}.src`;
|
|
1873
|
-
const outFilePath =
|
|
1888
|
+
const outFilePath = path6.join(outDirPath, outFileName);
|
|
1874
1889
|
fs3.writeFileSync(outFilePath, content);
|
|
1875
1890
|
}
|
|
1876
1891
|
if (command === "transpile") {
|
|
@@ -1879,7 +1894,7 @@ if (command === "transpile") {
|
|
|
1879
1894
|
process.exit(2);
|
|
1880
1895
|
}
|
|
1881
1896
|
const entryFile = args[0];
|
|
1882
|
-
const basename =
|
|
1897
|
+
const basename = path6.basename(entryFile, ".ts");
|
|
1883
1898
|
const transpiledStatements = transpileProgram(entryFile);
|
|
1884
1899
|
if (flags.includes("--print") || flags.includes("-p")) {
|
|
1885
1900
|
console.log(transpiledStatements.join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@grey-ts/transpiler",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "Transpiles TypeScript into GreyScript",
|
|
5
5
|
"author": "Okka",
|
|
6
6
|
"module": "src/index.ts",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
],
|
|
32
32
|
"scripts": {
|
|
33
33
|
"prepare": "bun run build",
|
|
34
|
-
"build": "bun run scripts/build.ts"
|
|
34
|
+
"build": "bun test --only-failures && bun run scripts/build.ts"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/bun": "latest",
|