Exprent (Exprent expr) { Exprent exprTmp = null; VarType cltype = null; // first quick test if (expr.type == Exprent.EXPRENT_INVOCATION) { InvocationExprent iex = (InvocationExprent)expr; if ("toString".equals(iex.getName())) { if (builderClass.equals(iex.getClassName())) { cltype = builderType; } else if (bufferClass.equals(iex.getClassName())) { cltype = bufferType; } if (cltype != null) { exprTmp = iex.getInstance(); } } else if ("makeConcatWithConstants".equals(iex.getName())) { // java 9 style List<Exprent> parameters = extractParameters(iex.getBootstrapArguments(), iex); if (parameters.size() >= 2) { return createConcatExprent(parameters, expr.bytecode); } } } if (exprTmp == null) { return expr; } // iterate in depth, collecting possible operands List<Exprent> lstOperands = new ArrayList<>(); while (true) { int found = 0; switch (exprTmp.type) { case Exprent.EXPRENT_INVOCATION -> { InvocationExprent iex = (InvocationExprent)exprTmp; if (isAppendConcat(iex, cltype)) { lstOperands.add(0, iex.getParameters().get(0)); exprTmp = iex.getInstance(); found = 1; } } case Exprent.EXPRENT_NEW -> { NewExprent nex = (NewExprent)exprTmp; if (isNewConcat(nex, cltype)) { VarType[] params = nex.getConstructor().getDescriptor().params; if (params.length == 1) { lstOperands.add(0, nex.getConstructor().getParameters().get(0)); } found = 2; } } } if (found == 0) { return expr; } else if (found == 2) { break; } } int first2str = 0; int index = 0; while (index < lstOperands.size() && index < 2) { if (lstOperands.get(index).getExprType().equals(VarType.VARTYPE_STRING)) { first2str |= (index + 1); } index++; } if (first2str == 0) { lstOperands.add(0, new ConstExprent(VarType.VARTYPE_STRING, "", expr.bytecode)); } // remove redundant String.valueOf for (int i = 0; i < lstOperands.size(); i++) { Exprent rep = removeStringValueOf(lstOperands.get(i)); boolean ok = (i > 1); if (!ok) { boolean isstr = rep.getExprType().equals(VarType.VARTYPE_STRING); ok = isstr || first2str != i + 1; if (i == 0) { first2str &= 2; } } if (ok) { lstOperands.set(i, rep); } } return createConcatExprent(lstOperands, expr.bytecode); }