在 JDT 中用 MethodInvocation 替换 ArrayAccess
Replacing ArrayAccess with MethodInvocation in JDT
我要转型
xyz[3].aaa[1].bbb[2].jjj
到
getXyz(3).getAaa(1).getBbb(2).getJjj()
使用 JDT
内核。
用getter替换ArrayAccess
方法没有帮助,因为访问的数组访问如下:-
xyz[3].aaa[1].bbb[2]
xyz[3].aaa[1]
xyz[3]
因此仅将 ArrayAccess 替换为 getter 将丢失一些替换。
我尝试的另一个选择是访问 FieldAccess
但这样做我只剩下
getXyz(3).getAaa(1)[1].getBbb(2)[2].getJjj()
有没有办法替换 [1] 或 [2],或者更确切地说,是否可以解析并获取 aaa[1]、bbb[2] 来删除或替换?
如果很难一次完成所有更改,最简单且 "best to understand" 的解决方案是将您的代码更改分成几遍。我的意思是:
- 解析 AST
- 进行不会覆盖自身的更改
- 应用编辑
所以这意味着您将重新分析每一次通过的代码。这样做的缺点是性能会下降很多。
将更改分成多遍的一种方法是首先找到所有数组声明,然后仅对该数组进行更改。
找到了我自己的问题的答案。简短的回答是,在表达式 xyz[3].aaa[1]
中, xyz[3].aaa
需要被视为索引表达式为 1
的数组,以便 aaa[1]
或 [1]
得到正确核算。
但是,我发现以编程方式处理以下方法要容易得多。
方法是通过简单的替换将此处的数组表达式视为方法调用 replace("\"", "").replace("+", "").replace('[', '(').replace(']', ')')
问题减少到重命名方法。
@Test
public void testArray() throws Exception {
String testExpr = "xyz[3].aaa[1].bbb[2]";
Document document;
ASTParser parser;
parser = ASTParser.newParser(AST.JLS8);
parser.setKind(ASTParser.K_EXPRESSION);
parser.setResolveBindings(true);
String exprString = testExpr.replace("\"", "").replace("+", "").replace('[', '(').replace(']', ')');
document = new Document(exprString);
parser.setSource(document.get().toCharArray());
Object o = parser.createAST(null);
if (o instanceof CompilationUnit) {
CompilationUnit cu = (CompilationUnit) o;
IProblem[] problems = cu.getProblems();
System.err.println(problems);
}
Expression expr = (Expression) o;
final ASTRewrite rewriter = ASTRewrite.create(expr.getAST());
final AST ast = expr.getAST();
final TextEditGroup textEdits = new TextEditGroup("test");
expr.accept(new ASTVisitor() {
@Override
public boolean visit(MethodInvocation node) {
String getter = getGetter(node.getName().getIdentifier().toString());
rewriter.replace(node.getName(),
ast.newSimpleName(getter),
textEdits);
return super.visit(node);
}
});
TextEdit edits = rewriter.rewriteAST(document, null);
edits.apply(document);
assertEquals("getXyz(3).getAaa(1).getBbb(2)",
document.get());
}
我要转型
xyz[3].aaa[1].bbb[2].jjj
到
getXyz(3).getAaa(1).getBbb(2).getJjj()
使用 JDT
内核。
用getter替换ArrayAccess
方法没有帮助,因为访问的数组访问如下:-
xyz[3].aaa[1].bbb[2]
xyz[3].aaa[1]
xyz[3]
因此仅将 ArrayAccess 替换为 getter 将丢失一些替换。
我尝试的另一个选择是访问 FieldAccess
但这样做我只剩下
getXyz(3).getAaa(1)[1].getBbb(2)[2].getJjj()
有没有办法替换 [1] 或 [2],或者更确切地说,是否可以解析并获取 aaa[1]、bbb[2] 来删除或替换?
如果很难一次完成所有更改,最简单且 "best to understand" 的解决方案是将您的代码更改分成几遍。我的意思是:
- 解析 AST
- 进行不会覆盖自身的更改
- 应用编辑
所以这意味着您将重新分析每一次通过的代码。这样做的缺点是性能会下降很多。
将更改分成多遍的一种方法是首先找到所有数组声明,然后仅对该数组进行更改。
找到了我自己的问题的答案。简短的回答是,在表达式 xyz[3].aaa[1]
中, xyz[3].aaa
需要被视为索引表达式为 1
的数组,以便 aaa[1]
或 [1]
得到正确核算。
但是,我发现以编程方式处理以下方法要容易得多。
方法是通过简单的替换将此处的数组表达式视为方法调用 replace("\"", "").replace("+", "").replace('[', '(').replace(']', ')')
问题减少到重命名方法。
@Test
public void testArray() throws Exception {
String testExpr = "xyz[3].aaa[1].bbb[2]";
Document document;
ASTParser parser;
parser = ASTParser.newParser(AST.JLS8);
parser.setKind(ASTParser.K_EXPRESSION);
parser.setResolveBindings(true);
String exprString = testExpr.replace("\"", "").replace("+", "").replace('[', '(').replace(']', ')');
document = new Document(exprString);
parser.setSource(document.get().toCharArray());
Object o = parser.createAST(null);
if (o instanceof CompilationUnit) {
CompilationUnit cu = (CompilationUnit) o;
IProblem[] problems = cu.getProblems();
System.err.println(problems);
}
Expression expr = (Expression) o;
final ASTRewrite rewriter = ASTRewrite.create(expr.getAST());
final AST ast = expr.getAST();
final TextEditGroup textEdits = new TextEditGroup("test");
expr.accept(new ASTVisitor() {
@Override
public boolean visit(MethodInvocation node) {
String getter = getGetter(node.getName().getIdentifier().toString());
rewriter.replace(node.getName(),
ast.newSimpleName(getter),
textEdits);
return super.visit(node);
}
});
TextEdit edits = rewriter.rewriteAST(document, null);
edits.apply(document);
assertEquals("getXyz(3).getAaa(1).getBbb(2)",
document.get());
}