com.googlecode.dex2jar.ir.ts.MultiArrayTransformer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle Show documentation
Show all versions of gradle Show documentation
fakeradnroid gradle builder
package com.googlecode.dex2jar.ir.ts;
import com.googlecode.d2j.DexType;
import com.googlecode.dex2jar.ir.IrMethod;
import com.googlecode.dex2jar.ir.StmtTraveler;
import com.googlecode.dex2jar.ir.expr.*;
/**
* dex does have the instruction to create a multi-array. the implement is to
* using the Array.newInstance().
* transform
*
* ((String[][][])Array.newInstance(String.class,new int[]{4, 5, 6}))
*
* to
*
* new String[4][5][6]
*
*/
public class MultiArrayTransformer extends StatedTransformer {
@Override
public boolean transformReportChanged(IrMethod method) {
final boolean changed[] = {false};
new StmtTraveler() {
@Override
public Value travel(Value op) {
if (op.vt == Value.VT.CHECK_CAST) {
TypeExpr te = (TypeExpr) op;
if (te.op.vt == Value.VT.CHECK_CAST) {
TypeExpr te2 = (TypeExpr) te.op;
if (te.type.equals(te2.type)) {
op = te2;
}
}
}
op = super.travel(op);
if (op.vt == Value.VT.CHECK_CAST) {
TypeExpr te = (TypeExpr) op;
if (te.type.charAt(0) == '[') {
Value from = te.getOp();
if (from.vt == Value.VT.INVOKE_STATIC) {
InvokeExpr invokeExpr = (InvokeExpr) from;
if (invokeExpr.getName().equals("newInstance")
&& invokeExpr.getOwner().equals("Ljava/lang/reflect/Array;")
&& invokeExpr.getArgs().length == 2
&& invokeExpr.getArgs()[0].equals("Ljava/lang/Class;")) {
Value arg0 = invokeExpr.getOps()[0];
String elementType = null;
if (arg0.vt == Value.VT.CONSTANT) {
elementType = ((DexType) ((Constant) invokeExpr.getOps()[0]).value).desc;
} else {
if (arg0.vt == Value.VT.STATIC_FIELD) {
StaticFieldExpr sfe = (StaticFieldExpr) arg0;
if (sfe.owner.startsWith("Ljava/lang/") && sfe.name.equals("TYPE")) {
switch (sfe.owner) {
case "Ljava/lang/Boolean;":
elementType = "Z";
break;
case "Ljava/lang/Byte;":
elementType = "B";
break;
case "Ljava/lang/Short;":
elementType = "S";
break;
case "Ljava/lang/Character;":
elementType = "C";
break;
case "Ljava/lang/Integer;":
elementType = "I";
break;
case "Ljava/lang/Long;":
elementType = "J";
break;
case "Ljava/lang/Float;":
elementType = "F";
break;
case "Ljava/lang/Double;":
elementType = "D";
break;
case "Ljava/lang/Void;":
elementType = "V";
break;
default:
}
}
}
}
if (elementType != null) {
Value dt = invokeExpr.getOps()[1];
if (invokeExpr.getArgs()[1].equals("I")) {
if (te.type.equals("[" + elementType)) {
int d = 0;
while (elementType.charAt(d) == '[') {
d++;
}
changed[0] = true;
if (d > 0) {
return Exprs.nNewMutiArray(elementType.substring(d), d + 1, new Value[]{dt});
} else {
return Exprs.nNewArray(elementType, dt);
}
}
} else {// [I
if (dt.vt == Value.VT.FILLED_ARRAY) {
FilledArrayExpr filledArrayExpr = (FilledArrayExpr) dt;
int d = filledArrayExpr.getOps().length;
if (te.type.length() > d && te.type.substring(d).equals(elementType)) {
int d1 = 0;
while (elementType.charAt(d1) == '[') {
d1++;
}
changed[0] = true;
return Exprs.nNewMutiArray(elementType.substring(d1), d1 + d, filledArrayExpr.getOps());
}
}
}
}
}
}
}
}
return op;
}
}.travel(method);
return changed[0];
}
}