How to add a code snippet to method body with JDT/AST
Asked Answered
H

3

17

I'm trying to generate Java source code with JDT/AST. I now have MethodDeclaration and want to add a code snippet (from another source) to the method body. The code snippet can contain any Java code, even syntactically invalid code. I just can't find the way to do this.

With JCodeModel you would use JBlock#directStatement(String s) method.

Is there a way to do this with JDT/AST?

Herne answered 10/12, 2012 at 12:50 Comment(8)
AST manipulations generally require you have syntactically valid trees. If you have invalid code for the method, in general, you won't have a valid tree to insert and you won't be able to do it, or you'll be able to do it but only get a nonsensical tree as a result.Lanky
Ok, JST/AST doesn't seem to be the right tool then...Herne
Why do you need to insert invalid code?Lanky
I'm implementing educational software, where UML activity diagrams (created by students) should be translated to Java source code. In the diagram editor it is possible to define action nodes with arbitrary Java code, which needs to appear in the generated code as it is.Herne
Then you could parse the code, and use it if it were error free, and insert it as comments if it were not.Lanky
Unfortunately that's not an option. :-( I need the compile errors of the invalid code to generate feedback for the students.Herne
Can't tell you how to do that with JDT. I can tell you how to do that with another tool, if you are interested, including handling erroneous text.Lanky
I'm very much interested. Consider that I need to modify existing source code (from a *.java file).Herne
L
9

Since you have a well-formed tree for the rest of the application, and you want to insert non-well-formed text at a particular place, you pretty much can't do it with the standard tree node insertion mechanisms.

What matters is that you produce text for the valid program text with the fragment inserted in at at the right place. Somewhere in there must be a piece of logic that prints the AST as text. What you need to do is to ask that the AST be printed as text, and catch it in the middle of that process, at the precise point necessary, to insert your arbitrary text.

Our DMS Software Reengineering Toolkit has enter/exit print-node hooks in its prettyprinter to allow this kind of thing to happen.

If such things don't exist in JDT/AST, you can try to modify its prettyprinter to give you that hook. Alternatively, you might consider modifying JDT/AST by adding a another tree node type that isn't part of the standard set, that simply holds arbitrary text but acts like a method node. Presumably each node controls what is printed; then you could define the prettyprinting for that tree node, to cause it to output its text.

A final really hacky solution: insert a perfectly valid AST where the arbitrary text will go, containing somewhere a bogus identifier with a unique name, e.g., ZZZ. Then, print the AST to a string, and post-process the string to replace the bogus trees containing the unique name with the actual user text.

Lanky answered 16/12, 2012 at 6:46 Comment(0)
P
3

You first need to parse the code snippet into an AST. You can use the ASTParser API for this purpose.

It is possible to get the compilation problems of a compilation unit (See CompilationUnit.getProblems()).

There are a couple of ways to modify Java code using JDT. I'd suggest that you consider the ASTRewrite API for modifying the body of a method.

Polonaise answered 12/12, 2012 at 19:19 Comment(5)
Well, I checked the API reference before, but I couldn't find a way to add an arbitrary code snippet. Consider that the code snippet may contain syntactically invalid code. (I just added this to the original question...)Herne
You can parse the arbitrary code snippet. Then, insert the resulting AST nodes into the AST node of the body of your method. Eclipse parser tolerates syntax errors to some extent.Polonaise
"To some extent" isn't enough unfortunately. :(Herne
I added my answer to include pointers for getting the compilation problems.Polonaise
Its not about retrieving the compilation problems. The asker wants to add code containing compilation errors to the AST. I believe this is not possible using any standard JDT manipulation techniiques.Westsouthwest
M
1

You can manipulate the AST with the ASTParser API - and the output doesn't even have to compile.

Here's an example for your case:

String textToInsert = "Some text";
StringLiteral stringLiteral = methodDeclaration.getAST().newStringLiteral();
rewriter.set(stringLiteral, StringLiteral.ESCAPED_VALUE_PROPERTY, textToInsert, null);
ListRewrite methodStatements = rewriter.getListRewrite(methodDeclaration.getBody(), Block.STATEMENTS_PROPERTY);
methodStatements.insertFirst(stringLiteral, null);

Result:

public void myMethod() {
  Some text
}
Miles answered 11/4, 2020 at 13:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.