handle private method without parameter

This commit is contained in:
金戟
2020-05-12 19:44:42 +08:00
parent 6a58e4f301
commit f45c7a34bc
3 changed files with 54 additions and 15 deletions

View File

@@ -4,6 +4,7 @@ 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.util.ArrayList;
import java.util.List;
@@ -11,11 +12,16 @@ import java.util.List;
* @author flin
*/
public class CallSuperMethod {
private final String className;
private final JCTree.JCMethodDecl method;
private Object[] params;
private String statement;
public CallSuperMethod(JCTree.JCMethodDecl method) {this.method = method;}
public CallSuperMethod(String className, JCTree.JCMethodDecl method) {
this.className = className;
this.method = method;
}
public Object[] getParams() {
return params;
@@ -26,17 +32,25 @@ public class CallSuperMethod {
}
public CallSuperMethod invoke() {
params = new String[method.params.length()];
List<Object> args = new ArrayList<>();
List<String> placeholders = new ArrayList<>();
for (int i = 0; i < method.params.length(); i++) {
params[i] = (method.params.get(i).name.toString());
placeholders.add("$N");
if (method.getModifiers().getFlags().contains(Modifier.PRIVATE)) {
statement = className + ".class.getMethod(\"" + method.name + "\").invoke(this)";
if (!method.restype.toString().equals(ConstPool.CONSTRUCTOR_VOID)) {
statement = "(" + method.restype + ")" + statement;
}
} else {
for (JCTree.JCVariableDecl p : method.params) {
args.add(p.name.toString());
placeholders.add("$N");
}
String call = "super";
if (!method.name.toString().equals(ConstPool.CONSTRUCTOR_NAME)) {
call += ("." + method.name.toString());
}
statement = call + "(" + StringUtil.join(placeholders, ", ") + ")";
}
String call = "super";
if (!method.name.toString().equals(ConstPool.CONSTRUCTOR_NAME)) {
call += ("." + method.name.toString());
}
statement = call + "(" + StringUtil.join(placeholders, ", ") + ")";
params = args.toArray();
return this;
}
}

View File

@@ -18,6 +18,7 @@ import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -55,25 +56,38 @@ public class TestableProcessor extends BaseProcessor {
List<MethodSpec> methodSpecs = new ArrayList<>();
for (JCTree.JCMethodDecl method : translator.getMethods()) {
if (method.getModifiers().getFlags().contains(Modifier.ABSTRACT)) {
continue;
}
if (method.name.toString().equals(ConstPool.CONSTRUCTOR_NAME)) {
MethodSpec.Builder builder = MethodSpec.constructorBuilder()
.addModifiers(Modifier.PUBLIC);
for (JCTree.JCVariableDecl p : method.getParameters()) {
builder.addParameter(getParameterSpec(p));
}
CallSuperMethod callSuperMethod = new CallSuperMethod(method).invoke();
CallSuperMethod callSuperMethod = new CallSuperMethod(classElement.getSimpleName().toString(), method).invoke();
builder.addStatement(callSuperMethod.getStatement(), callSuperMethod.getParams());
methodSpecs.add(builder.build());
} else {
MethodSpec.Builder builder = MethodSpec.methodBuilder(method.name.toString())
.addModifiers(method.getModifiers().getFlags())
.addModifiers(Modifier.PUBLIC)
.addModifiers(toPublicFlags(method.getModifiers()))
.returns(TypeName.get(((Type.MethodType)method.sym.type).restype));
for (JCTree.JCVariableDecl p : method.getParameters()) {
builder.addParameter(getParameterSpec(p));
}
CallSuperMethod callSuperMethod = new CallSuperMethod(method).invoke();
String statement = method.restype == null ? callSuperMethod.getStatement() : "return " + callSuperMethod.getStatement();
CallSuperMethod callSuperMethod = new CallSuperMethod(classElement.getSimpleName().toString(), method).invoke();
String statement = callSuperMethod.getStatement();
if (!method.restype.toString().equals(ConstPool.CONSTRUCTOR_VOID)) {
statement = "return " + statement;
}
if (method.getModifiers().getFlags().contains(Modifier.PRIVATE)) {
builder.addException(Exception.class);
} else {
builder.addAnnotation(Override.class);
for (JCTree.JCExpression exception : method.getThrows()) {
builder.addException(TypeName.get(exception.type));
}
}
builder.addStatement(statement, callSuperMethod.getParams());
methodSpecs.add(builder.build());
}
@@ -90,6 +104,14 @@ public class TestableProcessor extends BaseProcessor {
return javaFile.toString();
}
private Set<Modifier> toPublicFlags(JCTree.JCModifiers modifiers) {
Set<Modifier> flags = new HashSet<>(modifiers.getFlags());
flags.remove(Modifier.PRIVATE);
flags.remove(Modifier.PROTECTED);
flags.add(Modifier.PUBLIC);
return flags;
}
private ParameterSpec getParameterSpec(JCTree.JCVariableDecl type) {
return ParameterSpec.builder(TypeName.get(type.sym.type), type.name.toString()).build();
}

View File

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