Fix formatting and static code analysis findings.
This commit is contained in:
parent
1a9e721fb6
commit
69a24126f7
@ -5,82 +5,88 @@
|
|||||||
package net.sourceforge.pmd.lang.apex.rule.bestpractices;
|
package net.sourceforge.pmd.lang.apex.rule.bestpractices;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
|
||||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression;
|
import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression;
|
||||||
import net.sourceforge.pmd.lang.apex.ast.ASTParameter;
|
import net.sourceforge.pmd.lang.apex.ast.ASTParameter;
|
||||||
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
|
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
|
||||||
import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule;
|
import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule;
|
||||||
import net.sourceforge.pmd.lang.rule.RuleTargetSelector;
|
import net.sourceforge.pmd.lang.rule.RuleTargetSelector;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans classes which implement the `Queueable` interface. If the `public void
|
* Scans classes which implement the `Queueable` interface. If the `public void
|
||||||
* execute(QueueableContext context)` method does not call the `System.attachFinalizer(Finalizer f)`
|
* execute(QueueableContext context)` method does not call the
|
||||||
* method, then a violation will be added to the `execute` method.
|
* `System.attachFinalizer(Finalizer f)` method, then a violation will be added
|
||||||
|
* to the `execute` method.
|
||||||
*
|
*
|
||||||
* @author mitchspano
|
* @author mitchspano
|
||||||
*/
|
*/
|
||||||
public class QueueableWithoutFinalizerRule extends AbstractApexRule {
|
public class QueueableWithoutFinalizerRule extends AbstractApexRule {
|
||||||
|
|
||||||
private static final String EXECUTE = "execute";
|
private static final String EXECUTE = "execute";
|
||||||
private static final String QUEUEABLE = "queueable";
|
private static final String QUEUEABLE = "queueable";
|
||||||
private static final String QUEUEABLE_CONTEXT = "queueablecontext";
|
private static final String QUEUEABLE_CONTEXT = "queueablecontext";
|
||||||
private static final String SYSTEM_ATTACH_FINALIZER = "system.attachfinalizer";
|
private static final String SYSTEM_ATTACH_FINALIZER = "system.attachfinalizer";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected @NonNull RuleTargetSelector buildTargetSelector() {
|
protected @NonNull RuleTargetSelector buildTargetSelector() {
|
||||||
return RuleTargetSelector.forTypes(ASTUserClass.class);
|
return RuleTargetSelector.forTypes(ASTUserClass.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the class implements the `Queueable` interface and the `execute(QueueableContext context)`
|
* If the class implements the `Queueable` interface and the
|
||||||
* does not call the `System.attachFinalizer(Finalizer f)` method, then add a violation.
|
* `execute(QueueableContext context)` does not call the
|
||||||
*/
|
* `System.attachFinalizer(Finalizer f)` method, then add a violation.
|
||||||
@Override
|
*/
|
||||||
public Object visit(ASTUserClass theClass, Object data) {
|
@Override
|
||||||
if (!implementsTheQueueableInterface(theClass)) {
|
public Object visit(ASTUserClass theClass, Object data) {
|
||||||
return data;
|
if (!implementsTheQueueableInterface(theClass)) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
for (ASTMethod theMethod : theClass.descendants(ASTMethod.class).toList()) {
|
||||||
|
if (isTheExecuteMethodOfTheQueueableInterface(theMethod)
|
||||||
|
&& !callsTheSystemAttachFinalizerMethod(theMethod)) {
|
||||||
|
asCtx(data).addViolation(theMethod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
for (ASTMethod theMethod : theClass.descendants(ASTMethod.class).toList()) {
|
|
||||||
if (isTheExecuteMethodOfTheQueueableInterface(theMethod)
|
|
||||||
&& !callsTheSystemAttachFinalizerMethod(theMethod)) {
|
|
||||||
asCtx(data).addViolation(theMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determines if the class implements the Queueable interface. */
|
/** Determines if the class implements the Queueable interface. */
|
||||||
private boolean implementsTheQueueableInterface(ASTUserClass theClass) {
|
private boolean implementsTheQueueableInterface(ASTUserClass theClass) {
|
||||||
for (String interfaceName : theClass.getInterfaceNames()) {
|
for (String interfaceName : theClass.getInterfaceNames()) {
|
||||||
if (interfaceName.equalsIgnoreCase(QUEUEABLE)) {
|
if (QUEUEABLE.equalsIgnoreCase(interfaceName)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the method is the `execute(QueueableContext context)` method. Parameter count is
|
* Determines if the method is the `execute(QueueableContext context)`
|
||||||
* checked to account for method overloading.
|
* method. Parameter count is checked to account for method overloading.
|
||||||
*/
|
*/
|
||||||
private boolean isTheExecuteMethodOfTheQueueableInterface(ASTMethod theMethod) {
|
private boolean isTheExecuteMethodOfTheQueueableInterface(ASTMethod theMethod) {
|
||||||
if (!theMethod.getCanonicalName().equalsIgnoreCase(EXECUTE)) {
|
if (!EXECUTE.equalsIgnoreCase(theMethod.getCanonicalName())) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
List<ASTParameter> parameters = theMethod.descendants(ASTParameter.class).toList();
|
||||||
|
return parameters.size() == 1 && QUEUEABLE_CONTEXT.equalsIgnoreCase(parameters.get(0).getType());
|
||||||
}
|
}
|
||||||
List<ASTParameter> parameters = theMethod.descendants(ASTParameter.class).toList();
|
|
||||||
return parameters.size() == 1
|
|
||||||
&& parameters.get(0).getType().equalsIgnoreCase(QUEUEABLE_CONTEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Determines if the method calls the `System.attachFinalizer(Finalizer f)` method. */
|
/**
|
||||||
private boolean callsTheSystemAttachFinalizerMethod(ASTMethod theMethod) {
|
* Determines if the method calls the `System.attachFinalizer(Finalizer f)`
|
||||||
for (ASTMethodCallExpression methodCallExpression :
|
* method.
|
||||||
theMethod.descendants(ASTMethodCallExpression.class).toList()) {
|
*/
|
||||||
if (methodCallExpression.getFullMethodName().equalsIgnoreCase(SYSTEM_ATTACH_FINALIZER)) {
|
private boolean callsTheSystemAttachFinalizerMethod(ASTMethod theMethod) {
|
||||||
return true;
|
for (ASTMethodCallExpression methodCallExpression : theMethod.descendants(ASTMethodCallExpression.class)
|
||||||
}
|
.toList()) {
|
||||||
|
if (SYSTEM_ATTACH_FINALIZER.equalsIgnoreCase(methodCallExpression.getFullMethodName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,5 @@ package net.sourceforge.pmd.lang.apex.rule.bestpractices;
|
|||||||
import net.sourceforge.pmd.test.PmdRuleTst;
|
import net.sourceforge.pmd.test.PmdRuleTst;
|
||||||
|
|
||||||
class QueueableWithoutFinalizerTest extends PmdRuleTst {
|
class QueueableWithoutFinalizerTest extends PmdRuleTst {
|
||||||
// no additional unit tests
|
// no additional unit tests
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user