corrected invalid reporting of LoD violation

This commit is contained in:
Wayne Earl
2017-02-19 22:11:15 -07:00
committed by Juan Martín Sotuyo Dodero
parent acd891175d
commit 227060e5f8
2 changed files with 61 additions and 25 deletions

View File

@ -51,7 +51,9 @@ public class LawOfDemeterRule extends AbstractJavaRule {
private static final String REASON_STATIC_ACCESS = "static property access";
/**
* That's a new method. We are going to check each method call inside the method.
* That's a new method. We are going to check each method call inside the
* method.
*
* @return <code>null</code>.
*/
@Override
@ -119,9 +121,9 @@ public class LawOfDemeterRule extends AbstractJavaRule {
}
/**
* Factory method to convert a given primary expression into MethodCalls.
* In case the primary expression represents a method chain call, then multiple
* MethodCalls are returned.
* Factory method to convert a given primary expression into
* MethodCalls. In case the primary expression represents a method chain
* call, then multiple MethodCalls are returned.
*
* @return a list of MethodCalls, might be empty.
*/
@ -308,11 +310,14 @@ public class LawOfDemeterRule extends AbstractJavaRule {
private Assignment determineLastAssignment() {
List<Assignment> assignments = new ArrayList<>();
ASTBlock block = expression.getFirstParentOfType(ASTMethodDeclaration.class).getFirstChildOfType(ASTBlock.class);
ASTBlock block = expression.getFirstParentOfType(ASTMethodDeclaration.class)
.getFirstChildOfType(ASTBlock.class);
//get all variableDeclarators within this block
List<ASTVariableDeclarator> variableDeclarators = block.findDescendantsOfType(ASTVariableDeclarator.class);
for (ASTVariableDeclarator declarator : variableDeclarators) {
ASTVariableDeclaratorId variableDeclaratorId = declarator.getFirstChildOfType(ASTVariableDeclaratorId.class);
ASTVariableDeclaratorId variableDeclaratorId = declarator
.getFirstChildOfType(ASTVariableDeclaratorId.class);
//we only care about it if the image name matches the current baseName
if (variableDeclaratorId.hasImageEqualTo(baseName)) {
boolean allocationFound = declarator.getFirstDescendantOfType(ASTAllocationExpression.class) != null;
boolean iterator = isIterator() || isFactory(declarator);
@ -321,17 +326,33 @@ public class LawOfDemeterRule extends AbstractJavaRule {
}
}
//get all AssignmentOperators within this block
List<ASTAssignmentOperator> assignmentStmts = block.findDescendantsOfType(ASTAssignmentOperator.class);
for (ASTAssignmentOperator stmt : assignmentStmts) {
if (stmt.hasImageEqualTo(SIMPLE_ASSIGNMENT_OPERATOR)) {
boolean allocationFound = stmt.jjtGetParent().getFirstDescendantOfType(ASTAllocationExpression.class) != null;
boolean iterator = isIterator();
assignments.add(new Assignment(stmt.getBeginLine(), allocationFound, iterator, false));
//we only care about it if it occurs prior to (or on) the beginLine of the current expression
//and if it is a simple_assignement_operator
if (stmt.getBeginLine() <= expression.getBeginLine()
&& stmt.hasImageEqualTo(SIMPLE_ASSIGNMENT_OPERATOR)) {
//now we need to make sure it has the right image name
ASTPrimaryPrefix primaryPrefix = stmt.jjtGetParent()
.getFirstDescendantOfType(ASTPrimaryPrefix.class);
if (primaryPrefix != null) {
ASTName prefixName = primaryPrefix.getFirstChildOfType(ASTName.class);
if (prefixName != null && prefixName.hasImageEqualTo(baseName)) {
//this is an assignment related to the baseName we are working with
boolean allocationFound = stmt.jjtGetParent()
.getFirstDescendantOfType(ASTAllocationExpression.class) != null;
boolean iterator = isIterator();
assignments
.add(new Assignment(stmt.getBeginLine(), allocationFound, iterator, false));
}
}
}
}
Assignment result = null;
if (!assignments.isEmpty()) {
//sort them in reverse order and return the first one
Collections.sort(assignments);
result = assignments.get(0);
}

View File

@ -69,6 +69,21 @@ public class Foo {
]]></code>
</test-code>
<test-code>
<description>Simple Method calls with local created object and other variable assignment</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public void example() {
String something;
C c = new C();
c.doIt();
something = "no worries";
}
}
]]></code>
</test-code>
<test-code>
<description>Simple Method calls with local created object and variables</description>
<expected-problems>0</expected-problems>