Fixes #1479 CloseResource false positive on Statement
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user