java-parser
Advanced tools
Comparing version 0.2.0 to 0.3.1
{ | ||
"name": "java-parser", | ||
"version": "0.2.0", | ||
"version": "0.3.1", | ||
"description": "Java Parser in JavaScript", | ||
"main": "src/index.js", | ||
"repository": "https://github.com/jhipster/prettier-java/packages/java-parser", | ||
"license": "MIT", | ||
"repository": "https://github.com/jhipster/prettier-java/tree/master/packages/java-parser", | ||
"license": "Apache-2.0", | ||
"dependencies": { | ||
"chevrotain": "4.1.1" | ||
"chevrotain": "4.7.0" | ||
}, | ||
@@ -16,3 +16,3 @@ "scripts": { | ||
}, | ||
"gitHead": "e4359b29b74611cbd8553a3d806b1209bd54c4c8" | ||
"gitHead": "1a90f422fac6fcf686523485fe67c60756a0eec5" | ||
} |
@@ -17,2 +17,79 @@ /* eslint no-console: 0 */ | ||
branch: "v2.1.0.RELEASE" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/google/guava.git", | ||
branch: "v27.0.1" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/spring-projects/spring-framework.git", | ||
branch: "v5.1.5.RELEASE" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-online", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-microservice", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-gateway", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-oauth2", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-websocket", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-noi18n", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-nocache", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-hazelcast", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-elasticsearch", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-dto", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-couchbase", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-cassandra", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-mongodb", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-gradle", | ||
branch: "master" | ||
}, | ||
{ | ||
repoUrl: "https://github.com/jhipster/jhipster-sample-app-react", | ||
branch: "master" | ||
} | ||
@@ -19,0 +96,0 @@ ]; |
"use strict"; | ||
const JavaLexer = require("./lexer"); | ||
const JavaParser = require("./parser"); | ||
const { | ||
attachComments, | ||
ignoredComments, | ||
attachIgnoreNodes | ||
} = require("./comments"); | ||
// const startTime = new Date().getTime(); | ||
const parser = new JavaParser(); | ||
@@ -10,10 +14,5 @@ const BaseJavaCstVisitor = parser.getBaseCstVisitorConstructor(); | ||
// const endTime = new Date().getTime(); | ||
// const totalTime = endTime - startTime; | ||
// console.log("parse start time (ms): " + totalTime); | ||
function parse(inputText, entryPoint = "compilationUnit") { | ||
// Lex | ||
const lexResult = JavaLexer.tokenize(inputText); | ||
parser.input = lexResult.tokens; | ||
@@ -32,4 +31,14 @@ if (lexResult.errors.length > 0) { | ||
parser.input = lexResult.tokens; | ||
// prettier-ignore support | ||
const ignoreComments = ignoredComments( | ||
lexResult.tokens, | ||
lexResult.groups.comments | ||
); | ||
parser.setIgnoredComments(ignoreComments); | ||
// Automatic CST created when parsing | ||
const cst = parser[entryPoint](); | ||
if (parser.errors.length > 0) { | ||
@@ -49,2 +58,16 @@ const error = parser.errors[0]; | ||
// only comments code support | ||
// https://github.com/jhipster/prettier-java/pull/217 | ||
if (lexResult.tokens.length === 0) { | ||
const EOF = Object.assign({}, cst.children.EOF[0]); | ||
EOF.startOffset = Number.MAX_SAFE_INTEGER; | ||
EOF.endOffset = Number.MAX_SAFE_INTEGER; | ||
cst.children.EOF = [EOF]; | ||
attachComments(cst.children.EOF, lexResult.groups.comments); | ||
} else { | ||
attachComments(lexResult.tokens, lexResult.groups.comments); | ||
} | ||
attachIgnoreNodes(ignoreComments, parser.ignoredNodes); | ||
return cst; | ||
@@ -51,0 +74,0 @@ } |
@@ -13,2 +13,3 @@ "use strict"; | ||
const expressions = require("./productions/expressions"); | ||
const { shouldIgnore } = require("./comments"); | ||
@@ -46,2 +47,14 @@ /** | ||
ignoredIssues: { | ||
binaryExpression: { | ||
OR: true | ||
}, | ||
lambdaParameterType: { | ||
OR: true | ||
}, | ||
annotation: { | ||
OR: true | ||
}, | ||
localVariableType: { | ||
OR: true | ||
}, | ||
annotationTypeMemberDeclaration: { | ||
@@ -123,6 +136,9 @@ OR: true | ||
} | ||
} | ||
}, | ||
nodeLocationTracking: "full" | ||
}); | ||
const $ = this; | ||
this.ignoreNodes = {}; | ||
this.ignoreComments = []; | ||
@@ -132,2 +148,3 @@ // --------------------- | ||
// --------------------- | ||
// TODO: move this rule to the correct file | ||
$.RULE("typeIdentifier", () => { | ||
@@ -157,2 +174,3 @@ // TODO: implement: Identifier but not var in the lexer | ||
super.cstPostNonTerminal(ruleCstResult, ruleName); | ||
shouldIgnore(ruleCstResult, this.ignoredComments, this.ignoredNodes); | ||
} | ||
@@ -180,4 +198,9 @@ } | ||
} | ||
setIgnoredComments(comments) { | ||
this.ignoredNodes = {}; | ||
this.ignoredComments = [...comments]; | ||
} | ||
} | ||
module.exports = JavaParser; |
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
function defineRules($, t) { | ||
@@ -20,3 +23,3 @@ // https://docs.oracle.com/javase/specs/jls/se11/html/jls-10.html#jls-ArrayInitializer | ||
// The optional last "Comma" of an "arrayInitializer" | ||
GATE: () => this.LA(2).tokenType !== t.RCurly, | ||
GATE: () => tokenMatcher(this.LA(2).tokenType, t.RCurly) === false, | ||
DEF: () => { | ||
@@ -23,0 +26,0 @@ $.CONSUME(t.Comma); |
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
// Spec Deviation: The "*NoShortIf" variations were removed as the ambiguity of | ||
@@ -297,2 +299,3 @@ // the dangling else is resolved by attaching an "else" block | ||
}); | ||
$.CONSUME(t.Semicolon); | ||
}); | ||
@@ -306,2 +309,3 @@ | ||
}); | ||
$.CONSUME(t.Semicolon); | ||
}); | ||
@@ -315,2 +319,3 @@ | ||
}); | ||
$.CONSUME(t.Semicolon); | ||
}); | ||
@@ -321,5 +326,4 @@ | ||
$.CONSUME(t.Throw); | ||
$.OPTION(() => { | ||
$.SUBRULE($.expression); | ||
}); | ||
$.SUBRULE($.expression); | ||
$.CONSUME(t.Semicolon); | ||
}); | ||
@@ -427,5 +431,8 @@ | ||
$.SUBRULE($.resource); | ||
$.MANY(() => { | ||
$.CONSUME(t.Semicolon); | ||
$.SUBRULE2($.resource); | ||
$.MANY({ | ||
GATE: () => tokenMatcher($.LA(2).tokenType, t.RBrace) === false, | ||
DEF: () => { | ||
$.CONSUME(t.Semicolon); | ||
$.SUBRULE2($.resource); | ||
} | ||
}); | ||
@@ -432,0 +439,0 @@ }); |
@@ -126,3 +126,4 @@ "use strict"; | ||
{ | ||
GATE: () => nextRuleType === classBodyTypes.constructorDeclaration, | ||
GATE: () => | ||
tokenMatcher(nextRuleType, classBodyTypes.constructorDeclaration), | ||
ALT: () => $.SUBRULE($.constructorDeclaration) | ||
@@ -610,5 +611,13 @@ } | ||
$.SUBRULE($.enumConstant); | ||
$.MANY(() => { | ||
$.CONSUME(t.Comma); | ||
$.SUBRULE2($.enumConstant); | ||
$.MANY({ | ||
GATE: () => { | ||
const nextToken = $.LA(2); | ||
return ( | ||
tokenMatcher(nextToken, t.Identifier) || tokenMatcher(nextToken, t.At) | ||
); | ||
}, | ||
DEF: () => { | ||
$.CONSUME(t.Comma); | ||
$.SUBRULE2($.enumConstant); | ||
} | ||
}); | ||
@@ -625,6 +634,8 @@ }); | ||
$.CONSUME(t.LBrace); | ||
$.SUBRULE($.argumentList); | ||
$.OPTION2(() => { | ||
$.SUBRULE($.argumentList); | ||
}); | ||
$.CONSUME(t.RBrace); | ||
}); | ||
$.OPTION2(() => { | ||
$.OPTION3(() => { | ||
$.SUBRULE($.classBody); | ||
@@ -663,4 +674,4 @@ }); | ||
GATE: () => | ||
($.LA(1).tokenType === t.At && $.LA(2).tokenType === t.Interface) === | ||
false, | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
@@ -680,3 +691,6 @@ $.SUBRULE($.classModifier); | ||
const nextTokenType = this.LA(1).tokenType; | ||
return nextTokenType === t.Class || nextTokenType === t.Enum; | ||
return ( | ||
tokenMatcher(nextTokenType, t.Class) || | ||
tokenMatcher(nextTokenType, t.Enum) | ||
); | ||
}); | ||
@@ -704,4 +718,4 @@ | ||
GATE: () => | ||
($.LA(1).tokenType === t.At && $.LA(2).tokenType === t.Interface) === | ||
false, | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
@@ -716,4 +730,4 @@ // This alternation includes all possible modifiers for all types of "ClassBodyDeclaration" | ||
GATE: () => | ||
($.LA(1).tokenType === t.At && | ||
$.LA(2).tokenType === t.Interface) === false, | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
ALT: () => $.SUBRULE($.annotation) | ||
@@ -738,15 +752,24 @@ }, | ||
nextNextTokenType = this.LA(2).tokenType; | ||
if (nextTokenType === t.Identifier && nextNextTokenType === t.LBrace) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Identifier) && | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
return classBodyTypes.constructorDeclaration; | ||
} | ||
if (nextTokenType === t.Class || nextTokenType === t.Enum) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Class) || | ||
tokenMatcher(nextTokenType, t.Enum) | ||
) { | ||
return classBodyTypes.classDeclaration; | ||
} | ||
if (nextTokenType === t.Interface || nextTokenType === t.At) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Interface) || | ||
tokenMatcher(nextTokenType, t.At) | ||
) { | ||
return classBodyTypes.interfaceDeclaration; | ||
} | ||
if (nextTokenType === t.Void) { | ||
if (tokenMatcher(nextTokenType, t.Void)) { | ||
// method with result type "void" | ||
@@ -757,3 +780,3 @@ return classBodyTypes.methodDeclaration; | ||
// Type Arguments common prefix | ||
if (nextTokenType === t.Less) { | ||
if (tokenMatcher(nextTokenType, t.Less)) { | ||
this.SUBRULE($.typeParameters); | ||
@@ -763,3 +786,6 @@ const nextTokenType = this.LA(1).tokenType; | ||
// "<T> foo(" -> constructor | ||
if (nextTokenType === t.Identifier && nextNextTokenType === t.LBrace) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Identifier) && | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
return classBodyTypes.constructorDeclaration; | ||
@@ -782,3 +808,3 @@ } | ||
tokenMatcher(nextToken, t.Identifier) && | ||
nextNextTokenType === t.LBrace | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
@@ -785,0 +811,0 @@ return classBodyTypes.methodDeclaration; |
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
function defineRules($, t) { | ||
@@ -46,4 +47,5 @@ $.RULE("constantExpression", () => { | ||
return ( | ||
nextTokType === t.Identifier && | ||
(nextNextTokType === t.RBrace || nextNextTokType === t.Comma) | ||
tokenMatcher(nextTokType, t.Identifier) && | ||
(tokenMatcher(nextNextTokType, t.RBrace) || | ||
tokenMatcher(nextNextTokType, t.Comma)) | ||
); | ||
@@ -141,6 +143,8 @@ }, | ||
GATE: () => | ||
$.LA(2).tokenType === t.Less || $.LA(2).tokenType === t.Greater, | ||
tokenMatcher($.LA(2).tokenType, t.Less) || | ||
tokenMatcher($.LA(2).tokenType, t.Greater), | ||
ALT: () => { | ||
$.OR2([ | ||
{ | ||
GATE: () => $.LA(1).startOffset + 1 === $.LA(2).startOffset, | ||
ALT: () => { | ||
@@ -152,7 +156,9 @@ $.CONSUME(t.Less); | ||
{ | ||
GATE: () => $.LA(1).startOffset + 1 === $.LA(2).startOffset, | ||
ALT: () => { | ||
$.CONSUME(t.Greater); | ||
$.CONSUME2(t.Greater); | ||
$.OPTION(() => { | ||
$.CONSUME3(t.Greater); | ||
$.OPTION({ | ||
GATE: () => $.LA(0).startOffset + 1 === $.LA(1).startOffset, | ||
DEF: () => $.CONSUME3(t.Greater) | ||
}); | ||
@@ -204,3 +210,3 @@ } | ||
let isCastExpression = false; | ||
if ($.LA(1).tokenType === t.LBrace) { | ||
if (tokenMatcher($.LA(1).tokenType, t.LBrace)) { | ||
isCastExpression = this.BACKTRACK_LOOKAHEAD($.isCastExpression); | ||
@@ -236,4 +242,10 @@ } | ||
}, | ||
// TODO: this should probably not be preceded by a "dot" | ||
{ ALT: () => $.CONSUME(t.Identifier) } | ||
{ | ||
ALT: () => { | ||
$.OPTION(() => { | ||
$.SUBRULE($.typeArguments); | ||
}); | ||
$.CONSUME(t.Identifier); | ||
} | ||
} | ||
]); | ||
@@ -256,5 +268,5 @@ } | ||
// avoids ambiguity with ".this" and ".new" which are parsed as a primary suffix. | ||
this.LA(2).tokenType !== t.Class && | ||
this.LA(2).tokenType !== t.This && | ||
this.LA(2).tokenType !== t.New, | ||
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: () => { | ||
@@ -270,3 +282,5 @@ $.CONSUME(t.Dot); | ||
// arrayAccessSuffix | ||
GATE: () => $.LA(1).tokenType === t.At || $.LA(2).tokenType === t.RSquare, | ||
GATE: () => | ||
tokenMatcher($.LA(1).tokenType, t.At) || | ||
tokenMatcher($.LA(2).tokenType, t.RSquare), | ||
DEF: () => { | ||
@@ -306,3 +320,3 @@ $.SUBRULE($.dims); | ||
// We could do it only once for | ||
if ($.LA(1).tokenType === t.Less) { | ||
if (tokenMatcher($.LA(1).tokenType, t.Less)) { | ||
isRefTypeInMethodRef = this.BACKTRACK_LOOKAHEAD($.isRefTypeInMethodRef); | ||
@@ -448,2 +462,3 @@ } | ||
// https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.10.1 | ||
$.RULE("arrayCreationExpression", () => { | ||
@@ -480,9 +495,16 @@ $.CONSUME(t.New); | ||
// https://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-DimExprs | ||
$.RULE("dimExprs", () => { | ||
$.SUBRULE($.dimExpr); | ||
$.OPTION(() => { | ||
$.SUBRULE2($.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/se11/html/jls-15.html#jls-DimExpr | ||
$.RULE("dimExpr", () => { | ||
@@ -533,3 +555,3 @@ $.MANY(() => { | ||
// not an array initialization due to the prefix "TypeArguments" | ||
if (firstTokenAfterNew === t.Less) { | ||
if (tokenMatcher(firstTokenAfterNew, t.Less)) { | ||
return newExpressionTypes.unqualifiedClassInstanceCreationExpression; | ||
@@ -547,3 +569,3 @@ } | ||
const firstTokenAfterClassType = this.LA(1).tokenType; | ||
if (firstTokenAfterClassType === t.LBrace) { | ||
if (tokenMatcher(firstTokenAfterClassType, t.LBrace)) { | ||
return newExpressionTypes.unqualifiedClassInstanceCreationExpression; | ||
@@ -567,9 +589,12 @@ } | ||
// no parent lambda "x -> x * 2" | ||
if (firstTokenType === t.Identifier && secondTokenType === t.Arrow) { | ||
if ( | ||
tokenMatcher(firstTokenType, t.Identifier) && | ||
tokenMatcher(secondTokenType, t.Arrow) | ||
) { | ||
return true; | ||
} | ||
// Performance optimizations, fail fast if it is not a LBrace. | ||
else if (firstTokenType === t.LBrace) { | ||
else if (tokenMatcher(firstTokenType, t.LBrace)) { | ||
$.SUBRULE($.lambdaParametersWithBraces); | ||
const followedByArrow = this.LA(1).tokenType === t.Arrow; | ||
const followedByArrow = tokenMatcher(this.LA(1).tokenType, t.Arrow); | ||
return followedByArrow; | ||
@@ -619,4 +644,4 @@ } | ||
return ( | ||
firstForUnaryExpressionNotPlusMinus.find( | ||
tokType => tokType === firstTokTypeAfterRBrace | ||
firstForUnaryExpressionNotPlusMinus.find(tokType => | ||
tokenMatcher(firstTokTypeAfterRBrace, tokType) | ||
) !== undefined | ||
@@ -635,3 +660,3 @@ ); | ||
const firstTokTypeAfterTypeArgs = this.LA(1).tokenType; | ||
if (firstTokTypeAfterTypeArgs === t.ColonColon) { | ||
if (tokenMatcher(firstTokTypeAfterTypeArgs, t.ColonColon)) { | ||
return true; | ||
@@ -652,3 +677,3 @@ } | ||
const firstTokTypeAfterRefType = this.LA(1).tokenType; | ||
return firstTokTypeAfterRefType === t.ColonColon; | ||
return tokenMatcher(firstTokTypeAfterRefType, t.ColonColon); | ||
}); | ||
@@ -655,0 +680,0 @@ } |
@@ -213,2 +213,3 @@ "use strict"; | ||
}); | ||
$.CONSUME(t.Semicolon); | ||
}); | ||
@@ -232,30 +233,26 @@ | ||
// https://docs.oracle.com/javase/specs/jls/se11/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); | ||
$.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/se11/html/jls-9.html#jls-MarkerAnnotation | ||
$.OPTION(() => { | ||
$.CONSUME(t.LBrace); | ||
$.OR([ | ||
// normal annotation - https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-NormalAnnotation | ||
{ ALT: () => $.SUBRULE($.elementValuePairList) }, | ||
// Single Element Annotation - https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-SingleElementAnnotation | ||
{ ALT: () => $.SUBRULE($.elementValue) }, | ||
{ | ||
ALT: () => { | ||
/* empty normal annotation contents */ | ||
} | ||
// If this optional grammar was not invoked we have a markerAnnotation | ||
// https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-MarkerAnnotation | ||
$.OPTION(() => { | ||
$.CONSUME(t.LBrace); | ||
$.OR([ | ||
// normal annotation - https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-NormalAnnotation | ||
{ ALT: () => $.SUBRULE($.elementValuePairList) }, | ||
// Single Element Annotation - https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-SingleElementAnnotation | ||
{ ALT: () => $.SUBRULE($.elementValue) }, | ||
{ | ||
ALT: () => { | ||
/* empty normal annotation contents */ | ||
} | ||
]); | ||
$.CONSUME(t.RBrace); | ||
}); | ||
}, | ||
"annotation" | ||
); | ||
} | ||
]); | ||
$.CONSUME(t.RBrace); | ||
}); | ||
}); | ||
@@ -312,5 +309,8 @@ // https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-ElementValuePairList | ||
$.SUBRULE($.elementValue); | ||
$.MANY(() => { | ||
$.CONSUME(t.Comma); | ||
$.SUBRULE2($.elementValue); | ||
$.MANY({ | ||
GATE: () => tokenMatcher($.LA(2).tokenType, t.RCurly) === false, | ||
DEF: () => { | ||
$.CONSUME(t.Comma); | ||
$.SUBRULE2($.elementValue); | ||
} | ||
}); | ||
@@ -324,3 +324,3 @@ }); | ||
let nextTokenType = this.LA(1).tokenType; | ||
if (nextTokenType === t.Semicolon) { | ||
if (tokenMatcher(nextTokenType, t.Semicolon)) { | ||
return InterfaceBodyTypes.semiColon; | ||
@@ -333,4 +333,4 @@ } | ||
GATE: () => | ||
($.LA(1).tokenType === t.At && $.LA(2).tokenType === t.Interface) === | ||
false, | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
@@ -357,9 +357,18 @@ // This alternation includes all possible modifiers for all types of "interfaceMemberDeclaration" | ||
nextTokenType = this.LA(1).tokenType; | ||
if (nextTokenType === t.Class || nextTokenType === t.Enum) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Class) || | ||
tokenMatcher(nextTokenType, t.Enum) | ||
) { | ||
return InterfaceBodyTypes.classDeclaration; | ||
} | ||
if (nextTokenType === t.Interface || nextTokenType === t.At) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Interface) || | ||
tokenMatcher(nextTokenType, t.At) | ||
) { | ||
return InterfaceBodyTypes.interfaceDeclaration; | ||
} | ||
if (nextTokenType === t.Void || nextTokenType === t.Less) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Void) || | ||
tokenMatcher(nextTokenType, t.Less) | ||
) { | ||
// method with result type "void" | ||
@@ -379,3 +388,3 @@ return InterfaceBodyTypes.interfaceMethodDeclaration; | ||
tokenMatcher(nextToken, t.Identifier) && | ||
nextNextTokenType === t.LBrace | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
@@ -393,3 +402,3 @@ return InterfaceBodyTypes.interfaceMethodDeclaration; | ||
let nextTokenType = this.LA(1).tokenType; | ||
if (nextTokenType === t.Semicolon) { | ||
if (tokenMatcher(nextTokenType, t.Semicolon)) { | ||
return AnnotationBodyTypes.semiColon; | ||
@@ -402,4 +411,4 @@ } | ||
GATE: () => | ||
($.LA(1).tokenType === t.At && $.LA(2).tokenType === t.Interface) === | ||
false, | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
@@ -425,6 +434,12 @@ // This alternation includes all possible modifiers for all types of "annotationTypeMemberDeclaration" | ||
nextTokenType = this.LA(1).tokenType; | ||
if (nextTokenType === t.Class || nextTokenType === t.Enum) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Class) || | ||
tokenMatcher(nextTokenType, t.Enum) | ||
) { | ||
return AnnotationBodyTypes.classDeclaration; | ||
} | ||
if (nextTokenType === t.Interface || nextTokenType === t.At) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Interface) || | ||
tokenMatcher(nextTokenType, t.At) | ||
) { | ||
return AnnotationBodyTypes.interfaceDeclaration; | ||
@@ -441,7 +456,10 @@ } | ||
// "foo(..." --> look like annotationTypeElement start | ||
if (nextTokenType === t.Identifier && nextNextTokenType === t.LBrace) { | ||
if ( | ||
tokenMatcher(nextTokenType, t.Identifier) && | ||
tokenMatcher(nextNextTokenType, t.LBrace) | ||
) { | ||
return AnnotationBodyTypes.annotationTypeElementDeclaration; | ||
} | ||
// a valid constant | ||
if (nextTokenType === t.Identifier) { | ||
if (tokenMatcher(nextTokenType, t.Identifier)) { | ||
return AnnotationBodyTypes.constantDeclaration; | ||
@@ -448,0 +466,0 @@ } |
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
function defineRules($, t) { | ||
@@ -43,3 +44,3 @@ // https://docs.oracle.com/javase/specs/jls/se11/html/jls-6.html#jls-ModuleName | ||
// ahead. | ||
GATE: () => this.LA(2).tokenType === t.Identifier, | ||
GATE: () => tokenMatcher(this.LA(2).tokenType, t.Identifier), | ||
DEF: () => { | ||
@@ -66,3 +67,3 @@ $.CONSUME(t.Dot); | ||
// "import a.b.c.*" | ||
GATE: () => this.LA(2).tokenType !== t.Star, | ||
GATE: () => tokenMatcher(this.LA(2).tokenType, t.Star) === false, | ||
DEF: () => { | ||
@@ -69,0 +70,0 @@ $.CONSUME(t.Dot); |
"use strict"; | ||
const { isRecognitionException } = require("chevrotain"); | ||
const { isRecognitionException, tokenMatcher, EOF } = require("chevrotain"); | ||
@@ -18,2 +18,4 @@ function defineRules($, t) { | ||
]); | ||
// https://github.com/jhipster/prettier-java/pull/217 | ||
$.CONSUME(EOF); | ||
}); | ||
@@ -23,7 +25,10 @@ | ||
$.RULE("ordinaryCompilationUnit", () => { | ||
$.OPTION(() => { | ||
$.SUBRULE($.packageDeclaration); | ||
$.OPTION({ | ||
GATE: $.BACKTRACK($.packageDeclaration), | ||
DEF: () => { | ||
$.SUBRULE($.packageDeclaration); | ||
} | ||
}); | ||
$.MANY(() => { | ||
$.SUBRULE($.importDeclaration); | ||
$.SUBRULE3($.importDeclaration); | ||
}); | ||
@@ -69,12 +74,25 @@ $.MANY2(() => { | ||
// The Identifier "var" is not allowed in all positions and variations of the importDeclaration | ||
$.CONSUME(t.Import); | ||
$.OPTION(() => { | ||
$.CONSUME(t.Static); | ||
}); | ||
$.SUBRULE($.packageOrTypeName); | ||
$.OPTION2(() => { | ||
$.CONSUME(t.Dot); | ||
$.CONSUME(t.Star); | ||
}); | ||
$.CONSUME(t.Semicolon); | ||
$.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) | ||
} | ||
]); | ||
}); | ||
@@ -180,7 +198,8 @@ | ||
$.CONSUME(t.Provides); | ||
$.SUBRULE($.typeName); | ||
$.CONSUME(t.With); | ||
$.SUBRULE($.typeName); | ||
$.SUBRULE2($.typeName); | ||
$.MANY(() => { | ||
$.CONSUME(t.Comma); | ||
$.SUBRULE2($.typeName); | ||
$.SUBRULE3($.typeName); | ||
}); | ||
@@ -201,2 +220,3 @@ $.CONSUME(t.Semicolon); | ||
$.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. | ||
@@ -215,4 +235,4 @@ return false; | ||
GATE: () => | ||
($.LA(1).tokenType === t.At && $.LA(2).tokenType === t.Interface) === | ||
false, | ||
(tokenMatcher($.LA(1).tokenType, t.At) && | ||
tokenMatcher($.LA(2).tokenType, t.Interface)) === false, | ||
DEF: () => { | ||
@@ -233,3 +253,6 @@ $.SUBRULE($.annotation); | ||
const nextTokenType = this.LA(1).tokenType; | ||
return nextTokenType === t.Open || nextTokenType === t.Module; | ||
return ( | ||
tokenMatcher(nextTokenType, t.Open) || | ||
tokenMatcher(nextTokenType, t.Module) | ||
); | ||
}); | ||
@@ -236,0 +259,0 @@ } |
"use strict"; | ||
const { tokenMatcher } = require("chevrotain"); | ||
function defineRules($, t) { | ||
@@ -106,3 +108,3 @@ // --------------------- | ||
// optimized lookahead rule. | ||
GATE: () => $.LA(2).tokenType !== t.Greater, | ||
GATE: () => tokenMatcher($.LA(2).tokenType, t.Greater) === false, | ||
DEF: () => { | ||
@@ -109,0 +111,0 @@ $.SUBRULE2($.typeArguments); |
/* eslint-disable no-unused-vars */ | ||
"use strict"; | ||
const { createToken: createTokenOrg, Lexer } = require("chevrotain"); | ||
const fs = require("fs"); | ||
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 ?" | ||
); | ||
} | ||
@@ -33,8 +41,47 @@ function inlineFragments(def) { | ||
FRAGMENT("FloatTypeSuffix", "[fFdD]"); | ||
FRAGMENT("LineTerminator", "(\\x0A|(\\x0D(\\x0A)?))"); | ||
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", | ||
// TODO: Align with the spec, Consider generating the regExp for Identifier | ||
// as done in Esprima / Acorn | ||
pattern: /[a-zA-Z_\\$][a-zA-Z_\\$0-9]*/ | ||
pattern: { exec: matchJavaIdentifier }, | ||
line_breaks: false, | ||
start_chars_hint: Array.from(chars.firstIdentChar, x => | ||
String.fromCharCode(x) | ||
) | ||
}); | ||
@@ -44,4 +91,5 @@ | ||
const tokenDictionary = {}; | ||
function createToken(options) { | ||
// TODO: create a test to check all the tokens have a label defined | ||
// TODO create a test to check all the tokenbs have a label defined | ||
if (!options.label) { | ||
@@ -110,5 +158,11 @@ // simple token (e.g operator) | ||
// TODO: align with Java Spec | ||
createToken({ name: "WhiteSpace", pattern: /\s+/, group: Lexer.SKIPPED }); | ||
// 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", | ||
@@ -124,7 +178,6 @@ pattern: /\/\/[^\n\r]*/, | ||
createToken({ name: "BinaryLiteral", pattern: /0[bB][01]([01_]*[01])?[lL]?/ }); | ||
createToken({ name: "OctalLiteral", pattern: /0_*[0-7]([0-7_]*[0-7])?[lL]?/ }); | ||
createToken({ | ||
name: "FloatLiteral", | ||
pattern: MAKE_PATTERN( | ||
"{{Digits}}\\.({{Digits}})?({{FloatTypeSuffix}})?|" + | ||
"{{Digits}}\\.({{Digits}})?({{ExponentPart}})?({{FloatTypeSuffix}})?|" + | ||
"\\.{{Digits}}({{ExponentPart}})?({{FloatTypeSuffix}})?|" + | ||
@@ -135,2 +188,3 @@ "{{Digits}}{{ExponentPart}}({{FloatTypeSuffix}})?|" + | ||
}); | ||
createToken({ name: "OctalLiteral", pattern: /0_*[0-7]([0-7_]*[0-7])?[lL]?/ }); | ||
createToken({ | ||
@@ -148,3 +202,3 @@ name: "HexFloatLiteral", | ||
name: "DecimalLiteral", | ||
pattern: MAKE_PATTERN("(0|[1-9](({{Digits}})?|_+{{Digits}}))[lL]?") | ||
pattern: MAKE_PATTERN("(0|[1-9](_+{{Digits}}|({{Digits}})?))[lL]?") | ||
}); | ||
@@ -438,3 +492,2 @@ // https://docs.oracle.com/javase/specs/jls/se11/html/jls-3.html#jls-3.10.4 | ||
} | ||
module.exports = { | ||
@@ -441,0 +494,0 @@ allTokens, |
@@ -13,2 +13,21 @@ "use strict"; | ||
createSampleSpecs("spring-boot"); | ||
createSampleSpecs("spring-framework"); | ||
createSampleSpecs("jhipster"); | ||
createSampleSpecs("jhipster-online"); | ||
createSampleSpecs("jhipster-sample-app"); | ||
createSampleSpecs("jhipster-sample-app-cassandra"); | ||
createSampleSpecs("jhipster-sample-app-couchbase"); | ||
createSampleSpecs("jhipster-sample-app-dto"); | ||
createSampleSpecs("jhipster-sample-app-elasticsearch"); | ||
createSampleSpecs("jhipster-sample-app-gateway"); | ||
createSampleSpecs("jhipster-sample-app-gradle"); | ||
createSampleSpecs("jhipster-sample-app-hazelcast"); | ||
createSampleSpecs("jhipster-sample-app-microservice"); | ||
createSampleSpecs("jhipster-sample-app-mongodb"); | ||
createSampleSpecs("jhipster-sample-app-nocache"); | ||
createSampleSpecs("jhipster-sample-app-noi18n"); | ||
createSampleSpecs("jhipster-sample-app-oauth2"); | ||
createSampleSpecs("jhipster-sample-app-react"); | ||
createSampleSpecs("jhipster-sample-app-websocket"); | ||
createFailingSampleSpec("guava", 4, 0); | ||
}); | ||
@@ -36,1 +55,35 @@ | ||
} | ||
function createFailingSampleSpec(sampleName, failAllowed, timeout) { | ||
context(sampleName + " samples", () => { | ||
const samplesDir = path.resolve(__dirname, "../samples/" + sampleName); | ||
const sampleFiles = klawSync(samplesDir, { nodir: true }); | ||
const javaSampleFiles = sampleFiles.filter(fileDesc => | ||
fileDesc.path.endsWith(".java") | ||
); | ||
if (_.isEmpty(sampleFiles)) { | ||
throw `Missing sample-dir: <${samplesDir}> did you forget to clone the samples?`; | ||
} | ||
const errors = []; | ||
it(`Can Parse ${sampleName} repository`, function() { | ||
if (timeout !== undefined) { | ||
this.timeout(timeout); | ||
} | ||
_.forEach(javaSampleFiles, fileDesc => { | ||
const relativePath = path.relative(__dirname, fileDesc.path); | ||
const sampleText = fs.readFileSync(fileDesc.path, "utf8"); | ||
try { | ||
javaParser.parse(sampleText); | ||
} catch (error) { | ||
errors.push(relativePath); | ||
} | ||
}); | ||
expect(errors.length, `Can not Parse ${errors}`).to.equal(failAllowed); | ||
}); | ||
}); | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
1993160
29
6729
1
7
+ Addedchevrotain@4.7.0(transitive)
+ Addedregexp-to-ast@0.4.0(transitive)
- Removedchevrotain@4.1.1(transitive)
- Removedregexp-to-ast@0.3.5(transitive)
Updatedchevrotain@4.7.0