From 289933a46813630ca248f340d4527a4da9869374 Mon Sep 17 00:00:00 2001 From: "T.T" <7117978+ttodua@users.noreply.github.com> Date: Fri, 19 Jun 2026 09:13:41 +0400 Subject: [PATCH 1/5] manual --- README.md | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/README.md b/README.md index 422677f6..b4c6e59d 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,129 @@ Warning: Under active development so can change at any time! We will try to add more features/conversions in the future but this process is also customizable, check the Overrides section. +## 📚 Supported Methods & Operators + +Below is a detailed reference of the TypeScript constructs that the transpiler is able to convert (derived from `baseTranspiler.ts` and the language specific transpilers such as `pythonTranspiler.ts`). The Python column shows the resulting conversion as an example. + +### Language Constructs / Statements +These TypeScript AST nodes are handled by `printNode`: + +| Construct | Notes | +| --- | --- | +| Variable declarations | `const`/`let`/`var` declaration lists | +| Function declarations | function declarations, function expressions and arrow functions | +| Class declarations | including `extends` (single level heritage) | +| Method declarations | including access modifiers (`public`/`private`/`static`) | +| Constructor declarations | mapped to the target constructor (e.g. `__init__` + `super().__init__`) | +| Property declarations | class properties with/without initializer | +| `if` / `else if` / `else` | conditional statements | +| `for` loops | C-style `for` loop (Python converts to `range`) | +| `while` loops | | +| `break` / `continue` | loop control statements | +| `return` statements | | +| `throw` statements | mapped to `raise` in Python | +| `try` / `catch` | mapped to `try` / `except` | +| `new` expressions | object instantiation | +| `await` expressions | async support (configurable) | +| Conditional (ternary) expressions | `cond ? a : b` | +| `as` expressions | type cast (stripped where not needed) | +| `delete` expressions | mapped to `del` in Python | +| `instanceof` expressions | mapped to `isinstance(...)` in Python | +| `typeof` expressions | mapped to `isinstance(...)` checks (Python) | +| Object literal expressions | object/dictionary literals | +| Array literal expressions | | +| Property assignments | inside object literals | +| Property access expressions | `a.b` (with replacements) | +| Element access expressions | `a["b"]` / `a[0]` | +| Array binding patterns | array destructuring `[a, b] = ...` | +| Spread elements | `...args` | +| Parenthesized expressions | | +| Identifiers | with optional snake_casing | +| String / numeric / boolean literals | | +| `this` / `super` keywords | | +| `null` / `undefined` keywords | mapped to `None` in Python | +| Comments | leading & trailing (some AST-detached comments are lost) | +| Import / Export statements | parsed and returned separately (ESM & CJS) | + +### Operators + +| Category | Operators | +| --- | --- | +| Arithmetic | `+` `-` `*` `/` `%` | +| Increment / Decrement | `++` `--` (Python: `+= 1` / `-= 1`) | +| Comparison | `<` `<=` `>` `>=` `==` `===` `!=` `!==` | +| Logical | `&&` (Python `and`), `||` (Python `or`), `!` (Python `not`) | +| Assignment | `=` `+=` | +| Membership | `in` | +| Type | `instanceof`, `typeof` | +| Unary prefix | `!` `-` | + +> Note: in languages that don't support falsy/truthy values (e.g. C#), comparisons and conditions are automatically wrapped with helper functions. + +### Built-in Function Calls +The following global/built-in calls are recognized and converted (Python examples shown): + +| TypeScript | Python | +| --- | --- | +| `console.log(x)` | `print(x)` | +| `JSON.parse(x)` | `json.loads(x)` | +| `JSON.stringify(x)` | `json.dumps(x)` | +| `Array.isArray(x)` | `isinstance(x, list)` | +| `Object.keys(x)` | `list(x.keys())` | +| `Object.values(x)` | `list(x.values())` | +| `Promise.all(x)` | `asyncio.gather(*x)` | +| `Math.floor(x)` | `int(math.floor(x))` | +| `Math.ceil(x)` | `int(math.ceil(x))` | +| `Math.round(x)` | `int(round(x))` | +| `Math.min` / `Math.max` | `min` / `max` | +| `Math.abs` / `Math.log` / `Math.pow` | `abs` / `math.log` / `math.pow` | +| `Number.isInteger(x)` | `isinstance(x, int)` | +| `Number.MAX_SAFE_INTEGER` | `float('inf')` | +| `parseInt(x)` | `int(x)` | +| `parseFloat(x)` | `float(x)` | +| `Date.now()` | `int(time.time() * 1000)` | +| `assert(x)` | `assert x` | +| `process.exit()` | `sys.exit()` | + +### String Methods + +| TypeScript | Python | +| --- | --- | +| `s.length` | `len(s)` | +| `s.toString()` | `str(s)` | +| `s.toUpperCase()` | `s.upper()` | +| `s.toLowerCase()` | `s.lower()` | +| `s.trim()` | `s.strip()` | +| `s.indexOf(x)` | `s.find(x)` | +| `s.search(x)` | `s.find(x)` | +| `s.includes(x)` | `x in s` | +| `s.startsWith(x)` | `s.startswith(x)` | +| `s.endsWith(x)` | `s.endswith(x)` | +| `s.split(x)` | `s.split(x)` | +| `s.replace(a, b)` | `s.replace(a, b)` | +| `s.replaceAll(a, b)` | `s.replace(a, b)` | +| `s.padStart(n, c)` | `s.rjust(n, c)` | +| `s.padEnd(n, c)` | `s.ljust(n, c)` | +| `s.slice(a, b)` | slicing | +| `s.toFixed(n)` | number formatting | +| `s.concat(x)` | `s + x` | + +### Array Methods + +| TypeScript | Python | +| --- | --- | +| `a.length` | `len(a)` | +| `a.push(x)` | `a.append(x)` | +| `a.pop()` | `a.pop()` | +| `a.shift()` | `a.pop(0)` | +| `a.reverse()` | `a.reverse()` | +| `a.includes(x)` | `x in a` | +| `a.indexOf(x)` | `a.find(x)` | +| `a.join(x)` | `x.join(a)` | +| `a.slice(i, j)` | slicing | + +> The exact output depends on the target language. The Python column is provided as an illustrative example; PHP and C# have their own equivalent conversions defined in their respective transpilers. + ## 🔧 Options As mentioned above, this library allows for some customization through the offered options and available overrides. From bdb741bd1d74c214a6c7c42b59e6eab04b13d579 Mon Sep 17 00:00:00 2001 From: "T.T" <7117978+ttodua@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:24:34 +0400 Subject: [PATCH 2/5] supported list --- .github/workflows/node.js.yml | 7 +- package.json | 1 + supported.md | 184 ++++++++++++++++++++++++++++++++++ 3 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 supported.md diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 855d8f7e..4959d2e5 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -5,6 +5,7 @@ on: branches: [ master ] paths-ignore: - '**/README.md' + - 'supported.md' - '**.cs' - 'examples/' - '.npmignore' @@ -37,6 +38,8 @@ jobs: run: npm run test-ci - name: Integration test run: npm run integration + - name: Generate supported.md + run: npm run generate-supported - name: Generating coverage badges if: github.ref == 'refs/heads/master' uses: jpb06/jest-badges-action@latest @@ -46,5 +49,7 @@ jobs: if: github.ref == 'refs/heads/master' uses: EndBug/add-and-commit@v9 # You can change this to use a specific version. with: - add: 'dist/ -f' + add: | + dist/ -f + supported.md message: 'Update generated files' diff --git a/package.json b/package.json index 2c120e75..df03377a 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "testv": "jest --verbose --coverage", "integration": "tsx tests/integration/test.ts", "lint": "eslint src/ --ext .ts", + "generate-supported": "node src/generate-supported-md.ts", "publishPackage": "sh publish.sh && git push && git push --tags && npm publish" }, "devDependencies": { diff --git a/supported.md b/supported.md new file mode 100644 index 00000000..2333eb25 --- /dev/null +++ b/supported.md @@ -0,0 +1,184 @@ + + +# 📚 Supported Methods & Operators + +This document is automatically generated from the transpiler source code +(`src/baseTranspiler.ts` and the language specific transpilers). It lists every +TypeScript/JavaScript construct, operator and built-in call that the transpiler +currently understands and is able to convert. + + +## Operators + +`!==`, `!=`, `!`, `%`, `&&`, `*`, `++`, `+=`, `+`, `--`, `-`, `/`, `<=`, `<`, `===`, `==`, `=`, `>=`, `>`, `in`, `||` + +## Keywords / Modifiers + +`async`, `await`, `boolean`, `number`, `private`, `public`, `static`, `string`, `void` + +## Built-in Global Functions + +These global calls are recognized and converted to each target language: + +- `Array.isArray` +- `Date.now` +- `JSON.parse` +- `JSON.stringify` +- `Math.ceil` +- `Math.floor` +- `Math.round` +- `Number.isInteger` +- `Object.keys` +- `Object.values` +- `Promise.all` + +## Built-in Instance Methods (string / array / object) + +These instance methods are recognized and converted to each target language: + +- `concat` +- `endsWith` +- `includes` +- `indexOf` +- `join` +- `padEnd` +- `padStart` +- `pop` +- `push` +- `replace` +- `replaceAll` +- `reverse` +- `search` +- `shift` +- `slice` +- `split` +- `startsWith` +- `toFixed` +- `toLowerCase` +- `toString` +- `toUpperCase` +- `trim` + +## Per-language Conversions + +The explicit replacement maps defined in each language transpiler: + +### Python + +| TypeScript | Python | +| --- | --- | +| `console.log` | `print` | +| `JSON.stringify` | `json.dumps` | +| `JSON.parse` | `json.loads` | +| `Math.log` | `math.log` | +| `Math.abs` | `abs` | +| `Math.min` | `min` | +| `Math.max` | `max` | +| `Math.ceil` | `math.ceil` | +| `Math.round` | `math.round` | +| `Math.floor` | `math.floor` | +| `Math.pow` | `math.pow` | +| `process.exit` | `sys.exit` | +| `Number.MAX_SAFE_INTEGER` | `float(\'inf\')` | +| `x.push(...)` | `x.append(...)` | +| `x.toUpperCase(...)` | `x.upper(...)` | +| `x.toLowerCase(...)` | `x.lower(...)` | +| `x.parseFloat(...)` | `x.float(...)` | +| `x.parseInt(...)` | `x.int(...)` | +| `x.indexOf(...)` | `x.find(...)` | +| `x.padEnd(...)` | `x.ljust(...)` | +| `x.padStart(...)` | `x.rjust(...)` | +| `parseInt(...)` | `int(...)` | +| `parseFloat(...)` | `float(...)` | + +### PHP + +| TypeScript | PHP | +| --- | --- | +| `Number.MAX_SAFE_INTEGER` | `PHP_INT_MAX` | +| `JSON.stringify` | `json_encode` | +| `console.log` | `var_dump` | +| `process.exit` | `exit` | +| `Math.log` | `log` | +| `Math.abs` | `abs` | +| `Math.floor` | `(int) floor` | +| `Math.ceil` | `(int) ceil` | +| `Math.round` | `(int) round` | +| `Math.pow` | `pow` | +| `Math.min` | `min` | +| `Math.max` | `max` | +| `Promise.all` | `\\React\\Promise\\all` | +| `parseFloat(...)` | `floatval(...)` | +| `parseInt(...)` | `intval(...)` | + +### C# + +| TypeScript | C# | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `Console.WriteLine` | +| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | +| `Math.min` | `Math.Min` | +| `Math.max` | `Math.Max` | +| `Math.log` | `Math.Log` | +| `Math.abs` | `Math.Abs` | +| `Math.ceil` | `Math.Ceiling` | +| `Math.round` | `Math.Round` | +| `Math.floor` | `Math.Floor` | +| `Math.pow` | `Math.Pow` | +| `Promise.all` | `Task.WhenAll` | +| `x.push(...)` | `x.Add(...)` | +| `x.indexOf(...)` | `x.IndexOf(...)` | +| `x.toUpperCase(...)` | `x.ToUpper(...)` | +| `x.toLowerCase(...)` | `x.ToLower(...)` | +| `x.toString(...)` | `x.ToString(...)` | +| `parseInt(...)` | `parseINt(...)` | +| `parseFloat(...)` | `float.Parse(...)` | + +### Go + +| TypeScript | Go | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `fmt.Println` | +| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | +| `Math.min` | `Math.Min` | +| `Math.max` | `Math.Max` | +| `Math.log` | `Math.Log` | +| `Math.abs` | `Math.Abs` | +| `Math.ceil` | `Math.Ceiling` | +| `Math.round` | `Math.Round` | +| `Math.floor` | `Math.Floor` | +| `Math.pow` | `Math.Pow` | +| `Promise.all` | `Task.WhenAll` | +| `x.push(...)` | `x.Add(...)` | +| `x.indexOf(...)` | `x.IndexOf(...)` | +| `x.toUpperCase(...)` | `x.ToUpper(...)` | +| `x.toLowerCase(...)` | `x.ToLower(...)` | +| `x.toString(...)` | `x.ToString(...)` | +| `parseInt(...)` | `parseINt(...)` | +| `parseFloat(...)` | `float.Parse(...)` | + +### Java + +| TypeScript | Java | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `System.out.println` | +| `Number.MAX_SAFE_INTEGER` | `Long.MAX_VALUE` | +| `Math.min` | `Math.min` | +| `Math.max` | `Math.max` | +| `Math.log` | `Math.log` | +| `Math.abs` | `Math.abs` | +| `Math.floor` | `Math.floor` | +| `Math.pow` | `Math.pow` | +| `parseInt(...)` | `Helpers.parseInt(...)` | +| `parseFloat(...)` | `Helpers.parseFloat(...)` | + +> ⚠️ Many of these conversions rely on type information. Make sure to annotate +> types (especially function arguments) so the transpiler can disambiguate +> (e.g. `.length` → `len`/`count`, `+` → string concat vs numeric addition). From efe213f20a732823aacbb926241aabd8edcca4fb Mon Sep 17 00:00:00 2001 From: "T.T" <7117978+ttodua@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:32:28 +0400 Subject: [PATCH 3/5] updates --- .github/workflows/node.js.yml | 3 +- README.md | 310 ++++++++++++++++++++-------------- supported.md | 184 -------------------- 3 files changed, 188 insertions(+), 309 deletions(-) delete mode 100644 supported.md diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index 4959d2e5..21bec389 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -5,7 +5,6 @@ on: branches: [ master ] paths-ignore: - '**/README.md' - - 'supported.md' - '**.cs' - 'examples/' - '.npmignore' @@ -51,5 +50,5 @@ jobs: with: add: | dist/ -f - supported.md + README.md message: 'Update generated files' diff --git a/README.md b/README.md index b4c6e59d..8bf19dec 100644 --- a/README.md +++ b/README.md @@ -155,129 +155,6 @@ Warning: Under active development so can change at any time! We will try to add more features/conversions in the future but this process is also customizable, check the Overrides section. -## 📚 Supported Methods & Operators - -Below is a detailed reference of the TypeScript constructs that the transpiler is able to convert (derived from `baseTranspiler.ts` and the language specific transpilers such as `pythonTranspiler.ts`). The Python column shows the resulting conversion as an example. - -### Language Constructs / Statements -These TypeScript AST nodes are handled by `printNode`: - -| Construct | Notes | -| --- | --- | -| Variable declarations | `const`/`let`/`var` declaration lists | -| Function declarations | function declarations, function expressions and arrow functions | -| Class declarations | including `extends` (single level heritage) | -| Method declarations | including access modifiers (`public`/`private`/`static`) | -| Constructor declarations | mapped to the target constructor (e.g. `__init__` + `super().__init__`) | -| Property declarations | class properties with/without initializer | -| `if` / `else if` / `else` | conditional statements | -| `for` loops | C-style `for` loop (Python converts to `range`) | -| `while` loops | | -| `break` / `continue` | loop control statements | -| `return` statements | | -| `throw` statements | mapped to `raise` in Python | -| `try` / `catch` | mapped to `try` / `except` | -| `new` expressions | object instantiation | -| `await` expressions | async support (configurable) | -| Conditional (ternary) expressions | `cond ? a : b` | -| `as` expressions | type cast (stripped where not needed) | -| `delete` expressions | mapped to `del` in Python | -| `instanceof` expressions | mapped to `isinstance(...)` in Python | -| `typeof` expressions | mapped to `isinstance(...)` checks (Python) | -| Object literal expressions | object/dictionary literals | -| Array literal expressions | | -| Property assignments | inside object literals | -| Property access expressions | `a.b` (with replacements) | -| Element access expressions | `a["b"]` / `a[0]` | -| Array binding patterns | array destructuring `[a, b] = ...` | -| Spread elements | `...args` | -| Parenthesized expressions | | -| Identifiers | with optional snake_casing | -| String / numeric / boolean literals | | -| `this` / `super` keywords | | -| `null` / `undefined` keywords | mapped to `None` in Python | -| Comments | leading & trailing (some AST-detached comments are lost) | -| Import / Export statements | parsed and returned separately (ESM & CJS) | - -### Operators - -| Category | Operators | -| --- | --- | -| Arithmetic | `+` `-` `*` `/` `%` | -| Increment / Decrement | `++` `--` (Python: `+= 1` / `-= 1`) | -| Comparison | `<` `<=` `>` `>=` `==` `===` `!=` `!==` | -| Logical | `&&` (Python `and`), `||` (Python `or`), `!` (Python `not`) | -| Assignment | `=` `+=` | -| Membership | `in` | -| Type | `instanceof`, `typeof` | -| Unary prefix | `!` `-` | - -> Note: in languages that don't support falsy/truthy values (e.g. C#), comparisons and conditions are automatically wrapped with helper functions. - -### Built-in Function Calls -The following global/built-in calls are recognized and converted (Python examples shown): - -| TypeScript | Python | -| --- | --- | -| `console.log(x)` | `print(x)` | -| `JSON.parse(x)` | `json.loads(x)` | -| `JSON.stringify(x)` | `json.dumps(x)` | -| `Array.isArray(x)` | `isinstance(x, list)` | -| `Object.keys(x)` | `list(x.keys())` | -| `Object.values(x)` | `list(x.values())` | -| `Promise.all(x)` | `asyncio.gather(*x)` | -| `Math.floor(x)` | `int(math.floor(x))` | -| `Math.ceil(x)` | `int(math.ceil(x))` | -| `Math.round(x)` | `int(round(x))` | -| `Math.min` / `Math.max` | `min` / `max` | -| `Math.abs` / `Math.log` / `Math.pow` | `abs` / `math.log` / `math.pow` | -| `Number.isInteger(x)` | `isinstance(x, int)` | -| `Number.MAX_SAFE_INTEGER` | `float('inf')` | -| `parseInt(x)` | `int(x)` | -| `parseFloat(x)` | `float(x)` | -| `Date.now()` | `int(time.time() * 1000)` | -| `assert(x)` | `assert x` | -| `process.exit()` | `sys.exit()` | - -### String Methods - -| TypeScript | Python | -| --- | --- | -| `s.length` | `len(s)` | -| `s.toString()` | `str(s)` | -| `s.toUpperCase()` | `s.upper()` | -| `s.toLowerCase()` | `s.lower()` | -| `s.trim()` | `s.strip()` | -| `s.indexOf(x)` | `s.find(x)` | -| `s.search(x)` | `s.find(x)` | -| `s.includes(x)` | `x in s` | -| `s.startsWith(x)` | `s.startswith(x)` | -| `s.endsWith(x)` | `s.endswith(x)` | -| `s.split(x)` | `s.split(x)` | -| `s.replace(a, b)` | `s.replace(a, b)` | -| `s.replaceAll(a, b)` | `s.replace(a, b)` | -| `s.padStart(n, c)` | `s.rjust(n, c)` | -| `s.padEnd(n, c)` | `s.ljust(n, c)` | -| `s.slice(a, b)` | slicing | -| `s.toFixed(n)` | number formatting | -| `s.concat(x)` | `s + x` | - -### Array Methods - -| TypeScript | Python | -| --- | --- | -| `a.length` | `len(a)` | -| `a.push(x)` | `a.append(x)` | -| `a.pop()` | `a.pop()` | -| `a.shift()` | `a.pop(0)` | -| `a.reverse()` | `a.reverse()` | -| `a.includes(x)` | `x in a` | -| `a.indexOf(x)` | `a.find(x)` | -| `a.join(x)` | `x.join(a)` | -| `a.slice(i, j)` | slicing | - -> The exact output depends on the target language. The Python column is provided as an illustrative example; PHP and C# have their own equivalent conversions defined in their respective transpilers. - ## 🔧 Options As mentioned above, this library allows for some customization through the offered options and available overrides. @@ -468,6 +345,193 @@ function printOutOfOrderCallExpressionIfAny(node, identation) { transpiler.pythonTranspiler.printOutOfOrderCallExpressionIfAny = printOutOfOrderCallExpressionIfAny; ``` + + + + +## 📚 Supported Methods & Operators + +Below is a detailed reference of the TypeScript constructs that the transpiler is able to convert +(derived from `src/baseTranspiler.ts` and the language specific transpilers). The Python column/notes show the resulting conversion as an example. + +## Operators + +`!==`, `!=`, `!`, `%`, `&&`, `*`, `++`, `+=`, `+`, `--`, `-`, `/`, `<=`, `<`, `===`, `==`, `=`, `>=`, `>`, `in`, `||` + +## Keywords / Modifiers + +`async`, `await`, `boolean`, `number`, `private`, `public`, `static`, `string`, `void` + +## Built-in Global Functions + +These global calls are recognized and converted to each target language: + +- `Array.isArray` +- `Date.now` +- `JSON.parse` +- `JSON.stringify` +- `Math.ceil` +- `Math.floor` +- `Math.round` +- `Number.isInteger` +- `Object.keys` +- `Object.values` +- `Promise.all` + +## Built-in Instance Methods (string / array / object) + +These instance methods are recognized and converted to each target language: + +- `concat` +- `endsWith` +- `includes` +- `indexOf` +- `join` +- `padEnd` +- `padStart` +- `pop` +- `push` +- `replace` +- `replaceAll` +- `reverse` +- `search` +- `shift` +- `slice` +- `split` +- `startsWith` +- `toFixed` +- `toLowerCase` +- `toString` +- `toUpperCase` +- `trim` + +## Per-language Conversions + +The explicit replacement maps defined in each language transpiler: + +### Python + +| TypeScript | Python | +| --- | --- | +| `console.log` | `print` | +| `JSON.stringify` | `json.dumps` | +| `JSON.parse` | `json.loads` | +| `Math.log` | `math.log` | +| `Math.abs` | `abs` | +| `Math.min` | `min` | +| `Math.max` | `max` | +| `Math.ceil` | `math.ceil` | +| `Math.round` | `math.round` | +| `Math.floor` | `math.floor` | +| `Math.pow` | `math.pow` | +| `process.exit` | `sys.exit` | +| `Number.MAX_SAFE_INTEGER` | `float(\'inf\')` | +| `x.push(...)` | `x.append(...)` | +| `x.toUpperCase(...)` | `x.upper(...)` | +| `x.toLowerCase(...)` | `x.lower(...)` | +| `x.parseFloat(...)` | `x.float(...)` | +| `x.parseInt(...)` | `x.int(...)` | +| `x.indexOf(...)` | `x.find(...)` | +| `x.padEnd(...)` | `x.ljust(...)` | +| `x.padStart(...)` | `x.rjust(...)` | +| `parseInt(...)` | `int(...)` | +| `parseFloat(...)` | `float(...)` | + +### PHP + +| TypeScript | PHP | +| --- | --- | +| `Number.MAX_SAFE_INTEGER` | `PHP_INT_MAX` | +| `JSON.stringify` | `json_encode` | +| `console.log` | `var_dump` | +| `process.exit` | `exit` | +| `Math.log` | `log` | +| `Math.abs` | `abs` | +| `Math.floor` | `(int) floor` | +| `Math.ceil` | `(int) ceil` | +| `Math.round` | `(int) round` | +| `Math.pow` | `pow` | +| `Math.min` | `min` | +| `Math.max` | `max` | +| `Promise.all` | `\\React\\Promise\\all` | +| `parseFloat(...)` | `floatval(...)` | +| `parseInt(...)` | `intval(...)` | + +### C# + +| TypeScript | C# | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `Console.WriteLine` | +| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | +| `Math.min` | `Math.Min` | +| `Math.max` | `Math.Max` | +| `Math.log` | `Math.Log` | +| `Math.abs` | `Math.Abs` | +| `Math.ceil` | `Math.Ceiling` | +| `Math.round` | `Math.Round` | +| `Math.floor` | `Math.Floor` | +| `Math.pow` | `Math.Pow` | +| `Promise.all` | `Task.WhenAll` | +| `x.push(...)` | `x.Add(...)` | +| `x.indexOf(...)` | `x.IndexOf(...)` | +| `x.toUpperCase(...)` | `x.ToUpper(...)` | +| `x.toLowerCase(...)` | `x.ToLower(...)` | +| `x.toString(...)` | `x.ToString(...)` | +| `parseInt(...)` | `parseINt(...)` | +| `parseFloat(...)` | `float.Parse(...)` | + +### Go + +| TypeScript | Go | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `fmt.Println` | +| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | +| `Math.min` | `Math.Min` | +| `Math.max` | `Math.Max` | +| `Math.log` | `Math.Log` | +| `Math.abs` | `Math.Abs` | +| `Math.ceil` | `Math.Ceiling` | +| `Math.round` | `Math.Round` | +| `Math.floor` | `Math.Floor` | +| `Math.pow` | `Math.Pow` | +| `Promise.all` | `Task.WhenAll` | +| `x.push(...)` | `x.Add(...)` | +| `x.indexOf(...)` | `x.IndexOf(...)` | +| `x.toUpperCase(...)` | `x.ToUpper(...)` | +| `x.toLowerCase(...)` | `x.ToLower(...)` | +| `x.toString(...)` | `x.ToString(...)` | +| `parseInt(...)` | `parseINt(...)` | +| `parseFloat(...)` | `float.Parse(...)` | + +### Java + +| TypeScript | Java | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `System.out.println` | +| `Number.MAX_SAFE_INTEGER` | `Long.MAX_VALUE` | +| `Math.min` | `Math.min` | +| `Math.max` | `Math.max` | +| `Math.log` | `Math.log` | +| `Math.abs` | `Math.abs` | +| `Math.floor` | `Math.floor` | +| `Math.pow` | `Math.pow` | +| `parseInt(...)` | `Helpers.parseInt(...)` | +| `parseFloat(...)` | `Helpers.parseFloat(...)` | + +> ⚠️ Many of these conversions rely on type information. Make sure to annotate +> types (especially function arguments) so the transpiler can disambiguate +> (e.g. `.length` → `len`/`count`, `+` → string concat vs numeric addition). + + + + ## Contributing Pull requests are welcome. For major changes, please open an issue first diff --git a/supported.md b/supported.md deleted file mode 100644 index 2333eb25..00000000 --- a/supported.md +++ /dev/null @@ -1,184 +0,0 @@ - - -# 📚 Supported Methods & Operators - -This document is automatically generated from the transpiler source code -(`src/baseTranspiler.ts` and the language specific transpilers). It lists every -TypeScript/JavaScript construct, operator and built-in call that the transpiler -currently understands and is able to convert. - - -## Operators - -`!==`, `!=`, `!`, `%`, `&&`, `*`, `++`, `+=`, `+`, `--`, `-`, `/`, `<=`, `<`, `===`, `==`, `=`, `>=`, `>`, `in`, `||` - -## Keywords / Modifiers - -`async`, `await`, `boolean`, `number`, `private`, `public`, `static`, `string`, `void` - -## Built-in Global Functions - -These global calls are recognized and converted to each target language: - -- `Array.isArray` -- `Date.now` -- `JSON.parse` -- `JSON.stringify` -- `Math.ceil` -- `Math.floor` -- `Math.round` -- `Number.isInteger` -- `Object.keys` -- `Object.values` -- `Promise.all` - -## Built-in Instance Methods (string / array / object) - -These instance methods are recognized and converted to each target language: - -- `concat` -- `endsWith` -- `includes` -- `indexOf` -- `join` -- `padEnd` -- `padStart` -- `pop` -- `push` -- `replace` -- `replaceAll` -- `reverse` -- `search` -- `shift` -- `slice` -- `split` -- `startsWith` -- `toFixed` -- `toLowerCase` -- `toString` -- `toUpperCase` -- `trim` - -## Per-language Conversions - -The explicit replacement maps defined in each language transpiler: - -### Python - -| TypeScript | Python | -| --- | --- | -| `console.log` | `print` | -| `JSON.stringify` | `json.dumps` | -| `JSON.parse` | `json.loads` | -| `Math.log` | `math.log` | -| `Math.abs` | `abs` | -| `Math.min` | `min` | -| `Math.max` | `max` | -| `Math.ceil` | `math.ceil` | -| `Math.round` | `math.round` | -| `Math.floor` | `math.floor` | -| `Math.pow` | `math.pow` | -| `process.exit` | `sys.exit` | -| `Number.MAX_SAFE_INTEGER` | `float(\'inf\')` | -| `x.push(...)` | `x.append(...)` | -| `x.toUpperCase(...)` | `x.upper(...)` | -| `x.toLowerCase(...)` | `x.lower(...)` | -| `x.parseFloat(...)` | `x.float(...)` | -| `x.parseInt(...)` | `x.int(...)` | -| `x.indexOf(...)` | `x.find(...)` | -| `x.padEnd(...)` | `x.ljust(...)` | -| `x.padStart(...)` | `x.rjust(...)` | -| `parseInt(...)` | `int(...)` | -| `parseFloat(...)` | `float(...)` | - -### PHP - -| TypeScript | PHP | -| --- | --- | -| `Number.MAX_SAFE_INTEGER` | `PHP_INT_MAX` | -| `JSON.stringify` | `json_encode` | -| `console.log` | `var_dump` | -| `process.exit` | `exit` | -| `Math.log` | `log` | -| `Math.abs` | `abs` | -| `Math.floor` | `(int) floor` | -| `Math.ceil` | `(int) ceil` | -| `Math.round` | `(int) round` | -| `Math.pow` | `pow` | -| `Math.min` | `min` | -| `Math.max` | `max` | -| `Promise.all` | `\\React\\Promise\\all` | -| `parseFloat(...)` | `floatval(...)` | -| `parseInt(...)` | `intval(...)` | - -### C# - -| TypeScript | C# | -| --- | --- | -| `JSON.parse` | `parseJson` | -| `console.log` | `Console.WriteLine` | -| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | -| `Math.min` | `Math.Min` | -| `Math.max` | `Math.Max` | -| `Math.log` | `Math.Log` | -| `Math.abs` | `Math.Abs` | -| `Math.ceil` | `Math.Ceiling` | -| `Math.round` | `Math.Round` | -| `Math.floor` | `Math.Floor` | -| `Math.pow` | `Math.Pow` | -| `Promise.all` | `Task.WhenAll` | -| `x.push(...)` | `x.Add(...)` | -| `x.indexOf(...)` | `x.IndexOf(...)` | -| `x.toUpperCase(...)` | `x.ToUpper(...)` | -| `x.toLowerCase(...)` | `x.ToLower(...)` | -| `x.toString(...)` | `x.ToString(...)` | -| `parseInt(...)` | `parseINt(...)` | -| `parseFloat(...)` | `float.Parse(...)` | - -### Go - -| TypeScript | Go | -| --- | --- | -| `JSON.parse` | `parseJson` | -| `console.log` | `fmt.Println` | -| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | -| `Math.min` | `Math.Min` | -| `Math.max` | `Math.Max` | -| `Math.log` | `Math.Log` | -| `Math.abs` | `Math.Abs` | -| `Math.ceil` | `Math.Ceiling` | -| `Math.round` | `Math.Round` | -| `Math.floor` | `Math.Floor` | -| `Math.pow` | `Math.Pow` | -| `Promise.all` | `Task.WhenAll` | -| `x.push(...)` | `x.Add(...)` | -| `x.indexOf(...)` | `x.IndexOf(...)` | -| `x.toUpperCase(...)` | `x.ToUpper(...)` | -| `x.toLowerCase(...)` | `x.ToLower(...)` | -| `x.toString(...)` | `x.ToString(...)` | -| `parseInt(...)` | `parseINt(...)` | -| `parseFloat(...)` | `float.Parse(...)` | - -### Java - -| TypeScript | Java | -| --- | --- | -| `JSON.parse` | `parseJson` | -| `console.log` | `System.out.println` | -| `Number.MAX_SAFE_INTEGER` | `Long.MAX_VALUE` | -| `Math.min` | `Math.min` | -| `Math.max` | `Math.max` | -| `Math.log` | `Math.log` | -| `Math.abs` | `Math.abs` | -| `Math.floor` | `Math.floor` | -| `Math.pow` | `Math.pow` | -| `parseInt(...)` | `Helpers.parseInt(...)` | -| `parseFloat(...)` | `Helpers.parseFloat(...)` | - -> ⚠️ Many of these conversions rely on type information. Make sure to annotate -> types (especially function arguments) so the transpiler can disambiguate -> (e.g. `.length` → `len`/`count`, `+` → string concat vs numeric addition). From 14350620daa3f04269fe9ea3681f5d2a1f589b20 Mon Sep 17 00:00:00 2001 From: "T.T" <7117978+ttodua@users.noreply.github.com> Date: Fri, 19 Jun 2026 12:52:24 +0400 Subject: [PATCH 4/5] updates --- README.md | 125 +------------- language-conversions.md | 123 ++++++++++++++ src/generate-supported-md.ts | 310 +++++++++++++++++++++++++++++++++++ 3 files changed, 439 insertions(+), 119 deletions(-) create mode 100644 language-conversions.md create mode 100644 src/generate-supported-md.ts diff --git a/README.md b/README.md index 8bf19dec..9d33dd0a 100644 --- a/README.md +++ b/README.md @@ -356,17 +356,17 @@ transpiler.pythonTranspiler.printOutOfOrderCallExpressionIfAny = printOutOfOrder ## 📚 Supported Methods & Operators Below is a detailed reference of the TypeScript constructs that the transpiler is able to convert -(derived from `src/baseTranspiler.ts` and the language specific transpilers). The Python column/notes show the resulting conversion as an example. +(derived from `src/baseTranspiler.ts` and the language specific transpilers). -## Operators +### Operators `!==`, `!=`, `!`, `%`, `&&`, `*`, `++`, `+=`, `+`, `--`, `-`, `/`, `<=`, `<`, `===`, `==`, `=`, `>=`, `>`, `in`, `||` -## Keywords / Modifiers +### Keywords / Modifiers `async`, `await`, `boolean`, `number`, `private`, `public`, `static`, `string`, `void` -## Built-in Global Functions +### Built-in Global Functions These global calls are recognized and converted to each target language: @@ -382,7 +382,7 @@ These global calls are recognized and converted to each target language: - `Object.values` - `Promise.all` -## Built-in Instance Methods (string / array / object) +### Built-in Instance Methods (string / array / object) These instance methods are recognized and converted to each target language: @@ -410,120 +410,7 @@ These instance methods are recognized and converted to each target language: - `trim` ## Per-language Conversions - -The explicit replacement maps defined in each language transpiler: - -### Python - -| TypeScript | Python | -| --- | --- | -| `console.log` | `print` | -| `JSON.stringify` | `json.dumps` | -| `JSON.parse` | `json.loads` | -| `Math.log` | `math.log` | -| `Math.abs` | `abs` | -| `Math.min` | `min` | -| `Math.max` | `max` | -| `Math.ceil` | `math.ceil` | -| `Math.round` | `math.round` | -| `Math.floor` | `math.floor` | -| `Math.pow` | `math.pow` | -| `process.exit` | `sys.exit` | -| `Number.MAX_SAFE_INTEGER` | `float(\'inf\')` | -| `x.push(...)` | `x.append(...)` | -| `x.toUpperCase(...)` | `x.upper(...)` | -| `x.toLowerCase(...)` | `x.lower(...)` | -| `x.parseFloat(...)` | `x.float(...)` | -| `x.parseInt(...)` | `x.int(...)` | -| `x.indexOf(...)` | `x.find(...)` | -| `x.padEnd(...)` | `x.ljust(...)` | -| `x.padStart(...)` | `x.rjust(...)` | -| `parseInt(...)` | `int(...)` | -| `parseFloat(...)` | `float(...)` | - -### PHP - -| TypeScript | PHP | -| --- | --- | -| `Number.MAX_SAFE_INTEGER` | `PHP_INT_MAX` | -| `JSON.stringify` | `json_encode` | -| `console.log` | `var_dump` | -| `process.exit` | `exit` | -| `Math.log` | `log` | -| `Math.abs` | `abs` | -| `Math.floor` | `(int) floor` | -| `Math.ceil` | `(int) ceil` | -| `Math.round` | `(int) round` | -| `Math.pow` | `pow` | -| `Math.min` | `min` | -| `Math.max` | `max` | -| `Promise.all` | `\\React\\Promise\\all` | -| `parseFloat(...)` | `floatval(...)` | -| `parseInt(...)` | `intval(...)` | - -### C# - -| TypeScript | C# | -| --- | --- | -| `JSON.parse` | `parseJson` | -| `console.log` | `Console.WriteLine` | -| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | -| `Math.min` | `Math.Min` | -| `Math.max` | `Math.Max` | -| `Math.log` | `Math.Log` | -| `Math.abs` | `Math.Abs` | -| `Math.ceil` | `Math.Ceiling` | -| `Math.round` | `Math.Round` | -| `Math.floor` | `Math.Floor` | -| `Math.pow` | `Math.Pow` | -| `Promise.all` | `Task.WhenAll` | -| `x.push(...)` | `x.Add(...)` | -| `x.indexOf(...)` | `x.IndexOf(...)` | -| `x.toUpperCase(...)` | `x.ToUpper(...)` | -| `x.toLowerCase(...)` | `x.ToLower(...)` | -| `x.toString(...)` | `x.ToString(...)` | -| `parseInt(...)` | `parseINt(...)` | -| `parseFloat(...)` | `float.Parse(...)` | - -### Go - -| TypeScript | Go | -| --- | --- | -| `JSON.parse` | `parseJson` | -| `console.log` | `fmt.Println` | -| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | -| `Math.min` | `Math.Min` | -| `Math.max` | `Math.Max` | -| `Math.log` | `Math.Log` | -| `Math.abs` | `Math.Abs` | -| `Math.ceil` | `Math.Ceiling` | -| `Math.round` | `Math.Round` | -| `Math.floor` | `Math.Floor` | -| `Math.pow` | `Math.Pow` | -| `Promise.all` | `Task.WhenAll` | -| `x.push(...)` | `x.Add(...)` | -| `x.indexOf(...)` | `x.IndexOf(...)` | -| `x.toUpperCase(...)` | `x.ToUpper(...)` | -| `x.toLowerCase(...)` | `x.ToLower(...)` | -| `x.toString(...)` | `x.ToString(...)` | -| `parseInt(...)` | `parseINt(...)` | -| `parseFloat(...)` | `float.Parse(...)` | - -### Java - -| TypeScript | Java | -| --- | --- | -| `JSON.parse` | `parseJson` | -| `console.log` | `System.out.println` | -| `Number.MAX_SAFE_INTEGER` | `Long.MAX_VALUE` | -| `Math.min` | `Math.min` | -| `Math.max` | `Math.max` | -| `Math.log` | `Math.log` | -| `Math.abs` | `Math.abs` | -| `Math.floor` | `Math.floor` | -| `Math.pow` | `Math.pow` | -| `parseInt(...)` | `Helpers.parseInt(...)` | -| `parseFloat(...)` | `Helpers.parseFloat(...)` | +Conversions of global calls and string/array methods are also detailed. Explicit replacements are documented in [language-conversions.md](./language-conversions.md). > ⚠️ Many of these conversions rely on type information. Make sure to annotate > types (especially function arguments) so the transpiler can disambiguate diff --git a/language-conversions.md b/language-conversions.md new file mode 100644 index 00000000..1371936f --- /dev/null +++ b/language-conversions.md @@ -0,0 +1,123 @@ + + +# 🌐 Per-language Conversions + +This document is automatically generated from the transpiler source code. +It lists the explicit property replacements, call expression replacements and method conversions mapped to each target language. + +## Python + +| TypeScript | Python | +| --- | --- | +| `console.log` | `print` | +| `JSON.stringify` | `json.dumps` | +| `JSON.parse` | `json.loads` | +| `Math.log` | `math.log` | +| `Math.abs` | `abs` | +| `Math.min` | `min` | +| `Math.max` | `max` | +| `Math.ceil` | `math.ceil` | +| `Math.round` | `math.round` | +| `Math.floor` | `math.floor` | +| `Math.pow` | `math.pow` | +| `process.exit` | `sys.exit` | +| `Number.MAX_SAFE_INTEGER` | `float(\'inf\')` | +| `x.push(...)` | `x.append(...)` | +| `x.toUpperCase(...)` | `x.upper(...)` | +| `x.toLowerCase(...)` | `x.lower(...)` | +| `x.parseFloat(...)` | `x.float(...)` | +| `x.parseInt(...)` | `x.int(...)` | +| `x.indexOf(...)` | `x.find(...)` | +| `x.padEnd(...)` | `x.ljust(...)` | +| `x.padStart(...)` | `x.rjust(...)` | +| `parseInt(...)` | `int(...)` | +| `parseFloat(...)` | `float(...)` | + +## PHP + +| TypeScript | PHP | +| --- | --- | +| `Number.MAX_SAFE_INTEGER` | `PHP_INT_MAX` | +| `JSON.stringify` | `json_encode` | +| `console.log` | `var_dump` | +| `process.exit` | `exit` | +| `Math.log` | `log` | +| `Math.abs` | `abs` | +| `Math.floor` | `(int) floor` | +| `Math.ceil` | `(int) ceil` | +| `Math.round` | `(int) round` | +| `Math.pow` | `pow` | +| `Math.min` | `min` | +| `Math.max` | `max` | +| `Promise.all` | `\\React\\Promise\\all` | +| `parseFloat(...)` | `floatval(...)` | +| `parseInt(...)` | `intval(...)` | + +## C# + +| TypeScript | C# | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `Console.WriteLine` | +| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | +| `Math.min` | `Math.Min` | +| `Math.max` | `Math.Max` | +| `Math.log` | `Math.Log` | +| `Math.abs` | `Math.Abs` | +| `Math.ceil` | `Math.Ceiling` | +| `Math.round` | `Math.Round` | +| `Math.floor` | `Math.Floor` | +| `Math.pow` | `Math.Pow` | +| `Promise.all` | `Task.WhenAll` | +| `x.push(...)` | `x.Add(...)` | +| `x.indexOf(...)` | `x.IndexOf(...)` | +| `x.toUpperCase(...)` | `x.ToUpper(...)` | +| `x.toLowerCase(...)` | `x.ToLower(...)` | +| `x.toString(...)` | `x.ToString(...)` | +| `parseInt(...)` | `parseINt(...)` | +| `parseFloat(...)` | `float.Parse(...)` | + +## Go + +| TypeScript | Go | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `fmt.Println` | +| `Number.MAX_SAFE_INTEGER` | `Int32.MaxValue` | +| `Math.min` | `Math.Min` | +| `Math.max` | `Math.Max` | +| `Math.log` | `Math.Log` | +| `Math.abs` | `Math.Abs` | +| `Math.ceil` | `Math.Ceiling` | +| `Math.round` | `Math.Round` | +| `Math.floor` | `Math.Floor` | +| `Math.pow` | `Math.Pow` | +| `Promise.all` | `Task.WhenAll` | +| `x.push(...)` | `x.Add(...)` | +| `x.indexOf(...)` | `x.IndexOf(...)` | +| `x.toUpperCase(...)` | `x.ToUpper(...)` | +| `x.toLowerCase(...)` | `x.ToLower(...)` | +| `x.toString(...)` | `x.ToString(...)` | +| `parseInt(...)` | `parseINt(...)` | +| `parseFloat(...)` | `float.Parse(...)` | + +## Java + +| TypeScript | Java | +| --- | --- | +| `JSON.parse` | `parseJson` | +| `console.log` | `System.out.println` | +| `Number.MAX_SAFE_INTEGER` | `Long.MAX_VALUE` | +| `Math.min` | `Math.min` | +| `Math.max` | `Math.max` | +| `Math.log` | `Math.log` | +| `Math.abs` | `Math.abs` | +| `Math.floor` | `Math.floor` | +| `Math.pow` | `Math.pow` | +| `parseInt(...)` | `Helpers.parseInt(...)` | +| `parseFloat(...)` | `Helpers.parseFloat(...)` | + diff --git a/src/generate-supported-md.ts b/src/generate-supported-md.ts new file mode 100644 index 00000000..a703a9a2 --- /dev/null +++ b/src/generate-supported-md.ts @@ -0,0 +1,310 @@ +#!/usr/bin/env node +/* + * Auto-generates `supported.md` describing the TypeScript constructs, operators + * and built-in calls/methods that the transpiler is able to convert. + * + * It works by statically scanning the transpiler source files (no compilation + * needed): + * - `printNode` -> supported AST constructs / statements + * - `initOperators` -> supported operators / keywords / modifiers + * - `printCallExpression` -> supported built-in global calls & instance methods + * - each language's replacement maps -> per-language conversions + * + * Run with: `npm run generate-supported` + */ + +import { readFileSync, writeFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const SRC_DIR = join(__dirname, '..', 'src'); +const README_PATH = join(__dirname, '..', 'README.md'); +const CONVERSIONS_PATH = join(__dirname, '..', 'language-conversions.md'); + +const read = (file: string) => readFileSync(join(SRC_DIR, file), 'utf8'); + +// --------------------------------------------------------------------------- +// helpers +// --------------------------------------------------------------------------- + +// turn `FunctionDeclaration` / `isFunctionDeclaration` into `Function declaration` +function humanize(name: string): string { + const cleaned = name.replace(/^is/, ''); + const spaced = cleaned.replace(/([a-z0-9])([A-Z])/g, '$1 $2'); + return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase(); +} + +// extract the body of a method by name from a source string (brace matching) +function extractMethodBody(source: string, methodName: string): string { + // allows an optional return type annotation, e.g. `printNode(node, i = 0): string {` + const startRegex = new RegExp(`${methodName}\\s*\\([^)]*\\)\\s*(?::\\s*[\\w<>\\[\\],.| ]+\\s*)?\\{`); + const match = startRegex.exec(source); + + if (!match) return ''; + let i = match.index + match[0].length; + let depth = 1; + const bodyStart = i; + for (; i < source.length && depth > 0; i++) { + const ch = source[i]; + if (ch === '{') depth++; + else if (ch === '}') depth--; + } + return source.slice(bodyStart, i - 1); +} + +// extract `this.NAME = { ... };` object literal as key/value pairs +function extractObjectMap(source: string, propName: string): [string, string][] { + const startRegex = new RegExp(`this\\.${propName}\\s*=\\s*\\{`); + const match = startRegex.exec(source); + if (!match) return []; + let i = match.index + match[0].length; + let depth = 1; + const start = i; + for (; i < source.length && depth > 0; i++) { + const ch = source[i]; + if (ch === '{') depth++; + else if (ch === '}') depth--; + } + const block = source.slice(start, i - 1); + const pairs: [string, string][] = []; + const pairRegex = /(['"])((?:\\.|(?!\1).)*)\1\s*:\s*(['"])((?:\\.|(?!\3).)*)\3/g; + let m; + while ((m = pairRegex.exec(block)) !== null) { + pairs.push([m[2], m[4]]); + } + return pairs; +} + +// Map TS SyntaxKind names to readable symbols (used for operators/keywords) +const KIND_TO_SYMBOL: Record = { + MinusMinusToken: '`--`', + MinusToken: '`-`', + SlashToken: '`/`', + AsteriskToken: '`*`', + InKeyword: '`in`', + PlusToken: '`+`', + PercentToken: '`%`', + LessThanToken: '`<`', + LessThanEqualsToken: '`<=`', + GreaterThanToken: '`>`', + GreaterThanEqualsToken: '`>=`', + EqualsEqualsToken: '`==`', + EqualsEqualsEqualsToken: '`===`', + EqualsToken: '`=`', + PlusEqualsToken: '`+=`', + BarBarToken: '`||`', + AmpersandAmpersandToken: '`&&`', + ExclamationEqualsEqualsToken: '`!==`', + ExclamationEqualsToken: '`!=`', + ExclamationToken: '`!`', + PlusPlusToken: '`++`', +}; + +const KIND_TO_KEYWORD: Record = { + StringKeyword: '`string`', + NumberKeyword: '`number`', + BooleanKeyword: '`boolean`', + VoidKeyword: '`void`', + AsyncKeyword: '`async`', + AwaitKeyword: '`await`', + StaticKeyword: '`static`', + PublicKeyword: '`public`', + PrivateKeyword: '`private`', +}; + +// --------------------------------------------------------------------------- +// 1. supported AST constructs (from printNode) +// --------------------------------------------------------------------------- +function getSupportedConstructs(base: string): string[] { + const body = extractMethodBody(base, 'printNode'); + const constructs = new Set(); + // ts.isXxx(node) + for (const m of body.matchAll(/ts\.is([A-Za-z]+)\s*\(/g)) { + constructs.add(humanize(m[1])); + } + // ts.SyntaxKind.Xxx === node.kind + for (const m of body.matchAll(/ts\.SyntaxKind\.([A-Za-z]+)\s*===\s*node\.kind/g)) { + constructs.add(humanize(m[1].replace(/Keyword$/, ' keyword'))); + } + return [...constructs].sort(); +} + +// --------------------------------------------------------------------------- +// 2. supported operators / keywords (from initOperators) +// --------------------------------------------------------------------------- +function getOperatorsAndKeywords(base: string): { operators: string[], keywords: string[] } { + const body = extractMethodBody(base, 'initOperators'); + const kinds = new Set(); + for (const m of body.matchAll(/ts\.SyntaxKind\.([A-Za-z]+)\]/g)) { + kinds.add(m[1]); + } + const operators: string[] = []; + const keywords: string[] = []; + for (const kind of kinds) { + if (KIND_TO_SYMBOL[kind]) operators.push(KIND_TO_SYMBOL[kind]); + else if (KIND_TO_KEYWORD[kind]) keywords.push(KIND_TO_KEYWORD[kind]); + } + return { + operators: [...new Set(operators)].sort(), + keywords: [...new Set(keywords)].sort(), + }; +} + +// --------------------------------------------------------------------------- +// 3. supported built-in calls/methods (from printCallExpression) +// --------------------------------------------------------------------------- +function getBuiltInCalls(base: string): { globals: string[], methods: string[] } { + const body = extractMethodBody(base, 'printCallExpression'); + const calls = new Set(); + for (const m of body.matchAll(/case\s+(['"])([^'"]+)\1\s*:/g)) { + calls.add(m[2]); + } + // split into "Global" (contains a dot / capitalized) and "instance methods" + const globals: string[] = []; + const methods: string[] = []; + for (const c of [...calls].sort()) { + if (c.includes('.') || /^[A-Z]/.test(c)) globals.push(c); + else methods.push(c); + } + return { globals, methods }; +} + +// --------------------------------------------------------------------------- +// 4. per-language replacement maps +// --------------------------------------------------------------------------- +const LANGUAGES = [ + { id: 'Python', file: 'pythonTranspiler.ts' }, + { id: 'PHP', file: 'phpTranspiler.ts' }, + { id: 'C#', file: 'csharpTranspiler.ts' }, + { id: 'Go', file: 'goTranspiler.ts' }, + { id: 'Java', file: 'javaTranspiler.ts' }, +]; + +interface ILangReplacement { + id: string; + full: [string, string][]; + right: [string, string][]; + call: [string, string][]; +} + +function getLanguageReplacements(): ILangReplacement[] { + const result: ILangReplacement[] = []; + for (const lang of LANGUAGES) { + let source: string; + try { + source = read(lang.file); + } catch { + continue; + } + const full = extractObjectMap(source, 'FullPropertyAccessReplacements'); + const right = extractObjectMap(source, 'RightPropertyAccessReplacements'); + const call = extractObjectMap(source, 'CallExpressionReplacements'); + if (full.length || right.length || call.length) { + result.push({ id: lang.id, full, right, call }); + } + } + return result; +} + +// --------------------------------------------------------------------------- +// build markdown +// --------------------------------------------------------------------------- +function buildReadmeMarkdown(constructs: string[], operators: string[], keywords: string[], globals: string[], methods: string[]): string { + let md = '\n\n' + + '## 📚 Supported Methods & Operators\n\n' + + 'Below is a detailed reference of the TypeScript constructs that the transpiler is able to convert\n' + + '(derived from `src/baseTranspiler.ts` and the language specific transpilers).\n\n'; + + // md += '### Language Constructs / Statements\n\n' + + // 'The following AST node types are handled by `printNode`:\n\n' + + // constructs.map(c => `- ${c}`).join('\n') + '\n\n'; + + md += '### Operators\n\n' + + operators.join(', ') + '\n\n'; + + md += '### Keywords / Modifiers\n\n' + + keywords.join(', ') + '\n\n'; + + md += '### Built-in Global Functions\n\n' + + 'These global calls are recognized and converted to each target language:\n\n' + + globals.map(g => `- \`${g}\``).join('\n') + '\n\n'; + + md += '### Built-in Instance Methods (string / array / object)\n\n' + + 'These instance methods are recognized and converted to each target language:\n\n' + + methods.map(m => `- \`${m}\``).join('\n') + '\n\n'; + + md += '## Per-language Conversions\n' + + 'Conversions of global calls and string/array methods are also detailed. Explicit replacements are documented in [language-conversions.md](./language-conversions.md).\n\n'; + + md += '> ⚠️ Many of these conversions rely on type information. Make sure to annotate\n' + + '> types (especially function arguments) so the transpiler can disambiguate\n' + + '> (e.g. `.length` → `len`/`count`, `+` → string concat vs numeric addition).\n'; + + return md; +} + +function buildConversionsMarkdown(langReplacements: ILangReplacement[]): string { + let md = '\n\n' + + '# 🌐 Per-language Conversions\n\n' + + 'This document is automatically generated from the transpiler source code.\n' + + 'It lists the explicit property replacements, call expression replacements and method conversions mapped to each target language.\n\n'; + + for (const lang of langReplacements) { + md += `## ${lang.id}\n\n`; + const rows = [ + ...lang.full.map(([k, v]) => [`${k}`, `${v}`]), + ...lang.right.map(([k, v]) => [`x.${k}(...)`, `x.${v}(...)`]), + ...lang.call.map(([k, v]) => [`${k}(...)`, `${v}(...)`]), + ]; + if (rows.length === 0) { + md += '_No explicit replacements defined._\n\n'; + continue; + } + md += '| TypeScript | ' + lang.id + ' |\n' + + '| --- | --- |\n' + + rows.map(([k, v]) => `| \`${k}\` | \`${v}\` |`).join('\n') + '\n\n'; + } + + return md; +} + +const baseSource = read('baseTranspiler.ts'); +const constructsList = getSupportedConstructs(baseSource); +const { operators: operatorsList, keywords: keywordsList } = getOperatorsAndKeywords(baseSource); +const { globals: globalsList, methods: methodsList } = getBuiltInCalls(baseSource); +const langReplacementsList = getLanguageReplacements(); + +const readmeMarkdown = buildReadmeMarkdown(constructsList, operatorsList, keywordsList, globalsList, methodsList); +const conversionsMarkdown = buildConversionsMarkdown(langReplacementsList); + +// update README.md +const readmeContent = readFileSync(README_PATH, 'utf8'); +const startMarker = ''; +const endMarker = ''; + +const startIndex = readmeContent.indexOf(startMarker); +const endIndex = readmeContent.indexOf(endMarker); + +if (startIndex === -1 || endIndex === -1) { + throw new Error('Markers not found in README.md!'); +} + +const updatedReadme = readmeContent.slice(0, startIndex + startMarker.length) + + '\n' + readmeMarkdown + '\n' + + readmeContent.slice(endIndex); + +writeFileSync(README_PATH, updatedReadme, 'utf8'); +console.log(`Updated ${README_PATH}`); + +// update language-conversions.md +writeFileSync(CONVERSIONS_PATH, conversionsMarkdown, 'utf8'); +console.log(`Updated ${CONVERSIONS_PATH}`); From 3719c626c4573d30a1d4b9a4508f6e8aea98bf73 Mon Sep 17 00:00:00 2001 From: "T. Todua" <7117978+ttodua@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:24:42 +0400 Subject: [PATCH 5/5] Update node.js.yml --- .github/workflows/node.js.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index e6fcde1a..24486a63 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -46,11 +46,11 @@ jobs: uses: jpb06/jest-badges-action@latest with: branches: master - - name: Pushing generated files - if: github.ref == 'refs/heads/master' - uses: EndBug/add-and-commit@v9 # You can change this to use a specific version. - with: - add: | - dist/ -f - README.md - message: 'Update generated files' \ No newline at end of file + # - name: Pushing generated files + # if: github.ref == 'refs/heads/master' + # uses: EndBug/add-and-commit@v9 # You can change this to use a specific version. + # with: + # add: | + # dist/ -f + # README.md + # message: 'Update generated files'