FileDocCategorySizeDatePackage
TransformClassAdapter.javaAPI DocAndroid 1.5 API6684Wed May 06 22:42:02 BST 2009com.android.tools.layoutlib.create

TransformClassAdapter

public class TransformClassAdapter extends org.objectweb.asm.ClassAdapter
Class adapter that can stub some or all of the methods of the class.

Fields Summary
private final boolean
mStubAll
True if all methods should be stubbed, false if only native ones must be stubbed.
private boolean
mIsInterface
True if the class is an interface.
private final String
mClassName
private final Log
mLog
private final Set
mStubMethods
private Set
mDeleteReturns
Constructors Summary
public TransformClassAdapter(Log logger, Set stubMethods, Set deleteReturns, String className, org.objectweb.asm.ClassVisitor cv, boolean stubNativesOnly, boolean hasNative)
Creates a new class adapter that will stub some or all methods.

param
logger
param
stubMethods
param
deleteReturns list of types that trigger the deletion of methods returning them.
param
className The name of the class being modified
param
cv The parent class writer visitor
param
stubNativesOnly True if only native methods should be stubbed. False if all methods should be stubbed.
param
hasNative True if the method has natives, in which case its access should be changed.

        super(cv);
        mLog = logger;
        mStubMethods = stubMethods;
        mClassName = className;
        mStubAll = !stubNativesOnly;
        mIsInterface = false;
        mDeleteReturns = deleteReturns;
    
Methods Summary
org.objectweb.asm.TypereturnType(java.lang.String desc)
Extracts the return {@link Type} of this descriptor.

        if (desc != null) {
            try {
                return Type.getReturnType(desc);
            } catch (ArrayIndexOutOfBoundsException e) {
                // ignore, not a valid type.
            }
        }
        return null;
    
public voidvisit(int version, int access, java.lang.String name, java.lang.String signature, java.lang.String superName, java.lang.String[] interfaces)

        
        // This class might be being renamed.
        name = mClassName;
        
        // remove protected or private and set as public
        access = access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
        access |= Opcodes.ACC_PUBLIC;
        // remove final
        access = access & ~Opcodes.ACC_FINAL;
        // note: leave abstract classes as such
        // don't try to implement stub for interfaces

        mIsInterface = ((access & Opcodes.ACC_INTERFACE) != 0);
        super.visit(version, access, name, signature, superName, interfaces);
    
public org.objectweb.asm.FieldVisitorvisitField(int access, java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.Object value)

        // change access to public
        access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
        access |= Opcodes.ACC_PUBLIC;
        
        return super.visitField(access, name, desc, signature, value);
    
public voidvisitInnerClass(java.lang.String name, java.lang.String outerName, java.lang.String innerName, int access)

        // remove protected or private and set as public
        access = access & ~(Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED);
        access |= Opcodes.ACC_PUBLIC;
        // remove final
        access = access & ~Opcodes.ACC_FINAL;
        // note: leave abstract classes as such
        // don't try to implement stub for interfaces

        super.visitInnerClass(name, outerName, innerName, access);
    
public org.objectweb.asm.MethodVisitorvisitMethod(int access, java.lang.String name, java.lang.String desc, java.lang.String signature, java.lang.String[] exceptions)

        
        if (mDeleteReturns != null) {
            Type t = Type.getReturnType(desc);
            if (t.getSort() == Type.OBJECT) {
                String returnType = t.getInternalName();
                if (returnType != null) {
                    if (mDeleteReturns.contains(returnType)) {
                        return null;
                    }
                }
            }
        }

        String methodSignature = mClassName.replace('/", '.") + "#" + name;

        // change access to public
        access &= ~(Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE);
        access |= Opcodes.ACC_PUBLIC;

        // remove final
        access = access & ~Opcodes.ACC_FINAL;

        // stub this method if they are all to be stubbed or if it is a native method
        // and don't try to stub interfaces nor abstract non-native methods.
        if (!mIsInterface &&
            ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) &&
            (mStubAll ||
             (access & Opcodes.ACC_NATIVE) != 0) ||
             mStubMethods.contains(methodSignature)) {
            
            boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
            boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;

            // remove abstract, final and native
            access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
            
            String invokeSignature = methodSignature + desc;
            mLog.debug("  Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
            
            MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
            return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature,
                    isStatic, isNative);

        } else {
            mLog.debug("  Keep: %s %s", name, desc);
            return super.visitMethod(access, name, desc, signature, exceptions);
        }