[apex] OperationWithHighCostInLoop - support System.Schema... as well
And improve test cases
This commit is contained in:
2 files changed
+115
-44
No files matched your search
+14
-14
@@ -4,11 +4,15 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.rule.performance;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTMethodCallExpression;
|
||||
import net.sourceforge.pmd.lang.apex.rule.internal.Helper;
|
||||
import net.sourceforge.pmd.lang.rule.RuleTargetSelector;
|
||||
import net.sourceforge.pmd.util.CollectionUtil;
|
||||
|
||||
/**
|
||||
* Warn users when code that could impact performance is executing within a
|
||||
@@ -16,9 +20,12 @@ import net.sourceforge.pmd.lang.rule.RuleTargetSelector;
|
||||
*/
|
||||
public class OperationWithHighCostInLoopRule extends AbstractAvoidNodeInLoopsRule {
|
||||
|
||||
private static final String SCHEMA_CLASS_NAME = "Schema";
|
||||
|
||||
private static final String[] SCHEMA_PERFORMANCE_METHODS = new String[] { "getGlobalDescribe", "describeSObjects" };
|
||||
private static final Set<String> SCHEMA_PERFORMANCE_METHODS = CollectionUtil.setOf(
|
||||
"System.Schema.getGlobalDescribe",
|
||||
"Schema.getGlobalDescribe",
|
||||
"System.Schema.describeSObjects",
|
||||
"Schema.describeSObjects")
|
||||
.stream().map(s -> s.toLowerCase(Locale.ROOT)).collect(Collectors.toSet());
|
||||
|
||||
@Override
|
||||
protected @NonNull RuleTargetSelector buildTargetSelector() {
|
||||
@@ -30,22 +37,15 @@ public class OperationWithHighCostInLoopRule extends AbstractAvoidNodeInLoopsRul
|
||||
// Begin general method invocations
|
||||
@Override
|
||||
public Object visit(ASTMethodCallExpression node, Object data) {
|
||||
if (checkHighCostClassMethods(node, SCHEMA_CLASS_NAME, SCHEMA_PERFORMANCE_METHODS)) {
|
||||
if (checkHighCostClassMethods(node)) {
|
||||
return checkForViolation(node, data);
|
||||
} else {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkHighCostClassMethods(ASTMethodCallExpression node, String className, String[] methodNames) {
|
||||
|
||||
for (String method : methodNames) {
|
||||
if (Helper.isMethodName(node, className, method)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
private boolean checkHighCostClassMethods(ASTMethodCallExpression node) {
|
||||
return SCHEMA_PERFORMANCE_METHODS.contains(node.getFullMethodName().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
// End general method invocations
|
||||
}
|
||||
+101
-30
@@ -6,43 +6,114 @@
|
||||
|
||||
<!-- Begin Schema method invocations -->
|
||||
<test-code>
|
||||
<description>High cost performance getGlobalDescribe in loop</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code>
|
||||
<![CDATA[
|
||||
public class Foo {
|
||||
public void testGetGlobalDescribe() {
|
||||
Set<String> fieldNameSet = new Set<String> {'Id'};
|
||||
for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) {
|
||||
if (Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap().containsKey(fieldNameOrDefaultValue.trim() )) {
|
||||
fieldNameSet.add(fieldNameOrDefaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
<description>High cost performance getGlobalDescribe in loop (correct code) #4675</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void testGetGlobalDescribe() {
|
||||
Map<String, Schema.SObjectField> fieldMap = Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap();
|
||||
Set<String> fieldNameSet = new Set<String> {'Id'};
|
||||
|
||||
for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) {
|
||||
if (fieldMap.containsKey(fieldNameOrDefaultValue.trim())) {
|
||||
fieldNameSet.add(fieldNameOrDefaultValue);
|
||||
}
|
||||
]]>
|
||||
</code>
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>High cost performance describeSObjects in loop</description>
|
||||
<description>High cost performance getGlobalDescribe in loop #4675</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code>
|
||||
<![CDATA[
|
||||
public class Foo {
|
||||
public void test1() {
|
||||
Set<String> fieldNameSet = new Set<String> {'Id'};
|
||||
for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) {
|
||||
Schema.DescribeSObjectResult dsr = Account.sObjectType.getDescribe();
|
||||
if (Schema.describeSObjects(new List<String> { sObjectType })[0].fields.getMap().containsKey(fieldNameOrDefaultValue.trim() )) {
|
||||
fieldNameSet.add(fieldNameOrDefaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
<expected-linenumbers>5</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void testGetGlobalDescribe() {
|
||||
Set<String> fieldNameSet = new Set<String> {'Id'};
|
||||
for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) {
|
||||
if (Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap().containsKey(fieldNameOrDefaultValue.trim() )) {
|
||||
fieldNameSet.add(fieldNameOrDefaultValue);
|
||||
}
|
||||
]]>
|
||||
</code>
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>High cost performance getGlobalDescribe in loop - fully qualified #4675</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>5</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void testGetGlobalDescribe() {
|
||||
Set<String> fieldNameSet = new Set<String> {'Id'};
|
||||
for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) {
|
||||
if (System.Schema.getGlobalDescribe().get(objectName).getDescribe().fields.getMap().containsKey(fieldNameOrDefaultValue.trim() )) {
|
||||
fieldNameSet.add(fieldNameOrDefaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>High cost performance describeSObjects in loop (correct code) #4675</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void testDescribeSObjects() {
|
||||
Map<String, Schema.SObjectField> fieldMap = Schema.describeSObjects(new List<String> { 'Account' })[0].fields.getMap();
|
||||
Set<String> fieldNameSet = new Set<String> {'Id'};
|
||||
for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) {
|
||||
if (fieldMap.containsKey(fieldNameOrDefaultValue.trim())) {
|
||||
fieldNameSet.add(fieldNameOrDefaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>High cost performance describeSObjects in loop #4675</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>6</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void testDescribeSObjects() {
|
||||
String sObjectType = 'Account';
|
||||
Set<String> fieldNameSet = new Set<String> {'Id'};
|
||||
for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) {
|
||||
if (Schema.describeSObjects(new List<String> { sObjectType })[0].fields.getMap().containsKey(fieldNameOrDefaultValue.trim())) {
|
||||
fieldNameSet.add(fieldNameOrDefaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>High cost performance describeSObjects in loop - fully qualified #4675</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>6</expected-linenumbers>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void testDescribeSObjects() {
|
||||
String sObjectType = 'Account';
|
||||
Set<String> fieldNameSet = new Set<String> {'Id'};
|
||||
for (String fieldNameOrDefaultValue : fieldNameOrDefaultValueList) {
|
||||
if (System.Schema.describeSObjects(new List<String> { sObjectType })[0].fields.getMap().containsKey(fieldNameOrDefaultValue.trim())) {
|
||||
fieldNameSet.add(fieldNameOrDefaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<!-- End Schema method invocations -->
|
||||
</test-data>
|
||||
Reference in new issue
Block a user