diff --git a/p3c-pmd/src/main/java/com/alibaba/p3c/pmd/lang/java/rule/AbstractAliRule.java b/p3c-pmd/src/main/java/com/alibaba/p3c/pmd/lang/java/rule/AbstractAliRule.java index 743bb7119..bf595819b 100644 --- a/p3c-pmd/src/main/java/com/alibaba/p3c/pmd/lang/java/rule/AbstractAliRule.java +++ b/p3c-pmd/src/main/java/com/alibaba/p3c/pmd/lang/java/rule/AbstractAliRule.java @@ -15,12 +15,17 @@ */ package com.alibaba.p3c.pmd.lang.java.rule; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + import com.alibaba.p3c.pmd.I18nResources; import com.alibaba.p3c.pmd.fix.FixClassTypeResolver; +import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; +import org.apache.commons.lang3.StringUtils; /** * re calculate node type @@ -29,11 +34,29 @@ * @date 2016/11/20 */ public abstract class AbstractAliRule extends AbstractJavaRule { + + private static final Map TYPE_RESOLVER_MAP = new ConcurrentHashMap<>(16); + + private static final String EMPTY_FILE_NAME = "n/a"; + private static final String DELIMITER = "-"; + @Override public Object visit(ASTCompilationUnit node, Object data) { - FixClassTypeResolver classTypeResolver = new FixClassTypeResolver(AbstractAliRule.class.getClassLoader()); - node.setClassTypeResolver(classTypeResolver); - node.jjtAccept(classTypeResolver, data); + // Each CompilationUnit will be scanned only once by custom type resolver. + String sourceCodeFilename = ((RuleContext)data).getSourceCodeFilename(); + + // Do type resolve if file name is empty(unit tests). + if (StringUtils.isBlank(sourceCodeFilename) || EMPTY_FILE_NAME.equals(sourceCodeFilename)) { + resolveType(node, data); + return super.visit(node, data); + } + + // If file name is not empty, use filename + hashcode to identify a compilation unit. + String uniqueId = sourceCodeFilename + DELIMITER + node.hashCode(); + if (!TYPE_RESOLVER_MAP.containsKey(uniqueId)) { + resolveType(node, data); + TYPE_RESOLVER_MAP.put(uniqueId, true); + } return super.visit(node, data); } @@ -57,5 +80,11 @@ public void addViolationWithMessage(Object data, Node node, String message, Obje super.addViolationWithMessage(data, node, String.format(I18nResources.getMessageWithExceptionHandled(message), args)); } + + private void resolveType(ASTCompilationUnit node, Object data) { + FixClassTypeResolver classTypeResolver = new FixClassTypeResolver(AbstractAliRule.class.getClassLoader()); + node.setClassTypeResolver(classTypeResolver); + node.jjtAccept(classTypeResolver, data); + } }