Merge branch 'issue-1495'
This commit is contained in:
@ -7,6 +7,9 @@ package net.sourceforge.pmd.lang.java.rule.design;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.sourceforge.pmd.lang.java.ast.ASTAssertStatement;
|
||||||
|
import net.sourceforge.pmd.lang.java.ast.ASTBlock;
|
||||||
|
import net.sourceforge.pmd.lang.java.ast.ASTBlockStatement;
|
||||||
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
|
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
|
||||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||||
import net.sourceforge.pmd.lang.java.ast.ASTName;
|
import net.sourceforge.pmd.lang.java.ast.ASTName;
|
||||||
@ -47,7 +50,13 @@ public class UnnecessaryLocalBeforeReturnRule extends AbstractJavaRule {
|
|||||||
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : vars.entrySet()) {
|
for (Map.Entry<VariableNameDeclaration, List<NameOccurrence>> entry : vars.entrySet()) {
|
||||||
VariableNameDeclaration key = entry.getKey();
|
VariableNameDeclaration key = entry.getKey();
|
||||||
List<NameOccurrence> usages = entry.getValue();
|
List<NameOccurrence> usages = entry.getValue();
|
||||||
for (NameOccurrence occ : usages) {
|
|
||||||
|
// skip, if there is an assert between declaration and return
|
||||||
|
if (hasAssertStatement(key, rtn)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NameOccurrence occ: usages) {
|
||||||
if (occ.getLocation().equals(name)) {
|
if (occ.getLocation().equals(name)) {
|
||||||
// only check declarations that occur one line earlier
|
// only check declarations that occur one line earlier
|
||||||
if (key.getNode().getBeginLine() == name.getBeginLine() - 1) {
|
if (key.getNode().getBeginLine() == name.getBeginLine() - 1) {
|
||||||
@ -79,4 +88,31 @@ public class UnnecessaryLocalBeforeReturnRule extends AbstractJavaRule {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether there is an assert statement between the variable declaration
|
||||||
|
* and the return statement, that uses the variable.
|
||||||
|
* @param variableDeclaration
|
||||||
|
* @param rtn
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean hasAssertStatement(VariableNameDeclaration variableDeclaration, ASTReturnStatement rtn) {
|
||||||
|
boolean hasAssert = false;
|
||||||
|
ASTBlockStatement blockStatement = variableDeclaration.getAccessNodeParent().getFirstParentOfType(ASTBlockStatement.class);
|
||||||
|
int startIndex = blockStatement.jjtGetChildIndex() + 1;
|
||||||
|
int endIndex = rtn.getFirstParentOfType(ASTBlockStatement.class).jjtGetChildIndex();
|
||||||
|
ASTBlock block = (ASTBlock) blockStatement.jjtGetParent();
|
||||||
|
for (int i = startIndex; i < endIndex; i++) {
|
||||||
|
List<ASTAssertStatement> asserts = block.jjtGetChild(i).findDescendantsOfType(ASTAssertStatement.class);
|
||||||
|
for (ASTAssertStatement assertStatement : asserts) {
|
||||||
|
List<ASTName> names = assertStatement.findDescendantsOfType(ASTName.class);
|
||||||
|
for (ASTName n : names) {
|
||||||
|
if (n.hasImageEqualTo(variableDeclaration.getName())) {
|
||||||
|
hasAssert = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hasAssert;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,4 +65,17 @@ public class Foo {
|
|||||||
}
|
}
|
||||||
]]></code>
|
]]></code>
|
||||||
</test-code>
|
</test-code>
|
||||||
|
|
||||||
|
<test-code>
|
||||||
|
<description>#1495 [java] UnnecessaryLocalBeforeReturn with assert</description>
|
||||||
|
<expected-problems>0</expected-problems>
|
||||||
|
<code><![CDATA[
|
||||||
|
public class Foo {
|
||||||
|
public int bar() {
|
||||||
|
int res = 2; assert res>=0;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]></code>
|
||||||
|
</test-code>
|
||||||
</test-data>
|
</test-data>
|
||||||
|
@ -243,6 +243,7 @@ to avoid XSS attacks.
|
|||||||
* [#1545](https://sourceforge.net/p/pmd/bugs/1545/): \[java] Symbol Table fails to resolve inner classes
|
* [#1545](https://sourceforge.net/p/pmd/bugs/1545/): \[java] Symbol Table fails to resolve inner classes
|
||||||
* java-design
|
* java-design
|
||||||
* [#1448](https://sourceforge.net/p/pmd/bugs/1448/): \[java] ImmutableField: Private field in inner class gives false positive with lambdas
|
* [#1448](https://sourceforge.net/p/pmd/bugs/1448/): \[java] ImmutableField: Private field in inner class gives false positive with lambdas
|
||||||
|
* [#1495](https://sourceforge.net/p/pmd/bugs/1495/): \[java] UnnecessaryLocalBeforeReturn with assert
|
||||||
* [#1512](https://sourceforge.net/p/pmd/bugs/1512/): \[java] Combine rules AvoidConstantsInInterface and ConstantsInInterface
|
* [#1512](https://sourceforge.net/p/pmd/bugs/1512/): \[java] Combine rules AvoidConstantsInInterface and ConstantsInInterface
|
||||||
* [#1552](https://sourceforge.net/p/pmd/bugs/1552/): \[java] MissingBreakInSwitch - False positive for continue
|
* [#1552](https://sourceforge.net/p/pmd/bugs/1552/): \[java] MissingBreakInSwitch - False positive for continue
|
||||||
* [#1556](https://sourceforge.net/p/pmd/bugs/1556/): \[java] UseLocaleWithCaseConversions does not works with `ResultSet` (false negative)
|
* [#1556](https://sourceforge.net/p/pmd/bugs/1556/): \[java] UseLocaleWithCaseConversions does not works with `ResultSet` (false negative)
|
||||||
|
Reference in New Issue
Block a user