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]