aboutsummaryrefslogtreecommitdiffstats
path: root/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java
diff options
context:
space:
mode:
Diffstat (limited to 'javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java')
-rw-r--r--javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java369
1 files changed, 369 insertions, 0 deletions
diff --git a/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java b/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java
new file mode 100644
index 000000000..ef0b7efd4
--- /dev/null
+++ b/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java
@@ -0,0 +1,369 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.ArrayCreationLevel;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.comments.CommentsCollection;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.utils.Pair;
+
+import java.util.*;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.EOF;
+import static com.github.javaparser.ast.type.ArrayType.unwrapArrayTypes;
+import static com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * Base class for {@link GeneratedJavaParser}
+ */
+abstract class GeneratedJavaParserBase {
+ //// Interface with the generated code
+ abstract GeneratedJavaParserTokenManager getTokenSource();
+
+ abstract void ReInit(Provider provider);
+
+ /* Returns the JavaParser specific token type of the last matched token */
+ abstract JavaToken token();
+
+ abstract Token getNextToken();
+
+ ////
+
+ /* The problems encountered while parsing */
+ List<Problem> problems = new ArrayList<>();
+ /* Configuration flag whether we store tokens and tokenranges */
+ boolean storeTokens;
+
+ /* Resets the parser for reuse, gaining a little performance */
+ void reset(Provider provider) {
+ ReInit(provider);
+ problems = new ArrayList<>();
+ getTokenSource().reset();
+ }
+
+ /**
+ * Return the list of JavaParser specific tokens that have been encountered while parsing code using this parser.
+ *
+ * @return a list of tokens
+ */
+ public List<JavaToken> getTokens() {
+ return getTokenSource().getTokens();
+ }
+
+ /* The collection of comments encountered */
+ CommentsCollection getCommentsCollection() {
+ return getTokenSource().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));
+ }
+
+ /* Returns a tokenRange that spans the last matched token */
+ TokenRange tokenRange() {
+ if (storeTokens) {
+ return new TokenRange(token(), token());
+ }
+ return null;
+ }
+
+ /**
+ * Return a TokenRange spanning from begin to end
+ */
+ TokenRange range(JavaToken begin, JavaToken end) {
+ if (storeTokens) {
+ return new TokenRange(begin, end);
+ }
+ return null;
+ }
+
+ /**
+ * Return a TokenRange spanning from begin to end
+ */
+ TokenRange range(Node begin, JavaToken end) {
+ if (storeTokens) {
+ return new TokenRange(begin.getTokenRange().get().getBegin(), end);
+ }
+ return null;
+ }
+
+ /**
+ * Return a TokenRange spanning from begin to end
+ */
+ TokenRange range(JavaToken begin, Node end) {
+ if (storeTokens) {
+ return new TokenRange(begin, end.getTokenRange().get().getEnd());
+ }
+ return null;
+ }
+
+ /**
+ * Return a TokenRange spanning from begin to end
+ */
+ TokenRange range(Node begin, Node end) {
+ if (storeTokens) {
+ return new TokenRange(begin.getTokenRange().get().getBegin(), end.getTokenRange().get().getEnd());
+ }
+ return null;
+ }
+
+ /**
+ * @return secondChoice if firstChoice is JavaToken.UNKNOWN, otherwise firstChoice
+ */
+ JavaToken orIfInvalid(JavaToken firstChoice, JavaToken secondChoice) {
+ if (storeTokens) {
+ assertNotNull(firstChoice);
+ assertNotNull(secondChoice);
+ if (firstChoice.valid() || secondChoice.invalid()) {
+ return firstChoice;
+ }
+ return secondChoice;
+ }
+ return null;
+ }
+
+ /**
+ * @return the begin-token secondChoice if firstChoice is JavaToken.UNKNOWN, otherwise firstChoice
+ */
+ JavaToken orIfInvalid(JavaToken firstChoice, Node secondChoice) {
+ if (storeTokens) {
+ return orIfInvalid(firstChoice, secondChoice.getTokenRange().get().getBegin());
+ }
+ return null;
+ }
+
+ /**
+ * Get the token that starts the NodeList l
+ */
+ JavaToken nodeListBegin(NodeList<?> l) {
+ if (!storeTokens || l.isEmpty()) {
+ return JavaToken.INVALID;
+ }
+ return l.get(0).getTokenRange().get().getBegin();
+ }
+
+ /* Sets the kind of the last matched token to newKind */
+ void setTokenKind(int newKind) {
+ token().setKind(newKind);
+ }
+
+ /* Makes the parser keep a list of tokens */
+ void setStoreTokens(boolean storeTokens) {
+ this.storeTokens = storeTokens;
+ getTokenSource().setStoreTokens(storeTokens);
+ }
+
+ /* 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) {
+ begin = token();
+ }
+ Token t;
+ do {
+ t = getNextToken();
+ } while (t.kind != recoveryTokenType && t.kind != EOF);
+
+ JavaToken end = token();
+
+ TokenRange tokenRange = null;
+ if (begin != null && end != null) {
+ tokenRange = range(begin, end);
+ }
+
+ problems.add(new Problem(makeMessageForParseException(p), tokenRange, p));
+ return tokenRange;
+ }
+
+ /**
+ * Quickly create a new NodeList
+ */
+ <T extends Node> NodeList<T> emptyList() {
+ return new NodeList<>();
+ }
+
+ /**
+ * Add obj to list and return it. Create a new list if list is null
+ */
+ <T extends Node> NodeList<T> add(NodeList<T> list, T obj) {
+ if (list == null) {
+ list = new NodeList<>();
+ }
+ list.add(obj);
+ return list;
+ }
+
+ /**
+ * Add obj to list only when list is not null
+ */
+ <T extends Node> NodeList<T> addWhenNotNull(NodeList<T> list, T obj) {
+ if (obj == null) {
+ return list;
+ }
+ return add(list, obj);
+ }
+
+ /**
+ * Add obj to list at position pos
+ */
+ <T extends Node> NodeList<T> prepend(NodeList<T> list, T obj) {
+ if (list == null) {
+ list = new NodeList<>();
+ }
+ list.addFirst(obj);
+ return list;
+ }
+
+ /**
+ * Add obj to list
+ */
+ <T> List<T> add(List<T> list, T obj) {
+ if (list == null) {
+ list = new LinkedList<>();
+ }
+ list.add(obj);
+ return list;
+ }
+
+ /**
+ * Add modifier mod to modifiers
+ */
+ void addModifier(EnumSet<Modifier> modifiers, Modifier mod) {
+ if (modifiers.contains(mod)) {
+ addProblem("Duplicated modifier");
+ }
+ modifiers.add(mod);
+ }
+
+ /**
+ * Propagate expansion of the range on the right to the parent. This is necessary when the right border of the child
+ * is determining the right border of the parent (i.e., the child is the last element of the parent). In this case
+ * when we "enlarge" the child we should enlarge also the parent.
+ */
+ private void propagateRangeGrowthOnRight(Node node, Node endNode) {
+ if (storeTokens) {
+ node.getParentNode().ifPresent(nodeParent -> {
+ boolean isChildOnTheRightBorderOfParent = node.getTokenRange().get().getEnd().equals(nodeParent.getTokenRange().get().getEnd());
+ if (isChildOnTheRightBorderOfParent) {
+ propagateRangeGrowthOnRight(nodeParent, endNode);
+ }
+ });
+ node.setTokenRange(range(node, endNode));
+ }
+ }
+
+ /**
+ * Workaround for rather complex ambiguity that lambda's create
+ */
+ Expression generateLambda(Expression ret, Statement lambdaBody) {
+ if (ret instanceof EnclosedExpr) {
+ Expression inner = ((EnclosedExpr) ret).getInner();
+ SimpleName id = ((NameExpr) inner).getName();
+ NodeList<Parameter> params = add(new NodeList<>(), new Parameter(ret.getTokenRange().orElse(null), EnumSet.noneOf(Modifier.class), new NodeList<>(), new UnknownType(), false, new NodeList<>(), id));
+ ret = new LambdaExpr(range(ret, lambdaBody), params, lambdaBody, true);
+ } else if (ret instanceof NameExpr) {
+ SimpleName id = ((NameExpr) ret).getName();
+ NodeList<Parameter> params = add(new NodeList<>(), new Parameter(ret.getTokenRange().orElse(null), EnumSet.noneOf(Modifier.class), new NodeList<>(), new UnknownType(), false, new NodeList<>(), id));
+ ret = new LambdaExpr(range(ret, lambdaBody), params, lambdaBody, false);
+ } else if (ret instanceof LambdaExpr) {
+ ((LambdaExpr) ret).setBody(lambdaBody);
+ propagateRangeGrowthOnRight(ret, lambdaBody);
+ } else if (ret instanceof CastExpr) {
+ CastExpr castExpr = (CastExpr) ret;
+ Expression inner = generateLambda(castExpr.getExpression(), lambdaBody);
+ castExpr.setExpression(inner);
+ } else {
+ addProblem("Failed to parse lambda expression! Please create an issue at https://github.com/javaparser/javaparser/issues");
+ }
+ return ret;
+ }
+
+ /**
+ * Throws together an ArrayCreationExpr from a lot of pieces
+ */
+ ArrayCreationExpr juggleArrayCreation(TokenRange range, List<TokenRange> levelRanges, Type type, NodeList<Expression> dimensions, List<NodeList<AnnotationExpr>> arrayAnnotations, ArrayInitializerExpr arrayInitializerExpr) {
+ NodeList<ArrayCreationLevel> levels = new NodeList<>();
+
+ for (int i = 0; i < arrayAnnotations.size(); i++) {
+ levels.add(new ArrayCreationLevel(levelRanges.get(i), dimensions.get(i), arrayAnnotations.get(i)));
+ }
+ return new ArrayCreationExpr(range, type, levels, arrayInitializerExpr);
+ }
+
+ /**
+ * Throws together a Type, taking care of all the array brackets
+ */
+ Type juggleArrayType(Type partialType, List<ArrayType.ArrayBracketPair> additionalBrackets) {
+ Pair<Type, List<ArrayType.ArrayBracketPair>> partialParts = unwrapArrayTypes(partialType);
+ Type elementType = partialParts.a;
+ List<ArrayType.ArrayBracketPair> leftMostBrackets = partialParts.b;
+ return wrapInArrayTypes(elementType, leftMostBrackets, additionalBrackets).clone();
+ }
+
+ /**
+ * This is the code from ParseException.initialise, modified to be more horizontal.
+ */
+ private String makeMessageForParseException(ParseException exception) {
+ final StringBuilder sb = new StringBuilder("Parse error. Found ");
+ final StringBuilder expected = new StringBuilder();
+
+ int maxExpectedTokenSequenceLength = 0;
+ TreeSet<String> sortedOptions = new TreeSet<>();
+ for (int i = 0; i < exception.expectedTokenSequences.length; i++) {
+ if (maxExpectedTokenSequenceLength < exception.expectedTokenSequences[i].length) {
+ maxExpectedTokenSequenceLength = exception.expectedTokenSequences[i].length;
+ }
+ for (int j = 0; j < exception.expectedTokenSequences[i].length; j++) {
+ sortedOptions.add(exception.tokenImage[exception.expectedTokenSequences[i][j]]);
+ }
+ }
+
+ for (String option : sortedOptions) {
+ expected.append(" ").append(option);
+ }
+
+ sb.append("");
+
+ Token token = exception.currentToken.next;
+ for (int i = 0; i < maxExpectedTokenSequenceLength; i++) {
+ String tokenText = token.image;
+ String escapedTokenText = ParseException.add_escapes(tokenText);
+ if (i != 0) {
+ sb.append(" ");
+ }
+ if (token.kind == 0) {
+ sb.append(exception.tokenImage[0]);
+ break;
+ }
+ escapedTokenText = "\"" + escapedTokenText + "\"";
+ String image = exception.tokenImage[token.kind];
+ if (image.equals(escapedTokenText)) {
+ sb.append(image);
+ } else {
+ sb.append(" ")
+ .append(escapedTokenText)
+ .append(" ")
+ .append(image);
+ }
+ token = token.next;
+ }
+
+ if (exception.expectedTokenSequences.length != 0) {
+ int numExpectedTokens = exception.expectedTokenSequences.length;
+ sb.append(", expected")
+ .append(numExpectedTokens == 1 ? "" : " one of ")
+ .append(expected.toString());
+ }
+ return sb.toString();
+ }
+}