diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/ImportWrapper.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/ImportWrapper.java index 730759c9da..72f7673ff1 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/ImportWrapper.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/ImportWrapper.java @@ -8,10 +8,15 @@ package net.sourceforge.pmd.lang.java.ast.internal; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.Collections; import java.util.HashSet; import java.util.Objects; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import net.sourceforge.pmd.Report.ProcessingError; +import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; @@ -19,40 +24,64 @@ import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; * Helper class to analyze {@link ASTImportDeclaration}s. */ public class ImportWrapper { - private ASTImportDeclaration node; - private String name; - private String fullname; - private boolean isStaticDemand; - private Set allDemands = new HashSet<>(); + private static final Logger LOG = Logger.getLogger(ImportWrapper.class.getName()); + + private final ASTImportDeclaration node; + private final String name; + private final String fullname; + private final boolean isStaticDemand; + private final Set allStaticDemands; public ImportWrapper(String fullname, String name) { this(fullname, name, null); } public ImportWrapper(String fullname, String name, ASTImportDeclaration node) { - this(fullname, name, node, false); + this(fullname, name, node, false, null); } - public ImportWrapper(String fullname, String name, ASTImportDeclaration node, boolean isStaticDemand) { + public ImportWrapper(String fullname, String name, ASTImportDeclaration node, boolean isStaticDemand, RuleContext ctx) { this.fullname = fullname; this.name = name; this.node = node; this.isStaticDemand = isStaticDemand; + this.allStaticDemands = collectStaticFieldsAndMethods(node, ctx); - if (this.isStaticDemand && node != null && node.getType() != null) { + } + + /** + * @param node + */ + private Set collectStaticFieldsAndMethods(ASTImportDeclaration node, RuleContext ctx) { + if (!this.isStaticDemand || node == null || node.getType() == null) { + return Collections.emptySet(); + } + + try { + Set names = new HashSet<>(); Class type = node.getType(); // consider static fields, public and non-public for (Field f : type.getDeclaredFields()) { if (Modifier.isStatic(f.getModifiers())) { - allDemands.add(f.getName()); + names.add(f.getName()); } } // and methods, too for (Method m : type.getDeclaredMethods()) { if (Modifier.isStatic(m.getModifiers())) { - allDemands.add(m.getName()); + names.add(m.getName()); } } + return names; + } catch (LinkageError e) { + String filename = ctx != null ? String.valueOf(ctx.getSourceCodeFile()) : "n/a"; + + if (ctx != null) { + ctx.getReport().addError(new ProcessingError(e, filename)); + } else { + LOG.log(Level.WARNING, "Error while processing file " + filename, e); + } + return Collections.emptySet(); } } @@ -80,7 +109,7 @@ public class ImportWrapper { public boolean matches(ImportWrapper i) { if (isStaticDemand) { - if (allDemands.contains(i.fullname)) { + if (allStaticDemands.contains(i.fullname)) { return true; } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedImportsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedImportsRule.java index 2c952b6489..769a6c4c80 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedImportsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/bestpractices/UnusedImportsRule.java @@ -10,6 +10,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; @@ -117,7 +118,7 @@ public class UnusedImportsRule extends AbstractJavaRule { public Object visit(ASTImportDeclaration node, Object data) { if (node.isImportOnDemand()) { ASTName importedType = (ASTName) node.getChild(0); - imports.add(new ImportWrapper(importedType.getImage(), null, node, node.isStatic())); + imports.add(new ImportWrapper(importedType.getImage(), null, node, node.isStatic(), (RuleContext) data)); } else { if (!node.isImportOnDemand()) { ASTName importedType = (ASTName) node.getChild(0); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/DuplicateImportsRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/DuplicateImportsRule.java index 3fa2c2788a..b069ce99f3 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/DuplicateImportsRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/DuplicateImportsRule.java @@ -9,6 +9,7 @@ import java.lang.reflect.Modifier; import java.util.HashSet; import java.util.Set; +import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration; import net.sourceforge.pmd.lang.java.ast.internal.ImportWrapper; @@ -87,7 +88,7 @@ public class DuplicateImportsRule extends AbstractJavaRule { @Override public Object visit(ASTImportDeclaration node, Object data) { ImportWrapper wrapper = new ImportWrapper(node.getImportedName(), node.getImportedName(), - node, node.isStatic() && node.isImportOnDemand()); + node, node.isStatic() && node.isImportOnDemand(), (RuleContext) data); // blahhhh... this really wants to be ASTImportDeclaration to be // polymorphic...