mirror of
https://github.com/alibaba/testable-mock.git
synced 2025-01-09 20:00:21 +08:00
support specify source class for private accessor
This commit is contained in:
parent
77b955a5ce
commit
290d0db400
@ -7,11 +7,13 @@ import com.alibaba.testable.processor.translator.EnablePrivateAccessTranslator;
|
||||
import com.alibaba.testable.processor.util.JavacUtil;
|
||||
import com.alibaba.testable.processor.util.TestableLogger;
|
||||
import com.sun.tools.javac.api.JavacTrees;
|
||||
import com.sun.tools.javac.code.Attribute;
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.TreeMaker;
|
||||
import com.sun.tools.javac.util.Names;
|
||||
import com.sun.tools.javac.util.Pair;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
@ -19,7 +21,6 @@ import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import java.util.Set;
|
||||
|
||||
@ -29,6 +30,8 @@ import java.util.Set;
|
||||
@SupportedAnnotationTypes("com.alibaba.testable.processor.annotation.EnablePrivateAccess")
|
||||
public class EnablePrivateAccessProcessor extends AbstractProcessor {
|
||||
|
||||
private static final String SRC_CLASS = "srcClass";
|
||||
|
||||
private TestableContext cx;
|
||||
|
||||
@Override
|
||||
@ -53,8 +56,10 @@ public class EnablePrivateAccessProcessor extends AbstractProcessor {
|
||||
}
|
||||
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(EnablePrivateAccess.class);
|
||||
for (Element element : elements) {
|
||||
if (element.getKind().isClass() && isTestClass(element.getSimpleName())) {
|
||||
processClassElement((Symbol.ClassSymbol)element);
|
||||
if (element.getKind().isClass()) {
|
||||
Symbol.ClassSymbol testClass = (Symbol.ClassSymbol)element;
|
||||
String sourceClassName = getSourceClassName(testClass);
|
||||
processClassElement(testClass, sourceClassName);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -66,6 +71,19 @@ public class EnablePrivateAccessProcessor extends AbstractProcessor {
|
||||
return SourceVersion.values()[SourceVersion.values().length - 1];
|
||||
}
|
||||
|
||||
private String getSourceClassName(Symbol.ClassSymbol testClass) {
|
||||
for (Attribute.Compound annotation : testClass.getMetadata().getDeclarationAttributes()) {
|
||||
if (ConstPool.ENABLE_PRIVATE_ACCESS.equals(annotation.type.tsym.toString())) {
|
||||
for (Pair<Symbol.MethodSymbol, Attribute> p : annotation.values) {
|
||||
if (SRC_CLASS.equals(p.fst.name.toString())) {
|
||||
return p.snd.getValue().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private JavacProcessingEnvironment getJavacProcessingEnvironment(ProcessingEnvironment processingEnv) {
|
||||
try {
|
||||
return JavacUtil.getJavacProcessingEnvironment(processingEnv);
|
||||
@ -74,14 +92,10 @@ public class EnablePrivateAccessProcessor extends AbstractProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTestClass(Name name) {
|
||||
return name.toString().endsWith(ConstPool.TEST_POSTFIX);
|
||||
}
|
||||
|
||||
private void processClassElement(Symbol.ClassSymbol clazz) {
|
||||
private void processClassElement(Symbol.ClassSymbol testClass, String sourceClassName) {
|
||||
if (cx.trees != null) {
|
||||
JCTree tree = cx.trees.getTree(clazz);
|
||||
tree.accept(new EnablePrivateAccessTranslator(clazz, cx));
|
||||
JCTree tree = cx.trees.getTree(testClass);
|
||||
tree.accept(new EnablePrivateAccessTranslator(cx, testClass, sourceClassName));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.alibaba.testable.processor.annotation;
|
||||
|
||||
import javax.lang.model.type.NullType;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
@ -11,4 +12,11 @@ import java.lang.annotation.*;
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
public @interface EnablePrivateAccess {
|
||||
|
||||
/**
|
||||
* explicit specify the source class to be tested
|
||||
* @return
|
||||
*/
|
||||
Class<?> srcClass() default NullType.class;
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ package com.alibaba.testable.processor.constant;
|
||||
*/
|
||||
public final class ConstPool {
|
||||
|
||||
public static final String ENABLE_PRIVATE_ACCESS = "com.alibaba.testable.processor.annotation.EnablePrivateAccess";
|
||||
public static final String TESTABLE_PRIVATE_ACCESSOR = "com.alibaba.testable.core.accessor.PrivateAccessor";
|
||||
public static final String TEST_POSTFIX = "Test";
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.alibaba.testable.processor.translator;
|
||||
|
||||
import com.alibaba.testable.processor.constant.ConstPool;
|
||||
import com.alibaba.testable.processor.generator.PrivateAccessStatementGenerator;
|
||||
import com.alibaba.testable.processor.model.MemberRecord;
|
||||
import com.alibaba.testable.processor.model.MemberType;
|
||||
@ -22,6 +21,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.testable.processor.constant.ConstPool.TEST_POSTFIX;
|
||||
|
||||
/**
|
||||
* Travel AST
|
||||
*
|
||||
@ -50,14 +51,18 @@ public class EnablePrivateAccessTranslator extends BaseTranslator {
|
||||
private final PrivateAccessStatementGenerator privateAccessStatementGenerator;
|
||||
private final PrivateAccessChecker privateAccessChecker;
|
||||
|
||||
public EnablePrivateAccessTranslator(Symbol.ClassSymbol clazz, TestableContext cx) {
|
||||
String pkgName = ((Symbol.PackageSymbol)clazz.owner).fullname.toString();
|
||||
String testClassName = clazz.getSimpleName().toString();
|
||||
String sourceClass = testClassName.substring(0, testClassName.length() - ConstPool.TEST_POSTFIX.length());
|
||||
public EnablePrivateAccessTranslator(TestableContext cx, Symbol.ClassSymbol clazz, String srcClassName) {
|
||||
String sourceClassFullName;
|
||||
if (srcClassName == null) {
|
||||
String testClassFullName = clazz.fullname.toString();
|
||||
sourceClassFullName = testClassFullName.substring(0, testClassFullName.length() - TEST_POSTFIX.length());
|
||||
} else {
|
||||
sourceClassFullName = srcClassName;
|
||||
}
|
||||
String sourceClassShortName = sourceClassFullName.substring(sourceClassFullName.lastIndexOf('.') + 1);
|
||||
this.privateAccessStatementGenerator = new PrivateAccessStatementGenerator(cx);
|
||||
this.sourceClassName = cx.names.fromString(sourceClass);
|
||||
this.sourceClassName = cx.names.fromString(sourceClassShortName);
|
||||
try {
|
||||
String sourceClassFullName = pkgName + "." + sourceClass;
|
||||
Class<?> cls = getSourceClass(clazz, sourceClassFullName);
|
||||
if (cls == null) {
|
||||
cx.logger.error("Failed to load source class: " + sourceClassFullName);
|
||||
@ -67,7 +72,7 @@ public class EnablePrivateAccessTranslator extends BaseTranslator {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.privateAccessChecker = new PrivateAccessChecker(cx, sourceClassName.toString(), memberRecord);
|
||||
this.privateAccessChecker = new PrivateAccessChecker(cx, sourceClassShortName, memberRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user