java-parser
Advanced tools
Comparing version 2.2.0 to 2.3.0
{ | ||
"name": "java-parser", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"description": "Java Parser in JavaScript", | ||
"main": "src/index.js", | ||
"type": "module", | ||
"exports": "./src/index.js", | ||
"repository": "https://github.com/jhipster/prettier-java/tree/main/packages/java-parser", | ||
@@ -10,3 +11,4 @@ "license": "Apache-2.0", | ||
"dependencies": { | ||
"chevrotain": "6.5.0", | ||
"chevrotain": "11.0.3", | ||
"chevrotain-allstar": "0.3.1", | ||
"lodash": "4.17.21" | ||
@@ -19,3 +21,3 @@ }, | ||
}, | ||
"gitHead": "00a8585d20c56d933ce4c89dcb532d9e98d1a4cf" | ||
"gitHead": "30e1cad12e8936df43c25eeb9dad5aef20d9af6c" | ||
} |
@@ -1,5 +0,3 @@ | ||
"use strict"; | ||
import findLast from "lodash/findLast.js"; | ||
const findLast = require("lodash/findLast"); | ||
/** | ||
@@ -168,3 +166,3 @@ * Search where is the position of the comment in the token array by | ||
*/ | ||
function attachComments( | ||
export function attachComments( | ||
tokens, | ||
@@ -260,3 +258,3 @@ comments, | ||
*/ | ||
function matchFormatterOffOnPairs(comments) { | ||
export function matchFormatterOffOnPairs(comments) { | ||
const onOffComments = comments.filter(comment => | ||
@@ -300,3 +298,3 @@ isFormatterOffOnComment(comment) | ||
*/ | ||
function shouldNotFormat(node, commentPairs) { | ||
export function shouldNotFormat(node, commentPairs) { | ||
const matchingPair = findLast( | ||
@@ -314,7 +312,1 @@ commentPairs, | ||
} | ||
module.exports = { | ||
matchFormatterOffOnPairs, | ||
shouldNotFormat, | ||
attachComments | ||
}; |
@@ -1,13 +0,12 @@ | ||
"use strict"; | ||
const JavaLexer = require("./lexer"); | ||
const JavaParser = require("./parser"); | ||
const { attachComments, matchFormatterOffOnPairs } = require("./comments"); | ||
import JavaLexer from "./lexer.js"; | ||
import JavaParser from "./parser.js"; | ||
import { attachComments, matchFormatterOffOnPairs } from "./comments.js"; | ||
const parser = new JavaParser(); | ||
const BaseJavaCstVisitor = parser.getBaseCstVisitorConstructor(); | ||
const BaseJavaCstVisitorWithDefaults = | ||
export const BaseJavaCstVisitor = parser.getBaseCstVisitorConstructor(); | ||
export const BaseJavaCstVisitorWithDefaults = | ||
parser.getBaseCstVisitorConstructorWithDefaults(); | ||
function lexAndParse(inputText, entryPoint = "compilationUnit") { | ||
export function lexAndParse(inputText, entryPoint = "compilationUnit") { | ||
// Lex | ||
@@ -64,7 +63,7 @@ const lexResult = JavaLexer.tokenize(inputText); | ||
function parse(inputText, entryPoint = "compilationUnit") { | ||
export function parse(inputText, entryPoint = "compilationUnit") { | ||
return lexAndParse(inputText, entryPoint).cst; | ||
} | ||
module.exports = { | ||
export default { | ||
lexAndParse, | ||
@@ -71,0 +70,0 @@ parse, |
@@ -1,12 +0,8 @@ | ||
"use strict"; | ||
const chevrotain = require("chevrotain"); | ||
const { allTokens } = require("./tokens"); | ||
const { getSkipValidations } = require("./utils"); | ||
import { Lexer } from "chevrotain"; | ||
import { allTokens } from "./tokens.js"; | ||
import { getSkipValidations } from "./utils.js"; | ||
const Lexer = chevrotain.Lexer; | ||
const JavaLexer = new Lexer(allTokens, { | ||
export default new Lexer(allTokens, { | ||
ensureOptimizations: true, | ||
skipValidations: getSkipValidations() | ||
}); | ||
module.exports = JavaLexer; |
@@ -1,15 +0,15 @@ | ||
"use strict"; | ||
const { Parser, isRecognitionException } = require("chevrotain"); | ||
const { allTokens, tokens: t } = require("./tokens"); | ||
const lexicalStructure = require("./productions/lexical-structure"); | ||
const typesValuesVariables = require("./productions/types-values-and-variables"); | ||
const names = require("./productions/names"); | ||
const packagesModules = require("./productions/packages-and-modules"); | ||
const classes = require("./productions/classes"); | ||
const interfaces = require("./productions/interfaces"); | ||
const arrays = require("./productions/arrays"); | ||
const blocksStatements = require("./productions/blocks-and-statements"); | ||
const expressions = require("./productions/expressions"); | ||
const { getSkipValidations } = require("./utils"); | ||
const { shouldNotFormat } = require("./comments"); | ||
import { CstParser, isRecognitionException } from "chevrotain"; | ||
import { LLStarLookaheadStrategy } from "chevrotain-allstar"; | ||
import { allTokens, tokens as t } from "./tokens.js"; | ||
import * as lexicalStructure from "./productions/lexical-structure.js"; | ||
import * as typesValuesVariables from "./productions/types-values-and-variables.js"; | ||
import * as names from "./productions/names.js"; | ||
import * as packagesModules from "./productions/packages-and-modules.js"; | ||
import * as classes from "./productions/classes.js"; | ||
import * as interfaces from "./productions/interfaces.js"; | ||
import * as arrays from "./productions/arrays.js"; | ||
import * as blocksStatements from "./productions/blocks-and-statements.js"; | ||
import * as expressions from "./productions/expressions.js"; | ||
import { getSkipValidations } from "./utils.js"; | ||
import { shouldNotFormat } from "./comments.js"; | ||
@@ -39,6 +39,8 @@ /** | ||
*/ | ||
class JavaParser extends Parser { | ||
export default class JavaParser extends CstParser { | ||
constructor() { | ||
super(allTokens, { | ||
maxLookahead: 1, | ||
lookaheadStrategy: new LLStarLookaheadStrategy({ | ||
logging: getSkipValidations() ? () => {} : undefined | ||
}), | ||
nodeLocationTracking: "full", | ||
@@ -81,12 +83,12 @@ // traceInitPerf: 2, | ||
cstPostNonTerminal(ruleCstResult, ruleName) { | ||
if (this.isBackTracking()) { | ||
return; | ||
} | ||
super.cstPostNonTerminal(ruleCstResult, ruleName); | ||
if (this.isBackTracking() === false) { | ||
this.mostEnclosiveCstNodeByStartOffset[ | ||
ruleCstResult.location.startOffset | ||
] = ruleCstResult; | ||
this.mostEnclosiveCstNodeByEndOffset[ruleCstResult.location.endOffset] = | ||
ruleCstResult; | ||
this.mostEnclosiveCstNodeByStartOffset[ruleCstResult.location.startOffset] = | ||
ruleCstResult; | ||
this.mostEnclosiveCstNodeByEndOffset[ruleCstResult.location.endOffset] = | ||
ruleCstResult; | ||
shouldNotFormat(ruleCstResult, this.onOffCommentPairs); | ||
} | ||
shouldNotFormat(ruleCstResult, this.onOffCommentPairs); | ||
} | ||
@@ -100,5 +102,16 @@ | ||
try { | ||
// hack to enable outputting none CST values from grammar rules. | ||
this.outputCst = false; | ||
return production.call(this); | ||
// hack to enable outputting non-CST values from grammar rules. | ||
const { ruleName, originalGrammarAction } = production; | ||
try { | ||
this.ruleInvocationStateUpdate( | ||
this.fullRuleNameToShort[ruleName], | ||
ruleName, | ||
this.subruleIdx | ||
); | ||
return originalGrammarAction.call(this); | ||
} catch (e) { | ||
return this.invokeRuleCatch(e, true, () => undefined); | ||
} finally { | ||
this.ruleFinallyStateUpdate(); | ||
} | ||
} catch (e) { | ||
@@ -110,3 +123,2 @@ if (isRecognitionException(e)) { | ||
} finally { | ||
this.outputCst = true; | ||
this.reloadRecogState(orgState); | ||
@@ -122,3 +134,1 @@ this.isBackTrackingStack.pop(); | ||
} | ||
module.exports = JavaParser; |
@@ -1,6 +0,4 @@ | ||
"use strict"; | ||
import { tokenMatcher } from "chevrotain"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
function defineRules($, t) { | ||
export function defineRules($, t) { | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-10.html#jls-ArrayInitializer | ||
@@ -31,5 +29,1 @@ $.RULE("arrayInitializer", () => { | ||
} | ||
module.exports = { | ||
defineRules | ||
}; |
@@ -1,9 +0,7 @@ | ||
"use strict"; | ||
import { tokenMatcher } from "chevrotain"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
// Spec Deviation: The "*NoShortIf" variations were removed as the ambiguity of | ||
// the dangling else is resolved by attaching an "else" block | ||
// to the nearest "if" | ||
function defineRules($, t) { | ||
export function defineRules($, t) { | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-Block | ||
@@ -28,21 +26,7 @@ $.RULE("block", () => { | ||
$.RULE("blockStatement", () => { | ||
const isLocalVariableDeclaration = this.BACKTRACK_LOOKAHEAD( | ||
$.isLocalVariableDeclaration | ||
); | ||
const isClassDeclaration = this.BACKTRACK_LOOKAHEAD($.isClassDeclaration); | ||
$.OR({ | ||
DEF: [ | ||
{ | ||
GATE: () => isLocalVariableDeclaration, | ||
ALT: () => $.SUBRULE($.localVariableDeclarationStatement) | ||
}, | ||
{ | ||
GATE: () => isClassDeclaration, | ||
ALT: () => $.SUBRULE($.classDeclaration) | ||
}, | ||
{ | ||
ALT: () => $.SUBRULE($.interfaceDeclaration) | ||
}, | ||
{ ALT: () => $.SUBRULE($.localVariableDeclarationStatement) }, | ||
{ ALT: () => $.SUBRULE($.classDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.interfaceDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.statement) } | ||
@@ -82,15 +66,10 @@ ], | ||
$.RULE("statement", () => { | ||
$.OR({ | ||
DEF: [ | ||
{ | ||
ALT: () => $.SUBRULE($.statementWithoutTrailingSubstatement) | ||
}, | ||
{ ALT: () => $.SUBRULE($.labeledStatement) }, | ||
// Spec deviation: combined "IfThenStatement" and "IfThenElseStatement" | ||
{ ALT: () => $.SUBRULE($.ifStatement) }, | ||
{ ALT: () => $.SUBRULE($.whileStatement) }, | ||
{ ALT: () => $.SUBRULE($.forStatement) } | ||
], | ||
MAX_LOOKAHEAD: 2 | ||
}); | ||
$.OR([ | ||
{ ALT: () => $.SUBRULE($.statementWithoutTrailingSubstatement) }, | ||
{ ALT: () => $.SUBRULE($.labeledStatement) }, | ||
// Spec deviation: combined "IfThenStatement" and "IfThenElseStatement" | ||
{ ALT: () => $.SUBRULE($.ifStatement) }, | ||
{ ALT: () => $.SUBRULE($.whileStatement) }, | ||
{ ALT: () => $.SUBRULE($.forStatement) } | ||
]); | ||
}); | ||
@@ -103,6 +82,3 @@ | ||
{ ALT: () => $.SUBRULE($.block) }, | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.yieldStatement), | ||
ALT: () => $.SUBRULE($.yieldStatement) | ||
}, | ||
{ ALT: () => $.SUBRULE($.yieldStatement) }, | ||
{ ALT: () => $.SUBRULE($.emptyStatement) }, | ||
@@ -194,9 +170,4 @@ { | ||
$.OR([ | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.isClassicSwitchLabel), | ||
ALT: () => $.MANY(() => $.SUBRULE($.switchBlockStatementGroup)) | ||
}, | ||
{ | ||
ALT: () => $.MANY2(() => $.SUBRULE($.switchRule)) | ||
} | ||
{ ALT: () => $.MANY(() => $.SUBRULE($.switchBlockStatementGroup)) }, | ||
{ ALT: () => $.MANY2(() => $.SUBRULE($.switchRule)) } | ||
]); | ||
@@ -231,3 +202,2 @@ $.CONSUME(t.RCurly); | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.pattern), | ||
ALT: () => { | ||
@@ -304,6 +274,3 @@ $.SUBRULE($.pattern); | ||
$.OR([ | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.isBasicForStatement), | ||
ALT: () => $.SUBRULE($.basicForStatement) | ||
}, | ||
{ ALT: () => $.SUBRULE($.basicForStatement) }, | ||
{ ALT: () => $.SUBRULE($.enhancedForStatement) } | ||
@@ -335,6 +302,3 @@ ]); | ||
$.OR([ | ||
{ | ||
GATE: () => $.BACKTRACK_LOOKAHEAD($.isLocalVariableDeclaration), | ||
ALT: () => $.SUBRULE($.localVariableDeclaration) | ||
}, | ||
{ ALT: () => $.SUBRULE($.localVariableDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.statementExpressionList) } | ||
@@ -418,25 +382,22 @@ ]); | ||
$.RULE("tryStatement", () => { | ||
$.OR({ | ||
DEF: [ | ||
{ | ||
ALT: () => { | ||
$.CONSUME(t.Try); | ||
$.SUBRULE($.block); | ||
$.OR2([ | ||
{ | ||
ALT: () => { | ||
$.SUBRULE($.catches); | ||
$.OPTION(() => { | ||
$.SUBRULE($.finally); | ||
}); | ||
} | ||
}, | ||
{ ALT: () => $.SUBRULE2($.finally) } | ||
]); | ||
} | ||
}, | ||
{ ALT: () => $.SUBRULE($.tryWithResourcesStatement) } | ||
], | ||
MAX_LOOKAHEAD: 2 | ||
}); | ||
$.OR([ | ||
{ | ||
ALT: () => { | ||
$.CONSUME(t.Try); | ||
$.SUBRULE($.block); | ||
$.OR2([ | ||
{ | ||
ALT: () => { | ||
$.SUBRULE($.catches); | ||
$.OPTION(() => { | ||
$.SUBRULE($.finally); | ||
}); | ||
} | ||
}, | ||
{ ALT: () => $.SUBRULE2($.finally) } | ||
]); | ||
} | ||
}, | ||
{ ALT: () => $.SUBRULE($.tryWithResourcesStatement) } | ||
]); | ||
}); | ||
@@ -523,6 +484,3 @@ | ||
$.OR([ | ||
{ | ||
GATE: () => $.BACKTRACK_LOOKAHEAD($.isLocalVariableDeclaration), | ||
ALT: () => $.SUBRULE($.localVariableDeclaration) | ||
}, | ||
{ ALT: () => $.SUBRULE($.localVariableDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.variableAccess) } | ||
@@ -546,47 +504,2 @@ ]); | ||
}); | ||
// ------------------------------------ | ||
// Special optimized backtracking rules. | ||
// ------------------------------------ | ||
$.RULE("isBasicForStatement", () => { | ||
$.CONSUME(t.For); | ||
$.CONSUME(t.LBrace); | ||
$.OPTION(() => { | ||
$.SUBRULE($.forInit); | ||
}); | ||
$.CONSUME(t.Semicolon); | ||
// consuming the first semiColon distinguishes between | ||
// "basic" and "enhanced" for statements | ||
return true; | ||
}); | ||
$.RULE("isLocalVariableDeclaration", () => { | ||
$.MANY(() => { | ||
$.SUBRULE($.variableModifier); | ||
}); | ||
$.SUBRULE($.localVariableType); | ||
$.SUBRULE($.variableDeclaratorId); | ||
const nextTokenType = this.LA(1).tokenType; | ||
switch (nextTokenType) { | ||
// Int x; | ||
case t.Semicolon: | ||
// Int x, y, z; | ||
case t.Comma: | ||
// Int x = 5; | ||
case t.Equals: | ||
return true; | ||
default: | ||
return false; | ||
} | ||
}); | ||
$.RULE("isClassicSwitchLabel", () => { | ||
$.SUBRULE($.switchLabel); | ||
$.CONSUME(t.Colon); | ||
}); | ||
} | ||
module.exports = { | ||
defineRules | ||
}; |
@@ -1,7 +0,4 @@ | ||
"use strict"; | ||
import { tokenMatcher } from "chevrotain"; | ||
const { isRecognitionException, tokenMatcher } = require("chevrotain"); | ||
const { classBodyTypes } = require("./utils/class-body-types"); | ||
function defineRules($, t) { | ||
export function defineRules($, t) { | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassDeclaration | ||
@@ -116,24 +113,7 @@ $.RULE("classDeclaration", () => { | ||
$.RULE("classBodyDeclaration", () => { | ||
const nextRuleType = $.BACKTRACK_LOOKAHEAD( | ||
$.identifyClassBodyDeclarationType | ||
); | ||
$.OR([ | ||
{ | ||
GATE: () => | ||
nextRuleType >= classBodyTypes.fieldDeclaration && | ||
nextRuleType <= classBodyTypes.semiColon, | ||
ALT: () => | ||
$.SUBRULE($.classMemberDeclaration, { | ||
ARGS: [nextRuleType] | ||
}) | ||
}, | ||
// no gate needed for the initializers because these are LL(1) rules. | ||
{ ALT: () => $.SUBRULE($.classMemberDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.instanceInitializer) }, | ||
{ ALT: () => $.SUBRULE($.staticInitializer) }, | ||
{ | ||
GATE: () => | ||
tokenMatcher(nextRuleType, classBodyTypes.constructorDeclaration), | ||
ALT: () => $.SUBRULE($.constructorDeclaration) | ||
} | ||
{ ALT: () => $.SUBRULE($.constructorDeclaration) } | ||
]); | ||
@@ -143,24 +123,9 @@ }); | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassMemberDeclaration | ||
$.RULE("classMemberDeclaration", nextRuleType => { | ||
$.RULE("classMemberDeclaration", () => { | ||
$.OR([ | ||
{ | ||
GATE: () => nextRuleType === classBodyTypes.fieldDeclaration, | ||
ALT: () => $.SUBRULE($.fieldDeclaration) | ||
}, | ||
{ | ||
GATE: () => nextRuleType === classBodyTypes.methodDeclaration, | ||
ALT: () => $.SUBRULE($.methodDeclaration) | ||
}, | ||
{ | ||
GATE: () => nextRuleType === classBodyTypes.classDeclaration, | ||
ALT: () => $.SUBRULE($.classDeclaration) | ||
}, | ||
{ | ||
GATE: () => nextRuleType === classBodyTypes.interfaceDeclaration, | ||
ALT: () => $.SUBRULE($.interfaceDeclaration) | ||
}, | ||
{ | ||
// No GATE is needed as this is LL(1) | ||
ALT: () => $.CONSUME(t.Semicolon) | ||
} | ||
{ ALT: () => $.SUBRULE($.fieldDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.methodDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.classDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.interfaceDeclaration) }, | ||
{ ALT: () => $.CONSUME(t.Semicolon) } | ||
]); | ||
@@ -360,9 +325,18 @@ }); | ||
// https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-MethodDeclarator | ||
// https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-MethodDeclarator | ||
$.RULE("methodDeclarator", () => { | ||
$.CONSUME(t.Identifier); | ||
$.CONSUME(t.LBrace); | ||
$.OPTION(() => { | ||
$.SUBRULE($.formalParameterList); | ||
}); | ||
$.OR([ | ||
{ | ||
ALT: () => { | ||
$.SUBRULE($.receiverParameter); | ||
$.OPTION(() => { | ||
$.CONSUME(t.Comma); | ||
$.SUBRULE($.formalParameterList); | ||
}); | ||
} | ||
}, | ||
{ ALT: () => $.OPTION1(() => $.SUBRULE1($.formalParameterList)) } | ||
]); | ||
$.CONSUME(t.RBrace); | ||
@@ -400,6 +374,3 @@ $.OPTION2(() => { | ||
// Spec Deviation: extracted to "variableParaRegularParameter" | ||
{ | ||
GATE: $.BACKTRACK($.variableParaRegularParameter), | ||
ALT: () => $.SUBRULE($.variableParaRegularParameter) | ||
}, | ||
{ ALT: () => $.SUBRULE($.variableParaRegularParameter) }, | ||
{ ALT: () => $.SUBRULE($.variableArityParameter) } | ||
@@ -509,14 +480,14 @@ ]); | ||
$.CONSUME(t.LBrace); | ||
$.OPTION2({ | ||
// a "formalParameterList" and a "receiverParameter" | ||
// cannot be distinguished using fixed lookahead. | ||
GATE: $.BACKTRACK($.receiverParameter), | ||
DEF: () => { | ||
$.SUBRULE($.receiverParameter); | ||
$.CONSUME(t.Comma); | ||
} | ||
}); | ||
$.OPTION3(() => { | ||
$.SUBRULE($.formalParameterList); | ||
}); | ||
$.OR([ | ||
{ | ||
ALT: () => { | ||
$.SUBRULE($.receiverParameter); | ||
$.OPTION1(() => { | ||
$.CONSUME(t.Comma); | ||
$.SUBRULE($.formalParameterList); | ||
}); | ||
} | ||
}, | ||
{ ALT: () => $.OPTION2(() => $.SUBRULE1($.formalParameterList)) } | ||
]); | ||
$.CONSUME(t.RBrace); | ||
@@ -534,7 +505,4 @@ }); | ||
$.CONSUME(t.LCurly); | ||
$.OPTION({ | ||
GATE: $.BACKTRACK($.explicitConstructorInvocation), | ||
DEF: () => { | ||
$.SUBRULE($.explicitConstructorInvocation); | ||
} | ||
$.OPTION(() => { | ||
$.SUBRULE($.explicitConstructorInvocation); | ||
}); | ||
@@ -750,6 +718,3 @@ $.OPTION2(() => { | ||
$.OR([ | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.isCompactConstructorDeclaration), | ||
ALT: () => $.SUBRULE($.compactConstructorDeclaration) | ||
}, | ||
{ ALT: () => $.SUBRULE($.compactConstructorDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.classBodyDeclaration) } | ||
@@ -768,174 +733,2 @@ ]); | ||
$.RULE("isClassDeclaration", () => { | ||
let isEmptyTypeDeclaration = false; | ||
if ( | ||
$.OPTION(() => { | ||
$.CONSUME(t.Semicolon); | ||
}) | ||
) { | ||
// an empty "TypeDeclaration" | ||
isEmptyTypeDeclaration = true; | ||
} | ||
try { | ||
// The {classModifier} is a super grammar of the "interfaceModifier" | ||
// So we must parse all the "{classModifier}" before we can distinguish | ||
// between the alternatives. | ||
$.MANY({ | ||
GATE: () => | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
$.SUBRULE($.classModifier); | ||
} | ||
}); | ||
} catch (e) { | ||
if (isRecognitionException(e)) { | ||
// TODO: add original syntax error? | ||
throw "Cannot Identify if the <TypeDeclaration> is a <ClassDeclaration> or an <InterfaceDeclaration>"; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
if (isEmptyTypeDeclaration) { | ||
return false; | ||
} | ||
const nextTokenType = this.LA(1).tokenType; | ||
return ( | ||
tokenMatcher(nextTokenType, t.Class) || | ||
tokenMatcher(nextTokenType, t.Enum) || | ||
(tokenMatcher(nextTokenType, t.Record) && | ||
tokenMatcher(this.LA(2).tokenType, t.Identifier)) | ||
); | ||
}); | ||
$.RULE("identifyClassBodyDeclarationType", () => { | ||
try { | ||
let nextTokenType = this.LA(1).tokenType; | ||
let nextNextTokenType = this.LA(2).tokenType; | ||
switch (nextTokenType) { | ||
case t.Semicolon: | ||
return classBodyTypes.semiColon; | ||
case t.LCurly: | ||
return classBodyTypes.instanceInitializer; | ||
case t.Static: | ||
switch (nextNextTokenType) { | ||
case t.LCurly: | ||
return classBodyTypes.staticInitializer; | ||
} | ||
} | ||
// We have to look beyond the modifiers to distinguish between the declaration types. | ||
$.MANY({ | ||
GATE: () => | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
// This alternation includes all possible modifiers for all types of "ClassBodyDeclaration" | ||
// Certain combinations are syntactically invalid, this is **not** checked here, | ||
// Invalid combinations will cause a descriptive parsing error message to be | ||
// Created inside the relevant parsing rules **after** this lookahead | ||
// analysis. | ||
$.OR([ | ||
{ | ||
GATE: () => | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
ALT: () => $.SUBRULE($.annotation) | ||
}, | ||
{ ALT: () => $.CONSUME(t.Public) }, | ||
{ ALT: () => $.CONSUME(t.Protected) }, | ||
{ ALT: () => $.CONSUME(t.Private) }, | ||
{ ALT: () => $.CONSUME(t.Abstract) }, | ||
{ ALT: () => $.CONSUME(t.Static) }, | ||
{ ALT: () => $.CONSUME(t.Final) }, | ||
{ ALT: () => $.CONSUME(t.Transient) }, | ||
{ ALT: () => $.CONSUME(t.Volatile) }, | ||
{ ALT: () => $.CONSUME(t.Synchronized) }, | ||
{ ALT: () => $.CONSUME(t.Native) }, | ||
{ ALT: () => $.CONSUME(t.Sealed) }, | ||
{ ALT: () => $.CONSUME(t.NonSealed) }, | ||
{ ALT: () => $.CONSUME(t.Strictfp) } | ||
]); | ||
} | ||
}); | ||
nextTokenType = this.LA(1).tokenType; | ||
nextNextTokenType = this.LA(2).tokenType; | ||
if ( | ||
tokenMatcher(nextTokenType, t.Identifier) && | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
return classBodyTypes.constructorDeclaration; | ||
} | ||
if ( | ||
tokenMatcher(nextTokenType, t.Class) || | ||
tokenMatcher(nextTokenType, t.Enum) || | ||
tokenMatcher(nextTokenType, t.Record) | ||
) { | ||
return classBodyTypes.classDeclaration; | ||
} | ||
if ( | ||
tokenMatcher(nextTokenType, t.Interface) || | ||
tokenMatcher(nextTokenType, t.At) | ||
) { | ||
return classBodyTypes.interfaceDeclaration; | ||
} | ||
if (tokenMatcher(nextTokenType, t.Void)) { | ||
// method with result type "void" | ||
return classBodyTypes.methodDeclaration; | ||
} | ||
// Type Arguments common prefix | ||
if (tokenMatcher(nextTokenType, t.Less)) { | ||
this.SUBRULE($.typeParameters); | ||
const nextTokenType = this.LA(1).tokenType; | ||
const nextNextTokenType = this.LA(2).tokenType; | ||
// "<T> foo(" -> constructor | ||
if ( | ||
tokenMatcher(nextTokenType, t.Identifier) && | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
return classBodyTypes.constructorDeclaration; | ||
} | ||
// typeParameters can only appear in method or constructor | ||
// declarations, so if it is not a constructor it must be a method | ||
return classBodyTypes.methodDeclaration; | ||
} | ||
// Only field or method declarations may be valid at this point. | ||
// All other alternatives should have been attempted. | ||
// **both** start with "unannType" | ||
this.SUBRULE($.unannType); | ||
const nextToken = this.LA(1); | ||
nextNextTokenType = this.LA(2).tokenType; | ||
// "foo(..." --> look like method start | ||
if ( | ||
tokenMatcher(nextToken, t.Identifier) && | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
return classBodyTypes.methodDeclaration; | ||
} | ||
// a valid field | ||
// TODO: because we use token categories we should use tokenMatcher everywhere. | ||
if (tokenMatcher(nextToken, t.Identifier)) { | ||
return classBodyTypes.fieldDeclaration; | ||
} | ||
return classBodyTypes.unknown; | ||
} catch (e) { | ||
// TODO: add info from the original error | ||
throw Error("Cannot Identify the type of a <classBodyDeclaration>"); | ||
} | ||
}); | ||
$.RULE("isDims", () => { | ||
@@ -948,12 +741,2 @@ $.MANY($.annotation); | ||
}); | ||
$.RULE("isCompactConstructorDeclaration", () => { | ||
$.MANY($.constructorModifier); | ||
$.SUBRULE($.simpleTypeName); | ||
$.CONSUME(t.LCurly); | ||
}); | ||
} | ||
module.exports = { | ||
defineRules | ||
}; |
@@ -1,10 +0,6 @@ | ||
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
function defineRules($, t) { | ||
import { tokenMatcher } from "chevrotain"; | ||
export function defineRules($, t) { | ||
$.RULE("expression", () => { | ||
$.OR([ | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.isLambdaExpression), | ||
ALT: () => $.SUBRULE($.lambdaExpression) | ||
}, | ||
{ ALT: () => $.SUBRULE($.lambdaExpression) }, | ||
{ ALT: () => $.SUBRULE($.ternaryExpression) } | ||
@@ -72,9 +68,4 @@ ]); | ||
$.RULE("lambdaParameter", () => { | ||
// TODO: performance, investigate the performance boost that could | ||
// be gained by refactoring out the backtracking. | ||
$.OR([ | ||
{ | ||
GATE: $.BACKTRACK($.regularLambdaParameter), | ||
ALT: () => $.SUBRULE($.regularLambdaParameter) | ||
}, | ||
{ ALT: () => $.SUBRULE($.regularLambdaParameter) }, | ||
{ ALT: () => $.SUBRULE($.variableArityParameter) } | ||
@@ -129,9 +120,4 @@ ]); | ||
$.OR1([ | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.pattern), | ||
ALT: () => $.SUBRULE($.pattern) | ||
}, | ||
{ | ||
ALT: () => $.SUBRULE($.referenceType) | ||
} | ||
{ ALT: () => $.SUBRULE($.pattern) }, | ||
{ ALT: () => $.SUBRULE($.referenceType) } | ||
]); | ||
@@ -220,7 +206,2 @@ } | ||
$.RULE("primaryPrefix", () => { | ||
let isCastExpression = false; | ||
if (tokenMatcher($.LA(1).tokenType, t.LBrace)) { | ||
isCastExpression = this.BACKTRACK_LOOKAHEAD($.isCastExpression); | ||
} | ||
$.OR([ | ||
@@ -232,6 +213,3 @@ { ALT: () => $.SUBRULE($.literal) }, | ||
{ ALT: () => $.SUBRULE($.fqnOrRefType) }, | ||
{ | ||
GATE: () => isCastExpression, | ||
ALT: () => $.SUBRULE($.castExpression) | ||
}, | ||
{ ALT: () => $.SUBRULE($.castExpression) }, | ||
{ ALT: () => $.SUBRULE($.parenthesisExpression) }, | ||
@@ -244,31 +222,28 @@ { ALT: () => $.SUBRULE($.newExpression) }, | ||
$.RULE("primarySuffix", () => { | ||
$.OR({ | ||
DEF: [ | ||
{ | ||
ALT: () => { | ||
$.CONSUME(t.Dot); | ||
$.OR2([ | ||
{ ALT: () => $.CONSUME(t.This) }, | ||
{ | ||
ALT: () => | ||
$.SUBRULE($.unqualifiedClassInstanceCreationExpression) | ||
}, | ||
{ | ||
ALT: () => { | ||
$.OPTION(() => { | ||
$.SUBRULE($.typeArguments); | ||
}); | ||
$.CONSUME(t.Identifier); | ||
} | ||
$.OR([ | ||
{ | ||
ALT: () => { | ||
$.CONSUME(t.Dot); | ||
$.OR2([ | ||
{ ALT: () => $.CONSUME(t.This) }, | ||
{ | ||
ALT: () => $.SUBRULE($.unqualifiedClassInstanceCreationExpression) | ||
}, | ||
{ | ||
ALT: () => { | ||
$.OPTION(() => { | ||
$.SUBRULE($.typeArguments); | ||
}); | ||
$.CONSUME(t.Identifier); | ||
} | ||
]); | ||
} | ||
}, | ||
{ ALT: () => $.SUBRULE($.methodInvocationSuffix) }, | ||
{ ALT: () => $.SUBRULE($.classLiteralSuffix) }, | ||
{ ALT: () => $.SUBRULE($.arrayAccessSuffix) }, | ||
{ ALT: () => $.SUBRULE($.methodReferenceSuffix) } | ||
], | ||
MAX_LOOKAHEAD: 2 | ||
}); | ||
}, | ||
{ ALT: () => $.SUBRULE($.templateArgument) } | ||
]); | ||
} | ||
}, | ||
{ ALT: () => $.SUBRULE($.methodInvocationSuffix) }, | ||
{ ALT: () => $.SUBRULE($.classLiteralSuffix) }, | ||
{ ALT: () => $.SUBRULE($.arrayAccessSuffix) }, | ||
{ ALT: () => $.SUBRULE($.methodReferenceSuffix) } | ||
]); | ||
}); | ||
@@ -281,9 +256,16 @@ | ||
$.MANY2({ | ||
// ".class" is a classLiteralSuffix | ||
GATE: () => | ||
// avoids ambiguity with ".this" and ".new" which are parsed as a primary suffix. | ||
tokenMatcher(this.LA(2).tokenType, t.Class) === false && | ||
tokenMatcher(this.LA(2).tokenType, t.This) === false && | ||
tokenMatcher(this.LA(2).tokenType, t.New) === false, | ||
$.MANY({ | ||
// avoids ambiguity with primary suffixes | ||
GATE: () => { | ||
const nextNextToken = $.LA(2); | ||
return !( | ||
tokenMatcher(nextNextToken, t.Class) || | ||
tokenMatcher(nextNextToken, t.This) || | ||
tokenMatcher(nextNextToken, t.New) || | ||
tokenMatcher(nextNextToken, t.StringLiteral) || | ||
tokenMatcher(nextNextToken, t.TextBlock) || | ||
tokenMatcher(nextNextToken, t.StringTemplateBegin) || | ||
tokenMatcher(nextNextToken, t.TextBlockTemplateBegin) | ||
); | ||
}, | ||
DEF: () => { | ||
@@ -367,8 +349,3 @@ $.CONSUME(t.Dot); | ||
$.OR([ | ||
{ | ||
// TODO: performance: can avoid backtracking again here, parent rule could have this information | ||
// when it checks isCastExpression (refactor needed) | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.isPrimitiveCastExpression), | ||
ALT: () => $.SUBRULE($.primitiveCastExpression) | ||
}, | ||
{ ALT: () => $.SUBRULE($.primitiveCastExpression) }, | ||
{ ALT: () => $.SUBRULE($.referenceTypeCastExpression) } | ||
@@ -393,6 +370,3 @@ ]); | ||
$.OR([ | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.isLambdaExpression), | ||
ALT: () => $.SUBRULE($.lambdaExpression) | ||
}, | ||
{ ALT: () => $.SUBRULE($.lambdaExpression) }, | ||
{ ALT: () => $.SUBRULE($.unaryExpressionNotPlusMinus) } | ||
@@ -402,20 +376,6 @@ ]); | ||
const newExpressionTypes = { | ||
arrayCreationExpression: 1, | ||
unqualifiedClassInstanceCreationExpression: 2 | ||
}; | ||
$.RULE("newExpression", () => { | ||
const type = this.BACKTRACK_LOOKAHEAD($.identifyNewExpressionType); | ||
$.OR([ | ||
{ | ||
GATE: () => type === newExpressionTypes.arrayCreationExpression, | ||
ALT: () => $.SUBRULE($.arrayCreationExpression) | ||
}, | ||
{ | ||
GATE: () => | ||
type === | ||
newExpressionTypes.unqualifiedClassInstanceCreationExpression, | ||
ALT: () => $.SUBRULE($.unqualifiedClassInstanceCreationExpression) | ||
} | ||
{ ALT: () => $.SUBRULE($.arrayCreationExpression) }, | ||
{ ALT: () => $.SUBRULE($.unqualifiedClassInstanceCreationExpression) } | ||
]); | ||
@@ -459,9 +419,6 @@ }); | ||
$.RULE("typeArgumentsOrDiamond", () => { | ||
$.OR({ | ||
DEF: [ | ||
{ ALT: () => $.SUBRULE($.diamond) }, | ||
{ ALT: () => $.SUBRULE($.typeArguments) } | ||
], | ||
MAX_LOOKAHEAD: 2 | ||
}); | ||
$.OR([ | ||
{ ALT: () => $.SUBRULE($.diamond) }, | ||
{ ALT: () => $.SUBRULE($.typeArguments) } | ||
]); | ||
}); | ||
@@ -494,6 +451,3 @@ | ||
$.OR([ | ||
{ | ||
GATE: $.BACKTRACK($.primitiveType), | ||
ALT: () => $.SUBRULE($.primitiveType) | ||
}, | ||
{ ALT: () => $.SUBRULE($.primitiveType) }, | ||
{ ALT: () => $.SUBRULE($.classOrInterfaceType) } | ||
@@ -503,6 +457,3 @@ ]); | ||
$.OR2([ | ||
{ | ||
GATE: $.BACKTRACK($.arrayCreationDefaultInitSuffix), | ||
ALT: () => $.SUBRULE($.arrayCreationDefaultInitSuffix) | ||
}, | ||
{ ALT: () => $.SUBRULE($.arrayCreationDefaultInitSuffix) }, | ||
{ ALT: () => $.SUBRULE($.arrayCreationExplicitInitSuffix) } | ||
@@ -577,12 +528,48 @@ ]); | ||
$.RULE("templateArgument", () => { | ||
$.OR([ | ||
{ ALT: () => $.SUBRULE($.template) }, | ||
{ ALT: () => $.CONSUME(t.StringLiteral) }, | ||
{ ALT: () => $.CONSUME(t.TextBlock) } | ||
]); | ||
}); | ||
$.RULE("template", () => { | ||
$.OR([ | ||
{ ALT: () => $.SUBRULE($.stringTemplate) }, | ||
{ ALT: () => $.SUBRULE($.textBlockTemplate) } | ||
]); | ||
}); | ||
$.RULE("stringTemplate", () => { | ||
$.CONSUME(t.StringTemplateBegin); | ||
$.SUBRULE($.embeddedExpression); | ||
$.MANY(() => { | ||
$.CONSUME(t.StringTemplateMid); | ||
$.SUBRULE1($.embeddedExpression); | ||
}); | ||
$.CONSUME(t.StringTemplateEnd); | ||
}); | ||
$.RULE("textBlockTemplate", () => { | ||
$.CONSUME(t.TextBlockTemplateBegin); | ||
$.SUBRULE($.embeddedExpression); | ||
$.MANY(() => { | ||
$.CONSUME(t.TextBlockTemplateMid); | ||
$.SUBRULE1($.embeddedExpression); | ||
}); | ||
$.CONSUME(t.TextBlockTemplateEnd); | ||
}); | ||
$.RULE("embeddedExpression", () => { | ||
$.OPTION(() => { | ||
$.SUBRULE($.expression); | ||
}); | ||
}); | ||
// https://docs.oracle.com/javase/specs/jls/se21/html/jls-14.html#jls-Pattern | ||
$.RULE("pattern", () => { | ||
$.OR([ | ||
{ | ||
GATE: () => this.BACKTRACK_LOOKAHEAD($.typePattern), | ||
ALT: () => $.SUBRULE($.typePattern) | ||
}, | ||
{ | ||
ALT: () => $.SUBRULE($.recordPattern) | ||
} | ||
{ ALT: () => $.SUBRULE($.typePattern) }, | ||
{ ALT: () => $.SUBRULE($.recordPattern) } | ||
]); | ||
@@ -632,87 +619,2 @@ }); | ||
// backtracking lookahead logic | ||
$.RULE("identifyNewExpressionType", () => { | ||
$.CONSUME(t.New); | ||
const firstTokenAfterNew = this.LA(1).tokenType; | ||
// not an array initialization due to the prefix "TypeArguments" | ||
if (tokenMatcher(firstTokenAfterNew, t.Less)) { | ||
return newExpressionTypes.unqualifiedClassInstanceCreationExpression; | ||
} | ||
try { | ||
$.SUBRULE($.classOrInterfaceTypeToInstantiate); | ||
} catch (e) { | ||
// if it is not a "classOrInterfaceTypeToInstantiate" then | ||
// (assuming a valid input) we are looking at an "arrayCreationExpression" | ||
return newExpressionTypes.arrayCreationExpression; | ||
} | ||
const firstTokenAfterClassType = this.LA(1).tokenType; | ||
if (tokenMatcher(firstTokenAfterClassType, t.LBrace)) { | ||
return newExpressionTypes.unqualifiedClassInstanceCreationExpression; | ||
} | ||
// The LBrace above is mandatory in "classInstanceCreation..." so | ||
// it must be an "arrayCreationExp" (if the input is valid) | ||
// TODO: upgrade the logic to return "unknown" type if at this | ||
// point it does not match "arrayCreation" either. | ||
// - This will provide a better error message to the user | ||
// in case of invalid inputs | ||
return newExpressionTypes.arrayCreationExpression; | ||
}); | ||
// Optimized backtracking, only scan ahead until the arrow("->"). | ||
$.RULE("isLambdaExpression", () => { | ||
// TODO: this check of next two tokens is probably redundant as the normal lookahead should take care of this. | ||
const firstTokenType = this.LA(1).tokenType; | ||
const secondTokenType = this.LA(2).tokenType; | ||
// no parent lambda "x -> x * 2" | ||
if ( | ||
(tokenMatcher(firstTokenType, t.Identifier) || | ||
tokenMatcher(firstTokenType, t.Underscore)) && | ||
tokenMatcher(secondTokenType, t.Arrow) | ||
) { | ||
return true; | ||
} | ||
// Performance optimizations, fail fast if it is not a LBrace. | ||
else if (tokenMatcher(firstTokenType, t.LBrace)) { | ||
$.SUBRULE($.lambdaParametersWithBraces); | ||
const followedByArrow = tokenMatcher(this.LA(1).tokenType, t.Arrow); | ||
return followedByArrow; | ||
} | ||
return false; | ||
}); | ||
$.RULE("isCastExpression", () => { | ||
if (this.BACKTRACK_LOOKAHEAD($.isPrimitiveCastExpression)) { | ||
return true; | ||
} | ||
return this.BACKTRACK_LOOKAHEAD($.isReferenceTypeCastExpression); | ||
}); | ||
$.RULE("isPrimitiveCastExpression", () => { | ||
$.CONSUME(t.LBrace); | ||
$.SUBRULE($.primitiveType); | ||
// No dims so this is not a reference Type | ||
$.CONSUME(t.RBrace); | ||
return true; | ||
}); | ||
$.RULE("isReferenceTypeCastExpression", () => { | ||
$.CONSUME(t.LBrace); | ||
$.SUBRULE($.referenceType); | ||
$.MANY(() => { | ||
$.SUBRULE($.additionalBound); | ||
}); | ||
$.CONSUME(t.RBrace); | ||
const firstTokTypeAfterRBrace = this.LA(1).tokenType; | ||
return ( | ||
this.firstForUnaryExpressionNotPlusMinus.find(tokType => | ||
tokenMatcher(firstTokTypeAfterRBrace, tokType) | ||
) !== undefined | ||
); | ||
}); | ||
$.RULE("isRefTypeInMethodRef", () => { | ||
@@ -752,3 +654,3 @@ let result = undefined; | ||
function computeFirstForUnaryExpressionNotPlusMinus() { | ||
export function computeFirstForUnaryExpressionNotPlusMinus() { | ||
const firstUnaryExpressionNotPlusMinus = this.computeContentAssist( | ||
@@ -764,6 +666,1 @@ "unaryExpressionNotPlusMinus", | ||
} | ||
module.exports = { | ||
defineRules, | ||
computeFirstForUnaryExpressionNotPlusMinus | ||
}; |
@@ -1,13 +0,9 @@ | ||
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
import { tokenMatcher } from "chevrotain"; | ||
function defineRules($, t) { | ||
export function defineRules($, t) { | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-InterfaceDeclaration | ||
$.RULE("interfaceDeclaration", () => { | ||
// Spec Deviation: extracted the common "interfaceModifier" prefix to avoid backtracking. | ||
$.MANY({ | ||
DEF: () => { | ||
$.SUBRULE($.interfaceModifier); | ||
}, | ||
MAX_LOOKAHEAD: 2 | ||
$.MANY(() => { | ||
$.SUBRULE($.interfaceModifier); | ||
}); | ||
@@ -78,39 +74,10 @@ | ||
const InterfaceBodyTypes = { | ||
unknown: 0, | ||
constantDeclaration: 1, | ||
interfaceMethodDeclaration: 2, | ||
classDeclaration: 3, | ||
interfaceDeclaration: 4, | ||
semiColon: 5 | ||
}; | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-InterfaceMemberDeclaration | ||
$.RULE("interfaceMemberDeclaration", () => { | ||
const detectedType = this.BACKTRACK_LOOKAHEAD( | ||
$.identifyInterfaceBodyDeclarationType | ||
); | ||
$.OR([ | ||
{ | ||
GATE: () => detectedType === InterfaceBodyTypes.constantDeclaration, | ||
ALT: () => $.SUBRULE($.constantDeclaration) | ||
}, | ||
{ | ||
GATE: () => | ||
detectedType === InterfaceBodyTypes.interfaceMethodDeclaration, | ||
ALT: () => $.SUBRULE($.interfaceMethodDeclaration) | ||
}, | ||
{ | ||
GATE: () => detectedType === InterfaceBodyTypes.classDeclaration, | ||
ALT: () => $.SUBRULE($.classDeclaration) | ||
}, | ||
{ | ||
GATE: () => detectedType === InterfaceBodyTypes.interfaceDeclaration, | ||
ALT: () => $.SUBRULE($.interfaceDeclaration) | ||
}, | ||
{ | ||
// No GATE is needed as this is LL(1) | ||
ALT: () => $.CONSUME(t.Semicolon) | ||
} | ||
{ ALT: () => $.SUBRULE($.constantDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.interfaceMethodDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.classDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.interfaceDeclaration) }, | ||
{ ALT: () => $.CONSUME(t.Semicolon) } | ||
]); | ||
@@ -179,39 +146,10 @@ }); | ||
const AnnotationBodyTypes = { | ||
unknown: 0, | ||
annotationTypeElementDeclaration: 2, | ||
constantDeclaration: 1, | ||
classDeclaration: 3, | ||
interfaceDeclaration: 4, | ||
semiColon: 5 | ||
}; | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-InterfaceMemberDeclaration | ||
$.RULE("annotationTypeMemberDeclaration", () => { | ||
const detectedType = this.BACKTRACK_LOOKAHEAD( | ||
$.identifyAnnotationBodyDeclarationType | ||
); | ||
$.OR([ | ||
{ | ||
GATE: () => | ||
detectedType === AnnotationBodyTypes.annotationTypeElementDeclaration, | ||
ALT: () => $.SUBRULE($.annotationTypeElementDeclaration) | ||
}, | ||
{ | ||
GATE: () => detectedType === AnnotationBodyTypes.constantDeclaration, | ||
ALT: () => $.SUBRULE($.constantDeclaration) | ||
}, | ||
{ | ||
GATE: () => detectedType === AnnotationBodyTypes.classDeclaration, | ||
ALT: () => $.SUBRULE($.classDeclaration) | ||
}, | ||
{ | ||
GATE: () => detectedType === AnnotationBodyTypes.interfaceDeclaration, | ||
ALT: () => $.SUBRULE($.interfaceDeclaration) | ||
}, | ||
{ | ||
// No GATE is needed as this is LL(1) | ||
ALT: () => $.CONSUME(t.Semicolon) | ||
} | ||
{ ALT: () => $.SUBRULE($.annotationTypeElementDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.constantDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.classDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.interfaceDeclaration) }, | ||
{ ALT: () => $.CONSUME(t.Semicolon) } | ||
]); | ||
@@ -278,4 +216,3 @@ }); | ||
], | ||
IGNORE_AMBIGUITIES: true, | ||
MAX_LOOKAHEAD: 2 | ||
IGNORE_AMBIGUITIES: true | ||
}); | ||
@@ -303,18 +240,8 @@ $.CONSUME(t.RBrace); | ||
$.RULE("elementValue", () => { | ||
const isSimpleElementValueAnnotation = this.BACKTRACK_LOOKAHEAD( | ||
$.isSimpleElementValueAnnotation | ||
); | ||
$.OR([ | ||
// Spec Deviation: "conditionalExpression" replaced with "expression" | ||
// Because we cannot differentiate between the two using fixed lookahead. | ||
{ | ||
GATE: () => isSimpleElementValueAnnotation === false, | ||
ALT: () => $.SUBRULE($.expression) | ||
}, | ||
{ ALT: () => $.SUBRULE($.expression) }, | ||
{ ALT: () => $.SUBRULE($.elementValueArrayInitializer) }, | ||
{ | ||
GATE: () => isSimpleElementValueAnnotation === true, | ||
ALT: () => $.SUBRULE($.annotation) | ||
} | ||
{ ALT: () => $.SUBRULE($.annotation) } | ||
]); | ||
@@ -346,169 +273,2 @@ }); | ||
}); | ||
// ------------------------------------ | ||
// Special optimized backtracking rules. | ||
// ------------------------------------ | ||
$.RULE("identifyInterfaceBodyDeclarationType", () => { | ||
let nextTokenType = this.LA(1).tokenType; | ||
if (tokenMatcher(nextTokenType, t.Semicolon)) { | ||
return InterfaceBodyTypes.semiColon; | ||
} | ||
// We have to look beyond the modifiers to distinguish between the declaration types. | ||
$.MANY({ | ||
// To avoid ambiguity with @interface ("AnnotationTypeDeclaration" vs "Annotaion") | ||
GATE: () => | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
// This alternation includes all possible modifiers for all types of "interfaceMemberDeclaration" | ||
// Certain combinations are syntactically invalid, this is **not** checked here, | ||
// Invalid combinations will cause a descriptive parsing error message to be | ||
// Created inside the relevant parsing rules **after** this lookahead | ||
// analysis. | ||
$.OR([ | ||
{ ALT: () => $.SUBRULE($.annotation) }, | ||
{ ALT: () => $.CONSUME(t.Public) }, | ||
{ ALT: () => $.CONSUME(t.Protected) }, | ||
{ ALT: () => $.CONSUME(t.Private) }, | ||
{ ALT: () => $.CONSUME(t.Abstract) }, | ||
{ ALT: () => $.CONSUME(t.Static) }, | ||
{ ALT: () => $.CONSUME(t.Sealed) }, | ||
{ ALT: () => $.CONSUME(t.NonSealed) }, | ||
{ ALT: () => $.CONSUME(t.Strictfp) }, | ||
{ ALT: () => $.CONSUME(t.Final) }, | ||
{ ALT: () => $.CONSUME(t.Default) } | ||
]); | ||
} | ||
}); | ||
nextTokenType = this.LA(1).tokenType; | ||
if ( | ||
tokenMatcher(nextTokenType, t.Class) || | ||
tokenMatcher(nextTokenType, t.Enum) || | ||
tokenMatcher(nextTokenType, t.Record) | ||
) { | ||
return InterfaceBodyTypes.classDeclaration; | ||
} | ||
if ( | ||
tokenMatcher(nextTokenType, t.Interface) || | ||
tokenMatcher(nextTokenType, t.At) | ||
) { | ||
return InterfaceBodyTypes.interfaceDeclaration; | ||
} | ||
if ( | ||
tokenMatcher(nextTokenType, t.Void) || | ||
tokenMatcher(nextTokenType, t.Less) | ||
) { | ||
// method with result type "void" | ||
return InterfaceBodyTypes.interfaceMethodDeclaration; | ||
} | ||
// Only constant or interfaceMethod declarations may be valid at this point. | ||
// All other alternatives should have been attempted. | ||
// **both** start with "unannType" | ||
this.SUBRULE($.unannType); | ||
const nextToken = this.LA(1); | ||
const nextNextTokenType = this.LA(2).tokenType; | ||
// "foo(..." --> look like method start | ||
if ( | ||
tokenMatcher(nextToken, t.Identifier) && | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
return InterfaceBodyTypes.interfaceMethodDeclaration; | ||
} | ||
// a valid constant | ||
if (tokenMatcher(nextToken, t.Identifier)) { | ||
return InterfaceBodyTypes.constantDeclaration; | ||
} | ||
return InterfaceBodyTypes.unknown; | ||
}); | ||
$.RULE("identifyAnnotationBodyDeclarationType", () => { | ||
let nextTokenType = this.LA(1).tokenType; | ||
if (tokenMatcher(nextTokenType, t.Semicolon)) { | ||
return AnnotationBodyTypes.semiColon; | ||
} | ||
// We have to look beyond the modifiers to distinguish between the declaration types. | ||
$.MANY({ | ||
// To avoid ambiguity with @interface ("AnnotationTypeDeclaration" vs "Annotaion") | ||
GATE: () => | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
// This alternation includes all possible modifiers for all types of "annotationTypeMemberDeclaration" | ||
// Certain combinations are syntactically invalid, this is **not** checked here, | ||
// Invalid combinations will cause a descriptive parsing error message to be | ||
// Created inside the relevant parsing rules **after** this lookahead | ||
// analysis. | ||
$.OR([ | ||
{ ALT: () => $.SUBRULE($.annotation) }, | ||
{ ALT: () => $.CONSUME(t.Public) }, | ||
{ ALT: () => $.CONSUME(t.Protected) }, | ||
{ ALT: () => $.CONSUME(t.Private) }, | ||
{ ALT: () => $.CONSUME(t.Abstract) }, | ||
{ ALT: () => $.CONSUME(t.Static) }, | ||
{ ALT: () => $.CONSUME(t.Final) }, | ||
{ ALT: () => $.CONSUME(t.Strictfp) } | ||
]); | ||
} | ||
}); | ||
nextTokenType = this.LA(1).tokenType; | ||
if ( | ||
tokenMatcher(nextTokenType, t.Class) || | ||
tokenMatcher(nextTokenType, t.Enum) | ||
) { | ||
return AnnotationBodyTypes.classDeclaration; | ||
} | ||
if ( | ||
tokenMatcher(nextTokenType, t.Interface) || | ||
tokenMatcher(nextTokenType, t.At) | ||
) { | ||
return AnnotationBodyTypes.interfaceDeclaration; | ||
} | ||
// Only constant or annotationTypeElement declarations may be valid at this point. | ||
// All other alternatives should have been attempted. | ||
// **both** start with "unannType" | ||
this.SUBRULE($.unannType); | ||
nextTokenType = this.LA(1).tokenType; | ||
const nextNextTokenType = this.LA(2).tokenType; | ||
// "foo(..." --> look like annotationTypeElement start | ||
if ( | ||
tokenMatcher(nextTokenType, t.Identifier) && | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
return AnnotationBodyTypes.annotationTypeElementDeclaration; | ||
} | ||
// a valid constant | ||
if (tokenMatcher(nextTokenType, t.Identifier)) { | ||
return AnnotationBodyTypes.constantDeclaration; | ||
} | ||
return AnnotationBodyTypes.unknown; | ||
}); | ||
$.RULE("isSimpleElementValueAnnotation", () => { | ||
$.SUBRULE($.annotation); | ||
const nextTokenType = this.LA(1).tokenType; | ||
switch (nextTokenType) { | ||
// annotation in "ElementValue" would be followed by one of those | ||
// any other TokenType would indicate it is an annotation in a "referenceType" | ||
// as part of a "methodReference" in "primary" | ||
case t.Comma: | ||
case t.Semicolon: | ||
case t.RCurly: | ||
case t.RBrace: | ||
return true; | ||
default: | ||
return false; | ||
} | ||
}); | ||
} | ||
module.exports = { | ||
defineRules | ||
}; |
@@ -1,3 +0,2 @@ | ||
"use strict"; | ||
function defineRules($, t) { | ||
export function defineRules($, t) { | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-Literal | ||
@@ -39,5 +38,1 @@ $.RULE("literal", () => { | ||
} | ||
module.exports = { | ||
defineRules | ||
}; |
@@ -1,4 +0,3 @@ | ||
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
function defineRules($, t) { | ||
import { tokenMatcher } from "chevrotain"; | ||
export function defineRules($, t) { | ||
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-ModuleName | ||
@@ -83,5 +82,1 @@ $.RULE("moduleName", () => { | ||
} | ||
module.exports = { | ||
defineRules | ||
}; |
@@ -1,6 +0,4 @@ | ||
"use strict"; | ||
const { isRecognitionException, tokenMatcher, EOF } = require("chevrotain"); | ||
const { classBodyTypes } = require("./utils/class-body-types"); | ||
import { tokenMatcher, EOF } from "chevrotain"; | ||
function defineRules($, t) { | ||
export function defineRules($, t) { | ||
/** | ||
@@ -15,13 +13,5 @@ * Spec Deviation: As OrdinaryCompilationUnit and UnnamedClassCompilationUnit | ||
$.RULE("compilationUnit", () => { | ||
// custom optimized backtracking lookahead logic | ||
const isModule = $.BACKTRACK_LOOKAHEAD($.isModuleCompilationUnit); | ||
$.OR([ | ||
{ | ||
GATE: () => isModule === false, | ||
ALT: () => $.SUBRULE($.ordinaryCompilationUnit) | ||
}, | ||
{ | ||
ALT: () => $.SUBRULE($.modularCompilationUnit) | ||
} | ||
{ ALT: () => $.SUBRULE($.ordinaryCompilationUnit) }, | ||
{ ALT: () => $.SUBRULE($.modularCompilationUnit) } | ||
]); | ||
@@ -34,8 +24,3 @@ // https://github.com/jhipster/prettier-java/pull/217 | ||
$.RULE("ordinaryCompilationUnit", () => { | ||
$.OPTION({ | ||
GATE: $.BACKTRACK($.packageDeclaration), | ||
DEF: () => { | ||
$.SUBRULE($.packageDeclaration); | ||
} | ||
}); | ||
$.OPTION(() => $.SUBRULE($.packageDeclaration)); | ||
$.MANY(() => { | ||
@@ -120,24 +105,8 @@ $.SUBRULE3($.importDeclaration); | ||
$.RULE("typeDeclaration", () => { | ||
// TODO: consider extracting the prefix modifiers here to avoid backtracking | ||
const nextRuleType = $.BACKTRACK_LOOKAHEAD( | ||
$.identifyClassBodyDeclarationType | ||
); | ||
$.OR([ | ||
{ ALT: () => $.CONSUME(t.Semicolon) }, | ||
{ | ||
GATE: () => nextRuleType === classBodyTypes.classDeclaration, | ||
ALT: () => $.SUBRULE($.classDeclaration) | ||
}, | ||
{ | ||
GATE: () => nextRuleType === classBodyTypes.interfaceDeclaration, | ||
ALT: () => $.SUBRULE($.interfaceDeclaration) | ||
}, | ||
{ | ||
GATE: () => nextRuleType === classBodyTypes.fieldDeclaration, | ||
ALT: () => $.SUBRULE($.fieldDeclaration) | ||
}, | ||
{ | ||
ALT: () => $.SUBRULE($.methodDeclaration) | ||
} | ||
{ ALT: () => $.SUBRULE($.classDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.interfaceDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.fieldDeclaration) }, | ||
{ ALT: () => $.SUBRULE($.methodDeclaration) } | ||
]); | ||
@@ -261,47 +230,2 @@ }); | ||
}); | ||
$.RULE("isModuleCompilationUnit", () => { | ||
$.OPTION(() => { | ||
$.SUBRULE($.packageDeclaration); | ||
// TODO: this return must be outside the OPTION at the top level rule | ||
// a Java Module source code may not contain a package declaration. | ||
return false; | ||
}); | ||
try { | ||
// the "{importDeclaration}" is a common prefix | ||
$.MANY(() => { | ||
$.SUBRULE2($.importDeclaration); | ||
}); | ||
$.MANY2({ | ||
// To avoid ambiguity with @interface ("AnnotationTypeDeclaration" vs "Annotaion") | ||
GATE: () => | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
$.SUBRULE($.annotation); | ||
} | ||
}); | ||
} catch (e) { | ||
// This means we had a syntax error in the imports or annotations | ||
// So we can't keep parsing deep enough to make the decision | ||
if (isRecognitionException(e)) { | ||
// TODO: add original syntax error? | ||
throw "Cannot Identify if the source code is an OrdinaryCompilationUnit or ModularCompilationUnit"; | ||
} else { | ||
throw e; | ||
} | ||
} | ||
const nextTokenType = this.LA(1).tokenType; | ||
return ( | ||
tokenMatcher(nextTokenType, t.Open) || | ||
tokenMatcher(nextTokenType, t.Module) | ||
); | ||
}); | ||
} | ||
module.exports = { | ||
defineRules | ||
}; |
@@ -1,6 +0,2 @@ | ||
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
function defineRules($, t) { | ||
export function defineRules($, t) { | ||
// --------------------- | ||
@@ -107,11 +103,3 @@ // Productions from §4 (Types, Values, and Variables) | ||
$.CONSUME2(t.Identifier); | ||
$.OPTION2({ | ||
// To avoid confusion with "TypeArgumentsOrDiamond" rule | ||
// as we use the "classType" rule in the "identifyNewExpressionType" | ||
// optimized lookahead rule. | ||
GATE: () => tokenMatcher($.LA(2).tokenType, t.Greater) === false, | ||
DEF: () => { | ||
$.SUBRULE2($.typeArguments); | ||
} | ||
}); | ||
$.OPTION2(() => $.SUBRULE2($.typeArguments)); | ||
}); | ||
@@ -205,6 +193,3 @@ }); | ||
$.OR([ | ||
{ | ||
GATE: $.BACKTRACK($.referenceType), | ||
ALT: () => $.SUBRULE($.referenceType) | ||
}, | ||
{ ALT: () => $.SUBRULE($.referenceType) }, | ||
{ ALT: () => $.SUBRULE($.wildcard) } | ||
@@ -235,5 +220,1 @@ ]); | ||
} | ||
module.exports = { | ||
defineRules | ||
}; |
@@ -1,15 +0,7 @@ | ||
"use strict"; | ||
const { createToken: createTokenOrg, Lexer } = require("chevrotain"); | ||
const camelCase = require("lodash/camelCase"); | ||
import { createToken as createTokenOrg, Lexer } from "chevrotain"; | ||
import camelCase from "lodash/camelCase.js"; | ||
import * as chars from "./unicodesets.js"; | ||
let chars; | ||
// A little mini DSL for easier lexer definition. | ||
const fragments = {}; | ||
try { | ||
chars = require("./unicodesets"); | ||
} catch (e) { | ||
throw Error( | ||
"unicodesets.js file could not be found. Did you try to run the command: yarn run build ?" | ||
); | ||
} | ||
@@ -56,4 +48,8 @@ function inlineFragments(def) { | ||
"StringCharacter", | ||
"(?:(?:{{EscapeSequence}})|{{UnicodeInputCharacter}})" | ||
'(?:(?:{{EscapeSequence}})|{{UnicodeEscape}}|(?!["\\\\]).)' | ||
); | ||
FRAGMENT( | ||
"TextBlockCharacter", | ||
"(?:(?:{{EscapeSequence}})|{{UnicodeEscape}}|(?!\\\\).|\\\\?{{LineTerminator}})" | ||
); | ||
@@ -105,6 +101,14 @@ function matchJavaIdentifier(text, startOffset) { | ||
const allTokens = []; | ||
const allTokens = { | ||
modes: { | ||
global: [], | ||
stringTemplate: [], | ||
textBlockTemplate: [] | ||
}, | ||
defaultMode: "global" | ||
}; | ||
const allModes = Object.keys(allTokens.modes); | ||
const tokenDictionary = {}; | ||
function createToken(options) { | ||
function createToken(options, modes = allModes) { | ||
// TODO create a test to check all the tokenbs have a label defined | ||
@@ -123,3 +127,3 @@ if (!options.label) { | ||
const newTokenType = createTokenOrg(options); | ||
allTokens.push(newTokenType); | ||
modes.forEach(mode => allTokens.modes[mode].push(newTokenType)); | ||
tokenDictionary[options.name] = newTokenType; | ||
@@ -235,10 +239,58 @@ return newTokenType; | ||
name: "TextBlock", | ||
pattern: /"""\s*\n(\\"|\s|.)*?"""/ | ||
pattern: MAKE_PATTERN( | ||
'"""[\\x09\\x20\\x0C]*{{LineTerminator}}{{TextBlockCharacter}}*?"""' | ||
) | ||
}); | ||
createToken({ | ||
name: "TextBlockTemplateBegin", | ||
pattern: MAKE_PATTERN('"""{{LineTerminator}}{{TextBlockCharacter}}*?\\\\\\{'), | ||
push_mode: "textBlockTemplate" | ||
}); | ||
createToken( | ||
{ | ||
name: "TextBlockTemplateEnd", | ||
pattern: MAKE_PATTERN('\\}{{TextBlockCharacter}}*?"""'), | ||
pop_mode: true | ||
}, | ||
["textBlockTemplate"] | ||
); | ||
createToken({ | ||
name: "StringLiteral", | ||
pattern: MAKE_PATTERN('"(?:[^\\\\"]|{{StringCharacter}})*"') | ||
pattern: MAKE_PATTERN('"{{StringCharacter}}*?"') | ||
}); | ||
createToken({ | ||
name: "StringTemplateBegin", | ||
pattern: MAKE_PATTERN('"{{StringCharacter}}*?\\\\\\{'), | ||
push_mode: "stringTemplate" | ||
}); | ||
createToken( | ||
{ | ||
name: "StringTemplateEnd", | ||
pattern: MAKE_PATTERN('\\}{{StringCharacter}}*?"'), | ||
pop_mode: true | ||
}, | ||
["stringTemplate"] | ||
); | ||
createToken( | ||
{ | ||
name: "StringTemplateMid", | ||
pattern: MAKE_PATTERN("\\}{{StringCharacter}}*?\\\\\\{") | ||
}, | ||
["stringTemplate"] | ||
); | ||
createToken( | ||
{ | ||
name: "TextBlockTemplateMid", | ||
pattern: MAKE_PATTERN("\\}{{TextBlockCharacter}}*?\\\\\\{") | ||
}, | ||
["textBlockTemplate"] | ||
); | ||
// https://docs.oracle.com/javase/specs/jls/se21/html/jls-3.html#jls-3.9 | ||
@@ -391,4 +443,12 @@ // TODO: how to handle the special rule (see spec above) for "requires" and "transitive" | ||
createToken({ name: "RBrace", pattern: ")", categories: [Separators] }); | ||
createToken({ name: "LCurly", pattern: "{", categories: [Separators] }); | ||
createToken({ name: "RCurly", pattern: "}", categories: [Separators] }); | ||
createToken({ | ||
name: "LCurly", | ||
pattern: "{", | ||
categories: [Separators], | ||
push_mode: allTokens.defaultMode | ||
}); | ||
createToken( | ||
{ name: "RCurly", pattern: "}", categories: [Separators], pop_mode: true }, | ||
[allTokens.defaultMode] | ||
); | ||
createToken({ name: "LSquare", pattern: "[", categories: [Separators] }); | ||
@@ -530,3 +590,3 @@ createToken({ name: "RSquare", pattern: "]", categories: [Separators] }); | ||
// See: https://github.com/SAP/chevrotain/blob/master/examples/lexer/keywords_vs_identifiers/keywords_vs_identifiers.js | ||
allTokens.push(Identifier); | ||
allModes.forEach(mode => allTokens.modes[mode].push(Identifier)); | ||
tokenDictionary["Identifier"] = Identifier; | ||
@@ -540,5 +600,3 @@ | ||
} | ||
module.exports = { | ||
allTokens, | ||
tokens: tokenDictionary | ||
}; | ||
export { allTokens, tokenDictionary as tokens }; |
@@ -11,3 +11,2 @@ /*File generated with ../scripts/unicode.js using ../resources/Unicode/UnicodeData.txt. | ||
*/ | ||
"use strict"; | ||
const addRanges = (set, rangesArr) => { | ||
@@ -1003,5 +1002,2 @@ for (let i = 0; i < rangesArr.length; i++) { | ||
); | ||
module.exports = { | ||
firstIdentChar: fic, | ||
restIdentChar: ric | ||
}; | ||
export { fic as firstIdentChar, ric as restIdentChar }; |
@@ -1,3 +0,1 @@ | ||
"use strict"; | ||
/** | ||
@@ -11,3 +9,3 @@ * Should Parser / Lexer Validations be skipped? | ||
*/ | ||
function getSkipValidations() { | ||
export function getSkipValidations() { | ||
return ( | ||
@@ -19,5 +17,1 @@ (typeof process !== "undefined" && // (not every runtime has a global `process` object | ||
} | ||
module.exports = { | ||
getSkipValidations | ||
}; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Yes
255827
3
20
7438
+ Addedchevrotain-allstar@0.3.1
+ Added@chevrotain/cst-dts-gen@11.0.3(transitive)
+ Added@chevrotain/gast@11.0.3(transitive)
+ Added@chevrotain/regexp-to-ast@11.0.3(transitive)
+ Added@chevrotain/types@11.0.3(transitive)
+ Added@chevrotain/utils@11.0.3(transitive)
+ Addedchevrotain@11.0.3(transitive)
+ Addedchevrotain-allstar@0.3.1(transitive)
+ Addedlodash-es@4.17.21(transitive)
- Removedchevrotain@6.5.0(transitive)
- Removedregexp-to-ast@0.4.0(transitive)
Updatedchevrotain@11.0.3