Skip to content

Commit

Permalink
Prototype of the new parser interface
Browse files Browse the repository at this point in the history
  • Loading branch information
matozoid committed Aug 31, 2016
1 parent 0a1b86d commit 804bed8
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
* @author Júlio Vilmar Gesser
*/
class CommentsInserter {
private boolean doNotAssignCommentsPreceedingEmptyLines = true;
private boolean doNotConsiderAnnotationsAsNodeStartForCodeAttribution = false;

CommentsInserter() {
private final ParserConfiguration configuration;

CommentsInserter(ParserConfiguration configuration) {
this.configuration = configuration;
}

/**
Expand All @@ -59,22 +59,6 @@ public void insertComments(CompilationUnit cu, String cuSourceCode) throws IOExc
insertCommentsInCu(cu, allComments);
}

public boolean getDoNotConsiderAnnotationsAsNodeStartForCodeAttribution() {
return doNotConsiderAnnotationsAsNodeStartForCodeAttribution;
}

public void setDoNotConsiderAnnotationsAsNodeStartForCodeAttribution(boolean newValue) {
this.doNotConsiderAnnotationsAsNodeStartForCodeAttribution = newValue;
}

public boolean getDoNotAssignCommentsPreceedingEmptyLines() {
return doNotAssignCommentsPreceedingEmptyLines;
}

public void setDoNotAssignCommentsPreceedingEmptyLines(boolean newValue) {
this.doNotAssignCommentsPreceedingEmptyLines = newValue;
}

/**
* Comments are attributed to the thing the comment and are removed from
* allComments.
Expand Down Expand Up @@ -131,7 +115,7 @@ private void insertCommentsInNode(Node node,
List<Comment> commentsInsideChild = new LinkedList<Comment>();
for (Comment c : commentsToAttribute) {
if (PositionUtils.nodeContains(child, c,
doNotConsiderAnnotationsAsNodeStartForCodeAttribution)) {
configuration.doNotConsiderAnnotationsAsNodeStartForCodeAttribution)) {
commentsInsideChild.add(c);
}
}
Expand Down Expand Up @@ -163,7 +147,7 @@ && attributeLineCommentToNodeOrChild(child,
childrenAndComments.addAll(children);
childrenAndComments.addAll(commentsToAttribute);
PositionUtils.sortByBeginPosition(childrenAndComments,
doNotConsiderAnnotationsAsNodeStartForCodeAttribution);
configuration.doNotConsiderAnnotationsAsNodeStartForCodeAttribution);

for (Node thing : childrenAndComments) {
if (thing instanceof Comment) {
Expand All @@ -173,7 +157,7 @@ && attributeLineCommentToNodeOrChild(child,
}
} else {
if (previousComment != null && !thing.hasComment()) {
if (!doNotAssignCommentsPreceedingEmptyLines
if (!configuration.doNotAssignCommentsPrecedingEmptyLines
|| !thereAreLinesBetween(previousComment, thing)) {
thing.setComment(previousComment);
attributedComments.add(previousComment);
Expand Down
78 changes: 33 additions & 45 deletions javaparser-core/src/main/java/com/github/javaparser/JavaParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@

package com.github.javaparser;

import java.io.*;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.body.BodyDeclaration;
Expand All @@ -31,31 +29,33 @@
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.Statement;

import java.io.*;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Optional;

import static com.github.javaparser.ASTParser.*;
import static com.github.javaparser.Providers.*;
import static com.github.javaparser.ASTParser.tokenRange;
import static com.github.javaparser.Providers.UTF8;
import static com.github.javaparser.Providers.provider;
import static com.github.javaparser.utils.Utils.providerToString;
import static java.util.Collections.*;
import static java.util.Collections.singletonList;

/**
* Parse Java source code and creates Abstract Syntax Tree classes.
* Parse Java source code and creates Abstract Syntax Trees.
*
* @author Júlio Vilmar Gesser
*/
public final class JavaParser {
private static final CommentsInserter commentsInserter = new CommentsInserter();
private final CommentsInserter commentsInserter;

private ASTParser astParser = null;

/**
* Instantiate the parser. Note that parsing can also be done with the static methods on this class.
* Creating an instance will reduce setup time between parsing files.
*/
public JavaParser() {
// No specific constructors for this class.
public JavaParser(ParserConfiguration configuration) {
commentsInserter = new CommentsInserter(configuration);
}

private ASTParser getParserForProvider(Provider provider) {
Expand Down Expand Up @@ -97,6 +97,8 @@ public <N> ParseResult<N> parseStructure(ParseContext<N> context, Provider provi
return new ParseResult<>(Optional.of(resultNode), parser.problems);
} catch (ParseException e) {
return new ParseResult<>(Optional.empty(), singletonList(new Problem(e.getMessage(), tokenRange(e.currentToken))));
} catch (TokenMgrException e) {
return new ParseResult<>(Optional.empty(), singletonList(new Problem(e.getMessage(), Range.UNKNOWN)));
} finally {
try {
provider.close();
Expand All @@ -114,17 +116,19 @@ public <N> ParseResult<N> parseStructure(ParseContext<N> context, Provider provi
* @return the parse result and a collection of encountered problems.
*/
public ParseResult<CompilationUnit> parseFull(Provider provider) {
final ASTParser parser = getParserForProvider(provider);
try {
String comments = providerToString(provider);
CompilationUnit resultNode = ParseContext.COMPILATION_UNIT.parse(parser);
commentsInserter.insertComments(resultNode, comments);
final String sourceCode = providerToString(provider);
final ASTParser parser = getParserForProvider(provider(sourceCode));
final CompilationUnit resultNode = ParseContext.COMPILATION_UNIT.parse(parser);
commentsInserter.insertComments(resultNode, sourceCode);

return new ParseResult<>(Optional.of(resultNode), parser.problems);
} catch (ParseException e) {
return new ParseResult<>(Optional.empty(), singletonList(new Problem(e.getMessage(), tokenRange(e.currentToken))));
} catch (IOException e) {
// The commentsInserter won't throw an IOException since it's reading from a String.
return new ParseResult<>(Optional.empty(), singletonList(new Problem(e.getMessage(), tokenRange(e.currentToken))));
} catch (TokenMgrException e) {
return new ParseResult<>(Optional.empty(), singletonList(new Problem(e.getMessage(), Range.UNKNOWN)));
} catch (IOException e) {
// The commentsInserter won't throw an IOException since it's reading from a String.
throw new AssertionError("Unreachable code");
} finally {
try {
Expand All @@ -135,22 +139,6 @@ public ParseResult<CompilationUnit> parseFull(Provider provider) {
}
}

public static boolean getDoNotConsiderAnnotationsAsNodeStartForCodeAttribution() {
return commentsInserter.getDoNotConsiderAnnotationsAsNodeStartForCodeAttribution();
}

public static void setDoNotConsiderAnnotationsAsNodeStartForCodeAttribution(boolean newValue) {
commentsInserter.setDoNotConsiderAnnotationsAsNodeStartForCodeAttribution(newValue);
}

public static boolean getDoNotAssignCommentsPreceedingEmptyLines() {
return commentsInserter.getDoNotAssignCommentsPreceedingEmptyLines();
}

public static void setDoNotAssignCommentsPreceedingEmptyLines(boolean newValue) {
commentsInserter.setDoNotAssignCommentsPreceedingEmptyLines(newValue);
}

public static CompilationUnit parse(final InputStream in, final Charset encoding) throws ParseProblemException {
return parse(in, encoding, true);
}
Expand Down Expand Up @@ -270,25 +258,25 @@ public static Statement parseStatement(final String statement) throws ParseProbl
}

private static <T> T simplifiedParse(ParseContext<T> context, Provider provider) throws ParseProblemException {
ParseResult<T> result = new JavaParser().parseStructure(context, provider);
ParseResult<T> result = new JavaParser(new ParserConfiguration()).parseStructure(context, provider);
if (result.isSuccessful()) {
return result.result.get();
}
throw new ParseProblemException(result.problems);
}

private static CompilationUnit simplifiedParse(Provider provider, boolean considerComments) throws ParseProblemException {
final ParseResult<CompilationUnit> result;
if(considerComments) {
result = new JavaParser().parseFull(provider);
}else{
result = new JavaParser().parseStructure(ParseContext.COMPILATION_UNIT, provider);
}
if (result.isSuccessful()) {
return result.result.get();
}
throw new ParseProblemException(result.problems);
}
private static CompilationUnit simplifiedParse(Provider provider, boolean considerComments) throws ParseProblemException {
final ParseResult<CompilationUnit> result;
if (considerComments) {
result = new JavaParser(new ParserConfiguration()).parseFull(provider);
} else {
result = new JavaParser(new ParserConfiguration()).parseStructure(ParseContext.COMPILATION_UNIT, provider);
}
if (result.isSuccessful()) {
return result.result.get();
}
throw new ParseProblemException(result.problems);
}

/**
* Parses the Java statements contained in a {@link String} and returns a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.List;

@FunctionalInterface
// TODO this needs a better name. "StartProduction"?
public interface ParseContext<R> {
ParseContext<CompilationUnit> COMPILATION_UNIT = ASTParser::CompilationUnit;
ParseContext<BlockStmt> BLOCK = ASTParser::Block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,23 @@

import java.util.List;

/**
* Thrown when parsing problems occur during parsing with the static methods on JavaParser.
*/
public class ParseProblemException extends Exception {
public final List<Problem> problems;

public ParseProblemException(List<Problem> problems) {
this.problems = problems;
}
/** The problems that were encountered during parsing */
public final List<Problem> problems;

ParseProblemException(List<Problem> problems) {
super(createMessage(problems));
this.problems = problems;
}

private static String createMessage(List<Problem> problems){
StringBuilder message = new StringBuilder();
for(Problem problem: problems){
message.append(problem.toString()).append("\n");
}
return message.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,31 @@
import java.util.List;
import java.util.Optional;

/**
* The results given when parsing with an instance of JavaParser.
*/
public class ParseResult<T> {
public ParseResult(Optional<T> result, List<Problem> problems) {
this.result = result;
this.problems = problems;
}
public final List<Problem> problems;
public final Optional<T> result;

public final List<Problem> problems;
public ParseResult(Optional<T> result, List<Problem> problems) {
this.result = result;
this.problems = problems;
}

public boolean isSuccessful() {
return problems.isEmpty();
}

public final Optional<T> result;

public boolean isSuccessful() {
return problems.isEmpty();
}
}
@Override
public String toString() {
if (isSuccessful()) {
return "Parsing successful";
}
StringBuilder message = new StringBuilder("Parsing failed:\n");
for (Problem problem : problems) {
message.append(problem.toString()).append("\n");
}
return message.toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.javaparser;

public class ParserConfiguration {

public boolean doNotAssignCommentsPrecedingEmptyLines = true;
public boolean doNotConsiderAnnotationsAsNodeStartForCodeAttribution = false;
}
23 changes: 13 additions & 10 deletions javaparser-core/src/main/java/com/github/javaparser/Problem.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package com.github.javaparser;

/**
* A problem that was encountered during parsing.
*/
public class Problem {
public final String message;
public final Range range;
public final String message;
public final Range range;

public Problem(String message, Range range) {
this.message = message;
this.range = range;
}
Problem(String message, Range range) {
this.message = message;
this.range = range;
}

@Override
public String toString() {
return message + " " + range;
}
@Override
public String toString() {
return message + " " + range;
}
}
Loading

0 comments on commit 804bed8

Please sign in to comment.