duplication check is unnecessary

This commit is contained in:
金戟 2021-03-09 15:54:05 +08:00
parent 4995bbd9a9
commit edd4c24d88
2 changed files with 10 additions and 29 deletions

View File

@ -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();

View File

@ -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));
} }
/** /**