Correctly detect fields that appear after static initialization blocks

This commit is contained in:
Gwilym Kuiper
2020-04-03 15:10:30 +01:00
parent 292bcbbf04
commit 9e07836659
2 changed files with 30 additions and 1 deletions

View File

@@ -8,6 +8,8 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.sourceforge.pmd.lang.apex.ast.ASTBlockStatement;
import net.sourceforge.pmd.lang.apex.ast.ASTField;
@@ -32,7 +34,7 @@ public class FieldDeclarationsShouldBeAtStartRule extends AbstractApexRule {
List<ApexNode<?>> nonFieldDeclarations = new ArrayList<>();
nonFieldDeclarations.addAll(node.findChildrenOfType(ASTMethod.class));
nonFieldDeclarations.addAll(getMethodNodes(node));
nonFieldDeclarations.addAll(node.findChildrenOfType(ASTUserClass.class));
nonFieldDeclarations.addAll(node.findChildrenOfType(ASTProperty.class));
nonFieldDeclarations.addAll(node.findChildrenOfType(ASTBlockStatement.class));
@@ -54,4 +56,14 @@ public class FieldDeclarationsShouldBeAtStartRule extends AbstractApexRule {
return super.visit(node, data);
}
private List<ApexNode<?>> getMethodNodes(ASTUserClass node) {
// The method <clinit> represents static initializer blocks, of which there can be many. Given that the
// <clinit> method doesn't contain location information, only the containing ASTBlockStatements, we fetch
// them for that method only.
return node.findChildrenOfType(ASTMethod.class).stream()
.flatMap(method -> method.getImage().equals("<clinit>") ?
method.findChildrenOfType(ASTBlockStatement.class).stream() : Stream.of(method))
.collect(Collectors.toList());
}
}

View File

@@ -184,6 +184,23 @@ class Foo {
public Integer thisIsNotOkay;
}
]]>
</code>
</test-code>
<test-code>
<description>Fields should go before static block statements</description>
<expected-problems>1</expected-problems>
<expected-linenumbers>6</expected-linenumbers>
<code>
<![CDATA[
class Foo {
static {
System.debug('Hello');
}
public Integer thisIsNotOkay;
}
]]>
</code>
</test-code>