Update mkstubs from ASM 3.1 to ASM 4.0

Change-Id: If43fcdba7070af8ae3d72e7e30a1dcbe11a217ec
This commit is contained in:
Tor Norbye
2011-12-05 14:30:02 -08:00
parent 629fb72e6f
commit 7fb8be5c6a
10 changed files with 150 additions and 86 deletions

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="tests"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-3.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="tests"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-4.0.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -20,7 +20,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_JAR_MANIFEST := manifest.txt
LOCAL_STATIC_JAVA_LIBRARIES := \
asm-3.1
asm-4.0
LOCAL_MODULE := mkstubs

View File

@@ -20,7 +20,6 @@ import com.android.mkstubs.Main.Logger;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
@@ -30,14 +29,14 @@ import org.objectweb.asm.Opcodes;
* A class visitor that filters out all members (fields, methods and inner classes) that are
* either private, default-access or rejected by the {@link Filter}.
*/
class FilterClassAdapter extends ClassAdapter {
class FilterClassAdapter extends ClassVisitor {
private final Logger mLog;
private final Filter mFilter;
private String mClassName;
public FilterClassAdapter(ClassVisitor writer, Filter filter, Logger log) {
super(writer);
super(Opcodes.ASM4, writer);
mFilter = filter;
mLog = log;
}

View File

@@ -17,11 +17,12 @@
package com.android.mkstubs.sourcer;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;
/**
* An annotation visitor that generates Java source for an annotation.
*/
class AnnotationSourcer implements AnnotationVisitor {
class AnnotationSourcer extends AnnotationVisitor {
private final String mOpenChar;
private final String mCloseChar;
@@ -33,11 +34,13 @@ class AnnotationSourcer implements AnnotationVisitor {
}
public AnnotationSourcer(Output output, boolean isArray) {
super(Opcodes.ASM4);
mOutput = output;
mOpenChar = isArray ? "[" : "(";
mCloseChar = isArray ? "]" : ")";
}
@Override
public void visit(String name, Object value) {
startOpen();
@@ -56,6 +59,7 @@ class AnnotationSourcer implements AnnotationVisitor {
}
}
@Override
public void visitEnd() {
if (mNeedClose) {
mOutput.write(mCloseChar);
@@ -63,18 +67,21 @@ class AnnotationSourcer implements AnnotationVisitor {
mOutput.write("\n");
}
@Override
public AnnotationVisitor visitAnnotation(String name, String desc) {
startOpen();
mOutput.write("@%s", name);
return this;
}
@Override
public AnnotationVisitor visitArray(String name) {
startOpen();
return new AnnotationSourcer(mOutput, true /*isArray*/);
}
@Override
public void visitEnum(String name, String desc, String value) {
mOutput.write("/* annotation enum not supported: %s */\n", name);
}

View File

@@ -27,23 +27,25 @@ import org.objectweb.asm.signature.SignatureReader;
/**
* A class visitor that writes a java source.
*/
public class ClassSourcer implements ClassVisitor {
public class ClassSourcer extends ClassVisitor {
private final Output mOutput;
private final AccessSourcer mAccessSourcer;
private String mClassName;
public ClassSourcer(Output output) {
super(Opcodes.ASM4);
mOutput = output;
mAccessSourcer = new AccessSourcer(mOutput);
}
/* Examples:
* name = com/foo/MyClass
* signature = null (if not generic)
* superName = java/lang/Object
* interfaces = [ java/lang/Runnable ... ]
*/
@Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
@@ -63,13 +65,13 @@ public class ClassSourcer implements ClassVisitor {
SignatureReader sigReader = new SignatureReader(signature);
SignatureSourcer sigSourcer = new SignatureSourcer();
sigReader.accept(sigSourcer);
if (sigSourcer.hasFormalsContent()) {
mOutput.write(sigSourcer.formalsToString());
}
mOutput.write(" extends %s", sigSourcer.getSuperClass().toString());
} else {
// write non-generic super type
mOutput.write(" extends %s", superName.replace('/', '.'));
@@ -87,35 +89,40 @@ public class ClassSourcer implements ClassVisitor {
need_sep = true;
}
}
// open class body
mOutput.write(" {\n");
}
@Override
public void visitEnd() {
mOutput.write("}\n");
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
mOutput.write("@%s", desc);
return new AnnotationSourcer(mOutput);
}
@Override
public void visitAttribute(Attribute attr) {
mOutput.write("%s /* non-standard class attribute */ ", attr.type);
}
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature,
Object value) {
// skip synthetic fields
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
return null;
}
return new FieldSourcer(mOutput, access, name, desc, signature);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature,
String[] exceptions) {
@@ -123,15 +130,18 @@ public class ClassSourcer implements ClassVisitor {
return new MethodSourcer(mOutput, mClassName, access, name, desc, signature, exceptions);
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
// Skip inner classes. This just indicates there's an inner class definition but
// they are visited at the top level as separate classes.
}
@Override
public void visitOuterClass(String owner, String name, String desc) {
// Skip outer classes.
}
@Override
public void visitSource(String source, String debug) {
// Skip source information.
}

View File

@@ -19,13 +19,14 @@ package com.android.mkstubs.sourcer;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader;
/**
* A field visitor that generates Java source defining a field.
* A field visitor that generates Java source defining a field.
*/
class FieldSourcer implements FieldVisitor {
class FieldSourcer extends FieldVisitor {
private final Output mOutput;
private final int mAccess;
@@ -34,6 +35,7 @@ class FieldSourcer implements FieldVisitor {
private final String mSignature;
public FieldSourcer(Output output, int access, String name, String desc, String signature) {
super(Opcodes.ASM4);
mOutput = output;
mAccess = access;
mName = name;
@@ -41,21 +43,24 @@ class FieldSourcer implements FieldVisitor {
mSignature = signature;
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
mOutput.write("@%s", desc);
return new AnnotationSourcer(mOutput);
}
@Override
public void visitAttribute(Attribute attr) {
mOutput.write("%s /* non-standard attribute */ ", attr.type);
}
@Override
public void visitEnd() {
// Need to write type and field name after the annotations and attributes.
AccessSourcer as = new AccessSourcer(mOutput);
as.write(mAccess, AccessSourcer.IS_FIELD);
if (mSignature == null) {
mOutput.write(" %s", Type.getType(mDesc).getClassName());
} else {

View File

@@ -20,15 +20,16 @@ import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader;
import java.util.ArrayList;
/**
* A method visitor that generates the Java source for a whole method.
* A method visitor that generates the Java source for a whole method.
*/
class MethodSourcer implements MethodVisitor {
class MethodSourcer extends MethodVisitor {
private final Output mOutput;
private final int mAccess;
@@ -42,6 +43,7 @@ class MethodSourcer implements MethodVisitor {
public MethodSourcer(Output output, String className, int access, String name,
String desc, String signature, String[] exceptions) {
super(Opcodes.ASM4);
mOutput = output;
mClassName = className;
mAccess = access;
@@ -49,16 +51,16 @@ class MethodSourcer implements MethodVisitor {
mDesc = desc;
mSignature = signature;
mExceptions = exceptions;
mNeedDeclaration = true;
mIsConstructor = "<init>".equals(name);
}
private void writeHeader() {
private void writeHeader() {
if (!mNeedDeclaration) {
return;
}
AccessSourcer as = new AccessSourcer(mOutput);
as.write(mAccess, AccessSourcer.IS_METHOD);
@@ -68,19 +70,19 @@ class MethodSourcer implements MethodVisitor {
SignatureReader sigReader = new SignatureReader(mSignature);
sigSourcer = new SignatureSourcer();
sigReader.accept(sigSourcer);
if (sigSourcer.hasFormalsContent()) {
// dump formal template parameter definitions
mOutput.write(" %s", sigSourcer.formalsToString());
}
}
// output return type (constructor have no return type)
if (!mIsConstructor) {
// The signature overrides desc, if present
if (sigSourcer == null || sigSourcer.getReturnType() == null) {
mOutput.write(" %s", Type.getReturnType(mDesc).getClassName());
} else {
mOutput.write(" %s", sigSourcer.getReturnType().toString());
}
@@ -88,11 +90,11 @@ class MethodSourcer implements MethodVisitor {
// output name
mOutput.write(" %s(", mIsConstructor ? mClassName : mName);
// output arguments. The signature overrides desc, if present
if (mSignature == null) {
Type[] types = Type.getArgumentTypes(mDesc);
for(int i = 0; i < types.length; i++) {
if (i > 0) {
mOutput.write(", ");
@@ -101,7 +103,7 @@ class MethodSourcer implements MethodVisitor {
}
} else {
ArrayList<SignatureSourcer> params = sigSourcer.getParameters();
for(int i = 0; i < params.size(); i++) {
if (i > 0) {
mOutput.write(", ");
@@ -114,7 +116,7 @@ class MethodSourcer implements MethodVisitor {
// output throwable exceptions
if (mExceptions != null && mExceptions.length > 0) {
mOutput.write(" throws ");
for (int i = 0; i < mExceptions.length; i++) {
if (i > 0) {
mOutput.write(", ");
@@ -128,106 +130,130 @@ class MethodSourcer implements MethodVisitor {
mNeedDeclaration = false;
}
@Override
public void visitCode() {
writeHeader();
// write the stub itself
mOutput.write("throw new RuntimeException(\"Stub\");");
}
@Override
public void visitEnd() {
writeHeader();
mOutput.write("\n}\n");
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
mOutput.write("@%s", desc);
return new AnnotationSourcer(mOutput);
}
@Override
public AnnotationVisitor visitAnnotationDefault() {
// pass
return null;
}
@Override
public void visitAttribute(Attribute attr) {
mOutput.write("%s /* non-standard method attribute */ ", attr.type);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
// pass
}
@Override
public void visitFrame(int type, int local, Object[] local2, int stack, Object[] stack2) {
// pass
}
@Override
public void visitIincInsn(int var, int increment) {
// pass
}
@Override
public void visitInsn(int opcode) {
// pass
}
@Override
public void visitIntInsn(int opcode, int operand) {
// pass
}
@Override
public void visitJumpInsn(int opcode, Label label) {
// pass
}
@Override
public void visitLabel(Label label) {
// pass
}
@Override
public void visitLdcInsn(Object cst) {
// pass
}
@Override
public void visitLineNumber(int line, Label start) {
// pass
}
@Override
public void visitLocalVariable(String name, String desc, String signature,
Label start, Label end, int index) {
// pass
}
@Override
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
// pass
}
@Override
public void visitMaxs(int maxStack, int maxLocals) {
// pass
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
// pass
}
@Override
public void visitMultiANewArrayInsn(String desc, int dims) {
// pass
}
@Override
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
// pass
return null;
}
@Override
public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
// pass
}
@Override
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
// pass
}
@Override
public void visitTypeInsn(int opcode, String type) {
// pass
}
@Override
public void visitVarInsn(int opcode, int var) {
// pass
}

View File

@@ -16,6 +16,7 @@
package com.android.mkstubs.sourcer;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureReader;
import org.objectweb.asm.signature.SignatureVisitor;
@@ -36,12 +37,12 @@ import java.util.ArrayList;
* <p/>
* Note: When processing a method's signature, the signature order is the reverse of the source
* order, e.g. the signature is written as "(parameters)return-type" where we want to generate
* "return-type method-name (parameters)". To hanlde this case, the return-type and parameters
* "return-type method-name (parameters)". To handle this case, the return-type and parameters
* are <em>not</em> output directly but are instead accumulated in internal variables that you can
* get later using {@link #getReturnType()}, {@link #getParameters()}, {@link #getSuperClass()}
* and {@link #formalsToString()}.
*/
class SignatureSourcer implements SignatureVisitor {
class SignatureSourcer extends SignatureVisitor {
/**
* Buffer used to construct the signature.
@@ -85,13 +86,14 @@ class SignatureSourcer implements SignatureVisitor {
private ArrayList<SignatureSourcer> mParameters = new ArrayList<SignatureSourcer>();
/**
* Constructs a new {@link SignatureWriter} object.
*/
public SignatureSourcer() {
super(Opcodes.ASM4);
}
private StringBuilder getBuf() {
if (mWritingFormals) {
return mFormalsBuf;
@@ -117,7 +119,7 @@ class SignatureSourcer implements SignatureVisitor {
public SignatureSourcer getReturnType() {
return mReturnType;
}
/**
* Will be non-empty if a parameters were processed
* by {@link SignatureReader#accept(SignatureVisitor)}
@@ -125,19 +127,19 @@ class SignatureSourcer implements SignatureVisitor {
public ArrayList<SignatureSourcer> getParameters() {
return mParameters;
}
/**
* True if the signature contains formal type parameters, which are available
* True if the signature contains formal type parameters, which are available
* via {@link #formalsToString()} after calling {@link SignatureReader#accept(SignatureVisitor)}
*/
public boolean hasFormalsContent() {
return mFormalsBuf.length() > 0;
}
public String formalsToString() {
return mFormalsBuf.toString();
}
/**
* Will be non-null if a super class was processed
* by {@link SignatureReader#accept(SignatureVisitor)}
@@ -150,6 +152,7 @@ class SignatureSourcer implements SignatureVisitor {
// Implementation of the SignatureVisitor interface
// ------------------------------------------------------------------------
@Override
public void visitFormalTypeParameter(final String name) {
if (!mWritingFormals) {
mWritingFormals = true;
@@ -161,16 +164,19 @@ class SignatureSourcer implements SignatureVisitor {
getBuf().append(" extends ");
}
@Override
public SignatureVisitor visitClassBound() {
// we don't differentiate between visiting a sub class or interface type
// we don't differentiate between visiting a sub class or interface type
return this;
}
@Override
public SignatureVisitor visitInterfaceBound() {
// we don't differentiate between visiting a sub class or interface type
// we don't differentiate between visiting a sub class or interface type
return this;
}
@Override
public SignatureVisitor visitSuperclass() {
endFormals();
SignatureSourcer sourcer = new SignatureSourcer();
@@ -179,10 +185,12 @@ class SignatureSourcer implements SignatureVisitor {
return sourcer;
}
@Override
public SignatureVisitor visitInterface() {
return this;
}
@Override
public SignatureVisitor visitParameterType() {
endFormals();
SignatureSourcer sourcer = new SignatureSourcer();
@@ -190,6 +198,7 @@ class SignatureSourcer implements SignatureVisitor {
return sourcer;
}
@Override
public SignatureVisitor visitReturnType() {
endFormals();
SignatureSourcer sourcer = new SignatureSourcer();
@@ -198,29 +207,35 @@ class SignatureSourcer implements SignatureVisitor {
return sourcer;
}
@Override
public SignatureVisitor visitExceptionType() {
getBuf().append('^');
return this;
}
@Override
public void visitBaseType(final char descriptor) {
getBuf().append(Type.getType(Character.toString(descriptor)).getClassName());
}
@Override
public void visitTypeVariable(final String name) {
getBuf().append(name.replace('/', '.'));
}
@Override
public SignatureVisitor visitArrayType() {
getBuf().append('[');
return this;
}
@Override
public void visitClassType(final String name) {
getBuf().append(name.replace('/', '.'));
mArgumentStack *= 2;
}
@Override
public void visitInnerClassType(final String name) {
endArguments();
getBuf().append('.');
@@ -228,6 +243,7 @@ class SignatureSourcer implements SignatureVisitor {
mArgumentStack *= 2;
}
@Override
public void visitTypeArgument() {
if (mArgumentStack % 2 == 0) {
++mArgumentStack;
@@ -238,6 +254,7 @@ class SignatureSourcer implements SignatureVisitor {
getBuf().append('*');
}
@Override
public SignatureVisitor visitTypeArgument(final char wildcard) {
if (mArgumentStack % 2 == 0) {
++mArgumentStack;
@@ -258,6 +275,7 @@ class SignatureSourcer implements SignatureVisitor {
return this;
}
@Override
public void visitEnd() {
endArguments();
}

View File

@@ -18,19 +18,19 @@ package com.android.mkstubs.stubber;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassAdapter;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
/**
* A class visitor that generates stubs for all methods of the visited class.
* Everything else is passed as-is.
*/
public class ClassStubber extends ClassAdapter {
public class ClassStubber extends ClassVisitor {
public ClassStubber(ClassVisitor cv) {
super(cv);
super(Opcodes.ASM4, cv);
}
@Override
@@ -41,45 +41,45 @@ public class ClassStubber extends ClassAdapter {
String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visitEnd() {
super.visitEnd();
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
return super.visitAnnotation(desc, visible);
}
@Override
public void visitAttribute(Attribute attr) {
super.visitAttribute(attr);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature,
String[] exceptions) {
MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
return new MethodStubber(mw, access, name, desc, signature, exceptions);
}
@Override
public FieldVisitor visitField(int access, String name, String desc, String signature,
Object value) {
return super.visitField(access, name, desc, signature, value);
}
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
super.visitInnerClass(name, outerName, innerName, access);
}
@Override
public void visitOuterClass(String owner, String name, String desc) {
super.visitOuterClass(owner, name, desc);
}
@Override
public void visitSource(String source, String debug) {
super.visitSource(source, debug);

View File

@@ -19,7 +19,6 @@ 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;
@@ -32,13 +31,13 @@ import org.objectweb.asm.Opcodes;
* 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 class MethodStubber extends MethodVisitor {
public MethodStubber(MethodVisitor mw,
int access, String name, String desc, String signature, String[] exceptions) {
super(mw);
super(Opcodes.ASM4, mw);
}
@Override
public void visitCode() {
Label l0 = new Label();
@@ -64,7 +63,7 @@ public class MethodStubber extends MethodAdapter {
0); // index
mv.visitMaxs(3, 1); // maxStack, maxLocals
}
@Override
public void visitEnd() {
super.visitEnd();
@@ -74,110 +73,110 @@ public class MethodStubber extends MethodAdapter {
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