问题
So, here is a piece of code using CodeModel that generates java code:
JCodeModel cm = new JCodeModel();
JDefinedClass dc = cm._class("foo.Bar");
JMethod m = dc.method(0, int.class, "foo");
m.body()._return(JExpr.lit(5));
File f = new File("C:/target/classes");
f.mkdirs();
cm.build(f);
This code generates a .java file:
package foo;
public class Bar {
int foo() {
return 5;
}
}
However, I DO NOT want CodeModel to create a new java file for me. I do have a .java file already and would like to add a few lines of code to a method inside it. So, I would like the API to modify the java file directly/ create a modified copy of it. Is there a way to doing this?
回答1:
I know it's been a while since the original post, but one of the more accessible looking Java transformation libraries appears to be Spoon.
From the Spoon Homepage:
Spoon enables you to transform (see below) and analyze (see example) source code. Spoon provides a complete and fine-grained Java metamodel where any program element (classes, methods, fields, statements, expressions...) can be accessed both for reading and modification. Spoon takes as input source code and produces transformed source code ready to be compiled.
Update: Square have also created the JavaPoet source-code generation library, the fluent API looks simple enough to grasp.
回答2:
You're really going to need a full parse of the code you want to modify to ensure you insert code into the correct location. I'd have thought your best bet would be to make use of an existing parse tool that allows code to be rewritten, rather than to try and do something by hand.
The Eclipse IDE does something like this to support code refactoring. This article might be helpful.
回答3:
...I would like the API to modify the java file directly/ create a modified copy of it. Is there a way to doing this?
JavaParser is an API that allows you to read in Java files, modify them, and get the results as a String.
More specifically, JavaParser parses the file and builds an AST (abstract syntax tree). You can then modify the JavaParser AST representing your source code using the API and retrieve the String representation of the AST.
I do have a .java file already and would like to add a few lines of code to a method inside it.
Here's an example of using JavaParser to add a line onto the end of a method body and print the result:
class MyClass {
public static void someMethod() {
/* ... */
// Lines will be added here:
}
public static void main(String[] args) {
String newStatement = "System.out.println(\"Hello world!\");"
File myClassSourceFile = new File("MyClass.java");
CompilationUnit cu = JavaParser.parse(myClassSourceFile);
ClassOrInterfaceDeclaration classDeclaration = cu.getClassByName("MyClass").get();
MethodDeclaration method = classDeclaration.getMethodsByName().get(0);
method.getBody().get().addStatement(newStatement);
// Print out the resulting Java source code.
System.out.println(cu.toString());
}
}
CompilationUnit - From JavaParser's javadoc, "This class represents the entire compilation unit. Each java file denotes a compilation unit."
NOTE: In your code, you will want to replace the Option.get() calls with proper optional handling.
回答4:
What you want is a program transformation system. This is a tool that parses your source file, and can apply transformations to modify it, an regenerates source code with the modifications.
A source-to-source transformation system accepts rules of the form of:
lhs -> rhs if cond
where the lhs and rhs are souce patterns for valid fragments of the language and the cond checks that the rule is safe to apply. (Consider " ?x/?x -> 1 if ?x~=0"; you need the condition to verify that the division is valid).
One such tool is our DMS Software Reengineering Toolkit. DMS has full C, C++, C#, Java, COBOL, Python, PHP and ECMAScript front end parsers (as as many lesser known languages) and can apply such rules directly. DMS also provides symbol table construction and control and data flow analysis, as these are often useful in defining a cond for complex rules. If you want, you can also fall back to a "standard" procedural interface to visit tree nodes and modify ASTs.
来源:https://stackoverflow.com/questions/2333866/editing-modifying-a-java-file-programmatically-not-the-class-file