Fixes #1479 CloseResource false positive on Statement

This commit is contained in:
Andreas Dangel
2016-05-29 18:20:04 +02:00
parent 6afe513225
commit 04f16d7627
5 changed files with 74 additions and 3 deletions

View File

@ -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 <code>true</code> if this node referencing a type in the same compilation unit,
* <code>false</code> otherwise.
*/
public boolean isReferenceToClassSameCompilationUnit() {
ASTCompilationUnit root = getFirstParentOfType(ASTCompilationUnit.class);
List<ASTClassOrInterfaceDeclaration> classes = root.findDescendantsOfType(ASTClassOrInterfaceDeclaration.class);
for (ASTClassOrInterfaceDeclaration c : classes) {
if (c.hasImageEqualTo(getImage())) {
return true;
}
}
List<ASTEnumDeclaration> enums = root.findDescendantsOfType(ASTEnumDeclaration.class);
for (ASTEnumDeclaration e : enums) {
if (e.hasImageEqualTo(getImage())) {
return true;
}
}
return false;
}
}

View File

@ -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);

View File

@ -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);

View File

@ -652,6 +652,22 @@ public class CloseResource {
stmt.close();
}
}
}
]]></code>
</test-code>
<test-code>
<description>#1479 CloseResource false positive on Statement</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Test {
public static void main(String[] args) {
Statement statement = new Statement();
}
static class Statement {
}
}
]]></code>
</test-code>

View File

@ -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