/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.mkstubs.stubber; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Attribute; import org.objectweb.asm.Label; import org.objectweb.asm.MethodAdapter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; /** * A method visitor that generates a code stub for the visited method. * <p/> * Annotations and parameters are passed as-is. * All other code is replaced by the following: * <pre>throw new RuntimeException("stub");</pre> * Note that constructors rewritten this way will probably fail with the runtime bytecode * verifier since no call to <code>super</code> is generated. */ public class MethodStubber extends MethodAdapter { public MethodStubber(MethodVisitor mw, int access, String name, String desc, String signature, String[] exceptions) { super(mw); } @Override public void visitCode() { Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(36, l0); mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException"); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn("stub"); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, // opcode "java/lang/RuntimeException", // owner "<init>", // name "(Ljava/lang/String;)V"); // desc mv.visitInsn(Opcodes.ATHROW); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable( "this", // name "Lcom/android/mkstubs/stubber/MethodStubber;", // desc null, // signature l0, // label start l1, // label end 0); // index mv.visitMaxs(3, 1); // maxStack, maxLocals } @Override public void visitEnd() { super.visitEnd(); } @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { return super.visitAnnotation(desc, visible); } @Override public AnnotationVisitor visitAnnotationDefault() { return super.visitAnnotationDefault(); } @Override public void visitAttribute(Attribute attr) { super.visitAttribute(attr); } @Override public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { return super.visitParameterAnnotation(parameter, desc, visible); } // -- stuff that gets skipped @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) { // skip } @Override public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) { // skip } @Override public void visitIincInsn(int var, int increment) { // skip } @Override public void visitInsn(int opcode) { // skip } @Override public void visitIntInsn(int opcode, int operand) { // skip } @Override public void visitJumpInsn(int opcode, Label label) { // skip } @Override public void visitLabel(Label label) { // skip } @Override public void visitLdcInsn(Object cst) { // skip } @Override public void visitLineNumber(int line, Label start) { // skip } @Override public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { // skip } @Override public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { // skip } @Override public void visitMaxs(int maxStack, int maxLocals) { // skip } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { // skip } @Override public void visitMultiANewArrayInsn(String desc, int dims) { // skip } @Override public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { // skip } @Override public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { // skip } @Override public void visitTypeInsn(int opcode, String type) { // skip } @Override public void visitVarInsn(int opcode, int var) { // skip } }