diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceType.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceType.java
index 9cca41b798..05c6e7f6b6 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceType.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/ASTClassOrInterfaceType.java
@@ -5,6 +5,8 @@
package net.sourceforge.pmd.lang.java.ast;
+import java.util.List;
+
public class ASTClassOrInterfaceType extends AbstractJavaTypeNode {
public ASTClassOrInterfaceType(int id) {
super(id);
@@ -14,11 +16,35 @@ public class ASTClassOrInterfaceType extends AbstractJavaTypeNode {
super(p, id);
}
-
/**
* Accept the visitor. *
*/
public Object jjtAccept(JavaParserVisitor visitor, Object data) {
return visitor.visit(this, data);
}
+
+ /**
+ * Checks whether the type this node is referring to is declared
+ * within the same compilation unit - either a class/interface or a enum type.
+ * You want to check this, if {@link #getType()} is null.
+ *
+ * @return true
if this node referencing a type in the same compilation unit,
+ * false
otherwise.
+ */
+ public boolean isReferenceToClassSameCompilationUnit() {
+ ASTCompilationUnit root = getFirstParentOfType(ASTCompilationUnit.class);
+ List classes = root.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class);
+ for (ASTClassOrInterfaceDeclaration c : classes) {
+ if (c.hasImageEqualTo(getImage())) {
+ return true;
+ }
+ }
+ List enums = root.findDescendantsOfType(ASTEnumDeclaration.class);
+ for (ASTEnumDeclaration e : enums) {
+ if (e.hasImageEqualTo(getImage())) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CloseResourceRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CloseResourceRule.java
index fcef6e33f9..4c8bee843a 100644
--- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CloseResourceRule.java
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/CloseResourceRule.java
@@ -126,8 +126,9 @@ public class CloseResourceRule extends AbstractJavaRule {
if (ref.jjtGetChild(0) instanceof ASTClassOrInterfaceType) {
ASTClassOrInterfaceType clazz = (ASTClassOrInterfaceType) ref.jjtGetChild(0);
- if (clazz.getType() != null && types.contains(clazz.getType().getName()) || clazz.getType() == null
- && simpleTypes.contains(toSimpleType(clazz.getImage())) || types.contains(clazz.getImage())) {
+ if (clazz.getType() != null && types.contains(clazz.getType().getName())
+ || clazz.getType() == null && simpleTypes.contains(toSimpleType(clazz.getImage())) && !clazz.isReferenceToClassSameCompilationUnit()
+ || types.contains(clazz.getImage()) && !clazz.isReferenceToClassSameCompilationUnit()) {
ASTVariableDeclaratorId id = var.getFirstDescendantOfType(ASTVariableDeclaratorId.class);
ids.add(id);
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java
index 7c99a9dbf5..b85b962fd4 100644
--- a/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/typeresolution/ClassTypeResolverTest.java
@@ -7,12 +7,17 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.jaxen.JaxenException;
+import org.junit.Assert;
import org.junit.Test;
import net.sourceforge.pmd.lang.LanguageRegistry;
+import net.sourceforge.pmd.lang.LanguageVersion;
import net.sourceforge.pmd.lang.LanguageVersionHandler;
+import net.sourceforge.pmd.lang.Parser;
+import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.JavaLanguageModule;
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTBooleanLiteral;
@@ -120,6 +125,27 @@ public class ClassTypeResolverTest {
assertEquals(theInnerClass, formalParameter.getTypeNode().getType());
}
+ /**
+ * If we don't have the auxclasspath, we might not find the inner class. In that case,
+ * we'll need to search by name for a match.
+ * @throws Exception
+ */
+ @Test
+ public void testInnerClassNotCompiled() throws Exception {
+ LanguageVersion language = LanguageRegistry.getLanguage(JavaLanguageModule.NAME).getDefaultVersion();
+ LanguageVersionHandler languageHandler = language.getLanguageVersionHandler();
+ Parser parser = languageHandler.getParser(languageHandler.getDefaultParserOptions());
+ Node acu = parser.parse("test", new StringReader("public class TestInnerClass {\n" +
+ " public void foo() {\n" +
+ " Statement statement = new Statement();\n" +
+ " }\n" +
+ " static class Statement {\n" +
+ " }\n" +
+ "}"));
+ ASTClassOrInterfaceType statement = acu.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
+ Assert.assertTrue(statement.isReferenceToClassSameCompilationUnit());
+ }
+
@Test
public void testAnonymousInnerClass() throws ClassNotFoundException {
ASTCompilationUnit acu = parseAndTypeResolveForClass15(AnonymousInnerClass.class);
diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CloseResource.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CloseResource.xml
index 916bcd9ce3..301690ffba 100644
--- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CloseResource.xml
+++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/design/xml/CloseResource.xml
@@ -652,6 +652,22 @@ public class CloseResource {
stmt.close();
}
}
+}
+ ]]>
+
+
+
+ #1479 CloseResource false positive on Statement
+ 0
+
diff --git a/src/site/markdown/overview/changelog.md b/src/site/markdown/overview/changelog.md
index 2c872563c3..27613f65a4 100644
--- a/src/site/markdown/overview/changelog.md
+++ b/src/site/markdown/overview/changelog.md
@@ -14,6 +14,8 @@
**Bugfixes:**
+* java-design/CloseResource
+ * [#1479](https://sourceforge.net/p/pmd/bugs/1479/): CloseResource false positive on Statement
* java-unusedcode/UnusedLocalVariable
* [#1484](https://sourceforge.net/p/pmd/bugs/1484/): UnusedLocalVariable - false positive - parenthesis
* java-unusedcode/UnusedModifier