From ab8a0b32e50807d22739302dea99a96fd3d6ec84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=87=91=E6=88=9F?= Date: Sun, 31 Jan 2021 18:37:27 +0800 Subject: [PATCH] fix compile time check for private member access --- .../exception/MemberNotExistException.java | 11 +++++++++- .../EnablePrivateAccessTranslator.java | 2 +- .../translator/PrivateAccessChecker.java | 22 +++++++++++++++---- .../processor/util/TestableLogger.java | 3 ++- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/testable-processor/src/main/java/com/alibaba/testable/processor/exception/MemberNotExistException.java b/testable-processor/src/main/java/com/alibaba/testable/processor/exception/MemberNotExistException.java index ea22341..d721df5 100644 --- a/testable-processor/src/main/java/com/alibaba/testable/processor/exception/MemberNotExistException.java +++ b/testable-processor/src/main/java/com/alibaba/testable/processor/exception/MemberNotExistException.java @@ -6,7 +6,16 @@ package com.alibaba.testable.processor.exception; public class MemberNotExistException extends RuntimeException { public MemberNotExistException(String type, String className, String target) { - super(type + " \"" + target + "\" not exist in class \"" + className + "\""); + super(String.format("%s \"%s\" not exist in class \"%s\"", type, target, className)); + } + + public MemberNotExistException(String type, String className, String target, int count) { + super(String.format("%s \"%s\" with %d %s not exist in class \"%s\"", + type, target, count, parameters(count), className)); + } + + private static String parameters(int count) { + return count > 1 ? "parameters" : "parameter"; } } diff --git a/testable-processor/src/main/java/com/alibaba/testable/processor/translator/EnablePrivateAccessTranslator.java b/testable-processor/src/main/java/com/alibaba/testable/processor/translator/EnablePrivateAccessTranslator.java index bd3b375..52d05f0 100644 --- a/testable-processor/src/main/java/com/alibaba/testable/processor/translator/EnablePrivateAccessTranslator.java +++ b/testable-processor/src/main/java/com/alibaba/testable/processor/translator/EnablePrivateAccessTranslator.java @@ -146,13 +146,13 @@ public class EnablePrivateAccessTranslator extends BaseTranslator { // check is invoking a private method of source class if (expr instanceof JCMethodInvocation) { JCMethodInvocation invocation = (JCMethodInvocation)expr; - privateAccessChecker.validate(invocation); MemberType memberType = checkInvokeType(invocation); if (memberType.equals(MemberType.PRIVATE_OR_FINAL)) { expr = privateAccessStatementGenerator.fetchInvokeStatement(invocation); } else if (memberType.equals(MemberType.STATIC_PRIVATE)) { expr = privateAccessStatementGenerator.fetchStaticInvokeStatement(invocation); } + privateAccessChecker.validate((JCMethodInvocation)expr); } // check the casted expression if (expr instanceof JCTypeCast) { diff --git a/testable-processor/src/main/java/com/alibaba/testable/processor/translator/PrivateAccessChecker.java b/testable-processor/src/main/java/com/alibaba/testable/processor/translator/PrivateAccessChecker.java index ca63058..1b7066f 100644 --- a/testable-processor/src/main/java/com/alibaba/testable/processor/translator/PrivateAccessChecker.java +++ b/testable-processor/src/main/java/com/alibaba/testable/processor/translator/PrivateAccessChecker.java @@ -17,6 +17,7 @@ import java.util.Map; public class PrivateAccessChecker { private static final String CLASS_NAME_PRIVATE_ACCESSOR = "PrivateAccessor"; + private static final String CLASS_NAME_PRIVATE_ACCESSOR_FULL = "com.alibaba.testable.core.accessor.PrivateAccessor"; private static final List FIELD_ACCESS_METHOD = Arrays.asList(new String[] { "get", "set", "getStatic", "setStatic" }.clone()); private static final List FIELD_INVOKE_METHOD = Arrays.asList(new String[] @@ -37,8 +38,7 @@ public class PrivateAccessChecker { public void validate(JCTree.JCMethodInvocation invocation) { if (invocation.meth instanceof JCTree.JCFieldAccess && invocation.args.length() >= 2) { JCTree.JCFieldAccess fieldAccess = (JCTree.JCFieldAccess)invocation.meth; - if (fieldAccess.selected instanceof JCTree.JCIdent && invocation.args.get(1) instanceof JCTree.JCLiteral && - ((JCTree.JCIdent)fieldAccess.selected).name.toString().equals(CLASS_NAME_PRIVATE_ACCESSOR)) { + if (invocation.args.get(1) instanceof JCTree.JCLiteral && isPrivateAccessor(fieldAccess)) { Object target = ((JCTree.JCLiteral)invocation.args.get(1)).getValue(); if (target instanceof String) { String methodName = fieldAccess.name.toString(); @@ -55,10 +55,10 @@ public class PrivateAccessChecker { checkParameterCount(sourceMembers.privateMethods, (String)target, parameterCount)) { // Let it go } else if (sourceMembers.nonPrivateMethods.containsKey(target) && - checkParameterCount(sourceMembers.privateMethods, (String)target, parameterCount)) { + checkParameterCount(sourceMembers.nonPrivateMethods, (String)target, parameterCount)) { cx.logger.warn("Method " + className + "::" + target + " is not private."); } else { - throw new MemberNotExistException(TYPE_METHOD, className, (String)target); + throw new MemberNotExistException(TYPE_METHOD, className, (String)target, parameterCount); } } } @@ -66,6 +66,20 @@ public class PrivateAccessChecker { } } + private boolean isPrivateAccessor(JCTree.JCFieldAccess fieldAccess) { + return isPrivateAccessorWithShortRef(fieldAccess) || isPrivateAccessorWithFullRef(fieldAccess); + } + + private boolean isPrivateAccessorWithShortRef(JCTree.JCFieldAccess fieldAccess) { + return fieldAccess.selected instanceof JCTree.JCIdent && + ((JCTree.JCIdent)fieldAccess.selected).name.toString().equals(CLASS_NAME_PRIVATE_ACCESSOR); + } + + private boolean isPrivateAccessorWithFullRef(JCTree.JCFieldAccess fieldAccess) { + return fieldAccess.selected instanceof JCTree.JCFieldAccess && + fieldAccess.selected.toString().equals(CLASS_NAME_PRIVATE_ACCESSOR_FULL); + } + private boolean checkParameterCount(Map> methods, String target, int parameterCount) { for (Integer expectCount : methods.get(target)) { if (countMatch(parameterCount, expectCount)) { diff --git a/testable-processor/src/main/java/com/alibaba/testable/processor/util/TestableLogger.java b/testable-processor/src/main/java/com/alibaba/testable/processor/util/TestableLogger.java index 568dedb..25f6b66 100644 --- a/testable-processor/src/main/java/com/alibaba/testable/processor/util/TestableLogger.java +++ b/testable-processor/src/main/java/com/alibaba/testable/processor/util/TestableLogger.java @@ -22,7 +22,8 @@ public class TestableLogger { } public void warn(String msg) { - messager.printMessage(Diagnostic.Kind.WARNING, msg); + // Message level WARNING won't show, use MANDATORY_WARNING instead + messager.printMessage(Diagnostic.Kind.MANDATORY_WARNING, msg); } public void error(String msg) {