├── .eslintignore ├── .eslintrc.json ├── .github └── workflows │ └── nodejs.yml ├── .gitignore ├── .npmignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── License.txt ├── changelog.md ├── cli ├── License.txt ├── ReadMe.md ├── antlr-format.ts ├── config-schema.json ├── java2ts.ts ├── package-lock.json ├── package.json ├── process-options.ts └── tsconfig.json ├── cspell.json ├── data ├── java.io.json ├── java.lang.annotation.json ├── java.lang.instrument.json ├── java.lang.invoke.json ├── java.lang.json ├── java.lang.management.json ├── java.lang.module.json ├── java.lang.ref.json ├── java.lang.reflect.json ├── java.math.json ├── java.net.http.json ├── java.net.json ├── java.net.spi.json ├── java.nio.channels.json ├── java.nio.channels.spi.json ├── java.nio.charset.json ├── java.nio.charset.spi.json ├── java.nio.file.attribute.json ├── java.nio.file.json ├── java.nio.file.spi.json ├── java.nio.json ├── java.security.acl.json ├── java.security.cert.json ├── java.security.interfaces.json ├── java.security.json ├── java.security.spec.json ├── java.text.json ├── java.text.spi.json ├── java.time.chrono.json ├── java.time.format.json ├── java.time.json ├── java.time.temporal.json ├── java.time.zone.json ├── java.util.concurrent.atomic.json ├── java.util.concurrent.json ├── java.util.concurrent.locks.json ├── java.util.function.json ├── java.util.jar.json ├── java.util.json ├── java.util.logging.json ├── java.util.prefs.json ├── java.util.regex.json ├── java.util.spi.json ├── java.util.stream.json ├── java.util.zip.json ├── javax.crypto.interfaces.json ├── javax.crypto.json ├── javax.crypto.spec.json ├── javax.net.json ├── javax.net.ssl.json ├── javax.security.auth.callback.json ├── javax.security.auth.json ├── javax.security.auth.kerberos.json ├── javax.security.auth.login.json ├── javax.security.auth.spi.json ├── javax.security.auth.x500.json ├── javax.security.cert.json └── javax.security.sasl.json ├── doc ├── configuration.md ├── features.md └── symbol-resolution.md ├── jest.config.ts ├── package-lock.json ├── package.json ├── parser ├── JavaLexer.g4 ├── JavaParser.g4 └── generated │ ├── JavaLexer.tokens │ ├── JavaLexer.ts │ ├── JavaParser.tokens │ ├── JavaParser.ts │ ├── JavaParserListener.ts │ └── JavaParserVisitor.ts ├── readme.md ├── src ├── JavaFileSource.ts ├── JavaFileSymbolTable.ts ├── JavaPackageSource.ts ├── PackageSource.ts ├── PackageSourceManager.ts ├── conversion │ ├── FileProcessor.ts │ ├── JavaToTypeScript.ts │ ├── MemberOrdering.ts │ └── types.ts ├── index.ts ├── parsing │ ├── JavaClassSymbol.ts │ ├── JavaErrorListener.ts │ └── JavaParseTreeWalker.ts └── utilities.ts ├── tests ├── conversion │ └── Option.spec.ts ├── jest.config.ts ├── test-data │ └── java-sources │ │ └── org │ │ └── java2typescript │ │ └── options │ │ └── OptionSpec.java └── tsconfig.json ├── tools ├── convertANTLR3Runtime.ts ├── convertANTLR4Runtime.ts ├── convertANTLR4Tool.ts ├── convertJDKTests.ts ├── convertRuntimeTests.ts ├── convertST4.ts └── fetchJavaApis.ts └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Build & Test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [18.x, 20.x] 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v3 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | - run: npm ci 25 | - run: npm run build --if-present 26 | - run: npm test 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | node_modules 3 | coverage 4 | *.interp 5 | dist 6 | .vscode/numbered-bookmarks.json 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.tgz 2 | 3 | .github 4 | .vscode 5 | .coverage 6 | .eslintignore 7 | .eslintrc.json 8 | .antlr 9 | cspell.json 10 | jest.config.ts 11 | tsconfig.json 12 | 13 | bin/*.jar 14 | coverage/** 15 | data/** 16 | doc/** 17 | parser/** 18 | src/** 19 | tests/** 20 | tools/** 21 | config/ 22 | output/tools/ 23 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node", 6 | "request": "launch", 7 | "name": "Run current Jest test", 8 | "runtimeArgs": [ 9 | "${workspaceRoot}/node_modules/.bin/jest", 10 | "${fileBasenameNoExtension}.ts", 11 | "--no-coverage", 12 | "--runInBand" 13 | ], 14 | "console": "integratedTerminal", 15 | "stopOnEntry": false, 16 | "sourceMaps": true, 17 | "resolveSourceMapLocations": [ 18 | "${workspaceFolder}/**", 19 | "!**/node_modules/**" 20 | ], 21 | "smartStep": true, 22 | "trace": false 23 | }, 24 | { 25 | "type": "node", 26 | "request": "launch", 27 | "name": "Convert ANTLR3 runtime", 28 | "sourceMaps": true, 29 | "stopOnEntry": false, 30 | "smartStep": true, 31 | "args": [], 32 | "runtimeArgs": [ 33 | "--experimental-specifier-resolution=node", 34 | "--no-warnings", 35 | "--loader", 36 | "ts-node/esm", 37 | "tools/convertANTLR3Runtime.ts", 38 | ], 39 | "console": "integratedTerminal", 40 | "trace": false 41 | }, 42 | { 43 | "type": "node", 44 | "request": "launch", 45 | "name": "Convert ANTLR4 runtime", 46 | "sourceMaps": true, 47 | "stopOnEntry": false, 48 | "smartStep": true, 49 | "args": [], 50 | "runtimeArgs": [ 51 | "--experimental-specifier-resolution=node", 52 | "--no-warnings", 53 | "--loader", 54 | "ts-node/esm", 55 | "tools/convertANTLR4Runtime.ts", 56 | ], 57 | "console": "integratedTerminal", 58 | "trace": false 59 | }, 60 | { 61 | "type": "node", 62 | "request": "launch", 63 | "name": "Convert ANTLR4 tool", 64 | "sourceMaps": true, 65 | "stopOnEntry": false, 66 | "smartStep": true, 67 | "args": [], 68 | "runtimeArgs": [ 69 | "--experimental-specifier-resolution=node", 70 | "--no-warnings", 71 | "--loader", 72 | "ts-node/esm", 73 | "tools/convertANTLR4Tool.ts", 74 | ], 75 | "console": "integratedTerminal", 76 | "trace": false 77 | }, 78 | { 79 | "type": "node", 80 | "request": "launch", 81 | "name": "Convert JDK Tests", 82 | "sourceMaps": true, 83 | "stopOnEntry": false, 84 | "smartStep": true, 85 | "args": [], 86 | "runtimeArgs": [ 87 | "--experimental-specifier-resolution=node", 88 | "--loader", 89 | "ts-node/esm", 90 | "tools/convertJDKTests.ts", 91 | ], 92 | "console": "integratedTerminal", 93 | "trace": false 94 | }, 95 | { 96 | "type": "node", 97 | "request": "launch", 98 | "name": "Launch Java API fetch", 99 | "sourceMaps": true, 100 | "stopOnEntry": false, 101 | "smartStep": true, 102 | "args": [], 103 | "runtimeArgs": [ 104 | "--experimental-specifier-resolution=node", 105 | "--loader", 106 | "ts-node/esm", 107 | "tools/fetchJavaApis.ts" 108 | ], 109 | "console": "integratedTerminal", 110 | "trace": false 111 | }, 112 | ] 113 | } 114 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "jest.autoRun": "off", 3 | "jest.coverageFormatter": "GutterFormatter", 4 | "jest.jestCommandLine": "npm run test --", 5 | "jest.rootPath": "src", 6 | "jest.testExplorer": { 7 | "enabled": true 8 | }, 9 | "jest.showCoverageOnLoad": true, 10 | } 11 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "command": "tsc", 6 | "label": "tsc", 7 | "type": "shell", 8 | "args": [ 9 | "-w", 10 | "-p", 11 | "." 12 | ], 13 | "isBackground": true, 14 | "problemMatcher": "$tsc-watch", 15 | "presentation": { 16 | "echo": true, 17 | "reveal": "silent", 18 | "focus": false, 19 | "panel": "shared", 20 | "showReuseMessage": true, 21 | "clear": false 22 | } 23 | }, 24 | { 25 | "type": "typescript", 26 | "tsconfig": "tsconfig.json", 27 | "option": "watch", 28 | "problemMatcher": [ 29 | "$tsc-watch" 30 | ], 31 | "group": { 32 | "kind": "build", 33 | "isDefault": true 34 | }, 35 | "label": "tsc: watch" 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 - present Mike Lischke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | ## Changelog for Java2TypeScript 2 | 3 | ### 1.1.0 4 | 5 | - Switched from antlr4ts to antlr4ng. Regenerated all parser files. 6 | - Added support for automatic adding of the `override` keyword for inherited methods. 7 | - Fixed member ordering for nested classes. 8 | - Fixed resolution of types from which another type derives or which it implements. 9 | - Fixed wrong exclusion of transpiled files from tsconfig.json. 10 | - Updated documentation. 11 | - The javaLib setting now can either be undefined (defaulting to "jree"), a node package, a relative or an absolute path. Relative paths are resolved against the output path. 12 | - Updated the type information from the Java documentation. 13 | - Fully implemented annotation handling in the converter tool. 14 | - Implemented a new feature where Java types are written without full qualifier. Instead constant reassignments and type aliases are generated from the imports in a file. This brings the generated code even closer to that of Java. See the new configuration setting `useUnqualifiedTypes`. 15 | - Removed the automatic conversion of interfaces with implemented methods to abstract classes. Instead a side class and declaration merging should be used. 16 | - Improved handling of nested types. 17 | - Type aliases for number (e.g. int, long, etc.) are now imported using a type import. 18 | 19 | ### 1.0.1 - 1.0.2 20 | 21 | Small bug fixes. 22 | 23 | ### 1.0.0 24 | 25 | First public release. 26 | -------------------------------------------------------------------------------- /cli/License.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022, 2023 Mike Lischke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cli/ReadMe.md: -------------------------------------------------------------------------------- 1 | [![Weekly Downloads](https://img.shields.io/npm/dw/antlr-format-cli?style=for-the-badge&color=blue)](https://www.npmjs.com/package/antlr-format-cli) 2 | [![npm version](https://img.shields.io/npm/v/antlr-format-cli?style=for-the-badge&color=yellow)](https://www.npmjs.com/package/antlr-format-cli) 3 | 4 | # antlr-format 5 | 6 | The `antlr-format-cli` package is a terminal tool to use the [`antlr-format`](https://www.npmjs.com/package/antlr-format) package in a terminal, in batch files and other automatic formatting scenarios. 7 | 8 | ## Installation 9 | 10 | For a local installation in your project use: 11 | 12 | ```bash 13 | npm i --save-dev antlr-format-cli 14 | ``` 15 | 16 | Or as a global module, which allows you to run it anywhere on your machine: 17 | 18 | ```bash 19 | npm i -g --save-dev antlr-format-cli 20 | ``` 21 | 22 | The package provides the command `antlr-format` (note the missing -cli suffix). 23 | 24 | ## Usage 25 | 26 | Running the formatter tool in a terminal is simple. Switch to the project folder (or if you have the formatter installed globally use any directory) and issue the command: 27 | 28 | ```bash 29 | antlr-format --config config.json -v ./**/MyGrammar.g4 AnotherGrammar.g4 30 | ``` 31 | 32 | with the actual path to the grammar(s) you want to be formatted. 33 | 34 | You can omit the `--config` parameter, in which case the default options will be used. The list of files supports the usual glob pattern for file systems. Grammars may contain syntax errors (e.g. for testing), but you should only use the tool for real ANTLR4 grammars, otherwise the outcome is unpredictable. 35 | 36 | Run the tool with `--help` to have it print its supported parameters. For a detailed description of the supported formatting options check out the [formatting](https://github.com/mike-lischke/antlr-format/blob/main/doc/formatting.md) documentation in the `antlr-format` node package. 37 | 38 | ## Release Notes 39 | 40 | ### 1.2.1 41 | 42 | Updated the tool with the latest `antlr-format` package. 43 | 44 | ### 1.2.0 45 | 46 | The `--pattern` parameters has been removed. Instead files + patterns can be passed to the tool without any option name, but the file list has been moved to the end of the arguments list. 47 | 48 | ### 1.0.0 49 | 50 | This is the initial release of the tool, after it was extracted from the 'antlr-format` package. 51 | -------------------------------------------------------------------------------- /cli/antlr-format.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* 4 | * Copyright (c) Mike Lischke. All rights reserved. 5 | * Licensed under the MIT License. See License.txt in the project root for license information. 6 | */ 7 | 8 | import process from "process"; 9 | import { readFileSync, writeFileSync } from "fs"; 10 | import { glob } from "glob"; 11 | 12 | import { OptionValues, program } from "commander"; 13 | 14 | import { CharStreams, CommonTokenStream } from "antlr4ng"; 15 | 16 | import { ANTLRv4Lexer } from "../src/parser/ANTLRv4Lexer.js"; 17 | import { IConfigurationDetails, processFormattingOptions } from "./process-options.js"; 18 | 19 | import { IFormattingOptions } from "../src/types.js"; 20 | import { GrammarFormatter } from "../src/GrammarFormatter.js"; 21 | 22 | interface IAppParameters extends OptionValues { 23 | /** The path to a single source file or a glob pattern for multiple files. */ 24 | pattern: string; 25 | 26 | /** When true, add the default ANTLR formatting option string to the grammar, before formatting it. */ 27 | addOptions?: boolean; 28 | 29 | /** 30 | * Path to a JSON file with user-defined formatting options. If a grammar already contains formatting options, 31 | * they override the options from this file. If the grammar contains no options, the options from this file are 32 | * added to the grammar if the addOptions option is true. 33 | */ 34 | config?: string; 35 | 36 | /** Suppress all output except errors. */ 37 | silent?: boolean; 38 | 39 | /** Print additional information. */ 40 | verbose?: boolean; 41 | } 42 | 43 | const matchBoolean = (value: string): boolean => { 44 | if (value == null) { 45 | return false; 46 | } 47 | 48 | const lower = value.trim().toLowerCase(); 49 | 50 | return lower === "true" || lower === "1" || lower === "on" || lower === "yes"; 51 | }; 52 | 53 | const start = performance.now(); 54 | 55 | program 56 | .argument("file1, pattern2, ...", "A list of files or glob patterns for multiple files.") 57 | .option("-a, --add-options [boolean]", "Insert the used ANTLR grammar formatting " + 58 | "options to the grammar file, if it contains no options.", matchBoolean, true) 59 | .option("-c, --config ", "Path to a JSON file containing the formatting options to use.") 60 | .option("-s, --silent", "Suppress all output except errors.") 61 | .option("-v, --verbose", "Print additional information.") 62 | .version("antlr-format 1.0.1") 63 | .parse(); 64 | 65 | const options = program.opts(); 66 | 67 | const fileList = glob.sync(program.args, { nodir: true }); 68 | if (fileList.length === 0) { 69 | console.error(`No grammar file found using this pattern: ${program.args.join(", ")}.\n`); 70 | 71 | process.exit(0); 72 | } 73 | fileList.sort(); 74 | 75 | const defaultOptions: IFormattingOptions = { 76 | reflowComments: false, 77 | }; 78 | 79 | /** 80 | * Runs the grammar formatter on the given grammar file. 81 | * Start and stop positions are useful to format only a part of the grammar. When given the formatter returns 82 | * the formatted part and the new start and stop positions, which can be used to replace the original text. 83 | * 84 | * @param grammarPath The path to the grammar file. 85 | * @param config Options to use for formatting, both as object and string (for insertion). 86 | * @param start The character index in the file where formatting should start. 87 | * @param stop The character index in the file where formatting should stop. 88 | * @param addOptions If true, the default ANTLR grammar formatting options are added to the grammar file, if it 89 | * contains no options yet. 90 | * 91 | * @returns The formatted grammar and the computed start and stop indices. 92 | */ 93 | const formatGrammar = (grammarPath: string, config: IConfigurationDetails, start: number, 94 | stop: number, addOptions = true): [string, number, number] => { 95 | const grammar = readFileSync(grammarPath, { encoding: "utf8" }); 96 | 97 | const lexer = new ANTLRv4Lexer(CharStreams.fromString(grammar)); 98 | 99 | lexer.removeErrorListeners(); 100 | const tokenStream = new CommonTokenStream(lexer); 101 | tokenStream.fill(); 102 | const tokens = tokenStream.getTokens(); 103 | 104 | // Check the first default channel token for the grammar type. 105 | let options: IFormattingOptions = defaultOptions; 106 | for (const token of tokens) { 107 | if (token.channel === 0) { 108 | const type = token.text; 109 | if (type === "lexer") { 110 | options = config.lexer; 111 | } else { 112 | options = config.main; 113 | } 114 | 115 | break; 116 | } 117 | } 118 | 119 | const formatter = new GrammarFormatter(tokens, addOptions); 120 | 121 | return formatter.formatGrammar(options, start, stop); 122 | }; 123 | 124 | if (!options.silent) { 125 | console.log("\nantlr-format, processing options..."); 126 | } 127 | 128 | const details = processFormattingOptions(options.config); 129 | 130 | if (!options.silent) { 131 | console.log("\nformatting " + fileList.length + " file(s)..."); 132 | } 133 | 134 | fileList.forEach((grammarPath) => { 135 | if (options.verbose) { 136 | console.log(" " + grammarPath); 137 | } 138 | const [text] = formatGrammar(grammarPath, details, 0, 1e10, options.addOptions); 139 | 140 | //const formattedGrammarPath = path.join(args[1], path.basename(grammarPath)); 141 | const formattedGrammarPath = grammarPath; 142 | writeFileSync(formattedGrammarPath, text); 143 | }); 144 | 145 | if (!options.silent) { 146 | console.log(`\ndone [${Math.round((performance.now() - start))} ms]\n`); 147 | } 148 | -------------------------------------------------------------------------------- /cli/config-schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$ref": "#/definitions/IConfiguration", 3 | "$schema": "http://json-schema.org/draft-07/schema#", 4 | "definitions": { 5 | "IConfiguration": { 6 | "additionalProperties": false, 7 | "description": "Structure of a configuration JSON file.", 8 | "properties": { 9 | "lexer": { 10 | "$ref": "#/definitions/IFormattingOptions", 11 | "description": "Dedicated options only for lexer grammars." 12 | }, 13 | "main": { 14 | "$ref": "#/definitions/IFormattingOptions", 15 | "description": "Main options, used for parser and combined grammars. Also for lexer grammars, if the lexer key is not specified." 16 | } 17 | }, 18 | "required": [ 19 | "main" 20 | ], 21 | "type": "object" 22 | }, 23 | "IFormattingOptions": { 24 | "additionalProperties": false, 25 | "description": "Options for grammar text formatting. Some names, values and meanings have been taken from clang-format (http://clang.llvm.org/docs/ClangFormatStyleOptions.html), but may have slight variations tailored towards ANTLR grammars. Deviations from that are mentioned in comments, otherwise see clang-format and the documentation for descriptions + examples.", 26 | "properties": { 27 | "alignActions": { 28 | "description": "Align actions ({} blocks in rules) and predicates. Default: false.", 29 | "type": "boolean" 30 | }, 31 | "alignColons": { 32 | "description": "Values not found in clang-format: When set to \"none\" places the colon directly behind the rule name. Trailing alignment aligns colons of consecutive single line rules (with at least one whitespace between rule name and colon). Hanging alignment moves the colon to the next line (after the normal indentation, aligning it so with the alt pipe chars). Default: none.", 33 | "enum": [ 34 | "none", 35 | "trailing", 36 | "hanging" 37 | ], 38 | "type": "string" 39 | }, 40 | "alignFirstTokens": { 41 | "description": "Align first tokens in rules after the colon. Default: false.", 42 | "type": "boolean" 43 | }, 44 | "alignLabels": { 45 | "description": "Align alt labels (# name). Default: true.", 46 | "type": "boolean" 47 | }, 48 | "alignLexerCommands": { 49 | "description": "Align arrows from lexer commands. Default: false.", 50 | "type": "boolean" 51 | }, 52 | "alignSemicolons": { 53 | "description": "Place semicolon behind last code token or on an own line (with or w/o indentation). Default: ownLine (no indentation). This setting has no effect for non-rule commands that end with a semicolon (e.g. \"grammar Test;\", \"import Blah;\" etc.). Such commands are always placed on a single line.", 54 | "enum": [ 55 | "none", 56 | "ownLine", 57 | "hanging" 58 | ], 59 | "type": "string" 60 | }, 61 | "alignTrailers": { 62 | "description": "When true a single alignment for labels, actions, lexer commands and trailing comments is used instead of individual alignments for each type. This avoids large whitespace runs if you have a mix of these types. Setting alignTrailers disables the individual alignment settings of the mentioned types.", 63 | "type": "boolean" 64 | }, 65 | "alignTrailingComments": { 66 | "description": "Default: false", 67 | "type": "boolean" 68 | }, 69 | "allowShortBlocksOnASingleLine": { 70 | "description": "Default: true;", 71 | "type": "boolean" 72 | }, 73 | "allowShortRulesOnASingleLine": { 74 | "description": "Like allowShortBlocksOnASingleLine, but for entire rules. Default: true.", 75 | "type": "boolean" 76 | }, 77 | "breakBeforeBraces": { 78 | "description": "When true start predicates and actions on a new line. Default: false.", 79 | "type": "boolean" 80 | }, 81 | "breakBeforeParens": { 82 | "description": "For blocks: if true puts opening parentheses on an own line. Default: false.", 83 | "type": "boolean" 84 | }, 85 | "columnLimit": { 86 | "description": "Default: 100 chars.", 87 | "type": "number" 88 | }, 89 | "continuationIndentWidth": { 90 | "description": "For line continuation (only used if useTab is false). Default: same as indentWith.", 91 | "type": "number" 92 | }, 93 | "disabled": { 94 | "description": "Default: false", 95 | "type": "boolean" 96 | }, 97 | "groupedAlignments": { 98 | "description": "When true alignments are organized in groups of lines where they apply. These line groups are separated by lines where a specific alignment type does not appear. Default: true.", 99 | "type": "boolean" 100 | }, 101 | "indentWidth": { 102 | "description": "Default: 4 chars.", 103 | "type": "number" 104 | }, 105 | "keepEmptyLinesAtTheStartOfBlocks": { 106 | "description": "Default: false.", 107 | "type": "boolean" 108 | }, 109 | "maxEmptyLinesToKeep": { 110 | "description": "Default: 1.", 111 | "type": "number" 112 | }, 113 | "minEmptyLines": { 114 | "description": "Between top level elements, how many empty lines must exist? Default: 0.", 115 | "type": "number" 116 | }, 117 | "reflowComments": { 118 | "description": "Default: false.", 119 | "type": "boolean" 120 | }, 121 | "ruleInternalsOnSingleLine": { 122 | "description": "Place rule internals (return value, local variables,", 123 | "type": "boolean" 124 | }, 125 | "singleLineOverrulesHangingColon": { 126 | "description": "When `allowShortRulesOnASingleLine` is true and `alignColon` is set to \"hanging\" this setting determines which gets precedence. If true (the default) a rule is placed on a single line if it fits, ignoring the \"hanging\" setting.", 127 | "type": "boolean" 128 | }, 129 | "spaceBeforeAssignmentOperators": { 130 | "description": "Default: true", 131 | "type": "boolean" 132 | }, 133 | "tabWidth": { 134 | "description": "Default: 4.", 135 | "type": "number" 136 | }, 137 | "useTab": { 138 | "description": "Default: true.", 139 | "type": "boolean" 140 | } 141 | }, 142 | "type": "object" 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /cli/java2ts.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* 4 | * Copyright (c) Mike Lischke. All rights reserved. 5 | * Licensed under the MIT License. See License.txt in the project root for license information. 6 | */ 7 | 8 | /** This is the main entry point for the java2typescript conversion, when using NPM. */ 9 | 10 | import * as fs from "fs/promises"; 11 | import * as path from "path"; 12 | 13 | import { 14 | IClassResolver, IConverterConfiguration, IConverterOptions, ISourceMapping, JavaToTypescriptConverter, 15 | } from "../src/conversion/JavaToTypeScript.js"; 16 | import { IMemberOrderOptions } from "../src/conversion/MemberOrdering.js"; 17 | 18 | const args = process.argv.slice(2); 19 | 20 | if (args.length < 1) { 21 | console.log("Usage: java2ts "); 22 | process.exit(1); 23 | } 24 | 25 | console.log("\nConverting Java to TypeScript...\n"); 26 | 27 | // Load the given configuration file and create a converter configuration from it. 28 | const configFile = args[0]; 29 | const content = await fs.readFile(configFile, { encoding: "utf-8" }); 30 | const json = JSON.parse(content); 31 | 32 | let options: IConverterOptions | undefined; 33 | 34 | if ("options" in json) { 35 | // The class resolver entries are given as objects, but we need a map. 36 | const rawResolver = json.options.classResolver as Object; 37 | 38 | let classResolver: Map | undefined; 39 | if (rawResolver) { 40 | classResolver = new Map([ 41 | ...Object.entries(rawResolver), 42 | ]); 43 | } 44 | 45 | options = { 46 | prefix: json.options.prefix as string, 47 | convertAnnotations: json.options.convertAnnotations as boolean, 48 | preferArrowFunctions: json.options.preferArrowFunctions as boolean, 49 | autoAddBraces: json.options.autoAddBraces as boolean, 50 | addNullUnionType: json.options.addNullUnionType as boolean, 51 | suppressTypeWithInitializer: json.options.suppressTypeWithInitializer as boolean, 52 | wrapStringLiterals: json.options.wrapStringLiterals as boolean, 53 | memberOrderOptions: json.options.memberOrderOptions as IMemberOrderOptions, 54 | addIndexFiles: json.options.addIndexFiles as boolean, 55 | sourceMappings: json.options.sourceMappings as ISourceMapping[], 56 | // importResolver?: CustomImportResolver; 57 | classResolver, 58 | }; 59 | } 60 | 61 | let rawReplace = json.sourceReplace as Object; 62 | let sourceReplace: Map | undefined; 63 | 64 | if (rawReplace) { 65 | const list: Array<[RegExp, string]> = Object.entries(rawReplace).map(([key, value]) => { 66 | return [new RegExp(key, 'g'), value]; 67 | }); 68 | sourceReplace = new Map(list); 69 | } 70 | 71 | rawReplace = json.targetReplace as Object; 72 | let targetReplace: Map | undefined; 73 | if (rawReplace) { 74 | const list: Array<[RegExp, string]> = Object.entries(rawReplace).map(([key, value]) => { 75 | return [new RegExp(key, 'g'), value]; 76 | }); 77 | targetReplace = new Map(list); 78 | } 79 | 80 | const config: IConverterConfiguration = { 81 | packageRoot: json.packageRoot as string, 82 | outputPath: json.outputPath as string, 83 | 84 | javaLib: json.javaLib as string, 85 | include: json.include as string[], 86 | exclude: json.exclude as string[], 87 | sourceReplace, 88 | targetReplace, 89 | options, 90 | }; 91 | 92 | if (!config.packageRoot) { 93 | console.error("ERROR: No package root given in configuration file."); 94 | process.exit(1); 95 | } 96 | 97 | config.packageRoot = path.resolve(process.cwd(), config.packageRoot); 98 | 99 | if (!config.outputPath) { 100 | console.error("ERROR: No output path given in configuration file."); 101 | process.exit(1); 102 | } 103 | 104 | config.outputPath = path.resolve(process.cwd(), config.outputPath); 105 | 106 | const converter = new JavaToTypescriptConverter(config); 107 | await converter.startConversion(); 108 | -------------------------------------------------------------------------------- /cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "antlr-format-cli", 3 | "version": "1.2.1", 4 | "description": "A cli wrapper for the antlr-format package", 5 | "author": "Mike Lischke", 6 | "files": [ 7 | "License.txt", 8 | "dist/antlr-format.cjs" 9 | ], 10 | "bin": { 11 | "antlr-format": "./dist/antlr-format.cjs" 12 | }, 13 | "type": "module", 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/mike-lischke/antlr-format.git" 17 | }, 18 | "keywords": [ 19 | "ANTLR4", 20 | "Formatting", 21 | "cli" 22 | ], 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/mike-lischke/antlr-format/issues" 26 | }, 27 | "homepage": "https://github.com/mike-lischke/antlr-format", 28 | "scripts": { 29 | "prepublishOnly": "npm run build", 30 | "build": "esbuild ./java2ts.ts --main-fields=module,main --bundle --outfile=dist/antlr-format.cjs --platform=node --format=cjs --minify", 31 | "generate-configuration-schema": "./node_modules/.bin/ts-json-schema-generator --path '../src/types.ts' --type 'IConfiguration' > config-schema.json" 32 | }, 33 | "dependencies": { 34 | "@readme/better-ajv-errors": "1.6.0", 35 | "ajv": "8.12.0", 36 | "commander": "11.1.0", 37 | "glob": "10.3.10", 38 | "ts-json-schema-generator": "1.4.1" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cli/process-options.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | // @ts-ignore, because when setting node module resolution to Node16, tsc raises an error for the import assertion. 7 | import configSchema from "./config-schema.json" assert { type: "json" }; 8 | 9 | // eslint-disable-next-line @typescript-eslint/naming-convention 10 | import Ajv, { ErrorObject } from "ajv"; 11 | import betterAjvErrors from "@readme/better-ajv-errors"; 12 | 13 | import { existsSync, readFileSync } from "fs"; 14 | 15 | //import { convertToComment } from "../src/GrammarFormatter.js"; 16 | //import { IConfiguration, IFormattingOptions } from "../src/types.js"; 17 | 18 | /*export interface IConfigurationDetails { 19 | main: IFormattingOptions; 20 | mainText: string; 21 | lexer: IFormattingOptions; 22 | lexerText: string; 23 | };*/ 24 | 25 | /** 26 | * Processes the options specified by the user and adds inline options in the grammar file (if enabled). 27 | * 28 | * @param configPath The path to the configuration file. 29 | * 30 | * @returns A tuple with the main and lexer options, formatted as single line comments, ready to be inserted 31 | * into grammars. 32 | */ 33 | /* 34 | export const processFormattingOptions = (configPath?: string): IConfigurationDetails => { 35 | let mainOptions: IFormattingOptions = {}; 36 | let lexerOptions: IFormattingOptions = {}; 37 | 38 | if (configPath && existsSync(configPath)) { 39 | const content = readFileSync(configPath, { encoding: "utf-8" }); 40 | const config = JSON.parse(content) as IConfiguration; 41 | 42 | // Validate the configuration file using our schema. 43 | const ajv = new Ajv.default({ allErrors: true, verbose: true }); 44 | const validate = ajv.compile(configSchema); 45 | const valid = validate(config); 46 | if (!valid) { 47 | console.log(`\nFound config validation errors in ${configPath}\n`); 48 | 49 | // @ts-expect-error, because the type definition export is wrong. 50 | const error = betterAjvErrors(configSchema, config, validate.errors as ErrorObject[], { 51 | json: content, 52 | }); 53 | console.log(error + "\n"); 54 | 55 | process.exit(1); 56 | } 57 | 58 | mainOptions = config.main; 59 | lexerOptions = config.lexer ?? mainOptions; 60 | 61 | return { 62 | main: mainOptions, 63 | mainText: convertToComment(mainOptions), 64 | lexer: lexerOptions, 65 | lexerText: convertToComment(lexerOptions), 66 | }; 67 | } 68 | 69 | return { main: {}, mainText: "", lexer: {}, lexerText: "" }; 70 | }; 71 | */ 72 | -------------------------------------------------------------------------------- /cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "sourceMap": true, 7 | "esModuleInterop": true, 8 | "noEmit": false, 9 | "declaration": true, 10 | "emitDeclarationOnly": true, 11 | "outDir": "dist", 12 | "lib": [ 13 | "ESNext", 14 | ], 15 | "noImplicitAny": true, 16 | "strictNullChecks": true, 17 | "preserveConstEnums": true, 18 | "noImplicitOverride": true, 19 | "noImplicitReturns": true, 20 | "noImplicitThis": true, 21 | "noFallthroughCasesInSwitch": false, 22 | "forceConsistentCasingInFileNames": true, 23 | "resolveJsonModule": true, 24 | }, 25 | "include": [ 26 | "java2ts.ts", 27 | "process-options.ts", 28 | ], 29 | "exclude": [ 30 | "dist", 31 | "node_modules", 32 | ], 33 | "compileOnSave": true, 34 | } 35 | -------------------------------------------------------------------------------- /cspell.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2", 3 | "words": [ 4 | "antlr", 5 | "Appendable", 6 | "Charsets", 7 | "Cloneable", 8 | "closeables", 9 | "Declarators", 10 | "Deque", 11 | "Deserialisation", 12 | "Hashable", 13 | "initialisation", 14 | "initialised", 15 | "Initialisers", 16 | "initialises", 17 | "instanceof", 18 | "interruptible", 19 | "JREE", 20 | "misformatted", 21 | "NONSPACING", 22 | "Serialisation", 23 | "signum", 24 | "subfolders", 25 | "synchronisation", 26 | "TITLECASE", 27 | "whitespaces" 28 | ], 29 | "ignoreWords": [ 30 | "ANTL", 31 | "COLONCOLON", 32 | "Dlanguage", 33 | "FEFFFFFFFFFFFFF", 34 | "Harwell", 35 | "Hashtable", 36 | "Kona", 37 | "LBRACK", 38 | "LPAREN", 39 | "RBRACK", 40 | "RPAREN", 41 | "Xexact", 42 | "a4tstool", 43 | "allclasses", 44 | "arraycopy", 45 | "bitness", 46 | "chrono", 47 | "clazz", 48 | "javax", 49 | "mmap", 50 | "nanos", 51 | "outfile", 52 | "spliterator", 53 | "strictfp", 54 | "stringbuilder", 55 | "stringtemplate", 56 | "testlibrary", 57 | "testng", 58 | "testsuite", 59 | "typeof", 60 | "unmappable", 61 | "unmocked", 62 | "uxxxx", 63 | "ᬠᬣᬦᬪᬫᬬᬭ" 64 | ], 65 | "ignorePaths": [ 66 | ".eslintrc.json", 67 | "parser", 68 | "data" 69 | ] 70 | } 71 | -------------------------------------------------------------------------------- /data/java.lang.annotation.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.lang.annotation.Annotation", 4 | "type": "interface", 5 | "modifiers": [], 6 | "extends": [], 7 | "implements": [], 8 | "members": [ 9 | { 10 | "name": "annotationType", 11 | "modifiers": [], 12 | "type": "method" 13 | }, 14 | { 15 | "name": "equals", 16 | "modifiers": [], 17 | "type": "method" 18 | }, 19 | { 20 | "name": "hashCode", 21 | "modifiers": [], 22 | "type": "method" 23 | }, 24 | { 25 | "name": "toString", 26 | "modifiers": [], 27 | "type": "method" 28 | } 29 | ] 30 | }, 31 | { 32 | "name": "java.lang.annotation.AnnotationFormatError", 33 | "type": "class", 34 | "modifiers": [], 35 | "extends": [ 36 | "java.lang.Error" 37 | ], 38 | "implements": [], 39 | "members": [] 40 | }, 41 | { 42 | "name": "java.lang.annotation.AnnotationTypeMismatchException", 43 | "type": "class", 44 | "modifiers": [], 45 | "extends": [ 46 | "java.lang.RuntimeException" 47 | ], 48 | "implements": [], 49 | "members": [ 50 | { 51 | "name": "element", 52 | "modifiers": [], 53 | "type": "method" 54 | }, 55 | { 56 | "name": "foundType", 57 | "modifiers": [], 58 | "type": "method" 59 | } 60 | ] 61 | }, 62 | { 63 | "name": "java.lang.annotation.Type", 64 | "type": "annotation", 65 | "modifiers": [], 66 | "extends": [ 67 | "java.lang.Object" 68 | ], 69 | "implements": [], 70 | "members": [] 71 | }, 72 | { 73 | "name": "java.lang.annotation.ElementType", 74 | "type": "enum", 75 | "modifiers": [], 76 | "extends": [ 77 | "java.lang.Enum" 78 | ], 79 | "implements": [], 80 | "members": [ 81 | { 82 | "name": "valueOf", 83 | "modifiers": [ 84 | "static" 85 | ], 86 | "type": "method" 87 | }, 88 | { 89 | "name": "values", 90 | "modifiers": [ 91 | "static" 92 | ], 93 | "type": "method" 94 | } 95 | ] 96 | }, 97 | { 98 | "name": "java.lang.annotation.IncompleteAnnotationException", 99 | "type": "class", 100 | "modifiers": [], 101 | "extends": [ 102 | "java.lang.RuntimeException" 103 | ], 104 | "implements": [], 105 | "members": [ 106 | { 107 | "name": "annotationType", 108 | "modifiers": [], 109 | "type": "method" 110 | }, 111 | { 112 | "name": "elementName", 113 | "modifiers": [], 114 | "type": "method" 115 | } 116 | ] 117 | }, 118 | { 119 | "name": "java.lang.annotation.Type", 120 | "type": "annotation", 121 | "modifiers": [], 122 | "extends": [ 123 | "java.lang.Object" 124 | ], 125 | "implements": [], 126 | "members": [] 127 | }, 128 | { 129 | "name": "java.lang.annotation.Type", 130 | "type": "annotation", 131 | "modifiers": [], 132 | "extends": [ 133 | "java.lang.Object" 134 | ], 135 | "implements": [], 136 | "members": [] 137 | }, 138 | { 139 | "name": "java.lang.annotation.Type", 140 | "type": "annotation", 141 | "modifiers": [], 142 | "extends": [ 143 | "java.lang.Object" 144 | ], 145 | "implements": [], 146 | "members": [] 147 | }, 148 | { 149 | "name": "java.lang.annotation.Type", 150 | "type": "annotation", 151 | "modifiers": [], 152 | "extends": [ 153 | "java.lang.Object" 154 | ], 155 | "implements": [], 156 | "members": [] 157 | }, 158 | { 159 | "name": "java.lang.annotation.RetentionPolicy", 160 | "type": "enum", 161 | "modifiers": [], 162 | "extends": [ 163 | "java.lang.Enum" 164 | ], 165 | "implements": [], 166 | "members": [ 167 | { 168 | "name": "valueOf", 169 | "modifiers": [ 170 | "static" 171 | ], 172 | "type": "method" 173 | }, 174 | { 175 | "name": "values", 176 | "modifiers": [ 177 | "static" 178 | ], 179 | "type": "method" 180 | } 181 | ] 182 | }, 183 | { 184 | "name": "java.lang.annotation.Type", 185 | "type": "annotation", 186 | "modifiers": [], 187 | "extends": [ 188 | "java.lang.Object" 189 | ], 190 | "implements": [], 191 | "members": [] 192 | } 193 | ] -------------------------------------------------------------------------------- /data/java.lang.instrument.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.lang.instrument.ClassDefinition", 4 | "type": "class", 5 | "modifiers": [], 6 | "extends": [ 7 | "java.lang.Object" 8 | ], 9 | "implements": [], 10 | "members": [ 11 | { 12 | "name": "getDefinitionClass", 13 | "modifiers": [], 14 | "type": "method" 15 | }, 16 | { 17 | "name": "getDefinitionClassFile", 18 | "modifiers": [], 19 | "type": "method" 20 | } 21 | ] 22 | }, 23 | { 24 | "name": "java.lang.instrument.ClassFileTransformer", 25 | "type": "interface", 26 | "modifiers": [], 27 | "extends": [], 28 | "implements": [], 29 | "members": [ 30 | { 31 | "name": "transform", 32 | "modifiers": [], 33 | "type": "method" 34 | }, 35 | { 36 | "name": "transform", 37 | "modifiers": [], 38 | "type": "method" 39 | } 40 | ] 41 | }, 42 | { 43 | "name": "java.lang.instrument.IllegalClassFormatException", 44 | "type": "class", 45 | "modifiers": [], 46 | "extends": [ 47 | "java.lang.Exception" 48 | ], 49 | "implements": [], 50 | "members": [] 51 | }, 52 | { 53 | "name": "java.lang.instrument.Instrumentation", 54 | "type": "interface", 55 | "modifiers": [], 56 | "extends": [], 57 | "implements": [], 58 | "members": [ 59 | { 60 | "name": "addTransformer", 61 | "modifiers": [], 62 | "type": "method" 63 | }, 64 | { 65 | "name": "addTransformer", 66 | "modifiers": [], 67 | "type": "method" 68 | }, 69 | { 70 | "name": "appendToBootstrapClassLoaderSearch", 71 | "modifiers": [], 72 | "type": "method" 73 | }, 74 | { 75 | "name": "appendToSystemClassLoaderSearch", 76 | "modifiers": [], 77 | "type": "method" 78 | }, 79 | { 80 | "name": "getAllLoadedClasses", 81 | "modifiers": [], 82 | "type": "method" 83 | }, 84 | { 85 | "name": "getInitiatedClasses", 86 | "modifiers": [], 87 | "type": "method" 88 | }, 89 | { 90 | "name": "getObjectSize", 91 | "modifiers": [], 92 | "type": "method" 93 | }, 94 | { 95 | "name": "isModifiableClass", 96 | "modifiers": [], 97 | "type": "method" 98 | }, 99 | { 100 | "name": "isModifiableModule", 101 | "modifiers": [], 102 | "type": "method" 103 | }, 104 | { 105 | "name": "isNativeMethodPrefixSupported", 106 | "modifiers": [], 107 | "type": "method" 108 | }, 109 | { 110 | "name": "isRedefineClassesSupported", 111 | "modifiers": [], 112 | "type": "method" 113 | }, 114 | { 115 | "name": "isRetransformClassesSupported", 116 | "modifiers": [], 117 | "type": "method" 118 | }, 119 | { 120 | "name": "redefineClasses", 121 | "modifiers": [], 122 | "type": "method" 123 | }, 124 | { 125 | "name": "redefineModule", 126 | "modifiers": [], 127 | "type": "method" 128 | }, 129 | { 130 | "name": "removeTransformer", 131 | "modifiers": [], 132 | "type": "method" 133 | }, 134 | { 135 | "name": "retransformClasses", 136 | "modifiers": [], 137 | "type": "method" 138 | }, 139 | { 140 | "name": "setNativeMethodPrefix", 141 | "modifiers": [], 142 | "type": "method" 143 | } 144 | ] 145 | }, 146 | { 147 | "name": "java.lang.instrument.UnmodifiableClassException", 148 | "type": "class", 149 | "modifiers": [], 150 | "extends": [ 151 | "java.lang.Exception" 152 | ], 153 | "implements": [], 154 | "members": [] 155 | }, 156 | { 157 | "name": "java.lang.instrument.UnmodifiableModuleException", 158 | "type": "class", 159 | "modifiers": [], 160 | "extends": [ 161 | "java.lang.RuntimeException" 162 | ], 163 | "implements": [], 164 | "members": [] 165 | } 166 | ] -------------------------------------------------------------------------------- /data/java.lang.ref.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.lang.ref.Cleaner", 4 | "type": "class", 5 | "modifiers": [], 6 | "extends": [ 7 | "java.lang.Object" 8 | ], 9 | "implements": [], 10 | "members": [ 11 | { 12 | "name": "Cleaner.Cleanable", 13 | "modifiers": [ 14 | "static" 15 | ], 16 | "type": "class" 17 | }, 18 | { 19 | "name": "create", 20 | "modifiers": [ 21 | "static" 22 | ], 23 | "type": "method" 24 | }, 25 | { 26 | "name": "create", 27 | "modifiers": [ 28 | "static" 29 | ], 30 | "type": "method" 31 | }, 32 | { 33 | "name": "register", 34 | "modifiers": [], 35 | "type": "method" 36 | } 37 | ] 38 | }, 39 | { 40 | "name": "java.lang.ref.Cleaner.Cleanable", 41 | "type": "interface", 42 | "modifiers": [], 43 | "extends": [], 44 | "implements": [], 45 | "members": [ 46 | { 47 | "name": "clean", 48 | "modifiers": [], 49 | "type": "method" 50 | } 51 | ] 52 | }, 53 | { 54 | "name": "java.lang.ref.PhantomReference", 55 | "type": "class", 56 | "modifiers": [], 57 | "extends": [ 58 | "java.lang.ref.Reference" 59 | ], 60 | "implements": [], 61 | "members": [ 62 | { 63 | "name": "get", 64 | "modifiers": [], 65 | "type": "method" 66 | } 67 | ], 68 | "typeParameters": "" 69 | }, 70 | { 71 | "name": "java.lang.ref.Reference", 72 | "type": "class", 73 | "modifiers": [ 74 | "abstract" 75 | ], 76 | "extends": [ 77 | "java.lang.Object" 78 | ], 79 | "implements": [], 80 | "members": [ 81 | { 82 | "name": "clear", 83 | "modifiers": [], 84 | "type": "method" 85 | }, 86 | { 87 | "name": "clone", 88 | "modifiers": [], 89 | "type": "method" 90 | }, 91 | { 92 | "name": "enqueue", 93 | "modifiers": [], 94 | "type": "method" 95 | }, 96 | { 97 | "name": "get", 98 | "modifiers": [], 99 | "type": "method" 100 | }, 101 | { 102 | "name": "isEnqueued", 103 | "modifiers": [], 104 | "type": "method" 105 | }, 106 | { 107 | "name": "reachabilityFence", 108 | "modifiers": [ 109 | "static" 110 | ], 111 | "type": "method" 112 | } 113 | ], 114 | "typeParameters": "" 115 | }, 116 | { 117 | "name": "java.lang.ref.ReferenceQueue", 118 | "type": "class", 119 | "modifiers": [], 120 | "extends": [ 121 | "java.lang.Object" 122 | ], 123 | "implements": [], 124 | "members": [ 125 | { 126 | "name": "poll", 127 | "modifiers": [], 128 | "type": "method" 129 | }, 130 | { 131 | "name": "remove", 132 | "modifiers": [], 133 | "type": "method" 134 | }, 135 | { 136 | "name": "remove", 137 | "modifiers": [], 138 | "type": "method" 139 | } 140 | ], 141 | "typeParameters": "" 142 | }, 143 | { 144 | "name": "java.lang.ref.SoftReference", 145 | "type": "class", 146 | "modifiers": [], 147 | "extends": [ 148 | "java.lang.ref.Reference" 149 | ], 150 | "implements": [], 151 | "members": [ 152 | { 153 | "name": "get", 154 | "modifiers": [], 155 | "type": "method" 156 | } 157 | ], 158 | "typeParameters": "" 159 | }, 160 | { 161 | "name": "java.lang.ref.WeakReference", 162 | "type": "class", 163 | "modifiers": [], 164 | "extends": [ 165 | "java.lang.ref.Reference" 166 | ], 167 | "implements": [], 168 | "members": [], 169 | "typeParameters": "" 170 | } 171 | ] -------------------------------------------------------------------------------- /data/java.net.spi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.net.spi.URLStreamHandlerProvider", 4 | "type": "class", 5 | "modifiers": [ 6 | "abstract" 7 | ], 8 | "extends": [ 9 | "java.lang.Object" 10 | ], 11 | "implements": [ 12 | "java.net.URLStreamHandlerFactory" 13 | ], 14 | "members": [] 15 | } 16 | ] -------------------------------------------------------------------------------- /data/java.nio.channels.spi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.nio.channels.spi.AbstractInterruptibleChannel", 4 | "type": "class", 5 | "modifiers": [ 6 | "abstract" 7 | ], 8 | "extends": [ 9 | "java.lang.Object" 10 | ], 11 | "implements": [ 12 | "java.nio.channels.Channel", 13 | "java.nio.channels.InterruptibleChannel" 14 | ], 15 | "members": [ 16 | { 17 | "name": "begin", 18 | "modifiers": [], 19 | "type": "method" 20 | }, 21 | { 22 | "name": "close", 23 | "modifiers": [], 24 | "type": "method" 25 | }, 26 | { 27 | "name": "end", 28 | "modifiers": [], 29 | "type": "method" 30 | }, 31 | { 32 | "name": "implCloseChannel", 33 | "modifiers": [], 34 | "type": "method" 35 | } 36 | ] 37 | }, 38 | { 39 | "name": "java.nio.channels.spi.AbstractSelectableChannel", 40 | "type": "class", 41 | "modifiers": [ 42 | "abstract" 43 | ], 44 | "extends": [ 45 | "java.nio.channels.SelectableChannel" 46 | ], 47 | "implements": [], 48 | "members": [ 49 | { 50 | "name": "configureBlocking", 51 | "modifiers": [], 52 | "type": "method" 53 | }, 54 | { 55 | "name": "implCloseChannel", 56 | "modifiers": [], 57 | "type": "method" 58 | }, 59 | { 60 | "name": "implCloseSelectableChannel", 61 | "modifiers": [], 62 | "type": "method" 63 | }, 64 | { 65 | "name": "implConfigureBlocking", 66 | "modifiers": [], 67 | "type": "method" 68 | }, 69 | { 70 | "name": "provider", 71 | "modifiers": [], 72 | "type": "method" 73 | }, 74 | { 75 | "name": "register", 76 | "modifiers": [], 77 | "type": "method" 78 | } 79 | ] 80 | }, 81 | { 82 | "name": "java.nio.channels.spi.AbstractSelectionKey", 83 | "type": "class", 84 | "modifiers": [ 85 | "abstract" 86 | ], 87 | "extends": [ 88 | "java.nio.channels.SelectionKey" 89 | ], 90 | "implements": [], 91 | "members": [ 92 | { 93 | "name": "cancel", 94 | "modifiers": [], 95 | "type": "method" 96 | } 97 | ] 98 | }, 99 | { 100 | "name": "java.nio.channels.spi.AbstractSelector", 101 | "type": "class", 102 | "modifiers": [ 103 | "abstract" 104 | ], 105 | "extends": [ 106 | "java.nio.channels.Selector" 107 | ], 108 | "implements": [], 109 | "members": [ 110 | { 111 | "name": "begin", 112 | "modifiers": [], 113 | "type": "method" 114 | }, 115 | { 116 | "name": "cancelledKeys", 117 | "modifiers": [], 118 | "type": "method" 119 | }, 120 | { 121 | "name": "close", 122 | "modifiers": [], 123 | "type": "method" 124 | }, 125 | { 126 | "name": "deregister", 127 | "modifiers": [], 128 | "type": "method" 129 | }, 130 | { 131 | "name": "end", 132 | "modifiers": [], 133 | "type": "method" 134 | }, 135 | { 136 | "name": "implCloseSelector", 137 | "modifiers": [], 138 | "type": "method" 139 | }, 140 | { 141 | "name": "provider", 142 | "modifiers": [], 143 | "type": "method" 144 | }, 145 | { 146 | "name": "register", 147 | "modifiers": [], 148 | "type": "method" 149 | } 150 | ] 151 | }, 152 | { 153 | "name": "java.nio.channels.spi.AsynchronousChannelProvider", 154 | "type": "class", 155 | "modifiers": [ 156 | "abstract" 157 | ], 158 | "extends": [ 159 | "java.lang.Object" 160 | ], 161 | "implements": [], 162 | "members": [ 163 | { 164 | "name": "openAsynchronousChannelGroup", 165 | "modifiers": [], 166 | "type": "method" 167 | }, 168 | { 169 | "name": "openAsynchronousChannelGroup", 170 | "modifiers": [], 171 | "type": "method" 172 | }, 173 | { 174 | "name": "openAsynchronousServerSocketChannel", 175 | "modifiers": [], 176 | "type": "method" 177 | }, 178 | { 179 | "name": "openAsynchronousSocketChannel", 180 | "modifiers": [], 181 | "type": "method" 182 | }, 183 | { 184 | "name": "provider", 185 | "modifiers": [ 186 | "static" 187 | ], 188 | "type": "method" 189 | } 190 | ] 191 | }, 192 | { 193 | "name": "java.nio.channels.spi.SelectorProvider", 194 | "type": "class", 195 | "modifiers": [ 196 | "abstract" 197 | ], 198 | "extends": [ 199 | "java.lang.Object" 200 | ], 201 | "implements": [], 202 | "members": [ 203 | { 204 | "name": "inheritedChannel", 205 | "modifiers": [], 206 | "type": "method" 207 | }, 208 | { 209 | "name": "openDatagramChannel", 210 | "modifiers": [], 211 | "type": "method" 212 | }, 213 | { 214 | "name": "openDatagramChannel", 215 | "modifiers": [], 216 | "type": "method" 217 | }, 218 | { 219 | "name": "openPipe", 220 | "modifiers": [], 221 | "type": "method" 222 | }, 223 | { 224 | "name": "openSelector", 225 | "modifiers": [], 226 | "type": "method" 227 | }, 228 | { 229 | "name": "openServerSocketChannel", 230 | "modifiers": [], 231 | "type": "method" 232 | }, 233 | { 234 | "name": "openSocketChannel", 235 | "modifiers": [], 236 | "type": "method" 237 | }, 238 | { 239 | "name": "provider", 240 | "modifiers": [ 241 | "static" 242 | ], 243 | "type": "method" 244 | } 245 | ] 246 | } 247 | ] -------------------------------------------------------------------------------- /data/java.nio.charset.spi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.nio.charset.spi.CharsetProvider", 4 | "type": "class", 5 | "modifiers": [ 6 | "abstract" 7 | ], 8 | "extends": [ 9 | "java.lang.Object" 10 | ], 11 | "implements": [], 12 | "members": [ 13 | { 14 | "name": "charsetForName", 15 | "modifiers": [], 16 | "type": "method" 17 | }, 18 | { 19 | "name": "charsets", 20 | "modifiers": [], 21 | "type": "method" 22 | } 23 | ] 24 | } 25 | ] -------------------------------------------------------------------------------- /data/java.nio.file.spi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.nio.file.spi.FileSystemProvider", 4 | "type": "class", 5 | "modifiers": [ 6 | "abstract" 7 | ], 8 | "extends": [ 9 | "java.lang.Object" 10 | ], 11 | "implements": [], 12 | "members": [ 13 | { 14 | "name": "checkAccess", 15 | "modifiers": [], 16 | "type": "method" 17 | }, 18 | { 19 | "name": "copy", 20 | "modifiers": [], 21 | "type": "method" 22 | }, 23 | { 24 | "name": "createDirectory", 25 | "modifiers": [], 26 | "type": "method" 27 | }, 28 | { 29 | "name": "createLink", 30 | "modifiers": [], 31 | "type": "method" 32 | }, 33 | { 34 | "name": "createSymbolicLink", 35 | "modifiers": [], 36 | "type": "method" 37 | }, 38 | { 39 | "name": "delete", 40 | "modifiers": [], 41 | "type": "method" 42 | }, 43 | { 44 | "name": "deleteIfExists", 45 | "modifiers": [], 46 | "type": "method" 47 | }, 48 | { 49 | "name": "getFileAttributeView", 50 | "modifiers": [], 51 | "type": "method" 52 | }, 53 | { 54 | "name": "getFileStore", 55 | "modifiers": [], 56 | "type": "method" 57 | }, 58 | { 59 | "name": "getFileSystem", 60 | "modifiers": [], 61 | "type": "method" 62 | }, 63 | { 64 | "name": "getPath", 65 | "modifiers": [], 66 | "type": "method" 67 | }, 68 | { 69 | "name": "getScheme", 70 | "modifiers": [], 71 | "type": "method" 72 | }, 73 | { 74 | "name": "installedProviders", 75 | "modifiers": [ 76 | "static" 77 | ], 78 | "type": "method" 79 | }, 80 | { 81 | "name": "isHidden", 82 | "modifiers": [], 83 | "type": "method" 84 | }, 85 | { 86 | "name": "isSameFile", 87 | "modifiers": [], 88 | "type": "method" 89 | }, 90 | { 91 | "name": "move", 92 | "modifiers": [], 93 | "type": "method" 94 | }, 95 | { 96 | "name": "newAsynchronousFileChannel", 97 | "modifiers": [], 98 | "type": "method" 99 | }, 100 | { 101 | "name": "newByteChannel", 102 | "modifiers": [], 103 | "type": "method" 104 | }, 105 | { 106 | "name": "newDirectoryStream", 107 | "modifiers": [], 108 | "type": "method" 109 | }, 110 | { 111 | "name": "newFileChannel", 112 | "modifiers": [], 113 | "type": "method" 114 | }, 115 | { 116 | "name": "newFileSystem", 117 | "modifiers": [], 118 | "type": "method" 119 | }, 120 | { 121 | "name": "newFileSystem", 122 | "modifiers": [], 123 | "type": "method" 124 | }, 125 | { 126 | "name": "newInputStream", 127 | "modifiers": [], 128 | "type": "method" 129 | }, 130 | { 131 | "name": "newOutputStream", 132 | "modifiers": [], 133 | "type": "method" 134 | }, 135 | { 136 | "name": "readAttributes", 137 | "modifiers": [], 138 | "type": "method" 139 | }, 140 | { 141 | "name": "readAttributes", 142 | "modifiers": [], 143 | "type": "method" 144 | }, 145 | { 146 | "name": "readSymbolicLink", 147 | "modifiers": [], 148 | "type": "method" 149 | }, 150 | { 151 | "name": "setAttribute", 152 | "modifiers": [], 153 | "type": "method" 154 | } 155 | ] 156 | }, 157 | { 158 | "name": "java.nio.file.spi.FileTypeDetector", 159 | "type": "class", 160 | "modifiers": [ 161 | "abstract" 162 | ], 163 | "extends": [ 164 | "java.lang.Object" 165 | ], 166 | "implements": [], 167 | "members": [ 168 | { 169 | "name": "probeContentType", 170 | "modifiers": [], 171 | "type": "method" 172 | } 173 | ] 174 | } 175 | ] -------------------------------------------------------------------------------- /data/java.security.acl.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.security.acl.Acl", 4 | "type": "interface", 5 | "modifiers": [], 6 | "extends": [ 7 | "java.security.acl.Owner" 8 | ], 9 | "implements": [], 10 | "members": [ 11 | { 12 | "name": "addEntry", 13 | "modifiers": [], 14 | "type": "method" 15 | }, 16 | { 17 | "name": "checkPermission", 18 | "modifiers": [], 19 | "type": "method" 20 | }, 21 | { 22 | "name": "entries", 23 | "modifiers": [], 24 | "type": "method" 25 | }, 26 | { 27 | "name": "getName", 28 | "modifiers": [], 29 | "type": "method" 30 | }, 31 | { 32 | "name": "getPermissions", 33 | "modifiers": [], 34 | "type": "method" 35 | }, 36 | { 37 | "name": "removeEntry", 38 | "modifiers": [], 39 | "type": "method" 40 | }, 41 | { 42 | "name": "setName", 43 | "modifiers": [], 44 | "type": "method" 45 | }, 46 | { 47 | "name": "toString", 48 | "modifiers": [], 49 | "type": "method" 50 | } 51 | ] 52 | }, 53 | { 54 | "name": "java.security.acl.AclEntry", 55 | "type": "interface", 56 | "modifiers": [], 57 | "extends": [ 58 | "java.lang.Cloneable" 59 | ], 60 | "implements": [], 61 | "members": [ 62 | { 63 | "name": "addPermission", 64 | "modifiers": [], 65 | "type": "method" 66 | }, 67 | { 68 | "name": "checkPermission", 69 | "modifiers": [], 70 | "type": "method" 71 | }, 72 | { 73 | "name": "clone", 74 | "modifiers": [], 75 | "type": "method" 76 | }, 77 | { 78 | "name": "getPrincipal", 79 | "modifiers": [], 80 | "type": "method" 81 | }, 82 | { 83 | "name": "isNegative", 84 | "modifiers": [], 85 | "type": "method" 86 | }, 87 | { 88 | "name": "permissions", 89 | "modifiers": [], 90 | "type": "method" 91 | }, 92 | { 93 | "name": "removePermission", 94 | "modifiers": [], 95 | "type": "method" 96 | }, 97 | { 98 | "name": "setNegativePermissions", 99 | "modifiers": [], 100 | "type": "method" 101 | }, 102 | { 103 | "name": "setPrincipal", 104 | "modifiers": [], 105 | "type": "method" 106 | }, 107 | { 108 | "name": "toString", 109 | "modifiers": [], 110 | "type": "method" 111 | } 112 | ] 113 | }, 114 | { 115 | "name": "java.security.acl.AclNotFoundException", 116 | "type": "class", 117 | "modifiers": [], 118 | "extends": [ 119 | "java.lang.Exception" 120 | ], 121 | "implements": [], 122 | "members": [] 123 | }, 124 | { 125 | "name": "java.security.acl.Group", 126 | "type": "interface", 127 | "modifiers": [], 128 | "extends": [ 129 | "java.security.Principal" 130 | ], 131 | "implements": [], 132 | "members": [ 133 | { 134 | "name": "addMember", 135 | "modifiers": [], 136 | "type": "method" 137 | }, 138 | { 139 | "name": "isMember", 140 | "modifiers": [], 141 | "type": "method" 142 | }, 143 | { 144 | "name": "members", 145 | "modifiers": [], 146 | "type": "method" 147 | }, 148 | { 149 | "name": "removeMember", 150 | "modifiers": [], 151 | "type": "method" 152 | } 153 | ] 154 | }, 155 | { 156 | "name": "java.security.acl.LastOwnerException", 157 | "type": "class", 158 | "modifiers": [], 159 | "extends": [ 160 | "java.lang.Exception" 161 | ], 162 | "implements": [], 163 | "members": [] 164 | }, 165 | { 166 | "name": "java.security.acl.NotOwnerException", 167 | "type": "class", 168 | "modifiers": [], 169 | "extends": [ 170 | "java.lang.Exception" 171 | ], 172 | "implements": [], 173 | "members": [] 174 | }, 175 | { 176 | "name": "java.security.acl.Owner", 177 | "type": "interface", 178 | "modifiers": [], 179 | "extends": [], 180 | "implements": [], 181 | "members": [ 182 | { 183 | "name": "addOwner", 184 | "modifiers": [], 185 | "type": "method" 186 | }, 187 | { 188 | "name": "deleteOwner", 189 | "modifiers": [], 190 | "type": "method" 191 | }, 192 | { 193 | "name": "isOwner", 194 | "modifiers": [], 195 | "type": "method" 196 | } 197 | ] 198 | }, 199 | { 200 | "name": "java.security.acl.Permission", 201 | "type": "interface", 202 | "modifiers": [], 203 | "extends": [], 204 | "implements": [], 205 | "members": [ 206 | { 207 | "name": "equals", 208 | "modifiers": [], 209 | "type": "method" 210 | }, 211 | { 212 | "name": "toString", 213 | "modifiers": [], 214 | "type": "method" 215 | } 216 | ] 217 | } 218 | ] -------------------------------------------------------------------------------- /data/java.text.spi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.text.spi.BreakIteratorProvider", 4 | "type": "class", 5 | "modifiers": [ 6 | "abstract" 7 | ], 8 | "extends": [ 9 | "java.util.spi.LocaleServiceProvider" 10 | ], 11 | "implements": [], 12 | "members": [ 13 | { 14 | "name": "getCharacterInstance", 15 | "modifiers": [], 16 | "type": "method" 17 | }, 18 | { 19 | "name": "getLineInstance", 20 | "modifiers": [], 21 | "type": "method" 22 | }, 23 | { 24 | "name": "getSentenceInstance", 25 | "modifiers": [], 26 | "type": "method" 27 | }, 28 | { 29 | "name": "getWordInstance", 30 | "modifiers": [], 31 | "type": "method" 32 | } 33 | ] 34 | }, 35 | { 36 | "name": "java.text.spi.CollatorProvider", 37 | "type": "class", 38 | "modifiers": [ 39 | "abstract" 40 | ], 41 | "extends": [ 42 | "java.util.spi.LocaleServiceProvider" 43 | ], 44 | "implements": [], 45 | "members": [ 46 | { 47 | "name": "getInstance", 48 | "modifiers": [], 49 | "type": "method" 50 | } 51 | ] 52 | }, 53 | { 54 | "name": "java.text.spi.DateFormatProvider", 55 | "type": "class", 56 | "modifiers": [ 57 | "abstract" 58 | ], 59 | "extends": [ 60 | "java.util.spi.LocaleServiceProvider" 61 | ], 62 | "implements": [], 63 | "members": [ 64 | { 65 | "name": "getDateInstance", 66 | "modifiers": [], 67 | "type": "method" 68 | }, 69 | { 70 | "name": "getDateTimeInstance", 71 | "modifiers": [], 72 | "type": "method" 73 | }, 74 | { 75 | "name": "getTimeInstance", 76 | "modifiers": [], 77 | "type": "method" 78 | } 79 | ] 80 | }, 81 | { 82 | "name": "java.text.spi.DateFormatSymbolsProvider", 83 | "type": "class", 84 | "modifiers": [ 85 | "abstract" 86 | ], 87 | "extends": [ 88 | "java.util.spi.LocaleServiceProvider" 89 | ], 90 | "implements": [], 91 | "members": [ 92 | { 93 | "name": "getInstance", 94 | "modifiers": [], 95 | "type": "method" 96 | } 97 | ] 98 | }, 99 | { 100 | "name": "java.text.spi.DecimalFormatSymbolsProvider", 101 | "type": "class", 102 | "modifiers": [ 103 | "abstract" 104 | ], 105 | "extends": [ 106 | "java.util.spi.LocaleServiceProvider" 107 | ], 108 | "implements": [], 109 | "members": [ 110 | { 111 | "name": "getInstance", 112 | "modifiers": [], 113 | "type": "method" 114 | } 115 | ] 116 | }, 117 | { 118 | "name": "java.text.spi.NumberFormatProvider", 119 | "type": "class", 120 | "modifiers": [ 121 | "abstract" 122 | ], 123 | "extends": [ 124 | "java.util.spi.LocaleServiceProvider" 125 | ], 126 | "implements": [], 127 | "members": [ 128 | { 129 | "name": "getCurrencyInstance", 130 | "modifiers": [], 131 | "type": "method" 132 | }, 133 | { 134 | "name": "getIntegerInstance", 135 | "modifiers": [], 136 | "type": "method" 137 | }, 138 | { 139 | "name": "getNumberInstance", 140 | "modifiers": [], 141 | "type": "method" 142 | }, 143 | { 144 | "name": "getPercentInstance", 145 | "modifiers": [], 146 | "type": "method" 147 | } 148 | ] 149 | } 150 | ] -------------------------------------------------------------------------------- /data/java.util.spi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "java.util.spi.AbstractResourceBundleProvider", 4 | "type": "class", 5 | "modifiers": [ 6 | "abstract" 7 | ], 8 | "extends": [ 9 | "java.lang.Object" 10 | ], 11 | "implements": [ 12 | "java.util.spi.ResourceBundleProvider" 13 | ], 14 | "members": [ 15 | { 16 | "name": "getBundle", 17 | "modifiers": [], 18 | "type": "method" 19 | }, 20 | { 21 | "name": "toBundleName", 22 | "modifiers": [], 23 | "type": "method" 24 | } 25 | ] 26 | }, 27 | { 28 | "name": "java.util.spi.CalendarDataProvider", 29 | "type": "class", 30 | "modifiers": [ 31 | "abstract" 32 | ], 33 | "extends": [ 34 | "java.util.spi.LocaleServiceProvider" 35 | ], 36 | "implements": [], 37 | "members": [ 38 | { 39 | "name": "getFirstDayOfWeek", 40 | "modifiers": [], 41 | "type": "method" 42 | }, 43 | { 44 | "name": "getMinimalDaysInFirstWeek", 45 | "modifiers": [], 46 | "type": "method" 47 | } 48 | ] 49 | }, 50 | { 51 | "name": "java.util.spi.CalendarNameProvider", 52 | "type": "class", 53 | "modifiers": [ 54 | "abstract" 55 | ], 56 | "extends": [ 57 | "java.util.spi.LocaleServiceProvider" 58 | ], 59 | "implements": [], 60 | "members": [ 61 | { 62 | "name": "getDisplayName", 63 | "modifiers": [], 64 | "type": "method" 65 | }, 66 | { 67 | "name": "getDisplayNames", 68 | "modifiers": [], 69 | "type": "method" 70 | } 71 | ] 72 | }, 73 | { 74 | "name": "java.util.spi.CurrencyNameProvider", 75 | "type": "class", 76 | "modifiers": [ 77 | "abstract" 78 | ], 79 | "extends": [ 80 | "java.util.spi.LocaleServiceProvider" 81 | ], 82 | "implements": [], 83 | "members": [ 84 | { 85 | "name": "getDisplayName", 86 | "modifiers": [], 87 | "type": "method" 88 | }, 89 | { 90 | "name": "getSymbol", 91 | "modifiers": [], 92 | "type": "method" 93 | } 94 | ] 95 | }, 96 | { 97 | "name": "java.util.spi.LocaleNameProvider", 98 | "type": "class", 99 | "modifiers": [ 100 | "abstract" 101 | ], 102 | "extends": [ 103 | "java.util.spi.LocaleServiceProvider" 104 | ], 105 | "implements": [], 106 | "members": [ 107 | { 108 | "name": "getDisplayCountry", 109 | "modifiers": [], 110 | "type": "method" 111 | }, 112 | { 113 | "name": "getDisplayLanguage", 114 | "modifiers": [], 115 | "type": "method" 116 | }, 117 | { 118 | "name": "getDisplayScript", 119 | "modifiers": [], 120 | "type": "method" 121 | }, 122 | { 123 | "name": "getDisplayUnicodeExtensionKey", 124 | "modifiers": [], 125 | "type": "method" 126 | }, 127 | { 128 | "name": "getDisplayUnicodeExtensionType", 129 | "modifiers": [], 130 | "type": "method" 131 | }, 132 | { 133 | "name": "getDisplayVariant", 134 | "modifiers": [], 135 | "type": "method" 136 | } 137 | ] 138 | }, 139 | { 140 | "name": "java.util.spi.LocaleServiceProvider", 141 | "type": "class", 142 | "modifiers": [ 143 | "abstract" 144 | ], 145 | "extends": [ 146 | "java.lang.Object" 147 | ], 148 | "implements": [], 149 | "members": [ 150 | { 151 | "name": "getAvailableLocales", 152 | "modifiers": [], 153 | "type": "method" 154 | }, 155 | { 156 | "name": "isSupportedLocale", 157 | "modifiers": [], 158 | "type": "method" 159 | } 160 | ] 161 | }, 162 | { 163 | "name": "java.util.spi.ResourceBundleControlProvider", 164 | "type": "interface", 165 | "modifiers": [], 166 | "extends": [], 167 | "implements": [], 168 | "members": [ 169 | { 170 | "name": "getControl", 171 | "modifiers": [], 172 | "type": "method" 173 | } 174 | ] 175 | }, 176 | { 177 | "name": "java.util.spi.ResourceBundleProvider", 178 | "type": "interface", 179 | "modifiers": [], 180 | "extends": [], 181 | "implements": [], 182 | "members": [ 183 | { 184 | "name": "getBundle", 185 | "modifiers": [], 186 | "type": "method" 187 | } 188 | ] 189 | }, 190 | { 191 | "name": "java.util.spi.TimeZoneNameProvider", 192 | "type": "class", 193 | "modifiers": [ 194 | "abstract" 195 | ], 196 | "extends": [ 197 | "java.util.spi.LocaleServiceProvider" 198 | ], 199 | "implements": [], 200 | "members": [ 201 | { 202 | "name": "getDisplayName", 203 | "modifiers": [], 204 | "type": "method" 205 | }, 206 | { 207 | "name": "getGenericDisplayName", 208 | "modifiers": [], 209 | "type": "method" 210 | } 211 | ] 212 | }, 213 | { 214 | "name": "java.util.spi.ToolProvider", 215 | "type": "interface", 216 | "modifiers": [], 217 | "extends": [], 218 | "implements": [], 219 | "members": [ 220 | { 221 | "name": "findFirst", 222 | "modifiers": [ 223 | "static" 224 | ], 225 | "type": "method" 226 | }, 227 | { 228 | "name": "name", 229 | "modifiers": [], 230 | "type": "method" 231 | }, 232 | { 233 | "name": "run", 234 | "modifiers": [], 235 | "type": "method" 236 | }, 237 | { 238 | "name": "run", 239 | "modifiers": [], 240 | "type": "method" 241 | } 242 | ] 243 | } 244 | ] -------------------------------------------------------------------------------- /data/javax.crypto.interfaces.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "javax.crypto.interfaces.DHKey", 4 | "type": "interface", 5 | "modifiers": [], 6 | "extends": [], 7 | "implements": [], 8 | "members": [ 9 | { 10 | "name": "getParams", 11 | "modifiers": [], 12 | "type": "method" 13 | } 14 | ] 15 | }, 16 | { 17 | "name": "javax.crypto.interfaces.DHPrivateKey", 18 | "type": "interface", 19 | "modifiers": [], 20 | "extends": [ 21 | "javax.crypto.interfaces.DHKey", 22 | "java.security.PrivateKey" 23 | ], 24 | "implements": [], 25 | "members": [ 26 | { 27 | "name": "serialVersionUID", 28 | "modifiers": [ 29 | "static" 30 | ], 31 | "type": "field" 32 | }, 33 | { 34 | "name": "getX", 35 | "modifiers": [], 36 | "type": "method" 37 | } 38 | ] 39 | }, 40 | { 41 | "name": "javax.crypto.interfaces.DHPublicKey", 42 | "type": "interface", 43 | "modifiers": [], 44 | "extends": [ 45 | "javax.crypto.interfaces.DHKey", 46 | "java.security.PublicKey" 47 | ], 48 | "implements": [], 49 | "members": [ 50 | { 51 | "name": "serialVersionUID", 52 | "modifiers": [ 53 | "static" 54 | ], 55 | "type": "field" 56 | }, 57 | { 58 | "name": "getY", 59 | "modifiers": [], 60 | "type": "method" 61 | } 62 | ] 63 | }, 64 | { 65 | "name": "javax.crypto.interfaces.PBEKey", 66 | "type": "interface", 67 | "modifiers": [], 68 | "extends": [ 69 | "javax.crypto.SecretKey" 70 | ], 71 | "implements": [], 72 | "members": [ 73 | { 74 | "name": "serialVersionUID", 75 | "modifiers": [ 76 | "static" 77 | ], 78 | "type": "field" 79 | }, 80 | { 81 | "name": "getIterationCount", 82 | "modifiers": [], 83 | "type": "method" 84 | }, 85 | { 86 | "name": "getPassword", 87 | "modifiers": [], 88 | "type": "method" 89 | }, 90 | { 91 | "name": "getSalt", 92 | "modifiers": [], 93 | "type": "method" 94 | } 95 | ] 96 | } 97 | ] -------------------------------------------------------------------------------- /data/javax.net.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "javax.net.ServerSocketFactory", 4 | "type": "class", 5 | "modifiers": [ 6 | "abstract" 7 | ], 8 | "extends": [ 9 | "java.lang.Object" 10 | ], 11 | "implements": [], 12 | "members": [ 13 | { 14 | "name": "createServerSocket", 15 | "modifiers": [], 16 | "type": "method" 17 | }, 18 | { 19 | "name": "createServerSocket", 20 | "modifiers": [], 21 | "type": "method" 22 | }, 23 | { 24 | "name": "createServerSocket", 25 | "modifiers": [], 26 | "type": "method" 27 | }, 28 | { 29 | "name": "createServerSocket", 30 | "modifiers": [], 31 | "type": "method" 32 | }, 33 | { 34 | "name": "getDefault", 35 | "modifiers": [ 36 | "static" 37 | ], 38 | "type": "method" 39 | } 40 | ] 41 | }, 42 | { 43 | "name": "javax.net.SocketFactory", 44 | "type": "class", 45 | "modifiers": [ 46 | "abstract" 47 | ], 48 | "extends": [ 49 | "java.lang.Object" 50 | ], 51 | "implements": [], 52 | "members": [ 53 | { 54 | "name": "createSocket", 55 | "modifiers": [], 56 | "type": "method" 57 | }, 58 | { 59 | "name": "createSocket", 60 | "modifiers": [], 61 | "type": "method" 62 | }, 63 | { 64 | "name": "createSocket", 65 | "modifiers": [], 66 | "type": "method" 67 | }, 68 | { 69 | "name": "createSocket", 70 | "modifiers": [], 71 | "type": "method" 72 | }, 73 | { 74 | "name": "createSocket", 75 | "modifiers": [], 76 | "type": "method" 77 | }, 78 | { 79 | "name": "getDefault", 80 | "modifiers": [ 81 | "static" 82 | ], 83 | "type": "method" 84 | } 85 | ] 86 | } 87 | ] -------------------------------------------------------------------------------- /data/javax.security.auth.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "javax.security.auth.AuthPermission", 4 | "type": "class", 5 | "modifiers": [], 6 | "extends": [ 7 | "java.security.BasicPermission" 8 | ], 9 | "implements": [], 10 | "members": [] 11 | }, 12 | { 13 | "name": "javax.security.auth.Destroyable", 14 | "type": "interface", 15 | "modifiers": [], 16 | "extends": [], 17 | "implements": [], 18 | "members": [ 19 | { 20 | "name": "destroy", 21 | "modifiers": [], 22 | "type": "method" 23 | }, 24 | { 25 | "name": "isDestroyed", 26 | "modifiers": [], 27 | "type": "method" 28 | } 29 | ] 30 | }, 31 | { 32 | "name": "javax.security.auth.DestroyFailedException", 33 | "type": "class", 34 | "modifiers": [], 35 | "extends": [ 36 | "java.lang.Exception" 37 | ], 38 | "implements": [], 39 | "members": [] 40 | }, 41 | { 42 | "name": "javax.security.auth.PrivateCredentialPermission", 43 | "type": "class", 44 | "modifiers": [], 45 | "extends": [ 46 | "java.security.Permission" 47 | ], 48 | "implements": [], 49 | "members": [ 50 | { 51 | "name": "equals", 52 | "modifiers": [], 53 | "type": "method" 54 | }, 55 | { 56 | "name": "getActions", 57 | "modifiers": [], 58 | "type": "method" 59 | }, 60 | { 61 | "name": "getCredentialClass", 62 | "modifiers": [], 63 | "type": "method" 64 | }, 65 | { 66 | "name": "getPrincipals", 67 | "modifiers": [], 68 | "type": "method" 69 | }, 70 | { 71 | "name": "hashCode", 72 | "modifiers": [], 73 | "type": "method" 74 | }, 75 | { 76 | "name": "implies", 77 | "modifiers": [], 78 | "type": "method" 79 | }, 80 | { 81 | "name": "newPermissionCollection", 82 | "modifiers": [], 83 | "type": "method" 84 | } 85 | ] 86 | }, 87 | { 88 | "name": "javax.security.auth.Refreshable", 89 | "type": "interface", 90 | "modifiers": [], 91 | "extends": [], 92 | "implements": [], 93 | "members": [ 94 | { 95 | "name": "isCurrent", 96 | "modifiers": [], 97 | "type": "method" 98 | }, 99 | { 100 | "name": "refresh", 101 | "modifiers": [], 102 | "type": "method" 103 | } 104 | ] 105 | }, 106 | { 107 | "name": "javax.security.auth.RefreshFailedException", 108 | "type": "class", 109 | "modifiers": [], 110 | "extends": [ 111 | "java.lang.Exception" 112 | ], 113 | "implements": [], 114 | "members": [] 115 | }, 116 | { 117 | "name": "javax.security.auth.Subject", 118 | "type": "class", 119 | "modifiers": [], 120 | "extends": [ 121 | "java.lang.Object" 122 | ], 123 | "implements": [ 124 | "java.io.Serializable" 125 | ], 126 | "members": [ 127 | { 128 | "name": "doAs", 129 | "modifiers": [ 130 | "static" 131 | ], 132 | "type": "method" 133 | }, 134 | { 135 | "name": "doAs", 136 | "modifiers": [ 137 | "static" 138 | ], 139 | "type": "method" 140 | }, 141 | { 142 | "name": "doAsPrivileged", 143 | "modifiers": [ 144 | "static" 145 | ], 146 | "type": "method" 147 | }, 148 | { 149 | "name": "doAsPrivileged", 150 | "modifiers": [ 151 | "static" 152 | ], 153 | "type": "method" 154 | }, 155 | { 156 | "name": "equals", 157 | "modifiers": [], 158 | "type": "method" 159 | }, 160 | { 161 | "name": "getPrincipals", 162 | "modifiers": [], 163 | "type": "method" 164 | }, 165 | { 166 | "name": "getPrincipals", 167 | "modifiers": [], 168 | "type": "method" 169 | }, 170 | { 171 | "name": "getPrivateCredentials", 172 | "modifiers": [], 173 | "type": "method" 174 | }, 175 | { 176 | "name": "getPrivateCredentials", 177 | "modifiers": [], 178 | "type": "method" 179 | }, 180 | { 181 | "name": "getPublicCredentials", 182 | "modifiers": [], 183 | "type": "method" 184 | }, 185 | { 186 | "name": "getPublicCredentials", 187 | "modifiers": [], 188 | "type": "method" 189 | }, 190 | { 191 | "name": "getSubject", 192 | "modifiers": [ 193 | "static" 194 | ], 195 | "type": "method" 196 | }, 197 | { 198 | "name": "hashCode", 199 | "modifiers": [], 200 | "type": "method" 201 | }, 202 | { 203 | "name": "isReadOnly", 204 | "modifiers": [], 205 | "type": "method" 206 | }, 207 | { 208 | "name": "setReadOnly", 209 | "modifiers": [], 210 | "type": "method" 211 | }, 212 | { 213 | "name": "toString", 214 | "modifiers": [], 215 | "type": "method" 216 | } 217 | ] 218 | }, 219 | { 220 | "name": "javax.security.auth.SubjectDomainCombiner", 221 | "type": "class", 222 | "modifiers": [], 223 | "extends": [ 224 | "java.lang.Object" 225 | ], 226 | "implements": [ 227 | "java.security.DomainCombiner" 228 | ], 229 | "members": [ 230 | { 231 | "name": "combine", 232 | "modifiers": [], 233 | "type": "method" 234 | }, 235 | { 236 | "name": "getSubject", 237 | "modifiers": [], 238 | "type": "method" 239 | } 240 | ] 241 | } 242 | ] -------------------------------------------------------------------------------- /data/javax.security.auth.login.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "javax.security.auth.login.AccountException", 4 | "type": "class", 5 | "modifiers": [], 6 | "extends": [ 7 | "javax.security.auth.login.LoginException" 8 | ], 9 | "implements": [], 10 | "members": [] 11 | }, 12 | { 13 | "name": "javax.security.auth.login.AccountExpiredException", 14 | "type": "class", 15 | "modifiers": [], 16 | "extends": [ 17 | "javax.security.auth.login.AccountException" 18 | ], 19 | "implements": [], 20 | "members": [] 21 | }, 22 | { 23 | "name": "javax.security.auth.login.AccountLockedException", 24 | "type": "class", 25 | "modifiers": [], 26 | "extends": [ 27 | "javax.security.auth.login.AccountException" 28 | ], 29 | "implements": [], 30 | "members": [] 31 | }, 32 | { 33 | "name": "javax.security.auth.login.AccountNotFoundException", 34 | "type": "class", 35 | "modifiers": [], 36 | "extends": [ 37 | "javax.security.auth.login.AccountException" 38 | ], 39 | "implements": [], 40 | "members": [] 41 | }, 42 | { 43 | "name": "javax.security.auth.login.AppConfigurationEntry", 44 | "type": "class", 45 | "modifiers": [], 46 | "extends": [ 47 | "java.lang.Object" 48 | ], 49 | "implements": [], 50 | "members": [ 51 | { 52 | "name": "AppConfigurationEntry.LoginModuleControlFlag", 53 | "modifiers": [ 54 | "static" 55 | ], 56 | "type": "class" 57 | }, 58 | { 59 | "name": "getControlFlag", 60 | "modifiers": [], 61 | "type": "method" 62 | }, 63 | { 64 | "name": "getLoginModuleName", 65 | "modifiers": [], 66 | "type": "method" 67 | }, 68 | { 69 | "name": "getOptions", 70 | "modifiers": [], 71 | "type": "method" 72 | } 73 | ] 74 | }, 75 | { 76 | "name": "javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag", 77 | "type": "class", 78 | "modifiers": [], 79 | "extends": [ 80 | "java.lang.Object" 81 | ], 82 | "implements": [], 83 | "members": [ 84 | { 85 | "name": "OPTIONAL", 86 | "modifiers": [ 87 | "static" 88 | ], 89 | "type": "field" 90 | }, 91 | { 92 | "name": "REQUIRED", 93 | "modifiers": [ 94 | "static" 95 | ], 96 | "type": "field" 97 | }, 98 | { 99 | "name": "REQUISITE", 100 | "modifiers": [ 101 | "static" 102 | ], 103 | "type": "field" 104 | }, 105 | { 106 | "name": "SUFFICIENT", 107 | "modifiers": [ 108 | "static" 109 | ], 110 | "type": "field" 111 | }, 112 | { 113 | "name": "toString", 114 | "modifiers": [], 115 | "type": "method" 116 | } 117 | ] 118 | }, 119 | { 120 | "name": "javax.security.auth.login.Configuration", 121 | "type": "class", 122 | "modifiers": [ 123 | "abstract" 124 | ], 125 | "extends": [ 126 | "java.lang.Object" 127 | ], 128 | "implements": [], 129 | "members": [ 130 | { 131 | "name": "Configuration.Parameters", 132 | "modifiers": [ 133 | "static" 134 | ], 135 | "type": "class" 136 | }, 137 | { 138 | "name": "getAppConfigurationEntry", 139 | "modifiers": [], 140 | "type": "method" 141 | }, 142 | { 143 | "name": "getConfiguration", 144 | "modifiers": [ 145 | "static" 146 | ], 147 | "type": "method" 148 | }, 149 | { 150 | "name": "getInstance", 151 | "modifiers": [ 152 | "static" 153 | ], 154 | "type": "method" 155 | }, 156 | { 157 | "name": "getInstance", 158 | "modifiers": [ 159 | "static" 160 | ], 161 | "type": "method" 162 | }, 163 | { 164 | "name": "getInstance", 165 | "modifiers": [ 166 | "static" 167 | ], 168 | "type": "method" 169 | }, 170 | { 171 | "name": "getParameters", 172 | "modifiers": [], 173 | "type": "method" 174 | }, 175 | { 176 | "name": "getProvider", 177 | "modifiers": [], 178 | "type": "method" 179 | }, 180 | { 181 | "name": "getType", 182 | "modifiers": [], 183 | "type": "method" 184 | }, 185 | { 186 | "name": "refresh", 187 | "modifiers": [], 188 | "type": "method" 189 | }, 190 | { 191 | "name": "setConfiguration", 192 | "modifiers": [ 193 | "static" 194 | ], 195 | "type": "method" 196 | } 197 | ] 198 | }, 199 | { 200 | "name": "javax.security.auth.login.Configuration.Parameters", 201 | "type": "interface", 202 | "modifiers": [], 203 | "extends": [], 204 | "implements": [], 205 | "members": [] 206 | }, 207 | { 208 | "name": "javax.security.auth.login.ConfigurationSpi", 209 | "type": "class", 210 | "modifiers": [ 211 | "abstract" 212 | ], 213 | "extends": [ 214 | "java.lang.Object" 215 | ], 216 | "implements": [], 217 | "members": [ 218 | { 219 | "name": "engineGetAppConfigurationEntry", 220 | "modifiers": [], 221 | "type": "method" 222 | }, 223 | { 224 | "name": "engineRefresh", 225 | "modifiers": [], 226 | "type": "method" 227 | } 228 | ] 229 | }, 230 | { 231 | "name": "javax.security.auth.login.CredentialException", 232 | "type": "class", 233 | "modifiers": [], 234 | "extends": [ 235 | "javax.security.auth.login.LoginException" 236 | ], 237 | "implements": [], 238 | "members": [] 239 | }, 240 | { 241 | "name": "javax.security.auth.login.CredentialExpiredException", 242 | "type": "class", 243 | "modifiers": [], 244 | "extends": [ 245 | "javax.security.auth.login.CredentialException" 246 | ], 247 | "implements": [], 248 | "members": [] 249 | }, 250 | { 251 | "name": "javax.security.auth.login.CredentialNotFoundException", 252 | "type": "class", 253 | "modifiers": [], 254 | "extends": [ 255 | "javax.security.auth.login.CredentialException" 256 | ], 257 | "implements": [], 258 | "members": [] 259 | }, 260 | { 261 | "name": "javax.security.auth.login.FailedLoginException", 262 | "type": "class", 263 | "modifiers": [], 264 | "extends": [ 265 | "javax.security.auth.login.LoginException" 266 | ], 267 | "implements": [], 268 | "members": [] 269 | }, 270 | { 271 | "name": "javax.security.auth.login.LoginContext", 272 | "type": "class", 273 | "modifiers": [], 274 | "extends": [ 275 | "java.lang.Object" 276 | ], 277 | "implements": [], 278 | "members": [ 279 | { 280 | "name": "getSubject", 281 | "modifiers": [], 282 | "type": "method" 283 | }, 284 | { 285 | "name": "login", 286 | "modifiers": [], 287 | "type": "method" 288 | }, 289 | { 290 | "name": "logout", 291 | "modifiers": [], 292 | "type": "method" 293 | } 294 | ] 295 | }, 296 | { 297 | "name": "javax.security.auth.login.LoginException", 298 | "type": "class", 299 | "modifiers": [], 300 | "extends": [ 301 | "java.security.GeneralSecurityException" 302 | ], 303 | "implements": [], 304 | "members": [] 305 | } 306 | ] -------------------------------------------------------------------------------- /data/javax.security.auth.spi.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "javax.security.auth.spi.LoginModule", 4 | "type": "interface", 5 | "modifiers": [], 6 | "extends": [], 7 | "implements": [], 8 | "members": [ 9 | { 10 | "name": "abort", 11 | "modifiers": [], 12 | "type": "method" 13 | }, 14 | { 15 | "name": "commit", 16 | "modifiers": [], 17 | "type": "method" 18 | }, 19 | { 20 | "name": "initialize", 21 | "modifiers": [], 22 | "type": "method" 23 | }, 24 | { 25 | "name": "login", 26 | "modifiers": [], 27 | "type": "method" 28 | }, 29 | { 30 | "name": "logout", 31 | "modifiers": [], 32 | "type": "method" 33 | } 34 | ] 35 | } 36 | ] -------------------------------------------------------------------------------- /data/javax.security.auth.x500.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "javax.security.auth.x500.X500Principal", 4 | "type": "class", 5 | "modifiers": [], 6 | "extends": [ 7 | "java.lang.Object" 8 | ], 9 | "implements": [ 10 | "java.security.Principal", 11 | "java.io.Serializable" 12 | ], 13 | "members": [ 14 | { 15 | "name": "CANONICAL", 16 | "modifiers": [ 17 | "static" 18 | ], 19 | "type": "field" 20 | }, 21 | { 22 | "name": "RFC1779", 23 | "modifiers": [ 24 | "static" 25 | ], 26 | "type": "field" 27 | }, 28 | { 29 | "name": "RFC2253", 30 | "modifiers": [ 31 | "static" 32 | ], 33 | "type": "field" 34 | }, 35 | { 36 | "name": "equals", 37 | "modifiers": [], 38 | "type": "method" 39 | }, 40 | { 41 | "name": "getEncoded", 42 | "modifiers": [], 43 | "type": "method" 44 | }, 45 | { 46 | "name": "getName", 47 | "modifiers": [], 48 | "type": "method" 49 | }, 50 | { 51 | "name": "getName", 52 | "modifiers": [], 53 | "type": "method" 54 | }, 55 | { 56 | "name": "getName", 57 | "modifiers": [], 58 | "type": "method" 59 | }, 60 | { 61 | "name": "hashCode", 62 | "modifiers": [], 63 | "type": "method" 64 | }, 65 | { 66 | "name": "toString", 67 | "modifiers": [], 68 | "type": "method" 69 | } 70 | ] 71 | }, 72 | { 73 | "name": "javax.security.auth.x500.X500PrivateCredential", 74 | "type": "class", 75 | "modifiers": [], 76 | "extends": [ 77 | "java.lang.Object" 78 | ], 79 | "implements": [ 80 | "javax.security.auth.Destroyable" 81 | ], 82 | "members": [ 83 | { 84 | "name": "destroy", 85 | "modifiers": [], 86 | "type": "method" 87 | }, 88 | { 89 | "name": "getAlias", 90 | "modifiers": [], 91 | "type": "method" 92 | }, 93 | { 94 | "name": "getCertificate", 95 | "modifiers": [], 96 | "type": "method" 97 | }, 98 | { 99 | "name": "getPrivateKey", 100 | "modifiers": [], 101 | "type": "method" 102 | }, 103 | { 104 | "name": "isDestroyed", 105 | "modifiers": [], 106 | "type": "method" 107 | } 108 | ] 109 | } 110 | ] -------------------------------------------------------------------------------- /data/javax.security.cert.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "javax.security.cert.Certificate", 4 | "type": "class", 5 | "modifiers": [], 6 | "extends": [ 7 | "java.lang.Object" 8 | ], 9 | "implements": [], 10 | "members": [ 11 | { 12 | "name": "equals", 13 | "modifiers": [], 14 | "type": "method" 15 | }, 16 | { 17 | "name": "getEncoded", 18 | "modifiers": [], 19 | "type": "method" 20 | }, 21 | { 22 | "name": "getPublicKey", 23 | "modifiers": [], 24 | "type": "method" 25 | }, 26 | { 27 | "name": "hashCode", 28 | "modifiers": [], 29 | "type": "method" 30 | }, 31 | { 32 | "name": "toString", 33 | "modifiers": [], 34 | "type": "method" 35 | }, 36 | { 37 | "name": "verify", 38 | "modifiers": [], 39 | "type": "method" 40 | }, 41 | { 42 | "name": "verify", 43 | "modifiers": [], 44 | "type": "method" 45 | } 46 | ] 47 | }, 48 | { 49 | "name": "javax.security.cert.CertificateEncodingException", 50 | "type": "class", 51 | "modifiers": [], 52 | "extends": [ 53 | "javax.security.cert.CertificateException" 54 | ], 55 | "implements": [], 56 | "members": [] 57 | }, 58 | { 59 | "name": "javax.security.cert.CertificateException", 60 | "type": "class", 61 | "modifiers": [], 62 | "extends": [ 63 | "java.lang.Exception" 64 | ], 65 | "implements": [], 66 | "members": [] 67 | }, 68 | { 69 | "name": "javax.security.cert.CertificateExpiredException", 70 | "type": "class", 71 | "modifiers": [], 72 | "extends": [ 73 | "javax.security.cert.CertificateException" 74 | ], 75 | "implements": [], 76 | "members": [] 77 | }, 78 | { 79 | "name": "javax.security.cert.CertificateNotYetValidException", 80 | "type": "class", 81 | "modifiers": [], 82 | "extends": [ 83 | "javax.security.cert.CertificateException" 84 | ], 85 | "implements": [], 86 | "members": [] 87 | }, 88 | { 89 | "name": "javax.security.cert.CertificateParsingException", 90 | "type": "class", 91 | "modifiers": [], 92 | "extends": [ 93 | "javax.security.cert.CertificateException" 94 | ], 95 | "implements": [], 96 | "members": [] 97 | }, 98 | { 99 | "name": "javax.security.cert.X509Certificate", 100 | "type": "class", 101 | "modifiers": [], 102 | "extends": [ 103 | "javax.security.cert.Certificate" 104 | ], 105 | "implements": [], 106 | "members": [ 107 | { 108 | "name": "checkValidity", 109 | "modifiers": [], 110 | "type": "method" 111 | }, 112 | { 113 | "name": "checkValidity", 114 | "modifiers": [], 115 | "type": "method" 116 | }, 117 | { 118 | "name": "getInstance", 119 | "modifiers": [ 120 | "static" 121 | ], 122 | "type": "method" 123 | }, 124 | { 125 | "name": "getInstance", 126 | "modifiers": [ 127 | "static" 128 | ], 129 | "type": "method" 130 | }, 131 | { 132 | "name": "getIssuerDN", 133 | "modifiers": [], 134 | "type": "method" 135 | }, 136 | { 137 | "name": "getNotAfter", 138 | "modifiers": [], 139 | "type": "method" 140 | }, 141 | { 142 | "name": "getNotBefore", 143 | "modifiers": [], 144 | "type": "method" 145 | }, 146 | { 147 | "name": "getSerialNumber", 148 | "modifiers": [], 149 | "type": "method" 150 | }, 151 | { 152 | "name": "getSigAlgName", 153 | "modifiers": [], 154 | "type": "method" 155 | }, 156 | { 157 | "name": "getSigAlgOID", 158 | "modifiers": [], 159 | "type": "method" 160 | }, 161 | { 162 | "name": "getSigAlgParams", 163 | "modifiers": [], 164 | "type": "method" 165 | }, 166 | { 167 | "name": "getSubjectDN", 168 | "modifiers": [], 169 | "type": "method" 170 | }, 171 | { 172 | "name": "getVersion", 173 | "modifiers": [], 174 | "type": "method" 175 | } 176 | ] 177 | } 178 | ] -------------------------------------------------------------------------------- /doc/configuration.md: -------------------------------------------------------------------------------- 1 | # Conversion Configuration 2 | 3 | The configuration object (`IConverterConfiguration`) mentioned in the readme file holds all necessary path information and options to steer the conversion process. Below's a description of each field. 4 | 5 | ## Top Level Configuration Values 6 | 7 | * **packageRoot** (string, mandatory): The root path of a Java package tree. Usually not only a single Java file, but a whole package is converted. This root path is used to regenerate the same folder structure in the target root path and to resolve relative paths. Use an absolute path for this to avoid problems with path resolution. 8 | 9 | * **javaLib** (string, optional): This value is used to import JRE types. If left empty, the `jree` package is used. Alternatively you can specify a path from which to import those types. 10 | 11 | * **include** (array of string or regular expressions, optional): if given only Java files matching one of the entries are converted (all files without the `.java` extension are always ignored). Files are enumerated from the package root and their absolute names used for comparison. 12 | Note: this setting has no influence on which files are parsed, only which are generated. Usually every file in a package can be parsed if a symbol from it is required, that is, it's imported in one of the listed files. 13 | 14 | * **exclude** (array of string or regular expression, optional): if given then files matching any of the patterns are ignored and not converted. The exclusion matching runs after the inclusion matching, which means that a file which is in both lists will not be converted. 15 | 16 | * **outputPath** (string, mandatory): specifies where generated files have to be written to. This path can be relative to the current path and gets the same folder structure as found in the package root path. 17 | 18 | * **sourceReplace** (map, optional): Specifies patterns for string replacements to be done in a Java file before it is parsed. 19 | 20 | * **targetReplace** (map, optional): Specifies patterns for string replacements to be done in the generated TS file. 21 | 22 | * **options** (object with configuration options, mandatory): see below for a description of the possible values. 23 | 24 | * **debug** (object with debug configuration options, optional): see below for a description of the possible values. 25 | 26 | ## Converter Options 27 | 28 | The `options` field in the top level configuration object accepts the following fields: 29 | 30 | * **prefix** (string, optional): content which is inserted before the first generated source line (e.g. linter settings). 31 | 32 | * **convertAnnotations** (boolean, optional): if true then Java annotations are converted to Typescript decorator names. You have to provide implementations for these decorators. 33 | 34 | * **preferArrowFunctions** (boolean, optional): when true then methods and function expression use arrow syntax, which is preferred syntax. For overloaded methods this setting has no effect, because there arrow syntax is not supported. 35 | 36 | * **autoAddBraces** (boolean, optional): if true then the tool automatically adds braces around code in `if`/`else`/`switch` statements, if there are none yet. 37 | 38 | * **addNullUnionType** (boolean, optional, default: true): controls whether non-primitive types are extended with `| null` to indicate their possible nullability. 39 | 40 | * **suppressTypeWithInitializer** (boolean, optional) when true no explicit type is written for types that have an initializer. 41 | 42 | * **wrapStringLiterals** (boolean, optional) when true all string literals are wrapped with the template literal `S`, which makes conversion between Typescript string literals and the `java.lang.String` object easier. This can lead to problems if such literals are concatenated using the plus operator (which is often the case), because it is not possible by default with any object. You still can use primitive type coercion, like 43 | 44 | ``` 45 | * call("" + S`abc`) 46 | ``` 47 | 48 | * **memberOrderOptions** (object, optional) allows to specify a structure which describes how to order class members in generated classes. This structure was taken from the [ESLint member ordering rule](https://typescript-eslint.io/rules/member-ordering/#options), however the `order` and `optionalityOrder` settings are currently ignored. 49 | 50 | * **addIndexFiles** (boolean, optional): when true then the tool generates an index.ts file in every target (sub) folder, to allow for simpler import statements in generated files. 51 | 52 | * **useUnqualifiedTypes** (boolean, optional, default: false): when true then Java types are used without qualification, if they are imported in the current file. Instead const reassignments and type aliases are generated from the imports. 53 | 54 | * **sourceMappings** (array of mapping entries, optional): a rarely used member to provide mappings between Java source files, which do not belong to the current package (and are not converted) and 3rd party JS/TS packages. So these mappings can be used to specify already converted Java packages. Each entry in the array is an object with 2 members (`sourcePath` and `importPath`), the path of the separate Java package and the import path to be used in generated files (if given as relative path then Node.js will try to solve the path in the node_module folder). The source files are only needed to collect symbol information. 55 | 56 | * **importResolver** (custom import resolver function, optional): described in the [symbol resolution doc](symbol-resolution.md#import-resolvers). 57 | 58 | * **classResolver** (map, optional): provides a mapping of a class name to an alternative name. Each value in the map consists of two parts: an alias (optional) and an import path. This allows to swap implementations for not supported Java 3rd party packages and use another JS/TS 3rd party libraries instead. The `importPath` usually specifies a 3rd party node module and the `alias` allows to change the imported type name to something more useful (e.g. the original name of the Java type). 59 | 60 | * **libraryImports** (`Map`, optional): A list of additional imports to add to the generated file. Used for helper code, which is not part of the generated output. It's a mapping of a path to a file and the list of symbols to import from that file. 61 | 62 | * **packageImports** (list of strings, optional): A list of any other 3rd party package imports to add to the generated file. These are used as namespace imports like `import * as from "";`. 63 | 64 | * **importExtension** (string, optional): The extension to use for generated file import statements. 65 | 66 | If not otherwise indicated there's no default value for a settings in this list, except for boolean values, where undefined means `false`. 67 | 68 | ## Debug Options 69 | 70 | Sometimes it is necessary to determine which part of the converter generated a certain block of the TS code. Be it to fix a generation problem or because it is unclear from which Java code the output was produced. The tool processes Java files in a top down manner, splitting more complex tasks into smaller ones until a case can be properly handled. Each such split step is modelled after the parse tree generated from the Java source. So, knowing where in the parse tree a specific source position is helps to find the place in the converter tool where the equivalent TS code was constructed. The debug options object allows to specify such a position: 71 | 72 | ```typescript 73 | debug: { 74 | pathForPosition?: { 75 | filePattern?: string | RegExp; 76 | position: { 77 | row: number; // One-based line number 78 | column: number; 79 | }; 80 | }; 81 | ``` 82 | 83 | When this information is given then the converter tool checks every input file, after it was parsed, for a match with the file pattern. In case of a match a case of the parse tree is printed up to the given position. The last entry is the name of the rule covering the given position and can be used to identify the method in the converter that transformed code at this position. 84 | -------------------------------------------------------------------------------- /doc/symbol-resolution.md: -------------------------------------------------------------------------------- 1 | # Symbol Resolution 2 | 3 | For the tool to generate correct import statements and symbol qualifiers it is essential to be able to resolve a symbol, that is, to find the origin where it is defined. There can be a number of sources, starting with local variables, normal and static class members, nested types, inherited types, imported types from the package and imported types from another package, both with and without source code. If you have 3rd party packages without source code, from which types are imported, this description is for you. 4 | 5 | ## Package Sources 6 | 7 | Symbol resolution in java2typescript is based on package sources. A package source can represent a single source file or an entire package. Each package source holds a single symbol table, which is used to resolve symbols. In cases like the JRE the symbol table is loaded from json files (which are part of the tool package and have been automatically generated from the Java documentation), instead of parsing the JRE source code. 8 | 9 | A package source additionally holds the source string for its symbols, which is used in Typescript `import` statements. This import path can either be a file path or a node module (allowing it so to back a 3rd party Java package with a node package). 10 | 11 | If you have a 3rd party library (or one of the unsupported JRE classes) you can create a package source too and fill it with hard coded symbol information. There's no limit (other than available memory) for how many package sources you can use. 12 | 13 | ## The Process of Resolving a Symbol 14 | 15 | The converter resolves symbols according to this model: 16 | 17 | - The current file: local variables, parameters, normal and static class members, members of the owning class (if being nested), in this order. 18 | - Any of the extended or implemented classes/interfaces (public and protected normal and static class members), in the order they are specified in the Java code. 19 | - Any of the files in the current project/package (only exported classes/interfaces), in the order they are found while enumerating the files on disk. 20 | - Module mappings (exported classes/interfaces from a 3rd party package), in the order they are given. 21 | - Import resolvers. 22 | 23 | If a symbol cannot be resolved then the original text is used and you will have to fix it manually. 24 | 25 | Import resolvers are the last resort to get symbols automatically resolved if nothing else works. There is one predefined resolver in the project: for the JRE (as mentioned already above). 26 | 27 | ## Package Source Management 28 | 29 | A file package source is automatically created for each of the Java files in the current package (and each of the 3rd party source files, if specified in the source mapping configuration field). The package source parses the file and creates a symbol table from the generated parse tree. 30 | 31 | ### Source Mappings 32 | 33 | A source mapping allows to "link in" another source package. This allows to convert one package but use symbols from another, without converting that too. All Java files in the mapped source are parsed just like the files in the package being converted. Each source mapping contains the path where to find the Java source code and a target specifier (folder, node package) from which to import the types used in the converted code. 34 | 35 | This feature is especially useful when converting large projects. You can convert one package at a time and then use the converted code in other packages. 36 | 37 | ## Class Resolvers 38 | 39 | Another alternative is to provide a map with values that define how a specific symbol is to be mapped to another symbol, like an import from a third party library. This mapping allows to define a type alias to import a type with a different name. 40 | 41 | ### Import Resolvers 42 | 43 | An import resolver function maps a package ID to a package source: 44 | 45 | ```typescript 46 | const importResolver = (packageId: string): PackageSource[] => { 47 | const result: PackageSource[] = []; 48 | 49 | knownSDKPackages.forEach((value) => { 50 | if (packageId.startsWith(value)) { 51 | result.push(PackageSourceManager.emptySource(value)); // You'd better create a real package source here. 52 | } 53 | }); 54 | 55 | return result; 56 | }; 57 | ``` 58 | 59 | In this example the resolver creates empty sources for each known SDK package (which could not be resolved otherwise). An empty source has an empty symbol table and can hence not resolve symbols. So they are rather placeholders. If a package cannot be resolved `java2typescript` implicitly creates an empty source (and logs that in the console). 60 | 61 | The import resolver can be assigned to the `IConverterConfiguration.options.importResolver` field. This is only possible if you write your own conversion script as described in the [Running From Your Code](../readme.md#running-from-your-code) chapter. 62 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is released under the MIT license. 3 | * Copyright (c) 2023, Mike Lischke 4 | * 5 | * See LICENSE file for more info. 6 | */ 7 | 8 | import type { Config } from "jest"; 9 | 10 | const config: Config = { 11 | // All imported modules in your tests should be mocked automatically 12 | // automock: false, 13 | 14 | // Stop running tests after `n` failures 15 | //bail: 1, 16 | 17 | // The directory where Jest should store its cached dependency information 18 | // cacheDirectory: "/private/var/folders/03/gj5f1gl92w11zc3l2c526dnm0000gn/T/jest_dx", 19 | 20 | // Automatically clear mock calls, instances, contexts and results before every test 21 | // clearMocks: true, 22 | 23 | ci: true, 24 | 25 | // Indicates whether the coverage information should be collected while executing the test 26 | collectCoverage: true, 27 | 28 | // An array of glob patterns indicating a set of files for which coverage information should be collected 29 | collectCoverageFrom: [ 30 | "src/**/*.ts", 31 | "!tests/**", 32 | "!**/node_modules/**", 33 | ], 34 | 35 | // The directory where Jest should output its coverage files 36 | coverageDirectory: "coverage", 37 | 38 | // An array of regexp pattern strings used to skip coverage collection 39 | // coveragePathIgnorePatterns: [ 40 | // "/node_modules/" 41 | // ], 42 | 43 | // Indicates which provider should be used to instrument code for coverage 44 | coverageProvider: "v8", 45 | 46 | // A list of reporter names that Jest uses when writing coverage reports 47 | coverageReporters: [ 48 | "json", 49 | "text", 50 | "clover", 51 | "html", 52 | ], 53 | 54 | // An object that configures minimum threshold enforcement for coverage results 55 | coverageThreshold: { 56 | global: { 57 | statements: 65, 58 | branches: 70, 59 | functions: 50, 60 | lines: 65, 61 | }, 62 | }, 63 | 64 | // A path to a custom dependency extractor 65 | // dependencyExtractor: undefined, 66 | 67 | // displayName: "FE unit tests", 68 | 69 | // Make calling deprecated APIs throw helpful error messages 70 | // errorOnDeprecated: false, 71 | 72 | // The default configuration for fake timers 73 | // fakeTimers: { 74 | // "enableGlobally": false 75 | // }, 76 | 77 | // Force coverage collection from ignored files using an array of glob patterns 78 | // forceCoverageMatch: [], 79 | 80 | // A path to a module which exports an async function that is triggered once before all test suites 81 | // globalSetup: "./src/tests/globalSetup.ts", 82 | 83 | // A path to a module which exports an async function that is triggered once after all test suites 84 | // globalTeardown: "./src/tests/globalTearDown.ts", 85 | 86 | // A set of global variables that need to be available in all test environments 87 | // globals: {}, 88 | 89 | // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 90 | // 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 91 | // 2 workers. 92 | //maxWorkers: "50%", 93 | 94 | // An array of directory names to be searched recursively up from the requiring module's location 95 | // moduleDirectories: [ 96 | // "node_modules" 97 | // ], 98 | 99 | workerIdleMemoryLimit: "500MB", 100 | 101 | // An array of file extensions your modules use 102 | moduleFileExtensions: [ 103 | "tsx", 104 | "ts", 105 | "js", 106 | "mjs", 107 | "cjs", 108 | "jsx", 109 | "json", 110 | "node", 111 | ], 112 | 113 | // A map from regular expressions to module names or to arrays of module names that allow to stub out resources 114 | // with a single module 115 | moduleNameMapper: { 116 | }, 117 | 118 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module 119 | // loader 120 | // modulePathIgnorePatterns: [], 121 | 122 | // Activates notifications for test results 123 | // notify: false, 124 | 125 | // An enum that specifies notification mode. Requires { notify: true } 126 | // notifyMode: "failure-change", 127 | 128 | // A preset that is used as a base for Jest's configuration 129 | preset: "ts-jest", 130 | 131 | // Run tests from one or more projects 132 | // projects: undefined, 133 | 134 | // Use this configuration option to add custom reporters to Jest 135 | // reporters: undefined, 136 | 137 | // Automatically reset mock state before every test 138 | resetMocks: false, 139 | 140 | // Reset the module registry before running each individual test 141 | // resetModules: false, 142 | 143 | // A path to a custom resolver 144 | // resolver: undefined, 145 | 146 | // Automatically restore mock state and implementation before every test 147 | // restoreMocks: false, 148 | 149 | // The root directory that Jest should scan for tests and modules within 150 | // rootDir: undefined, 151 | 152 | // A list of paths to directories that Jest should use to search for files in 153 | roots: [ 154 | "tests", 155 | ], 156 | 157 | // Allows you to use a custom runner instead of Jest's default test runner 158 | // runner: "jest-runner", 159 | 160 | // The paths to modules that run some code to configure or set up the testing environment before each test 161 | // setupFiles: [], 162 | 163 | // A list of paths to modules that run some code to configure or set up the testing framework before each test 164 | setupFilesAfterEnv: [ 165 | // Note: this is not optimal. This setup is run again for every test file, while we actually want to 166 | // run it only once. 167 | //"./src/tests/setupTestEnv.ts", 168 | ], 169 | 170 | // The number of seconds after which a test is considered as slow and reported as such in the results. 171 | // slowTestThreshold: 5, 172 | 173 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 174 | // snapshotSerializers: [], 175 | 176 | // The test environment that will be used for testing 177 | testEnvironment: "node", 178 | 179 | // Options that will be passed to the testEnvironment 180 | testEnvironmentOptions: {}, 181 | 182 | // Adds a location field to test results 183 | // testLocationInResults: false, 184 | 185 | // The glob patterns Jest uses to detect test files 186 | testMatch: [ 187 | "**/tests/**/*.spec.ts", 188 | ], 189 | 190 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 191 | testPathIgnorePatterns: [ 192 | //"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$", 193 | //"^.+\\.module\\.(css|sass|scss)$", 194 | ], 195 | 196 | // The regexp pattern or array of patterns that Jest uses to detect test files 197 | // testRegex: [], 198 | 199 | // This option allows the use of a custom results processor 200 | // testResultsProcessor: undefined, 201 | 202 | // This option allows use of a custom test runner 203 | // testRunner: "jest-circus/runner", 204 | 205 | // CI machines can be slow. 206 | testTimeout: 30000, 207 | 208 | // A map from regular expressions to paths to transformers 209 | // transform: {}, 210 | 211 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip 212 | // transformation 213 | transformIgnorePatterns: [ 214 | "/../node_modules/", 215 | ], 216 | 217 | // An array of regexp pattern strings that are matched against all modules before the module loader will 218 | // automatically return a mock for them 219 | // unmockedModulePathPatterns: undefined, 220 | 221 | // Indicates whether each individual test should be reported during the run 222 | // verbose: undefined, 223 | 224 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 225 | // watchPathIgnorePatterns: [], 226 | 227 | // Whether to use watchman for file crawling 228 | // watchman: true, 229 | }; 230 | 231 | export default config; 232 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "java2typescript", 3 | "version": "1.1.0", 4 | "description": "Convert Java Code to Typescript", 5 | "keywords": [ 6 | "Java", 7 | "Typescript", 8 | "ANTLR4", 9 | "JRE", 10 | "JDK" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/mike-lischke/java2typescript.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/mike-lischke/java2typescript/issues" 18 | }, 19 | "homepage": "https://github.com/mike-lischke/java2typescript", 20 | "author": "Mike Lischke", 21 | "license": "MIT", 22 | "type": "module", 23 | "bin": { 24 | "java2ts": "output/src/convert.js" 25 | }, 26 | "main": "output/src/convert.js", 27 | "dependencies": { 28 | "antlr4-c3": "^3.4.1", 29 | "antlr4ng": "^3.0.3", 30 | "glob": "10.3.10", 31 | "jree": "1.2.2" 32 | }, 33 | "devDependencies": { 34 | "@types/glob": "8.1.0", 35 | "@types/jest": "29.5.12", 36 | "@types/jsdom": "21.1.6", 37 | "@types/node": "20.11.24", 38 | "@typescript-eslint/eslint-plugin": "7.1.0", 39 | "@typescript-eslint/parser": "7.1.0", 40 | "antlr4ng-cli": "^2.0.0", 41 | "esbuild": "0.20.1", 42 | "eslint": "8.57.0", 43 | "eslint-plugin-import": "2.29.1", 44 | "eslint-plugin-jsdoc": "48.2.0", 45 | "eslint-plugin-prefer-arrow": "1.2.3", 46 | "jest": "29.7.0", 47 | "jsdom": "24.0.0", 48 | "ts-jest": "29.1.2", 49 | "ts-node": "10.9.2", 50 | "tsc-hooks": "1.1.2", 51 | "typescript": "5.3.3" 52 | }, 53 | "scripts": { 54 | "build": "tsc && esbuild ./src/index.ts --main-fields=module,main --bundle --outfile=dist/index.js --format=esm --platform=node", 55 | "build-minified": "npm run build -- --minify", 56 | "build-watch": "npm run build -- --sourcemap --watch", 57 | "fetch-apis": "ts-node-esm tools/fetchJavaApis.ts", 58 | "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=./tests/jest.config.ts --no-coverage --watchAll=false", 59 | "test-ci": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=./tests/jest.config.ts --no-coverage --watchAll=false --silent", 60 | "test-coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=./tests/jest.config.ts --coverage", 61 | "lint": "eslint \"./src/**/*.ts\"", 62 | "generate": "antlr4ng -Dlanguage=TypeScript -Xexact-output-dir ./parser/JavaLexer.g4 ./parser/JavaParser.g4 -visitor -o ./parser/generated", 63 | "link": "npm link", 64 | "unlink": "npm unlink ." 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /parser/JavaLexer.g4: -------------------------------------------------------------------------------- 1 | /* 2 | [The "BSD licence"] 3 | Copyright (c) 2013 Terence Parr, Sam Harwell 4 | Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8) 5 | Copyright (c) 2021 Michał Lorek (upgrade to Java 11) 6 | Copyright (c) 2022 Michał Lorek (upgrade to Java 17) 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions 11 | are met: 12 | 1. Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 2. Redistributions in binary form must reproduce the above copyright 15 | notice, this list of conditions and the following disclaimer in the 16 | documentation and/or other materials provided with the distribution. 17 | 3. The name of the author may not be used to endorse or promote products 18 | derived from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | lexer grammar JavaLexer; 33 | 34 | // Keywords 35 | 36 | ABSTRACT: 'abstract'; 37 | ASSERT: 'assert'; 38 | BOOLEAN: 'boolean'; 39 | BREAK: 'break'; 40 | BYTE: 'byte'; 41 | CASE: 'case'; 42 | CATCH: 'catch'; 43 | CHAR: 'char'; 44 | CLASS: 'class'; 45 | CONST: 'const'; 46 | CONTINUE: 'continue'; 47 | DEFAULT: 'default'; 48 | DO: 'do'; 49 | DOUBLE: 'double'; 50 | ELSE: 'else'; 51 | ENUM: 'enum'; 52 | EXTENDS: 'extends'; 53 | FINAL: 'final'; 54 | FINALLY: 'finally'; 55 | FLOAT: 'float'; 56 | FOR: 'for'; 57 | IF: 'if'; 58 | GOTO: 'goto'; 59 | IMPLEMENTS: 'implements'; 60 | IMPORT: 'import'; 61 | INSTANCEOF: 'instanceof'; 62 | INT: 'int'; 63 | INTERFACE: 'interface'; 64 | LONG: 'long'; 65 | NATIVE: 'native'; 66 | NEW: 'new'; 67 | PACKAGE: 'package'; 68 | PRIVATE: 'private'; 69 | PROTECTED: 'protected'; 70 | PUBLIC: 'public'; 71 | RETURN: 'return'; 72 | SHORT: 'short'; 73 | STATIC: 'static'; 74 | STRICTFP: 'strictfp'; 75 | SUPER: 'super'; 76 | SWITCH: 'switch'; 77 | SYNCHRONIZED: 'synchronized'; 78 | THIS: 'this'; 79 | THROW: 'throw'; 80 | THROWS: 'throws'; 81 | TRANSIENT: 'transient'; 82 | TRY: 'try'; 83 | VOID: 'void'; 84 | VOLATILE: 'volatile'; 85 | WHILE: 'while'; 86 | 87 | // Module related keywords 88 | MODULE: 'module'; 89 | OPEN: 'open'; 90 | REQUIRES: 'requires'; 91 | EXPORTS: 'exports'; 92 | OPENS: 'opens'; 93 | TO: 'to'; 94 | USES: 'uses'; 95 | PROVIDES: 'provides'; 96 | WITH: 'with'; 97 | TRANSITIVE: 'transitive'; 98 | 99 | // Local Variable Type Inference 100 | VAR: 'var'; // reserved type name 101 | 102 | // Switch Expressions 103 | YIELD: 'yield'; 104 | 105 | // Records 106 | RECORD: 'record'; 107 | 108 | // Sealed Classes 109 | SEALED: 'sealed'; 110 | PERMITS: 'permits'; 111 | NON_SEALED: 'non-sealed'; 112 | 113 | // Literals 114 | 115 | DECIMAL_LITERAL: ('0' | [1-9] (Digits? | '_'+ Digits)) [lL]?; 116 | HEX_LITERAL: '0' [xX] [0-9a-fA-F] ([0-9a-fA-F_]* [0-9a-fA-F])? [lL]?; 117 | OCT_LITERAL: '0' '_'* [0-7] ([0-7_]* [0-7])? [lL]?; 118 | BINARY_LITERAL: '0' [bB] [01] ([01_]* [01])? [lL]?; 119 | 120 | FLOAT_LITERAL: (Digits '.' Digits? | '.' Digits) ExponentPart? [fFdD]? 121 | | Digits (ExponentPart [fFdD]? | [fFdD]) 122 | ; 123 | 124 | HEX_FLOAT_LITERAL: '0' [xX] (HexDigits '.'? | HexDigits? '.' HexDigits) [pP] [+-]? Digits [fFdD]?; 125 | 126 | BOOL_LITERAL: 'true' 127 | | 'false' 128 | ; 129 | 130 | CHAR_LITERAL: '\'' (~['\\\r\n] | EscapeSequence) '\''; 131 | 132 | STRING_LITERAL: '"' (~["\\\r\n] | EscapeSequence)* '"'; 133 | 134 | TEXT_BLOCK: '"""' [ \t]* [\r\n] (. | EscapeSequence)*? '"""'; 135 | 136 | NULL_LITERAL: 'null'; 137 | 138 | // Separators 139 | 140 | LPAREN: '('; 141 | RPAREN: ')'; 142 | LBRACE: '{'; 143 | RBRACE: '}'; 144 | LBRACK: '['; 145 | RBRACK: ']'; 146 | SEMI: ';'; 147 | COMMA: ','; 148 | DOT: '.'; 149 | 150 | // Operators 151 | 152 | ASSIGN: '='; 153 | GT: '>'; 154 | LT: '<'; 155 | BANG: '!'; 156 | TILDE: '~'; 157 | QUESTION: '?'; 158 | COLON: ':'; 159 | EQUAL: '=='; 160 | LE: '<='; 161 | GE: '>='; 162 | NOTEQUAL: '!='; 163 | AND: '&&'; 164 | OR: '||'; 165 | INC: '++'; 166 | DEC: '--'; 167 | ADD: '+'; 168 | SUB: '-'; 169 | MUL: '*'; 170 | DIV: '/'; 171 | BITAND: '&'; 172 | BITOR: '|'; 173 | CARET: '^'; 174 | MOD: '%'; 175 | 176 | ADD_ASSIGN: '+='; 177 | SUB_ASSIGN: '-='; 178 | MUL_ASSIGN: '*='; 179 | DIV_ASSIGN: '/='; 180 | AND_ASSIGN: '&='; 181 | OR_ASSIGN: '|='; 182 | XOR_ASSIGN: '^='; 183 | MOD_ASSIGN: '%='; 184 | LSHIFT_ASSIGN: '<<='; 185 | RSHIFT_ASSIGN: '>>='; 186 | URSHIFT_ASSIGN: '>>>='; 187 | 188 | // Java 8 tokens 189 | 190 | ARROW: '->'; 191 | COLONCOLON: '::'; 192 | 193 | // Additional symbols not defined in the lexical specification 194 | 195 | AT: '@'; 196 | ELLIPSIS: '...'; 197 | 198 | // Whitespace and comments 199 | 200 | WS: [ \t\r\n\u000C]+ -> channel(HIDDEN); 201 | COMMENT: '/*' .*? '*/' -> channel(HIDDEN); 202 | LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN); 203 | 204 | // Identifiers 205 | 206 | IDENTIFIER: Letter LetterOrDigit*; 207 | 208 | // Fragment rules 209 | 210 | fragment ExponentPart 211 | : [eE] [+-]? Digits 212 | ; 213 | 214 | fragment EscapeSequence 215 | : '\\' [btnfr"'\\] 216 | | '\\' ([0-3]? [0-7])? [0-7] 217 | | '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit 218 | ; 219 | 220 | fragment HexDigits 221 | : HexDigit ((HexDigit | '_')* HexDigit)? 222 | ; 223 | 224 | fragment HexDigit 225 | : [0-9a-fA-F] 226 | ; 227 | 228 | fragment Digits 229 | : [0-9] ([0-9_]* [0-9])? 230 | ; 231 | 232 | fragment LetterOrDigit 233 | : Letter 234 | | [0-9] 235 | ; 236 | 237 | fragment Letter 238 | : [a-zA-Z$_] // these are the "java letters" below 0x7F 239 | | ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate 240 | | [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF 241 | ; 242 | -------------------------------------------------------------------------------- /parser/generated/JavaLexer.tokens: -------------------------------------------------------------------------------- 1 | ABSTRACT=1 2 | ASSERT=2 3 | BOOLEAN=3 4 | BREAK=4 5 | BYTE=5 6 | CASE=6 7 | CATCH=7 8 | CHAR=8 9 | CLASS=9 10 | CONST=10 11 | CONTINUE=11 12 | DEFAULT=12 13 | DO=13 14 | DOUBLE=14 15 | ELSE=15 16 | ENUM=16 17 | EXTENDS=17 18 | FINAL=18 19 | FINALLY=19 20 | FLOAT=20 21 | FOR=21 22 | IF=22 23 | GOTO=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | STATIC=38 39 | STRICTFP=39 40 | SUPER=40 41 | SWITCH=41 42 | SYNCHRONIZED=42 43 | THIS=43 44 | THROW=44 45 | THROWS=45 46 | TRANSIENT=46 47 | TRY=47 48 | VOID=48 49 | VOLATILE=49 50 | WHILE=50 51 | MODULE=51 52 | OPEN=52 53 | REQUIRES=53 54 | EXPORTS=54 55 | OPENS=55 56 | TO=56 57 | USES=57 58 | PROVIDES=58 59 | WITH=59 60 | TRANSITIVE=60 61 | VAR=61 62 | YIELD=62 63 | RECORD=63 64 | SEALED=64 65 | PERMITS=65 66 | NON_SEALED=66 67 | DECIMAL_LITERAL=67 68 | HEX_LITERAL=68 69 | OCT_LITERAL=69 70 | BINARY_LITERAL=70 71 | FLOAT_LITERAL=71 72 | HEX_FLOAT_LITERAL=72 73 | BOOL_LITERAL=73 74 | CHAR_LITERAL=74 75 | STRING_LITERAL=75 76 | TEXT_BLOCK=76 77 | NULL_LITERAL=77 78 | LPAREN=78 79 | RPAREN=79 80 | LBRACE=80 81 | RBRACE=81 82 | LBRACK=82 83 | RBRACK=83 84 | SEMI=84 85 | COMMA=85 86 | DOT=86 87 | ASSIGN=87 88 | GT=88 89 | LT=89 90 | BANG=90 91 | TILDE=91 92 | QUESTION=92 93 | COLON=93 94 | EQUAL=94 95 | LE=95 96 | GE=96 97 | NOTEQUAL=97 98 | AND=98 99 | OR=99 100 | INC=100 101 | DEC=101 102 | ADD=102 103 | SUB=103 104 | MUL=104 105 | DIV=105 106 | BITAND=106 107 | BITOR=107 108 | CARET=108 109 | MOD=109 110 | ADD_ASSIGN=110 111 | SUB_ASSIGN=111 112 | MUL_ASSIGN=112 113 | DIV_ASSIGN=113 114 | AND_ASSIGN=114 115 | OR_ASSIGN=115 116 | XOR_ASSIGN=116 117 | MOD_ASSIGN=117 118 | LSHIFT_ASSIGN=118 119 | RSHIFT_ASSIGN=119 120 | URSHIFT_ASSIGN=120 121 | ARROW=121 122 | COLONCOLON=122 123 | AT=123 124 | ELLIPSIS=124 125 | WS=125 126 | COMMENT=126 127 | LINE_COMMENT=127 128 | IDENTIFIER=128 129 | 'abstract'=1 130 | 'assert'=2 131 | 'boolean'=3 132 | 'break'=4 133 | 'byte'=5 134 | 'case'=6 135 | 'catch'=7 136 | 'char'=8 137 | 'class'=9 138 | 'const'=10 139 | 'continue'=11 140 | 'default'=12 141 | 'do'=13 142 | 'double'=14 143 | 'else'=15 144 | 'enum'=16 145 | 'extends'=17 146 | 'final'=18 147 | 'finally'=19 148 | 'float'=20 149 | 'for'=21 150 | 'if'=22 151 | 'goto'=23 152 | 'implements'=24 153 | 'import'=25 154 | 'instanceof'=26 155 | 'int'=27 156 | 'interface'=28 157 | 'long'=29 158 | 'native'=30 159 | 'new'=31 160 | 'package'=32 161 | 'private'=33 162 | 'protected'=34 163 | 'public'=35 164 | 'return'=36 165 | 'short'=37 166 | 'static'=38 167 | 'strictfp'=39 168 | 'super'=40 169 | 'switch'=41 170 | 'synchronized'=42 171 | 'this'=43 172 | 'throw'=44 173 | 'throws'=45 174 | 'transient'=46 175 | 'try'=47 176 | 'void'=48 177 | 'volatile'=49 178 | 'while'=50 179 | 'module'=51 180 | 'open'=52 181 | 'requires'=53 182 | 'exports'=54 183 | 'opens'=55 184 | 'to'=56 185 | 'uses'=57 186 | 'provides'=58 187 | 'with'=59 188 | 'transitive'=60 189 | 'var'=61 190 | 'yield'=62 191 | 'record'=63 192 | 'sealed'=64 193 | 'permits'=65 194 | 'non-sealed'=66 195 | 'null'=77 196 | '('=78 197 | ')'=79 198 | '{'=80 199 | '}'=81 200 | '['=82 201 | ']'=83 202 | ';'=84 203 | ','=85 204 | '.'=86 205 | '='=87 206 | '>'=88 207 | '<'=89 208 | '!'=90 209 | '~'=91 210 | '?'=92 211 | ':'=93 212 | '=='=94 213 | '<='=95 214 | '>='=96 215 | '!='=97 216 | '&&'=98 217 | '||'=99 218 | '++'=100 219 | '--'=101 220 | '+'=102 221 | '-'=103 222 | '*'=104 223 | '/'=105 224 | '&'=106 225 | '|'=107 226 | '^'=108 227 | '%'=109 228 | '+='=110 229 | '-='=111 230 | '*='=112 231 | '/='=113 232 | '&='=114 233 | '|='=115 234 | '^='=116 235 | '%='=117 236 | '<<='=118 237 | '>>='=119 238 | '>>>='=120 239 | '->'=121 240 | '::'=122 241 | '@'=123 242 | '...'=124 243 | -------------------------------------------------------------------------------- /parser/generated/JavaParser.tokens: -------------------------------------------------------------------------------- 1 | ABSTRACT=1 2 | ASSERT=2 3 | BOOLEAN=3 4 | BREAK=4 5 | BYTE=5 6 | CASE=6 7 | CATCH=7 8 | CHAR=8 9 | CLASS=9 10 | CONST=10 11 | CONTINUE=11 12 | DEFAULT=12 13 | DO=13 14 | DOUBLE=14 15 | ELSE=15 16 | ENUM=16 17 | EXTENDS=17 18 | FINAL=18 19 | FINALLY=19 20 | FLOAT=20 21 | FOR=21 22 | IF=22 23 | GOTO=23 24 | IMPLEMENTS=24 25 | IMPORT=25 26 | INSTANCEOF=26 27 | INT=27 28 | INTERFACE=28 29 | LONG=29 30 | NATIVE=30 31 | NEW=31 32 | PACKAGE=32 33 | PRIVATE=33 34 | PROTECTED=34 35 | PUBLIC=35 36 | RETURN=36 37 | SHORT=37 38 | STATIC=38 39 | STRICTFP=39 40 | SUPER=40 41 | SWITCH=41 42 | SYNCHRONIZED=42 43 | THIS=43 44 | THROW=44 45 | THROWS=45 46 | TRANSIENT=46 47 | TRY=47 48 | VOID=48 49 | VOLATILE=49 50 | WHILE=50 51 | MODULE=51 52 | OPEN=52 53 | REQUIRES=53 54 | EXPORTS=54 55 | OPENS=55 56 | TO=56 57 | USES=57 58 | PROVIDES=58 59 | WITH=59 60 | TRANSITIVE=60 61 | VAR=61 62 | YIELD=62 63 | RECORD=63 64 | SEALED=64 65 | PERMITS=65 66 | NON_SEALED=66 67 | DECIMAL_LITERAL=67 68 | HEX_LITERAL=68 69 | OCT_LITERAL=69 70 | BINARY_LITERAL=70 71 | FLOAT_LITERAL=71 72 | HEX_FLOAT_LITERAL=72 73 | BOOL_LITERAL=73 74 | CHAR_LITERAL=74 75 | STRING_LITERAL=75 76 | TEXT_BLOCK=76 77 | NULL_LITERAL=77 78 | LPAREN=78 79 | RPAREN=79 80 | LBRACE=80 81 | RBRACE=81 82 | LBRACK=82 83 | RBRACK=83 84 | SEMI=84 85 | COMMA=85 86 | DOT=86 87 | ASSIGN=87 88 | GT=88 89 | LT=89 90 | BANG=90 91 | TILDE=91 92 | QUESTION=92 93 | COLON=93 94 | EQUAL=94 95 | LE=95 96 | GE=96 97 | NOTEQUAL=97 98 | AND=98 99 | OR=99 100 | INC=100 101 | DEC=101 102 | ADD=102 103 | SUB=103 104 | MUL=104 105 | DIV=105 106 | BITAND=106 107 | BITOR=107 108 | CARET=108 109 | MOD=109 110 | ADD_ASSIGN=110 111 | SUB_ASSIGN=111 112 | MUL_ASSIGN=112 113 | DIV_ASSIGN=113 114 | AND_ASSIGN=114 115 | OR_ASSIGN=115 116 | XOR_ASSIGN=116 117 | MOD_ASSIGN=117 118 | LSHIFT_ASSIGN=118 119 | RSHIFT_ASSIGN=119 120 | URSHIFT_ASSIGN=120 121 | ARROW=121 122 | COLONCOLON=122 123 | AT=123 124 | ELLIPSIS=124 125 | WS=125 126 | COMMENT=126 127 | LINE_COMMENT=127 128 | IDENTIFIER=128 129 | 'abstract'=1 130 | 'assert'=2 131 | 'boolean'=3 132 | 'break'=4 133 | 'byte'=5 134 | 'case'=6 135 | 'catch'=7 136 | 'char'=8 137 | 'class'=9 138 | 'const'=10 139 | 'continue'=11 140 | 'default'=12 141 | 'do'=13 142 | 'double'=14 143 | 'else'=15 144 | 'enum'=16 145 | 'extends'=17 146 | 'final'=18 147 | 'finally'=19 148 | 'float'=20 149 | 'for'=21 150 | 'if'=22 151 | 'goto'=23 152 | 'implements'=24 153 | 'import'=25 154 | 'instanceof'=26 155 | 'int'=27 156 | 'interface'=28 157 | 'long'=29 158 | 'native'=30 159 | 'new'=31 160 | 'package'=32 161 | 'private'=33 162 | 'protected'=34 163 | 'public'=35 164 | 'return'=36 165 | 'short'=37 166 | 'static'=38 167 | 'strictfp'=39 168 | 'super'=40 169 | 'switch'=41 170 | 'synchronized'=42 171 | 'this'=43 172 | 'throw'=44 173 | 'throws'=45 174 | 'transient'=46 175 | 'try'=47 176 | 'void'=48 177 | 'volatile'=49 178 | 'while'=50 179 | 'module'=51 180 | 'open'=52 181 | 'requires'=53 182 | 'exports'=54 183 | 'opens'=55 184 | 'to'=56 185 | 'uses'=57 186 | 'provides'=58 187 | 'with'=59 188 | 'transitive'=60 189 | 'var'=61 190 | 'yield'=62 191 | 'record'=63 192 | 'sealed'=64 193 | 'permits'=65 194 | 'non-sealed'=66 195 | 'null'=77 196 | '('=78 197 | ')'=79 198 | '{'=80 199 | '}'=81 200 | '['=82 201 | ']'=83 202 | ';'=84 203 | ','=85 204 | '.'=86 205 | '='=87 206 | '>'=88 207 | '<'=89 208 | '!'=90 209 | '~'=91 210 | '?'=92 211 | ':'=93 212 | '=='=94 213 | '<='=95 214 | '>='=96 215 | '!='=97 216 | '&&'=98 217 | '||'=99 218 | '++'=100 219 | '--'=101 220 | '+'=102 221 | '-'=103 222 | '*'=104 223 | '/'=105 224 | '&'=106 225 | '|'=107 226 | '^'=108 227 | '%'=109 228 | '+='=110 229 | '-='=111 230 | '*='=112 231 | '/='=113 232 | '&='=114 233 | '|='=115 234 | '^='=116 235 | '%='=117 236 | '<<='=118 237 | '>>='=119 238 | '>>>='=120 239 | '->'=121 240 | '::'=122 241 | '@'=123 242 | '...'=124 243 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | [![Build & Test](https://github.com/mike-lischke/java2typescript/actions/workflows/nodejs.yml/badge.svg?branch=master)](https://github.com/mike-lischke/java2typescript/actions/workflows/nodejs.yml) 2 | [![Java 11](https://img.shields.io/badge/java-11-4c7e9f.svg)](http://java.oracle.com) [![Downloads](https://img.shields.io/npm/dw/java2typescript?color=blue)](https://www.npmjs.com/package/java2typescript) 3 | 4 | # Java To Typescript Converter 5 | 6 | This tool is a Node.js application written in Typescript to convert Java source code to Typescript. The conversion usually takes a Java source package (path to the package root) and creates a copy of the folder structure of that, thereby translating all *.java files to Typescript. 7 | 8 | The converter uses (a copy of) the [Java grammar from the ANTLR4 grammar directory](https://github.com/antlr/grammars-v4/tree/master/java/java), which supports Java 17, however, only language features up to Java 11 are supported. 9 | 10 | Install the tool like most other Node.js packages, by running `npm i java2typescript` in your project folder. 11 | 12 | # How To Use the Tool 13 | 14 | There are two ways to execute a conversion. For convenience there's a converter script, exported as binary script when adding the converter package as dependency, which can be executed. The other way is to write an own script which imports the necessary classes and run the process from there. 15 | 16 | ## The `java2ts` Command 17 | 18 | When you install the tool locally in a project, you can use an NPM script to run it. Define a script in your package.json: 19 | 20 | ```json 21 | { 22 | "scripts": { 23 | "java2ts": "java2ts config.json" 24 | } 25 | } 26 | ``` 27 | 28 | and run it: 29 | 30 | ```bash 31 | npm run java2ts 32 | ``` 33 | 34 | in the root of your project. The config file contains everything needed by the tool and is described in detail in [configuration.md](doc/configuration.md). 35 | 36 | When you install the tool globally (`npm i -g java2typescript`) you even can run it from everywhere, without involving NPM. 37 | 38 | ## Running From Your Code 39 | 40 | It is possible to launch a conversion from your application, by importing the `JavaToTypescriptConverter` class, configuring its options and then run it like this: 41 | 42 | ```typescript 43 | const configuration: IConverterConfiguration = { 44 | packageRoot: "../", 45 | ... 46 | }; 47 | 48 | const converter = new JavaToTypescriptConverter(configuration); 49 | await converter.startConversion(); 50 | ``` 51 | 52 | This is almost identical how the above mentioned `java2ts` script does it, except for some support code to transform the config json file into the require configuration structure. 53 | 54 | There's a dedicated repository demonstrating the use of java2typescript in both ways. Check it out: [java2ts-examples](https://github.com/mike-lischke/java2ts-examples). 55 | 56 | To support iterative conversions (running the tool multiple times with the same settings) without overwriting good files (e.g. when you have fixed errors in a file) add the text `/* java2ts: keep */` as the first line in such a file. The associated Java file is always parsed (for symbol resolution), but a Typescript file with that line is not overwritten anymore. A different log line is printed in the console when that is the case. 57 | 58 | ## Supported Language Features 59 | 60 | Of course there's no 1:1 translation between Java and Typescript and therefore it is important to understand what needs to be considered and what problems are to be expected. A separate document discusses these aspects: [feature documentation](doc/features.md). 61 | 62 | ### Common Problems in Converted Java Code 63 | 64 | There is almost never an error free result, after conversion. There are simply too many conditions that influence the process and its result. The most common problem classes that can occur are: 65 | 66 | - **Incomplete Conversion**: The source file may contain code that is not supported by java2typescript. However, the coverage of Java 11 features should be fairly complete, so this is a rare problem. 67 | - **Bugs**: The conversion process may contain bugs. 68 | - **Automatic Initialization**: Java guarantees proper initialization of every variable and class member, which is not the case in Typescript. For example, allocated arrays (`new Array()`) have no initial values for each index (in fact the indexes don't exist yet until a value is assigned). Hence you must ensure such arrays are initialized properly (`array.fill()`). For other elements, like variables, your linter should warn you about that. 69 | - **Boxing**: [Auto boxing in TypeScript](doc/features.md#boxing-and-unboxing) works only for built-in types. Other boxing, for example the conversion of a string literal to `java.lang.String`, is a manual process. For this reason you may get errors when string literals appear in Java code where `java.lang.String` is expected. In such cases you have to manually adjust the code to deal with this situation. This is probably the most common issue with translated code. 70 | - **Circular Dependencies**: Another fairly common problem is circular dependencies. TypeScript handles dependencies completely different compared to Java. What's totally normal in Java, for example using a static instance of a class, which derives from the class being loaded, will not work in TypeScript, because a class is not fully evaluated until all its imports are. There are a number of strategies to overcome trouble with circular dependencies, but it still is a major pain point to solve. 71 | - **Unsupported Features**: Certain constructs cannot be converted automatically (e.g. `this` calls, aka. explicit constructor invocation). The tool does as much as it can to convert the code, but some manual work is needed to make the code compiling and working. 72 | - **Linter Errors**: Many projects use a linter (like ESLint). Converted Java code often does not conform to popular TS linter formatting rules. It is recommended to allow formatting the generated code by the IDE (e.g. in VS Code) to fix the most common problems (like indentation). To help getting over linter problems until you have time to deal with them use the conversion setting which allows to add arbitrary text to each generated file. This is useful to write suppression commands for linter or spelling errors. See the `configuration.options.prefix` field. 73 | - **Project Settings**: There's a variety of possible TypeScript settings for a project (target versions, browser vs. Node.js etc.). These can cause errors that relate to your project setup, not the conversion process as such. 74 | -------------------------------------------------------------------------------- /src/JavaFileSource.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | import fs from "fs"; 7 | 8 | import { CharStream, CommonTokenStream, Interval, ParseTree } from "antlr4ng"; 9 | 10 | import { JavaLexer } from "../parser/generated/JavaLexer.js"; 11 | import { JavaParser, CompilationUnitContext } from "../parser/generated/JavaParser.js"; 12 | 13 | import { PackageSource } from "./PackageSource.js"; 14 | import { JavaFileSymbolTable } from "./JavaFileSymbolTable.js"; 15 | import { JavaErrorListener } from "./parsing/JavaErrorListener.js"; 16 | import { printParseTreeStack } from "./utilities.js"; 17 | import { ISymbolInfo } from "./conversion/types.js"; 18 | 19 | /** 20 | * This interface keeps all concerned parsing parts together, to ensure they stay alive during the entire 21 | * processing time. Symbol tables and parse trees depend on that. 22 | */ 23 | interface IFileParseInfo { 24 | content: string; 25 | inputStream: CharStream; 26 | lexer: JavaLexer; 27 | tokenStream: CommonTokenStream; 28 | parser: JavaParser; 29 | tree: CompilationUnitContext; 30 | } 31 | 32 | /** A source class for a single Java source file. */ 33 | export class JavaFileSource extends PackageSource { 34 | 35 | /** Only set if a file was parsed. */ 36 | public fileParseInfo?: IFileParseInfo; 37 | 38 | public constructor(packageId: string, sourceFile: string, targetFile: string, private packageRoot: string, 39 | private replacements?: Map) { 40 | super(packageId, sourceFile, targetFile); 41 | } 42 | 43 | public override get parseTree(): CompilationUnitContext | undefined { 44 | if (!this.fileParseInfo) { 45 | this.parse(); 46 | } 47 | 48 | return this.fileParseInfo?.tree; 49 | } 50 | 51 | public override getQualifiedSymbol = (context: ParseTree, name: string): ISymbolInfo | undefined => { 52 | return (this.symbolTable as JavaFileSymbolTable).getQualifiedSymbol(context, name); 53 | }; 54 | 55 | public override printParseTreeForPosition = (position: { column: number; row: number; }): void => { 56 | if (this.fileParseInfo) { 57 | printParseTreeStack(this.sourceFile, this.fileParseInfo.tree, this.fileParseInfo.parser.ruleNames, 58 | position); 59 | } 60 | }; 61 | 62 | protected override textFromInterval = (interval: Interval): string => { 63 | return this.fileParseInfo?.inputStream.getTextFromInterval(interval) ?? ""; 64 | }; 65 | 66 | private parse = (): void => { 67 | if (!fs.existsSync(this.sourceFile)) { 68 | console.warn(`\nFile ${this.sourceFile} does not exist.`); 69 | 70 | return; 71 | } 72 | 73 | let content = fs.readFileSync(this.sourceFile, "utf-8"); 74 | this.replacements?.forEach((value, pattern) => { 75 | content = content.replace(pattern, value); 76 | }); 77 | 78 | const inputStream = CharStream.fromString(content); 79 | const lexer = new JavaLexer(inputStream); 80 | const tokenStream = new CommonTokenStream(lexer); 81 | const parser = new JavaParser(tokenStream); 82 | 83 | const listener = new JavaErrorListener(); 84 | parser.addErrorListener(listener); 85 | 86 | const tree = parser.compilationUnit(); 87 | 88 | if (listener.errors.length === 0) { 89 | this.fileParseInfo = { 90 | content, 91 | inputStream, 92 | lexer, 93 | tokenStream, 94 | parser, 95 | tree, 96 | }; 97 | 98 | this.symbolTable = new JavaFileSymbolTable(this, this.packageRoot, this.importList); 99 | this.importList.delete(this); 100 | } else { 101 | throw new Error("Parsing failed for " + this.sourceFile); 102 | } 103 | }; 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/PackageSourceManager.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | import { JavaFileSource } from "./JavaFileSource.js"; 7 | import { JavaPackageSource } from "./JavaPackageSource.js"; 8 | import { PackageSource } from "./PackageSource.js"; 9 | 10 | /** This is the hook for the application to provide custom package sources for symbol resolution. */ 11 | export type CustomImportResolver = (packageId: string) => PackageSource | undefined; 12 | 13 | /** A class to hold package sources for use by the conversion process. */ 14 | export class PackageSourceManager { 15 | // A mapper function which can return a package source for a package ID. 16 | // Such a package source is usually not loaded from a file, but contains a symbol table constructed by 17 | // other means (e.g. hard coded values). 18 | private static customImportResolver?: CustomImportResolver; 19 | 20 | // A special path holding the JDK polyfills. 21 | private static javaTargetRoot: string; 22 | 23 | // The list of all known package sources. 24 | private static sources = new Map(); 25 | 26 | public static configure = (javaTargetRoot: string, customImportResolver?: CustomImportResolver): void => { 27 | this.customImportResolver = customImportResolver; 28 | this.javaTargetRoot = javaTargetRoot; 29 | 30 | // All JRE sources are always known. 31 | const source = new JavaPackageSource("java", "", this.javaTargetRoot); 32 | this.sources.set("java", source); 33 | }; 34 | 35 | /** 36 | * Looks up a package source in the internal registry, loaded from the given absolute path. 37 | * If it doesn't exist yet, it's created from the specified file. 38 | * 39 | * @param source The absolute path to a Java file, which can be loaded and parse. This file must exist or an error 40 | * is raised. 41 | * @param target The absolute path to the TS file, which will be generated. Can be empty if no target file is 42 | * generated or may contain a reference to some other source like a node module. 43 | * @param packageRoot The path to the root of the package where the given file is in. Used to resolve 44 | * relative file paths for imports. 45 | * @param replacements Patterns for string replacements in the source file, before it is parsed. 46 | * 47 | * @returns A package source instance. An error is thrown if the source could not be read. 48 | */ 49 | public static fromFile = (source: string, target: string, packageRoot: string, 50 | replacements?: Map): PackageSource => { 51 | // Construct a package name for lookup from the given paths. 52 | if (!source.startsWith(packageRoot)) { 53 | throw new Error("The full path must specify a file within the given package root."); 54 | } 55 | 56 | if (!source.endsWith(".java")) { 57 | throw new Error("Only Java files can be processed."); 58 | } 59 | 60 | let subPath = source.substring(packageRoot.length, source.length - ".java".length); 61 | if (subPath.length > 0 && subPath[0] === "/") { 62 | subPath = subPath.substring(1); 63 | } 64 | const packageId = subPath.replace(/\//g, "."); 65 | 66 | let packageSource = this.findSource(packageId); 67 | if (packageSource) { 68 | return packageSource; 69 | } 70 | 71 | packageSource = new JavaFileSource(packageId, source, target, packageRoot, replacements); 72 | this.sources.set(packageId, packageSource); 73 | 74 | return packageSource; 75 | }; 76 | 77 | /** 78 | * Uses a package ID for look up of a package source. This must be a complete package ID as used by imports. 79 | * Wildcard imports are handled in `fromPackageIdWildcard`. 80 | * 81 | * All packages should be created upfront before invoking any of the package lookup methods. Exceptions are 82 | * sources created from the custom import resolver. 83 | * 84 | * As a last resort an empty package source is created for IDs that are not know to the manager. 85 | * 86 | * @param packageId The ID of a package to load. 87 | * 88 | * @returns A package source instance which matches the given ID. 89 | */ 90 | public static fromPackageId = (packageId: string): PackageSource => { 91 | // Has the given package already been loaded? 92 | const source = this.findSource(packageId); 93 | if (source) { 94 | return source; 95 | } 96 | 97 | // No package with that ID registered yet. Reach out to the import resolver. 98 | if (this.customImportResolver) { 99 | const source = this.customImportResolver(packageId); 100 | if (source) { 101 | this.sources.set(source.packageId, source); 102 | 103 | return source; 104 | } 105 | } 106 | 107 | console.warn(`\nCannot find the source for package "${packageId}". Using an empty source instead.`); 108 | 109 | return this.emptySource(packageId); 110 | 111 | }; 112 | 113 | /** 114 | * Returns a list of package sources for all files in the given package. 115 | * 116 | * @param packageId The ID of a package to get all sources for. 117 | * 118 | * @returns A list of package source instances which match the given parameters. 119 | */ 120 | public static fromPackageIdWildcard = (packageId: string): PackageSource[] => { 121 | const sources: PackageSource[] = []; 122 | this.sources.forEach((value, key) => { 123 | if (key.startsWith(packageId)) { 124 | const rest = key.substring(packageId.length); 125 | if (rest.lastIndexOf(".") === 0) { 126 | sources.push(value); 127 | } 128 | } 129 | }); 130 | 131 | return sources; 132 | }; 133 | 134 | /** 135 | * Creates and registers an empty package source for the given ID. Such a source has no symbol table 136 | * and hence cannot contribute to symbol resolutions. 137 | * If there's already a package source (empty or not) for the given ID, that will be returned instead of 138 | * creating a new package source. 139 | * 140 | * @param packageId The package ID to use. 141 | * 142 | * @returns A package source for that ID. 143 | */ 144 | public static emptySource = (packageId: string): PackageSource => { 145 | let source = this.findSource(packageId); 146 | if (!source) { 147 | source = new PackageSource(packageId, "", ""); 148 | this.sources.set(packageId, source); 149 | } 150 | 151 | return source; 152 | }; 153 | 154 | /** 155 | * Removes all imported symbols from all known package sources. 156 | * Used at each process run to remove imported symbols from a previous run. 157 | */ 158 | public static clearImportedSymbols = (): void => { 159 | this.sources.forEach((source) => { 160 | source.clearImportedSymbols(); 161 | }); 162 | }; 163 | 164 | /** 165 | * Takes a full package ID and returns a package source for it, if one exists. 166 | * 167 | * @param packageId The package ID as used in a Java import statement (no wildcard). 168 | * 169 | * @returns The found package source or undefined, if none could be found. 170 | */ 171 | private static findSource = (packageId: string): PackageSource | undefined => { 172 | for (const [id, source] of this.sources) { 173 | if (packageId === id || packageId.startsWith(id + ".")) { 174 | return source; 175 | } 176 | } 177 | 178 | return undefined; 179 | }; 180 | 181 | } 182 | -------------------------------------------------------------------------------- /src/conversion/types.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | import { BaseSymbol } from "antlr4-c3"; 7 | 8 | import { PackageSource } from "../PackageSource.js"; 9 | 10 | export interface ISymbolInfo { 11 | /** The resolved symbol or undefined for anonymous class expressions. */ 12 | symbol?: BaseSymbol; 13 | qualifiedName: string; 14 | source?: PackageSource; 15 | } 16 | 17 | /** Determines the type of context for which certain processing is going to happen. */ 18 | export enum ContextType { 19 | File, 20 | Class, 21 | Interface, 22 | Enum, 23 | ClassExpression, 24 | } 25 | 26 | export enum MemberType { 27 | Initializer, 28 | Field, 29 | Constructor, 30 | Method, 31 | Lambda, 32 | Static, 33 | Abstract, 34 | Annotation, 35 | Class, 36 | Interface, 37 | Enum, 38 | Empty, 39 | } 40 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | export * from "./conversion/FileProcessor.js"; 7 | export * from "./conversion/JavaToTypeScript.js"; 8 | export * from "./conversion/MemberOrdering.js"; 9 | export * from "./conversion/types.js"; 10 | 11 | export * from "./parsing/JavaClassSymbol.js"; 12 | export * from "./parsing/JavaErrorListener.js"; 13 | export * from "./parsing/JavaParseTreeWalker.js"; 14 | 15 | export * from "./JavaFileSource.js"; 16 | export * from "./JavaFileSymbolTable.js"; 17 | export * from "./PackageSource.js"; 18 | export * from "./PackageSource.js"; 19 | export * from "./PackageSourceManager.js"; 20 | export * from "./utilities.js"; 21 | -------------------------------------------------------------------------------- /src/parsing/JavaClassSymbol.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | import { ClassSymbol, BaseSymbol } from "antlr4-c3"; 6 | 7 | import { JavaFileSymbolTable } from "../JavaFileSymbolTable.js"; 8 | 9 | /** 10 | * Extends the standard class symbol type by handling implemented types and adds symbol resolving for inherited members. 11 | */ 12 | export class JavaClassSymbol extends ClassSymbol { 13 | public typeParameters?: string; 14 | 15 | public override resolveSync(name: string, localOnly?: boolean): BaseSymbol | undefined { 16 | // First look for members of the classes this one is derived from. 17 | if (this.symbolTable instanceof JavaFileSymbolTable) { 18 | this.symbolTable.resolveReferences(); 19 | } 20 | 21 | const localType = super.resolveSync(name, localOnly); 22 | if (localType) { 23 | return localType; 24 | } 25 | 26 | if (this.extends.length > 0) { 27 | if (this.extends[0].name === name) { 28 | return this.extends[0]; 29 | } 30 | 31 | const symbol = this.extends[0].resolveSync(name, true); 32 | if (symbol) { 33 | return symbol; 34 | } 35 | } 36 | 37 | if (this.implements.length > 0) { 38 | for (const base of this.implements) { 39 | if (base.name === name) { 40 | return base; 41 | } 42 | 43 | const symbol = base.resolveSync(name, localOnly); 44 | if (symbol) { 45 | return symbol; 46 | } 47 | } 48 | } 49 | 50 | return undefined; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/parsing/JavaErrorListener.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | import { Recognizer, RecognitionException, Token, ATNSimulator, BaseErrorListener } from "antlr4ng"; 7 | 8 | export class JavaErrorListener extends BaseErrorListener { 9 | 10 | public errors: string[] = []; 11 | 12 | public override syntaxError(recognizer: Recognizer, 13 | offendingSymbol: S | null, line: number, charPositionInLine: number, msg: string, 14 | _e: RecognitionException | null): void { 15 | this.errors.push(msg); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/utilities.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | import { ParserRuleContext, TerminalNode, ParseTree } from "antlr4ng"; 7 | 8 | /** 9 | * Get the lowest level parse tree, which covers the given position. 10 | * 11 | * @param root The start point to search from. 12 | * @param column The position in the given row. 13 | * @param row The row position to search for. 14 | * 15 | * @returns The parse tree which covers the given position or undefined if none could be found. 16 | */ 17 | export const parseTreeFromPosition = (root: ParseTree, column: number, row: number): ParseTree | undefined => { 18 | // Does the root node actually contain the position? If not we don't need to look further. 19 | if (root instanceof TerminalNode) { 20 | const token = root.symbol; 21 | if (token.line !== row) { 22 | return undefined; 23 | } 24 | 25 | const tokenStop = token.column + (token.stop - token.start + 1); 26 | if (token.column <= column && tokenStop >= column) { 27 | return root; 28 | } 29 | 30 | return undefined; 31 | } else { 32 | const context = (root as ParserRuleContext); 33 | if (!context.start || !context.stop) { // Invalid tree? 34 | return undefined; 35 | } 36 | 37 | if (context.start.line > row || (context.start.line === row && column < context.start.column)) { 38 | return undefined; 39 | } 40 | 41 | const tokenStop = context.stop.column + (context.stop.stop - context.stop.start + 1); 42 | if (context.stop.line < row || (context.stop.line === row && tokenStop < column)) { 43 | return undefined; 44 | } 45 | 46 | if (context.children) { 47 | for (const child of context.children) { 48 | const result = parseTreeFromPosition(child, column, row); 49 | if (result) { 50 | return result; 51 | } 52 | } 53 | } 54 | 55 | return context; 56 | 57 | } 58 | }; 59 | 60 | /** 61 | * Converts a parse tree invocation stack to a string and prints it to the console. 62 | * 63 | * @param fileName The name of the file for which the output is produced. 64 | * @param root The parse tree to use. 65 | * @param ruleNames The list of all rule names for pretty printing. 66 | * @param position The position in the source text where to start parse tree traversal from. 67 | * @param position.column The column value. 68 | * @param position.row The row value. 69 | */ 70 | export const printParseTreeStack = (fileName: string, root: ParseTree, ruleNames: string[], 71 | position: { column: number; row: number; }): void => { 72 | const tree = parseTreeFromPosition(root, position.column, position.row); 73 | if (!tree) { 74 | console.warn(`DEBUG: no parse tree found in ${fileName} at column ${position.column}, row ${position.row}`); 75 | } 76 | 77 | console.log("\n\n"); 78 | if (tree instanceof TerminalNode) { 79 | console.log("Parse tree: " + (tree.parent as ParserRuleContext).toString(ruleNames)); 80 | console.log("\nText at position: " + tree.toString()); 81 | } else if (tree instanceof ParserRuleContext) { 82 | console.log(tree.toString(ruleNames)); 83 | } 84 | 85 | console.log("\n"); 86 | }; 87 | -------------------------------------------------------------------------------- /tests/conversion/Option.spec.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | import * as fs from "fs/promises"; 7 | import * as path from "path"; 8 | 9 | import { JavaToTypescriptConverter } from "../../src/conversion/JavaToTypeScript.js"; 10 | 11 | describe("Options Tests", () => { 12 | const testDir = path.join(process.cwd(), "tests"); 13 | const dataDir = path.join(testDir, "test-data"); 14 | const targetDir = path.join(testDir, "conversion", "generated"); 15 | 16 | afterAll(async () => { 17 | await fs.rm(targetDir, { recursive: true, force: true }); 18 | }); 19 | 20 | it("Prefix", async () => { 21 | const rand = Math.random(); 22 | 23 | const converter = new JavaToTypescriptConverter({ 24 | packageRoot: path.join(dataDir, "java-sources", "org"), 25 | outputPath: targetDir, 26 | exclude: [], 27 | include: [], 28 | options: { 29 | prefix: (sourcePath) => { 30 | return `/**\n * ${rand}\n * Auto generated from ${sourcePath}\n * ${new Date().toString()} */`; 31 | }, 32 | preferArrowFunctions: true, 33 | convertAnnotations: false, 34 | autoAddBraces: true, 35 | addIndexFiles: true, 36 | }, 37 | }); 38 | await converter.startConversion(); 39 | 40 | const targetFileName = path.join(targetDir, "java2typescript", "options", "OptionSpec.ts"); 41 | const targetFile = await fs.readFile(targetFileName, { encoding: "utf-8" }); 42 | expect(targetFile).toContain(`/**\n * ${rand}\n * Auto generated from`); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /tests/jest.config.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is released under the MIT license. 3 | * Copyright (c) 2023, Mike Lischke 4 | * 5 | * See LICENSE file for more info. 6 | */ 7 | 8 | import type { JestConfigWithTsJest } from "ts-jest"; 9 | 10 | const config: JestConfigWithTsJest = { 11 | // All imported modules in your tests should be mocked automatically 12 | // automock: false, 13 | 14 | // Stop running tests after `n` failures 15 | //bail: 1, 16 | 17 | // The directory where Jest should store its cached dependency information 18 | // cacheDirectory: "/private/var/folders/03/gj5f1gl92w11zc3l2c526dnm0000gn/T/jest_dx", 19 | 20 | // Automatically clear mock calls, instances, contexts and results before every test 21 | // clearMocks: true, 22 | 23 | ci: true, 24 | 25 | // Indicates whether the coverage information should be collected while executing the test 26 | collectCoverage: true, 27 | 28 | // An array of glob patterns indicating a set of files for which coverage information should be collected 29 | collectCoverageFrom: [ 30 | "**/src/**/*.ts", 31 | ], 32 | 33 | // The directory where Jest should output its coverage files 34 | coverageDirectory: "../coverage", 35 | 36 | // An array of regexp pattern strings used to skip coverage collection 37 | // coveragePathIgnorePatterns: [ 38 | // "/node_modules/" 39 | // ], 40 | 41 | // Indicates which provider should be used to instrument code for coverage 42 | coverageProvider: "v8", 43 | 44 | // A list of reporter names that Jest uses when writing coverage reports 45 | coverageReporters: [ 46 | "json", 47 | "text", 48 | "clover", 49 | "html", 50 | ], 51 | 52 | // An object that configures minimum threshold enforcement for coverage results 53 | coverageThreshold: { 54 | global: { 55 | statements: 65, 56 | branches: 70, 57 | functions: 50, 58 | lines: 65, 59 | }, 60 | }, 61 | 62 | // A path to a custom dependency extractor 63 | // dependencyExtractor: undefined, 64 | 65 | // displayName: "FE unit tests", 66 | 67 | // Make calling deprecated APIs throw helpful error messages 68 | // errorOnDeprecated: false, 69 | 70 | // The default configuration for fake timers 71 | // fakeTimers: { 72 | // "enableGlobally": false 73 | // }, 74 | 75 | // Force coverage collection from ignored files using an array of glob patterns 76 | // forceCoverageMatch: [], 77 | 78 | // A path to a module which exports an async function that is triggered once before all test suites 79 | // globalSetup: "./src/tests/globalSetup.ts", 80 | 81 | // A path to a module which exports an async function that is triggered once after all test suites 82 | // globalTeardown: "./src/tests/globalTearDown.ts", 83 | 84 | // A set of global variables that need to be available in all test environments 85 | globals: {}, 86 | 87 | // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 88 | // 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 89 | // 2 workers. 90 | //maxWorkers: "50%", 91 | 92 | // An array of directory names to be searched recursively up from the requiring module's location 93 | // moduleDirectories: [ 94 | // "node_modules" 95 | // ], 96 | 97 | workerIdleMemoryLimit: "500MB", 98 | 99 | // An array of file extensions your modules use 100 | moduleFileExtensions: [ 101 | "tsx", 102 | "ts", 103 | "js", 104 | "mjs", 105 | "cjs", 106 | "jsx", 107 | "json", 108 | "node", 109 | ], 110 | 111 | // A map from regular expressions to module names or to arrays of module names that allow to stub out resources 112 | // with a single module 113 | moduleNameMapper: { 114 | // eslint-disable-next-line @typescript-eslint/naming-convention 115 | "^(\\.{1,2}/.*)\\.js$": "$1", 116 | }, 117 | 118 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module 119 | // loader 120 | // modulePathIgnorePatterns: [], 121 | 122 | // Activates notifications for test results 123 | // notify: false, 124 | 125 | // An enum that specifies notification mode. Requires { notify: true } 126 | // notifyMode: "failure-change", 127 | 128 | // A preset that is used as a base for Jest's configuration 129 | preset: "ts-jest/presets/default-esm", 130 | 131 | // Run tests from one or more projects 132 | // projects: undefined, 133 | 134 | // Use this configuration option to add custom reporters to Jest 135 | // reporters: undefined, 136 | 137 | // Automatically reset mock state before every test 138 | resetMocks: false, 139 | 140 | // Reset the module registry before running each individual test 141 | // resetModules: false, 142 | 143 | // A path to a custom resolver 144 | // resolver: undefined, 145 | 146 | // Automatically restore mock state and implementation before every test 147 | // restoreMocks: false, 148 | 149 | // The main base directory for resolving all other relative paths from. 150 | rootDir: "../", 151 | 152 | // A list of paths to directories that Jest should use to search for files in 153 | roots: [ 154 | "/src/", 155 | "/tests/", 156 | ], 157 | 158 | // Allows you to use a custom runner instead of Jest's default test runner 159 | // runner: "jest-runner", 160 | 161 | // The paths to modules that run some code to configure or set up the testing environment before each test 162 | // setupFiles: [], 163 | 164 | // A list of paths to modules that run some code to configure or set up the testing framework before each test 165 | setupFilesAfterEnv: [ 166 | ], 167 | 168 | // The number of seconds after which a test is considered as slow and reported as such in the results. 169 | // slowTestThreshold: 5, 170 | 171 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 172 | // snapshotSerializers: [], 173 | 174 | // The test environment that will be used for testing 175 | testEnvironment: "node", 176 | 177 | // Options that will be passed to the testEnvironment 178 | testEnvironmentOptions: {}, 179 | 180 | // Adds a location field to test results 181 | // testLocationInResults: false, 182 | 183 | // The glob patterns Jest uses to detect test files 184 | testMatch: ["**/*.spec.ts"], 185 | 186 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 187 | testPathIgnorePatterns: [ 188 | //"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$", 189 | //"^.+\\.module\\.(css|sass|scss)$", 190 | ], 191 | 192 | // The regexp pattern or array of patterns that Jest uses to detect test files 193 | // testRegex: [], 194 | 195 | // This option allows the use of a custom results processor 196 | // testResultsProcessor: undefined, 197 | 198 | // This option allows use of a custom test runner 199 | // testRunner: "jest-circus/runner", 200 | 201 | // CI machines can be slow. 202 | testTimeout: 30000, 203 | 204 | // A map from regular expressions to paths to transformers 205 | transform: { 206 | // eslint-disable-next-line @typescript-eslint/naming-convention 207 | "^.+\\.ts$": [ 208 | "ts-jest", 209 | { 210 | useESM: true, 211 | }, 212 | ], 213 | }, 214 | 215 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip 216 | // transformation 217 | transformIgnorePatterns: [ 218 | "/../node_modules/", 219 | ], 220 | 221 | // An array of regexp pattern strings that are matched against all modules before the module loader will 222 | // automatically return a mock for them 223 | // unmockedModulePathPatterns: undefined, 224 | 225 | // Indicates whether each individual test should be reported during the run 226 | // verbose: undefined, 227 | 228 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 229 | // watchPathIgnorePatterns: [], 230 | 231 | // Whether to use watchman for file crawling 232 | // watchman: true, 233 | }; 234 | 235 | export default config; 236 | -------------------------------------------------------------------------------- /tests/test-data/java-sources/org/java2typescript/options/OptionSpec.java: -------------------------------------------------------------------------------- 1 | public class OptionSpec { 2 | private String val1; 3 | private String val2; 4 | private String val3; 5 | } 6 | -------------------------------------------------------------------------------- /tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "NodeNext", 4 | "target": "ES2022", 5 | "module": "NodeNext", 6 | "outDir": "./output", 7 | "noEmit": true, 8 | "sourceMap": true, 9 | "esModuleInterop": true, 10 | "isolatedModules": true, 11 | "strict": true, 12 | "noImplicitAny": true, 13 | "noImplicitOverride": false, 14 | "strictNullChecks": true, 15 | "strictPropertyInitialization": true, 16 | "rootDirs": [ 17 | "src", 18 | ] 19 | }, 20 | "include": [ 21 | "**/*.spec.ts", 22 | "jest.config.ts" 23 | ], 24 | "exclude": [ 25 | "node_modules/**/*.*", 26 | "output/**/*.*" 27 | ], 28 | "ts-node": { 29 | "esm": true, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tools/convertANTLR3Runtime.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | /* eslint-disable max-classes-per-file */ 7 | 8 | // cspell:ignore Compiletime, Interp 9 | 10 | import * as path from "path"; 11 | 12 | import { PackageSourceManager } from "../src/PackageSourceManager.js"; 13 | import { IConverterConfiguration, JavaToTypescriptConverter } from "../src/conversion/JavaToTypeScript.js"; 14 | import { PackageSource } from "../src/PackageSource.js"; 15 | 16 | /** Member sorting identifiers as used in the project's eslint configuration. */ 17 | const memberOrderOptions = { 18 | default: [ 19 | "public-static-field", 20 | "protected-static-field", 21 | "private-static-field", 22 | "public-instance-field", 23 | "protected-instance-field", 24 | "private-instance-field", 25 | "public-abstract-field", 26 | "protected-abstract-field", 27 | "public-field", 28 | "protected-field", 29 | "private-field", 30 | "static-field", 31 | "instance-field", 32 | "abstract-field", 33 | "decorated-field", 34 | "field", 35 | "public-constructor", 36 | "protected-constructor", 37 | "private-constructor", 38 | "constructor", 39 | "public-static-method", 40 | "protected-static-method", 41 | "private-static-method", 42 | "public-method", 43 | "protected-method", 44 | "private-method", 45 | "public-abstract-method", 46 | "protected-abstract-method", 47 | ], 48 | }; 49 | 50 | const importResolver = (packageId: string): PackageSource | undefined => { 51 | if (packageId.startsWith("org.antlr.runtime")) { 52 | // ANTLRv3 runtime. Use ANTLRv4 instead. 53 | return new PackageSource("org.antlr.runtime", "", "antlr4ng"); 54 | } 55 | 56 | return PackageSourceManager.emptySource(packageId); 57 | }; 58 | 59 | const include: string[] = [ 60 | //"ErrorBufferAllErrors.java", 61 | ]; 62 | 63 | const classResolver = new Map([ 64 | ["String", { alias: "string", importPath: "" }], 65 | ["Object", { alias: "unknown", importPath: "" }], 66 | ["ArrayList", { alias: "Array", importPath: "" }], 67 | ["Locale", { alias: "Intl.Locale", importPath: "" }], 68 | ["Map", { alias: "Map", importPath: "" }], 69 | ["HashMap", { alias: "Map", importPath: "" }], 70 | ["Integer", { alias: "number", importPath: "" }], 71 | ["RuntimeException", { alias: "Error", importPath: "" }], 72 | ["NoSuchMethodError", { alias: "Error", importPath: "" }], 73 | ]); 74 | 75 | const convertANTLR4JavaRuntime = async () => { 76 | const antlrToolOptions: IConverterConfiguration = { 77 | javaLib: "", 78 | packageRoot: path.resolve(process.cwd(), "../antlr3/runtime/Java/src/main/java/org"), 79 | include, 80 | exclude: [], 81 | outputPath: "../antlr3ts-temp/", 82 | options: { 83 | prefix: 84 | `/* 85 | * Copyright (c) The ANTLR Project. All rights reserved. 86 | * Use of this file is governed by the BSD 3-clause license that 87 | * can be found in the LICENSE.txt file in the project root. 88 | */ 89 | 90 | // cspell: disable 91 | 92 | /* eslint-disable jsdoc/require-returns, jsdoc/require-param */`, 93 | importResolver, 94 | convertAnnotations: false, 95 | preferArrowFunctions: false, 96 | autoAddBraces: true, 97 | addIndexFiles: false, 98 | addNullUnionType: false, 99 | suppressTypeWithInitializer: true, 100 | wrapStringLiterals: false, 101 | memberOrderOptions, 102 | sourceMappings: [ 103 | ], 104 | useUnqualifiedTypes: true, 105 | classResolver, 106 | importExtension: ".js", 107 | convertNumberPrimitiveTypes: true, 108 | }, 109 | sourceReplace: new Map([ 110 | ]), 111 | debug: { 112 | pathForPosition: { 113 | filePattern: "XXX", 114 | position: { 115 | row: 49, 116 | column: 5, 117 | }, 118 | }, 119 | }, 120 | 121 | }; 122 | 123 | const converter = new JavaToTypescriptConverter(antlrToolOptions); 124 | await converter.startConversion(); 125 | }; 126 | 127 | await convertANTLR4JavaRuntime(); 128 | -------------------------------------------------------------------------------- /tools/convertANTLR4Runtime.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | /* eslint-disable max-classes-per-file */ 7 | 8 | // cspell:ignore Compiletime, Interp 9 | 10 | import * as path from "path"; 11 | 12 | import { PackageSourceManager } from "../src/PackageSourceManager.js"; 13 | import { IConverterConfiguration, JavaToTypescriptConverter } from "../src/conversion/JavaToTypeScript.js"; 14 | import { PackageSource } from "../src/PackageSource.js"; 15 | 16 | /** Member sorting identifiers as used in the project's eslint configuration. */ 17 | const memberOrderOptions = { 18 | default: [ 19 | "public-static-field", 20 | "protected-static-field", 21 | "private-static-field", 22 | "public-instance-field", 23 | "protected-instance-field", 24 | "private-instance-field", 25 | "public-abstract-field", 26 | "protected-abstract-field", 27 | "public-field", 28 | "protected-field", 29 | "private-field", 30 | "static-field", 31 | "instance-field", 32 | "abstract-field", 33 | "decorated-field", 34 | "field", 35 | "public-constructor", 36 | "protected-constructor", 37 | "private-constructor", 38 | "constructor", 39 | "public-static-method", 40 | "protected-static-method", 41 | "private-static-method", 42 | "public-method", 43 | "protected-method", 44 | "private-method", 45 | "public-abstract-method", 46 | "protected-abstract-method", 47 | ], 48 | }; 49 | 50 | const importResolver = (packageId: string): PackageSource | undefined => { 51 | if (packageId.startsWith("org.antlr.runtime")) { 52 | // ANTLRv3 runtime. Use ANTLRv4 instead. 53 | return new PackageSource("org.antlr.runtime", "", "antlr4ng"); 54 | } 55 | 56 | return PackageSourceManager.emptySource(packageId); 57 | }; 58 | 59 | const include: string[] = [ 60 | //"ErrorBufferAllErrors.java", 61 | ]; 62 | 63 | const classResolver = new Map([ 64 | ["String", { alias: "string", importPath: "" }], 65 | ["Object", { alias: "Object", importPath: "" }], 66 | ["ArrayList", { alias: "Array", importPath: "" }], 67 | ["Locale", { alias: "Intl.Locale", importPath: "" }], 68 | ["Map", { alias: "Map", importPath: "" }], 69 | ["HashMap", { alias: "Map", importPath: "" }], 70 | ["Integer", { alias: "number", importPath: "" }], 71 | ]); 72 | 73 | const convertANTLR4JavaRuntime = async () => { 74 | const antlrToolOptions: IConverterConfiguration = { 75 | packageRoot: path.resolve(process.cwd(), "../antlr4/runtime/Java/src/org"), 76 | include, 77 | exclude: [], 78 | outputPath: "../antlr4-temp/tests", 79 | options: { 80 | prefix: 81 | `/* 82 | * Copyright(c) Terence Parr.All rights reserved. 83 | * Licensed under the BSD- 3 License.See License.txt in the project root for license information. 84 | */ 85 | 86 | // cspell: disable`, 87 | importResolver, 88 | convertAnnotations: true, 89 | preferArrowFunctions: false, 90 | autoAddBraces: true, 91 | addIndexFiles: false, 92 | addNullUnionType: false, 93 | suppressTypeWithInitializer: true, 94 | wrapStringLiterals: false, 95 | memberOrderOptions, 96 | sourceMappings: [ 97 | ], 98 | useUnqualifiedTypes: true, 99 | classResolver, 100 | importExtension: ".js", 101 | convertNumberPrimitiveTypes: true, 102 | }, 103 | sourceReplace: new Map([ 104 | ]), 105 | debug: { 106 | pathForPosition: { 107 | filePattern: "XXX", 108 | position: { 109 | row: 49, 110 | column: 5, 111 | }, 112 | }, 113 | }, 114 | 115 | }; 116 | 117 | const converter = new JavaToTypescriptConverter(antlrToolOptions); 118 | await converter.startConversion(); 119 | }; 120 | 121 | await convertANTLR4JavaRuntime(); 122 | -------------------------------------------------------------------------------- /tools/convertANTLR4Tool.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | /* eslint-disable max-classes-per-file */ 7 | 8 | import * as path from "path"; 9 | 10 | import { PackageSourceManager } from "../src/PackageSourceManager.js"; 11 | import { IConverterConfiguration, JavaToTypescriptConverter } from "../src/conversion/JavaToTypeScript.js"; 12 | import { PackageSource } from "../src/PackageSource.js"; 13 | 14 | /** Member sorting identifiers as used in the project's eslint configuration. */ 15 | const memberOrderOptions = { 16 | default: [ 17 | "signature", 18 | "public-static-field", 19 | "protected-static-field", 20 | "private-static-field", 21 | "public-decorated-field", 22 | "protected-decorated-field", 23 | "private-decorated-field", 24 | "public-instance-field", 25 | "protected-instance-field", 26 | "private-instance-field", 27 | "public-abstract-field", 28 | "protected-abstract-field", 29 | "public-field", 30 | "protected-field", 31 | "private-field", 32 | "static-field", 33 | "instance-field", 34 | "abstract-field", 35 | "decorated-field", 36 | "field", 37 | "public-constructor", 38 | "protected-constructor", 39 | "private-constructor", 40 | "constructor", 41 | "public-static-method", 42 | "protected-static-method", 43 | "private-static-method", 44 | "public-decorated-method", 45 | "protected-decorated-method", 46 | "private-decorated-method", 47 | "public-instance-method", 48 | "protected-instance-method", 49 | "private-instance-method", 50 | "public-abstract-method", 51 | "protected-abstract-method", 52 | ], 53 | }; 54 | 55 | const importResolver = (packageId: string): PackageSource | undefined => { 56 | if (packageId.startsWith("org.antlr.runtime")) { 57 | // ANTLRv3 runtime. Use ANTLRv4 instead. 58 | return new PackageSource("org.antlr.runtime", "", "antlr4ng"); 59 | } 60 | 61 | return PackageSourceManager.emptySource(packageId); 62 | }; 63 | 64 | const include: string[] = [ 65 | ]; 66 | 67 | const classResolver = new Map([ 68 | ["String", { alias: "string", importPath: "" }], 69 | ["Object", { alias: "Object", importPath: "" }], 70 | ["ArrayList", { alias: "Array", importPath: "" }], 71 | ["List", { alias: "Array", importPath: "" }], 72 | ["Locale", { alias: "Intl.Locale", importPath: "" }], 73 | ["Map", { alias: "Map", importPath: "" }], 74 | ["HashMap", { alias: "Map", importPath: "" }], 75 | ["Integer", { alias: "number", importPath: "" }], 76 | ["HashSet", { alias: "", importPath: "antlr4ng" }], 77 | ["OrderedHashSet", { alias: "", importPath: "antlr4ng" }], 78 | ["HashMap", { alias: "", importPath: "antlr4ng" }], 79 | ["OrderedHashMap", { alias: "", importPath: "antlr4ng" }], 80 | ["LinkedHashMap", { alias: "HashMap", importPath: "antlr4ng" }], 81 | ["VocabularyImpl", { alias: "Vocabulary", importPath: "antlr4ng" }], 82 | ["Pair", { alias: "", importPath: "" }], 83 | ]); 84 | 85 | const convertANTLR4Tool = async () => { 86 | const antlrToolOptions: IConverterConfiguration = { 87 | packageRoot: path.resolve(process.cwd(), "../ANTLRng/src/tree-walkers"), 88 | include, 89 | exclude: [], 90 | outputPath: "../ANTLRng/src/tree-walkers", 91 | javaLib: "", 92 | options: { 93 | prefix: ` 94 | /* eslint-disable jsdoc/require-returns, jsdoc/require-param */`, 95 | importResolver, 96 | convertAnnotations: true, 97 | preferArrowFunctions: false, 98 | autoAddBraces: true, 99 | addIndexFiles: false, 100 | addNullUnionType: false, 101 | suppressTypeWithInitializer: true, 102 | wrapStringLiterals: false, 103 | memberOrderOptions, 104 | sourceMappings: [ 105 | { sourcePath: path.resolve(process.cwd(), "../antlr4/runtime/Java/src"), importPath: "antlr4ng" }, 106 | ], 107 | useUnqualifiedTypes: true, 108 | libraryImports: new Map([ 109 | //[path.resolve(process.cwd(), "../ANTLRng/runtime-testsuite/decorators.js"), ["Test", "Override"]], 110 | ]), 111 | importExtension: ".js", 112 | convertNumberPrimitiveTypes: true, 113 | classResolver, 114 | }, 115 | sourceReplace: new Map([ 116 | ]), 117 | debug: { 118 | pathForPosition: { 119 | filePattern: "XXX", 120 | position: { 121 | row: 49, 122 | column: 5, 123 | }, 124 | }, 125 | }, 126 | 127 | }; 128 | 129 | const converter = new JavaToTypescriptConverter(antlrToolOptions); 130 | await converter.startConversion(); 131 | }; 132 | 133 | await convertANTLR4Tool(); 134 | -------------------------------------------------------------------------------- /tools/convertJDKTests.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | import * as path from "path"; 7 | 8 | import { PackageSourceManager } from "../src/PackageSourceManager.js"; 9 | import { 10 | IConverterConfiguration, JavaToTypescriptConverter, 11 | } from "../src/conversion/JavaToTypeScript.js"; 12 | import { PackageSource } from "../src/PackageSource.js"; 13 | import { ClassSymbol, Modifier, NamespaceSymbol, RoutineSymbol, SymbolTable } from "antlr4-c3"; 14 | 15 | /** Member sorting identifiers as used in the project's eslint configuration. */ 16 | const memberOrderOptions = { 17 | default: [ 18 | "signature", 19 | "public-static-field", 20 | "protected-static-field", 21 | "private-static-field", 22 | "public-decorated-field", 23 | "protected-decorated-field", 24 | "private-decorated-field", 25 | "public-instance-field", 26 | "protected-instance-field", 27 | "private-instance-field", 28 | "public-abstract-field", 29 | "protected-abstract-field", 30 | "public-field", 31 | "protected-field", 32 | "private-field", 33 | "static-field", 34 | "instance-field", 35 | "abstract-field", 36 | "decorated-field", 37 | "field", 38 | "public-constructor", 39 | "protected-constructor", 40 | "private-constructor", 41 | "constructor", 42 | "public-static-method", 43 | "protected-static-method", 44 | "private-static-method", 45 | "public-decorated-method", 46 | "protected-decorated-method", 47 | "private-decorated-method", 48 | "public-instance-method", 49 | "protected-instance-method", 50 | "private-instance-method", 51 | "public-abstract-method", 52 | "protected-abstract-method", 53 | ], 54 | }; 55 | 56 | class TestNGSource extends PackageSource { 57 | protected override createSymbolTable(): SymbolTable { 58 | const symbolTable = new SymbolTable("TestNG", { allowDuplicateSymbols: false }); 59 | 60 | const testng = symbolTable.addNewNamespaceFromPathSync(undefined, "org.testng"); 61 | const assert = symbolTable.addNewSymbolOfType(ClassSymbol, testng, "Assert", [], []); 62 | let routine = symbolTable.addNewSymbolOfType(RoutineSymbol, assert, "assertEquals"); 63 | routine.modifiers.add(Modifier.Static); 64 | routine = symbolTable.addNewSymbolOfType(RoutineSymbol, assert, "assertNotEquals"); 65 | routine.modifiers.add(Modifier.Static); 66 | routine = symbolTable.addNewSymbolOfType(RoutineSymbol, assert, "assertTrue"); 67 | routine.modifiers.add(Modifier.Static); 68 | routine = symbolTable.addNewSymbolOfType(RoutineSymbol, assert, "assertFalse"); 69 | routine.modifiers.add(Modifier.Static); 70 | 71 | const annotations = symbolTable.addNewSymbolOfType(NamespaceSymbol, testng, "annotations"); 72 | symbolTable.addNewSymbolOfType(RoutineSymbol, annotations, "Test"); 73 | symbolTable.addNewSymbolOfType(RoutineSymbol, annotations, "DataProvider"); 74 | 75 | return symbolTable; 76 | } 77 | 78 | protected override get importOverride(): string | undefined { 79 | return "org"; 80 | } 81 | } 82 | 83 | let annotationSource: TestNGSource; 84 | 85 | const importResolver = (packageId: string): PackageSource | undefined => { 86 | if (packageId.startsWith("org.testng")) { 87 | if (!annotationSource) { 88 | // Create the package source on demand, so we don't try to access internal stuff before the 89 | // package manager is fully initialized. 90 | annotationSource = new TestNGSource("org.testng", "", "../../../../org/org"); 91 | } 92 | 93 | return annotationSource; 94 | } 95 | 96 | return PackageSourceManager.emptySource(packageId); 97 | }; 98 | 99 | /** 100 | * Files and folders of the JDK test suite that should be converted. Included here are only those tests for classes 101 | * we currently have in the JREE (white list). The rest is ignored for now. 102 | * However, some of the tests included via folders cannot be executed as they require additional classes that are not 103 | * part of the JREE. These are listed in the exclude list. 104 | */ 105 | const include: string[] = [ 106 | "io/BufferedReader/", 107 | "io/NegativeInitSize.java", 108 | "io/Unicode.java", 109 | "util/AbstractList", 110 | "util/ArrayList", 111 | "util/List", 112 | "util/Collection/testlibrary", 113 | "util/HashMap", 114 | "util/HashSet", 115 | "util/Iterator", 116 | ]; 117 | 118 | const convertJDKLangTests = async () => { 119 | const antlrToolOptions: IConverterConfiguration = { 120 | packageRoot: path.resolve(process.cwd(), "../jdk/test/jdk/java/"), 121 | javaLib: "../../../src", 122 | //include, 123 | include: ["/IteratorDefaults.java"], 124 | exclude: [ // Contains only files that were included above. 125 | "io/BufferedReader/Lines.java", // Requires stream + lambda support. 126 | "io/BufferedReader/ReadLineSync.java", // Requires thread support. 127 | "io/BufferedReader/SkipNegativeInitSize.java", // Requires CharArrayReader 128 | "io/BufferedReader/SkipNegative.java", // Requires CharArrayReader 129 | "io/SkipNegativeInitSize.java", // Requires ByteArrayInputStream and others. 130 | "io/NegativeInitSize.java", // Requires CharArrayReader and others. 131 | 132 | "util/ArrayList/ArrayManagement.java", // Requires reflection. 133 | "util/ArrayList/Bug6533203.java", // Requires thread support. 134 | "util/ArrayList/IteratorMicroBenchmark.java", // Requires concurrent + ref support. 135 | "util/ArrayList/RangeCheckMicroBenchmark.java", // Requires stream support. 136 | "util/HashMap/KeySetRemove.java", // Uses TreeMap too. 137 | "util/HashMap/PutNullKey.java", // Uses IntStream. 138 | "util/HashSet/Serialization.java", // Requires serialization support. 139 | ], 140 | outputPath: "../jree/tests/jdk/java/", 141 | options: { 142 | importResolver, 143 | convertAnnotations: true, 144 | sourceMappings: [ 145 | ], 146 | preferArrowFunctions: false, 147 | autoAddBraces: true, 148 | addIndexFiles: false, 149 | addNullUnionType: false, 150 | suppressTypeWithInitializer: true, 151 | wrapStringLiterals: false, 152 | memberOrderOptions, 153 | prefix: ` 154 | /* eslint-disable @typescript-eslint/prefer-for-of */ 155 | /* eslint-disable max-len */ 156 | /* cspell: disable */ 157 | /* eslint-disable jsdoc/check-tag-names */ 158 | /* eslint-disable @typescript-eslint/naming-convention */ 159 | `, 160 | useUnqualifiedTypes: true, 161 | }, 162 | sourceReplace: new Map([ 163 | ]), 164 | debug: { 165 | pathForPosition: { 166 | //filePattern: "XXX", 167 | position: { 168 | row: 49, 169 | column: 5, 170 | }, 171 | }, 172 | }, 173 | 174 | }; 175 | 176 | const converter = new JavaToTypescriptConverter(antlrToolOptions); 177 | await converter.startConversion(); 178 | }; 179 | 180 | await convertJDKLangTests(); 181 | -------------------------------------------------------------------------------- /tools/convertRuntimeTests.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | /* eslint-disable max-classes-per-file */ 7 | 8 | import * as path from "path"; 9 | 10 | import { PackageSourceManager } from "../src/PackageSourceManager.js"; 11 | import { IConverterConfiguration, JavaToTypescriptConverter } from "../src/conversion/JavaToTypeScript.js"; 12 | import { PackageSource } from "../src/PackageSource.js"; 13 | 14 | /** Member sorting identifiers as used in the project's eslint configuration. */ 15 | const memberOrderOptions = { 16 | default: [ 17 | "signature", 18 | "public-static-field", 19 | "protected-static-field", 20 | "private-static-field", 21 | "public-decorated-field", 22 | "protected-decorated-field", 23 | "private-decorated-field", 24 | "public-instance-field", 25 | "protected-instance-field", 26 | "private-instance-field", 27 | "public-abstract-field", 28 | "protected-abstract-field", 29 | "public-field", 30 | "protected-field", 31 | "private-field", 32 | "static-field", 33 | "instance-field", 34 | "abstract-field", 35 | "decorated-field", 36 | "field", 37 | "public-constructor", 38 | "protected-constructor", 39 | "private-constructor", 40 | "constructor", 41 | "public-static-method", 42 | "protected-static-method", 43 | "private-static-method", 44 | "public-decorated-method", 45 | "protected-decorated-method", 46 | "private-decorated-method", 47 | "public-instance-method", 48 | "protected-instance-method", 49 | "private-instance-method", 50 | "public-abstract-method", 51 | "protected-abstract-method", 52 | ], 53 | }; 54 | 55 | /** An empty source for JUnit test. We'll provide some helper methods instead. */ 56 | class JUnitSource extends PackageSource { 57 | } 58 | 59 | let annotationSource: JUnitSource; 60 | 61 | const junitAPIs = [ 62 | "assertEquals", 63 | "assertThrows", 64 | ]; 65 | 66 | const importResolver = (packageId: string): PackageSource | undefined => { 67 | if (packageId.startsWith("org.junit.jupiter.api")) { 68 | if (!annotationSource) { 69 | // Create the package source on demand, so we don't try to access internal stuff before the 70 | // package manager is fully initialized. 71 | annotationSource = new JUnitSource("org.junit.jupiter.api.Assertions", "", 72 | path.resolve(process.cwd(), "../ANTLRng/runtime-testsuite/junit.js")); 73 | 74 | junitAPIs.forEach((name) => { 75 | annotationSource.addImportedSymbol(name); 76 | }); 77 | } 78 | 79 | return annotationSource; 80 | } 81 | 82 | return PackageSourceManager.emptySource(packageId); 83 | }; 84 | 85 | const include: string[] = [ 86 | //"OSType.java", 87 | ]; 88 | 89 | const convertAntlrRuntimeTests = async () => { 90 | const antlrToolOptions: IConverterConfiguration = { 91 | packageRoot: path.resolve(process.cwd(), "../antlr4/runtime-testsuite/test"), 92 | include, 93 | exclude: [], 94 | outputPath: "../ANTLRng/runtime-testsuite/test", 95 | options: { 96 | importResolver, 97 | convertAnnotations: true, 98 | preferArrowFunctions: false, 99 | autoAddBraces: true, 100 | addIndexFiles: false, 101 | addNullUnionType: false, 102 | suppressTypeWithInitializer: true, 103 | wrapStringLiterals: false, 104 | memberOrderOptions, 105 | sourceMappings: [ 106 | { sourcePath: path.resolve(process.cwd(), "../antlr4/runtime/Java/src"), importPath: "antlr4ng" }, 107 | ], 108 | useUnqualifiedTypes: true, 109 | libraryImports: new Map([ 110 | [path.resolve(process.cwd(), "../ANTLRng/runtime-testsuite/decorators.js"), ["Test", "Override"]], 111 | ]), 112 | importExtension: ".js", 113 | }, 114 | sourceReplace: new Map([ 115 | ]), 116 | debug: { 117 | pathForPosition: { 118 | filePattern: "XXX", 119 | position: { 120 | row: 49, 121 | column: 5, 122 | }, 123 | }, 124 | }, 125 | 126 | }; 127 | 128 | const converter = new JavaToTypescriptConverter(antlrToolOptions); 129 | await converter.startConversion(); 130 | }; 131 | 132 | await convertAntlrRuntimeTests(); 133 | -------------------------------------------------------------------------------- /tools/convertST4.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) Mike Lischke. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | */ 5 | 6 | /* eslint-disable max-classes-per-file */ 7 | 8 | // cspell:ignore Compiletime, Interp 9 | 10 | import * as path from "path"; 11 | 12 | import { PackageSourceManager } from "../src/PackageSourceManager.js"; 13 | import { IConverterConfiguration, JavaToTypescriptConverter } from "../src/conversion/JavaToTypeScript.js"; 14 | import { PackageSource } from "../src/PackageSource.js"; 15 | import { ISymbolInfo } from "../src/conversion/types.js"; 16 | 17 | const junitAPIs = [ 18 | "assertEquals", 19 | "assertThrows", 20 | "assertTrue", 21 | ]; 22 | 23 | const supportClasses = [ 24 | "Test", 25 | "Override", 26 | ]; 27 | 28 | /** Member sorting identifiers as used in the project's eslint configuration. */ 29 | const memberOrderOptions = { 30 | default: [ 31 | "public-static-field", 32 | "protected-static-field", 33 | "private-static-field", 34 | "public-instance-field", 35 | "protected-instance-field", 36 | "private-instance-field", 37 | "public-abstract-field", 38 | "protected-abstract-field", 39 | "public-field", 40 | "protected-field", 41 | "private-field", 42 | "static-field", 43 | "instance-field", 44 | "abstract-field", 45 | "decorated-field", 46 | "field", 47 | "public-constructor", 48 | "protected-constructor", 49 | "private-constructor", 50 | "constructor", 51 | "public-static-method", 52 | "protected-static-method", 53 | "private-static-method", 54 | "public-method", 55 | "protected-method", 56 | "private-method", 57 | "public-abstract-method", 58 | "protected-abstract-method", 59 | ], 60 | }; 61 | 62 | /** An empty source for JUnit test. We'll provide some helper methods instead. */ 63 | class JUnitSource extends PackageSource { 64 | public override resolveType = (name: string): ISymbolInfo | undefined => { 65 | if (junitAPIs.includes(name)) { 66 | this.addImportedSymbol(name); 67 | }; 68 | 69 | return undefined; 70 | }; 71 | } 72 | 73 | class StringTemplateSource extends PackageSource { 74 | public override resolveType = (name: string): ISymbolInfo | undefined => { 75 | if (name.indexOf(".") >= 0) { 76 | return undefined; 77 | } 78 | 79 | if (!junitAPIs.includes(name) && !supportClasses.includes(name)) { 80 | this.addImportedSymbol(name); 81 | }; 82 | 83 | return undefined; 84 | }; 85 | } 86 | 87 | const importResolver = (packageId: string): PackageSource | undefined => { 88 | if (packageId.startsWith("org.antlr.runtime")) { 89 | // ANTLRv3 runtime. Use ANTLRv4 instead. 90 | return new PackageSource("org.antlr.runtime", "", "antlr4ng"); 91 | } 92 | 93 | if (packageId.startsWith("org.stringtemplate.v4")) { 94 | const stSource = new StringTemplateSource("org.stringtemplate.v4", "", path.resolve(process.cwd(), 95 | "../stringtemplate4-ts/src/index")); 96 | 97 | return stSource; 98 | } 99 | 100 | if (packageId.startsWith("org.junit")) { 101 | // Create the package source on demand, so we don't try to access internal stuff before the 102 | // package manager is fully initialized. 103 | const junitSource = new JUnitSource("org.junit", "", path.resolve(process.cwd(), 104 | "../stringtemplate4-ts/tests/junit.js")); 105 | 106 | return junitSource; 107 | } 108 | 109 | return PackageSourceManager.emptySource(packageId); 110 | }; 111 | 112 | const include: string[] = [ 113 | //"ErrorBufferAllErrors.java", 114 | ]; 115 | 116 | const classResolver = new Map([ 117 | ["String", { alias: "string", importPath: "" }], 118 | ["Object", { alias: "Object", importPath: "" }], 119 | ["ArrayList", { alias: "Array", importPath: "" }], 120 | ["Locale", { alias: "Intl.Locale", importPath: "" }], 121 | ["Map", { alias: "Map", importPath: "" }], 122 | ["HashMap", { alias: "Map", importPath: "" }], 123 | ["Integer", { alias: "number", importPath: "" }], 124 | ]); 125 | 126 | const convertStringTemplate4 = async () => { 127 | const antlrToolOptions: IConverterConfiguration = { 128 | packageRoot: path.resolve(process.cwd(), "../stringtemplate4/test"), 129 | include, 130 | exclude: ["gui", "ArrayIterator.java"], 131 | outputPath: "../stringtemplate4-ts/tests", 132 | options: { 133 | prefix: 134 | `/* 135 | * Copyright(c) Terence Parr.All rights reserved. 136 | * Licensed under the BSD- 3 License.See License.txt in the project root for license information. 137 | */ 138 | 139 | // cspell: disable`, 140 | importResolver, 141 | convertAnnotations: true, 142 | preferArrowFunctions: false, 143 | autoAddBraces: true, 144 | addIndexFiles: false, 145 | addNullUnionType: false, 146 | suppressTypeWithInitializer: true, 147 | wrapStringLiterals: false, 148 | memberOrderOptions, 149 | sourceMappings: [ 150 | ], 151 | useUnqualifiedTypes: true, 152 | classResolver, 153 | libraryImports: new Map([ 154 | [path.resolve(process.cwd(), "../stringtemplate4-ts/tests/decorators.js"), supportClasses], 155 | ]), 156 | importExtension: ".js", 157 | convertNumberPrimitiveTypes: true, 158 | }, 159 | sourceReplace: new Map([ 160 | ]), 161 | debug: { 162 | pathForPosition: { 163 | filePattern: "XXX", 164 | position: { 165 | row: 49, 166 | column: 5, 167 | }, 168 | }, 169 | }, 170 | 171 | }; 172 | 173 | const converter = new JavaToTypescriptConverter(antlrToolOptions); 174 | await converter.startConversion(); 175 | }; 176 | 177 | await convertStringTemplate4(); 178 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "sourceMap": true, 7 | "esModuleInterop": true, 8 | "noEmit": false, 9 | "declaration": true, 10 | "emitDeclarationOnly": true, 11 | "outDir": "dist", 12 | "lib": [ 13 | "ESNext", 14 | ], 15 | "noImplicitAny": true, 16 | "strictNullChecks": true, 17 | "preserveConstEnums": true, 18 | "noImplicitOverride": true, 19 | "noImplicitReturns": true, 20 | "noImplicitThis": true, 21 | "noFallthroughCasesInSwitch": false, 22 | "forceConsistentCasingInFileNames": true, 23 | "resolveJsonModule": true, 24 | }, 25 | "include": [ 26 | "src/index.ts", 27 | "src/**/*.ts", 28 | "parser/generated/**/*.ts", 29 | "data/**/*.json", 30 | "tools/*.ts", 31 | "cli/java2ts.ts" 32 | ], 33 | "exclude": [ 34 | "node_modules", 35 | "dist", 36 | "tests" 37 | ], 38 | "compileOnSave": true, 39 | "ts-node": { 40 | "esm": true 41 | }, 42 | "hooks": [ 43 | "file-permissions" 44 | ], 45 | "filePermissions": { 46 | "output/src/convert.js": "0744" 47 | } 48 | } 49 | --------------------------------------------------------------------------------