如何在JavaParser AST中用字符串替换表达式

时间:2019-03-23 00:31:28

标签: java abstract-syntax-tree javaparser

假设我有表达式"(a == b || a == c) && (d == e)"。如何使用自定义字符串替换子表达式,例如如何将a == b替换为a.equals(b)

1 个答案:

答案 0 :(得分:0)

基于@Andreas建议的解决方案

public static void main(String[] args) {
    String strExpr = "(get(a == b) || b == c ) && ( a == b ? b == c : c == d)";

    Expression expr = StaticJavaParser.parseExpression(strExpr);
    EnclosedExpr parentExpr = addParentExpr(expr);
    processExpr(parentExpr);
    expr = removeParentExpr(parentExpr);

    // OUTPUT: (get(a.equals(b)) || b.equals(c)) && (a.equals(b) ? b.equals(c) : c.equals(d))
    System.out.println(expr);
}

处理

private static void processExpr(Expression expr) {
    expr.stream()
            .filter(node -> node instanceof Expression)
            .map(node -> ( Expression ) node)
            .filter(Expression::isBinaryExpr)
            .map(Expression::asBinaryExpr)
            .filter(binaryExpr -> binaryExpr.getOperator() == Operator.EQUALS)
            .forEach(binaryExpr -> binaryExpr.getParentNode().ifPresent(node ->  {
                node.replace(binaryExpr, equalsExpr(
                        binaryExpr.getLeft(), binaryExpr.getRight()));
            }));
}

辅助方法

private static EnclosedExpr addParentExpr(Expression expr) {
    EnclosedExpr enclosedExpr = new EnclosedExpr();
    enclosedExpr.setInner(expr);
    return enclosedExpr;
}

private static Expression removeParentExpr(EnclosedExpr parentExpr) {
    Expression expr = parentExpr.getInner();
    parentExpr.remove(expr);
    return expr;
}

private static MethodCallExpr equalsExpr(Expression leftExpr, Expression rightExpr) {
    return new MethodCallExpr(leftExpr, "equals", new NodeList<>(rightExpr));
}

由于StaticJavaParser运行缓慢,因此还可以选择将JavaParserParseConfiguration一起使用来禁用后期处理和验证(快速解析)。

JavaParser javaParser = new JavaParser(new ParserConfiguration()
            .setLanguageLevel(LanguageLevel.RAW));