add switch to disable private access target existence check

This commit is contained in:
金戟 2021-02-06 21:54:18 +08:00
parent 7bbdf82a41
commit d860684e91
4 changed files with 39 additions and 12 deletions

View File

@ -2,6 +2,7 @@ package com.alibaba.testable.processor;
import com.alibaba.testable.processor.annotation.EnablePrivateAccess;
import com.alibaba.testable.processor.constant.ConstPool;
import com.alibaba.testable.processor.model.Parameters;
import com.alibaba.testable.processor.model.TestableContext;
import com.alibaba.testable.processor.translator.EnablePrivateAccessTranslator;
import com.alibaba.testable.processor.util.JavacUtil;
@ -31,6 +32,7 @@ import java.util.Set;
public class EnablePrivateAccessProcessor extends AbstractProcessor {
private static final String SRC_CLASS = "srcClass";
private static final String VERIFY_ON_COMPILE = "verifyTargetOnCompile";
private TestableContext cx;
@ -58,8 +60,8 @@ public class EnablePrivateAccessProcessor extends AbstractProcessor {
for (Element element : elements) {
if (element.getKind().isClass()) {
Symbol.ClassSymbol testClass = (Symbol.ClassSymbol)element;
String sourceClassName = getSourceClassName(testClass);
processClassElement(testClass, sourceClassName);
Parameters parameters = getAnnotationParameters(testClass);
processClassElement(testClass, parameters);
}
}
return true;
@ -71,17 +73,20 @@ public class EnablePrivateAccessProcessor extends AbstractProcessor {
return SourceVersion.values()[SourceVersion.values().length - 1];
}
private String getSourceClassName(Symbol.ClassSymbol testClass) {
private Parameters getAnnotationParameters(Symbol.ClassSymbol testClass) {
Parameters parameters = new Parameters();
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();
parameters.sourceClassName = p.snd.getValue().toString();
} else if (VERIFY_ON_COMPILE.equals(p.fst.name.toString())) {
parameters.verifyTargetExistence = (Boolean)p.snd.getValue();
}
}
}
}
return null;
return parameters;
}
private JavacProcessingEnvironment getJavacProcessingEnvironment(ProcessingEnvironment processingEnv) {
@ -92,10 +97,10 @@ public class EnablePrivateAccessProcessor extends AbstractProcessor {
}
}
private void processClassElement(Symbol.ClassSymbol testClass, String sourceClassName) {
private void processClassElement(Symbol.ClassSymbol testClass, Parameters parameters) {
if (cx.trees != null) {
JCTree tree = cx.trees.getTree(testClass);
tree.accept(new EnablePrivateAccessTranslator(cx, testClass, sourceClassName));
tree.accept(new EnablePrivateAccessTranslator(cx, testClass, parameters));
}
}

View File

@ -19,4 +19,10 @@ public @interface EnablePrivateAccess {
*/
Class<?> srcClass() default NullType.class;
/**
* whether enable compile-time existence verification for the private members accessed
* @return
*/
boolean verifyTargetOnCompile() default true;
}

View File

@ -0,0 +1,12 @@
package com.alibaba.testable.processor.model;
/**
* @author flin
*/
public class Parameters {
public String sourceClassName;
public Boolean verifyTargetExistence;
}

View File

@ -3,6 +3,7 @@ package com.alibaba.testable.processor.translator;
import com.alibaba.testable.processor.generator.PrivateAccessStatementGenerator;
import com.alibaba.testable.processor.model.MemberRecord;
import com.alibaba.testable.processor.model.MemberType;
import com.alibaba.testable.processor.model.Parameters;
import com.alibaba.testable.processor.model.TestableContext;
import com.alibaba.testable.processor.util.PathUtil;
import com.sun.tools.javac.code.Symbol;
@ -51,13 +52,13 @@ public class EnablePrivateAccessTranslator extends BaseTranslator {
private final PrivateAccessStatementGenerator privateAccessStatementGenerator;
private final PrivateAccessChecker privateAccessChecker;
public EnablePrivateAccessTranslator(TestableContext cx, Symbol.ClassSymbol clazz, String srcClassName) {
public EnablePrivateAccessTranslator(TestableContext cx, Symbol.ClassSymbol clazz, Parameters p) {
String sourceClassFullName;
if (srcClassName == null) {
if (p.sourceClassName == null) {
String testClassFullName = clazz.fullname.toString();
sourceClassFullName = testClassFullName.substring(0, testClassFullName.length() - TEST_POSTFIX.length());
} else {
sourceClassFullName = srcClassName;
sourceClassFullName = p.sourceClassName;
}
String sourceClassShortName = sourceClassFullName.substring(sourceClassFullName.lastIndexOf('.') + 1);
this.privateAccessStatementGenerator = new PrivateAccessStatementGenerator(cx);
@ -72,7 +73,8 @@ public class EnablePrivateAccessTranslator extends BaseTranslator {
} catch (Exception e) {
e.printStackTrace();
}
this.privateAccessChecker = new PrivateAccessChecker(cx, sourceClassShortName, memberRecord);
this.privateAccessChecker = (p.verifyTargetExistence == null || p.verifyTargetExistence) ?
new PrivateAccessChecker(cx, sourceClassShortName, memberRecord) : null;
}
/**
@ -157,7 +159,9 @@ public class EnablePrivateAccessTranslator extends BaseTranslator {
} else if (memberType.equals(MemberType.STATIC_PRIVATE)) {
expr = privateAccessStatementGenerator.fetchStaticInvokeStatement(invocation);
}
privateAccessChecker.validate((JCMethodInvocation)expr);
if (privateAccessChecker != null) {
privateAccessChecker.validate((JCMethodInvocation)expr);
}
}
// check the casted expression
if (expr instanceof JCTypeCast) {