New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How can I access the contents of my code? #2149
Comments
Hi! Have you read the book? |
Yes - I am using the book and the JavaDocs as a tutorial/guide. Would you recommend to look into a specific chapter? I have not found what I am looking for so far. |
Okay. The order of visiting is set in the visitor you are inheriting from. I guess your inherited visit method calls If I'm mistaken, it would be helpful to see the code you are writing. |
I'm using the code above to count how many if-statements and loops appear in the code. I tried to use |
Okay, you asked help with if statements being visited inside out. Is that problem solved? You are counting |
The first part of the problem is solved. The second, which I added a piece of my code, works but I was wondering if there is a more optimal way to count all the statements rather than having to create a case for each one of them. I read in the JavaDocs that instead of using e.g.
The above which was my approach to this is wrong though. |
Ah, like that! The visitor only has methods for the "leaves" of the AST, so no abstract classes like Statement. What you can try is one of the |
Thanks for your replies they really helped me a lot. I'm following your proposal to use the The small Java program:
My JP code:
And this is my output:
The code is correct and working but I cannot overcome the following issue: E.g. when we are inside the first
Is there a way to identify that we reached the end of the nested |
Okay, I'm guessing at exactly what it is you're trying to achieve, so let's ask that question: what exactly is the statistic you're trying to calculate from your latest example? |
I want to classify all the possible states of the program and how they connect to each other, where a state can be any E.g. from the code: -first line- -second line- -third line- etc. My code has managed to do so up to a point, but of course it cannot identify that after we reach state 2 the code will jump to state 6 and won't continue to state 3 which is the |
If I understand correctly, then you need more control. For if-statements, it looks like you first want to find the top level ones. Then, for each of those, you want to find any second-level In this case I personally would create a visitor for if statements that does not call super, since it won't automatically continue visiting inside the if statement. But in the visit method you can ask for the same visitor (or another) to visit the true or the false part of the if ( If this is all too much, try going fully manual: write a recursive method that takes a node, iterates through |
I've been trying to implement the first approach the past few days but unsuccessfully. This is the closest I got but it prints nothing as output:
I was hoping this would print the contents of the When I remove |
If I find some free time I can write some code. |
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.IfStmt;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.visitor.VoidVisitorWithDefaults;
import java.util.ArrayList;
import java.util.List;
public class Bla {
public static void main(String[] args) {
CompilationUnit cu = StaticJavaParser.parse("class X{void x(){" +
" int x = 1;" +
" if (x>4) { " +
" x=21; " +
" } " +
" else { " +
" if (x>1) { " +
" x=211; " +
" } " +
" else { " +
" x=212; " +
" } " +
" } " +
" if (x==4) { " +
" x=3; " +
" }}}");
State start = new State(null);
State end = new State(null);
findStatesInBlock(cu.findFirst(BlockStmt.class).get(), start, end);
}
static class State {
final Statement statement;
// The states that follow this state:
final List<State> nextStates = new ArrayList<>();
State(Statement statement) {
this.statement = statement;
}
}
/**
* Make a state graph of the statements in block. beforeState will get a next-state to the first statement in the block.
* afterState will be the next-state of the last statement(s) in the block.
*/
private static void findStatesInBlock(BlockStmt block, State beforeState, State afterState) {
List<State> states = new ArrayList<>();
// Create the sequence in this block
for (Statement statement : block.getStatements()) {
states.add(new State(statement));
}
beforeState.nextStates.add(states.get(0));
// Attach to next states
for (int i = 0; i < states.size(); i++) {
State currentState = states.get(i);
State nextState;
if (i == states.size() - 1) {
nextState = afterState;
} else {
nextState = states.get(i + 1);
}
currentState.statement.accept(new VoidVisitorWithDefaults<Void>() {
@Override
public void visit(ExpressionStmt n, Void arg) {
currentState.nextStates.add(nextState);
}
@Override
public void visit(IfStmt n, Void arg) {
findStatesInBlock(n.getThenStmt().asBlockStmt(), currentState, nextState);
n.getElseStmt().ifPresent(elseStmt ->
findStatesInBlock(elseStmt.asBlockStmt(), currentState, nextState));
}
}, null);
}
}
} After |
Thanks for putting the effort to make this example, I appreciate it. With "you can find the state graph in |
You are making a graph of states. The numbers you use are the If you want to print it, you start at root, print some representation, then print an arrow and the states in the nextStates-list. Then you can do the same for those states, and so on. |
Indeed this prints exactly what I had in mind with the only addition of a What I'm trying now is to add support for loops, e.g. for Code to be parsed (changed the last
Added
What I noticed is that while the loop is recognised as a Is there a way to print the contents of the loop (meaning the different |
Okay, I have to draw a line here: my support is to maintain and explain JavaParser. Developing solutions for clients is what I do at work, and that's not for free ;-) That said, I think you want to have the following things: Or maybe less, depending on what your ultimate goal is. |
Apologies for asking too many questions. You helped me understand some of the core functionalities of JavaParser. Thanks again! |
No problem, feel free to ask more :-) |
This time I have a more concrete example of a problem rather than a question. I added
I'm not sure why this occurs when the
The commended out line recreates the error, while the other skips the corresponding |
Some hints:
|
I believe I found what has caused this by inspecting the AST as you suggested, but still I'm not sure why this happens. The I do not think there is an error in the parsing code. In general, the |
By design the else is part of the |
Sorry, I will try to make it more understandable. This is the AST generated by my code:
And these are the lines of code that correspond to this AST:
Regarding the AST, the first line implies that this All of the following |
Try outputting the AST's for these code fragments: |
Hi, I am new to Java Parser and I'm trying to understand how to use some of its features - if what I am thinking can be achieved.
I have this piece of code, mainly for experimenting with Java Parser:
What I would like to achieve is to call JP, and based on the order of the constructs to perform some operations. So far I have tried to do this for the if statements with the
public void visit(IfStmt n, Void arg)
method, but this method just identifies all the ifs located in my code, without preserving the order (the second if is inside the first and not below).Is there a way to identify all constructs in my code and preserve their order? (I am not looking to print the AST).
The text was updated successfully, but these errors were encountered: