重写方法错误地将更改重写为ICompilationUnit第二次重写更新

时间:2012-10-11 07:15:13

标签: abstract-syntax-tree eclipse-jdt

我有这个方法UpdateProperty:

public void run(ObjectNavigatorModel model, String propertyKey,
        String propertyValue) {
    // get reference to CompilationUnit
    ICompilationUnit cu = model.getICompilationUnit();
    try {
        cu.becomeWorkingCopy(null);
    } catch (JavaModelException e1) {
        e1.printStackTrace();
    }
    // unit instance of CompilationUnit
    CompilationUnit unit = model.getCompilationUnit();
    AST ast               = unit.getAST();
    ASTRewrite rewrite = ASTRewrite.create(ast);

    // get methods map
    MethodVisitor visitor = new MethodVisitor();
    unit.accept(visitor);
    Map<String, MethodDeclaration> methodMap = new Hashtable<String, MethodDeclaration>();
    for (MethodDeclaration methodDeclaration : visitor.getMethods()) {
        methodMap.put(methodDeclaration.getName().toString(),
                methodDeclaration);
    }

    // find the reference to the MethodDeclaration
    MethodDeclaration methodDecl = null;
    @SuppressWarnings("rawtypes")
    Hashtable nameIndex = (Hashtable) StatementVisitor.queryTable.get(model.getClass().getSimpleName());
    String methodName = (String) ((nameIndex!=null) ? nameIndex.get("modelName") : model.getClass().getSimpleName());
    System.out.println("methodName: " + methodName);
    if (methodMap.containsKey("get" + methodName + model.getOriginalName())) {
        methodDecl = methodMap.get("get" + methodName + model.getOriginalName());
    }

    if (methodDecl == null)
        // failed to find correct method
        return;

    // finding the existing statement
    Block block = methodDecl.getBody();
    List<?> statements = block.statements();
    Iterator<?> iter = statements.iterator();
    System.out.println("property key:"+propertyKey);
    System.out.println("property value:"+propertyValue);

    while (iter.hasNext()) {
        // get each statement
        Statement stmt = (Statement) iter.next();

        stmt.accept(new UpdatePropertyStatementVisitor(propertyKey,
                propertyValue, rewrite));


    }


    TextEdit edits;
    try {
        Document document = new Document(cu.getSource());
        // computation of the text edits
        edits = rewrite.rewriteAST(document, cu.getJavaProject()
                .getOptions(true));

        // computation of the new source code
        edits.apply(document);

        String newSource = document.get();

        // update of the compilation unit
        cu.getBuffer().setContents(newSource);
        File file = cu.getResource().getLocation().toFile();
        write(newSource, file);
        cu.getResource().refreshLocal(0, null);
        cu.close();
    } 
    catch (CoreException e) {
        e.printStackTrace();
    }


}
    public static void write(String content, File file)
        throws IOException {
    // create file if it necessary
    if (!file.exists()) {
        file.createNewFile();
    }
    // write to file
    // Use printwriter with buffered writer is faster than FileWriter
    PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
    out.write(content);

    out.close();
}

和propertyStatementVisitor用更新的值替换ASTNode:     公共类UpdatePropertyStatementVisitor扩展ASTVisitor {     private String propertyKey;     private String propertyValue;     private ASTRewrite rewrite;

public UpdatePropertyStatementVisitor(String propertyKey,
        String propertyValue, ASTRewrite rewrite) {
    this.propertyKey = propertyKey;
    this.propertyValue = propertyValue;
    this.rewrite = rewrite;
}

/* Auto called by eclipse JDT, see visitor pattern
 * (non-Javadoc)
 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ExpressionStatement)
 */
public boolean visit(ExpressionStatement stmt) 
{
    // first, go down to MethodInvocation level
    Expression expression = stmt.getExpression();
    if (expression instanceof MethodInvocation) 
    {
        MethodInvocation mi = (MethodInvocation) expression;
        // check method name, e.g. setHeight(5);
        String miName = mi.getName().toString();
        miName = miName.replaceAll("((?<=[a-z])[A-Z]|[A-Z](?=[a-z]))"," $1");
        String[] array = miName.split(" ");
        if (array[0].equals("set")) 
        {
            // merge remaining parts of the split method name
            StringBuilder key = new StringBuilder();
            for (int i = 1; i < array.length; i++) {
                key.append(array[i]);
            }
            if (key.toString().equalsIgnoreCase(propertyKey)) {
                System.out.println("found set property");
                // do the replace, if the key matches
                StringLiteral newValue = mi.getAST().newStringLiteral();
                newValue.setEscapedValue("\""+propertyValue+"\"");
                // the argument to change update index, so far 1st argument for all cases, i.e. 0
                System.out.println("Inside Visit Statement: \npropertyValue:"+propertyValue+ " \n arguments[0]"+(ASTNode) mi.arguments().get(0) + "/n NewValue:"+ newValue );
                rewrite.replace((ASTNode) mi.arguments().get(0), newValue, null);
                return true;
            }
        }
    }
    return false;
}

}

目标是在一个文件的方法中设置Name属性String值:

     // Setting alert properties GOT PROBLEM HERE!!!!
     alert.setName("Delete_Alert");
     alert.setMessage("Are you sure you want to remove this customer? (Note: changes do not become final until you Save them.)");

我的问题是,我第一次更新语句的值时,它可以正常工作,但是第二次回写不准确时,它只会吞掉下一行代码 - 应该写入。是这样的:

//1st Attempt: 
    Alert.setName("Delete_Alert_firstAttempt")      //(Success)

alert.setMessage(“您确定要删除此客户吗?(注意:在您保存更改之前,更改不会成为最终版本。)”);

//2nd Attempt: 
    Alert.setName("Delete_Alert_secondAttempt"Are you sure you want to remove this customer? (Note: changes do not become final until you Save them.)");  //(fail)

任何JDT专家都可以指出错误是什么?

0 个答案:

没有答案