1

Suppose I have expression "(a == b || a == c) && (d == e)". How can I replace subexpression by custom String e.g. how can I replace a == b by a.equals(b)?

matoni
  • 2,479
  • 21
  • 39
  • By replacing the [`BinaryExpr`](http://static.javadoc.io/com.github.javaparser/javaparser-core/3.2.5/com/github/javaparser/ast/expr/BinaryExpr.html) for the [`EQUALS`](http://static.javadoc.io/com.github.javaparser/javaparser-core/3.2.5/com/github/javaparser/ast/expr/BinaryExpr.Operator.html#EQUALS) operator with a [`MethodCallExpr`](http://static.javadoc.io/com.github.javaparser/javaparser-core/3.2.5/com/github/javaparser/ast/expr/MethodCallExpr.html) of the `equals` method. Seems fairly obvious if you understand AST, and if you don't, you do it by first learning more about AST. – Andreas Mar 23 '19 at 00:40
  • @Andreas thanks, your suggestion helped me to build solution. – matoni Mar 23 '19 at 01:38

1 Answers1

2

Solution based on @Andreas suggestion

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);
}

processing

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()));
            }));
}

helper methods

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));
}

Since StaticJavaParser is slow, there is also an option to use JavaParser with ParseConfiguration to disable post processing and validation (fast parsing).

JavaParser javaParser = new JavaParser(new ParserConfiguration()
            .setLanguageLevel(LanguageLevel.RAW));
matoni
  • 2,479
  • 21
  • 39