generate static new method

This commit is contained in:
金戟 2020-05-13 22:32:36 +08:00
parent 8a13e3d595
commit 066107372b
3 changed files with 29 additions and 7 deletions

View File

@ -14,7 +14,7 @@ import java.util.List;
* *
* @author flin * @author flin
*/ */
public class CallSuperMethodStatementGenerator { public class CallSuperMethodStatement {
public Statement[] fetch(String className, JCTree.JCMethodDecl method) { public Statement[] fetch(String className, JCTree.JCMethodDecl method) {
if (method.getModifiers().getFlags().contains(Modifier.PRIVATE)) { if (method.getModifiers().getFlags().contains(Modifier.PRIVATE)) {

View File

@ -34,6 +34,7 @@ public class TestableClassGenerator {
tree.accept(translator); tree.accept(translator);
List<MethodSpec> methodSpecs = new ArrayList<>(); List<MethodSpec> methodSpecs = new ArrayList<>();
methodSpecs.add(buildStaticNewMethod(clazz));
for (JCTree.JCMethodDecl method : translator.getMethods()) { for (JCTree.JCMethodDecl method : translator.getMethods()) {
if (isNoncallableMethod(method)) { if (isNoncallableMethod(method)) {
continue; continue;
@ -56,6 +57,28 @@ public class TestableClassGenerator {
return javaFile.toString(); return javaFile.toString();
} }
private MethodSpec buildStaticNewMethod(Element clazz) {
TypeVariableName typeVariable = TypeVariableName.get("T");
MethodSpec.Builder builder = MethodSpec.methodBuilder("New")
.addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC)
.addException(Exception.class)
.addTypeVariable(typeVariable)
.varargs(true)
.addParameter(ParameterizedTypeName.get(ClassName.get(Class.class), typeVariable), "type")
.addParameter(ArrayTypeName.of(Object.class), "args")
.returns(typeVariable);
addStaticNewMethodStatement(builder);
return builder.build();
}
private void addStaticNewMethodStatement(MethodSpec.Builder builder) {
builder.addStatement("$T<$T> pts = new $T<>()", List.class, Class.class, ArrayList.class)
.beginControlFlow("for (Object o : args)")
.addStatement("pts.add(o.getClass())")
.endControlFlow()
.addStatement("return type.getConstructor(pts.toArray(new Class[0])).newInstance(args)");
}
private MethodSpec buildMemberMethod(Element classElement, JCTree.JCMethodDecl method) { private MethodSpec buildMemberMethod(Element classElement, JCTree.JCMethodDecl method) {
MethodSpec.Builder builder = MethodSpec.methodBuilder(method.name.toString()) MethodSpec.Builder builder = MethodSpec.methodBuilder(method.name.toString())
.addModifiers(toPublicFlags(method.getModifiers())) .addModifiers(toPublicFlags(method.getModifiers()))
@ -71,7 +94,7 @@ public class TestableClassGenerator {
builder.addException(TypeName.get(exception.type)); builder.addException(TypeName.get(exception.type));
} }
} }
addStatements(builder, classElement, method); addCallSuperStatements(builder, classElement, method);
return builder.build(); return builder.build();
} }
@ -81,13 +104,13 @@ public class TestableClassGenerator {
for (JCTree.JCVariableDecl p : method.getParameters()) { for (JCTree.JCVariableDecl p : method.getParameters()) {
builder.addParameter(getParameterSpec(p)); builder.addParameter(getParameterSpec(p));
} }
addStatements(builder, classElement, method); addCallSuperStatements(builder, classElement, method);
return builder.build(); return builder.build();
} }
private void addStatements(MethodSpec.Builder builder, Element classElement, JCTree.JCMethodDecl method) { private void addCallSuperStatements(MethodSpec.Builder builder, Element classElement, JCTree.JCMethodDecl method) {
String className = classElement.getSimpleName().toString(); String className = classElement.getSimpleName().toString();
Statement[] statements = new CallSuperMethodStatementGenerator().fetch(className, method); Statement[] statements = new CallSuperMethodStatement().fetch(className, method);
for (Statement s : statements) { for (Statement s : statements) {
builder.addStatement(s.getLine(), s.getParams()); builder.addStatement(s.getLine(), s.getParams());
} }

View File

@ -1,7 +1,5 @@
package com.alibaba.testable.util; package com.alibaba.testable.util;
import com.sun.tools.javac.tree.JCTree;
/** /**
* @author flin * @author flin
*/ */
@ -10,4 +8,5 @@ public final class ConstPool {
public static final String CONSTRUCTOR_NAME = "<init>"; public static final String CONSTRUCTOR_NAME = "<init>";
public static final String TYPE_VOID = "void"; public static final String TYPE_VOID = "void";
public static final String TESTABLE = "Testable"; public static final String TESTABLE = "Testable";
} }