groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pa...@apache.org
Subject [groovy] branch master updated: GROOVY-9289: @Delegate should check property/method names for annotation attributes like includes/excludes
Date Wed, 23 Oct 2019 23:50:36 GMT
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new d68bd5d  GROOVY-9289: @Delegate should check property/method names for annotation
attributes like includes/excludes
d68bd5d is described below

commit d68bd5d68fd7c1820bfaf10853ea9be5e8e25b92
Author: Paul King <paulk@asert.com.au>
AuthorDate: Wed Oct 23 23:11:00 2019 +1000

    GROOVY-9289: @Delegate should check property/method names for annotation attributes like
includes/excludes
---
 .../transform/DelegateASTTransformation.java       | 25 ++++++++++++++++++++++
 .../groovy/transform/DelegateTransformTest.groovy  | 19 ++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/src/main/java/org/codehaus/groovy/transform/DelegateASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/DelegateASTTransformation.java
index 6da77ed..a855275 100644
--- a/src/main/java/org/codehaus/groovy/transform/DelegateASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/DelegateASTTransformation.java
@@ -35,6 +35,7 @@ import org.codehaus.groovy.ast.PropertyNode;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.tools.BeanUtils;
 import org.codehaus.groovy.ast.tools.GenericsUtils;
 import org.codehaus.groovy.classgen.Verifier;
 import org.codehaus.groovy.control.CompilePhase;
@@ -151,6 +152,8 @@ public class DelegateASTTransformation extends AbstractASTTransformation
{
             delegate.includeTypes = getMemberClassList(node, MEMBER_INCLUDE_TYPES);
             checkIncludeExcludeUndefinedAware(node, delegate.excludes, delegate.includes,
                                               delegate.excludeTypes, delegate.includeTypes,
MY_TYPE_NAME);
+            if (!checkPropertyOrMethodList(delegate.type, delegate.includes, "includes",
node, MY_TYPE_NAME)) return;
+            if (!checkPropertyOrMethodList(delegate.type, delegate.excludes, "excludes",
node, MY_TYPE_NAME)) return;
 
             final List<MethodNode> ownerMethods = getAllMethods(delegate.owner);
             for (MethodNode mn : delegateMethods) {
@@ -196,6 +199,28 @@ public class DelegateASTTransformation extends AbstractASTTransformation
{
         }
     }
 
+    private boolean checkPropertyOrMethodList(ClassNode cNode, List<String> propertyNameList,
String listName, AnnotationNode anno, String typeName) {
+        if (propertyNameList == null || propertyNameList.isEmpty()) {
+            return true;
+        }
+        final List<String> pNames = new ArrayList<>();
+        for (PropertyNode pNode : BeanUtils.getAllProperties(cNode, false, false, false))
{
+            pNames.add(pNode.getField().getName());
+        }
+        final List<String> mNames = new ArrayList<>();
+        for (MethodNode mNode : cNode.getAllDeclaredMethods()) {
+            mNames.add(mNode.getName());
+        }
+        boolean result = true;
+        for (String name : propertyNameList) {
+            if (!pNames.contains(name) && !mNames.contains(name)) {
+                addError("Error during " + typeName + " processing: '" + listName + "' property
or method '" + name + "' does not exist.", anno);
+                result = false;
+            }
+        }
+        return result;
+    }
+
     private static void addSetterIfNeeded(DelegateDescription delegate, PropertyNode prop,
String name, boolean allNames) {
         String setterName = "set" + Verifier.capitalize(name);
         if ((prop.getModifiers() & ACC_FINAL) == 0
diff --git a/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy b/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
index b7ac685..bb60c83 100644
--- a/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
@@ -828,6 +828,25 @@ assert foo.dm.x == '123'
             assert new BugsMe().length == 2
         '''
     }
+
+    // GROOVY-9289
+    void testExcludesWithInvalidPropertyNameResultsInError() {
+        def message = shouldFail """
+            class WMap {
+                String name
+                @Delegate(excludes = "name")
+                Map<String, String> data
+             
+                WMap(String name, Map<String, String> data) {
+                    this.name = name
+                    this.data = data
+                }
+            }
+
+            new WMap('example', [name: 'weird'])
+        """
+        assert message.contains("Error during @Delegate processing: 'excludes' property or
method 'name' does not exist.")
+    }
 }
 
 interface DelegateFoo {


Mime
View raw message