1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2008 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage com.android.tools.layoutlib.create; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.AnnotationVisitor; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.Attribute; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.Label; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.MethodVisitor; 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.Opcodes; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.objectweb.asm.Type; 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This method adapter rewrites a method by discarding the original code and generating 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * a stub depending on the return type. Original annotations are passed along unchanged. 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass StubMethodAdapter extends MethodVisitor { 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32d2a411840c58eaee05499bab0190e3f3656e2e84Deepanshu Gupta private static final String CONSTRUCTOR = "<init>"; 33d2a411840c58eaee05499bab0190e3f3656e2e84Deepanshu Gupta private static final String CLASS_INIT = "<clinit>"; 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** The parent method writer */ 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private MethodVisitor mParentVisitor; 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** The method return type. Can be null. */ 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private Type mReturnType; 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Message to be printed by stub methods. */ 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private String mInvokeSignature; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Flag to output the first line number. */ 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private boolean mOutputFirstLineNumber = true; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** Flag that is true when implementing a constructor, to accept all original 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * code calling the original super constructor. */ 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private boolean mIsInitMethod = false; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private boolean mMessageGenerated; 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final boolean mIsStatic; 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final boolean mIsNative; 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public StubMethodAdapter(MethodVisitor mv, String methodName, Type returnType, 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String invokeSignature, boolean isStatic, boolean isNative) { 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski super(Opcodes.ASM4); 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor = mv; 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mReturnType = returnType; 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mInvokeSignature = invokeSignature; 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIsStatic = isStatic; 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIsNative = isNative; 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (CONSTRUCTOR.equals(methodName) || CLASS_INIT.equals(methodName)) { 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIsInitMethod = true; 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void generateInvoke() { 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* Generates the code: 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * OverrideMethod.invoke("signature", mIsNative ? true : false, null or this); 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitLdcInsn(mInvokeSignature); 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // push true or false 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(mIsNative ? Opcodes.ICONST_1 : Opcodes.ICONST_0); 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // push null or this 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsStatic) { 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.ACONST_NULL); 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitVarInsn(Opcodes.ALOAD, 0); 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int sort = mReturnType != null ? mReturnType.getSort() : Type.VOID; 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski switch(sort) { 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.VOID: 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "invokeV", 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "(Ljava/lang/String;ZLjava/lang/Object;)V"); 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.RETURN); 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.BOOLEAN: 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.CHAR: 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.BYTE: 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.SHORT: 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.INT: 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "invokeI", 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "(Ljava/lang/String;ZLjava/lang/Object;)I"); 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski switch(sort) { 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.BOOLEAN: 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Label l1 = new Label(); 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitJumpInsn(Opcodes.IFEQ, l1); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.ICONST_1); 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.IRETURN); 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitLabel(l1); 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.ICONST_0); 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.CHAR: 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.I2C); 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.BYTE: 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.I2B); 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.SHORT: 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.I2S); 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.IRETURN); 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.LONG: 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "invokeL", 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "(Ljava/lang/String;ZLjava/lang/Object;)J"); 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.LRETURN); 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.FLOAT: 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "invokeF", 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "(Ljava/lang/String;ZLjava/lang/Object;)F"); 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.FRETURN); 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.DOUBLE: 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "invokeD", 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "(Ljava/lang/String;ZLjava/lang/Object;)D"); 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.DRETURN); 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.ARRAY: 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.OBJECT: 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "com/android/tools/layoutlib/create/OverrideMethod", 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "invokeA", 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "(Ljava/lang/String;ZLjava/lang/Object;)Ljava/lang/Object;"); 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitTypeInsn(Opcodes.CHECKCAST, mReturnType.getInternalName()); 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.ARETURN); 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private void generatePop() { 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* Pops the stack, depending on the return type. 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski switch(mReturnType != null ? mReturnType.getSort() : Type.VOID) { 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.VOID: 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.BOOLEAN: 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.CHAR: 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.BYTE: 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.SHORT: 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.INT: 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.FLOAT: 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.ARRAY: 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.OBJECT: 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.POP); 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.LONG: 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Type.DOUBLE: 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(Opcodes.POP2); 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski break; 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* Pass down to visitor writer. In this implementation, either do nothing. */ 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitCode() { 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitCode(); 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * visitMaxs is called just before visitEnd if there was any code to rewrite. 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * For non-constructor, generate the messaging code and the return statement 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * if it hasn't been done before. 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMaxs(int maxStack, int maxLocals) { 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!mIsInitMethod && !mMessageGenerated) { 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generateInvoke(); 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mMessageGenerated = true; 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMaxs(maxStack, maxLocals); 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * End of visiting. 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * For non-constructor, generate the messaging code and the return statement 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * if it hasn't been done before. 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitEnd() { 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!mIsInitMethod && !mMessageGenerated) { 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generateInvoke(); 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mMessageGenerated = true; 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMaxs(1, 1); 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitEnd(); 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* Writes all annotation from the original method. */ 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mParentVisitor.visitAnnotation(desc, visible); 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* Writes all annotation default values from the original method. */ 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitAnnotationDefault() { 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mParentVisitor.visitAnnotationDefault(); 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean visible) { 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mParentVisitor.visitParameterAnnotation(parameter, desc, visible); 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* Writes all attributes from the original method. */ 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitAttribute(Attribute attr) { 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitAttribute(attr); 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Only writes the first line number present in the original code so that source 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * viewers can direct to the correct method, even if the content doesn't match. 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLineNumber(int line, Label start) { 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod || mOutputFirstLineNumber) { 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitLineNumber(line, start); 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOutputFirstLineNumber = false; 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * For non-constructor, rewrite existing "return" instructions to write the message. 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitInsn(int opcode) { 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski switch (opcode) { 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Opcodes.RETURN: 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Opcodes.ARETURN: 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Opcodes.DRETURN: 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Opcodes.FRETURN: 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Opcodes.IRETURN: 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski case Opcodes.LRETURN: 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Pop the last word from the stack since invoke will generate its own return. 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generatePop(); 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generateInvoke(); 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mMessageGenerated = true; 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //$FALL-THROUGH$ 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski default: 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitInsn(opcode); 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLabel(Label label) { 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitLabel(label); 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitTryCatchBlock(start, end, handler, type); 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMethodInsn(int opcode, String owner, String name, String desc) { 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMethodInsn(opcode, owner, name, desc); 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitFieldInsn(int opcode, String owner, String name, String desc) { 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitFieldInsn(opcode, owner, name, desc); 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitFrame(type, nLocal, local, nStack, stack); 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitIincInsn(int var, int increment) { 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitIincInsn(var, increment); 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitIntInsn(int opcode, int operand) { 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitIntInsn(opcode, operand); 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitJumpInsn(int opcode, Label label) { 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitJumpInsn(opcode, label); 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLdcInsn(Object cst) { 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitLdcInsn(cst); 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLocalVariable(String name, String desc, String signature, 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Label start, Label end, int index) { 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitLocalVariable(name, desc, signature, start, end, index); 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitLookupSwitchInsn(dflt, keys, labels); 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitMultiANewArrayInsn(String desc, int dims) { 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitMultiANewArrayInsn(desc, dims); 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitTableSwitchInsn(min, max, dflt, labels); 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitTypeInsn(int opcode, String type) { 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitTypeInsn(opcode, type); 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void visitVarInsn(int opcode, int var) { 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mIsInitMethod) { 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mParentVisitor.visitVarInsn(opcode, var); 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 377