From 526aa9aff948a6500bdec5cd07261299ae602a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=A2=A6?= Date: Mon, 7 Aug 2017 17:33:40 +0800 Subject: [PATCH 1/2] add images for wiki --- ...ust\347\273\223\346\236\204\345\233\276.png" | Bin 0 -> 67816 bytes ...243\347\240\201\347\273\223\346\236\204.png" | Bin 0 -> 87947 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 "images/Robust\347\273\223\346\236\204\345\233\276.png" create mode 100644 "images/\350\241\245\344\270\201\344\273\243\347\240\201\347\273\223\346\236\204.png" diff --git "a/images/Robust\347\273\223\346\236\204\345\233\276.png" "b/images/Robust\347\273\223\346\236\204\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..35d8ab10d28b0b9a08270f1b5b3d001ca0bce4d9 GIT binary patch literal 67816 zcmeFZWmuHa+BS@Ypfsp}bT=p<9U>`GN`rJsH%JS}kP;3^gMbRsIY=Yj-NS%%cQY{a z-h+ET&-Xt2+56Xbe80XQ9tv~Mz1F(cwXQhNa~Ywos(^q0@qIKjH2jx}vTxAPFbC1l z?(E>)1%AUZu{Z?$b;s?E!V9#LL8?vQhkMS7dTwZFkC;(^?!0`%bbyBT9POp7wC4Le zJ2319?w49T2l#U-^sGGxm`sdxmk}R@`swIMnAjB)=w7P3eipWfi^jx~XTm1#`5GLK z$$T$zC7o$q;7J2~zpqZC#_3$uI?KQHW^%t~Xg;sLuI_4kuiDn%PHQ3}pj?N=t$Qfo ztg^?Yi&{toak0!AMjLRkQr1S0wwyol=q2UZ;w3oi+TtjL_WEl*S)OnQI}5AWOpiA1 z303u~(GG@<*q^v{Q}|qzIAJYW@m2qE+&cY`Ow{wtut%RZ!o&%^Y4kCV#H-%PO09Tz z9}hE>No0nR($0OezlSbOhl3eJM}!&toCxQC{?M+M`R_hLed)=E=i!xi)GOHk{TpyT z3it8{4yAPMc=WQC$1dbrM468kR4;}T9ORi?CWq>z_G^}dS% z7a6`!H?_$nG+nxn%k~??1HuE|IlRpLUzQ!Wo-N0C1y}~KOOQBWXlLefj95v4+Kv3E zIuoY!>*hR~s-+B@Hp%CUgi#EGYmH%r4b-({@ZmWE;T7*`$#aGwnLW8e>tpf1X8a%T z<9<8>SQ@Z1j(zO9=}-=4GTEgptLVrVB5SOL?D@M>`!asKK7_bkT7I-!=Q&U2l&I37 zVHbnP&hNJK#R*Tf_u!zeZ2QV1;Pvl_fqlv;AF`5{`i4|jliQKI0-tgL&!Tp=?H
  • yArGlwlr2C&UR+_Q_g8hjshI=d>8AE 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 literal 0 HcmV?d00001 diff --git "a/images/\350\241\245\344\270\201\344\273\243\347\240\201\347\273\223\346\236\204.png" "b/images/\350\241\245\344\270\201\344\273\243\347\240\201\347\273\223\346\236\204.png" new file mode 100644 index 0000000000000000000000000000000000000000..e3aafcb9098a9241f69e442f832380d8fdaf443d GIT binary patch literal 87947 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%0AHLWwN33g(p>YlP$^l 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 literal 0 HcmV?d00001 From 231fab02ccab341214f15e1d8d6310008bdbd02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=A2=A6?= Date: Tue, 8 Aug 2017 10:57:16 +0800 Subject: [PATCH 2/2] add some annotation in the code --- .../java/com/meituan/sample/MainActivity.java | 25 +- .../com/meituan/sample/robusttest/Super.java | 1 - .../meituan/sample/robusttest/other/Hll.java | 1 + .../meituan/robust/patch/RobustModify.java | 2 + .../meituan/robust/patch/annotaion/Add.java | 2 + .../robust/patch/annotaion/Modify.java | 1 + .../robust/utils/EnhancedRobustUtils.java | 2 + build.gradle | 4 +- .../gradle/plugin/InsertcodeStrategy.java | 36 +- .../gradle/plugin/RobustApkHashAction.groovy | 2 + .../plugin/RobustApkHashZipUtils.groovy | 7 +- .../gradle/plugin/RobustTransform.groovy | 2 +- .../gradle/plugin/asm/AsmInsertImpl.java | 144 ++-- .../gradle/plugin/asm/RobustAsmUtils.java | 786 +++++++++--------- .../javaassist/JavaAssistInsertImpl.java | 177 ++-- .../com/meituan/robust/PatchedClassInfo.java | 1 + .../java/com/meituan/robust/PatchesInfo.java | 1 + 17 files changed, 618 insertions(+), 576 deletions(-) diff --git a/app/src/main/java/com/meituan/sample/MainActivity.java b/app/src/main/java/com/meituan/sample/MainActivity.java index 653fe775..ac1792a4 100644 --- a/app/src/main/java/com/meituan/sample/MainActivity.java +++ b/app/src/main/java/com/meituan/sample/MainActivity.java @@ -49,6 +49,8 @@ public class MainActivity extends AppCompatActivity { Hll hll = new Hll(false); + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -104,27 +106,28 @@ public void onClick(View v) { e.printStackTrace(); } - System.out.println(" run(String x) "+run("robust ",123)); - System.out.println(" run(People x) "+run(new People(),123d)); - System.out.println(" run(float x) "+run(123f)); - System.out.println(" double run() "+run()); + System.out.println(" run(String x) " + run("robust ", 123)); + System.out.println(" run(People x) " + run(new People(), 123d)); + System.out.println(" run(float x) " + run(123f)); + System.out.println(" double run() " + run()); System.out.println("in MainActivity end "); } - - private String run(String x,int p){ - return x+"meituan"; + private String run(String x, int p) { + return x + "meituan"; } - private String run(People x,double d){ + + private String run(People x, double d) { x.setAddr("meituan"); return x.getAddr(); } - private int run(float x){ - return (int)x; + + private int run(float x) { + return (int) x; } - private double run(){ + private double run() { return 1d; } diff --git a/app/src/main/java/com/meituan/sample/robusttest/Super.java b/app/src/main/java/com/meituan/sample/robusttest/Super.java index 8b3416ab..14fb3613 100644 --- a/app/src/main/java/com/meituan/sample/robusttest/Super.java +++ b/app/src/main/java/com/meituan/sample/robusttest/Super.java @@ -28,7 +28,6 @@ public class Super extends Hll { } - public String[] methodWithArrayParameters(String[] flag) { return flag; } diff --git a/app/src/main/java/com/meituan/sample/robusttest/other/Hll.java b/app/src/main/java/com/meituan/sample/robusttest/other/Hll.java index a477ecf6..66933073 100644 --- a/app/src/main/java/com/meituan/sample/robusttest/other/Hll.java +++ b/app/src/main/java/com/meituan/sample/robusttest/other/Hll.java @@ -23,6 +23,7 @@ public Hll(boolean t) { public Hll() { } + private String privateMethod(int index, String name) { Log.d("robust", "in hll.getStrings() "); packageMethod(1,name); diff --git a/autopatchbase/src/main/java/com/meituan/robust/patch/RobustModify.java b/autopatchbase/src/main/java/com/meituan/robust/patch/RobustModify.java index ae06be22..e9a51ebb 100644 --- a/autopatchbase/src/main/java/com/meituan/robust/patch/RobustModify.java +++ b/autopatchbase/src/main/java/com/meituan/robust/patch/RobustModify.java @@ -2,6 +2,8 @@ /** * Created by mivanzhang on 16/12/9. + *

    + * A backup for annotation Modify, in some situation Modify will not work, such as Generic */ public final class RobustModify { diff --git a/autopatchbase/src/main/java/com/meituan/robust/patch/annotaion/Add.java b/autopatchbase/src/main/java/com/meituan/robust/patch/annotaion/Add.java index 03eddf46..856dd3fb 100644 --- a/autopatchbase/src/main/java/com/meituan/robust/patch/annotaion/Add.java +++ b/autopatchbase/src/main/java/com/meituan/robust/patch/annotaion/Add.java @@ -8,6 +8,8 @@ /** * Created by mivanzhang on 16/12/19. + * 用来标记新增的类和方法 + * annotaion used for add classes or methods,classes and methods will be packed into patch.jar/patch.apk */ @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.CONSTRUCTOR}) diff --git a/autopatchbase/src/main/java/com/meituan/robust/patch/annotaion/Modify.java b/autopatchbase/src/main/java/com/meituan/robust/patch/annotaion/Modify.java index 14fecd6a..5c35014f 100644 --- a/autopatchbase/src/main/java/com/meituan/robust/patch/annotaion/Modify.java +++ b/autopatchbase/src/main/java/com/meituan/robust/patch/annotaion/Modify.java @@ -8,6 +8,7 @@ /** * Created by mivanzhang on 16/12/9. + * annotaion used for modify classes or methods,classes and methods will be packed into patch.jar/patch.apk */ @Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.CLASS) diff --git a/autopatchbase/src/main/java/com/meituan/robust/utils/EnhancedRobustUtils.java b/autopatchbase/src/main/java/com/meituan/robust/utils/EnhancedRobustUtils.java index 22145346..3f96b00e 100644 --- a/autopatchbase/src/main/java/com/meituan/robust/utils/EnhancedRobustUtils.java +++ b/autopatchbase/src/main/java/com/meituan/robust/utils/EnhancedRobustUtils.java @@ -7,6 +7,8 @@ /** * Created by mivanzhang on 16/8/15. + *

    + * A reflect utility class, providing methods for reflecting methods and set/get fields */ public class EnhancedRobustUtils { public static boolean isThrowable = true; diff --git a/build.gradle b/build.gradle index 7b9de258..85388b4c 100644 --- a/build.gradle +++ b/build.gradle @@ -9,8 +9,8 @@ buildscript { classpath 'com.android.tools.build:gradle:2.1.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files - classpath 'com.meituan.robust:gradle-plugin:0.4.5' - classpath 'com.meituan.robust:auto-patch-plugin:0.4.5' + classpath 'com.meituan.robust:gradle-plugin:0.4.7' + classpath 'com.meituan.robust:auto-patch-plugin:0.4.7' classpath 'me.tatarka:gradle-retrolambda:3.2.0' classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' diff --git a/gradle-plugin/src/main/groovy/robust/gradle/plugin/InsertcodeStrategy.java b/gradle-plugin/src/main/groovy/robust/gradle/plugin/InsertcodeStrategy.java index 6739c38b..cee29cf7 100644 --- a/gradle-plugin/src/main/groovy/robust/gradle/plugin/InsertcodeStrategy.java +++ b/gradle-plugin/src/main/groovy/robust/gradle/plugin/InsertcodeStrategy.java @@ -18,13 +18,23 @@ */ public abstract class InsertcodeStrategy { - protected List hotfixPackageList = new ArrayList<>(); - protected List hotfixMethodList = new ArrayList<>(); - protected List exceptPackageList = new ArrayList<>(); - protected List exceptMethodList = new ArrayList<>(); - protected boolean isHotfixMethodLevel = false; - protected boolean isExceptMethodLevel = false; + //packnames need to be insert code 需要插桩的包名列表, + protected List hotfixPackageList = new ArrayList<>(); + //methods list need to insert code 需要插桩的方法列表 + protected List hotfixMethodList = new ArrayList<>(); + + //packnames don`t need to be insert code 不需要插桩的包名列表, + protected List exceptPackageList = new ArrayList<>(); + + //methods list do not need to insert code 不需要插桩的方法列表 + protected List exceptMethodList = new ArrayList<>(); + //a switch control whether need to filter method in hotfixMethodList, if false ,hotfixMethodList will be ignored + protected boolean isHotfixMethodLevel = false; + + //a switch control whether need to filter method in exceptMethodList, if false ,exceptMethodList will be ignored + protected boolean isExceptMethodLevel = false; protected AtomicInteger insertMethodCount = new AtomicInteger(0); + //record every method with unique method number public HashMap methodMap = new HashMap(); public InsertcodeStrategy(List hotfixPackageList, List hotfixMethodList, List exceptPackageList, List exceptMethodList, boolean isHotfixMethodLevel, boolean isExceptMethodLevel) { @@ -37,8 +47,16 @@ public InsertcodeStrategy(List hotfixPackageList, List hotfixMet insertMethodCount.set(0); } + /** + * @param box all classes which will be packed into apk,所有需要打入apk中的类 + * @param jarFile 所有的插桩处理过的class都会被输出的jarFile + * @throws CannotCompileException + * @throws IOException + * @throws NotFoundException + */ protected abstract void insertCode(List box, File jarFile) throws CannotCompileException, IOException, NotFoundException; - protected boolean isNeedInsertClass(String className) { + + protected boolean isNeedInsertClass(String className) { //这样子可以在需要埋点的剔除指定的类 for (String exceptName : exceptPackageList) { @@ -54,14 +72,14 @@ protected boolean isNeedInsertClass(String className) { return false; } - protected void zipFile(byte[] classBytesArray, ZipOutputStream zos, String entryName){ + protected void zipFile(byte[] classBytesArray, ZipOutputStream zos, String entryName) { try { ZipEntry entry = new ZipEntry(entryName); zos.putNextEntry(entry); zos.write(classBytesArray, 0, classBytesArray.length); zos.closeEntry(); zos.flush(); - }catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); } } diff --git a/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustApkHashAction.groovy b/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustApkHashAction.groovy index a6ba12f3..9dc17133 100755 --- a/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustApkHashAction.groovy +++ b/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustApkHashAction.groovy @@ -8,6 +8,8 @@ import java.security.MessageDigest /** * Created by hedex on 17/2/14. + * + * calculate unique string for each apk,you can get the string in file located in build/outputs/robust/robust.apkhash */ class RobustApkHashAction implements Action { @Override diff --git a/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustApkHashZipUtils.groovy b/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustApkHashZipUtils.groovy index 9ad565c9..baeeba8e 100755 --- a/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustApkHashZipUtils.groovy +++ b/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustApkHashZipUtils.groovy @@ -3,6 +3,7 @@ package robust.gradle.plugin import com.meituan.robust.Constants import java.util.zip.* + /** * Created by hedex on 17/2/14. */ @@ -82,7 +83,7 @@ class RobustApkHashZipUtils { while (entries.hasMoreElements()) { // ZipEntry zipEntry = entries.nextElement();//保守 ZipEntry zipEntry = new ZipEntry(entries.nextElement().name); - if (null != zipEntry ) { + if (null != zipEntry) { addZipEntry(zipOutputStream, zipEntry, apZipFile.getInputStream(zipEntry)) } } @@ -116,7 +117,6 @@ class RobustApkHashZipUtils { return crc.getValue(); } - /** * add zip entry * @@ -125,7 +125,8 @@ class RobustApkHashZipUtils { * @param inputStream * @throws Exception */ - private static void addZipEntry(ZipOutputStream zipOutputStream, ZipEntry zipEntry, InputStream inputStream) throws Exception { + private + static void addZipEntry(ZipOutputStream zipOutputStream, ZipEntry zipEntry, InputStream inputStream) throws Exception { try { zipOutputStream.putNextEntry(zipEntry); byte[] buffer = new byte[1024]; diff --git a/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustTransform.groovy b/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustTransform.groovy index e768c175..fee26dfc 100644 --- a/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustTransform.groovy +++ b/gradle-plugin/src/main/groovy/robust/gradle/plugin/RobustTransform.groovy @@ -40,7 +40,7 @@ class RobustTransform extends Transform implements Plugin { robust = new XmlSlurper().parse(new File("${project.projectDir}/${Constants.ROBUST_XML}")) logger = project.logger initConfig() - //turnOnDevelopModel 是true的话,则强制执行插入 + //isForceInsert 是true的话,则强制执行插入 if (!isForceInsert) { def taskNames = project.gradle.startParameter.taskNames def isDebugTask = false; diff --git a/gradle-plugin/src/main/groovy/robust/gradle/plugin/asm/AsmInsertImpl.java b/gradle-plugin/src/main/groovy/robust/gradle/plugin/asm/AsmInsertImpl.java index 22c64a5a..9e375c75 100644 --- a/gradle-plugin/src/main/groovy/robust/gradle/plugin/asm/AsmInsertImpl.java +++ b/gradle-plugin/src/main/groovy/robust/gradle/plugin/asm/AsmInsertImpl.java @@ -34,6 +34,8 @@ /** * Created by zhangmeng on 2017/5/10. + *

    + * insert code using asm */ public class AsmInsertImpl extends InsertcodeStrategy { @@ -45,12 +47,15 @@ public AsmInsertImpl(List hotfixPackageList, List hotfixMethodLi @Override protected void insertCode(List box, File jarFile) throws IOException, CannotCompileException { - ZipOutputStream outStream=new JarOutputStream(new FileOutputStream(jarFile)); - for(CtClass ctClass:box) { + ZipOutputStream outStream = new JarOutputStream(new FileOutputStream(jarFile)); + //get every class in the box ,ready to insert code + for (CtClass ctClass : box) { + //change modifier to public ,so all the class in the apk will be public ,you will be able to access it in the patch ctClass.setModifiers(AccessFlag.setPublic(ctClass.getModifiers())); - if(isNeedInsertClass(ctClass.getName())&&!(ctClass.isInterface() || ctClass.getDeclaredMethods().length < 1)) { + if (isNeedInsertClass(ctClass.getName()) && !(ctClass.isInterface() || ctClass.getDeclaredMethods().length < 1)) { + //only insert code into specific classes zipFile(transformCode(ctClass.toBytecode(), ctClass.getName().replaceAll("\\.", "/")), outStream, ctClass.getName().replaceAll("\\.", "/") + ".class"); - }else { + } else { zipFile(ctClass.toBytecode(), outStream, ctClass.getName().replaceAll("\\.", "/") + ".class"); } @@ -58,65 +63,69 @@ protected void insertCode(List box, File jarFile) throws IOException, C outStream.close(); } - private class InsertMethodBodyAdapter extends ClassVisitor implements Opcodes { + private class InsertMethodBodyAdapter extends ClassVisitor implements Opcodes { public InsertMethodBodyAdapter() { super(Opcodes.ASM5); } + ClassWriter classWriter; private String className; //this maybe change in the future - private Map methodInstructionTypeMap; - public InsertMethodBodyAdapter(ClassWriter cw,String className, Map methodInstructionTypeMap) { - super(Opcodes.ASM5,cw); - this.classWriter =cw; - this.className=className; - this.methodInstructionTypeMap=methodInstructionTypeMap; - classWriter.visitField(Opcodes.ACC_PUBLIC|Opcodes.ACC_STATIC, Constants.INSERT_FIELD_NAME, Type.getDescriptor(ChangeQuickRedirect.class), null, null); + private Map methodInstructionTypeMap; + + public InsertMethodBodyAdapter(ClassWriter cw, String className, Map methodInstructionTypeMap) { + super(Opcodes.ASM5, cw); + this.classWriter = cw; + this.className = className; + this.methodInstructionTypeMap = methodInstructionTypeMap; + //insert the field + classWriter.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, Constants.INSERT_FIELD_NAME, Type.getDescriptor(ChangeQuickRedirect.class), null, null); } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - if(isProtect(access)) { + if (isProtect(access)) { access = setPublic(access); } - // MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); - if (!isQualifiedMethod(access,name,desc,methodInstructionTypeMap)) { + if (!isQualifiedMethod(access, name, desc, methodInstructionTypeMap)) { return mv; } - StringBuilder parameters=new StringBuilder(); - Type[]types=Type.getArgumentTypes(desc); - for(Type type:types){ + StringBuilder parameters = new StringBuilder(); + Type[] types = Type.getArgumentTypes(desc); + for (Type type : types) { parameters.append(type.getClassName()).append(","); } - if(parameters.length() > 0 && parameters.charAt(parameters.length()-1)==','){ - parameters.deleteCharAt(parameters.length()-1); + //remove the last "," + if (parameters.length() > 0 && parameters.charAt(parameters.length() - 1) == ',') { + parameters.deleteCharAt(parameters.length() - 1); } + //record method number + methodMap.put(className.replace('/', '.') + "." + name + "(" + parameters.toString() + ")", insertMethodCount.incrementAndGet()); + return new MethodBodyInsertor(mv, className, desc, isStatic(access), String.valueOf(insertMethodCount.get()), name, access); + } - methodMap.put(className.replace('/','.')+"."+name+"("+parameters.toString()+")", insertMethodCount.incrementAndGet()); - return new MethodBodyInsertor(mv,className,desc,isStatic(access), String .valueOf(insertMethodCount.get()),name,access); + private boolean isProtect(int access) { + return (access & Opcodes.ACC_PROTECTED) != 0; } - private boolean isProtect(int access) { - return (access & Opcodes.ACC_PROTECTED) != 0; - } + private int setPublic(int access) { + return (access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) | Opcodes.ACC_PUBLIC; + } - private int setPublic(int access){ - return (access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) | Opcodes.ACC_PUBLIC; - } - private boolean isQualifiedMethod(int access, String name, String desc,Map methodInstructionTypeMap) { + private boolean isQualifiedMethod(int access, String name, String desc, Map c) { //类初始化函数和构造函数过滤 - if(AsmUtils.CLASS_INITIALIZER.equals(name)||AsmUtils.CONSTRUCTOR.equals(name)){ + if (AsmUtils.CLASS_INITIALIZER.equals(name) || AsmUtils.CONSTRUCTOR.equals(name)) { return false; } //@warn 这部分代码请重点review一下,判断条件写错会要命 //这部分代码请重点review一下,判断条件写错会要命 // synthetic 方法暂时不aop 比如AsyncTask 会生成一些同名 synthetic方法,对synthetic 以及private的方法也插入的代码,主要是针对lambda表达式 - if(((access& Opcodes.ACC_SYNTHETIC) != 0)&&((access & Opcodes.ACC_PRIVATE)==0)){ + if (((access & Opcodes.ACC_SYNTHETIC) != 0) && ((access & Opcodes.ACC_PRIVATE) == 0)) { return false; } if ((access & Opcodes.ACC_ABSTRACT) != 0) { @@ -150,10 +159,9 @@ private boolean isQualifiedMethod(int access, String name, String desc,Map paramsTypeClass=new ArrayList(); + List paramsTypeClass = new ArrayList(); boolean isStatic; //目前methodid是int类型的,未来可能会修改为String类型的,这边进行了一次强转 String methodId; - public MethodBodyInsertor(MethodVisitor mv,String className, String desc, boolean isStatic,String methodId,String name,int access) { + public MethodBodyInsertor(MethodVisitor mv, String className, String desc, boolean isStatic, String methodId, String name, int access) { super(Opcodes.ASM5, mv, access, name, desc); - this.className=className; - this.returnType =Type.getReturnType(desc); + this.className = className; + this.returnType = Type.getReturnType(desc); Type[] argsType = Type.getArgumentTypes(desc); for (Type type : argsType) { paramsTypeClass.add(type); } - this.isStatic=isStatic; - this.methodId =methodId; + this.isStatic = isStatic; + this.methodId = methodId; } @Override public void visitCode() { - RobustAsmUtils.createInsertCode(this,className,paramsTypeClass, returnType,isStatic,Integer.valueOf(methodId)); + //insert code here + RobustAsmUtils.createInsertCode(this, className, paramsTypeClass, returnType, isStatic, Integer.valueOf(methodId)); } } - private boolean isStatic(int access){ + + private boolean isStatic(int access) { return (access & Opcodes.ACC_STATIC) != 0; } - - - } - public byte [] transformCode2(byte []b1, String className) throws IOException { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); - InsertMethodBodyAdapter insertMethodBodyAdapter=new InsertMethodBodyAdapter(cw,className,new HashMap()); - ClassReader cr = new ClassReader(b1); - cr.accept(insertMethodBodyAdapter,ClassReader.EXPAND_FRAMES); - return cw.toByteArray(); } - public byte [] transformCode(byte []b1, String className) throws IOException { + public byte[] transformCode(byte[] b1, String className) throws IOException { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassReader cr = new ClassReader(b1); - ClassNode classNode = new ClassNode(); - Map methodInstructionTypeMap=new HashMap<>(); - cr.accept(classNode,0); + Map methodInstructionTypeMap = new HashMap<>(); + cr.accept(classNode, 0); final List methods = classNode.methods; - for(MethodNode m: methods){ + for (MethodNode m : methods) { InsnList inList = m.instructions; - boolean isMethodInvoke=false; - for(int i = 0; i< inList.size(); i++) { - if(inList.get(i).getType()==AbstractInsnNode.METHOD_INSN) { - isMethodInvoke=true; + boolean isMethodInvoke = false; + for (int i = 0; i < inList.size(); i++) { + if (inList.get(i).getType() == AbstractInsnNode.METHOD_INSN) { + isMethodInvoke = true; } } methodInstructionTypeMap.put(m.name + m.desc, isMethodInvoke); } -// printlnMap(methodInstructionTypeMap); - - InsertMethodBodyAdapter insertMethodBodyAdapter=new InsertMethodBodyAdapter(cw,className,methodInstructionTypeMap); - cr.accept(insertMethodBodyAdapter,ClassReader.EXPAND_FRAMES); + InsertMethodBodyAdapter insertMethodBodyAdapter = new InsertMethodBodyAdapter(cw, className, methodInstructionTypeMap); + cr.accept(insertMethodBodyAdapter, ClassReader.EXPAND_FRAMES); return cw.toByteArray(); } - - public static void main(String []args) throws IOException { - - AsmInsertImpl asmInsert=new AsmInsertImpl(null,null,null,null,false,false); -// byte[]bytes= org.apache.commons.io.FileUtils.readFileToByteArray(new File("/Users/zhangmeng/Downloads/asm-5.2/asm/com/meituan/robust/PatchProxy.class")); -// byte[]bytes= org.apache.commons.io.FileUtils.readFileToByteArray(new File("/Users/zhangmeng/Downloads/asm-5.2/com/meituan/robust/Patch.class")); - byte[]bytes= org.apache.commons.io.FileUtils.readFileToByteArray(new File("/Users/zhangmeng/Desktop/code/openSource/robust/app/build/intermediates/transforms/aspectJ/release/folders/1/1/main/com/meituan/sample/robusttest/People.class")); -// org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("/Users/zhangmeng/Downloads/asm-5.2/asm/com/meituan/robust/PatchProxy2.class"),asmInsert.transformCode2(bytes,"com.meituan.robust.PatchProxy","1231")); -// org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("/Users/zhangmeng/Downloads/asm-5.2/com/meituan/robust/Patch2.class"),asmInsert.transformCode2(bytes,"com.meituan.robust.Patch","1231")); - org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("/Users/zhangmeng/Desktop/code/openSource/robust/app/build/intermediates/transforms/aspectJ/release/folders/1/1/main/com/meituan/sample/robusttest/People2.class"),asmInsert.transformCode2(bytes,"com.meituan.sample.robusttest.People")); - } - private void printlnMap(Map map){ - for (Map.Entry entry : map.entrySet()) { - System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); - - } - } - } diff --git a/gradle-plugin/src/main/groovy/robust/gradle/plugin/asm/RobustAsmUtils.java b/gradle-plugin/src/main/groovy/robust/gradle/plugin/asm/RobustAsmUtils.java index b0d9ce5e..427ed253 100644 --- a/gradle-plugin/src/main/groovy/robust/gradle/plugin/asm/RobustAsmUtils.java +++ b/gradle-plugin/src/main/groovy/robust/gradle/plugin/asm/RobustAsmUtils.java @@ -11,398 +11,404 @@ public final class RobustAsmUtils { - public final static String REDIRECTFIELD_NAME = "changeQuickRedirect"; - public final static String REDIRECTCLASSNAME = Type.getDescriptor(com.meituan.robust.ChangeQuickRedirect.class); - public final static String PROXYCLASSNAME = "com.meituan.robust.PatchProxy".replace(".", "/"); - - /** - * 插入代码 - * @param mv - * @param className - * @param args - * @param returnType - * @param isStatic - */ - public static void createInsertCode(GeneratorAdapter mv, String className, List args, Type returnType, boolean isStatic, int methodId){ - - /** - * 调用isSupport方法 - */ - prepareMethodParameters(mv,className,args,returnType,isStatic,methodId); - //开始调用 - mv.visitMethodInsn(Opcodes.INVOKESTATIC, - PROXYCLASSNAME, - "isSupport", - "([Ljava/lang/Object;Ljava/lang/Object;"+REDIRECTCLASSNAME+"ZI[Ljava/lang/Class;Ljava/lang/Class;)Z"); - Label l1 = new Label(); - mv.visitJumpInsn(Opcodes.IFEQ, l1); - prepareMethodParameters(mv,className,args,returnType,isStatic,methodId); - //开始调用 - mv.visitMethodInsn(Opcodes.INVOKESTATIC, - PROXYCLASSNAME, - "accessDispatch", - "([Ljava/lang/Object;Ljava/lang/Object;"+REDIRECTCLASSNAME+"ZI[Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;"); - - //判断是否有返回值,代码不同 - if("V".equals(returnType.getDescriptor())){ - mv.visitInsn(Opcodes.POP); - mv.visitInsn(Opcodes.RETURN); - }else{ - //强制转化类型 - if(!castPrimateToObj(mv, returnType.getDescriptor())){ - //这里需要注意,如果是数组类型的直接使用即可,如果非数组类型,就得去除前缀了,还有最终是没有结束符; - //比如:Ljava/lang/String; ==》 java/lang/String - String newTypeStr = null; - int len = returnType.getDescriptor().length(); - if(returnType.getDescriptor().startsWith("[")){ - newTypeStr = returnType.getDescriptor().substring(0, len); - }else{ - newTypeStr = returnType.getDescriptor().substring(1, len-1); - } - mv.visitTypeInsn(Opcodes.CHECKCAST, newTypeStr); - } - - //这里还需要做返回类型不同返回指令也不同 - mv.visitInsn(getReturnTypeCode(returnType.getDescriptor())); - } - - mv.visitLabel(l1); - } - - private static void prepareMethodParameters(GeneratorAdapter mv, String className, List args, Type returnType, boolean isStatic, int methodId) { - //第一个参数:new Object[]{...};,如果方法没有参数直接传入new Object[0] - if(args.size() == 0){ - mv.visitInsn(Opcodes.ICONST_0); - mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); - }else{ - createObjectArray(mv, args, isStatic); - } - - //第二个参数:this,如果方法是static的话就直接传入null - if(isStatic){ - mv.visitInsn(Opcodes.ACONST_NULL); - }else{ - mv.visitVarInsn(Opcodes.ALOAD, 0); - } - - //第三个参数:changeQuickRedirect - mv.visitFieldInsn(Opcodes.GETSTATIC, - className, - REDIRECTFIELD_NAME, - REDIRECTCLASSNAME); - - //第四个参数:false,标志是否为static - mv.visitInsn(isStatic ? Opcodes.ICONST_1 : Opcodes.ICONST_0); - //第五个参数: - mv.push(methodId); - //第六个参数:参数class数组 - createClassArray(mv,args); - //第七个参数:返回值类型class - createReturnClass(mv,returnType); - } - - private static void createReturnClass(GeneratorAdapter mv, Type returnType) { - redirectLocal(mv, returnType); - } - - private static void createClassArray(GeneratorAdapter mv, List args){ - // create an array of objects capable of containing all the parameters and optionally the "this" - - createLocals(mv, args); - // we need to maintain the stack index when loading parameters from, as for long and double - // values, it uses 2 stack elements, all others use only 1 stack element. - int stackIndex = 0; - for (int arrayIndex = 0; arrayIndex < args.size(); arrayIndex++) { - Type arg = args.get(arrayIndex); - // duplicate the array of objects reference, it will be used to store the value in. - mv.dup(); - // index in the array of objects to store the boxed parameter. - mv.push(arrayIndex); - // Pushes the appropriate local variable on the stack - redirectLocal(mv, arg); + public final static String REDIRECTFIELD_NAME = "changeQuickRedirect"; + public final static String REDIRECTCLASSNAME = Type.getDescriptor(com.meituan.robust.ChangeQuickRedirect.class); + public final static String PROXYCLASSNAME = "com.meituan.robust.PatchProxy".replace(".", "/"); + + /** + * 插入代码 + * + * @param mv + * @param className + * @param args + * @param returnType + * @param isStatic + */ + public static void createInsertCode(GeneratorAdapter mv, String className, List args, Type returnType, boolean isStatic, int methodId) { + + /** + * 调用isSupport方法 + */ + prepareMethodParameters(mv, className, args, returnType, isStatic, methodId); + //开始调用 + mv.visitMethodInsn(Opcodes.INVOKESTATIC, + PROXYCLASSNAME, + "isSupport", + "([Ljava/lang/Object;Ljava/lang/Object;" + REDIRECTCLASSNAME + "ZI[Ljava/lang/Class;Ljava/lang/Class;)Z"); + Label l1 = new Label(); + mv.visitJumpInsn(Opcodes.IFEQ, l1); + prepareMethodParameters(mv, className, args, returnType, isStatic, methodId); + //开始调用 + mv.visitMethodInsn(Opcodes.INVOKESTATIC, + PROXYCLASSNAME, + "accessDispatch", + "([Ljava/lang/Object;Ljava/lang/Object;" + REDIRECTCLASSNAME + "ZI[Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;"); + + //判断是否有返回值,代码不同 + if ("V".equals(returnType.getDescriptor())) { + mv.visitInsn(Opcodes.POP); + mv.visitInsn(Opcodes.RETURN); + } else { + //强制转化类型 + if (!castPrimateToObj(mv, returnType.getDescriptor())) { + //这里需要注意,如果是数组类型的直接使用即可,如果非数组类型,就得去除前缀了,还有最终是没有结束符; + //比如:Ljava/lang/String; ==》 java/lang/String + String newTypeStr = null; + int len = returnType.getDescriptor().length(); + if (returnType.getDescriptor().startsWith("[")) { + newTypeStr = returnType.getDescriptor().substring(0, len); + } else { + newTypeStr = returnType.getDescriptor().substring(1, len - 1); + } + mv.visitTypeInsn(Opcodes.CHECKCAST, newTypeStr); + } + + //这里还需要做返回类型不同返回指令也不同 + mv.visitInsn(getReturnTypeCode(returnType.getDescriptor())); + } + + mv.visitLabel(l1); + } + + private static void prepareMethodParameters(GeneratorAdapter mv, String className, List args, Type returnType, boolean isStatic, int methodId) { + //第一个参数:new Object[]{...};,如果方法没有参数直接传入new Object[0] + if (args.size() == 0) { + mv.visitInsn(Opcodes.ICONST_0); + mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); + } else { + createObjectArray(mv, args, isStatic); + } + + //第二个参数:this,如果方法是static的话就直接传入null + if (isStatic) { + mv.visitInsn(Opcodes.ACONST_NULL); + } else { + mv.visitVarInsn(Opcodes.ALOAD, 0); + } + + //第三个参数:changeQuickRedirect + mv.visitFieldInsn(Opcodes.GETSTATIC, + className, + REDIRECTFIELD_NAME, + REDIRECTCLASSNAME); + + //第四个参数:false,标志是否为static + mv.visitInsn(isStatic ? Opcodes.ICONST_1 : Opcodes.ICONST_0); + //第五个参数: + mv.push(methodId); + //第六个参数:参数class数组 + createClassArray(mv, args); + //第七个参数:返回值类型class + createReturnClass(mv, returnType); + } + + private static void createReturnClass(GeneratorAdapter mv, Type returnType) { + redirectLocal(mv, returnType); + } + + private static void createClassArray(GeneratorAdapter mv, List args) { + // create an array of objects capable of containing all the parameters and optionally the "this" + + createLocals(mv, args); + // we need to maintain the stack index when loading parameters from, as for long and double + // values, it uses 2 stack elements, all others use only 1 stack element. + int stackIndex = 0; + for (int arrayIndex = 0; arrayIndex < args.size(); arrayIndex++) { + Type arg = args.get(arrayIndex); + // duplicate the array of objects reference, it will be used to store the value in. + mv.dup(); + // index in the array of objects to store the boxed parameter. + mv.push(arrayIndex); + // Pushes the appropriate local variable on the stack + redirectLocal(mv, arg); // mv.visitLdcInsn(Type.getType(arg.getDescriptor())); - // potentially box up intrinsic types. + // potentially box up intrinsic types. // mv.box(arg); - mv.arrayStore(Type.getType(Class.class)); - // stack index must progress according to the parameter type we just processed. + mv.arrayStore(Type.getType(Class.class)); + // stack index must progress according to the parameter type we just processed. // stackIndex += arg.getSize(); - } - } - - /** - * Creates and pushes to the stack the array to hold all the parameters to redirect, and - * optionally this. - */ - protected static void createLocals(GeneratorAdapter mv, List args) { - mv.push(args.size()); - mv.newArray(Type.getType(Class.class)); - } - /** - * Pushes in the stack the value that should be redirected for the given local. - */ - protected static void redirectLocal(GeneratorAdapter mv, Type arg) { - switch (arg.getDescriptor()){ - case "Z": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); - break; - case "B": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); - break; - case "C": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); - break; - case "S": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); - break; - case "I": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); - break; - case "F": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); - break; - case "D": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); - break; - case "J": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); - break; - case "V": - mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Void", "TYPE", "Ljava/lang/Class;"); - break; - default: - mv.visitLdcInsn(Type.getType(arg.getDescriptor())); - } - - } - - /** - * 创建局部参数代码 - * @param mv - * @param paramsTypeClass - * @param isStatic - */ - private static void createObjectArray(MethodVisitor mv, List paramsTypeClass, boolean isStatic){ - //Opcodes.ICONST_0 ~ Opcodes.ICONST_5 这个指令范围 - int argsCount = paramsTypeClass.size(); - //声明 Object[argsCount]; - if(argsCount >= 6){ - mv.visitIntInsn(Opcodes.BIPUSH, argsCount); - }else{ - mv.visitInsn(Opcodes.ICONST_0+argsCount); - } - mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); - - //如果是static方法,没有this隐含参数 - int loadIndex = (isStatic ? 0 : 1); - - //填充数组数据 - for(int i=0;i= 1){ - //这里需要判断当前参数的前面一个参数的类型是什么 - if("J".equals(paramsTypeClass.get(i-1).getDescriptor()) || "D".equals(paramsTypeClass.get(i-1).getDescriptor())){ - //如果前面一个参数是long,double类型,load指令索引就要增加1 - loadIndex ++; - } - } - if(!createPrimateTypeObj(mv, loadIndex, paramsTypeClass.get(i).getDescriptor())){ - mv.visitVarInsn(Opcodes.ALOAD, loadIndex); - mv.visitInsn(Opcodes.AASTORE); - } - loadIndex ++; - } - } - - private static void createBooleanObj(MethodVisitor mv, int argsPostion){ - mv.visitTypeInsn(Opcodes.NEW, "java/lang/Byte"); - mv.visitInsn(Opcodes.DUP); - mv.visitVarInsn(Opcodes.ILOAD, argsPostion); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Byte", "", "(B)V"); - mv.visitInsn(Opcodes.AASTORE); - } - - private static void createShortObj(MethodVisitor mv, int argsPostion){ - mv.visitTypeInsn(Opcodes.NEW, "java/lang/Short"); - mv.visitInsn(Opcodes.DUP); - mv.visitVarInsn(Opcodes.ILOAD, argsPostion); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Short", "", "(S)V"); - mv.visitInsn(Opcodes.AASTORE); - } - - private static void createCharObj(MethodVisitor mv, int argsPostion){ - mv.visitTypeInsn(Opcodes.NEW, "java/lang/Character"); - mv.visitInsn(Opcodes.DUP); - mv.visitVarInsn(Opcodes.ILOAD, argsPostion); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Character", "", "(C)V"); - mv.visitInsn(Opcodes.AASTORE); - } - - private static void createIntegerObj(MethodVisitor mv, int argsPostion){ - mv.visitTypeInsn(Opcodes.NEW, "java/lang/Integer"); - mv.visitInsn(Opcodes.DUP); - mv.visitVarInsn(Opcodes.ILOAD, argsPostion); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Integer", "", "(I)V"); - mv.visitInsn(Opcodes.AASTORE); - } - - private static void createFloatObj(MethodVisitor mv, int argsPostion){ - mv.visitTypeInsn(Opcodes.NEW, "java/lang/Float"); - mv.visitInsn(Opcodes.DUP); - mv.visitVarInsn(Opcodes.FLOAD, argsPostion); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Float", "", "(F)V"); - mv.visitInsn(Opcodes.AASTORE); - } - - private static void createDoubleObj(MethodVisitor mv, int argsPostion){ - mv.visitTypeInsn(Opcodes.NEW, "java/lang/Double"); - mv.visitInsn(Opcodes.DUP); - mv.visitVarInsn(Opcodes.DLOAD, argsPostion); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Double", "", "(D)V"); - mv.visitInsn(Opcodes.AASTORE); - } - - private static void createLongObj(MethodVisitor mv, int argsPostion){ - mv.visitTypeInsn(Opcodes.NEW, "java/lang/Long"); - mv.visitInsn(Opcodes.DUP); - mv.visitVarInsn(Opcodes.LLOAD, argsPostion); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Long", "", "(J)V"); - mv.visitInsn(Opcodes.AASTORE); - } - - /** - * 创建基本类型对应的对象 - * @param mv - * @param argsPostion - * @param typeS - * @return - */ - private static boolean createPrimateTypeObj(MethodVisitor mv, int argsPostion, String typeS){ - if("Z".equals(typeS)){ - createBooleanObj(mv, argsPostion); - return true; - } - if("B".equals(typeS)){ - createBooleanObj(mv, argsPostion); - return true; - } - if("C".equals(typeS)){ - createCharObj(mv, argsPostion); - return true; - } - if("S".equals(typeS)){ - createShortObj(mv, argsPostion); - return true; - } - if("I".equals(typeS)){ - createIntegerObj(mv, argsPostion); - return true; - } - if("F".equals(typeS)){ - createFloatObj(mv, argsPostion); - return true; - } - if("D".equals(typeS)){ - createDoubleObj(mv, argsPostion); - return true; - } - if("J".equals(typeS)){ - createLongObj(mv, argsPostion); - return true; - } - return false; - } - - /** - * 基本类型需要做对象类型分装 - * @param mv - * @param typeS - * @return - */ - private static boolean castPrimateToObj(MethodVisitor mv, String typeS){ - if("Z".equals(typeS)){ - mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean");//强制转化类型 - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); - return true; - } - if("B".equals(typeS)){ - mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Byte");//强制转化类型 - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B"); - return true; - } - if("C".equals(typeS)){ - mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Character");//强制转化类型 - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "intValue", "()C"); - return true; - } - if("S".equals(typeS)){ - mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Short");//强制转化类型 - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); - return true; - } - if("I".equals(typeS)){ - mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Integer");//强制转化类型 - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); - return true; - } - if("F".equals(typeS)){ - mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Float");//强制转化类型 - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); - return true; - } - if("D".equals(typeS)){ - mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Double");//强制转化类型 - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); - return true; - } - if("J".equals(typeS)){ - mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Long");//强制转化类型 - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); - return true; - } - return false; - } - - /** - * 针对不同类型返回指令不一样 - * @param typeS - * @return - */ - private static int getReturnTypeCode(String typeS){ - if("Z".equals(typeS)){ - return Opcodes.IRETURN; - } - if("B".equals(typeS)){ - return Opcodes.IRETURN; - } - if("C".equals(typeS)){ - return Opcodes.IRETURN; - } - if("S".equals(typeS)){ - return Opcodes.IRETURN; - } - if("I".equals(typeS)){ - return Opcodes.IRETURN; - } - if("F".equals(typeS)){ - return Opcodes.FRETURN; - } - if("D".equals(typeS)){ - return Opcodes.DRETURN; - } - if("J".equals(typeS)){ - return Opcodes.LRETURN; - } - return Opcodes.ARETURN; - } + } + } + + /** + * Creates and pushes to the stack the array to hold all the parameters to redirect, and + * optionally this. + */ + protected static void createLocals(GeneratorAdapter mv, List args) { + mv.push(args.size()); + mv.newArray(Type.getType(Class.class)); + } + + /** + * Pushes in the stack the value that should be redirected for the given local. + */ + protected static void redirectLocal(GeneratorAdapter mv, Type arg) { + switch (arg.getDescriptor()) { + case "Z": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); + break; + case "B": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); + break; + case "C": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); + break; + case "S": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); + break; + case "I": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); + break; + case "F": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); + break; + case "D": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); + break; + case "J": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); + break; + case "V": + mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Void", "TYPE", "Ljava/lang/Class;"); + break; + default: + mv.visitLdcInsn(Type.getType(arg.getDescriptor())); + } + + } + + /** + * 创建局部参数代码 + * + * @param mv + * @param paramsTypeClass + * @param isStatic + */ + private static void createObjectArray(MethodVisitor mv, List paramsTypeClass, boolean isStatic) { + //Opcodes.ICONST_0 ~ Opcodes.ICONST_5 这个指令范围 + int argsCount = paramsTypeClass.size(); + //声明 Object[argsCount]; + if (argsCount >= 6) { + mv.visitIntInsn(Opcodes.BIPUSH, argsCount); + } else { + mv.visitInsn(Opcodes.ICONST_0 + argsCount); + } + mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); + + //如果是static方法,没有this隐含参数 + int loadIndex = (isStatic ? 0 : 1); + + //填充数组数据 + for (int i = 0; i < argsCount; i++) { + mv.visitInsn(Opcodes.DUP); + if (i <= 5) { + mv.visitInsn(Opcodes.ICONST_0 + i); + } else { + mv.visitIntInsn(Opcodes.BIPUSH, i); + } + + //这里又要做特殊处理,在实践过程中发现个问题:public void xxx(long a, boolean b, double c,int d) + //当一个参数的前面一个参数是long或者是double类型的话,后面参数在使用LOAD指令,加载数据索引值要+1 + //个人猜想是和long,double是8个字节的问题有关系。这里做了处理 + //比如这里的参数:[a=LLOAD 1] [b=ILOAD 3] [c=DLOAD 4] [d=ILOAD 6]; + if (i >= 1) { + //这里需要判断当前参数的前面一个参数的类型是什么 + if ("J".equals(paramsTypeClass.get(i - 1).getDescriptor()) || "D".equals(paramsTypeClass.get(i - 1).getDescriptor())) { + //如果前面一个参数是long,double类型,load指令索引就要增加1 + loadIndex++; + } + } + if (!createPrimateTypeObj(mv, loadIndex, paramsTypeClass.get(i).getDescriptor())) { + mv.visitVarInsn(Opcodes.ALOAD, loadIndex); + mv.visitInsn(Opcodes.AASTORE); + } + loadIndex++; + } + } + + private static void createBooleanObj(MethodVisitor mv, int argsPostion) { + mv.visitTypeInsn(Opcodes.NEW, "java/lang/Byte"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.ILOAD, argsPostion); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Byte", "", "(B)V"); + mv.visitInsn(Opcodes.AASTORE); + } + + private static void createShortObj(MethodVisitor mv, int argsPostion) { + mv.visitTypeInsn(Opcodes.NEW, "java/lang/Short"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.ILOAD, argsPostion); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Short", "", "(S)V"); + mv.visitInsn(Opcodes.AASTORE); + } + + private static void createCharObj(MethodVisitor mv, int argsPostion) { + mv.visitTypeInsn(Opcodes.NEW, "java/lang/Character"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.ILOAD, argsPostion); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Character", "", "(C)V"); + mv.visitInsn(Opcodes.AASTORE); + } + + private static void createIntegerObj(MethodVisitor mv, int argsPostion) { + mv.visitTypeInsn(Opcodes.NEW, "java/lang/Integer"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.ILOAD, argsPostion); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Integer", "", "(I)V"); + mv.visitInsn(Opcodes.AASTORE); + } + + private static void createFloatObj(MethodVisitor mv, int argsPostion) { + mv.visitTypeInsn(Opcodes.NEW, "java/lang/Float"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.FLOAD, argsPostion); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Float", "", "(F)V"); + mv.visitInsn(Opcodes.AASTORE); + } + + private static void createDoubleObj(MethodVisitor mv, int argsPostion) { + mv.visitTypeInsn(Opcodes.NEW, "java/lang/Double"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.DLOAD, argsPostion); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Double", "", "(D)V"); + mv.visitInsn(Opcodes.AASTORE); + } + + private static void createLongObj(MethodVisitor mv, int argsPostion) { + mv.visitTypeInsn(Opcodes.NEW, "java/lang/Long"); + mv.visitInsn(Opcodes.DUP); + mv.visitVarInsn(Opcodes.LLOAD, argsPostion); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Long", "", "(J)V"); + mv.visitInsn(Opcodes.AASTORE); + } + + /** + * 创建基本类型对应的对象 + * + * @param mv + * @param argsPostion + * @param typeS + * @return + */ + private static boolean createPrimateTypeObj(MethodVisitor mv, int argsPostion, String typeS) { + if ("Z".equals(typeS)) { + createBooleanObj(mv, argsPostion); + return true; + } + if ("B".equals(typeS)) { + createBooleanObj(mv, argsPostion); + return true; + } + if ("C".equals(typeS)) { + createCharObj(mv, argsPostion); + return true; + } + if ("S".equals(typeS)) { + createShortObj(mv, argsPostion); + return true; + } + if ("I".equals(typeS)) { + createIntegerObj(mv, argsPostion); + return true; + } + if ("F".equals(typeS)) { + createFloatObj(mv, argsPostion); + return true; + } + if ("D".equals(typeS)) { + createDoubleObj(mv, argsPostion); + return true; + } + if ("J".equals(typeS)) { + createLongObj(mv, argsPostion); + return true; + } + return false; + } + + /** + * 基本类型需要做对象类型分装 + * + * @param mv + * @param typeS + * @return + */ + private static boolean castPrimateToObj(MethodVisitor mv, String typeS) { + if ("Z".equals(typeS)) { + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean");//强制转化类型 + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); + return true; + } + if ("B".equals(typeS)) { + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Byte");//强制转化类型 + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B"); + return true; + } + if ("C".equals(typeS)) { + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Character");//强制转化类型 + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "intValue", "()C"); + return true; + } + if ("S".equals(typeS)) { + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Short");//强制转化类型 + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S"); + return true; + } + if ("I".equals(typeS)) { + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Integer");//强制转化类型 + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I"); + return true; + } + if ("F".equals(typeS)) { + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Float");//强制转化类型 + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F"); + return true; + } + if ("D".equals(typeS)) { + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Double");//强制转化类型 + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D"); + return true; + } + if ("J".equals(typeS)) { + mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Long");//强制转化类型 + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J"); + return true; + } + return false; + } + + /** + * 针对不同类型返回指令不一样 + * + * @param typeS + * @return + */ + private static int getReturnTypeCode(String typeS) { + if ("Z".equals(typeS)) { + return Opcodes.IRETURN; + } + if ("B".equals(typeS)) { + return Opcodes.IRETURN; + } + if ("C".equals(typeS)) { + return Opcodes.IRETURN; + } + if ("S".equals(typeS)) { + return Opcodes.IRETURN; + } + if ("I".equals(typeS)) { + return Opcodes.IRETURN; + } + if ("F".equals(typeS)) { + return Opcodes.FRETURN; + } + if ("D".equals(typeS)) { + return Opcodes.DRETURN; + } + if ("J".equals(typeS)) { + return Opcodes.LRETURN; + } + return Opcodes.ARETURN; + } } \ No newline at end of file diff --git a/gradle-plugin/src/main/groovy/robust/gradle/plugin/javaassist/JavaAssistInsertImpl.java b/gradle-plugin/src/main/groovy/robust/gradle/plugin/javaassist/JavaAssistInsertImpl.java index 8e03769d..a077fd04 100644 --- a/gradle-plugin/src/main/groovy/robust/gradle/plugin/javaassist/JavaAssistInsertImpl.java +++ b/gradle-plugin/src/main/groovy/robust/gradle/plugin/javaassist/JavaAssistInsertImpl.java @@ -30,6 +30,7 @@ /** * Created by zhangmeng on 2017/5/10. + * this class do almost the same thing with AsmInsertImpl */ public class JavaAssistInsertImpl extends InsertcodeStrategy { @@ -40,57 +41,64 @@ public JavaAssistInsertImpl(List hotfixPackageList, List hotfixM @Override protected void insertCode(List box, File jarFile) throws CannotCompileException, IOException, NotFoundException { - ZipOutputStream outStream=new JarOutputStream(new FileOutputStream(jarFile)); + ZipOutputStream outStream = new JarOutputStream(new FileOutputStream(jarFile)); // new ForkJoinPool().submit { - for(CtClass ctClass:box) { - if (isNeedInsertClass(ctClass.getName())) { - ctClass.setModifiers(AccessFlag.setPublic(ctClass.getModifiers())); - if (ctClass.isInterface() || ctClass.getDeclaredMethods().length < 1) { - zipFile(ctClass.toBytecode(), outStream, ctClass.getName().replaceAll("\\.", "/") + ".class"); + for (CtClass ctClass : box) { + if (isNeedInsertClass(ctClass.getName())) { + //change class modifier + ctClass.setModifiers(AccessFlag.setPublic(ctClass.getModifiers())); + if (ctClass.isInterface() || ctClass.getDeclaredMethods().length < 1) { + //skip the unsatisfied class + zipFile(ctClass.toBytecode(), outStream, ctClass.getName().replaceAll("\\.", "/") + ".class"); + continue; + } + + boolean addIncrementalChange = false; + for (CtBehavior ctBehavior : ctClass.getDeclaredBehaviors()) { + if (!addIncrementalChange) { + //insert the field + addIncrementalChange = true; + ClassPool classPool = ctBehavior.getDeclaringClass().getClassPool(); + CtClass type = classPool.getOrNull(Constants.INTERFACE_NAME); + CtField ctField = new CtField(type, Constants.INSERT_FIELD_NAME, ctClass); + ctField.setModifiers(AccessFlag.PUBLIC | AccessFlag.STATIC); + ctClass.addField(ctField); + } + if (!isQualifiedMethod(ctBehavior)) { continue; } - - boolean addIncrementalChange = false; - for (CtBehavior ctBehavior : ctClass.getDeclaredBehaviors()) { - if (!addIncrementalChange) { - addIncrementalChange = true; - ClassPool classPool = ctBehavior.getDeclaringClass().getClassPool(); - CtClass type = classPool.getOrNull(Constants.INTERFACE_NAME); - CtField ctField = new CtField(type, Constants.INSERT_FIELD_NAME, ctClass); - ctField.setModifiers(AccessFlag.PUBLIC | AccessFlag.STATIC); - ctClass.addField(ctField); - } - if(!isQualifiedMethod(ctBehavior)){ - continue; - } - //here comes the method will be inserted code - methodMap.put(ctBehavior.getLongName(), insertMethodCount.incrementAndGet()); - try { - if (ctBehavior.getMethodInfo().isMethod()) { - CtMethod ctMethod=(CtMethod)ctBehavior; - boolean isStatic = (ctMethod.getModifiers() & AccessFlag.STATIC)!= 0; - CtClass returnType = ctMethod.getReturnType(); - String returnTypeString = returnType.getName(); - String body = "Object argThis = null;"; - if (!isStatic) { - body += "argThis = $0;"; - } - String parametersClassType=getParametersClassType(ctMethod); -// body += " if (com.meituan.robust.PatchProxy.isSupport(\$args, argThis, ${Constants.INSERT_FIELD_NAME}, $isStatic, " + methodMap.get(ctBehavior.longName) + ",${parametersClassType},${returnTypeString}.class)) {" - body += " if (com.meituan.robust.PatchProxy.isSupport($args, argThis, "+Constants.INSERT_FIELD_NAME+", "+isStatic+ - ", " + methodMap.get(ctBehavior.getLongName()) + ","+parametersClassType+","+returnTypeString+".class)) {"; - body += getReturnStatement(returnTypeString, isStatic, methodMap.get(ctBehavior.getLongName()),parametersClassType,returnTypeString+".class"); - body += " }"; - ctBehavior.insertBefore(body); + //here comes the method will be inserted code + methodMap.put(ctBehavior.getLongName(), insertMethodCount.incrementAndGet()); + try { + if (ctBehavior.getMethodInfo().isMethod()) { + CtMethod ctMethod = (CtMethod) ctBehavior; + boolean isStatic = (ctMethod.getModifiers() & AccessFlag.STATIC) != 0; + CtClass returnType = ctMethod.getReturnType(); + String returnTypeString = returnType.getName(); + //construct the code will be inserted in string format + String body = "Object argThis = null;"; + if (!isStatic) { + body += "argThis = $0;"; } - } catch (Throwable t ) { - t.printStackTrace(); - System.out.println("ctClass: " + ctClass.getName() + " error: " + t.getMessage()); + String parametersClassType = getParametersClassType(ctMethod); +// body += " if (com.meituan.robust.PatchProxy.isSupport(\$args, argThis, ${Constants.INSERT_FIELD_NAME}, $isStatic, " + methodMap.get(ctBehavior.longName) + ",${parametersClassType},${returnTypeString}.class)) {" + body += " if (com.meituan.robust.PatchProxy.isSupport($args, argThis, " + Constants.INSERT_FIELD_NAME + ", " + isStatic + + ", " + methodMap.get(ctBehavior.getLongName()) + "," + parametersClassType + "," + returnTypeString + ".class)) {"; + body += getReturnStatement(returnTypeString, isStatic, methodMap.get(ctBehavior.getLongName()), parametersClassType, returnTypeString + ".class"); + body += " }"; + //finish the insert-code body ,let`s insert it + ctBehavior.insertBefore(body); } + } catch (Throwable t) { + //here we ignore the error + t.printStackTrace(); + System.out.println("ctClass: " + ctClass.getName() + " error: " + t.getMessage()); } } - zipFile(ctClass.toBytecode(), outStream, ctClass.getName().replaceAll("\\.", "/") + ".class"); } + //zip the inserted-classes into output file + zipFile(ctClass.toBytecode(), outStream, ctClass.getName().replaceAll("\\.", "/") + ".class"); + } // }.get() outStream.close(); } @@ -146,25 +154,28 @@ private boolean isQualifiedMethod(CtBehavior it) throws CannotCompileException { return !isHotfixMethodLevel; } - private String getParametersClassType(CtMethod method) throws NotFoundException { - if(method.getParameterTypes().length==0){ + private String getParametersClassType(CtMethod method) throws NotFoundException { + if (method.getParameterTypes().length == 0) { return " null "; } - StringBuilder parameterType=new StringBuilder(); + StringBuilder parameterType = new StringBuilder(); parameterType.append("new Class[]{"); - for(CtClass paramterClass:method.getParameterTypes()){ + for (CtClass paramterClass : method.getParameterTypes()) { parameterType.append(paramterClass.getName()).append(".class,"); } //remove last ',' - if(','==parameterType.charAt(parameterType.length()-1)) - parameterType.deleteCharAt(parameterType.length()-1); + if (',' == parameterType.charAt(parameterType.length() - 1)) + parameterType.deleteCharAt(parameterType.length() - 1); parameterType.append("}"); return parameterType.toString(); } + //判断代码中是否有方法调用 private boolean isCallMethod = false; + /** * 判断是否有方法调用 + * * @return 是否插桩 */ private boolean isMethodWithExpression(CtMethod ctMethod) throws CannotCompileException { @@ -189,14 +200,18 @@ private boolean isMethodWithExpression(CtMethod ctMethod) throws CannotCompileEx * @param a the new expression for creating an array. * @throws CannotCompileException */ - public void edit(NewArray a) throws CannotCompileException { isCallMethod = true; } + public void edit(NewArray a) throws CannotCompileException { + isCallMethod = true; + } /** * Edits a method call (overridable). * * The default implementation performs nothing. */ - public void edit(MethodCall m) throws CannotCompileException { isCallMethod = true; } + public void edit(MethodCall m) throws CannotCompileException { + isCallMethod = true; + } /** * Edits a constructor call (overridable). @@ -216,79 +231,87 @@ public void edit(ConstructorCall c) throws CannotCompileException { * Edits an instanceof expression (overridable). * The default implementation performs nothing. */ - public void edit(Instanceof i) throws CannotCompileException { isCallMethod = true; } + public void edit(Instanceof i) throws CannotCompileException { + isCallMethod = true; + } /** * Edits an expression for explicit type casting (overridable). * The default implementation performs nothing. */ - public void edit(Cast c) throws CannotCompileException { isCallMethod = true; } + public void edit(Cast c) throws CannotCompileException { + isCallMethod = true; + } /** * Edits a catch clause (overridable). * The default implementation performs nothing. */ - public void edit(Handler h) throws CannotCompileException { isCallMethod = true; } + public void edit(Handler h) throws CannotCompileException { + isCallMethod = true; + } }); return isCallMethod; } + /** * 根据传入类型判断调用PathProxy的方法 - * @param type 返回类型 - * @param isStatic 是否是静态方法 + * + * @param type 返回类型 + * @param isStatic 是否是静态方法 * @param methodNumber 方法数 * @return 返回return语句 */ - private String getReturnStatement(String type, boolean isStatic, int methodNumber,String parametersClassType,String returnTypeString) { + private String getReturnStatement(String type, boolean isStatic, int methodNumber, String parametersClassType, String returnTypeString) { switch (type) { case Constants.CONSTRUCTOR: - return " com.meituan.robust.PatchProxy.accessDispatchVoid( $args, argThis, changeQuickRedirect, "+isStatic+", "+methodNumber+","+parametersClassType+","+returnTypeString+"); "; + return " com.meituan.robust.PatchProxy.accessDispatchVoid( $args, argThis, changeQuickRedirect, " + isStatic + ", " + methodNumber + "," + parametersClassType + "," + returnTypeString + "); "; case Constants.LANG_VOID: - return " com.meituan.robust.PatchProxy.accessDispatchVoid( $args, argThis, changeQuickRedirect, "+isStatic+", "+methodNumber+","+parametersClassType+","+returnTypeString+"); return null;"; + return " com.meituan.robust.PatchProxy.accessDispatchVoid( $args, argThis, changeQuickRedirect, " + isStatic + ", " + methodNumber + "," + parametersClassType + "," + returnTypeString + "); return null;"; case Constants.VOID: - return " com.meituan.robust.PatchProxy.accessDispatchVoid( $args, argThis, changeQuickRedirect, "+isStatic+", "+methodNumber+","+parametersClassType+","+returnTypeString+"); return ;"; + return " com.meituan.robust.PatchProxy.accessDispatchVoid( $args, argThis, changeQuickRedirect, " + isStatic + ", " + methodNumber + "," + parametersClassType + "," + returnTypeString + "); return ;"; case Constants.LANG_BOOLEAN: - return " return ((java.lang.Boolean)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+"));"; + return " return ((java.lang.Boolean)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + "));"; case Constants.BOOLEAN: - return " return ((java.lang.Boolean)com.meituan.robust.PatchProxy.accessDispatch($args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+")).booleanValue();"; + return " return ((java.lang.Boolean)com.meituan.robust.PatchProxy.accessDispatch($args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")).booleanValue();"; case Constants.INT: - return " return ((java.lang.Integer)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+")).intValue();"; + return " return ((java.lang.Integer)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")).intValue();"; case Constants.LANG_INT: - return " return ((java.lang.Integer)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+methodNumber+","+parametersClassType+","+returnTypeString+")); "; + return " return ((java.lang.Integer)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")); "; case Constants.LONG: - return " return ((java.lang.Long)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+")).longValue();"; + return " return ((java.lang.Long)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")).longValue();"; case Constants.LANG_LONG: - return " return ((java.lang.Long)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+"));"; + return " return ((java.lang.Long)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + "));"; case Constants.DOUBLE: - return " return ((java.lang.Double)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+")).doubleValue();"; + return " return ((java.lang.Double)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")).doubleValue();"; case Constants.LANG_DOUBLE: - return " return ((java.lang.Double)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+"));"; + return " return ((java.lang.Double)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + "));"; case Constants.FLOAT: - return " return ((java.lang.Float)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+")).floatValue();"; + return " return ((java.lang.Float)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")).floatValue();"; case Constants.LANG_FLOAT: - return " return ((java.lang.Float)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+"));"; + return " return ((java.lang.Float)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + "));"; case Constants.SHORT: - return " return ((java.lang.Short)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+")).shortValue();"; + return " return ((java.lang.Short)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")).shortValue();"; case Constants.LANG_SHORT: - return " return ((java.lang.Short)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+"));"; + return " return ((java.lang.Short)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + "));"; case Constants.BYTE: - return " return ((java.lang.Byte)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+")).byteValue();"; + return " return ((java.lang.Byte)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")).byteValue();"; case Constants.LANG_BYTE: - return " return ((java.lang.Byte)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+"));"; + return " return ((java.lang.Byte)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + "));"; case Constants.CHAR: - return " return ((java.lang.Character)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+")).charValue();"; + return " return ((java.lang.Character)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ")).charValue();"; case Constants.LANG_CHARACTER: - return " return ((java.lang.Character)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+"));"; + return " return ((java.lang.Character)com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + "));"; default: - return " return ("+type+")com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, "+isStatic+","+ methodNumber+","+parametersClassType+","+returnTypeString+");"; + return " return (" + type + ")com.meituan.robust.PatchProxy.accessDispatch( $args, argThis, changeQuickRedirect, " + isStatic + "," + methodNumber + "," + parametersClassType + "," + returnTypeString + ");"; } } } diff --git a/patch/src/main/java/com/meituan/robust/PatchedClassInfo.java b/patch/src/main/java/com/meituan/robust/PatchedClassInfo.java index cf73c488..40e628c3 100644 --- a/patch/src/main/java/com/meituan/robust/PatchedClassInfo.java +++ b/patch/src/main/java/com/meituan/robust/PatchedClassInfo.java @@ -2,6 +2,7 @@ /** * Created by hedex on 16/6/3. + * a map record the class name before ProGuard and after ProGuard */ public class PatchedClassInfo { public String patchedClassName; diff --git a/patch/src/main/java/com/meituan/robust/PatchesInfo.java b/patch/src/main/java/com/meituan/robust/PatchesInfo.java index 80b9aa72..c2f9f950 100644 --- a/patch/src/main/java/com/meituan/robust/PatchesInfo.java +++ b/patch/src/main/java/com/meituan/robust/PatchesInfo.java @@ -4,6 +4,7 @@ /** * Created by c_kunwu on 16/5/12. + * an interface describe patch.jar info */ public interface PatchesInfo { List getPatchedClassesInfo();