问题在于:
我有一个班级,例如,
public class EmployeeServiceImpl {
@Autowired
EmployeeDAO empDAO;
public void findDepartments() throws NoEmployeeFoundException {
int age = empDAO.findEmployeeById(12).getAge();
if( age > 30 ){
//do something
}else{
//do something else.
}
}
}
我的目标是:
(1)检测变量赋值 (2)删除变量赋值和 (3)将赋值的变量添加为方法参数。
因此,在AST转换之后,代码将如下所示:
public class EmployeeServiceImpl {
@Autowired
EmployeeDAO empDAO;
public void findDepartments(int age) throws NoEmployeeFoundException {
if( age > 30 ){
//do something
}else{
//do something else.
}
}
}
我能做(1)& (2)。但是,对于(3),虽然变量赋值节点被删除,但我无法将参数添加到方法中。 AST变换器代码如下。我错过了什么? (请原谅单片代码和绝对无视声音设计)
MethodVisitor visitor = new MethodVisitor();
String source = unit.getSource();
Document document = new Document(source);
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(unit);
CompilationUnit astRoot = parse(unit);
AST ast = astRoot.getAST();
astRoot.accept(visitor);
TestGenClassVisitor classVisitor = new TestGenClassVisitor();
for (MethodDeclaration method : visitor.getMethods()) {
method.accept( classVisitor );
}
// creation of ASTRewrite
ASTRewrite rewrite = ASTRewrite.create( ast );
astRoot.recordModifications();
// for getting insertion position
TypeDeclaration typeDecl = (TypeDeclaration) astRoot.types()
.get(0);
MethodDeclaration methodDecl = typeDecl.getMethods()[0];
Block block = methodDecl.getBody();
List<VariableDeclarationStatement> varDeclarations = classVisitor.getReplaceableVardDeclarationNodes();
ListRewrite listRewrite = rewrite.getListRewrite(block,
Block.STATEMENTS_PROPERTY);
TextEditGroup textEditGroup = new TextEditGroup("abc");
for( VariableDeclarationStatement statement : varDeclarations ){
List<VariableDeclarationFragment> fragments = statement.fragments();
for( VariableDeclarationFragment fragment : fragments){
IVariableBinding varBinding = fragment.resolveBinding();
System.out.println("Will replace node with var name :"+ varBinding.getName() +", of type :"+varBinding.getType().getQualifiedName());
SingleVariableDeclaration singleVariableDeclaration = ast.newSingleVariableDeclaration();
singleVariableDeclaration.setType(ast.newPrimitiveType(PrimitiveType.toCode(varBinding.getType().getQualifiedName())));
singleVariableDeclaration.setName(ast.newSimpleName(varBinding.getName()));
singleVariableDeclaration.setVarargs(false);
singleVariableDeclaration.setExtraDimensions(0);
methodDecl.parameters().add(singleVariableDeclaration);
}
listRewrite.remove(statement, textEditGroup);
}
TextEdit edits = rewrite.rewriteAST();
// computation of the new source code
try {
edits.apply(document);
} catch (MalformedTreeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadLocationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String newSource = document.get();
FileOutputStream fos = null;
try {
File newFile = File.createTempFile("Modified", ".java");
fos = new FileOutputStream(newFile);
fos.write(newSource.getBytes());
fos.flush();
System.out.println("File created at " + newFile.getCanonicalPath());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
答案 0 :(得分:0)
诀窍是正确使用ListRewrite。 使用以下代码解决了它:
ASTRewrite rewrite = ASTRewrite.create( ast );
astRoot.recordModifications();
// for getting insertion position
TypeDeclaration typeDecl = (TypeDeclaration) astRoot.types()
.get(0);
MethodDeclaration methodDecl = typeDecl.getMethods()[0];
Block block = methodDecl.getBody();
ListRewrite paramRewrite = rewrite.getListRewrite( methodDecl ,
MethodDeclaration.PARAMETERS_PROPERTY);
ListRewrite listRewrite = rewrite.getListRewrite( block ,
Block.STATEMENTS_PROPERTY );
List<SingleVariableDeclaration> paramList = new ArrayList<SingleVariableDeclaration>();
List<VariableDeclarationStatement> varDeclarations = classVisitor.getReplaceableVardDeclarationNodes();
for( VariableDeclarationStatement statement : varDeclarations ){
List<VariableDeclarationFragment> fragments = statement.fragments();
for( VariableDeclarationFragment fragment : fragments){
IVariableBinding varBinding = fragment.resolveBinding();
System.out.println("Will replace node with var name :"+ varBinding.getName() +", of type :"+varBinding.getType().getQualifiedName());
SingleVariableDeclaration singleVariableDeclaration = ast.newSingleVariableDeclaration();
singleVariableDeclaration.setType(ast.newPrimitiveType(PrimitiveType.toCode(varBinding.getType().getQualifiedName())));
singleVariableDeclaration.setName(ast.newSimpleName(varBinding.getName()));
paramRewrite.insertLast( singleVariableDeclaration, null);
}
listRewrite.remove(statement, null);
}
TextEdit edits = rewrite.rewriteAST(document, null);