@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.
Files changed (2) hide show
  1. package/dist/index.js +91 -76
  2. 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 path5 from "node:path";
5
+ import path6 from "node:path";
6
6
 
7
7
  // src/transpiler.ts
8
8
  import * as fs2 from "node:fs";
9
- import * as path4 from "node:path";
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
- return result;
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 path from "node:path";
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) => path.join(file, 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(path.join(dir, fileToSearch))) {
380
- const parent = path.dirname(dir);
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 path2 from "node:path";
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 = path2.resolve(ctx.currentFolder, fileArg.text);
600
+ const absPath = path3.resolve(ctx.currentFolder, fileArg.text);
559
601
  const sources = getSourceFiles(absPath);
560
602
  for (const source of sources) {
561
- transpileSourceFile(source, ctx);
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.pos < functionAncestor.pos || leftSymbol.valueDeclaration.pos > functionAncestor.end;
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
- return "@" + createAnonFunction(body, params).name;
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 path3 from "node:path";
1058
+ import path4 from "node:path";
1011
1059
  import ts10 from "typescript";
1012
- function importFile(filePath, ctx, returnResult) {
1013
- let srcPath = path3.resolve(ctx.currentFolder, filePath);
1014
- if (!path3.extname(srcPath))
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 transpileSourceFile(source, ctx, returnResult);
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
- const transpiledFile = importFile(moduleName, ctx, true);
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
- function createAnonFunction(body, params) {
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_${utilitiesToInsert.size}`;
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
- utilitiesToInsert.set(nextName, result);
1803
+ anonFunctionsCreated++;
1804
+ if (insertToUtils)
1805
+ utilitiesToInsert.set(nextName, result);
1767
1806
  return { name: nextName, str: result };
1768
1807
  }
1769
- function transpileProgram(entryFileRelativePath) {
1770
- const ctx = {
1771
- currentFolder: "",
1772
- currentFilePath: path4.resolve(process.cwd(), entryFileRelativePath),
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 = path4.dirname(ctx.currentFilePath);
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, path4.dirname(tsconfigPath));
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
- transpileSourceFile(entry, ctx);
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 = path5.join(outDirPath, outFileName);
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 = path5.basename(entryFile, ".ts");
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.2",
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",