You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/01/29 17:58:01 UTC

[groovy] branch GROOVY_3_0_X updated (7174a60 -> 4949982)

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a change to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git.


    from 7174a60  no need for jcenter reference in the build
     new 466caea  GROOVY-4516: refactor delegate tests
     new 9352e9c  GROOVY-5239: prefer outer class method over static import method
     new 4949982  GROOVY-5364: find static members from static script methods

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../groovy/ast/expr/MethodCallExpression.java      |   4 +-
 .../groovy/classgen/VariableScopeVisitor.java      |  15 +-
 .../groovy/control/StaticImportVisitor.java        |  22 +-
 src/test/groovy/bugs/Groovy4516Bug.groovy          |  41 --
 src/test/groovy/bugs/Groovy5239.groovy             | 100 ++++
 src/test/groovy/bugs/Groovy5364.groovy             | 104 ++++
 .../groovy/transform/DelegateTransformTest.groovy  | 615 ++++++++++++---------
 7 files changed, 565 insertions(+), 336 deletions(-)
 delete mode 100644 src/test/groovy/bugs/Groovy4516Bug.groovy
 create mode 100644 src/test/groovy/bugs/Groovy5239.groovy
 create mode 100644 src/test/groovy/bugs/Groovy5364.groovy

[groovy] 02/03: GROOVY-5239: prefer outer class method over static import method

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 9352e9c3e55bce5988f9b7de034c7305a82eec41
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu May 27 15:14:27 2021 -0500

    GROOVY-5239: prefer outer class method over static import method
    
    Conflicts:
    	src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
---
 .../groovy/ast/expr/MethodCallExpression.java      |   4 +-
 .../groovy/control/StaticImportVisitor.java        |  22 ++---
 src/test/groovy/bugs/Groovy5239.groovy             | 100 +++++++++++++++++++++
 3 files changed, 112 insertions(+), 14 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
index 4f8583c..6a6379c 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/MethodCallExpression.java
@@ -115,9 +115,7 @@ public class MethodCallExpression extends Expression implements MethodCall {
      * calculated method name, but a constant.
      */
     public String getMethodAsString() {
-        if (!(method instanceof ConstantExpression)) return null;
-        ConstantExpression constant = (ConstantExpression) method;
-        return constant.getText();
+        return (method instanceof ConstantExpression ? method.getText() : null);
     }
 
     public Expression getObjectExpression() {
diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index 5f7e1a5..ad24384 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -59,6 +59,8 @@ import static org.apache.groovy.ast.tools.ClassNodeUtils.hasPossibleStaticProper
 import static org.apache.groovy.ast.tools.ClassNodeUtils.hasStaticProperty;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.isInnerClass;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.isValidAccessorName;
+import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression;
+import static org.apache.groovy.ast.tools.ExpressionUtils.isThisOrSuper;
 import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants;
 import static org.apache.groovy.util.BeanUtils.capitalize;
 import static org.codehaus.groovy.ast.tools.ClosureUtils.getParametersSafe;
@@ -248,16 +250,16 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
         Expression args = transform(mce.getArguments());
 
         if (mce.isImplicitThis()) {
-            if (currentClass.tryFindPossibleMethod(mce.getMethodAsString(), args) == null) {
+            String name = mce.getMethodAsString();
+            if (currentClass.tryFindPossibleMethod(name, args) == null
+                    && currentClass.getOuterClasses().stream().noneMatch(oc -> oc.tryFindPossibleMethod(name, args) != null)) {
                 Expression result = findStaticMethodImportFromModule(method, args);
                 if (result != null) {
                     setSourcePosition(result, mce);
                     return result;
                 }
-                if (method instanceof ConstantExpression && !inLeftExpression) {
-                    // could be a closure field
-                    String methodName = (String) ((ConstantExpression) method).getValue();
-                    result = findStaticFieldOrPropAccessorImportFromModule(methodName);
+                if (name != null && !inLeftExpression) { // maybe a closure field
+                    result = findStaticFieldOrPropAccessorImportFromModule(name);
                     if (result != null) {
                         result = new MethodCallExpression(result, "call", args);
                         result.setSourcePosition(mce);
@@ -265,14 +267,13 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
                     }
                 }
             }
-        } else if (currentMethod != null && currentMethod.isStatic() && (object instanceof VariableExpression && ((VariableExpression) object).isSuperExpression())) {
+        } else if (currentMethod != null && currentMethod.isStatic() && isSuperExpression(object)) {
             Expression result = new MethodCallExpression(new ClassExpression(currentClass.getSuperClass()), method, args);
             result.setSourcePosition(mce);
             return result;
         }
 
-        if (method instanceof ConstantExpression && ((ConstantExpression) method).getValue() instanceof String && (mce.isImplicitThis()
-                || (object instanceof VariableExpression && (((VariableExpression) object).isThisExpression() || ((VariableExpression) object).isSuperExpression())))) {
+        if (method instanceof ConstantExpression && ((ConstantExpression) method).getValue() instanceof String && (mce.isImplicitThis() || isThisOrSuper(object))) {
             String methodName = (String) ((ConstantExpression) method).getValue();
 
             boolean foundInstanceMethod = (currentMethod != null && !currentMethod.isStatic() && currentClass.hasPossibleMethod(methodName, args));
@@ -358,9 +359,8 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
     }
 
     protected Expression transformPropertyExpression(PropertyExpression pe) {
-        if (currentMethod!=null && currentMethod.isStatic()
-                && pe.getObjectExpression() instanceof VariableExpression
-                && ((VariableExpression) pe.getObjectExpression()).isSuperExpression()) {
+        if (currentMethod != null && currentMethod.isStatic()
+                && isSuperExpression(pe.getObjectExpression())) {
             PropertyExpression pexp = new PropertyExpression(
                     new ClassExpression(currentClass.getSuperClass()),
                     transform(pe.getProperty())
diff --git a/src/test/groovy/bugs/Groovy5239.groovy b/src/test/groovy/bugs/Groovy5239.groovy
new file mode 100644
index 0000000..e76281c
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy5239.groovy
@@ -0,0 +1,100 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.bugs
+
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy5239 {
+
+    static class PublicStatic {
+        static who() { 'PublicStatic' }
+    }
+
+    @Test @groovy.test.NotYetImplemented
+    void testStaticImportVersusDelegateMethod() {
+        assertScript '''
+            import static groovy.bugs.Groovy5239.PublicStatic.who
+
+            class C {
+                def who() {
+                    'C'
+                }
+            }
+
+            new C().with {
+                assert 'C' == who()
+            }
+        '''
+    }
+
+    @Test
+    void testStaticImportVersusOuterClassMethod1() {
+        assertScript '''
+            import static groovy.bugs.Groovy5239.PublicStatic.who
+
+            class C {
+                def who() {
+                    'C'
+                }
+                void test() {
+                    assert 'C' == who()
+                    new D().test()
+                }
+
+                class D {
+                    void test() {
+                        assert 'C' == who() // resolves to static import
+                    }
+                }
+            }
+
+            new C().test()
+        '''
+    }
+
+    @Test
+    void testStaticImportVersusOuterClassMethod2() {
+        assertScript '''
+            import static groovy.bugs.Groovy5239.PublicStatic.who
+
+            class C {
+                def who() {
+                    'C'
+                }
+            }
+
+            class D extends C {
+                void test() {
+                    assert 'C' == who()
+                    new E().test()
+                }
+
+                class E {
+                    void test() {
+                        assert 'C' == who() // resolves to static import
+                    }
+                }
+            }
+
+            new D().test()
+        '''
+    }
+}

[groovy] 03/03: GROOVY-5364: find static members from static script methods

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 494998222aaa94bc1ea8bb07b030b4d70808fa50
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri May 28 09:55:01 2021 -0500

    GROOVY-5364: find static members from static script methods
    
    Conflicts:
    	src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
---
 .../groovy/classgen/VariableScopeVisitor.java      |  15 +--
 src/test/groovy/bugs/Groovy5364.groovy             | 104 +++++++++++++++++++++
 2 files changed, 112 insertions(+), 7 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index cc6a324..07102bc 100644
--- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -58,6 +58,7 @@ import java.util.function.BiConsumer;
 import static java.lang.reflect.Modifier.isFinal;
 import static java.lang.reflect.Modifier.isStatic;
 import static org.apache.groovy.ast.tools.MethodNodeUtils.getPropertyName;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.getAllProperties;
 
 /**
  * Initializes the variable scopes for an AST.
@@ -170,10 +171,6 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
         final boolean abstractType = node.isAbstract();
 
         for (ClassNode cn = node; cn != null && !cn.equals(ClassHelper.OBJECT_TYPE); cn = cn.getSuperClass()) {
-            if (cn.isScript()) {
-                return new DynamicVariable(name, false);
-            }
-
             for (FieldNode fn : cn.getFields()) {
                 if (name.equals(fn.getName())) return fn;
             }
@@ -184,7 +181,11 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
 
             for (MethodNode mn : cn.getMethods()) {
                 if ((abstractType || !mn.isAbstract()) && name.equals(getPropertyName(mn))) {
-                    FieldNode fn = new FieldNode(name, mn.getModifiers() & 0xF, ClassHelper.OBJECT_TYPE, cn, null);
+                    // check for override of super class property
+                    for (PropertyNode pn : getAllProperties(cn.getSuperClass())) {
+                        if (name.equals(pn.getName())) return pn;
+                    }
+                    FieldNode fn = new FieldNode(name, mn.getModifiers() & 0xF, ClassHelper.DYNAMIC_TYPE, cn, null);
                     fn.setHasNoRealSourcePosition(true);
                     fn.setDeclaringClass(cn);
                     fn.setSynthetic(true);
@@ -195,8 +196,8 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
                 }
             }
 
-            for (ClassNode face : cn.getAllInterfaces()) {
-                FieldNode fn = face.getDeclaredField(name);
+            for (ClassNode in : cn.getAllInterfaces()) {
+                FieldNode fn = in.getDeclaredField(name);
                 if (fn != null) return fn;
             }
         }
diff --git a/src/test/groovy/bugs/Groovy5364.groovy b/src/test/groovy/bugs/Groovy5364.groovy
new file mode 100644
index 0000000..5ab849e
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy5364.groovy
@@ -0,0 +1,104 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.bugs
+
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+import static groovy.test.GroovyAssert.shouldFail
+
+final class Groovy5364 {
+
+    @Test
+    void testStaticScriptMethodAsProperty1() {
+        assertScript '''
+            static getStaticProperty() {
+                'x'
+            }
+
+            assert 'x' == getStaticProperty()
+            assert 'x' == staticProperty
+        '''
+    }
+
+    @Test
+    void testStaticScriptMethodAsProperty2() {
+        assertScript '''
+            static getSomething() { 'x' }
+            something = 'y' // script var
+
+            assert 'x' == getSomething()
+            assert 'y' == something
+        '''
+    }
+
+    @Test
+    void testStaticScriptMethodAsProperty3() {
+        new GroovyShell(new Binding(something: 'y')).evaluate '''
+            static getSomething() { 'x' }
+
+            assert 'x' == getSomething()
+            assert 'y' == something
+        '''
+    }
+
+    @Test
+    void testStaticScriptMethodAsProperty4() {
+        assertScript '''
+            static getStaticProperty() {
+                'x'
+            }
+
+            void test() {
+                assert 'x' == getStaticProperty()
+                assert 'x' == staticProperty
+            }
+            test()
+        '''
+    }
+
+    @Test
+    void testStaticScriptMethodAsProperty5() {
+        assertScript '''
+            static getStaticProperty() {
+                'x'
+            }
+
+            static void test() {
+                assert 'x' == getStaticProperty()
+                assert 'x' == staticProperty // Apparent variable 'staticProperty' was found in a static scope but doesn't refer to a local variable, static field or class
+            }
+            test()
+        '''
+    }
+
+    @Test
+    void testStaticScriptMethodAsProperty6() {
+        def err = shouldFail '''
+            def getNonStaticProperty() {
+                'x'
+            }
+
+            static void test() {
+                nonStaticProperty
+            }
+        '''
+        assert err =~ /Apparent variable 'nonStaticProperty' was found in a static scope but doesn't refer to a local variable, static field or class/
+    }
+}

[groovy] 01/03: GROOVY-4516: refactor delegate tests

Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 466caeaf657a35e0b78caf7a5d4b9b864364fb6e
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon May 17 19:20:46 2021 -0500

    GROOVY-4516: refactor delegate tests
---
 src/test/groovy/bugs/Groovy4516Bug.groovy          |  41 --
 .../groovy/transform/DelegateTransformTest.groovy  | 615 ++++++++++++---------
 2 files changed, 341 insertions(+), 315 deletions(-)

diff --git a/src/test/groovy/bugs/Groovy4516Bug.groovy b/src/test/groovy/bugs/Groovy4516Bug.groovy
deleted file mode 100644
index 498526b..0000000
--- a/src/test/groovy/bugs/Groovy4516Bug.groovy
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package groovy.bugs
-
-import groovy.test.GroovyTestCase
-
-class Groovy4516Bug extends GroovyTestCase {
-    void testDelegateMethodsWithDefaultValues() {
-        assertScript """
-            class Del4516 {
-                def doSomething(boolean flag = true) { 
-                    flag 
-                }
-            }
-            
-            class AClass4516 { 
-                @Delegate Del4516 Del4516 = new Del4516() 
-            }
-            
-            def a = new AClass4516()
-            assert a.doSomething(false) == false
-            assert a.doSomething() == true
-        """
-    }
-}
diff --git a/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy b/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
index ea6df85..8e7026d 100644
--- a/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/DelegateTransformTest.groovy
@@ -18,16 +18,25 @@
  */
 package org.codehaus.groovy.transform
 
-import gls.CompilableTestSupport
+import org.codehaus.groovy.control.MultipleCompilationErrorsException
+import org.junit.Test
+
+import java.util.concurrent.locks.Lock
+
+import static groovy.test.GroovyAssert.assertScript
+import static groovy.test.GroovyAssert.shouldFail
+import static org.junit.Assert.assertEquals
+import static org.junit.Assert.assertFalse
+import static org.junit.Assert.assertTrue
 
 /**
  * Tests for the {@code @Delegate} AST transform.
  */
-class DelegateTransformTest extends CompilableTestSupport {
+final class DelegateTransformTest {
 
-    /** fix for GROOVY-3380   */
-    void testDelegateImplementingANonPublicInterface() {
-        assertScript """
+    @Test // GROOVY-3380
+    void testDelegateImplementingNonPublicInterface() {
+        assertScript '''
             import org.codehaus.groovy.transform.ClassImplementingANonPublicInterface
 
             class DelegatingToClassImplementingANonPublicInterface {
@@ -36,76 +45,78 @@ class DelegateTransformTest extends CompilableTestSupport {
 
             def constant = new DelegatingToClassImplementingANonPublicInterface().returnConstant()
             assert constant == "constant"
-        """
+        '''
     }
 
-    /** fix for GROOVY-3380   */
-    void testDelegateImplementingANonPublicInterfaceWithZipFileConcreteCase() {
-        assertScript """
+    @Test // GROOVY-3380
+    void testDelegateImplementingNonPublicInterfaceWithZipFileConcreteCase() {
+        assertScript '''
             import java.util.zip.*
 
-            class ZipWrapper{
+            class ZipWrapper {
                @Delegate ZipFile zipFile
             }
 
             new ZipWrapper()
-        """
+        '''
     }
 
-    /** test for GROOVY-5974 */
+    @Test // GROOVY-5974
     void testDelegateExcludes() {
-        assertScript """
-          class MapSet {
-            @Delegate(interfaces=false, excludes=['remove','clear']) Map m = [a: 1]
-            @Delegate Set s = new LinkedHashSet([2, 3, 4] as Set) // HashSet not good enough in JDK 1.5
-            String toString() { m.toString() + ' ' + s }
-          }
-
-          def ms = new MapSet()
-          assert ms.size() == 1
-          assert ms.toString() == '[a:1] [2, 3, 4]'
-          ms.remove(3)
-          assert ms.size() == 1
-          assert ms.toString() == '[a:1] [2, 4]'
-          ms.clear()
-          assert ms.toString() == '[a:1] []'
-        """
+        assertScript '''
+            class MapSet {
+                @Delegate(interfaces=false, excludes=["remove","clear"]) Map m = [a: 1]
+                @Delegate Set s = new LinkedHashSet([2, 3, 4] as Set) // HashSet not good enough in JDK 1.5
+                String toString() { m.toString() + " " + s }
+            }
+
+            def ms = new MapSet()
+            assert ms.size() == 1
+            assert ms.toString() == "[a:1] [2, 3, 4]"
+            ms.remove(3)
+            assert ms.size() == 1
+            assert ms.toString() == "[a:1] [2, 4]"
+            ms.clear()
+            assert ms.toString() == "[a:1] []"
+        '''
     }
 
+    @Test
     void testDelegateCompileStatic() {
-        assertScript """
-          @groovy.transform.CompileStatic
-          class MapSet {
-            @Delegate(interfaces=false, excludes=['remove','clear']) Map m = [a: 1]
-            @Delegate Set s = new LinkedHashSet([2, 3, 4] as Set)
-            String toString() { m.toString() + ' ' + s }
-          }
-
-          def ms = new MapSet()
-          assert ms.size() == 1
-          assert ms.toString() == '{a=1} [2, 3, 4]'
-          ms.remove(3)
-          assert ms.size() == 1
-          assert ms.toString() == '{a=1} [2, 4]'
-          ms.clear()
-          assert ms.toString() == '{a=1} []'
-        """
+        assertScript '''
+            @groovy.transform.CompileStatic
+            class MapSet {
+                @Delegate(interfaces=false, excludes=["remove","clear"]) Map m = [a: 1]
+                @Delegate Set s = new LinkedHashSet([2, 3, 4] as Set)
+                String toString() { m.toString() + " " + s }
+            }
+
+            def ms = new MapSet()
+            assert ms.size() == 1
+            assert ms.toString() == "{a=1} [2, 3, 4]"
+            ms.remove(3)
+            assert ms.size() == 1
+            assert ms.toString() == "{a=1} [2, 4]"
+            ms.clear()
+            assert ms.toString() == "{a=1} []"
+        '''
     }
 
+    @Test
     void testLock() {
-        def res = new GroovyShell().evaluate("""
-              import java.util.concurrent.locks.*
+        def res = new GroovyShell().evaluate('''
+            import java.util.concurrent.locks.*
 
-              class LockableMap {
-                 @Delegate private Map map = [:]
+            class LockableMap {
+               @Delegate private Map map = [:]
 
-                 @Delegate private Lock lock = new ReentrantLock ()
+               @Delegate private Lock lock = new ReentrantLock()
 
-                 @Delegate(interfaces=false) private List list = new ArrayList ()
-              }
+               @Delegate(interfaces=false) private List list = []
+            }
 
-              new LockableMap ()
-        """)
+            new LockableMap()
+        ''')
 
         res.lock()
         try {
@@ -113,41 +124,42 @@ class DelegateTransformTest extends CompilableTestSupport {
             res[1] = 1
             res[2] = 2
 
-            res.add("in list")
+            res.add('in list')
         }
         finally {
             res.unlock()
         }
 
         assertEquals([0: 0, 1: 1, 2: 2], res.@map)
-        assertEquals("in list", res.@list[0])
+        assertEquals('in list', res.@list[0])
 
         assertTrue res instanceof Map
-        assertTrue res instanceof java.util.concurrent.locks.Lock
+        assertTrue res instanceof Lock
         assertFalse res instanceof List
     }
 
+    @Test
     void testMultiple() {
-        def res = new GroovyShell().evaluate("""
-        class X {
-          def value = 10
-        }
+        def res = new GroovyShell().evaluate('''
+            class X {
+                def value = 10
+            }
 
-        class Y {
-          @Delegate X  x  = new X ()
-          @Delegate XX xx = new XX ()
+            class Y {
+                @Delegate X  x  = new X ()
+                @Delegate XX xx = new XX ()
 
-          void setValue (v) {
-            this.@x.@value = 12
-          }
-        }
+                void setValue (v) {
+                    this.@x.@value = 12
+                }
+            }
 
-        class XX {
-          def value2 = 11
-        }
+            class XX {
+                def value2 = 11
+            }
 
-        new Y ()
-        """)
+            new Y ()
+        ''')
 
         assertEquals 10, res.value
         assertEquals 11, res.value2
@@ -155,31 +167,33 @@ class DelegateTransformTest extends CompilableTestSupport {
         assertEquals 12, res.value
     }
 
+    @Test
     void testUsingDateCompiles() {
-        assertScript """
-        class Foo {
-          @Delegate Date d = new Date();
-        }
-        Foo
-      """
+        assertScript '''
+            class C {
+                @Delegate Date d = new Date()
+            }
+            new C()
+        '''
     }
 
-    /** fix for GROOVY-3471   */
+    @Test // GROOVY-3471
     void testDelegateOnAMapTypeFieldWithInitializationUsingConstructorProperties() {
-        assertScript """
+        // this was resulting in NPE due to MetaClassImpl's special handling of Map
+        assertScript '''
             class Test3471 { @Delegate Map mp }
-            def t = new Test3471(mp: new HashMap()) // this was resulting in a NPE due to MetaClassImpl's special handling of Map
-            assert t.keySet().size() == 0
-        """
+            def t = new Test3471(mp: [:])
+            assert t.keySet().isEmpty()
+        '''
     }
 
-    /** GROOVY-3323   */
+    @Test // GROOVY-3323
     void testDelegateTransformCorrectlyDelegatesMethodsFromSuperInterfaces() {
         assert new DelegateBarImpl(new DelegateFooImpl()).bar() == 'bar impl'
         assert new DelegateBarImpl(new DelegateFooImpl()).foo() == 'foo impl'
     }
 
-    /** GROOVY-3555   */
+    @Test // GROOVY-3555
     void testDelegateTransformIgnoresDeprecatedMethodsByDefault() {
         def b1 = new DelegateBarForcingDeprecated(baz: new BazWithDeprecatedFoo())
         def b2 = new DelegateBarWithoutDeprecated(baz: new BazWithDeprecatedFoo())
@@ -191,9 +205,9 @@ class DelegateTransformTest extends CompilableTestSupport {
         }
     }
 
-    /** GROOVY-4163   */
+    @Test // GROOVY-4163
     void testDelegateTransformAllowsInterfacesAndDelegation() {
-        assertScript """
+        assertScript '''
             class Temp implements Runnable {
                 @Delegate
                 private Thread runnable
@@ -203,23 +217,30 @@ class DelegateTransformTest extends CompilableTestSupport {
                     def temp = new Temp(runnable: thread)
                 }
             }
-        """
+        '''
+    }
+
+    @Test
+    void testDelegateToObjectShouldFail() {
+        shouldFail '''
+            class C {
+                @Delegate b = new Object()
+            }
+        '''
     }
 
+    @Test
     void testDelegateToSelfTypeShouldFail() {
-        shouldNotCompile """
-            class B {
-                @Delegate B b = new B()
-                static main(args){
-                    new B()
-                }
+        shouldFail '''
+            class C {
+                @Delegate C c = new C()
             }
-        """
+        '''
     }
 
-    // GROOVY-4265
+    @Test // GROOVY-4265
     void testShouldPreferDelegatedOverStaticSuperMethod() {
-        assertScript """
+        assertScript '''
             class A {
                 static foo(){"A->foo()"}
             }
@@ -229,19 +250,11 @@ class DelegateTransformTest extends CompilableTestSupport {
             class C {
                 def foo(){"C->foo()"}
             }
-            assert new B().foo() == 'C->foo()'
-        """
-    }
-
-    void testDelegateToObjectShouldFail() {
-        shouldNotCompile """
-            class B {
-                @Delegate b = new Object()
-            }
-        """
+            assert new B().foo() == "C->foo()"
+        '''
     }
 
-    /** GROOVY-4244 */
+    @Test // GROOVY-4244
     void testSetPropertiesThroughDelegate() {
         def foo = new Foo4244()
 
@@ -255,25 +268,26 @@ class DelegateTransformTest extends CompilableTestSupport {
         }
     }
 
-    void testDelegateSuperInterfaces_Groovy4619() {
+    @Test // GROOVY-4619
+    void testDelegateSuperInterfaces() {
         assert 'doSomething' in SomeClass4619.class.methods*.name
     }
 
-    // GROOVY-5112
+    @Test // GROOVY-5112
     void testGenericsOnArray() {
         assertScript '''
             class ListWrapper {
-              @Delegate
-              List myList
+                @Delegate
+                List myList
 
-              @Delegate
-              URL homepage
+                @Delegate
+                URL homepage
             }
             new ListWrapper()
         '''
     }
 
-    // GROOVY-5732
+    @Test // GROOVY-5732
     void testInterfacesFromSuperClasses() {
         assertScript '''
             interface I5732 {
@@ -294,7 +308,7 @@ class DelegateTransformTest extends CompilableTestSupport {
         '''
     }
 
-    // GROOVY-5729
+    @Test // GROOVY-5729
     void testDeprecationWithInterfaces() {
         assertScript '''
             interface I5729 {
@@ -306,25 +320,25 @@ class DelegateTransformTest extends CompilableTestSupport {
                 @Delegate private I5729 delegate
             }
             assert I5729.isAssignableFrom(Delegator1)
-            assert Delegator1.methods*.name.contains('aMethod')
+            assert Delegator1.methods*.name.contains("aMethod")
 
             class Delegator2 {
                 @Delegate(interfaces=false) private I5729 delegate
             }
             assert !I5729.isAssignableFrom(Delegator2)
-            assert !Delegator2.methods*.name.contains('aMethod')
+            assert !Delegator2.methods*.name.contains("aMethod")
 
             class Delegator3 {
                 @Delegate(interfaces=false, deprecated=true) private I5729 delegate
             }
             assert !I5729.isAssignableFrom(Delegator3)
-            assert Delegator3.methods*.name.contains('aMethod')
+            assert Delegator3.methods*.name.contains("aMethod")
         '''
     }
 
-    // GROOVY-5446
+    @Test // GROOVY-5446
     void testDelegateWithParameterAnnotations() {
-        assertScript """
+        assertScript '''
             import java.lang.annotation.*
 
             @Retention(RetentionPolicy.RUNTIME)
@@ -341,19 +355,20 @@ class DelegateTransformTest extends CompilableTestSupport {
                 A a = new A()
             }
 
-            def originalMethod = A.getMethod('method', [Object.class] as Class[])
+            def originalMethod = A.getMethod("method", [Object.class] as Class[])
             def originalAnno = originalMethod.parameterAnnotations[0][0]
 
-            def delegateMethod = A_Delegate.getMethod('method', [Object.class] as Class[])
+            def delegateMethod = A_Delegate.getMethod("method", [Object.class] as Class[])
             def delegateAnno = delegateMethod.parameterAnnotations[0][0]
             println delegateMethod.parameterAnnotations
 
             assert delegateAnno == originalAnno
-        """
+        '''
     }
 
+    @Test
     void testDelegateWithMethodAnnotations() {
-        assertScript """
+        assertScript '''
             import java.lang.annotation.*
 
             @Retention(RetentionPolicy.RUNTIME)
@@ -372,21 +387,22 @@ class DelegateTransformTest extends CompilableTestSupport {
                 A a = new A()
             }
 
-            def originalMethod = A.getMethod('method', [Object.class] as Class[])
+            def originalMethod = A.getMethod("method", [Object.class] as Class[])
             def originalAnno = originalMethod.declaredAnnotations[0]
 
-            def delegateMethod = A_Delegate.getMethod('method', [Object.class] as Class[])
+            def delegateMethod = A_Delegate.getMethod("method", [Object.class] as Class[])
             def delegateAnno = delegateMethod.declaredAnnotations[1]
 
             assert delegateAnno == originalAnno
 
             assert delegateAnno.value() == 42
             assert delegateAnno.value() == originalAnno.value()
-        """
+        '''
     }
 
+    @Test
     void testParameterAnnotationsShouldNotBeCarriedOverByDefault() {
-        assertScript """
+        assertScript '''
             import java.lang.annotation.*
 
             @Retention(RetentionPolicy.RUNTIME)
@@ -403,74 +419,73 @@ class DelegateTransformTest extends CompilableTestSupport {
                 A a = new A()
             }
 
-            def originalMethod = A.getMethod('method', [Object.class] as Class[])
+            def originalMethod = A.getMethod("method", [Object.class] as Class[])
             def originalAnno = originalMethod.parameterAnnotations[0][0]
 
-            def delegateMethod = A_Delegate.getMethod('method', [Object.class] as Class[])
+            def delegateMethod = A_Delegate.getMethod("method", [Object.class] as Class[])
             assert delegateMethod.parameterAnnotations[0].length == 0
-        """
+        '''
     }
 
     // this test reflects that we currently don't support carrying over
     // Closure Annotations rather than a desired design goal
     // TODO: support Closure Annotations and then remove/change this test
+    @Test
     void testAnnotationWithClosureMemberIsNotSupported() {
-        def message = shouldFail {
-            assertScript """
-                import java.lang.annotation.*
-
-                @Retention(RetentionPolicy.RUNTIME)
-                @Target([ElementType.METHOD])
-                public @interface SomeAnnotation {
-                    Class value()
-                }
+        def err = shouldFail '''
+            import java.lang.annotation.*
 
-                class A {
-                    @SomeAnnotation({ param != null })
-                    def method(def param) { "Test" }
-                }
+            @Retention(RetentionPolicy.RUNTIME)
+            @Target([ElementType.METHOD])
+            public @interface SomeAnnotation {
+                Class value()
+            }
 
-                class A_Delegate {
-                    @Delegate(methodAnnotations = true)
-                    A a = new A()
-                }
-            """
-        }
+            class A {
+                @SomeAnnotation({ param != null })
+                def method(def param) { "Test" }
+            }
 
-        assert message.contains('@Delegate does not support keeping Closure annotation members.')
+            class A_Delegate {
+                @Delegate(methodAnnotations = true)
+                A a = new A()
+            }
+        '''
+
+        assert err.message.contains('@Delegate does not support keeping Closure annotation members.')
     }
 
     // this test reflects that we currently don't support carrying over
     // Closure Annotations rather than a desired design goal
     // TODO: support Closure Annotations and then remove/change this test
+    @Test
     void testAnnotationWithClosureClassDescendantIsNotSupported() {
-        def message = shouldFail {
-            assertScript """
-                import java.lang.annotation.*
-
-                @Retention(RetentionPolicy.RUNTIME)
-                @Target([ElementType.METHOD])
-                public @interface SomeAnnotation {
-                    Class value()
-                }
+        def err = shouldFail '''
+            import java.lang.annotation.*
 
-                class A {
-                    @SomeAnnotation(org.codehaus.groovy.runtime.GeneratedClosure.class)
-                    def method(def param) { "Test" }
-                }
+            @Retention(RetentionPolicy.RUNTIME)
+            @Target([ElementType.METHOD])
+            public @interface SomeAnnotation {
+                Class value()
+            }
 
-                class A_Delegate {
-                    @Delegate(methodAnnotations = true)
-                    A a = new A()
-                }
-            """
-        }
-        assert message.contains('@Delegate does not support keeping Closure annotation members.')
+            class A {
+                @SomeAnnotation(org.codehaus.groovy.runtime.GeneratedClosure.class)
+                def method(def param) { "Test" }
+            }
+
+            class A_Delegate {
+                @Delegate(methodAnnotations = true)
+                A a = new A()
+            }
+        '''
+
+        assert err.message.contains('@Delegate does not support keeping Closure annotation members.')
     }
 
-    // GROOVY-5445
+    @Test // GROOVY-5445
     void testDelegateToSuperProperties() {
-        assertScript """
+        assertScript '''
             class Foo {
                 @Delegate Bar delegate = new Bar()
                 def foo() {
@@ -484,11 +499,11 @@ class DelegateTransformTest extends CompilableTestSupport {
 
             def f = new Foo()
             f.foo()
-            assert f.bar + f.baz == 'barbaz'
-        """
+            assert f.bar + f.baz == "barbaz"
+        '''
     }
 
-    // GROOVY-7243
+    @Test // GROOVY-7243
     void testInclude() {
         assertScript '''
             class Book {
@@ -507,35 +522,35 @@ class DelegateTransformTest extends CompilableTestSupport {
             class OwnedBook {
                 String owner
 
-                @Delegate(includes=['author', 'getTitleAndAuthor'])
+                @Delegate(includes=["author", "getTitleAndAuthor"])
                 Book book
             }
 
-            Book book = new Book(title: 'Ulysses', author: 'James Joyce')
-            OwnedBook ownedBook = new OwnedBook(owner: 'John Smith', book: book)
+            Book book = new Book(title: "Ulysses", author: "James Joyce")
+            OwnedBook ownedBook = new OwnedBook(owner: "John Smith", book: book)
 
-            ownedBook.author = 'John Smith'
-            assert book.author == 'John Smith'
+            ownedBook.author = "John Smith"
+            assert book.author == "John Smith"
 
-            assert ownedBook.getTitleAndAuthor() == 'Ulysses : John Smith'
+            assert ownedBook.getTitleAndAuthor() == "Ulysses : John Smith"
 
             try {
                 ownedBook.getAuthorAndTitle()
-                assert false, 'Non-included methods should not be delegated'
+                assert false : "Non-included methods should not be delegated"
             } catch(groovy.lang.MissingMethodException expected) {
             }
 
             try {
-                ownedBook.title = 'Finnegans Wake'
-                assert false, 'Non-included properties should not be delegated'
+                ownedBook.title = "Finnegans Wake"
+                assert false : "Non-included properties should not be delegated"
             } catch(groovy.lang.MissingPropertyException expected) {
             }
         '''
     }
 
-    // GROOVY-6329
+    @Test // GROOVY-6329
     void testIncludeAndExcludeByType() {
-        assertScript """
+        assertScript '''
             interface OddInclusionsTU<T, U> {
                 boolean addAll(Collection<? extends T> t)
                 boolean add(U u)
@@ -571,12 +586,12 @@ class DelegateTransformTest extends CompilableTestSupport {
             assert list.indexOf(8) == 1
             list.clear()
             assert list.all == [2, 8, 4, 6, 3, 5, 7, 9]
-        """
+        '''
     }
 
-    // GROOVY-5211
+    @Test // GROOVY-5211
     void testAvoidFieldNameClashWithParameterName() {
-        assertScript """
+        assertScript '''
             class A {
                 def foo(a) { a * 2 }
             }
@@ -586,66 +601,80 @@ class DelegateTransformTest extends CompilableTestSupport {
             }
 
             assert new B().foo(10) == 20
-        """
+        '''
     }
 
-    // GROOVY-6542
+    @Test
+    void testUnknownTypes() {
+        shouldFail MultipleCompilationErrorsException, '''
+            class Foo {
+                @Delegate(includeTypes=XYZZY) List a = []
+            }
+        '''
+        shouldFail MultipleCompilationErrorsException, '''
+            class Foo {
+                @Delegate(excludeTypes=42) List a = []
+            }
+        '''
+    }
+
+    @Test // GROOVY-6542
     void testLineNumberInStackTrace() {
-        try {
-            assertScript '''import groovy.transform.ASTTest
-
-    @ASTTest(phase=CANONICALIZATION, value={
-        def fieldNode = node.getDeclaredField('thingie')
-        def blowupMethod = node.getDeclaredMethod('blowup')
-        def mce = blowupMethod.code.expression
-        assert mce.lineNumber==fieldNode.lineNumber
-        assert mce.lineNumber>0
-    })
-    class Upper {
-      @Delegate Lower thingie
-
-      Upper() {
-        thingie = new Lower()
-      }
-    }
-
-    class Lower {
-      def foo() {
-        println("Foo!")
-      }
-
-      def blowup(String a) {
-        throw new Exception("blow up with ${a}")
-      }
-
-      def blowup() {
-        throw new Exception("blow up")
-      }
-    }
-
-    def up = new Upper()
-    up.foo()
-    up.blowup("bar")
-    '''
-        } catch (e) {
-            // ok
-        }
+        def err = shouldFail '''\
+            @groovy.transform.ASTTest(phase=CANONICALIZATION, value={
+                def property = node.getDeclaredField("thingie")
+                def method = node.getDeclaredMethod("blowup")
+                def call = method.code.expression
+
+                assert property.lineNumber > 0
+                assert call.lineNumber == property.lineNumber
+            })
+            class Upper {
+                @Delegate Lower thingie
+
+                Upper() {
+                    thingie = new Lower()
+                }
+            }
+
+            class Lower {
+                def foo() {
+                    println("Foo!")
+                }
+
+                def blowup(String a) {
+                    throw new Exception("blow up with ${a}")
+                }
+
+                def blowup() {
+                    throw new Exception("blow up")
+                }
+            }
+
+            def up = new Upper()
+            up.foo()
+            up.blowup("bar")
+        '''
+
+        String stackTrace = err.asString()
+        assert stackTrace =~ /at Upper\.blowup\(TestScript\d+\.groovy:10\)/
     }
 
-    //
+    @Test
     void testShouldNotReuseRawClassNode() {
-        assertScript '''import org.codehaus.groovy.transform.DelegateMap
-class Foo {
-    DelegateMap dm = new DelegateMap()
-}
-def foo = new Foo()
-assert foo.dm.x == '123'
-'''
+        assertScript '''
+            import org.codehaus.groovy.transform.DelegateMap
+            class Foo {
+                DelegateMap dm = new DelegateMap()
+            }
+            def foo = new Foo()
+            assert foo.dm.x == "123"
+        '''
     }
 
-    // GROOVY-7118
+    @Test // GROOVY-7118
     void testDelegateOfMethodHavingPlaceholder() {
-        assertScript """
+        assertScript '''
             interface FooInt {
               public <T extends Throwable> T get(Class<T> clazz) throws Exception
             }
@@ -673,14 +702,14 @@ assert foo.dm.x == '123'
                 @Delegate Bar bar = new Bar()
             }
             assert new BarMain().get(Exception).class == Exception
-        """
+        '''
     }
 
-    // GROOVY-7261
+    @Test // GROOVY-7261
     void testShouldWorkWithLazyTransform() {
         assertScript '''
             class Foo {
-                private @Delegate @Lazy ArrayList list = ['bar', 'baz']
+                private @Delegate @Lazy ArrayList list = ["bar", "baz"]
                 // fragile: $list is an internal implementation detail that may change
                 def getInternalDelegate() { $list }
             }
@@ -688,11 +717,11 @@ assert foo.dm.x == '123'
             def f = new Foo()
             assert f.internalDelegate == null
             assert f.size() == 2
-            assert f.internalDelegate == ['bar', 'baz']
+            assert f.internalDelegate == ["bar", "baz"]
         '''
     }
 
-    // GROOVY-6454
+    @Test // GROOVY-6454
     void testMethodsWithInternalNameShouldNotBeDelegatedTo() {
         assertScript '''
             class HasMethodWithInternalName {
@@ -709,7 +738,7 @@ assert foo.dm.x == '123'
         '''
     }
 
-    // GROOVY-6454
+    @Test // GROOVY-6454
     void testMethodsWithInternalNameShouldBeDelegatedToIfRequested() {
         assertScript '''
             interface HasMethodWithInternalName {
@@ -725,7 +754,7 @@ assert foo.dm.x == '123'
         '''
     }
 
-    // GROOVY-6454
+    @Test // GROOVY-6454
     void testProperitesWithInternalNameShouldBeDelegatedToIfRequested() {
         assertScript '''
             class HasPropertyWithInternalName {
@@ -743,6 +772,7 @@ assert foo.dm.x == '123'
         '''
     }
 
+    @Test
     void testDelegateToGetterMethod() {
         // given:
         def delegate = { new DelegateFooImpl() }
@@ -752,9 +782,9 @@ assert foo.dm.x == '123'
         assert foo.foo() == delegate().foo()
     }
 
-    // GROOVY-5752
+    @Test // GROOVY-5752
     void testDelegationShouldAccountForPrimitiveBooleanProperties() {
-        assertScript """
+        assertScript '''
             class A {
                 boolean a
                 boolean b
@@ -778,10 +808,10 @@ assert foo.dm.x == '123'
             assert b.isA()
             assert b.isB()
             assert b.getC()
-        """
+        '''
     }
 
-    //GROOVY-8132
+    @Test //GROOVY-8132
     void testOwnerPropertyPreferredToDelegateProperty() {
         assertScript '''
             class Foo {
@@ -793,44 +823,43 @@ assert foo.dm.x == '123'
             class Bar {
                 String pls
             }
-            assert new Foo(pls: 'ok').pls == 'ok'
+            assert new Foo(pls: "ok").pls == "ok"
         '''
     }
 
+    @Test
     void testOwnerMethodPreferredToDelegateMethod() {
         assertScript '''
             class Foo {
-                String pls() { 'foo pls' }
+                String pls() { "foo pls" }
                 @groovy.lang.Delegate
                 Bar bar
             }
 
             class Bar {
-                String pls() { 'bar pls' }
+                String pls() { "bar pls" }
             }
-            assert new Foo(bar: new Bar()).pls() == 'foo pls'
+            assert new Foo(bar: new Bar()).pls() == "foo pls"
         '''
     }
 
-    // GROOVY-8204
+    @Test // GROOVY-8204
     void testDelegateToArray() {
         assertScript '''
-            import groovy.lang.Delegate
-
             class BugsMe {
                 @Delegate
-                String[] content = ['foo', 'bar']
+                String[] content = ["foo", "bar"]
             }
 
-            assert new BugsMe().content.join() == 'foobar'
+            assert new BugsMe().content.join() == "foobar"
             assert new BugsMe().content.length == 2
             assert new BugsMe().length == 2
         '''
     }
 
-    // GROOVY-9289
+    @Test // GROOVY-9289
     void testExcludesWithInvalidPropertyNameResultsInError() {
-        def message = shouldFail """
+        def err = shouldFail '''
             class WMap {
                 String name
                 @Delegate(excludes = "name")
@@ -842,12 +871,13 @@ assert foo.dm.x == '123'
                 }
             }
 
-            new WMap('example', [name: 'weird'])
-        """
-        assert message.contains("Error during @Delegate processing: 'excludes' property or method 'name' does not exist.")
+            new WMap("example", [name: "weird"])
+        '''
+
+        assert err.message.contains("Error during @Delegate processing: 'excludes' property or method 'name' does not exist.")
     }
 
-    // GROOVY-8825
+    @Test // GROOVY-8825
     void testDelegateToPrecompiledGroovyGeneratedMethod() {
         assertScript '''
             import org.codehaus.groovy.transform.CompiledClass8825
@@ -855,24 +885,61 @@ assert foo.dm.x == '123'
                 @Delegate(methodAnnotations = true)
                 private final CompiledClass8825 delegate = new CompiledClass8825()
             }
-            assert new B().s == '456'
+            assert new B().s == "456"
         '''
     }
 
-    // GROOVY-9414
+    @Test // GROOVY-9414
     void testDelegateToPropertyViaGetter() {
         assertScript '''
             class Bar {
                 String name
             }
             class BarDelegate {
-                @Delegate(includes = "getName") Bar bar = new Bar(name: 'Baz')
+                @Delegate(includes = "getName") Bar bar = new Bar(name: "Baz")
             }
-            assert new BarDelegate().name == 'Baz'
+            assert new BarDelegate().name == "Baz"
+        '''
+    }
+
+    @Test // GROOVY-4516
+    void testParameterWithDefaultArgument1() {
+        assertScript '''
+            class C {
+                def m(boolean b = true) {
+                    b
+                }
+            }
+            class D {
+                @Delegate private C c = new C()
+            }
+
+            assert new D().m() == true
+            assert new D().m(false) == false
+        '''
+    }
+
+    @Test // GROOVY-4516
+    void testParameterWithDefaultArgument2() {
+        assertScript '''
+            class C {
+                def m(x = "x", y = "y", int z) {
+                    "" + x + y + z
+                }
+            }
+            class D {
+                @Delegate private C c = new C()
+            }
+
+            assert new D().m(1) == "xy1"
+            assert new D().m(1,2) == "1y2"
+            assert new D().m(1,2,3) == "123"
         '''
     }
 }
 
+//------------------------------------------------------------------------------
+
 interface DelegateFoo {
     def foo()
 }
@@ -955,4 +1022,4 @@ class CompiledClass8825 {
 // WHAT IT IS SUPPOSED TO TEST ANYMORE !
 class DelegateMap {
     protected final @Delegate Map props = [x:'123']
-}
\ No newline at end of file
+}