generate testable internal ref at runtime instead of compile time

This commit is contained in:
金戟 2020-10-12 20:09:11 +08:00
parent ce0e7e4d3a
commit b2ecd2fd14
5 changed files with 10 additions and 53 deletions

View File

@ -22,6 +22,10 @@ public class SourceClassHandler extends BaseClassHandler {
this.injectMethods = injectMethods; this.injectMethods = injectMethods;
} }
/**
* Handle bytecode of source class
* @param cn original class node
*/
@Override @Override
protected void transform(ClassNode cn) { protected void transform(ClassNode cn) {
List<MethodInfo> methods = new ArrayList<MethodInfo>(); List<MethodInfo> methods = new ArrayList<MethodInfo>();

View File

@ -12,11 +12,17 @@ import java.util.List;
*/ */
public class TestClassHandler extends BaseClassHandler { public class TestClassHandler extends BaseClassHandler {
/**
* Handle bytecode of test class
* @param cn original class node
*/
@Override @Override
protected void transform(ClassNode cn) { protected void transform(ClassNode cn) {
for (MethodNode m : cn.methods) { for (MethodNode m : cn.methods) {
transformMethod(cn, m); transformMethod(cn, m);
} }
cn.fields.add(new FieldNode(ACC_PUBLIC | ACC_STATIC, ConstPool.TESTABLE_INJECT_REF,
ClassUtil.toByteCodeClassName(cn.name), null, null));
} }
private void transformMethod(ClassNode cn, MethodNode mn) { private void transformMethod(ClassNode cn, MethodNode mn) {

View File

@ -6,8 +6,6 @@ package com.alibaba.testable.core.constant;
public final class ConstPool { public final class ConstPool {
public static final String TESTABLE_PRIVATE_ACCESSOR = "com.alibaba.testable.core.accessor.PrivateAccessor"; public static final String TESTABLE_PRIVATE_ACCESSOR = "com.alibaba.testable.core.accessor.PrivateAccessor";
public static final String ANNOTATION_TESTABLE_INJECT = "com.alibaba.testable.core.annotation.TestableInject";
public static final String TESTABLE_REF_FIELD_NAME = "_testableInternalRef";
public static final String TEST_POSTFIX = "Test"; public static final String TEST_POSTFIX = "Test";
} }

View File

@ -1,30 +0,0 @@
package com.alibaba.testable.core.generator;
import com.alibaba.testable.core.constant.ConstPool;
import com.alibaba.testable.core.model.TestableContext;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import java.lang.reflect.Modifier;
/**
* Generate test class reference field
*
* @author flin
*/
public class TestableRefFieldGenerator extends BaseGenerator {
private final String testClassFullName;
public TestableRefFieldGenerator(TestableContext cx, String testClassFullName) {
super(cx);
this.testClassFullName = testClassFullName;
}
public JCVariableDecl fetch() {
JCModifiers mods = cx.treeMaker.Modifiers(Modifier.PUBLIC | Modifier.STATIC);
return cx.treeMaker.VarDef(mods, cx.names.fromString(ConstPool.TESTABLE_REF_FIELD_NAME),
nameToExpression(testClassFullName), null);
}
}

View File

@ -2,10 +2,7 @@ package com.alibaba.testable.core.translator;
import com.alibaba.testable.core.constant.ConstPool; import com.alibaba.testable.core.constant.ConstPool;
import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator; import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator;
import com.alibaba.testable.core.generator.TestableRefFieldGenerator;
import com.alibaba.testable.core.model.TestableContext; import com.alibaba.testable.core.model.TestableContext;
import com.alibaba.testable.core.util.TypeUtil;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
@ -21,19 +18,15 @@ import java.lang.reflect.Modifier;
*/ */
public class EnableTestableTranslator extends BaseTranslator { public class EnableTestableTranslator extends BaseTranslator {
private final String testClassName;
private final String sourceClassName; private final String sourceClassName;
private final ListBuffer<Name> sourceClassIns = new ListBuffer<>(); private final ListBuffer<Name> sourceClassIns = new ListBuffer<>();
private final ListBuffer<String> privateOrFinalFields = new ListBuffer<>(); private final ListBuffer<String> privateOrFinalFields = new ListBuffer<>();
private final ListBuffer<String> privateMethods = new ListBuffer<>(); private final ListBuffer<String> privateMethods = new ListBuffer<>();
private final PrivateAccessStatementGenerator privateAccessStatementGenerator; private final PrivateAccessStatementGenerator privateAccessStatementGenerator;
private final TestableRefFieldGenerator testableRefFieldGenerator;
public EnableTestableTranslator(String pkgName, String testClassName, TestableContext cx) { public EnableTestableTranslator(String pkgName, String testClassName, TestableContext cx) {
this.testClassName = testClassName;
this.sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length()); this.sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length());
this.privateAccessStatementGenerator = new PrivateAccessStatementGenerator(cx); this.privateAccessStatementGenerator = new PrivateAccessStatementGenerator(cx);
this.testableRefFieldGenerator = new TestableRefFieldGenerator(cx, pkgName + "." + testClassName);
try { try {
Class<?> cls = Class.forName(pkgName + "." + sourceClassName); Class<?> cls = Class.forName(pkgName + "." + sourceClassName);
Field[] fields = cls.getDeclaredFields(); Field[] fields = cls.getDeclaredFields();
@ -77,20 +70,6 @@ public class EnableTestableTranslator extends BaseTranslator {
super.visitExec(jcExpressionStatement); super.visitExec(jcExpressionStatement);
} }
/**
* Generate test setup method to initialize n.e.pool
*/
@Override
public void visitClassDef(JCClassDecl jcClassDecl) {
super.visitClassDef(jcClassDecl);
if (jcClassDecl.name.toString().equals(testClassName)) {
ListBuffer<JCTree> ndefs = new ListBuffer<>();
ndefs.addAll(jcClassDecl.defs);
ndefs.add(testableRefFieldGenerator.fetch());
jcClassDecl.defs = ndefs.toList();
}
}
/** /**
* For private invoke invocation break point * For private invoke invocation break point
*/ */