NEW : REBASE THE ENTIRE WORKING PROJECT

This commit is contained in:
2022-02-09 19:19:09 +01:00
parent ddad60988e
commit ae93015aa8
1338 changed files with 286867 additions and 0 deletions

311
node_modules/java-parser/src/comments.js generated vendored Normal file
View File

@@ -0,0 +1,311 @@
"use strict";
const findLast = require("lodash/findLast");
/**
* Search where is the position of the comment in the token array by
* using dichotomic search.
* @param {*} tokens ordered array of tokens
* @param {*} comment comment token
* @return the position of the token next to the comment
*/
function findUpperBoundToken(tokens, comment) {
let diff;
let i;
let current;
let len = tokens.length;
i = 0;
while (len) {
diff = len >>> 1;
current = i + diff;
if (tokens[current].startOffset > comment.startOffset) {
len = diff;
} else {
i = current + 1;
len -= diff + 1;
}
}
return i;
}
function isPrettierIgnoreComment(comment) {
return comment.image.match(
/(\/\/(\s*)prettier-ignore(\s*))|(\/\*(\s*)prettier-ignore(\s*)\*\/)/gm
);
}
function isFormatterOffOnComment(comment) {
return comment.image.match(
/(\/\/(\s*)@formatter:(off|on)(\s*))|(\/\*(\s*)@formatter:(off|on)(\s*)\*\/)/gm
);
}
/**
* Pre-processing of tokens in order to
* complete the parser's mostEnclosiveCstNodeByStartOffset and mostEnclosiveCstNodeByEndOffset structures.
*
* @param {ITokens[]} tokens - array of tokens
* @param {{[startOffset: number]: CSTNode}} mostEnclosiveCstNodeByStartOffset
* @param {{[endOffset: number]: CSTNode}} mostEnclosiveCstNodeByEndOffset
*/
function completeMostEnclosiveCSTNodeByOffset(
tokens,
mostEnclosiveCstNodeByStartOffset,
mostEnclosiveCstNodeByEndOffset
) {
tokens.forEach(token => {
if (mostEnclosiveCstNodeByStartOffset[token.startOffset] === undefined) {
mostEnclosiveCstNodeByStartOffset[token.startOffset] = token;
}
if (mostEnclosiveCstNodeByEndOffset[token.endOffset] === undefined) {
mostEnclosiveCstNodeByEndOffset[token.endOffset] = token;
}
});
}
function extendRangeOffset(comments, tokens) {
let position;
comments.forEach(comment => {
position = findUpperBoundToken(tokens, comment);
const extendedStartOffset =
position - 1 < 0 ? comment.startOffset : tokens[position - 1].endOffset;
const extendedEndOffset =
position == tokens.length
? comment.endOffset
: tokens[position].startOffset;
comment.extendedOffset = {
startOffset: extendedStartOffset,
endOffset: extendedEndOffset
};
});
}
/**
* Create two data structures we use to know at which offset a comment can be attached.
* - commentsByExtendedStartOffset: map a comment by the endOffset of the previous token.
* - commentsByExtendedEndOffset: map a comment by the startOffset of the next token
*
* @param {ITokens[]} tokens - array of tokens
*
* @return {{commentsByExtendedStartOffset: {[extendedStartOffset: number]: Comment[]}, commentsByExtendedEndOffset: {[extendedEndOffset: number]: Comment[]}}}
*/
function mapCommentsByExtendedRange(comments) {
const commentsByExtendedEndOffset = {};
const commentsByExtendedStartOffset = {};
comments.forEach(comment => {
const extendedStartOffset = comment.extendedOffset.startOffset;
const extendedEndOffset = comment.extendedOffset.endOffset;
if (commentsByExtendedEndOffset[extendedEndOffset] === undefined) {
commentsByExtendedEndOffset[extendedEndOffset] = [comment];
} else {
commentsByExtendedEndOffset[extendedEndOffset].push(comment);
}
if (commentsByExtendedStartOffset[extendedStartOffset] === undefined) {
commentsByExtendedStartOffset[extendedStartOffset] = [comment];
} else {
commentsByExtendedStartOffset[extendedStartOffset].push(comment);
}
});
return { commentsByExtendedEndOffset, commentsByExtendedStartOffset };
}
/**
* Determine if a comment should be attached as a trailing comment to a specific node.
* A comment should be trailing if it is on the same line than the previous token and
* not on the same line than the next token
*
* @param {*} comment
* @param {CSTNode} node
* @param {{[startOffset: number]: CSTNode}} mostEnclosiveCstNodeByStartOffset
*/
function shouldAttachTrailingComments(
comment,
node,
mostEnclosiveCstNodeByStartOffset
) {
if (isPrettierIgnoreComment(comment)) {
return false;
}
const nextNode =
mostEnclosiveCstNodeByStartOffset[comment.extendedOffset.endOffset];
// Last node of the file
if (nextNode === undefined) {
return true;
}
const nodeEndLine =
node.location !== undefined ? node.location.endLine : node.endLine;
if (comment.startLine !== nodeEndLine) {
return false;
}
const nextNodeStartLine =
nextNode.location !== undefined
? nextNode.location.startLine
: nextNode.startLine;
return comment.endLine !== nextNodeStartLine;
}
/**
* Attach comments to the most enclosive CSTNode (node or token)
*
* @param {ITokens[]} tokens
* @param {*} comments
* @param {{[startOffset: number]: CSTNode}} mostEnclosiveCstNodeByStartOffset
* @param {{[endOffset: number]: CSTNode}} mostEnclosiveCstNodeByEndOffset
*/
function attachComments(
tokens,
comments,
mostEnclosiveCstNodeByStartOffset,
mostEnclosiveCstNodeByEndOffset
) {
// Edge case: only comments in the file
if (tokens.length === 0) {
mostEnclosiveCstNodeByStartOffset[NaN].leadingComments = comments;
return;
}
// Pre-processing phase to complete the data structures we need to attach
// a comment to the right place
completeMostEnclosiveCSTNodeByOffset(
tokens,
mostEnclosiveCstNodeByStartOffset,
mostEnclosiveCstNodeByEndOffset
);
extendRangeOffset(comments, tokens);
const { commentsByExtendedStartOffset, commentsByExtendedEndOffset } =
mapCommentsByExtendedRange(comments);
/*
This set is here to ensure that we attach comments only once
If a comment is attached to a node or token, we remove it from this set
*/
const commentsToAttach = new Set(comments);
// Attach comments as trailing comments if desirable
Object.keys(mostEnclosiveCstNodeByEndOffset).forEach(endOffset => {
// We look if some comments is directly following this node/token
if (commentsByExtendedStartOffset[endOffset] !== undefined) {
const nodeTrailingComments = commentsByExtendedStartOffset[
endOffset
].filter(comment => {
return (
shouldAttachTrailingComments(
comment,
mostEnclosiveCstNodeByEndOffset[endOffset],
mostEnclosiveCstNodeByStartOffset
) && commentsToAttach.has(comment)
);
});
if (nodeTrailingComments.length > 0) {
mostEnclosiveCstNodeByEndOffset[endOffset].trailingComments =
nodeTrailingComments;
}
nodeTrailingComments.forEach(comment => {
commentsToAttach.delete(comment);
});
}
});
// Attach rest of comments as leading comments
Object.keys(mostEnclosiveCstNodeByStartOffset).forEach(startOffset => {
// We look if some comments is directly preceding this node/token
if (commentsByExtendedEndOffset[startOffset] !== undefined) {
const nodeLeadingComments = commentsByExtendedEndOffset[
startOffset
].filter(comment => commentsToAttach.has(comment));
if (nodeLeadingComments.length > 0) {
mostEnclosiveCstNodeByStartOffset[startOffset].leadingComments =
nodeLeadingComments;
}
// prettier ignore support
for (let i = 0; i < nodeLeadingComments.length; i++) {
if (isPrettierIgnoreComment(nodeLeadingComments[i])) {
mostEnclosiveCstNodeByStartOffset[startOffset].ignore = true;
break;
}
}
}
});
}
/**
* Create pairs of formatter:off and formatter:on
* @param comments
* @returns pairs of formatter:off and formatter:on
*/
function matchFormatterOffOnPairs(comments) {
const onOffComments = comments.filter(comment =>
isFormatterOffOnComment(comment)
);
let isPreviousCommentOff = false;
let isCurrentCommentOff = true;
const pairs = [];
let paired = {};
onOffComments.forEach(comment => {
isCurrentCommentOff = comment.image.slice(-3) === "off";
if (!isPreviousCommentOff) {
if (isCurrentCommentOff) {
paired.off = comment;
}
} else {
if (!isCurrentCommentOff) {
paired.on = comment;
pairs.push(paired);
paired = {};
}
}
isPreviousCommentOff = isCurrentCommentOff;
});
if (onOffComments.length > 0 && isCurrentCommentOff) {
paired.on = undefined;
pairs.push(paired);
}
return pairs;
}
/**
* Check if the node is between formatter:off and formatter:on and change his ignore state
* @param node
* @param commentPairs
*/
function shouldNotFormat(node, commentPairs) {
const matchingPair = findLast(
commentPairs,
comment => comment.off.endOffset < node.location.startOffset
);
if (
matchingPair !== undefined &&
(matchingPair.on === undefined ||
matchingPair.on.startOffset > node.location.endOffset)
) {
node.ignore = true;
}
}
module.exports = {
matchFormatterOffOnPairs,
shouldNotFormat,
attachComments
};

67
node_modules/java-parser/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,67 @@
"use strict";
const JavaLexer = require("./lexer");
const JavaParser = require("./parser");
const { attachComments, matchFormatterOffOnPairs } = require("./comments");
const parser = new JavaParser();
const BaseJavaCstVisitor = parser.getBaseCstVisitorConstructor();
const BaseJavaCstVisitorWithDefaults =
parser.getBaseCstVisitorConstructorWithDefaults();
function parse(inputText, entryPoint = "compilationUnit") {
// Lex
const lexResult = JavaLexer.tokenize(inputText);
if (lexResult.errors.length > 0) {
const firstError = lexResult.errors[0];
throw Error(
"Sad sad panda, lexing errors detected in line: " +
firstError.line +
", column: " +
firstError.column +
"!\n" +
firstError.message
);
}
parser.input = lexResult.tokens;
parser.mostEnclosiveCstNodeByStartOffset = {};
parser.mostEnclosiveCstNodeByEndOffset = {};
parser.setOnOffCommentPairs(
matchFormatterOffOnPairs(lexResult.groups.comments)
);
// Automatic CST created when parsing
const cst = parser[entryPoint]();
if (parser.errors.length > 0) {
const error = parser.errors[0];
throw Error(
"Sad sad panda, parsing errors detected in line: " +
error.token.startLine +
", column: " +
error.token.startColumn +
"!\n" +
error.message +
"!\n\t->" +
error.context.ruleStack.join("\n\t->")
);
}
attachComments(
lexResult.tokens,
lexResult.groups.comments,
parser.mostEnclosiveCstNodeByStartOffset,
parser.mostEnclosiveCstNodeByEndOffset
);
return cst;
}
module.exports = {
parse,
BaseJavaCstVisitor,
BaseJavaCstVisitorWithDefaults
};

12
node_modules/java-parser/src/lexer.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
"use strict";
const chevrotain = require("chevrotain");
const { allTokens } = require("./tokens");
const { getSkipValidations } = require("./utils");
const Lexer = chevrotain.Lexer;
const JavaLexer = new Lexer(allTokens, {
ensureOptimizations: true,
skipValidations: getSkipValidations()
});
module.exports = JavaLexer;

119
node_modules/java-parser/src/parser.js generated vendored Normal file
View File

@@ -0,0 +1,119 @@
"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");
/**
* This parser attempts to strongly align with the specs style at:
* - https://docs.oracle.com/javase/specs/jls/se11/html/jls-19.html
*
* Deviations from the spec will be marked.
*
* Note that deviations from the spec do not mean deviations from Java Grammar.
* Rather it means an **equivalent** grammar which was written differently, e.g:
* - LL(k) vs LR(K)
* - Left Recursions vs Repetitions
* - NonTerminals combined together or divided to sub-NonTerminals
* - ...
*
* A special type of spec deviations are the "super grammar" kind.
* This means that the parser has been defined in such a way that it accept a
* **strict superset** of the inputs the official grammar accepts.
*
* This technique is used to simplify the parser when narrowing the set
* of accepted inputs can more easily be done in a post parsing phase.
*
* TODO: document guide lines for using back tracking
*
*/
class JavaParser extends Parser {
constructor() {
super(allTokens, {
maxLookahead: 1,
nodeLocationTracking: "full",
// traceInitPerf: 2,
skipValidations: getSkipValidations()
});
const $ = this;
this.mostEnclosiveCstNodeByStartOffset = {};
this.mostEnclosiveCstNodeByEndOffset = {};
// ---------------------
// Productions from §3 (Lexical Structure)
// ---------------------
// TODO: move this rule to the correct file
$.RULE("typeIdentifier", () => {
// TODO: implement: Identifier but not var in the lexer
$.CONSUME(t.Identifier);
});
// Include the productions from all "chapters".
lexicalStructure.defineRules.call(this, $, t);
typesValuesVariables.defineRules.call(this, $, t);
names.defineRules.call(this, $, t);
classes.defineRules.call(this, $, t);
packagesModules.defineRules.call(this, $, t);
interfaces.defineRules.call(this, $, t);
arrays.defineRules.call(this, $, t);
blocksStatements.defineRules.call(this, $, t);
expressions.defineRules.call(this, $, t);
this.firstForUnaryExpressionNotPlusMinus = [];
this.performSelfAnalysis();
this.firstForUnaryExpressionNotPlusMinus =
expressions.computeFirstForUnaryExpressionNotPlusMinus.call(this);
}
cstPostNonTerminal(ruleCstResult, ruleName) {
super.cstPostNonTerminal(ruleCstResult, ruleName);
if (this.isBackTracking() === false) {
this.mostEnclosiveCstNodeByStartOffset[
ruleCstResult.location.startOffset
] = ruleCstResult;
this.mostEnclosiveCstNodeByEndOffset[ruleCstResult.location.endOffset] =
ruleCstResult;
shouldNotFormat(ruleCstResult, this.onOffCommentPairs);
}
}
BACKTRACK_LOOKAHEAD(production, errValue = false) {
return this.ACTION(() => {
this.isBackTrackingStack.push(1);
// TODO: "saveRecogState" does not handle the occurrence stack
const orgState = this.saveRecogState();
try {
// hack to enable outputting none CST values from grammar rules.
this.outputCst = false;
return production.call(this);
} catch (e) {
if (isRecognitionException(e)) {
return errValue;
}
throw e;
} finally {
this.outputCst = true;
this.reloadRecogState(orgState);
this.isBackTrackingStack.pop();
}
});
}
setOnOffCommentPairs(onOffCommentPairs) {
this.onOffCommentPairs = onOffCommentPairs;
}
}
module.exports = JavaParser;

34
node_modules/java-parser/src/productions/arrays.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
"use strict";
const { tokenMatcher } = require("chevrotain");
function defineRules($, t) {
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-10.html#jls-ArrayInitializer
$.RULE("arrayInitializer", () => {
$.CONSUME(t.LCurly);
$.OPTION(() => {
$.SUBRULE($.variableInitializerList);
});
$.OPTION2(() => {
$.CONSUME(t.Comma);
});
$.CONSUME(t.RCurly);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-10.html#jls-VariableInitializerList
$.RULE("variableInitializerList", () => {
$.SUBRULE($.variableInitializer);
$.MANY({
// The optional last "Comma" of an "arrayInitializer"
GATE: () => tokenMatcher(this.LA(2).tokenType, t.RCurly) === false,
DEF: () => {
$.CONSUME(t.Comma);
$.SUBRULE2($.variableInitializer);
}
});
});
}
module.exports = {
defineRules
};

View File

@@ -0,0 +1,597 @@
"use strict";
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) {
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-Block
$.RULE("block", () => {
$.CONSUME(t.LCurly);
$.OPTION(() => {
$.SUBRULE($.blockStatements);
});
$.CONSUME(t.RCurly);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-BlockStatements
$.RULE("blockStatements", () => {
$.SUBRULE($.blockStatement);
$.MANY(() => {
$.SUBRULE2($.blockStatement);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-BlockStatement
$.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($.statement) }
],
IGNORE_AMBIGUITIES: true
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-LocalVariableDeclarationStatement
$.RULE("localVariableDeclarationStatement", () => {
$.SUBRULE($.localVariableDeclaration);
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-LocalVariableDeclaration
$.RULE("localVariableDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.variableModifier);
});
$.SUBRULE($.localVariableType);
$.SUBRULE($.variableDeclaratorList);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-LocalVariableType
$.RULE("localVariableType", () => {
$.OR({
DEF: [
{ ALT: () => $.SUBRULE($.unannType) },
{ ALT: () => $.CONSUME(t.Var) }
],
IGNORE_AMBIGUITIES: true
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-Statement
$.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
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-StatementWithoutTrailingSubstatement
$.RULE("statementWithoutTrailingSubstatement", () => {
$.OR({
DEF: [
{ ALT: () => $.SUBRULE($.block) },
{
GATE: () => this.BACKTRACK_LOOKAHEAD($.yieldStatement),
ALT: () => $.SUBRULE($.yieldStatement)
},
{ ALT: () => $.SUBRULE($.emptyStatement) },
{
GATE: () => !tokenMatcher(this.LA(1).tokenType, t.Switch),
ALT: () => $.SUBRULE($.expressionStatement)
},
{ ALT: () => $.SUBRULE($.assertStatement) },
{ ALT: () => $.SUBRULE($.switchStatement) },
{ ALT: () => $.SUBRULE($.doStatement) },
{ ALT: () => $.SUBRULE($.breakStatement) },
{ ALT: () => $.SUBRULE($.continueStatement) },
{ ALT: () => $.SUBRULE($.returnStatement) },
{ ALT: () => $.SUBRULE($.synchronizedStatement) },
{ ALT: () => $.SUBRULE($.throwStatement) },
{ ALT: () => $.SUBRULE($.tryStatement) }
],
IGNORE_AMBIGUITIES: true
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-EmptyStatement
$.RULE("emptyStatement", () => {
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-LabeledStatement
$.RULE("labeledStatement", () => {
$.CONSUME(t.Identifier);
$.CONSUME(t.Colon);
$.SUBRULE($.statement);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ExpressionStatement
$.RULE("expressionStatement", () => {
$.SUBRULE($.statementExpression);
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-StatementExpression
$.RULE("statementExpression", () => {
// Spec deviation: The many alternatives here were replaced with
// the "expression" rule as it contains them all,
// and distinguishing between the alternatives cannot be done
// using a fixed lookahead.
// TODO: verify the resulting expression is one of the valid alternatives?
$.SUBRULE($.expression);
});
// Spec deviation: combined "IfThenStatement" and "IfThenElseStatement"
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-IfThenStatement
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-IfThenElseStatement
$.RULE("ifStatement", () => {
$.CONSUME(t.If);
$.CONSUME(t.LBrace);
$.SUBRULE($.expression);
$.CONSUME(t.RBrace);
$.SUBRULE($.statement);
$.OPTION(() => {
$.CONSUME(t.Else);
$.SUBRULE2($.statement);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-AssertStatement
$.RULE("assertStatement", () => {
$.CONSUME(t.Assert);
$.SUBRULE($.expression);
$.OPTION(() => {
$.CONSUME(t.Colon);
$.SUBRULE2($.expression);
});
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-SwitchStatement
$.RULE("switchStatement", () => {
$.CONSUME(t.Switch);
$.CONSUME(t.LBrace);
$.SUBRULE($.expression);
$.CONSUME(t.RBrace);
$.SUBRULE($.switchBlock);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-SwitchBlock
$.RULE("switchBlock", () => {
$.CONSUME(t.LCurly);
$.OR([
{
GATE: () => this.BACKTRACK_LOOKAHEAD($.isClassicSwitchLabel),
ALT: () => $.MANY(() => $.SUBRULE($.switchBlockStatementGroup))
},
{
ALT: () => $.MANY2(() => $.SUBRULE($.switchRule))
}
]);
$.CONSUME(t.RCurly);
});
$.RULE("switchBlockStatementGroup", () => {
$.SUBRULE($.switchLabel);
$.CONSUME(t.Colon);
$.OPTION(() => {
$.SUBRULE($.blockStatements);
});
});
$.RULE("switchLabel", () => {
$.SUBRULE($.caseOrDefaultLabel);
$.MANY({
GATE: () =>
tokenMatcher($.LA(1).tokenType, t.Colon) &&
(tokenMatcher($.LA(2).tokenType, t.Case) ||
tokenMatcher($.LA(2).tokenType, t.Default)),
DEF: () => {
$.CONSUME(t.Colon);
$.SUBRULE2($.caseOrDefaultLabel);
}
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-SwitchLabel
$.RULE("caseOrDefaultLabel", () => {
$.OR([
{
ALT: () => {
$.CONSUME(t.Case);
$.SUBRULE($.caseLabelElement);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.caseLabelElement);
});
}
},
{
ALT: () => $.CONSUME(t.Default)
}
]);
});
$.RULE("caseLabelElement", () => {
$.OR([
{ ALT: () => $.CONSUME(t.Null) },
{ ALT: () => $.CONSUME(t.Default) },
{
GATE: () => this.BACKTRACK_LOOKAHEAD($.pattern),
ALT: () => $.SUBRULE($.pattern)
},
{
GATE: () => tokenMatcher($.LA(1).tokenType, t.Null) === false,
ALT: () => $.SUBRULE($.caseConstant)
}
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-SwitchRule
$.RULE("switchRule", () => {
$.SUBRULE($.switchLabel);
$.CONSUME(t.Arrow);
$.OR([
{ ALT: () => $.SUBRULE($.throwStatement) },
{ ALT: () => $.SUBRULE($.block) },
{
ALT: () => {
$.SUBRULE($.expression);
$.CONSUME(t.Semicolon);
}
}
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-EnumConstantName
$.RULE("caseConstant", () => {
$.SUBRULE($.ternaryExpression);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-WhileStatement
$.RULE("whileStatement", () => {
$.CONSUME(t.While);
$.CONSUME(t.LBrace);
$.SUBRULE($.expression);
$.CONSUME(t.RBrace);
$.SUBRULE($.statement);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-DoStatement
$.RULE("doStatement", () => {
$.CONSUME(t.Do);
$.SUBRULE($.statement);
$.CONSUME(t.While);
$.CONSUME(t.LBrace);
$.SUBRULE($.expression);
$.CONSUME(t.RBrace);
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ForStatement
$.RULE("forStatement", () => {
$.OR([
{
GATE: () => this.BACKTRACK_LOOKAHEAD($.isBasicForStatement),
ALT: () => $.SUBRULE($.basicForStatement)
},
{ ALT: () => $.SUBRULE($.enhancedForStatement) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-BasicForStatement
$.RULE("basicForStatement", () => {
$.CONSUME(t.For);
$.CONSUME(t.LBrace);
$.OPTION(() => {
$.SUBRULE($.forInit);
});
$.CONSUME(t.Semicolon);
$.OPTION2(() => {
$.SUBRULE($.expression);
});
$.CONSUME2(t.Semicolon);
$.OPTION3(() => {
$.SUBRULE($.forUpdate);
});
$.CONSUME(t.RBrace);
$.SUBRULE($.statement);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ForInit
$.RULE("forInit", () => {
$.OR([
{
GATE: () => $.BACKTRACK_LOOKAHEAD($.isLocalVariableDeclaration),
ALT: () => $.SUBRULE($.localVariableDeclaration)
},
{ ALT: () => $.SUBRULE($.statementExpressionList) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ForUpdate
$.RULE("forUpdate", () => {
$.SUBRULE($.statementExpressionList);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-StatementExpressionList
$.RULE("statementExpressionList", () => {
$.SUBRULE($.statementExpression);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.statementExpression);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-EnhancedForStatement
$.RULE("enhancedForStatement", () => {
$.CONSUME(t.For);
$.CONSUME(t.LBrace);
$.MANY(() => {
$.SUBRULE($.variableModifier);
});
$.SUBRULE($.localVariableType);
$.SUBRULE($.variableDeclaratorId);
$.CONSUME(t.Colon);
$.SUBRULE($.expression);
$.CONSUME(t.RBrace);
$.SUBRULE($.statement);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-BreakStatement
$.RULE("breakStatement", () => {
$.CONSUME(t.Break);
$.OPTION(() => {
$.CONSUME(t.Identifier);
});
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ContinueStatement
$.RULE("continueStatement", () => {
$.CONSUME(t.Continue);
$.OPTION(() => {
$.CONSUME(t.Identifier);
});
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ReturnStatement
$.RULE("returnStatement", () => {
$.CONSUME(t.Return);
$.OPTION(() => {
$.SUBRULE($.expression);
});
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ThrowStatement
$.RULE("throwStatement", () => {
$.CONSUME(t.Throw);
$.SUBRULE($.expression);
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-SynchronizedStatement
$.RULE("synchronizedStatement", () => {
$.CONSUME(t.Synchronized);
$.CONSUME(t.LBrace);
$.SUBRULE($.expression);
$.CONSUME(t.RBrace);
$.SUBRULE($.block);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-TryStatement
$.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
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-Catches
$.RULE("catches", () => {
$.SUBRULE($.catchClause);
$.MANY(() => {
$.SUBRULE2($.catchClause);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-CatchClause
$.RULE("catchClause", () => {
$.CONSUME(t.Catch);
$.CONSUME(t.LBrace);
$.SUBRULE($.catchFormalParameter);
$.CONSUME(t.RBrace);
$.SUBRULE($.block);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-CatchFormalParameter
$.RULE("catchFormalParameter", () => {
$.MANY(() => {
$.SUBRULE($.variableModifier);
});
$.SUBRULE($.catchType);
$.SUBRULE($.variableDeclaratorId);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-CatchType
$.RULE("catchType", () => {
$.SUBRULE($.unannClassType);
$.MANY(() => {
$.CONSUME(t.Or);
$.SUBRULE2($.classType);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-Finally
$.RULE("finally", () => {
$.CONSUME(t.Finally);
$.SUBRULE($.block);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-TryWithResourcesStatement
$.RULE("tryWithResourcesStatement", () => {
$.CONSUME(t.Try);
$.SUBRULE($.resourceSpecification);
$.SUBRULE($.block);
$.OPTION(() => {
$.SUBRULE($.catches);
});
$.OPTION2(() => {
$.SUBRULE($.finally);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ResourceSpecification
$.RULE("resourceSpecification", () => {
$.CONSUME(t.LBrace);
$.SUBRULE($.resourceList);
$.OPTION(() => {
$.CONSUME(t.Semicolon);
});
$.CONSUME(t.RBrace);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-ResourceList
$.RULE("resourceList", () => {
$.SUBRULE($.resource);
$.MANY({
GATE: () => tokenMatcher($.LA(2).tokenType, t.RBrace) === false,
DEF: () => {
$.CONSUME(t.Semicolon);
$.SUBRULE2($.resource);
}
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-Resource
$.RULE("resource", () => {
$.OR([
{
GATE: $.BACKTRACK($.resourceInit),
// Spec Deviation: extracted this alternative to "resourceInit"
// to enable backtracking.
ALT: () => $.SUBRULE($.resourceInit)
},
{ ALT: () => $.SUBRULE($.variableAccess) }
]);
});
// Spec Deviation: extracted from "resource"
$.RULE("resourceInit", () => {
$.MANY(() => {
$.SUBRULE($.variableModifier);
});
$.SUBRULE($.localVariableType);
$.CONSUME(t.Identifier);
$.CONSUME(t.Equals);
$.SUBRULE($.expression);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-YieldStatement
$.RULE("yieldStatement", () => {
$.CONSUME(t.Yield);
$.SUBRULE($.expression);
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-VariableAccess
$.RULE("variableAccess", () => {
// Spec Deviation: both "expressionName" and "fieldAccess" can be parsed
// by the "primary" rule
// TODO: verify that the primary is a fieldAccess or an expressionName.
$.SUBRULE($.primary);
});
// ------------------------------------
// 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
};

950
node_modules/java-parser/src/productions/classes.js generated vendored Normal file
View File

@@ -0,0 +1,950 @@
"use strict";
const { isRecognitionException, tokenMatcher } = require("chevrotain");
function defineRules($, t) {
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassDeclaration
$.RULE("classDeclaration", () => {
// Spec Deviation: extracted common "{classModifier}" prefix
// extraction is safe because there are no other references to
// "normalClassDeclaration" and "enumDeclaration"
$.MANY(() => {
$.SUBRULE($.classModifier);
});
$.OR([
{ ALT: () => $.SUBRULE($.normalClassDeclaration) },
{ ALT: () => $.SUBRULE($.enumDeclaration) },
{ ALT: () => $.SUBRULE($.recordDeclaration) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-NormalClassDeclaration
$.RULE("normalClassDeclaration", () => {
// Spec Deviation: extracted common "{classModifier}" to "classDeclaration"
$.CONSUME(t.Class);
$.SUBRULE($.typeIdentifier);
$.OPTION(() => {
$.SUBRULE($.typeParameters);
});
$.OPTION2(() => {
$.SUBRULE($.superclass);
});
$.OPTION3(() => {
$.SUBRULE($.superinterfaces);
});
$.OPTION4(() => {
$.SUBRULE($.classPermits);
});
$.SUBRULE($.classBody);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassModifier
$.RULE("classModifier", () => {
$.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.Sealed) },
{ ALT: () => $.CONSUME(t.NonSealed) },
{ ALT: () => $.CONSUME(t.Strictfp) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-TypeParameters
$.RULE("typeParameters", () => {
$.CONSUME(t.Less);
$.SUBRULE($.typeParameterList);
$.CONSUME(t.Greater);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-TypeParameterList
$.RULE("typeParameterList", () => {
$.SUBRULE($.typeParameter);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.typeParameter);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassExtends
$.RULE("superclass", () => {
$.CONSUME(t.Extends);
$.SUBRULE($.classType);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassImplements
$.RULE("superinterfaces", () => {
$.CONSUME(t.Implements);
$.SUBRULE($.interfaceTypeList);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-InterfaceTypeList
$.RULE("interfaceTypeList", () => {
$.SUBRULE($.interfaceType);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.interfaceType);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/preview/specs/sealed-classes-jls.html
$.RULE("classPermits", () => {
$.CONSUME(t.Permits);
$.SUBRULE($.typeName);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.typeName);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassBody
$.RULE("classBody", () => {
$.CONSUME(t.LCurly);
$.MANY(() => {
$.SUBRULE($.classBodyDeclaration);
});
$.CONSUME(t.RCurly);
});
const classBodyTypes = {
unknown: 0,
fieldDeclaration: 1,
methodDeclaration: 2,
classDeclaration: 3,
interfaceDeclaration: 4,
semiColon: 5,
instanceInitializer: 6,
staticInitializer: 7,
constructorDeclaration: 8
};
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassBodyDeclaration
$.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($.instanceInitializer) },
{ ALT: () => $.SUBRULE($.staticInitializer) },
{
GATE: () =>
tokenMatcher(nextRuleType, classBodyTypes.constructorDeclaration),
ALT: () => $.SUBRULE($.constructorDeclaration)
}
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassMemberDeclaration
$.RULE("classMemberDeclaration", nextRuleType => {
$.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)
}
]);
});
// // https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-FieldDeclaration
$.RULE("fieldDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.fieldModifier);
});
$.SUBRULE($.unannType);
$.SUBRULE($.variableDeclaratorList);
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-FieldModifier
$.RULE("fieldModifier", () => {
$.OR([
{ ALT: () => $.SUBRULE($.annotation) },
{ ALT: () => $.CONSUME(t.Public) },
{ ALT: () => $.CONSUME(t.Protected) },
{ ALT: () => $.CONSUME(t.Private) },
{ ALT: () => $.CONSUME(t.Static) },
{ ALT: () => $.CONSUME(t.Final) },
{ ALT: () => $.CONSUME(t.Transient) },
{ ALT: () => $.CONSUME(t.Volatile) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-VariableDeclaratorList
$.RULE("variableDeclaratorList", () => {
$.SUBRULE($.variableDeclarator);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.variableDeclarator);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-VariableDeclarator
$.RULE("variableDeclarator", () => {
$.SUBRULE($.variableDeclaratorId);
$.OPTION(() => {
$.CONSUME(t.Equals);
$.SUBRULE($.variableInitializer);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-VariableDeclaratorId
$.RULE("variableDeclaratorId", () => {
$.CONSUME(t.Identifier);
$.OPTION(() => {
$.SUBRULE($.dims);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-VariableInitializer
$.RULE("variableInitializer", () => {
$.OR([
{ ALT: () => $.SUBRULE($.expression) },
{ ALT: () => $.SUBRULE($.arrayInitializer) }
]);
});
// // https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-UnannType
$.RULE("unannType", () => {
$.OR([
// Spec Deviation: The array type "dims" suffix was extracted to this rule
// to avoid backtracking for performance reasons.
{ ALT: () => $.SUBRULE($.unannPrimitiveTypeWithOptionalDimsSuffix) },
{ ALT: () => $.SUBRULE($.unannReferenceType) }
]);
});
$.RULE("unannPrimitiveTypeWithOptionalDimsSuffix", () => {
$.SUBRULE($.unannPrimitiveType);
$.OPTION({
GATE: () => this.BACKTRACK_LOOKAHEAD($.isDims),
DEF: () => $.SUBRULE2($.dims)
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-UnannPrimitiveType
$.RULE("unannPrimitiveType", () => {
$.OR([
{ ALT: () => $.SUBRULE($.numericType) },
{ ALT: () => $.CONSUME(t.Boolean) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-UnannReferenceType
$.RULE("unannReferenceType", () => {
$.SUBRULE($.unannClassOrInterfaceType);
$.OPTION({
GATE: () => this.BACKTRACK_LOOKAHEAD($.isDims),
DEF: () => $.SUBRULE2($.dims)
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-UnannClassType
$.RULE("unannClassOrInterfaceType", () => {
// Spec Deviation: The spec says: "UnannClassType | UnannInterfaceType" but "UnannInterfaceType"
// is not mentioned in the parser because it is identical to "UnannClassType"
// The distinction is **semantic** not syntactic.
$.SUBRULE($.unannClassType);
});
$.RULE("unannClassType", () => {
// Spec Deviation: Refactored left recursion and alternation to iterations
$.CONSUME(t.Identifier);
$.OPTION(() => {
$.SUBRULE($.typeArguments);
});
$.MANY2(() => {
$.CONSUME(t.Dot);
$.MANY3(() => {
$.SUBRULE2($.annotation);
});
// TODO: Semantic Check: This Identifier cannot be "var"
$.CONSUME2(t.Identifier);
$.OPTION2(() => {
$.SUBRULE2($.typeArguments);
});
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-UnannInterfaceType
$.RULE("unannInterfaceType", () => {
$.SUBRULE($.unannClassType);
});
$.RULE("unannTypeVariable", () => {
// TODO: Semantic Check: This Identifier cannot be "var"
// TODO: or define as token type?
$.CONSUME(t.Identifier);
});
// // https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-MethodDeclaration
$.RULE("methodDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.methodModifier);
});
$.SUBRULE($.methodHeader);
$.SUBRULE($.methodBody);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-MethodModifier
$.RULE("methodModifier", () => {
$.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.Synchronized) },
{ ALT: () => $.CONSUME(t.Native) },
{ ALT: () => $.CONSUME(t.Strictfp) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-MethodHeader
$.RULE("methodHeader", () => {
// Spec Deviation: extracted common prefix from both alternatives
$.OPTION(() => {
$.SUBRULE($.typeParameters);
$.MANY(() => {
$.SUBRULE($.annotation);
});
});
$.SUBRULE($.result);
$.SUBRULE($.methodDeclarator);
$.OPTION2(() => {
$.SUBRULE($.throws);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-Result
$.RULE("result", () => {
$.OR([
{ ALT: () => $.SUBRULE($.unannType) },
{ ALT: () => $.CONSUME(t.Void) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-MethodDeclarator
$.RULE("methodDeclarator", () => {
$.CONSUME(t.Identifier);
$.CONSUME(t.LBrace);
$.OPTION(() => {
$.SUBRULE($.formalParameterList);
});
$.CONSUME(t.RBrace);
$.OPTION2(() => {
$.SUBRULE($.dims);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ReceiverParameter
$.RULE("receiverParameter", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.SUBRULE($.unannType);
$.OPTION(() => {
$.CONSUME(t.Identifier);
$.CONSUME(t.Dot);
});
$.CONSUME(t.This);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-FormalParameterList
$.RULE("formalParameterList", () => {
$.SUBRULE($.formalParameter);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.formalParameter);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-FormalParameter
$.RULE("formalParameter", () => {
$.OR([
// Spec Deviation: extracted to "variableParaRegularParameter"
{
GATE: $.BACKTRACK($.variableParaRegularParameter),
ALT: () => $.SUBRULE($.variableParaRegularParameter)
},
{ ALT: () => $.SUBRULE($.variableArityParameter) }
]);
});
// Spec Deviation: extracted from "formalParameter"
$.RULE("variableParaRegularParameter", () => {
$.MANY(() => {
$.SUBRULE($.variableModifier);
});
$.SUBRULE($.unannType);
$.SUBRULE($.variableDeclaratorId);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-VariableArityParameter
$.RULE("variableArityParameter", () => {
$.MANY(() => {
$.SUBRULE($.variableModifier);
});
$.SUBRULE($.unannType);
$.MANY2(() => {
$.SUBRULE($.annotation);
});
$.CONSUME(t.DotDotDot);
$.CONSUME(t.Identifier);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-VariableModifier
$.RULE("variableModifier", () => {
$.OR([
{ ALT: () => $.SUBRULE($.annotation) },
{ ALT: () => $.CONSUME(t.Final) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-Throws
$.RULE("throws", () => {
$.CONSUME(t.Throws);
$.SUBRULE($.exceptionTypeList);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ExceptionTypeList
$.RULE("exceptionTypeList", () => {
$.SUBRULE($.exceptionType);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.exceptionType);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ExceptionType
$.RULE("exceptionType", () => {
// Spec Deviation: "typeVariable" alternative is missing because
// it is contained in classType.
$.SUBRULE($.classType);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-MethodBody
$.RULE("methodBody", () => {
$.OR([
{ ALT: () => $.SUBRULE($.block) },
{ ALT: () => $.CONSUME(t.Semicolon) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-InstanceInitializer
$.RULE("instanceInitializer", () => {
$.SUBRULE($.block);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-StaticInitializer
$.RULE("staticInitializer", () => {
$.CONSUME(t.Static);
$.SUBRULE($.block);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ConstructorDeclaration
$.RULE("constructorDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.constructorModifier);
});
$.SUBRULE($.constructorDeclarator);
$.OPTION(() => {
$.SUBRULE($.throws);
});
$.SUBRULE($.constructorBody);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ConstructorModifier
$.RULE("constructorModifier", () => {
$.OR([
{ ALT: () => $.SUBRULE($.annotation) },
{ ALT: () => $.CONSUME(t.Public) },
{ ALT: () => $.CONSUME(t.Protected) },
{ ALT: () => $.CONSUME(t.Private) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ConstructorDeclarator
$.RULE("constructorDeclarator", () => {
$.OPTION(() => {
$.SUBRULE($.typeParameters);
});
$.SUBRULE($.simpleTypeName);
$.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);
});
$.CONSUME(t.RBrace);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-SimpleTypeName
$.RULE("simpleTypeName", () => {
// TODO: implement: Identifier but not var
$.CONSUME(t.Identifier);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ConstructorBody
$.RULE("constructorBody", () => {
$.CONSUME(t.LCurly);
$.OPTION({
GATE: $.BACKTRACK($.explicitConstructorInvocation),
DEF: () => {
$.SUBRULE($.explicitConstructorInvocation);
}
});
$.OPTION2(() => {
$.SUBRULE($.blockStatements);
});
$.CONSUME(t.RCurly);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ExplicitConstructorInvocation
$.RULE("explicitConstructorInvocation", () => {
// Spec Deviation: split into two separate sub rules.
$.OR([
{
ALT: () => $.SUBRULE($.unqualifiedExplicitConstructorInvocation)
},
{ ALT: () => $.SUBRULE($.qualifiedExplicitConstructorInvocation) }
]);
});
$.RULE("unqualifiedExplicitConstructorInvocation", () => {
$.OPTION(() => {
$.SUBRULE($.typeArguments);
});
$.OR([
{
ALT: () => $.CONSUME(t.This)
},
{
ALT: () => $.CONSUME(t.Super)
}
]);
$.CONSUME(t.LBrace);
$.OPTION2(() => {
$.SUBRULE($.argumentList);
});
$.CONSUME(t.RBrace);
$.CONSUME(t.Semicolon);
});
$.RULE("qualifiedExplicitConstructorInvocation", () => {
// Spec Deviation: According to the spec the prefix may be a "primary' as well,
// however, most primary variants don't make sense here
// TODO: discover which primary forms could be valid here
// and handle only those specific cases.
// It is best if we avoid referencing "primary" rule from
// outside the expressions rules as the expressions rules are not aligned
// to the spec style, so we want the smallest possible "external api"
// for the expressions rules.
$.SUBRULE($.expressionName);
$.CONSUME(t.Dot);
$.OPTION(() => {
$.SUBRULE($.typeArguments);
});
$.CONSUME(t.Super);
$.CONSUME(t.LBrace);
$.OPTION2(() => {
$.SUBRULE($.argumentList);
});
$.CONSUME(t.RBrace);
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-EnumDeclaration
$.RULE("enumDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.classModifier);
});
$.CONSUME(t.Enum);
$.SUBRULE($.typeIdentifier);
$.OPTION(() => {
$.SUBRULE($.superinterfaces);
});
$.SUBRULE($.enumBody);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-EnumBody
$.RULE("enumBody", () => {
$.CONSUME(t.LCurly);
$.OPTION(() => {
$.SUBRULE($.enumConstantList);
});
$.OPTION2(() => {
$.CONSUME(t.Comma);
});
$.OPTION3(() => {
$.SUBRULE($.enumBodyDeclarations);
});
$.CONSUME(t.RCurly);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-EnumConstantList
$.RULE("enumConstantList", () => {
$.SUBRULE($.enumConstant);
$.MANY({
GATE: () => {
const nextToken = $.LA(2);
return (
tokenMatcher(nextToken, t.Identifier) || tokenMatcher(nextToken, t.At)
);
},
DEF: () => {
$.CONSUME(t.Comma);
$.SUBRULE2($.enumConstant);
}
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-EnumConstant
$.RULE("enumConstant", () => {
$.MANY(() => {
$.SUBRULE($.enumConstantModifier);
});
$.CONSUME(t.Identifier);
$.OPTION(() => {
$.CONSUME(t.LBrace);
$.OPTION2(() => {
$.SUBRULE($.argumentList);
});
$.CONSUME(t.RBrace);
});
$.OPTION3(() => {
$.SUBRULE($.classBody);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-EnumConstantModifier
$.RULE("enumConstantModifier", () => {
$.SUBRULE($.annotation);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-EnumBodyDeclarations
$.RULE("enumBodyDeclarations", () => {
$.CONSUME(t.Semicolon);
$.MANY(() => {
$.SUBRULE($.classBodyDeclaration);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-RecordHeader
$.RULE("recordDeclaration", () => {
$.CONSUME(t.Record);
$.SUBRULE($.typeIdentifier);
$.OPTION(() => {
$.SUBRULE($.typeParameters);
});
$.SUBRULE($.recordHeader);
$.OPTION2(() => {
$.SUBRULE($.superinterfaces);
});
$.SUBRULE($.recordBody);
});
$.RULE("recordHeader", () => {
$.CONSUME(t.LBrace);
$.OPTION(() => {
$.SUBRULE($.recordComponentList);
});
$.CONSUME(t.RBrace);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-RecordComponentList
$.RULE("recordComponentList", () => {
$.SUBRULE($.recordComponent);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.recordComponent);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-RecordComponent
$.RULE("recordComponent", () => {
// Spec Deviation: extracted common "{recordComponentModifier} unannType" prefix
// extraction is safe because there are no other references to
// "variableArityRecordComponent"
$.MANY(() => {
$.SUBRULE($.recordComponentModifier);
});
$.SUBRULE($.unannType);
$.OR([
{ ALT: () => $.CONSUME(t.Identifier) },
{ ALT: () => $.SUBRULE($.variableArityRecordComponent) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-VariableArityRecordComponent
// Spec Deviation: common "{recordComponentModifier} unannType" prefix was extracted in "recordComponent"
$.RULE("variableArityRecordComponent", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.CONSUME(t.DotDotDot);
$.CONSUME(t.Identifier);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-RecordComponentModifier
$.RULE("recordComponentModifier", () => {
$.SUBRULE($.annotation);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-RecordBody
$.RULE("recordBody", () => {
$.CONSUME(t.LCurly);
$.MANY(() => {
$.SUBRULE($.recordBodyDeclaration);
});
$.CONSUME(t.RCurly);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-RecordBodyDeclaration
$.RULE("recordBodyDeclaration", () => {
$.OR([
{
GATE: () => this.BACKTRACK_LOOKAHEAD($.isCompactConstructorDeclaration),
ALT: () => $.SUBRULE($.compactConstructorDeclaration)
},
{ ALT: () => $.SUBRULE($.classBodyDeclaration) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-CompactConstructorDeclaration
$.RULE("compactConstructorDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.constructorModifier);
});
$.SUBRULE($.simpleTypeName);
$.SUBRULE($.constructorBody);
});
$.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", () => {
$.MANY($.annotation);
return (
tokenMatcher(this.LA(1).tokenType, t.LSquare) &&
tokenMatcher(this.LA(2).tokenType, t.RSquare)
);
});
$.RULE("isCompactConstructorDeclaration", () => {
$.MANY($.constructorModifier);
$.SUBRULE($.simpleTypeName);
$.CONSUME(t.LCurly);
});
}
module.exports = {
defineRules
};

705
node_modules/java-parser/src/productions/expressions.js generated vendored Normal file
View File

@@ -0,0 +1,705 @@
"use strict";
const { tokenMatcher } = require("chevrotain");
function defineRules($, t) {
$.RULE("expression", () => {
$.OR([
{
GATE: () => this.BACKTRACK_LOOKAHEAD($.isLambdaExpression),
ALT: () => $.SUBRULE($.lambdaExpression)
},
{ ALT: () => $.SUBRULE($.ternaryExpression) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-LambdaExpression
$.RULE("lambdaExpression", () => {
$.SUBRULE($.lambdaParameters);
$.CONSUME(t.Arrow);
$.SUBRULE($.lambdaBody);
});
$.RULE("lambdaParameters", () => {
$.OR([
{ ALT: () => $.SUBRULE($.lambdaParametersWithBraces) },
{ ALT: () => $.CONSUME(t.Identifier) }
]);
});
$.RULE("lambdaParametersWithBraces", () => {
$.CONSUME(t.LBrace);
$.OPTION(() => {
$.SUBRULE($.lambdaParameterList);
});
$.CONSUME(t.RBrace);
});
$.RULE("lambdaParameterList", () => {
$.OR([
{
GATE: () => {
const nextTokType = this.LA(1).tokenType;
const nextNextTokType = this.LA(2).tokenType;
return (
tokenMatcher(nextTokType, t.Identifier) &&
(tokenMatcher(nextNextTokType, t.RBrace) ||
tokenMatcher(nextNextTokType, t.Comma))
);
},
ALT: () => $.SUBRULE($.inferredLambdaParameterList)
},
{ ALT: () => $.SUBRULE($.explicitLambdaParameterList) }
]);
});
$.RULE("inferredLambdaParameterList", () => {
$.CONSUME(t.Identifier);
$.MANY(() => {
$.CONSUME(t.Comma);
$.CONSUME2(t.Identifier);
});
});
$.RULE("explicitLambdaParameterList", () => {
$.SUBRULE($.lambdaParameter);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.lambdaParameter);
});
});
$.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($.variableArityParameter) }
]);
});
$.RULE("regularLambdaParameter", () => {
$.MANY(() => {
$.SUBRULE($.variableModifier);
});
$.SUBRULE($.lambdaParameterType);
$.SUBRULE($.variableDeclaratorId);
});
$.RULE("lambdaParameterType", () => {
$.OR({
DEF: [
{ ALT: () => $.SUBRULE($.unannType) },
{ ALT: () => $.CONSUME(t.Var) }
],
IGNORE_AMBIGUITIES: true
});
});
$.RULE("lambdaBody", () => {
$.OR([
{ ALT: () => $.SUBRULE($.expression) },
{ ALT: () => $.SUBRULE($.block) }
]);
});
$.RULE("ternaryExpression", () => {
$.SUBRULE($.binaryExpression);
$.OPTION(() => {
$.CONSUME(t.QuestionMark);
$.SUBRULE($.expression);
$.CONSUME(t.Colon);
// TODO: in the grammar this is limited to "lambdaExpression: or "conditionalExpression"
$.SUBRULE2($.expression);
});
});
$.RULE("binaryExpression", () => {
$.SUBRULE($.unaryExpression);
$.MANY(() => {
$.OR({
DEF: [
{
ALT: () => {
$.CONSUME(t.Instanceof);
$.OR1([
{
GATE: () => this.BACKTRACK_LOOKAHEAD($.pattern),
ALT: () => $.SUBRULE($.pattern)
},
{
ALT: () => $.SUBRULE($.referenceType)
}
]);
}
},
{
ALT: () => {
$.CONSUME(t.AssignmentOperator);
$.SUBRULE2($.expression);
}
},
// This is an example of why Java does not have a well designed grammar
// See: https://manas.tech/blog/2008/10/12/why-java-generics-dont-have-problems-with-right-shift-operator.html
// TODO: ensure the LT/GT sequences have no whitespace between each other.
{
// TODO: this is a bug in Chevrotain lookahead calculation. the "BinaryOperator" token can match "Less" or "Greater"
// as well, but because it is a **token Category** Chevrotain does not understand it need to looks two tokens ahead.
GATE: () =>
tokenMatcher($.LA(2).tokenType, t.Less) ||
tokenMatcher($.LA(2).tokenType, t.Greater),
ALT: () => {
$.OR2([
{
GATE: () => $.LA(1).startOffset + 1 === $.LA(2).startOffset,
ALT: () => {
$.CONSUME(t.Less);
$.CONSUME2(t.Less);
}
},
{
GATE: () => $.LA(1).startOffset + 1 === $.LA(2).startOffset,
ALT: () => {
$.CONSUME(t.Greater);
$.CONSUME2(t.Greater);
$.OPTION({
GATE: () =>
$.LA(0).startOffset + 1 === $.LA(1).startOffset,
DEF: () => $.CONSUME3(t.Greater)
});
}
}
]);
$.SUBRULE2($.unaryExpression);
}
},
{
ALT: () => {
$.CONSUME(t.BinaryOperator);
$.SUBRULE3($.unaryExpression);
}
}
],
IGNORE_AMBIGUITIES: true // the ambiguity between 1 and 4 options is resolved by the order (instanceOf is first)
});
});
});
$.RULE("unaryExpression", () => {
$.MANY(() => {
$.CONSUME(t.UnaryPrefixOperator);
});
$.SUBRULE($.primary);
$.MANY2(() => {
$.CONSUME(t.UnarySuffixOperator);
});
});
$.RULE("unaryExpressionNotPlusMinus", () => {
$.MANY(() => {
$.CONSUME(t.UnaryPrefixOperatorNotPlusMinus);
});
$.SUBRULE($.primary);
$.MANY2(() => {
$.CONSUME(t.UnarySuffixOperator);
});
});
$.RULE("primary", () => {
$.SUBRULE($.primaryPrefix);
$.MANY(() => {
$.SUBRULE($.primarySuffix);
});
});
$.RULE("primaryPrefix", () => {
let isCastExpression = false;
if (tokenMatcher($.LA(1).tokenType, t.LBrace)) {
isCastExpression = this.BACKTRACK_LOOKAHEAD($.isCastExpression);
}
$.OR([
{ ALT: () => $.SUBRULE($.literal) },
{ ALT: () => $.CONSUME(t.This) },
{ ALT: () => $.CONSUME(t.Void) },
{ ALT: () => $.SUBRULE($.unannPrimitiveTypeWithOptionalDimsSuffix) },
{ ALT: () => $.SUBRULE($.fqnOrRefType) },
{
GATE: () => isCastExpression,
ALT: () => $.SUBRULE($.castExpression)
},
{ ALT: () => $.SUBRULE($.parenthesisExpression) },
{ ALT: () => $.SUBRULE($.newExpression) },
{ ALT: () => $.SUBRULE($.switchStatement) }
]);
});
$.RULE("primarySuffix", () => {
$.OR({
DEF: [
{
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
});
});
// See https://github.com/jhipster/prettier-java/pull/154 to understand
// why fqnOrRefTypePart is split in two rules (First and Rest)
$.RULE("fqnOrRefType", () => {
$.SUBRULE($.fqnOrRefTypePartFirst);
$.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,
DEF: () => {
$.CONSUME(t.Dot);
$.SUBRULE2($.fqnOrRefTypePartRest);
}
});
// in case of an arrayType
$.OPTION({
// it is not enough to check only the opening "[", we must avoid conflict with
// arrayAccessSuffix
GATE: () =>
tokenMatcher($.LA(1).tokenType, t.At) ||
tokenMatcher($.LA(2).tokenType, t.RSquare),
DEF: () => {
$.SUBRULE($.dims);
}
});
});
// TODO: validation:
// 1. "annotation" cannot be mixed with "methodTypeArguments" or "Super".
// 2. "methodTypeArguments" cannot be mixed with "classTypeArguments" or "annotation".
// 3. "Super" cannot be mixed with "classTypeArguments" or "annotation".
// 4. At most one "Super" may be used.
// 5. "Super" may be last or one before last (last may also be first if there is only a single part).
$.RULE("fqnOrRefTypePartRest", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.OPTION(() => $.SUBRULE2($.typeArguments));
$.SUBRULE($.fqnOrRefTypePartCommon);
});
$.RULE("fqnOrRefTypePartCommon", () => {
$.OR([
{ ALT: () => $.CONSUME(t.Identifier) },
{ ALT: () => $.CONSUME(t.Super) }
]);
let isRefTypeInMethodRef = false;
// Performance optimization, only perform this backtracking when a '<' is found
// TODO: performance optimization evaluation: avoid doing this backtracking for every "<" encountered.
// we could do it once (using global state) per "fqnOrRefType"
// We could do it only once for
if (tokenMatcher($.LA(1).tokenType, t.Less)) {
isRefTypeInMethodRef = this.BACKTRACK_LOOKAHEAD($.isRefTypeInMethodRef);
}
$.OPTION2({
// unrestricted typeArguments here would create an ambiguity with "LessThan" operator
// e.g: "var x = a < b;"
// The "<" would be parsed as the beginning of a "typeArguments"
// and we will get an error: "expecting '>' but found: ';'"
GATE: () => isRefTypeInMethodRef,
DEF: () => {
$.SUBRULE3($.typeArguments);
}
});
});
$.RULE("fqnOrRefTypePartFirst", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.SUBRULE($.fqnOrRefTypePartCommon);
});
$.RULE("parenthesisExpression", () => {
$.CONSUME(t.LBrace);
$.SUBRULE($.expression);
$.CONSUME(t.RBrace);
});
$.RULE("castExpression", () => {
$.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($.referenceTypeCastExpression) }
]);
});
$.RULE("primitiveCastExpression", () => {
$.CONSUME(t.LBrace);
$.SUBRULE($.primitiveType);
$.CONSUME(t.RBrace);
$.SUBRULE($.unaryExpression);
});
$.RULE("referenceTypeCastExpression", () => {
$.CONSUME(t.LBrace);
$.SUBRULE($.referenceType);
$.MANY(() => {
$.SUBRULE($.additionalBound);
});
$.CONSUME(t.RBrace);
$.OR([
{
GATE: () => this.BACKTRACK_LOOKAHEAD($.isLambdaExpression),
ALT: () => $.SUBRULE($.lambdaExpression)
},
{ ALT: () => $.SUBRULE($.unaryExpressionNotPlusMinus) }
]);
});
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)
}
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-UnqualifiedClassInstanceCreationExpression
$.RULE("unqualifiedClassInstanceCreationExpression", () => {
$.CONSUME(t.New);
$.OPTION(() => {
$.SUBRULE($.typeArguments);
});
$.SUBRULE($.classOrInterfaceTypeToInstantiate);
$.CONSUME(t.LBrace);
$.OPTION2(() => {
$.SUBRULE($.argumentList);
});
$.CONSUME(t.RBrace);
$.OPTION3(() => {
$.SUBRULE($.classBody);
});
});
$.RULE("classOrInterfaceTypeToInstantiate", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.CONSUME(t.Identifier);
$.MANY2(() => {
$.CONSUME(t.Dot);
$.MANY3(() => {
$.SUBRULE2($.annotation);
});
$.CONSUME2(t.Identifier);
});
$.OPTION(() => {
$.SUBRULE($.typeArgumentsOrDiamond);
});
});
$.RULE("typeArgumentsOrDiamond", () => {
$.OR({
DEF: [
{ ALT: () => $.SUBRULE($.diamond) },
{ ALT: () => $.SUBRULE($.typeArguments) }
],
MAX_LOOKAHEAD: 2
});
});
$.RULE("diamond", () => {
$.CONSUME(t.Less);
$.CONSUME(t.Greater);
});
$.RULE("methodInvocationSuffix", () => {
$.CONSUME(t.LBrace);
$.OPTION2(() => {
$.SUBRULE($.argumentList);
});
$.CONSUME(t.RBrace);
});
$.RULE("argumentList", () => {
$.SUBRULE($.expression);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.expression);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-15.10.1
$.RULE("arrayCreationExpression", () => {
$.CONSUME(t.New);
$.OR([
{
GATE: $.BACKTRACK($.primitiveType),
ALT: () => $.SUBRULE($.primitiveType)
},
{ ALT: () => $.SUBRULE($.classOrInterfaceType) }
]);
$.OR2([
{
GATE: $.BACKTRACK($.arrayCreationDefaultInitSuffix),
ALT: () => $.SUBRULE($.arrayCreationDefaultInitSuffix)
},
{ ALT: () => $.SUBRULE($.arrayCreationExplicitInitSuffix) }
]);
});
$.RULE("arrayCreationDefaultInitSuffix", () => {
$.SUBRULE($.dimExprs);
$.OPTION(() => {
$.SUBRULE($.dims);
});
});
$.RULE("arrayCreationExplicitInitSuffix", () => {
$.SUBRULE($.dims);
$.SUBRULE($.arrayInitializer);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-DimExprs
$.RULE("dimExprs", () => {
$.SUBRULE($.dimExpr);
$.MANY({
// The GATE is to distinguish DimExpr from Dims :
// the only difference between these two is the presence of an expression in the DimExpr
// Example: If the GATE is not present double[3][] won't be parsed as the parser will try to parse "[]"
// as a dimExpr instead of a dims
GATE: () => tokenMatcher($.LA(2).tokenType, t.RSquare) === false,
DEF: () => $.SUBRULE2($.dimExpr)
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-DimExpr
$.RULE("dimExpr", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.CONSUME(t.LSquare);
$.SUBRULE($.expression);
$.CONSUME(t.RSquare);
});
$.RULE("classLiteralSuffix", () => {
$.MANY(() => {
$.CONSUME(t.LSquare);
$.CONSUME(t.RSquare);
});
$.CONSUME(t.Dot);
$.CONSUME(t.Class);
});
$.RULE("arrayAccessSuffix", () => {
$.CONSUME(t.LSquare);
$.SUBRULE($.expression);
$.CONSUME(t.RSquare);
});
$.RULE("methodReferenceSuffix", () => {
$.CONSUME(t.ColonColon);
$.OPTION(() => {
$.SUBRULE($.typeArguments);
});
$.OR([
{ ALT: () => $.CONSUME(t.Identifier) },
// TODO: a constructor method reference ("new") can only be used
// in specific contexts, but perhaps this verification is best left
// for a semantic analysis phase
{ ALT: () => $.CONSUME(t.New) }
]);
});
$.RULE("pattern", () => {
$.SUBRULE($.typePattern);
});
$.RULE("typePattern", () => {
$.SUBRULE($.localVariableDeclaration);
});
// 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(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", () => {
let result = undefined;
$.SUBRULE($.typeArguments);
// arrayType
const hasDims = $.OPTION(() => {
$.SUBRULE($.dims);
});
const firstTokTypeAfterTypeArgs = this.LA(1).tokenType;
if (tokenMatcher(firstTokTypeAfterTypeArgs, t.ColonColon)) {
result = true;
}
// we must be at the end of a "referenceType" if "dims" were encountered
// So there is not point to check farther
else if (hasDims) {
result = false;
}
// in the middle of a "classReferenceType"
$.OPTION2(() => {
$.CONSUME(t.Dot);
$.SUBRULE($.classOrInterfaceType);
});
if (result !== undefined) {
return result;
}
const firstTokTypeAfterRefType = this.LA(1).tokenType;
return tokenMatcher(firstTokTypeAfterRefType, t.ColonColon);
});
}
function computeFirstForUnaryExpressionNotPlusMinus() {
const firstUnaryExpressionNotPlusMinus = this.computeContentAssist(
"unaryExpressionNotPlusMinus",
[]
);
const nextTokTypes = firstUnaryExpressionNotPlusMinus.map(
x => x.nextTokenType
);
// uniq
return nextTokTypes.filter((v, i, a) => a.indexOf(v) === i);
}
module.exports = {
defineRules,
computeFirstForUnaryExpressionNotPlusMinus
};

507
node_modules/java-parser/src/productions/interfaces.js generated vendored Normal file
View File

@@ -0,0 +1,507 @@
"use strict";
const { tokenMatcher } = require("chevrotain");
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
});
$.OR([
{ ALT: () => $.SUBRULE($.normalInterfaceDeclaration) },
{ ALT: () => $.SUBRULE($.annotationTypeDeclaration) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-NormalInterfaceDeclaration
$.RULE("normalInterfaceDeclaration", () => {
// Spec Deviation: The "interfaceModifier" prefix was extracted to the "interfaceDeclaration"
$.CONSUME(t.Interface);
$.SUBRULE($.typeIdentifier);
$.OPTION(() => {
$.SUBRULE($.typeParameters);
});
$.OPTION2(() => {
$.SUBRULE($.extendsInterfaces);
});
$.OPTION3(() => {
$.SUBRULE($.interfacePermits);
});
$.SUBRULE($.interfaceBody);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-InterfaceModifier
$.RULE("interfaceModifier", () => {
$.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) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-InterfaceExtends
$.RULE("extendsInterfaces", () => {
$.CONSUME(t.Extends);
$.SUBRULE($.interfaceTypeList);
});
// https://docs.oracle.com/javase/specs/jls/se16/preview/specs/sealed-classes-jls.html
$.RULE("interfacePermits", () => {
$.CONSUME(t.Permits);
$.SUBRULE($.typeName);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.typeName);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-InterfaceBody
$.RULE("interfaceBody", () => {
$.CONSUME(t.LCurly);
$.MANY(() => {
$.SUBRULE($.interfaceMemberDeclaration);
});
$.CONSUME(t.RCurly);
});
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)
}
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-ConstantDeclaration
$.RULE("constantDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.constantModifier);
});
$.SUBRULE($.unannType);
$.SUBRULE($.variableDeclaratorList);
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-ConstantModifier
$.RULE("constantModifier", () => {
$.OR([
{ ALT: () => $.SUBRULE($.annotation) },
{ ALT: () => $.CONSUME(t.Public) },
{ ALT: () => $.CONSUME(t.Static) },
{ ALT: () => $.CONSUME(t.Final) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-InterfaceMethodDeclaration
$.RULE("interfaceMethodDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.interfaceMethodModifier);
});
$.SUBRULE($.methodHeader);
$.SUBRULE($.methodBody);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-InterfaceMethodModifier
$.RULE("interfaceMethodModifier", () => {
$.OR([
{ ALT: () => $.SUBRULE($.annotation) },
{ ALT: () => $.CONSUME(t.Public) },
{ ALT: () => $.CONSUME(t.Private) },
{ ALT: () => $.CONSUME(t.Abstract) },
{ ALT: () => $.CONSUME(t.Default) },
{ ALT: () => $.CONSUME(t.Static) },
{ ALT: () => $.CONSUME(t.Strictfp) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-AnnotationTypeDeclaration
$.RULE("annotationTypeDeclaration", () => {
// Spec Deviation: The "interfaceModifier" prefix was extracted to the "interfaceDeclaration"
$.CONSUME(t.At);
$.CONSUME(t.Interface);
$.SUBRULE($.typeIdentifier);
$.SUBRULE($.annotationTypeBody);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-AnnotationTypeBody
$.RULE("annotationTypeBody", () => {
$.CONSUME(t.LCurly);
$.MANY(() => {
$.SUBRULE($.annotationTypeMemberDeclaration);
});
$.CONSUME(t.RCurly);
});
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)
}
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-AnnotationTypeElementDeclaration
$.RULE("annotationTypeElementDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.annotationTypeElementModifier);
});
$.SUBRULE($.unannType);
$.CONSUME(t.Identifier);
$.CONSUME(t.LBrace);
$.CONSUME(t.RBrace);
$.OPTION(() => {
$.SUBRULE($.dims);
});
$.OPTION2(() => {
$.SUBRULE($.defaultValue);
});
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-AnnotationTypeElementModifier
$.RULE("annotationTypeElementModifier", () => {
$.OR([
{ ALT: () => $.SUBRULE($.annotation) },
{ ALT: () => $.CONSUME(t.Public) },
{ ALT: () => $.CONSUME(t.Abstract) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-DefaultValue
$.RULE("defaultValue", () => {
$.CONSUME(t.Default);
$.SUBRULE($.elementValue);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-Annotation
$.RULE("annotation", () => {
// Spec Deviation: The common prefix for all three annotation types was extracted to this rule.
// This was done to avoid the use of backtracking for performance reasons.
$.CONSUME(t.At);
$.SUBRULE($.typeName);
// If this optional grammar was not invoked we have a markerAnnotation
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-MarkerAnnotation
$.OPTION(() => {
$.CONSUME(t.LBrace);
$.OR({
DEF: [
// normal annotation - https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-NormalAnnotation
{ ALT: () => $.SUBRULE($.elementValuePairList) },
// Single Element Annotation - https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-SingleElementAnnotation
{
ALT: () => $.SUBRULE($.elementValue)
},
{
ALT: () => {
/* empty normal annotation contents */
}
}
],
IGNORE_AMBIGUITIES: true,
MAX_LOOKAHEAD: 2
});
$.CONSUME(t.RBrace);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-ElementValuePairList
$.RULE("elementValuePairList", () => {
$.SUBRULE($.elementValuePair);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.elementValuePair);
});
});
$.RULE("elementValuePair", () => {
$.CONSUME(t.Identifier);
$.CONSUME(t.Equals);
$.SUBRULE($.elementValue);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-ElementValue
$.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($.elementValueArrayInitializer) },
{
GATE: () => isSimpleElementValueAnnotation === true,
ALT: () => $.SUBRULE($.annotation)
}
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-ElementValueArrayInitializer
$.RULE("elementValueArrayInitializer", () => {
$.CONSUME(t.LCurly);
$.OPTION(() => {
$.SUBRULE($.elementValueList);
});
$.OPTION2(() => {
$.CONSUME(t.Comma);
});
$.CONSUME(t.RCurly);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-ElementValueList
$.RULE("elementValueList", () => {
$.SUBRULE($.elementValue);
$.MANY({
GATE: () => tokenMatcher($.LA(2).tokenType, t.RCurly) === false,
DEF: () => {
$.CONSUME(t.Comma);
$.SUBRULE2($.elementValue);
}
});
});
// ------------------------------------
// 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.Static) },
{ ALT: () => $.CONSUME(t.Final) },
{ ALT: () => $.CONSUME(t.Abstract) },
{ ALT: () => $.CONSUME(t.Default) },
{ ALT: () => $.CONSUME(t.Strictfp) }
]);
}
});
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
};

View File

@@ -0,0 +1,42 @@
"use strict";
function defineRules($, t) {
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-Literal
$.RULE("literal", () => {
$.OR([
{ ALT: () => $.SUBRULE($.integerLiteral) },
{ ALT: () => $.SUBRULE($.floatingPointLiteral) },
{ ALT: () => $.SUBRULE($.booleanLiteral) },
{ ALT: () => $.CONSUME(t.CharLiteral) },
{ ALT: () => $.CONSUME(t.TextBlock) },
{ ALT: () => $.CONSUME(t.StringLiteral) },
{ ALT: () => $.CONSUME(t.Null) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-IntegerLiteral
$.RULE("integerLiteral", () => {
$.OR([
{ ALT: () => $.CONSUME(t.DecimalLiteral) },
{ ALT: () => $.CONSUME(t.HexLiteral) },
{ ALT: () => $.CONSUME(t.OctalLiteral) },
{ ALT: () => $.CONSUME(t.BinaryLiteral) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-FloatingPointLiteral
$.RULE("floatingPointLiteral", () => {
$.OR([
{ ALT: () => $.CONSUME(t.FloatLiteral) },
{ ALT: () => $.CONSUME(t.HexFloatLiteral) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-BooleanLiteral
$.RULE("booleanLiteral", () => {
$.OR([{ ALT: () => $.CONSUME(t.True) }, { ALT: () => $.CONSUME(t.False) }]);
});
}
module.exports = {
defineRules
};

86
node_modules/java-parser/src/productions/names.js generated vendored Normal file
View File

@@ -0,0 +1,86 @@
"use strict";
const { tokenMatcher } = require("chevrotain");
function defineRules($, t) {
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-ModuleName
$.RULE("moduleName", () => {
$.CONSUME(t.Identifier);
$.MANY(() => {
$.CONSUME(t.Dot);
$.CONSUME2(t.Identifier);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-PackageName
$.RULE("packageName", () => {
$.CONSUME(t.Identifier);
$.MANY(() => {
$.CONSUME(t.Dot);
$.CONSUME2(t.Identifier);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-TypeName
$.RULE("typeName", () => {
// Spec Deviation: The last Identifier in a "typeName" may not be be "var"
// But the parser does not check for that.
// TODO: post parsing semantic check: last "Identifier" in a "typeName"
// cannot be the "var" keyword
// TODO: option 2 implement "Not Var" Ident using token categories?
$.CONSUME(t.Identifier);
$.MANY(() => {
$.CONSUME(t.Dot);
$.CONSUME2(t.Identifier);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-ExpressionName
$.RULE("expressionName", () => {
// Spec Deviation: in-lined "ambiguousName" to be LL(K)
$.CONSUME(t.Identifier);
$.MANY({
// expressionName could be called by "qualifiedExplicitConstructorInvocation"
// in that case it may be followed by ".super" so we need to look two tokens
// ahead.
GATE: () => tokenMatcher(this.LA(2).tokenType, t.Identifier),
DEF: () => {
$.CONSUME(t.Dot);
$.CONSUME2(t.Identifier);
}
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-MethodName
$.RULE("methodName", () => {
$.CONSUME(t.Identifier);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-PackageOrTypeName
$.RULE("packageOrTypeName", () => {
$.CONSUME(t.Identifier);
$.MANY({
// In some contexts a "Dot Star" (.*) may appear
// after a "packageOrTypeName", by default Chevrotain will
// only look a single token ahead (Dot) to determine if another iteration
// exists which will cause a parsing error for inputs such as:
// "import a.b.c.*"
GATE: () => tokenMatcher(this.LA(2).tokenType, t.Star) === false,
DEF: () => {
$.CONSUME(t.Dot);
$.CONSUME2(t.Identifier);
}
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-6.html#jls-AmbiguousName
$.RULE("ambiguousName", () => {
$.CONSUME(t.Identifier);
$.MANY(() => {
$.CONSUME(t.Dot);
$.CONSUME2(t.Identifier);
});
});
}
module.exports = {
defineRules
};

View File

@@ -0,0 +1,273 @@
"use strict";
const { isRecognitionException, tokenMatcher, EOF } = require("chevrotain");
function defineRules($, t) {
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#CompilationUnit
$.RULE("compilationUnit", () => {
// custom optimized backtracking lookahead logic
const isModule = $.BACKTRACK_LOOKAHEAD($.isModuleCompilationUnit);
$.OR([
{
GATE: () => isModule === false,
ALT: () => $.SUBRULE($.ordinaryCompilationUnit)
},
{
ALT: () => $.SUBRULE($.modularCompilationUnit)
}
]);
// https://github.com/jhipster/prettier-java/pull/217
$.CONSUME(EOF);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-OrdinaryCompilationUnit
$.RULE("ordinaryCompilationUnit", () => {
$.OPTION({
GATE: $.BACKTRACK($.packageDeclaration),
DEF: () => {
$.SUBRULE($.packageDeclaration);
}
});
$.MANY(() => {
$.SUBRULE3($.importDeclaration);
});
$.MANY2(() => {
$.SUBRULE($.typeDeclaration);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-ModularCompilationUnit
$.RULE("modularCompilationUnit", () => {
$.MANY(() => {
$.SUBRULE($.importDeclaration);
});
$.SUBRULE($.moduleDeclaration);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-PackageDeclaration
$.RULE("packageDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.packageModifier);
});
$.CONSUME(t.Package);
$.CONSUME(t.Identifier);
$.MANY2(() => {
$.CONSUME(t.Dot);
$.CONSUME2(t.Identifier);
});
$.CONSUME2(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-PackageModifier
$.RULE("packageModifier", () => {
$.SUBRULE($.annotation);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-ImportDeclaration
$.RULE("importDeclaration", () => {
// Spec Deviation: The spec defines four different kinds of import declarations.
// Our grammar however combines those into a single rule due to difficulties
// distinguishing between the alternatives due to unbound common prefix.
// TODO: A post parsing step is required to align with the official specs.
// The Identifier "var" is not allowed in all positions and variations of the importDeclaration
$.OR([
{
ALT: () => {
$.CONSUME(t.Import);
$.OPTION(() => {
$.CONSUME(t.Static);
});
$.SUBRULE($.packageOrTypeName);
$.OPTION2(() => {
$.CONSUME(t.Dot);
$.CONSUME(t.Star);
});
$.CONSUME(t.Semicolon);
}
},
// Spec Deviation: The spec do not allow empty statement in between imports.
// However Java compiler consider empty statements valid, we chose
// to support that case, thus deviate from the spec.
// See here: https://github.com/jhipster/prettier-java/pull/158
{
ALT: () => $.SUBRULE($.emptyStatement)
}
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-TypeDeclaration
$.RULE("typeDeclaration", () => {
// TODO: consider extracting the prefix modifiers here to avoid backtracking
const isClassDeclaration = this.BACKTRACK_LOOKAHEAD($.isClassDeclaration);
$.OR([
{
GATE: () => isClassDeclaration,
ALT: () => $.SUBRULE($.classDeclaration)
},
{ ALT: () => $.SUBRULE($.interfaceDeclaration) },
{ ALT: () => $.CONSUME(t.Semicolon) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-ModuleDeclaration
$.RULE("moduleDeclaration", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.OPTION(() => {
$.CONSUME(t.Open);
});
$.CONSUME(t.Module);
$.CONSUME(t.Identifier);
$.MANY2(() => {
$.CONSUME(t.Dot);
$.CONSUME2(t.Identifier);
});
$.CONSUME(t.LCurly);
$.MANY3(() => {
$.SUBRULE($.moduleDirective);
});
$.CONSUME(t.RCurly);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-ModuleDirective
$.RULE("moduleDirective", () => {
// Spec Deviation: Each of the alternatives of "moduleDirective" was extracted
// to its own nonTerminal, to reduce verbosity.
$.OR([
{ ALT: () => $.SUBRULE($.requiresModuleDirective) },
{ ALT: () => $.SUBRULE($.exportsModuleDirective) },
{ ALT: () => $.SUBRULE($.opensModuleDirective) },
{ ALT: () => $.SUBRULE($.usesModuleDirective) },
{ ALT: () => $.SUBRULE($.providesModuleDirective) }
]);
});
$.RULE("requiresModuleDirective", () => {
// Spec Deviation: extracted from "moduleDirective"
$.CONSUME(t.Requires);
$.MANY({
GATE: () => {
/**
* https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-3.9 -
* There is one exception: immediately to the right of the character sequence `requires` in the ModuleDirective production,
* the character sequence `transitive` is tokenized as a keyword unless it is followed by a separator,
* in which case it is tokenized as an identifier.
*/
return (
(tokenMatcher($.LA(1).tokenType, t.Transitive) &&
tokenMatcher($.LA(2).tokenType, t.Separators)) === false
);
},
DEF: () => {
$.SUBRULE($.requiresModifier);
}
});
$.SUBRULE($.moduleName);
$.CONSUME(t.Semicolon);
});
$.RULE("exportsModuleDirective", () => {
// Spec Deviation: extracted from "moduleDirective"
$.CONSUME(t.Exports);
$.SUBRULE($.packageName);
$.OPTION(() => {
$.CONSUME(t.To);
$.SUBRULE($.moduleName);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.moduleName);
});
});
$.CONSUME(t.Semicolon);
});
$.RULE("opensModuleDirective", () => {
// Spec Deviation: extracted from "moduleDirective"
$.CONSUME(t.Opens);
$.SUBRULE($.packageName);
$.OPTION(() => {
$.CONSUME(t.To);
$.SUBRULE($.moduleName);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.moduleName);
});
});
$.CONSUME(t.Semicolon);
});
$.RULE("usesModuleDirective", () => {
// Spec Deviation: extracted from "moduleDirective"
$.CONSUME(t.Uses);
$.SUBRULE($.typeName);
$.CONSUME(t.Semicolon);
});
$.RULE("providesModuleDirective", () => {
// Spec Deviation: extracted from "moduleDirective"
$.CONSUME(t.Provides);
$.SUBRULE($.typeName);
$.CONSUME(t.With);
$.SUBRULE2($.typeName);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE3($.typeName);
});
$.CONSUME(t.Semicolon);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-7.html#jls-RequiresModifier
$.RULE("requiresModifier", () => {
$.OR([
{ ALT: () => $.CONSUME(t.Transitive) },
{ ALT: () => $.CONSUME(t.Static) }
]);
});
$.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
};

View File

@@ -0,0 +1,236 @@
"use strict";
const { tokenMatcher } = require("chevrotain");
function defineRules($, t) {
// ---------------------
// Productions from §4 (Types, Values, and Variables)
// ---------------------
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-PrimitiveType
$.RULE("primitiveType", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.OR([
{ ALT: () => $.SUBRULE($.numericType) },
{ ALT: () => $.CONSUME(t.Boolean) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-NumericType
$.RULE("numericType", () => {
$.OR([
{ ALT: () => $.SUBRULE($.integralType) },
{ ALT: () => $.SUBRULE($.floatingPointType) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-IntegralType
$.RULE("integralType", () => {
$.OR([
{ ALT: () => $.CONSUME(t.Byte) },
{ ALT: () => $.CONSUME(t.Short) },
{ ALT: () => $.CONSUME(t.Int) },
{ ALT: () => $.CONSUME(t.Long) },
{ ALT: () => $.CONSUME(t.Char) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-FloatingPointType
$.RULE("floatingPointType", () => {
$.OR([
{ ALT: () => $.CONSUME(t.Float) },
{ ALT: () => $.CONSUME(t.Double) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-ReferenceType
$.RULE("referenceType", () => {
$.MANY(() => {
// Spec Deviation: by extracting the common "annotation" prefix
// we can avoid backtracking and thus improve performance.
// Note that the annotation prefix is still present inside
// "primitiveType" and "classOrInterfaceType"
$.SUBRULE($.annotation);
});
// Spec Deviation: The array type "dims" suffix was extracted to this rule
// to avoid backtracking for performance reasons.
$.OR({
DEF: [
{
ALT: () => {
$.SUBRULE($.primitiveType);
$.SUBRULE($.dims);
}
},
{
// Spec Deviation: "typeVariable" alternative is missing because
// it is included in "classOrInterfaceType"
ALT: () => {
$.SUBRULE($.classOrInterfaceType);
$.OPTION(() => {
$.SUBRULE2($.dims);
});
}
}
],
IGNORE_AMBIGUITIES: true // annotation prefix was extracted to remove ambiguities
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-ClassOrInterfaceType
$.RULE("classOrInterfaceType", () => {
// Spec Deviation: The spec says: "classType | interfaceType" but "interfaceType"
// is not mentioned in the parser because it is identical to "classType"
// The distinction is **semantic** not syntactic.
$.SUBRULE($.classType);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-ClassType
$.RULE("classType", () => {
// Spec Deviation: Refactored left recursion and alternation to iterations
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.CONSUME(t.Identifier);
$.OPTION(() => {
$.SUBRULE($.typeArguments);
});
$.MANY2(() => {
$.CONSUME(t.Dot);
$.MANY3(() => {
$.SUBRULE2($.annotation);
});
// TODO: Semantic Check: This Identifier cannot be "var"
$.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);
}
});
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-InterfaceType
$.RULE("interfaceType", () => {
$.SUBRULE($.classType);
});
$.RULE("typeVariable", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
// TODO: Semantic Check: This Identifier cannot be "var"
$.CONSUME(t.Identifier);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-Dims
$.RULE("dims", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.CONSUME(t.LSquare);
$.CONSUME(t.RSquare);
$.MANY2({
GATE: () => $.BACKTRACK_LOOKAHEAD($.isDims),
DEF: () => {
$.MANY3(() => {
$.SUBRULE2($.annotation);
});
$.CONSUME2(t.LSquare);
$.CONSUME2(t.RSquare);
}
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-TypeParameter
$.RULE("typeParameter", () => {
$.MANY(() => {
$.SUBRULE($.typeParameterModifier);
});
$.SUBRULE($.typeIdentifier);
$.OPTION(() => {
$.SUBRULE($.typeBound);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-TypeParameterModifier
$.RULE("typeParameterModifier", () => {
$.SUBRULE($.annotation);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-TypeBound
$.RULE("typeBound", () => {
$.CONSUME(t.Extends);
// Spec Deviation: The alternative with "TypeVariable" is not specified
// because it's syntax is included in "classOrInterfaceType"
$.SUBRULE($.classOrInterfaceType);
$.MANY2(() => {
$.SUBRULE($.additionalBound);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-AdditionalBound
$.RULE("additionalBound", () => {
$.CONSUME(t.And);
$.SUBRULE($.interfaceType);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-TypeArguments
$.RULE("typeArguments", () => {
$.CONSUME(t.Less);
$.SUBRULE($.typeArgumentList);
$.CONSUME(t.Greater);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-TypeArgumentList
$.RULE("typeArgumentList", () => {
$.SUBRULE($.typeArgument);
$.MANY(() => {
$.CONSUME(t.Comma);
$.SUBRULE2($.typeArgument);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-TypeArgument
$.RULE("typeArgument", () => {
// TODO: performance: evaluate flipping the order of alternatives
$.OR([
{
GATE: $.BACKTRACK($.referenceType),
ALT: () => $.SUBRULE($.referenceType)
},
{ ALT: () => $.SUBRULE($.wildcard) }
]);
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-Wildcard
$.RULE("wildcard", () => {
$.MANY(() => {
$.SUBRULE($.annotation);
});
$.CONSUME(t.QuestionMark);
$.OPTION(() => {
$.SUBRULE($.wildcardBounds);
});
});
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-4.html#jls-WildcardBounds
$.RULE("wildcardBounds", () => {
// TODO: consider in-lining suffix into the alternatives to match the spec more strongly
$.OR([
{ ALT: () => $.CONSUME(t.Extends) },
{ ALT: () => $.CONSUME(t.Super) }
]);
$.SUBRULE($.referenceType);
});
}
module.exports = {
defineRules
};

536
node_modules/java-parser/src/tokens.js generated vendored Normal file
View File

@@ -0,0 +1,536 @@
"use strict";
const { createToken: createTokenOrg, Lexer } = require("chevrotain");
const camelCase = require("lodash/camelCase");
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 ?"
);
}
function inlineFragments(def) {
let inlinedDef = def;
Object.keys(fragments).forEach(prevFragmentName => {
const prevFragmentDef = fragments[prevFragmentName];
const templateRegExp = new RegExp(`{{${prevFragmentName}}}`, "g");
inlinedDef = inlinedDef.replace(templateRegExp, prevFragmentDef);
});
return inlinedDef;
}
function FRAGMENT(name, def) {
fragments[name] = inlineFragments(def);
}
function MAKE_PATTERN(def, flags) {
const inlinedDef = inlineFragments(def);
return new RegExp(inlinedDef, flags);
}
// The order of fragments definitions is important
FRAGMENT("Digits", "[0-9]([0-9_]*[0-9])?");
FRAGMENT("ExponentPart", "[eE][+-]?{{Digits}}");
FRAGMENT("HexDigit", "[0-9a-fA-F]");
FRAGMENT("HexDigits", "{{HexDigit}}(({{HexDigit}}|'_')*{{HexDigit}})?");
FRAGMENT("FloatTypeSuffix", "[fFdD]");
FRAGMENT("LineTerminator", "(\\x0A|(\\x0D(\\x0A)?))");
FRAGMENT("UnicodeMarker", "uu*");
FRAGMENT("UnicodeEscape", "\\\\{{UnicodeMarker}}{{HexDigit}}{4}");
FRAGMENT("RawInputCharacter", "\\\\{{UnicodeMarker}}[0-9a-fA-F]{4}");
FRAGMENT("UnicodeInputCharacter", "({{UnicodeEscape}}|{{RawInputCharacter}})");
FRAGMENT("OctalDigit", "[0-7]");
FRAGMENT("ZeroToThree", "[0-3]");
FRAGMENT(
"OctalEscape",
"\\\\({{OctalDigit}}|{{ZeroToThree}}?{{OctalDigit}}{2})"
);
FRAGMENT("EscapeSequence", "\\\\[btnfr\"'\\\\]|{{OctalEscape}}");
// Not using InputCharacter terminology there because CR and LF are already captured in EscapeSequence
FRAGMENT(
"StringCharacter",
"(?:(?:{{EscapeSequence}})|{{UnicodeInputCharacter}})"
);
function matchJavaIdentifier(text, startOffset) {
let endOffset = startOffset;
let charCode = text.codePointAt(endOffset);
// We verifiy if the first character is from one of these categories
// Corresponds to the isJavaIdentifierStart function from Java
if (chars.firstIdentChar.has(charCode)) {
endOffset++;
// If we encounter a surrogate pair (something that is beyond 65535/FFFF)
// We skip another offset because a surrogate pair is of length 2.
if (charCode > 65535) {
endOffset++;
}
charCode = text.codePointAt(endOffset);
}
// We verify if the remaining characters is from one of these categories
// Corresponds to the isJavaIdentifierPart function from Java
while (chars.restIdentChar.has(charCode)) {
endOffset++;
// See above.
if (charCode > 65535) {
endOffset++;
}
charCode = text.codePointAt(endOffset);
}
// No match, must return null to conform with the RegExp.prototype.exec signature
if (endOffset === startOffset) {
return null;
}
const matchedString = text.substring(startOffset, endOffset);
// according to the RegExp.prototype.exec API the first item in the returned array must be the whole matched string.
return [matchedString];
}
const Identifier = createTokenOrg({
name: "Identifier",
pattern: { exec: matchJavaIdentifier },
line_breaks: false,
start_chars_hint: Array.from(chars.firstIdentChar, x =>
String.fromCharCode(x)
)
});
const allTokens = [];
const tokenDictionary = {};
function createToken(options) {
// TODO create a test to check all the tokenbs have a label defined
if (!options.label) {
// simple token (e.g operator)
if (typeof options.pattern === "string") {
options.label = `'${options.pattern}'`;
}
// Complex token (e.g literal)
else if (options.pattern instanceof RegExp) {
options.label = `'${options.name}'`;
}
}
const newTokenType = createTokenOrg(options);
allTokens.push(newTokenType);
tokenDictionary[options.name] = newTokenType;
return newTokenType;
}
function createKeywordLikeToken(options) {
// A keyword 'like' token uses the "longer_alt" config option
// to resolve ambiguities, see: http://sap.github.io/chevrotain/docs/features/token_alternative_matches.html
options.longer_alt = Identifier;
return createToken(options);
}
// Token Categories
// Used a Token Category to mark all restricted keywords.
// This could be used in syntax highlights implementation.
const RestrictedKeyword = createToken({
name: "RestrictedKeyword",
pattern: Lexer.NA
});
// Used a Token Category to mark all keywords.
// This could be used in syntax highlights implementation.
const Keyword = createToken({
name: "Keyword",
pattern: Lexer.NA
});
const AssignmentOperator = createToken({
name: "AssignmentOperator",
pattern: Lexer.NA
});
const BinaryOperator = createToken({
name: "BinaryOperator",
pattern: Lexer.NA
});
const UnaryPrefixOperator = createToken({
name: "UnaryPrefixOperator",
pattern: Lexer.NA
});
const UnaryPrefixOperatorNotPlusMinus = createToken({
name: "UnaryPrefixOperatorNotPlusMinus",
pattern: Lexer.NA
});
const UnarySuffixOperator = createToken({
name: "UnarySuffixOperator",
pattern: Lexer.NA
});
// https://docs.oracle.com/javase/specs/jls/se11/html/jls-3.html#jls-3.11
const Separators = createToken({
name: "Separators",
pattern: Lexer.NA
});
// https://docs.oracle.com/javase/specs/jls/se11/html/jls-3.html#jls-3.6
// Note [\\x09\\x20\\x0C] is equivalent to [\\t\\x20\\f] and that \\x20 represents
// space character
createToken({
name: "WhiteSpace",
pattern: MAKE_PATTERN("[\\x09\\x20\\x0C]|{{LineTerminator}}"),
group: Lexer.SKIPPED
});
createToken({
name: "LineComment",
pattern: /\/\/[^\n\r]*/,
group: "comments"
});
createToken({
name: "TraditionalComment",
pattern: /\/\*([^*]|\*(?!\/))*\*\//,
group: "comments"
});
createToken({ name: "BinaryLiteral", pattern: /0[bB][01]([01_]*[01])?[lL]?/ });
createToken({
name: "FloatLiteral",
pattern: MAKE_PATTERN(
"{{Digits}}\\.({{Digits}})?({{ExponentPart}})?({{FloatTypeSuffix}})?|" +
"\\.{{Digits}}({{ExponentPart}})?({{FloatTypeSuffix}})?|" +
"{{Digits}}{{ExponentPart}}({{FloatTypeSuffix}})?|" +
"{{Digits}}({{ExponentPart}})?{{FloatTypeSuffix}}"
)
});
createToken({ name: "OctalLiteral", pattern: /0_*[0-7]([0-7_]*[0-7])?[lL]?/ });
createToken({
name: "HexFloatLiteral",
pattern: MAKE_PATTERN(
"0[xX]({{HexDigits}}\\.?|({{HexDigits}})?\\.{{HexDigits}})[pP][+-]?{{Digits}}[fFdD]?"
)
});
createToken({
name: "HexLiteral",
pattern: /0[xX][0-9a-fA-F]([0-9a-fA-F_]*[0-9a-fA-F])?[lL]?/
});
createToken({
name: "DecimalLiteral",
pattern: MAKE_PATTERN("(0|[1-9](_+{{Digits}}|({{Digits}})?))[lL]?")
});
// https://docs.oracle.com/javase/specs/jls/se11/html/jls-3.html#jls-3.10.4
createToken({
name: "CharLiteral",
// Not using SingleCharacter Terminology because ' and \ are captured in EscapeSequence
pattern: MAKE_PATTERN(
"'(?:[^\\\\']|(?:(?:{{EscapeSequence}})|{{UnicodeInputCharacter}}))'"
)
});
createToken({
name: "TextBlock",
pattern: /"""\s*\n(\\"|\s|.)*?"""/
});
createToken({
name: "StringLiteral",
pattern: MAKE_PATTERN('"(?:[^\\\\"]|{{StringCharacter}})*"')
});
// https://docs.oracle.com/javase/specs/jls/se11/html/jls-3.html#jls-3.9
// TODO: how to handle the special rule (see spec above) for "requires" and "transitive"
const restrictedKeywords = [
"open",
"module",
"requires",
"transitive",
"exports",
"opens",
"to",
"uses",
"provides",
"with",
"sealed",
"non-sealed",
"permits"
];
// By sorting the keywords in descending order we avoid ambiguities
// of common prefixes.
sortDescLength(restrictedKeywords).forEach(word => {
createKeywordLikeToken({
name: word[0].toUpperCase() + camelCase(word.substr(1)),
pattern: word,
// restricted keywords can also be used as an Identifiers according to the spec.
// TODO: inspect this causes no ambiguities
categories: [Identifier, RestrictedKeyword]
});
});
// https://docs.oracle.com/javase/specs/jls/se11/html/jls-3.html#jls-3.9
const keywords = [
"abstract",
"continue",
"for",
"new",
"switch",
"assert",
"default",
"if",
"package",
"synchronized",
"boolean",
"do",
"goto",
"private",
"this",
"break",
"double",
"implements",
"protected",
"throw",
"byte",
"else",
"import",
"public",
"throws",
"case",
"enum",
// "instanceof", // special handling for "instanceof" operator below
"return",
"transient",
"catch",
"extends",
"int",
"short",
"try",
"char",
"final",
"interface",
"static",
"void",
"class",
"finally",
"long",
"strictfp",
"volatile",
"const",
"float",
"native",
"super",
"while",
["_", "underscore"]
];
sortDescLength(keywords).forEach(word => {
// For handling symbols keywords (underscore)
const isPair = Array.isArray(word);
const actualName = isPair ? word[1] : word;
const actualPattern = isPair ? word[0] : word;
const options = {
name: actualName[0].toUpperCase() + actualName.substr(1),
pattern: actualPattern,
categories: Keyword
};
if (isPair) {
options.label = `'${actualName}'`;
}
createKeywordLikeToken(options);
});
createKeywordLikeToken({
name: "Instanceof",
pattern: "instanceof",
categories: [Keyword, BinaryOperator]
});
createKeywordLikeToken({
name: "Var",
pattern: "var",
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-3.9
// "var is not a keyword, but rather an identifier with special meaning as the type of a local variable declaration"
categories: Identifier
});
createKeywordLikeToken({
name: "Yield",
pattern: "yield",
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-3.9
// "yield is not a keyword, but rather an identifier with special meaning as the type of a local variable declaration"
categories: Identifier
});
createKeywordLikeToken({
name: "Record",
pattern: "record",
// https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-3.9
// "record is not a keyword, but rather an identifier with special meaning as the type of a local variable declaration"
categories: Identifier
});
createKeywordLikeToken({ name: "True", pattern: "true" });
createKeywordLikeToken({ name: "False", pattern: "false" });
createKeywordLikeToken({ name: "Null", pattern: "null" });
// punctuation and symbols
createToken({ name: "At", pattern: "@", categories: [Separators] });
createToken({ name: "Arrow", pattern: "->" });
createToken({ name: "DotDotDot", pattern: "...", categories: [Separators] });
createToken({ name: "Dot", pattern: ".", categories: [Separators] });
createToken({ name: "Comma", pattern: ",", categories: [Separators] });
createToken({ name: "Semicolon", pattern: ";", categories: [Separators] });
createToken({ name: "ColonColon", pattern: "::", categories: [Separators] });
createToken({ name: "Colon", pattern: ":" });
createToken({ name: "QuestionMark", pattern: "?" });
createToken({ name: "LBrace", pattern: "(", categories: [Separators] });
createToken({ name: "RBrace", pattern: ")", categories: [Separators] });
createToken({ name: "LCurly", pattern: "{", categories: [Separators] });
createToken({ name: "RCurly", pattern: "}", categories: [Separators] });
createToken({ name: "LSquare", pattern: "[", categories: [Separators] });
createToken({ name: "RSquare", pattern: "]", categories: [Separators] });
// prefix and suffix operators
// must be defined before "-"
createToken({
name: "MinusMinus",
pattern: "--",
categories: [
UnaryPrefixOperator,
UnarySuffixOperator,
UnaryPrefixOperatorNotPlusMinus
]
});
// must be defined before "+"
createToken({
name: "PlusPlus",
pattern: "++",
categories: [
UnaryPrefixOperator,
UnarySuffixOperator,
UnaryPrefixOperatorNotPlusMinus
]
});
createToken({
name: "Complement",
pattern: "~",
categories: [UnaryPrefixOperator, UnaryPrefixOperatorNotPlusMinus]
});
createToken({
name: "LessEquals",
pattern: "<=",
categories: [BinaryOperator]
});
createToken({
name: "LessLessEquals",
pattern: "<<=",
categories: [AssignmentOperator]
});
createToken({ name: "Less", pattern: "<", categories: [BinaryOperator] });
createToken({
name: "GreaterEquals",
pattern: ">=",
categories: [BinaryOperator]
});
createToken({
name: "GreaterGreaterEquals",
pattern: ">>=",
categories: [AssignmentOperator]
});
createToken({
name: "GreaterGreaterGreaterEquals",
pattern: ">>>=",
categories: [AssignmentOperator]
});
createToken({ name: "Greater", pattern: ">", categories: [BinaryOperator] });
createToken({
name: "EqualsEquals",
pattern: "==",
categories: [BinaryOperator]
});
createToken({
name: "Equals",
pattern: "=",
categories: [BinaryOperator, AssignmentOperator]
});
createToken({
name: "MinusEquals",
pattern: "-=",
categories: [AssignmentOperator]
});
createToken({
name: "Minus",
pattern: "-",
categories: [BinaryOperator, UnaryPrefixOperator]
});
createToken({
name: "PlusEquals",
pattern: "+=",
categories: [AssignmentOperator]
});
createToken({
name: "Plus",
pattern: "+",
categories: [BinaryOperator, UnaryPrefixOperator]
});
createToken({ name: "AndAnd", pattern: "&&", categories: [BinaryOperator] });
createToken({
name: "AndEquals",
pattern: "&=",
categories: [AssignmentOperator]
});
createToken({ name: "And", pattern: "&", categories: [BinaryOperator] });
createToken({
name: "XorEquals",
pattern: "^=",
categories: [AssignmentOperator]
});
createToken({ name: "Xor", pattern: "^", categories: [BinaryOperator] });
createToken({ name: "NotEquals", pattern: "!=", categories: [BinaryOperator] });
createToken({ name: "OrOr", pattern: "||", categories: [BinaryOperator] });
createToken({
name: "OrEquals",
pattern: "|=",
categories: [AssignmentOperator]
});
createToken({ name: "Or", pattern: "|", categories: [BinaryOperator] });
createToken({
name: "MultiplyEquals",
pattern: "*=",
categories: [AssignmentOperator]
});
createToken({ name: "Star", pattern: "*", categories: [BinaryOperator] });
createToken({
name: "DivideEquals",
pattern: "/=",
categories: [AssignmentOperator]
});
createToken({ name: "Divide", pattern: "/", categories: [BinaryOperator] });
createToken({
name: "ModuloEquals",
pattern: "%=",
categories: [AssignmentOperator]
});
createToken({ name: "Modulo", pattern: "%", categories: [BinaryOperator] });
// must be defined after "!="
createToken({
name: "Not",
pattern: "!",
categories: [UnaryPrefixOperator, UnaryPrefixOperatorNotPlusMinus]
});
// Identifier must appear AFTER all the keywords to avoid ambiguities.
// See: https://github.com/SAP/chevrotain/blob/master/examples/lexer/keywords_vs_identifiers/keywords_vs_identifiers.js
allTokens.push(Identifier);
tokenDictionary["Identifier"] = Identifier;
function sortDescLength(arr) {
// sort is not stable, but that will not affect the lexing results.
return arr.sort((a, b) => {
return b.length - a.length;
});
}
module.exports = {
allTokens,
tokens: tokenDictionary
};

1005
node_modules/java-parser/src/unicodesets.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

21
node_modules/java-parser/src/utils.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
"use strict";
/**
* Should Parser / Lexer Validations be skipped?
*
* By default (productive mode) the validations would be skipped to reduce parser initialization time.
* But during development flows (e.g testing/CI) they should be enabled to detect possible issues.
*
* @returns {boolean}
*/
function getSkipValidations() {
return (
(process && // (not every runtime has a global `process` object
process.env &&
process.env["prettier-java-development-mode"] === "enabled") === false
);
}
module.exports = {
getSkipValidations
};