11160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta/* 21160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * Copyright (C) 2014 The Android Open Source Project 31160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * 41160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 51160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * you may not use this file except in compliance with the License. 61160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * You may obtain a copy of the License at 71160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * 81160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * http://www.apache.org/licenses/LICENSE-2.0 91160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * 101160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * Unless required by applicable law or agreed to in writing, software 111160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * distributed under the License is distributed on an "AS IS" BASIS, 121160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * See the License for the specific language governing permissions and 141160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta * limitations under the License. 151160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta */ 161160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta 171160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Guptapackage com.android.tools.layoutlib.create; 181160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta 191330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Guptaimport com.android.tools.layoutlib.java.LinkedHashMap_Delegate; 2017a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Guptaimport com.android.tools.layoutlib.java.System_Delegate; 2117a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta 221160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Guptaimport org.objectweb.asm.ClassVisitor; 231160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Guptaimport org.objectweb.asm.MethodVisitor; 241160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Guptaimport org.objectweb.asm.Opcodes; 25b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Guptaimport org.objectweb.asm.Type; 261160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta 275cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Guptaimport java.util.ArrayList; 28e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Guptaimport java.util.Arrays; 29e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Guptaimport java.util.HashSet; 301330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Guptaimport java.util.LinkedHashMap; 315cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Guptaimport java.util.List; 32b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Guptaimport java.util.Locale; 331330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Guptaimport java.util.Map; 34e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Guptaimport java.util.Set; 35e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta 361160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta/** 375cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta * Replaces calls to certain methods that do not exist in the Desktop VM. Useful for methods in the 385cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta * "java" package. 391160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta */ 401160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Guptapublic class ReplaceMethodCallsAdapter extends ClassVisitor { 41e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta 42e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta /** 43e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta * Descriptors for specialized versions {@link System#arraycopy} that are not present on the 44e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta * Desktop VM. 45e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta */ 46e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta private static Set<String> ARRAYCOPY_DESCRIPTORS = new HashSet<String>(Arrays.asList( 47e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta "([CI[CII)V", "([BI[BII)V", "([SI[SII)V", "([II[III)V", 48e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta "([JI[JII)V", "([FI[FII)V", "([DI[DII)V", "([ZI[ZII)V")); 49e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta 501330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta private static final List<MethodReplacer> METHOD_REPLACERS = new ArrayList<MethodReplacer>(5); 515cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta 52b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta private static final String ANDROID_LOCALE_CLASS = 53b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta "com/android/layoutlib/bridge/android/AndroidLocale"; 54b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta 5517a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta private static final String JAVA_LOCALE_CLASS = Type.getInternalName(java.util.Locale.class); 56b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta private static final Type STRING = Type.getType(String.class); 57b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta 5817a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta private static final String JAVA_LANG_SYSTEM = Type.getInternalName(System.class); 5917a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta 605cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta // Static initialization block to initialize METHOD_REPLACERS. 615cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta static { 625cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta // Case 1: java.lang.System.arraycopy() 635cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta METHOD_REPLACERS.add(new MethodReplacer() { 645cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta @Override 655cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta public boolean isNeeded(String owner, String name, String desc) { 6617a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta return JAVA_LANG_SYSTEM.equals(owner) && "arraycopy".equals(name) && 675cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta ARRAYCOPY_DESCRIPTORS.contains(desc); 685cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 695cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta 705cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta @Override 7117a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public void replace(MethodInformation mi) { 7217a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta assert isNeeded(mi.owner, mi.name, mi.desc); 7317a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta mi.desc = "(Ljava/lang/Object;ILjava/lang/Object;II)V"; 745cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 755cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta }); 765cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta 77b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta // Case 2: java.util.Locale.toLanguageTag() and java.util.Locale.getScript() 785cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta METHOD_REPLACERS.add(new MethodReplacer() { 79b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta 801330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta private final String LOCALE_TO_STRING = 811330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta Type.getMethodDescriptor(STRING, Type.getType(Locale.class)); 82b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta 83b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta @Override 84b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta public boolean isNeeded(String owner, String name, String desc) { 85b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta return JAVA_LOCALE_CLASS.equals(owner) && "()Ljava/lang/String;".equals(desc) && 86b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta ("toLanguageTag".equals(name) || "getScript".equals(name)); 87b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta } 88b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta 89b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta @Override 9017a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public void replace(MethodInformation mi) { 9117a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta assert isNeeded(mi.owner, mi.name, mi.desc); 9217a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta mi.opcode = Opcodes.INVOKESTATIC; 9317a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta mi.owner = ANDROID_LOCALE_CLASS; 9417a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta mi.desc = LOCALE_TO_STRING; 95b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta } 96b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta }); 97b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta 98b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta // Case 3: java.util.Locale.adjustLanguageCode() or java.util.Locale.forLanguageTag() 99b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta METHOD_REPLACERS.add(new MethodReplacer() { 100b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta 101b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta private final String STRING_TO_STRING = Type.getMethodDescriptor(STRING, STRING); 102b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta private final String STRING_TO_LOCALE = Type.getMethodDescriptor( 103b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta Type.getType(Locale.class), STRING); 104b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta 1055cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta @Override 1065cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta public boolean isNeeded(String owner, String name, String desc) { 107b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta return JAVA_LOCALE_CLASS.equals(owner) && 108b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta ("adjustLanguageCode".equals(name) && desc.equals(STRING_TO_STRING) || 109b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta "forLanguageTag".equals(name) && desc.equals(STRING_TO_LOCALE)); 1105cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 1115cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta 1125cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta @Override 11317a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public void replace(MethodInformation mi) { 11417a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta assert isNeeded(mi.owner, mi.name, mi.desc); 11517a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta mi.owner = ANDROID_LOCALE_CLASS; 11617a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta } 11717a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta }); 11817a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta 11917a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta // Case 4: java.lang.System.log?() 12017a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta METHOD_REPLACERS.add(new MethodReplacer() { 12117a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta @Override 12217a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public boolean isNeeded(String owner, String name, String desc) { 12317a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta return JAVA_LANG_SYSTEM.equals(owner) && name.length() == 4 12417a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta && name.startsWith("log"); 12517a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta } 12617a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta 12717a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta @Override 12817a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public void replace(MethodInformation mi) { 12917a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta assert isNeeded(mi.owner, mi.name, mi.desc); 13017a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta assert mi.desc.equals("(Ljava/lang/String;Ljava/lang/Throwable;)V") 13117a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta || mi.desc.equals("(Ljava/lang/String;)V"); 13217a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta mi.name = "log"; 13317a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta mi.owner = Type.getInternalName(System_Delegate.class); 1345cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 1355cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta }); 1361330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta 1371330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta // Case 5: java.util.LinkedHashMap.eldest() 1381330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta METHOD_REPLACERS.add(new MethodReplacer() { 1391330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta 1401330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta private final String VOID_TO_MAP_ENTRY = 1411330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta Type.getMethodDescriptor(Type.getType(Map.Entry.class)); 1421330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta private final String LINKED_HASH_MAP = Type.getInternalName(LinkedHashMap.class); 1431330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta 1441330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta @Override 1451330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta public boolean isNeeded(String owner, String name, String desc) { 1461330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta return LINKED_HASH_MAP.equals(owner) && 1471330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta "eldest".equals(name) && 1481330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta VOID_TO_MAP_ENTRY.equals(desc); 1491330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta } 1501330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta 1511330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta @Override 1521330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta public void replace(MethodInformation mi) { 1531330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta assert isNeeded(mi.owner, mi.name, mi.desc); 1541330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta mi.opcode = Opcodes.INVOKESTATIC; 1551330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta mi.owner = Type.getInternalName(LinkedHashMap_Delegate.class); 1561330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta mi.desc = Type.getMethodDescriptor( 1571330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta Type.getType(Map.Entry.class), Type.getType(LinkedHashMap.class)); 1581330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta } 1591330f79f95fd14b53c393402fbcbf7b7bbdcbc60Deepanshu Gupta }); 1605cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 1615cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta 1625cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta public static boolean isReplacementNeeded(String owner, String name, String desc) { 1635cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta for (MethodReplacer replacer : METHOD_REPLACERS) { 1645cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta if (replacer.isNeeded(owner, name, desc)) { 1655cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta return true; 1665cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 1675cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 1685cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta return false; 1695cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 1705cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta 1711160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta public ReplaceMethodCallsAdapter(ClassVisitor cv) { 1721160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta super(Opcodes.ASM4, cv); 1731160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta } 1741160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta 1751160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta @Override 1761160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta public MethodVisitor visitMethod(int access, String name, String desc, String signature, 1771160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta String[] exceptions) { 1781160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta return new MyMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions)); 1791160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta } 1801160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta 1811160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta private class MyMethodVisitor extends MethodVisitor { 1821160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta 1831160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta public MyMethodVisitor(MethodVisitor mv) { 1841160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta super(Opcodes.ASM4, mv); 1851160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta } 1861160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta 1871160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta @Override 1881160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta public void visitMethodInsn(int opcode, String owner, String name, String desc) { 1895cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta for (MethodReplacer replacer : METHOD_REPLACERS) { 1905cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta if (replacer.isNeeded(owner, name, desc)) { 19117a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta MethodInformation mi = new MethodInformation(opcode, owner, name, desc); 19217a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta replacer.replace(mi); 19317a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta opcode = mi.opcode; 19417a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta owner = mi.owner; 19517a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta name = mi.name; 19617a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta desc = mi.desc; 1975cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta break; 198e1960cc0b541cda93db94de5bef42dff922b9ec3Deepanshu Gupta } 1991160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta } 2001160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta super.visitMethodInsn(opcode, owner, name, desc); 2011160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta } 2021160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta } 2035cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta 20417a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta private static class MethodInformation { 20517a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public int opcode; 20617a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public String owner; 20717a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public String name; 20817a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public String desc; 20917a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta 21017a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public MethodInformation(int opcode, String owner, String name, String desc) { 21117a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta this.opcode = opcode; 21217a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta this.owner = owner; 21317a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta this.name = name; 21417a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta this.desc = desc; 21517a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta } 21617a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta } 21717a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta 2185cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta private interface MethodReplacer { 2195cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta public boolean isNeeded(String owner, String name, String desc); 2205cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta 2215cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta /** 22217a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta * Updates the MethodInformation with the new values of the method attributes - 223b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta * opcode, owner, name and desc. 224b80e42f93ff26984c410da0235dd10f463e5722aDeepanshu Gupta * 2255cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta */ 22617a6170c62e6f74f2881623a9c16f0b6fea54721Deepanshu Gupta public void replace(MethodInformation mi); 2275cd9dde5a2a77c5095f985186d8f03147fd22870Deepanshu Gupta } 2281160e6d2f7018117b0c29a7e2adba9ece36faec1Deepanshu Gupta} 229