generate testable reference field

This commit is contained in:
金戟 2020-07-28 17:50:12 +08:00
parent ee275a319a
commit bd203dc409
4 changed files with 48 additions and 14 deletions

View File

@ -15,6 +15,7 @@ public final class ConstPool {
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_SETUP_METHOD_NAME = "testableSetup";
public static final String TESTABLE_REF_FIELD_NAME = "_testableInternalRef";
public static final String TEST_POSTFIX = "Test";
}

View File

@ -0,0 +1,30 @@
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

@ -48,18 +48,13 @@ public class EnableTestableProcessor extends BaseProcessor {
private void processClassElement(Symbol.ClassSymbol clazz) {
JCTree tree = cx.trees.getTree(clazz);
tree.accept(new EnableTestableTranslator(getPkgName(clazz), getOriginClassName(clazz), cx));
tree.accept(new EnableTestableTranslator(getPkgName(clazz), clazz.getSimpleName().toString(), cx));
}
private String getPkgName(Symbol.ClassSymbol clazz) {
return ((Symbol.PackageSymbol)clazz.owner).fullname.toString();
}
private String getOriginClassName(Symbol.ClassSymbol clazz) {
String testClassName = clazz.getSimpleName().toString();
return testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length());
}
private void createTestableAgentJar() {
if (!hasFirstClassCompiled) {
hasFirstClassCompiled = true;

View File

@ -2,6 +2,7 @@ package com.alibaba.testable.core.translator;
import com.alibaba.testable.core.generator.PrivateAccessStatementGenerator;
import com.alibaba.testable.core.generator.TestSetupMethodGenerator;
import com.alibaba.testable.core.generator.TestableRefFieldGenerator;
import com.alibaba.testable.core.model.TestableContext;
import com.alibaba.testable.core.constant.ConstPool;
import com.sun.tools.javac.tree.JCTree;
@ -23,20 +24,24 @@ import java.util.Arrays;
public class EnableTestableTranslator extends BaseTranslator {
private final TestableContext cx;
private String sourceClassName = "";
private String testClassName;
private String sourceClassName;
private final ListBuffer<Name> sourceClassIns = new ListBuffer<>();
private final ListBuffer<String> privateOrFinalFields = new ListBuffer<>();
private final ListBuffer<String> privateMethods = new ListBuffer<>();
private final TestSetupMethodGenerator testSetupMethodGenerator;
private final PrivateAccessStatementGenerator privateAccessStatementGenerator;
private final TestableRefFieldGenerator testableRefFieldGenerator;
public EnableTestableTranslator(String pkgName, String className, TestableContext cx) {
this.sourceClassName = className;
public EnableTestableTranslator(String pkgName, String testClassName, TestableContext cx) {
this.testClassName = testClassName;
this.sourceClassName = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length());
this.cx = cx;
this.testSetupMethodGenerator = new TestSetupMethodGenerator(cx);
this.privateAccessStatementGenerator = new PrivateAccessStatementGenerator(cx);
this.testableRefFieldGenerator = new TestableRefFieldGenerator(cx, pkgName + "." + testClassName);
try {
Class<?> cls = Class.forName(pkgName + "." + className);
Class<?> cls = Class.forName(pkgName + "." + sourceClassName);
Field[] fields = cls.getDeclaredFields();
for (Field f : fields) {
if (Modifier.isFinal(f.getModifiers()) || Modifier.isPrivate(f.getModifiers())) {
@ -104,10 +109,13 @@ public class EnableTestableTranslator extends BaseTranslator {
@Override
public void visitClassDef(JCClassDecl jcClassDecl) {
super.visitClassDef(jcClassDecl);
ListBuffer<JCTree> ndefs = new ListBuffer<>();
ndefs.addAll(jcClassDecl.defs);
ndefs.add(testSetupMethodGenerator.fetch());
jcClassDecl.defs = ndefs.toList();
if (jcClassDecl.name.toString().equals(testClassName)) {
ListBuffer<JCTree> ndefs = new ListBuffer<>();
ndefs.addAll(jcClassDecl.defs);
ndefs.add(testSetupMethodGenerator.fetch());
ndefs.add(testableRefFieldGenerator.fetch());
jcClassDecl.defs = ndefs.toList();
}
}
/**