diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index bc1a36ec7a..7fc215597c 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,6 +15,9 @@ This is a {{ site.pmd.release_type }} release. ### 🚀 New and noteworthy ### 🐛 Fixed Issues +* apex + * [#5163](https://github.com/pmd/pmd/issues/5163): \[apex] Parser error when using toLabel in SOSL query + * [#5182](https://github.com/pmd/pmd/issues/5182): \[apex] Parser error when using GROUPING in a SOQL query ### 🚨 API Changes diff --git a/pmd-apex/pom.xml b/pmd-apex/pom.xml index 6f6eaa749c..c616dde033 100644 --- a/pmd-apex/pom.xml +++ b/pmd-apex/pom.xml @@ -92,12 +92,17 @@ kotlin-stdlib-jdk8 compile + + + io.github.apex-dev-tools + apex-parser + 4.2.0 + com.google.summit summit-ast 2.3.0 - io.github.apex-dev-tools apex-ls_2.13 diff --git a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeDumpTest.java b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeDumpTest.java index 997d76819e..5d3cbe3287 100644 --- a/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeDumpTest.java +++ b/pmd-apex/src/test/java/net/sourceforge/pmd/lang/apex/ast/ApexTreeDumpTest.java @@ -70,4 +70,20 @@ class ApexTreeDumpTest extends BaseTreeDumpTest { void trigger() { doTest("AccountTrigger"); } + + /** + * @see [apex] Parser error when using toLabel in SOSL query + */ + @Test + void toLabelInSosl() { + doTest("ToLabelInSosl"); + } + + /** + * @see [apex] Parser error when using GROUPING in a SOQL query + */ + @Test + void groupingInSoql() { + doTest("GroupingInSoql"); + } } diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/GroupingInSoql.cls b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/GroupingInSoql.cls new file mode 100644 index 0000000000..d833bcba56 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/GroupingInSoql.cls @@ -0,0 +1,19 @@ +// https://github.com/pmd/pmd/issues/5182 + +public class GroupingInSoql { + private List getDefects() { + AggregateResult[] defects = [ + SELECT + OBJ1__c O1, + OBJ2__c O2, + OBJ3__c O3, + SUM(OBJ4__c) O4, + GROUPING(OBJ1__c) O1Group, + GROUPING(OBJ2__c) O2Group, + GROUPING(OBJ3__c) O3Group + FROM OBJ4__c + GROUP BY ROLLUP(OBJ1__c, OBJ2__c, OBJ3__c) + ]; + return defects; + } +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/GroupingInSoql.txt b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/GroupingInSoql.txt new file mode 100644 index 0000000000..ee017ca6bf --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/GroupingInSoql.txt @@ -0,0 +1,15 @@ ++- ApexFile[@DefiningType = "GroupingInSoql", @RealLoc = true] + +- UserClass[@DefiningType = "GroupingInSoql", @Image = "GroupingInSoql", @InterfaceNames = (), @Nested = false, @RealLoc = true, @SimpleName = "GroupingInSoql", @SuperClassName = ""] + +- ModifierNode[@Abstract = false, @DefiningType = "GroupingInSoql", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- Method[@Arity = 0, @CanonicalName = "getDefects", @Constructor = false, @DefiningType = "GroupingInSoql", @Image = "getDefects", @RealLoc = true, @ReturnType = "List", @StaticInitializer = false] + +- ModifierNode[@Abstract = false, @DefiningType = "GroupingInSoql", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 2, @Override = false, @Private = true, @Protected = false, @Public = false, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- BlockStatement[@CurlyBrace = true, @DefiningType = "GroupingInSoql", @RealLoc = true] + +- VariableDeclarationStatements[@DefiningType = "GroupingInSoql", @RealLoc = true] + | +- ModifierNode[@Abstract = false, @DefiningType = "GroupingInSoql", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- VariableDeclaration[@DefiningType = "GroupingInSoql", @Image = "defects", @RealLoc = true, @Type = "AggregateResult[]"] + | +- SoqlExpression[@CanonicalQuery = "SELECT\n OBJ1__c O1,\n OBJ2__c O2,\n OBJ3__c O3,\n SUM(OBJ4__c) O4,\n GROUPING(OBJ1__c) O1Group,\n GROUPING(OBJ2__c) O2Group,\n GROUPING(OBJ3__c) O3Group\n FROM OBJ4__c\n GROUP BY ROLLUP(OBJ1__c, OBJ2__c, OBJ3__c)", @DefiningType = "GroupingInSoql", @Query = "SELECT\n OBJ1__c O1,\n OBJ2__c O2,\n OBJ3__c O3,\n SUM(OBJ4__c) O4,\n GROUPING(OBJ1__c) O1Group,\n GROUPING(OBJ2__c) O2Group,\n GROUPING(OBJ3__c) O3Group\n FROM OBJ4__c\n GROUP BY ROLLUP(OBJ1__c, OBJ2__c, OBJ3__c)", @RealLoc = true] + | +- VariableExpression[@DefiningType = "GroupingInSoql", @Image = "defects", @RealLoc = true] + | +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false] + +- ReturnStatement[@DefiningType = "GroupingInSoql", @RealLoc = true] + +- VariableExpression[@DefiningType = "GroupingInSoql", @Image = "defects", @RealLoc = true] + +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false] diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/ToLabelInSosl.cls b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/ToLabelInSosl.cls new file mode 100644 index 0000000000..972bac468d --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/ToLabelInSosl.cls @@ -0,0 +1,16 @@ +// https://github.com/pmd/pmd/issues/5163 + +public with sharing class ToLabelInSosl { + public Object doSoslSearch() { + + List> searchResults = [ + FIND :searchTerm + IN ALL FIELDS + RETURNING + Account(Id, toLabel(Name)) + LIMIT 10 + ]; + + return null; + } +} diff --git a/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/ToLabelInSosl.txt b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/ToLabelInSosl.txt new file mode 100644 index 0000000000..a507de7710 --- /dev/null +++ b/pmd-apex/src/test/resources/net/sourceforge/pmd/lang/apex/ast/ToLabelInSosl.txt @@ -0,0 +1,17 @@ ++- ApexFile[@DefiningType = "ToLabelInSosl", @RealLoc = true] + +- UserClass[@DefiningType = "ToLabelInSosl", @Image = "ToLabelInSosl", @InterfaceNames = (), @Nested = false, @RealLoc = true, @SimpleName = "ToLabelInSosl", @SuperClassName = ""] + +- ModifierNode[@Abstract = false, @DefiningType = "ToLabelInSosl", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = true, @WithoutSharing = false] + +- Method[@Arity = 0, @CanonicalName = "doSoslSearch", @Constructor = false, @DefiningType = "ToLabelInSosl", @Image = "doSoslSearch", @RealLoc = true, @ReturnType = "Object", @StaticInitializer = false] + +- ModifierNode[@Abstract = false, @DefiningType = "ToLabelInSosl", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 1, @Override = false, @Private = false, @Protected = false, @Public = true, @RealLoc = true, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + +- BlockStatement[@CurlyBrace = true, @DefiningType = "ToLabelInSosl", @RealLoc = true] + +- VariableDeclarationStatements[@DefiningType = "ToLabelInSosl", @RealLoc = true] + | +- ModifierNode[@Abstract = false, @DefiningType = "ToLabelInSosl", @DeprecatedTestMethod = false, @Final = false, @Global = false, @InheritedSharing = false, @Modifiers = 0, @Override = false, @Private = false, @Protected = false, @Public = false, @RealLoc = false, @Static = false, @Test = false, @TestOrTestSetup = false, @Transient = false, @Virtual = false, @WebService = false, @WithSharing = false, @WithoutSharing = false] + | +- VariableDeclaration[@DefiningType = "ToLabelInSosl", @Image = "searchResults", @RealLoc = true, @Type = "List>"] + | +- SoslExpression[@CanonicalQuery = "FIND :tmpVar1\n IN ALL FIELDS\n RETURNING\n Account(Id, TOLABEL(Name))\n LIMIT 10", @DefiningType = "ToLabelInSosl", @Query = "\n FIND :searchTerm\n IN ALL FIELDS\n RETURNING\n Account(Id, toLabel(Name))\n LIMIT 10\n ", @RealLoc = true] + | | +- BindExpressions[@DefiningType = "ToLabelInSosl", @RealLoc = true] + | | +- VariableExpression[@DefiningType = "ToLabelInSosl", @Image = "searchTerm", @RealLoc = true] + | | +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false] + | +- VariableExpression[@DefiningType = "ToLabelInSosl", @Image = "searchResults", @RealLoc = true] + | +- EmptyReferenceExpression[@DefiningType = null, @RealLoc = false] + +- ReturnStatement[@DefiningType = "ToLabelInSosl", @RealLoc = true] + +- LiteralExpression[@Boolean = false, @Decimal = false, @DefiningType = "ToLabelInSosl", @Double = false, @Image = "", @Integer = false, @LiteralType = LiteralType.NULL, @Long = false, @Name = null, @Null = true, @RealLoc = true, @String = false]