diff --git a/src/main/java/com/alibaba/testable/generator/TestableClassDevRoleGenerator.java b/src/main/java/com/alibaba/testable/generator/TestableClassDevRoleGenerator.java index 44ade24..cd49604 100644 --- a/src/main/java/com/alibaba/testable/generator/TestableClassDevRoleGenerator.java +++ b/src/main/java/com/alibaba/testable/generator/TestableClassDevRoleGenerator.java @@ -1,6 +1,10 @@ package com.alibaba.testable.generator; import com.alibaba.testable.generator.model.Statement; +import com.alibaba.testable.generator.statement.CallSuperMethodStatementGenerator; +import com.alibaba.testable.generator.statement.FieldGetterStatementGenerator; +import com.alibaba.testable.generator.statement.FieldSetterStatementGenerator; +import com.alibaba.testable.generator.statement.FieldStatementGenerator; import com.alibaba.testable.translator.TestableClassDevRoleTranslator; import com.alibaba.testable.util.ConstPool; import com.squareup.javapoet.*; @@ -47,6 +51,10 @@ public class TestableClassDevRoleGenerator { methodSpecs.add(buildMemberMethod(clazz, method)); } } + for (JCTree.JCVariableDecl field : translator.getPrivateFields()) { + methodSpecs.add(buildFieldGetter(clazz, field)); + methodSpecs.add(buildFieldSetter(clazz, field)); + } TypeSpec.Builder builder = TypeSpec.classBuilder(className) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) @@ -59,6 +67,29 @@ public class TestableClassDevRoleGenerator { return javaFile.toString(); } + private MethodSpec buildFieldGetter(Element classElement, JCTree.JCVariableDecl field) { + return buildFieldAccessor(classElement, field, "TestableGet", + TypeName.get(((Type.MethodType)field.type).restype), new FieldGetterStatementGenerator()); + } + + private MethodSpec buildFieldSetter(Element classElement, JCTree.JCVariableDecl field) { + return buildFieldAccessor(classElement, field, "TestableSet", + TypeName.VOID, new FieldSetterStatementGenerator()); + } + + private MethodSpec buildFieldAccessor(Element classElement, JCTree.JCVariableDecl field, String prefix, + TypeName returnType, FieldStatementGenerator generator) { + MethodSpec.Builder builder = MethodSpec.methodBuilder(field.name.toString() + prefix) + .addModifiers(Modifier.PUBLIC) + .returns(returnType); + String className = classElement.getSimpleName().toString(); + Statement[] statements = generator.fetch(className, field); + for (Statement s : statements) { + builder.addStatement(s.getLine(), s.getParams()); + } + return builder.build(); + } + private MethodSpec buildMemberMethod(Element classElement, JCTree.JCMethodDecl method) { MethodSpec.Builder builder = MethodSpec.methodBuilder(method.name.toString()) .addModifiers(toPublicFlags(method.getModifiers())) @@ -79,8 +110,7 @@ public class TestableClassDevRoleGenerator { } private MethodSpec buildConstructorMethod(Element classElement, JCTree.JCMethodDecl method) { - MethodSpec.Builder builder = MethodSpec.constructorBuilder() - .addModifiers(Modifier.PUBLIC); + MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC); for (JCTree.JCVariableDecl p : method.getParameters()) { builder.addParameter(getParameterSpec(p)); } diff --git a/src/main/java/com/alibaba/testable/generator/CallSuperMethodStatementGenerator.java b/src/main/java/com/alibaba/testable/generator/statement/CallSuperMethodStatementGenerator.java similarity index 98% rename from src/main/java/com/alibaba/testable/generator/CallSuperMethodStatementGenerator.java rename to src/main/java/com/alibaba/testable/generator/statement/CallSuperMethodStatementGenerator.java index e52bbe6..a9d7802 100644 --- a/src/main/java/com/alibaba/testable/generator/CallSuperMethodStatementGenerator.java +++ b/src/main/java/com/alibaba/testable/generator/statement/CallSuperMethodStatementGenerator.java @@ -1,4 +1,4 @@ -package com.alibaba.testable.generator; +package com.alibaba.testable.generator.statement; import com.alibaba.testable.generator.model.Statement; import com.alibaba.testable.util.ConstPool; diff --git a/src/main/java/com/alibaba/testable/generator/statement/FieldGetterStatementGenerator.java b/src/main/java/com/alibaba/testable/generator/statement/FieldGetterStatementGenerator.java new file mode 100644 index 0000000..7edf23a --- /dev/null +++ b/src/main/java/com/alibaba/testable/generator/statement/FieldGetterStatementGenerator.java @@ -0,0 +1,25 @@ +package com.alibaba.testable.generator.statement; + +import com.alibaba.testable.generator.model.Statement; +import com.alibaba.testable.util.ConstPool; +import com.alibaba.testable.util.StringUtil; +import com.sun.tools.javac.tree.JCTree; + +import javax.lang.model.element.Modifier; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * Generate field getter method statement + * + * @author flin + */ +public class FieldGetterStatementGenerator implements FieldStatementGenerator { + + @Override + public Statement[] fetch(String className, JCTree.JCVariableDecl field) { + return new Statement[] {new Statement("return null", new Object[] {})}; + } + +} diff --git a/src/main/java/com/alibaba/testable/generator/statement/FieldSetterStatementGenerator.java b/src/main/java/com/alibaba/testable/generator/statement/FieldSetterStatementGenerator.java new file mode 100644 index 0000000..c70116b --- /dev/null +++ b/src/main/java/com/alibaba/testable/generator/statement/FieldSetterStatementGenerator.java @@ -0,0 +1,25 @@ +package com.alibaba.testable.generator.statement; + +import com.alibaba.testable.generator.model.Statement; +import com.alibaba.testable.util.ConstPool; +import com.alibaba.testable.util.StringUtil; +import com.sun.tools.javac.tree.JCTree; + +import javax.lang.model.element.Modifier; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +/** + * Generate field setter method statement + * + * @author flin + */ +public class FieldSetterStatementGenerator implements FieldStatementGenerator { + + @Override + public Statement[] fetch(String className, JCTree.JCVariableDecl field) { + return new Statement[]{}; + } + +} diff --git a/src/main/java/com/alibaba/testable/generator/statement/FieldStatementGenerator.java b/src/main/java/com/alibaba/testable/generator/statement/FieldStatementGenerator.java new file mode 100644 index 0000000..5b4f443 --- /dev/null +++ b/src/main/java/com/alibaba/testable/generator/statement/FieldStatementGenerator.java @@ -0,0 +1,14 @@ +package com.alibaba.testable.generator.statement; + +import com.alibaba.testable.generator.model.Statement; +import com.sun.tools.javac.tree.JCTree; + +/** + * @author flin + */ +public interface FieldStatementGenerator { + /** + * Generate field access code statement + */ + Statement[] fetch(String className, JCTree.JCVariableDecl field); +} diff --git a/src/main/java/com/alibaba/testable/processor/TestableProcessor.java b/src/main/java/com/alibaba/testable/processor/TestableProcessor.java index 1ae13cd..77e8ee9 100644 --- a/src/main/java/com/alibaba/testable/processor/TestableProcessor.java +++ b/src/main/java/com/alibaba/testable/processor/TestableProcessor.java @@ -91,9 +91,14 @@ public class TestableProcessor extends BaseProcessor { } } - private void processTestRoleClassElement(Element field) { - JCTree tree = trees.getTree(field); - tree.accept(new TestableClassTestRoleTranslator(treeMaker)); + private void processTestRoleClassElement(Element clazz) { + JCTree tree = trees.getTree(clazz); + tree.accept(new TestableClassTestRoleTranslator(getOriginClassName(clazz), treeMaker)); + } + + private String getOriginClassName(Element clazz) { + String testClassName = clazz.getSimpleName().toString(); + return testClassName.substring(0, testClassName.length() - "Test".length()); } private void writeSourceFile(String fullQualityTypeName, String content) throws IOException { diff --git a/src/main/java/com/alibaba/testable/translator/TestableClassDevRoleTranslator.java b/src/main/java/com/alibaba/testable/translator/TestableClassDevRoleTranslator.java index ccf6de0..699fca9 100644 --- a/src/main/java/com/alibaba/testable/translator/TestableClassDevRoleTranslator.java +++ b/src/main/java/com/alibaba/testable/translator/TestableClassDevRoleTranslator.java @@ -27,10 +27,19 @@ public class TestableClassDevRoleTranslator extends TreeTranslator { */ private List methods = List.nil(); + /** + * Private field to mock + */ + private List fields = List.nil(); + public List getMethods() { return methods; } + public List getPrivateFields() { + return fields; + } + public TestableClassDevRoleTranslator(TreeMaker treeMaker) { this.treeMaker = treeMaker; } @@ -69,10 +78,14 @@ public class TestableClassDevRoleTranslator extends TreeTranslator { } /** + * record all private fields * case: Demo d = new Demo() */ @Override public void visitVarDef(JCTree.JCVariableDecl jcVariableDecl) { + if (jcVariableDecl.mods.getFlags().contains(javax.lang.model.element.Modifier.PRIVATE)) { + fields.append(jcVariableDecl); + } jcVariableDecl.init = checkAndExchangeNewOperation(jcVariableDecl.init); super.visitVarDef(jcVariableDecl); } @@ -91,6 +104,11 @@ public class TestableClassDevRoleTranslator extends TreeTranslator { super.visitNewClass(jcNewClass); } + @Override + public void visitNewArray(JCTree.JCNewArray jcNewArray) { + super.visitNewArray(jcNewArray); + } + private List checkAndExchangeNewOperation(List args) { if (args != null) { JCTree.JCExpression[] es = new JCTree.JCExpression[args.length()]; diff --git a/src/main/java/com/alibaba/testable/translator/TestableClassTestRoleTranslator.java b/src/main/java/com/alibaba/testable/translator/TestableClassTestRoleTranslator.java index f976b35..608013a 100644 --- a/src/main/java/com/alibaba/testable/translator/TestableClassTestRoleTranslator.java +++ b/src/main/java/com/alibaba/testable/translator/TestableClassTestRoleTranslator.java @@ -6,6 +6,9 @@ import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.TreeTranslator; import com.sun.tools.javac.util.Name; +import java.util.ArrayList; +import java.util.List; + /** * Travel AST * @@ -14,19 +17,29 @@ import com.sun.tools.javac.util.Name; public class TestableClassTestRoleTranslator extends TreeTranslator { private TreeMaker treeMaker; + private String sourceClassName; + private List sourceClassIns = new ArrayList<>(); - public TestableClassTestRoleTranslator(TreeMaker treeMaker) {this.treeMaker = treeMaker;} + public TestableClassTestRoleTranslator(String className, TreeMaker treeMaker) { + this.sourceClassName = className; + this.treeMaker = treeMaker; + } @Override - public void visitVarDef(JCTree.JCVariableDecl decl) { - super.visitVarDef(decl); - decl.vartype = getTestableClassIdent(decl.vartype); + public void visitVarDef(JCTree.JCVariableDecl jcVariableDecl) { + super.visitVarDef(jcVariableDecl); + if (((JCTree.JCIdent)jcVariableDecl.vartype).name.toString().equals(sourceClassName)) { + jcVariableDecl.vartype = getTestableClassIdent(jcVariableDecl.vartype); + sourceClassIns.add(jcVariableDecl.name); + } } @Override public void visitNewClass(JCTree.JCNewClass jcNewClass) { super.visitNewClass(jcNewClass); - jcNewClass.clazz = getTestableClassIdent(jcNewClass.clazz); + if (((JCTree.JCIdent)jcNewClass.clazz).name.toString().equals(sourceClassName)) { + jcNewClass.clazz = getTestableClassIdent(jcNewClass.clazz); + } } private JCTree.JCIdent getTestableClassIdent(JCTree.JCExpression clazz) { diff --git a/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/src/main/resources/META-INF/services/javax.annotation.processing.Processor index ca38b72..45fc714 100644 --- a/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ b/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -1,2 +1 @@ com.alibaba.testable.processor.TestableProcessor -com.alibaba.testable.processor.TestableInjectProcessor