From 4f34bf942bf47b72815f0306463b61bb5fc8ff55 Mon Sep 17 00:00:00 2001 From: Danny van Bruggen Date: Sun, 9 Jul 2017 23:03:32 +0200 Subject: * add workaround for JPMS edge case * correct token type to identifier for funky JPMS keywords in identifier positions --- .../src/main/java/com/github/javaparser/JavaToken.java | 6 +++++- javaparser-core/src/main/javacc/java.jj | 6 +++++- .../github/javaparser/modules/ModuleDeclarationTest.java | 14 +++++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java b/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java index c7b7fdbb4..9193b7f6b 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java +++ b/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java @@ -35,7 +35,7 @@ public class JavaToken { public static final JavaToken INVALID = new JavaToken(); private final Range range; - private final int kind; + private int kind; private final String text; private final Optional previousToken; private Optional nextToken = Optional.empty(); @@ -110,6 +110,10 @@ public class JavaToken { return kind; } + public void setKind(int kind) { + this.kind = kind; + } + public String getText() { return text; } diff --git a/javaparser-core/src/main/javacc/java.jj b/javaparser-core/src/main/javacc/java.jj index 0db6bb467..9b80fcf12 100644 --- a/javaparser-core/src/main/javacc/java.jj +++ b/javaparser-core/src/main/javacc/java.jj @@ -1477,7 +1477,7 @@ String Identifier(): { // Make sure the module info keywords don't interfere with normal Java parsing by matching them as normal identifiers. ( | | | | | | | | | | - ) { ret = token.image; } + ) { ret = token.image; token().setKind(IDENTIFIER);} { return ret; } } @@ -2770,9 +2770,13 @@ ModuleStmt ModuleStmt(): NodeList types=emptyList(); JavaToken begin; ModuleStmt stmt=new ModuleRequiresStmt(); + JavaToken transitiveExceptionalToken; } { ( + LOOKAHEAD( ";") + {begin=token();} {transitiveExceptionalToken=token(); transitiveExceptionalToken.setKind(IDENTIFIER);} ";" {stmt=new ModuleRequiresStmt(range(begin, token()), EnumSet.noneOf(Modifier.class), new Name(range(transitiveExceptionalToken, transitiveExceptionalToken), null, transitiveExceptionalToken.getText(), new NodeList()));} + | {begin=token();} modifiers=Modifiers() name=Name() ";" {stmt=new ModuleRequiresStmt(range(begin, token()), modifiers.modifiers, name);} | {begin=token();} name=Name() [ tmpName=Name() {names.add(tmpName);} ("," tmpName=Name(){names.add(tmpName);} )* ] ";" {stmt=new ModuleExportsStmt(range(begin, token()), name, names);} diff --git a/javaparser-testing/src/test/java/com/github/javaparser/modules/ModuleDeclarationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/modules/ModuleDeclarationTest.java index 7b7dd229b..cc6b0d7b9 100644 --- a/javaparser-testing/src/test/java/com/github/javaparser/modules/ModuleDeclarationTest.java +++ b/javaparser-testing/src/test/java/com/github/javaparser/modules/ModuleDeclarationTest.java @@ -1,6 +1,7 @@ package com.github.javaparser.modules; import com.github.javaparser.JavaParser; +import com.github.javaparser.JavaToken; import com.github.javaparser.ParseStart; import com.github.javaparser.ParserConfiguration; import com.github.javaparser.ast.CompilationUnit; @@ -14,6 +15,7 @@ import com.github.javaparser.ast.validator.Java9Validator; import com.github.javaparser.printer.ConcreteSyntaxModel; import org.junit.Test; +import static com.github.javaparser.GeneratedJavaParserConstants.IDENTIFIER; import static com.github.javaparser.JavaParser.parseClassOrInterfaceType; import static com.github.javaparser.JavaParser.parseName; import static com.github.javaparser.Providers.provider; @@ -30,7 +32,17 @@ public class ModuleDeclarationTest { @Test public void moduleInfoKeywordsAreSeenAsIdentifiers() { - parse("class module { }"); + CompilationUnit cu = parse("class module { }"); + JavaToken moduleToken = cu.getClassByName("module").get().getName().getTokenRange().get().getBegin(); + assertEquals(IDENTIFIER, moduleToken.getKind()); + } + + @Test + public void issue988RequireTransitiveShouldRequireAModuleCalledTransitive() { + CompilationUnit cu = parse("module X { requires transitive; }"); + ModuleRequiresStmt requiresTransitive = (ModuleRequiresStmt) cu.getModule().get().getModuleStmts().get(0); + assertEquals("transitive", requiresTransitive.getNameAsString()); + assertEquals(IDENTIFIER, requiresTransitive.getName().getTokenRange().get().getBegin().getKind()); } @Test -- cgit v1.2.3 From 159e9e9d2c0ff63676502d4361687325fecc7e28 Mon Sep 17 00:00:00 2001 From: Danny van Bruggen Date: Mon, 10 Jul 2017 20:02:21 +0200 Subject: Add lots of documentation --- .../main/java/com/github/javaparser/JavaToken.java | 10 +++++++- .../javaparser/GeneratedJavaParserSupport.java | 17 ++++++++++--- javaparser-core/src/main/javacc/java.jj | 28 ++++++++++++++++++---- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java b/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java index 9193b7f6b..dc1a3463f 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java +++ b/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java @@ -102,6 +102,14 @@ public class JavaToken { } } + public JavaToken(Range range, int kind, String text, Optional previousToken, Optional nextToken) { + this.range = range; + this.kind = kind; + this.text = text; + this.previousToken = previousToken; + this.nextToken = nextToken; + } + public Range getRange() { return range; } @@ -110,7 +118,7 @@ public class JavaToken { return kind; } - public void setKind(int kind) { + void setKind(int kind) { this.kind = kind; } diff --git a/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserSupport.java b/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserSupport.java index 6fbe2fe70..0a930782b 100644 --- a/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserSupport.java +++ b/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserSupport.java @@ -22,10 +22,12 @@ import static com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes; * Support class for {@link GeneratedJavaParser} */ class GeneratedJavaParserSupport { + /** Quickly create a new NodeList */ static NodeList emptyList() { - return new NodeList(); + return new NodeList<>(); } + /** Add obj to list and return it. Create a new list if list is null */ static NodeList add(NodeList list, T obj) { if (list == null) { list = new NodeList(); @@ -34,6 +36,7 @@ class GeneratedJavaParserSupport { return list; } + /** Add obj to list only when list is not null */ static NodeList addWhenNotNull(NodeList list, T obj) { if (obj == null) { return list; @@ -41,6 +44,7 @@ class GeneratedJavaParserSupport { return add(list, obj); } + /** Add obj to list at position pos */ static NodeList add(int pos, NodeList list, T obj) { if (list == null) { list = new NodeList(); @@ -49,6 +53,7 @@ class GeneratedJavaParserSupport { return list; } + /** Add obj to list */ static List add(List list, T obj) { if (list == null) { list = new LinkedList(); @@ -57,6 +62,7 @@ class GeneratedJavaParserSupport { return list; } + /** Add modifier mod to modifiers */ static void addModifier(GeneratedJavaParser generatedJavaParser, EnumSet modifiers, Modifier mod) { if (modifiers.contains(mod)) { generatedJavaParser.addProblem("Duplicated modifier"); @@ -64,14 +70,17 @@ class GeneratedJavaParserSupport { modifiers.add(mod); } + /** Return a TokenRange spanning from begin to end */ static TokenRange range(JavaToken begin, JavaToken end) { return new TokenRange(begin, end); } + /** Return a TokenRange spanning from begin to end */ static TokenRange range(Node begin, Node end) { return new TokenRange(begin.getTokenRange().get().getBegin(), end.getTokenRange().get().getEnd()); } + /** Workaround for rather complex ambiguity that lambda's create */ static Expression generateLambda(GeneratedJavaParser generatedJavaParser, Expression ret, Statement lambdaBody) { if (ret instanceof EnclosedExpr) { Optional inner = ((EnclosedExpr) ret).getInner(); @@ -99,6 +108,7 @@ class GeneratedJavaParserSupport { return ret; } + /** Throws together an ArrayCreationExpr from a lot of pieces */ static ArrayCreationExpr juggleArrayCreation(TokenRange range, List levelRanges, Type type, NodeList dimensions, List> arrayAnnotations, ArrayInitializerExpr arrayInitializerExpr) { NodeList levels = new NodeList(); @@ -108,6 +118,7 @@ class GeneratedJavaParserSupport { return new ArrayCreationExpr(range, type, levels, arrayInitializerExpr); } + /** Throws together a Type, taking care of all the array brackets */ static Type juggleArrayType(Type partialType, List additionalBrackets) { Pair> partialParts = unwrapArrayTypes(partialType); Type elementType = partialParts.a; @@ -115,11 +126,13 @@ class GeneratedJavaParserSupport { return wrapInArrayTypes(elementType, leftMostBrackets, additionalBrackets).clone(); } + /** Create a TokenRange that spans exactly one token */ static TokenRange tokenRange(Token token) { JavaToken javaToken = ((CustomToken) token).javaToken; return new TokenRange(javaToken, javaToken); } + /** Get the token that starts the NodeList l */ static JavaToken nodeListBegin(NodeList l) { if (l.isEmpty()) { return JavaToken.INVALID; @@ -182,7 +195,5 @@ class GeneratedJavaParserSupport { .append(expected.toString()); } return sb.toString(); - } - } diff --git a/javaparser-core/src/main/javacc/java.jj b/javaparser-core/src/main/javacc/java.jj index 9b80fcf12..38273f7e0 100644 --- a/javaparser-core/src/main/javacc/java.jj +++ b/javaparser-core/src/main/javacc/java.jj @@ -68,14 +68,18 @@ import static com.github.javaparser.ast.type.ArrayType.*; *

This class was generated automatically by javacc, do not edit.

*/ final class GeneratedJavaParser { + /* The problems encountered while parsing */ List problems = new ArrayList(); + /* Resets the parser for reuse, gaining a little performance */ void reset(Provider provider) { ReInit(provider); problems = new ArrayList(); token_source.reset(); } + /* Called from within a catch block to skip forward to a known token, + and report the occurred exception as a problem. */ TokenRange recover(int recoveryTokenType, ParseException p) { JavaToken begin = null; if (p.currentToken != null) { @@ -101,8 +105,8 @@ final class GeneratedJavaParser { } /** - * Return the list of tokens that have been encountered while parsing code using - * this parser. + * Return the list of JavaParser specific tokens that have been encountered while + * parsing code using this parser. * * @return a list of tokens */ @@ -110,15 +114,19 @@ final class GeneratedJavaParser { return token_source.getTokens(); } + /* The collection of comments encountered */ public CommentsCollection getCommentsCollection() { return token_source.getCommentsCollection(); } + /* Reports a problem to the user */ void addProblem(String message) { // TODO tokenRange only takes the final token. Need all the tokens. problems.add(new Problem(message, tokenRange(), null)); } + /* Supports a case where >> should be two tokens instead of one, + and keeps track of the JavaParser specific token type for this token */ static final class CustomToken extends Token { int realKind = GeneratedJavaParserConstants.GT; JavaToken javaToken; @@ -132,15 +140,24 @@ final class GeneratedJavaParser { return new CustomToken(kind, image); } } - + + /* Returns the JavaParser specific token type of the last matched token */ private JavaToken token() { return ((CustomToken)token).javaToken; } + /* Returns a tokenRange that spans the last matched token */ private TokenRange tokenRange() { return new TokenRange(token(), token()); } + /* Sets the kind of the last matched token to newKind */ + private void setTokenKind(int newKind) { + token().setKind(newKind); + } + + /* Changes the amount by which the horizontal position is increased when a tab character is encountered. + One by default.*/ public void setTabSize(int size) { jj_input_stream.setTabSize(size); } @@ -1477,7 +1494,7 @@ String Identifier(): { // Make sure the module info keywords don't interfere with normal Java parsing by matching them as normal identifiers. ( | | | | | | | | | | - ) { ret = token.image; token().setKind(IDENTIFIER);} + ) { ret = token.image; setTokenKind(IDENTIFIER);} { return ret; } } @@ -2774,8 +2791,9 @@ ModuleStmt ModuleStmt(): } { ( + // This is a hack for the edge case "requires transitive;" which is supposed to mean "require the module named 'transitive'" LOOKAHEAD( ";") - {begin=token();} {transitiveExceptionalToken=token(); transitiveExceptionalToken.setKind(IDENTIFIER);} ";" {stmt=new ModuleRequiresStmt(range(begin, token()), EnumSet.noneOf(Modifier.class), new Name(range(transitiveExceptionalToken, transitiveExceptionalToken), null, transitiveExceptionalToken.getText(), new NodeList()));} + {begin=token();} {transitiveExceptionalToken=token(); setTokenKind(IDENTIFIER);} ";" {stmt=new ModuleRequiresStmt(range(begin, token()), EnumSet.noneOf(Modifier.class), new Name(range(transitiveExceptionalToken, transitiveExceptionalToken), null, transitiveExceptionalToken.getText(), new NodeList()));} | {begin=token();} modifiers=Modifiers() name=Name() ";" {stmt=new ModuleRequiresStmt(range(begin, token()), modifiers.modifiers, name);} | -- cgit v1.2.3