mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-27 12:51:00 +08:00
duplication check is unnecessary
This commit is contained in:
parent
4995bbd9a9
commit
edd4c24d88
@ -1,15 +1,9 @@
|
|||||||
package com.alibaba.testable.agent.handler;
|
package com.alibaba.testable.agent.handler;
|
||||||
|
|
||||||
import com.alibaba.testable.agent.util.ClassUtil;
|
|
||||||
import com.alibaba.testable.core.util.LogUtil;
|
|
||||||
import org.objectweb.asm.ClassReader;
|
import org.objectweb.asm.ClassReader;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
import org.objectweb.asm.tree.ClassNode;
|
||||||
import org.objectweb.asm.tree.FieldNode;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author flin
|
* @author flin
|
||||||
@ -23,26 +17,11 @@ abstract public class BaseClassHandler implements Opcodes {
|
|||||||
|
|
||||||
protected String mockClassName;
|
protected String mockClassName;
|
||||||
|
|
||||||
protected boolean markTransformed(ClassNode cn, String refName, String refDescriptor) {
|
public byte[] getBytes(byte[] classFileBuffer) {
|
||||||
Iterator<FieldNode> iterator = cn.fields.iterator();
|
|
||||||
if (iterator.hasNext()) {
|
|
||||||
if (refName.equals(iterator.next().name)) {
|
|
||||||
// avoid duplicate injection
|
|
||||||
LogUtil.verbose("Duplicate injection found, ignore " + cn.name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cn.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, refName, refDescriptor, null, null));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes(byte[] classFileBuffer) throws IOException {
|
|
||||||
ClassReader cr = new ClassReader(classFileBuffer);
|
ClassReader cr = new ClassReader(classFileBuffer);
|
||||||
ClassNode cn = new ClassNode();
|
ClassNode cn = new ClassNode();
|
||||||
cr.accept(cn, 0);
|
cr.accept(cn, 0);
|
||||||
if (markTransformed(cn, TESTABLE_REF, ClassUtil.toByteCodeClassName(mockClassName))) {
|
|
||||||
transform(cn);
|
transform(cn);
|
||||||
}
|
|
||||||
ClassWriter cw = new ClassWriter( 0);
|
ClassWriter cw = new ClassWriter( 0);
|
||||||
cn.accept(cw);
|
cn.accept(cw);
|
||||||
return cw.toByteArray();
|
return cw.toByteArray();
|
||||||
|
@ -40,7 +40,7 @@ public class MockClassHandler extends BaseClassWithContextHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void transform(ClassNode cn) {
|
protected void transform(ClassNode cn) {
|
||||||
injectGetInstanceMethod(cn);
|
injectRefFieldAndGetInstanceMethod(cn);
|
||||||
for (MethodNode mn : cn.methods) {
|
for (MethodNode mn : cn.methods) {
|
||||||
if (isMockMethod(mn)) {
|
if (isMockMethod(mn)) {
|
||||||
mn.access &= ~ACC_PRIVATE;
|
mn.access &= ~ACC_PRIVATE;
|
||||||
@ -61,25 +61,27 @@ public class MockClassHandler extends BaseClassWithContextHandler {
|
|||||||
/**
|
/**
|
||||||
* add method to fetch singleton instance of this mock class
|
* add method to fetch singleton instance of this mock class
|
||||||
*/
|
*/
|
||||||
private void injectGetInstanceMethod(ClassNode cn) {
|
private void injectRefFieldAndGetInstanceMethod(ClassNode cn) {
|
||||||
|
String byteCodeMockClassName = ClassUtil.toByteCodeClassName(mockClassName);
|
||||||
MethodNode getInstanceMethod = new MethodNode(ACC_PUBLIC | ACC_STATIC, GET_TESTABLE_REF,
|
MethodNode getInstanceMethod = new MethodNode(ACC_PUBLIC | ACC_STATIC, GET_TESTABLE_REF,
|
||||||
VOID_ARGS + ClassUtil.toByteCodeClassName(mockClassName), null, null);
|
VOID_ARGS + byteCodeMockClassName, null, null);
|
||||||
InsnList il = new InsnList();
|
InsnList il = new InsnList();
|
||||||
il.add(new FieldInsnNode(GETSTATIC, mockClassName, TESTABLE_REF, ClassUtil.toByteCodeClassName(mockClassName)));
|
il.add(new FieldInsnNode(GETSTATIC, mockClassName, TESTABLE_REF, byteCodeMockClassName));
|
||||||
LabelNode label = new LabelNode();
|
LabelNode label = new LabelNode();
|
||||||
il.add(new JumpInsnNode(IFNONNULL, label));
|
il.add(new JumpInsnNode(IFNONNULL, label));
|
||||||
il.add(new TypeInsnNode(NEW, mockClassName));
|
il.add(new TypeInsnNode(NEW, mockClassName));
|
||||||
il.add(new InsnNode(DUP));
|
il.add(new InsnNode(DUP));
|
||||||
il.add(new MethodInsnNode(INVOKESPECIAL, mockClassName, CONSTRUCTOR, VOID_ARGS + VOID_RES, false));
|
il.add(new MethodInsnNode(INVOKESPECIAL, mockClassName, CONSTRUCTOR, VOID_ARGS + VOID_RES, false));
|
||||||
il.add(new FieldInsnNode(PUTSTATIC, mockClassName, TESTABLE_REF, ClassUtil.toByteCodeClassName(mockClassName)));
|
il.add(new FieldInsnNode(PUTSTATIC, mockClassName, TESTABLE_REF, byteCodeMockClassName));
|
||||||
il.add(label);
|
il.add(label);
|
||||||
il.add(new FrameNode(F_SAME, 0, null, 0, null));
|
il.add(new FrameNode(F_SAME, 0, null, 0, null));
|
||||||
il.add(new FieldInsnNode(GETSTATIC, mockClassName, TESTABLE_REF, ClassUtil.toByteCodeClassName(mockClassName)));
|
il.add(new FieldInsnNode(GETSTATIC, mockClassName, TESTABLE_REF, byteCodeMockClassName));
|
||||||
il.add(new InsnNode(ARETURN));
|
il.add(new InsnNode(ARETURN));
|
||||||
getInstanceMethod.instructions = il;
|
getInstanceMethod.instructions = il;
|
||||||
getInstanceMethod.maxStack = 2;
|
getInstanceMethod.maxStack = 2;
|
||||||
getInstanceMethod.maxLocals = 0;
|
getInstanceMethod.maxLocals = 0;
|
||||||
cn.methods.add(getInstanceMethod);
|
cn.methods.add(getInstanceMethod);
|
||||||
|
cn.fields.add(new FieldNode(ACC_PRIVATE | ACC_STATIC, TESTABLE_REF, byteCodeMockClassName, null, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user