diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers/Test.js.stg b/runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers/Test.js.stg index 928a1e4a12..053a357d8d 100644 --- a/runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers/Test.js.stg +++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers/Test.js.stg @@ -1,4 +1,4 @@ -import antlr4 from 'file:///src/antlr4/index.js' +import antlr4 from 'file:///src/antlr4/index.node.js' import from './.js'; import from './.js'; @@ -23,7 +23,7 @@ class TreeShapeListener extends antlr4.tree.ParseTreeListener { function main(argv) { - var input = new antlr4.FileStream(argv[2], true); + var input = new antlr4.FileStream(argv[2], "utf-8", true); var lexer = new (input); var stream = new antlr4.CommonTokenStream(lexer); diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers/Test.ts.stg b/runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers/Test.ts.stg index 11b78d856a..09d97c7f1e 100644 --- a/runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers/Test.ts.stg +++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers/Test.ts.stg @@ -33,7 +33,7 @@ class TreeShapeListener extends ParseTreeListener { function main(argv: string[]): void { - const input = new FileStream(argv[2], true); + const input = new FileStream(argv[2], "utf-8", true); const lexer = new (input); const stream = new CommonTokenStream(lexer); diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/javascript/NodeRunner.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/javascript/NodeRunner.java index a1d013cd01..4b0ceff17f 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/javascript/NodeRunner.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/javascript/NodeRunner.java @@ -36,7 +36,7 @@ public String getLanguage() { private final static String normalizedRuntimePath = getRuntimePath("JavaScript").replace('\\', '/'); private final static String newImportAntlrString = - "import antlr4 from 'file://" + normalizedRuntimePath + "/src/antlr4/index.js'"; + "import antlr4 from 'file://" + normalizedRuntimePath + "/src/antlr4/index.node.js'"; @Override protected CompiledState compile(RunOptions runOptions, GeneratedState generatedState) { diff --git a/runtime/JavaScript/package.json b/runtime/JavaScript/package.json index a97492c142..0174b5404c 100644 --- a/runtime/JavaScript/package.json +++ b/runtime/JavaScript/package.json @@ -1,9 +1,10 @@ { "name": "antlr4", - "version": "4.12.0-beta.5", + "version": "4.12.0-beta.10", "type": "module", "description": "JavaScript runtime for ANTLR4", - "main": "dist/antlr4.js", + "browser": "dist/antlr4.web.js", + "main": "dist/antlr4.node.js", "types": "src/antlr4/index.d.ts", "repository": "antlr/antlr4.git", "keywords": [ @@ -43,8 +44,5 @@ }, "engines": { "node": ">=16" - }, - "browser": { - "fs": false } } diff --git a/runtime/JavaScript/src/antlr4/CharStreams.js b/runtime/JavaScript/src/antlr4/CharStreams.js index befafb353e..920e28cc61 100644 --- a/runtime/JavaScript/src/antlr4/CharStreams.js +++ b/runtime/JavaScript/src/antlr4/CharStreams.js @@ -3,8 +3,8 @@ * can be found in the LICENSE.txt file in the project root. */ -import InputStream from './InputStream.js'; -import fs from "fs"; +import CharStream from "./CharStream.js"; +import FileStream from "./FileStream.js"; /** * Utility functions to create InputStreams from various sources. @@ -16,7 +16,7 @@ import fs from "fs"; export default { // Creates an InputStream from a string. fromString: function(str) { - return new InputStream(str, true); + return new CharStream(str, true); }, /** @@ -30,7 +30,7 @@ export default { fromBlob: function(blob, encoding, onLoad, onError) { const reader = new window.FileReader(); reader.onload = function(e) { - const is = new InputStream(e.target.result, true); + const is = new CharStream(e.target.result, true); onLoad(is); }; reader.onerror = onError; @@ -43,7 +43,7 @@ export default { * encoding is null). */ fromBuffer: function(buffer, encoding) { - return new InputStream(buffer.toString(encoding), true); + return new CharStream(buffer.toString(encoding), true); }, /** Asynchronously creates an InputStream from a file on disk given @@ -53,13 +53,7 @@ export default { * Invokes callback(error, result) on completion. */ fromPath: function(path, encoding, callback) { - fs.readFile(path, encoding, function(err, data) { - let is = null; - if (data !== null) { - is = new InputStream(data, true); - } - callback(err, is); - }); + FileStream.fromPath(path, encoding, callback); }, /** @@ -68,7 +62,6 @@ export default { * 'utf8' if encoding is null). */ fromPathSync: function(path, encoding) { - const data = fs.readFileSync(path, encoding); - return new InputStream(data, true); + return new FileStream(path, encoding); } }; diff --git a/runtime/JavaScript/src/antlr4/FileStream.d.ts b/runtime/JavaScript/src/antlr4/FileStream.d.ts index ff9e537ea8..204b09dcbf 100644 --- a/runtime/JavaScript/src/antlr4/FileStream.d.ts +++ b/runtime/JavaScript/src/antlr4/FileStream.d.ts @@ -4,7 +4,6 @@ export declare class FileStream extends CharStream { fileName: string; - constructor(fileName: string); - constructor(fileName: string, decodeToUnicodeCodePoints: boolean); + constructor(fileName: string, encoding?: string, decodeToUnicodeCodePoints?: boolean); } diff --git a/runtime/JavaScript/src/antlr4/FileStream.js b/runtime/JavaScript/src/antlr4/FileStream.js index 55c20e717f..fce1d33d8c 100644 --- a/runtime/JavaScript/src/antlr4/FileStream.js +++ b/runtime/JavaScript/src/antlr4/FileStream.js @@ -4,22 +4,36 @@ */ import InputStream from './InputStream.js'; +import CharStream from './CharStream.js'; const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null; -// use eval to fool webpack and mocha -const fs = isNode ? await eval("import('fs')") : null; +import fs from 'fs'; /** * This is an InputStream that is loaded from a file all at once * when you construct the object. */ export default class FileStream extends InputStream { - constructor(fileName, decodeToUnicodeCodePoints) { + + static fromPath(path, encoding, callback) { + if(!isNode) + throw new Error("FileStream is only available when running in Node!"); + fs.readFile(path, encoding, function(err, data) { + let is = null; + if (data !== null) { + is = new CharStream(data, true); + } + callback(err, is); + }); + + } + + constructor(fileName, encoding, decodeToUnicodeCodePoints) { if(!isNode) throw new Error("FileStream is only available when running in Node!"); - const data = fs.readFileSync(fileName, "utf8"); + const data = fs.readFileSync(fileName, encoding || "utf-8" ); super(data, decodeToUnicodeCodePoints); this.fileName = fileName; } diff --git a/runtime/JavaScript/src/antlr4/Lexer.d.ts b/runtime/JavaScript/src/antlr4/Lexer.d.ts index d3f08e52d8..8ddb293d07 100644 --- a/runtime/JavaScript/src/antlr4/Lexer.d.ts +++ b/runtime/JavaScript/src/antlr4/Lexer.d.ts @@ -18,6 +18,7 @@ export declare class Lexer extends Recognizer { _type: number; constructor(input: CharStream); - nextToken() : Token; - emit() : Token; + nextToken(): Token; + emit(): Token; + reset(): void; } diff --git a/runtime/JavaScript/src/antlr4/atn/ParserATNSimulator.d.ts b/runtime/JavaScript/src/antlr4/atn/ParserATNSimulator.d.ts index d6e739bbb2..78a1feb847 100644 --- a/runtime/JavaScript/src/antlr4/atn/ParserATNSimulator.d.ts +++ b/runtime/JavaScript/src/antlr4/atn/ParserATNSimulator.d.ts @@ -14,6 +14,7 @@ export declare class ParserATNSimulator extends ATNSimulator { decisionToDFA: DFA[]; atn: ATN; debug?: boolean; + trace_atn_sim?: boolean; constructor(recog: Recognizer, atn: ATN, decisionToDFA: DFA[], sharedContextCache: PredictionContextCache); adaptivePredict(input: TokenStream, decision: number, outerContext: ParserRuleContext) : number; diff --git a/runtime/JavaScript/src/antlr4/index.d.ts b/runtime/JavaScript/src/antlr4/index.d.ts index 09d16d99a6..1f0ee6ec9d 100644 --- a/runtime/JavaScript/src/antlr4/index.d.ts +++ b/runtime/JavaScript/src/antlr4/index.d.ts @@ -5,6 +5,7 @@ export * from "./CharStreams"; export * from "./TokenStream"; export * from "./BufferedTokenStream"; export * from "./CommonTokenStream"; +export * from "./Recognizer"; export * from "./Lexer"; export * from "./Parser"; export * from './Token'; diff --git a/runtime/JavaScript/src/antlr4/index.js b/runtime/JavaScript/src/antlr4/index.node.js similarity index 100% rename from runtime/JavaScript/src/antlr4/index.js rename to runtime/JavaScript/src/antlr4/index.node.js diff --git a/runtime/JavaScript/src/antlr4/index.web.js b/runtime/JavaScript/src/antlr4/index.web.js new file mode 100644 index 0000000000..96a30e9d4d --- /dev/null +++ b/runtime/JavaScript/src/antlr4/index.web.js @@ -0,0 +1,64 @@ +/* Copyright (c) 2012-2022 The ANTLR Project. All rights reserved. + * Use of this file is governed by the BSD 3-clause license that + * can be found in the LICENSE.txt file in the project root. + */ +import { default as atn } from './atn/index.js'; +import { default as dfa } from './dfa/index.js'; +import { default as context } from './context/index.js'; +import { default as misc } from './misc/index.js'; +import { default as tree } from './tree/index.js'; +import { default as error } from './error/index.js'; +import { default as CharStreams } from './CharStreams.js'; +import { default as Utils } from './utils/index.js'; + +import Token from './Token.js'; +import CommonToken from './CommonToken.js'; +import InputStream from './InputStream.js'; +import CharStream from './InputStream.js'; +import CommonTokenStream from './CommonTokenStream.js'; +import Lexer from './Lexer.js'; +import Parser from './Parser.js'; + +import RuleContext from './context/RuleContext.js'; +import ParserRuleContext from './context/ParserRuleContext.js'; +import ATN from './atn/ATN.js'; +import PredictionMode from './atn/PredictionMode.js'; +import LL1Analyzer from './atn/LL1Analyzer.js'; +import ATNDeserializer from './atn/ATNDeserializer.js'; +import LexerATNSimulator from './atn/LexerATNSimulator.js'; +import ParserATNSimulator from './atn/ParserATNSimulator.js'; +import PredictionContextCache from './atn/PredictionContextCache.js'; +import DFA from "./dfa/DFA.js"; +import RecognitionException from "./error/RecognitionException.js"; +import FailedPredicateException from "./error/FailedPredicateException.js"; +import NoViableAltException from "./error/NoViableAltException.js"; +import BailErrorStrategy from "./error/BailErrorStrategy.js"; +import Interval from './misc/Interval.js'; +import IntervalSet from './misc/IntervalSet.js'; +import ParseTreeListener from "./tree/ParseTreeListener.js"; +import ParseTreeVisitor from "./tree/ParseTreeVisitor.js"; +import ParseTreeWalker from "./tree/ParseTreeWalker.js"; +import ErrorListener from "./error/ErrorListener.js" +import DiagnosticErrorListener from "./error/DiagnosticErrorListener.js" +import RuleNode from "./tree/RuleNode.js" +import TerminalNode from "./tree/TerminalNode.js" +import arrayToString from "./utils/arrayToString.js" + +export default { + atn, dfa, context, misc, tree, error, Token, CommonToken, CharStreams, CharStream, InputStream, CommonTokenStream, Lexer, Parser, + ParserRuleContext, Interval, IntervalSet, LL1Analyzer, Utils +} + +export { + Token, CommonToken, CharStreams, CharStream, InputStream, CommonTokenStream, Lexer, Parser, + RuleNode, TerminalNode, ParseTreeWalker, RuleContext, ParserRuleContext, Interval, IntervalSet, + PredictionMode, LL1Analyzer, ParseTreeListener, ParseTreeVisitor, ATN, ATNDeserializer, PredictionContextCache, LexerATNSimulator, ParserATNSimulator, DFA, + RecognitionException, NoViableAltException, FailedPredicateException, ErrorListener, DiagnosticErrorListener, BailErrorStrategy, + arrayToString +} + +/* eslint no-unused-vars: [ "off"] */ +// need to import unused to force loading +import StringHashCode from './utils/stringHashCode.js'; +import CodePointAt from './polyfills/codepointat.js'; +import FromCodePoint from './polyfills/fromcodepoint.js'; diff --git a/runtime/JavaScript/webpack.config.cjs b/runtime/JavaScript/webpack.config.cjs deleted file mode 100644 index a2b64a2763..0000000000 --- a/runtime/JavaScript/webpack.config.cjs +++ /dev/null @@ -1,39 +0,0 @@ -const path = require('path'); -const ESLintPlugin = require('eslint-webpack-plugin'); - -module.exports = { - mode: "production", - entry: './src/antlr4/index.js', - output: { - filename: 'antlr4.js', - path: path.resolve(__dirname, 'dist'), - // the name of the exported antlr4 - library: { - type: "module" - } - }, - resolve: { - extensions: [ '.js'], - fallback: { - fs: false - } - }, - target: "web", - module: { - rules: [{ - test: /\.js$/, - exclude: /node_modules/, - use: [ 'babel-loader' ] - }] - }, - performance: { - maxAssetSize: 512000, - maxEntrypointSize: 512000 - }, - plugins: [ new ESLintPlugin() ], - experiments: { - outputModule: true, - topLevelAwait: true - }, - devtool: "source-map" -}; diff --git a/runtime/JavaScript/webpack.config.js b/runtime/JavaScript/webpack.config.js new file mode 100644 index 0000000000..b140698641 --- /dev/null +++ b/runtime/JavaScript/webpack.config.js @@ -0,0 +1,72 @@ +import path from 'path'; +import ESLintPlugin from 'eslint-webpack-plugin'; +import {fileURLToPath} from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const nodeConfig = { + mode: "production", + entry: './src/antlr4/index.node.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'antlr4.node.js', + chunkFormat: "module", + library: { + type: "module" + } + }, + resolve: { + extensions: [ '.js'] + }, + target: "node", + module: { + rules: [{ + test: /\.js$/, + exclude: /node_modules/, + use: [ 'babel-loader' ] + }] + }, + plugins: [ new ESLintPlugin() ], + experiments: { + outputModule: true + }, + devtool: "source-map" +}; + +const webConfig = { + mode: "production", + entry: './src/antlr4/index.web.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'antlr4.web.js', + library: { + type: "module" + } + }, + resolve: { + extensions: [ '.js'], + fallback: { + fs: false + } + }, + target: "web", + module: { + rules: [{ + test: /\.js$/, + exclude: [ /node_modules/, path.resolve(__dirname, "src/FileStream.js") ], + use: [ 'babel-loader' ] + }] + }, + performance: { + maxAssetSize: 512000, + maxEntrypointSize: 512000 + }, + plugins: [ new ESLintPlugin() ], + experiments: { + outputModule: true + }, + devtool: "source-map" +}; + +export default [ nodeConfig, webConfig ];