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