Add GetDescribeShouldUseSObjectDescribeOptions Apex rule

This commit is contained in:
Jonathan Wiesel
2021-10-04 00:01:42 +02:00
parent c9077e19ea
commit bd479e4cc4
3 changed files with 111 additions and 0 deletions

View File

@@ -137,6 +137,42 @@ public class Something {
</example>
</rule>
<rule name="GetDescribeShouldUseSObjectDescribeOptions"
language="apex"
since="6.40.0"
message="getDescribe calls should supply valid SObjectDescribeOptions argument"
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_performance.html#getdescribeshouldusesobjectdescribeoptions">
<description>
Explicitly supplying appropriate SObjectDescribeOptions to getDescribe calls to avoid default eager-loading possibly unnecesary
describe information on API version earlier than v43 when may not be really required
</description>
<priority>3</priority>
<properties>
<property name="noDefault" type="Boolean" value="false" description="Do not allow SObjectDescribeOptions.DEFAULT option to ensure consistent results no matter where getDescribe is called"/>
<property name="version" value="2.0"/>
<property name="xpath">
<value>
<![CDATA[
//MethodCallExpression[lower-case(@MethodName) = "getdescribe" and not(VariableExpression/ReferenceExpression[lower-case(@Image) = "sobjectdescribeoptions" ])] |
//ReferenceExpression[$noDefault = true() and lower-case(@Image) = "sobjectdescribeoptions" and parent::VariableExpression[lower-case(@Image) = "default"]]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
public static void bar(List<Account> accounts) {
if (Account.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).isCreateable()) {
insert accounts;
}
}
}
]]>
</example>
</rule>
<rule name="OperationWithLimitsInLoop"
language="apex"
since="6.29.0"

View File

@@ -0,0 +1,11 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.rule.performance;
import net.sourceforge.pmd.testframework.PmdRuleTst;
public class GetDescribeShouldUseSObjectDescribeOptionsTest extends PmdRuleTst {
// no additional unit tests
}

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<test-data
xmlns="http://pmd.sourceforge.net/rule-tests"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">
<test-code>
<description>No describer options</description>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public void bar(List<Account> accounts) {
if (Account.SObjectType.getDescribe().isCreateable()) {
insert accounts;
}
}
}
]]></code>
</test-code>
<test-code>
<description>Correct describer option check</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public void bar(List<Account> accounts) {
if (Account.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).isCreateable()) {
insert accounts;
}
}
}
]]></code>
</test-code>
<test-code>
<description>Default describer option check allowing default</description>
<expected-problems>0</expected-problems>
<code><![CDATA[
public class Foo {
public void bar(List<Account> accounts) {
if (Account.SObjectType.getDescribe(SObjectDescribeOptions.DEFAULT).isCreateable()) {
insert accounts;
}
}
}
]]></code>
</test-code>
<test-code>
<description>Default describer option check restricting default option</description>
<rule-property name="noDefault">true</rule-property>
<expected-problems>1</expected-problems>
<code><![CDATA[
public class Foo {
public void bar(List<Account> accounts) {
if (Account.SObjectType.getDescribe(SObjectDescribeOptions.DEFAULT).isCreateable()) {
insert accounts;
}
}
}
]]></code>
</test-code>
</test-data>