Avoid explicit array creation for vararg parameters
This commit is contained in:
committed by
Egor.Ushakov
parent
d149b53799
commit
dfd90978c9
@@ -343,14 +343,18 @@ public class InvocationExprent extends Exprent {
|
||||
|
||||
BitSet setAmbiguousParameters = getAmbiguousParameters();
|
||||
|
||||
// omit 'new Type[] {}' for the last parameter of a vararg method call
|
||||
if (lstParameters.size() == descriptor.params.length && isVarArgCall()) {
|
||||
Exprent lastParam = lstParameters.get(lstParameters.size() - 1);
|
||||
if (lastParam.type == EXPRENT_NEW && lastParam.getExprType().arrayDim >= 1) {
|
||||
((NewExprent) lastParam).setVarArgParam(true);
|
||||
}
|
||||
}
|
||||
|
||||
boolean firstParameter = true;
|
||||
int start = isEnum ? 2 : 0;
|
||||
for (int i = start; i < lstParameters.size(); i++) {
|
||||
if (sigFields == null || sigFields.get(i) == null) {
|
||||
if (!firstParameter) {
|
||||
buf.append(", ");
|
||||
}
|
||||
|
||||
TextBuffer buff = new TextBuffer();
|
||||
boolean ambiguous = setAmbiguousParameters.get(i);
|
||||
|
||||
@@ -361,7 +365,14 @@ public class InvocationExprent extends Exprent {
|
||||
}
|
||||
// 'byte' and 'short' literals need an explicit narrowing type cast when used as a parameter
|
||||
ExprProcessor.getCastedExprent(param, descriptor.params[i], buff, indent, true, ambiguous, true, tracer);
|
||||
buf.append(buff);
|
||||
|
||||
// the last "new Object[0]" in the vararg call is not printed
|
||||
if (buff.length() > 0) {
|
||||
if (!firstParameter) {
|
||||
buf.append(", ");
|
||||
}
|
||||
buf.append(buff);
|
||||
}
|
||||
|
||||
firstParameter = false;
|
||||
}
|
||||
@@ -372,6 +383,20 @@ public class InvocationExprent extends Exprent {
|
||||
return buf;
|
||||
}
|
||||
|
||||
private boolean isVarArgCall() {
|
||||
StructClass cl = DecompilerContext.getStructContext().getClass(classname);
|
||||
if (cl != null) {
|
||||
StructMethod mt = cl.getMethod(InterpreterUtil.makeUniqueKey(name, stringDescriptor));
|
||||
if (mt != null) {
|
||||
return mt.hasModifier(CodeConstants.ACC_VARARGS);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO: try to check the class on the classpath
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isBoxingCall() {
|
||||
if (isStatic && "valueOf".equals(name) && lstParameters.size() == 1) {
|
||||
int paramType = lstParameters.get(0).getExprType().type;
|
||||
|
||||
@@ -44,6 +44,7 @@ public class NewExprent extends Exprent {
|
||||
private List<Exprent> lstDims = new ArrayList<>();
|
||||
private List<Exprent> lstArrayElements = new ArrayList<>();
|
||||
private boolean directArrayInit;
|
||||
private boolean isVarArgParam;
|
||||
private boolean anonymous;
|
||||
private boolean lambda;
|
||||
private boolean enumConst;
|
||||
@@ -349,6 +350,30 @@ public class NewExprent extends Exprent {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isVarArgParam) {
|
||||
// just print the array elements
|
||||
VarType leftType = newType.decreaseArrayDim();
|
||||
for (int i = 0; i < lstArrayElements.size(); i++) {
|
||||
if (i > 0) {
|
||||
buf.append(", ");
|
||||
}
|
||||
|
||||
// new String[][]{{"abc"}, {"DEF"}} => new String[]{"abc"}, new String[]{"DEF"}
|
||||
Exprent element = lstArrayElements.get(i);
|
||||
if (element.type == EXPRENT_NEW) {
|
||||
((NewExprent) element).setDirectArrayInit(false);
|
||||
}
|
||||
ExprProcessor.getCastedExprent(element, leftType, buf, indent, false, tracer);
|
||||
}
|
||||
|
||||
// if there is just one element of Object[] type it needs to be casted to resolve ambiguity
|
||||
if (lstArrayElements.size() == 1) {
|
||||
VarType elementType = lstArrayElements.get(0).getExprType();
|
||||
if (elementType.type == CodeConstants.TYPE_OBJECT && elementType.value.equals("java/lang/Object") && elementType.arrayDim >= 1) {
|
||||
buf.prepend("(Object)");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
buf.append("new ").append(ExprProcessor.getTypeName(newType));
|
||||
|
||||
@@ -478,6 +503,10 @@ public class NewExprent extends Exprent {
|
||||
this.directArrayInit = directArrayInit;
|
||||
}
|
||||
|
||||
public void setVarArgParam(boolean isVarArgParam) {
|
||||
this.isVarArgParam = isVarArgParam;
|
||||
}
|
||||
|
||||
public boolean isLambda() {
|
||||
return lambda;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user