javaparser / javaparser

Java 1-21 Parser and Abstract Syntax Tree for Java with advanced analysis functionalities.
https://javaparser.org
Other
5.43k stars 1.16k forks source link

AST and Comments #3162

Closed IjazAhmed closed 3 years ago

IjazAhmed commented 3 years ago

Lets assume, the original code of ClassB is given below.

public class ClassB { int b; /@ public normal_behavior @ requires a > 5; @ ensures b == 16; @/ public void test1 (int a) { b=16; // This is my comment.

} I am using "org.eclipse.jdt.core.dom.AST" to parse and modify classB. After modifying the original code (indeed AST), I saved the modified AST with the aid of "ICompilationUnit. save()" method. The modified code of ClassB is given below.

public class ClassB { int b; public void test1 (int a) { assert (a >5); b=16; assert(b==16); } Basically, I added the assertion statements in at the start and end of a method.

Now the problem that I am facing is that as AST does not contain comments, so when I rewrite the AST, I loose all code comments, including my JML contract (/@ public normal_behavior @ requires a > 5; @ ensures b == 16; @/) and comment (// This is my comment.)

I understand that there is a method "CompilationUnit.getCommentList()" that may give me the list of comments, but then I loose track that which comment (contract) belong to which line. So any advise, what is a most straight way to deal it?

jlerbsc commented 3 years ago

Why did you parse and modify class with "org.eclipse.jdt.core.dom.AST". It's not a JP API. Also it seems that in your example the Java Modeling Language syntax is not correct.

Comments and JML are preserved in the example below :

@Test
public void test1() {
    String code = 
            "public class ClassB {\n" + 
            " int b;\n" + 
            " /*@ public normal_behavior\n" + 
            "  @ requires a > 5;\n" + 
            "  @ ensures b == 16;\n" + 
            "  @*/\n" + 
            " public void test1 (int a) {\n" + 
            "  b=16; // This is my comment.\n" + 
            " }\n" + 
            "}";
    CompilationUnit cu = StaticJavaParser.parse(code);

    MethodDeclaration md = cu.findFirst(MethodDeclaration.class).get();
    Expression assertExpr = new BinaryExpr(new NameExpr("a"), new IntegerLiteralExpr(), Operator.GREATER);
    md.getBody().get().getStatements().addFirst(new AssertStmt(new EnclosedExpr(assertExpr)));
    md.getBody().get().getStatements().addLast(new AssertStmt(new EnclosedExpr(assertExpr)));

    System.out.println(cu.toString());
}

the result is

public class ClassB {

int b;

/*@ public normal_behavior
@ requires a > 5;
@ ensures b == 16;
@*/
public void test1(int a) {
    assert (a > 0);
    // This is my comment.
    b = 16;
    assert (a > 0);
}
}
IjazAhmed commented 3 years ago

Thank you for your consistent support. I am also very close to achieve my goal, albeit with the aid of orthodox ""...core.dom.AST" :). I googled the jar file for "StaticJavaParser", but I could not find a one. Can you please direct me to the link of the jar file?

Regards

jlerbsc commented 3 years ago

StaticJavaParser is a JP class mainly uses in tests. You cannot use StaticJavaParser with another parser . What is this project org.eclipse.jdt.core.dom.AST ? Why did you use org.eclipse.jdt.core.dom.AST and Javaparser at the same time? I don't really understand what you are doing? Can you explain to us what you want to do from JP?

IjazAhmed commented 3 years ago

In my post, "org.eclipse.jdt.core.dom.AST" means JDT APIs. I am not using JDT APIs and JP API at the same time. Currently, I programmed the application by using JDT APIs. But I too want to explore JP APIs, so that in future I may port my application to JP, if required. Anyhow, thank you for your guidance regarding StaticJavaParser and JP.

Regards

jlerbsc commented 3 years ago

Interesting. What is the pros and cons of JDT APIs (versus JP or another solution)?

IjazAhmed commented 3 years ago

sure. I will write once my study complete.

Regards Ijaz