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 2024/01/05 22:10:47 UTC

(groovy) branch GROOVY_4_0_X updated: GROOVY-8854: write `T.m(p)` as `this.m($static$self,p)` not `$self.m(p)`

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

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


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new e0a2db64d3 GROOVY-8854: write `T.m(p)` as `this.m($static$self,p)` not `$self.m(p)`
e0a2db64d3 is described below

commit e0a2db64d3eca236b6e0d34d358e1ebb021123db
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Jan 5 15:36:46 2024 -0600

    GROOVY-8854: write `T.m(p)` as `this.m($static$self,p)` not `$self.m(p)`
    
    GROOVY-7191, GROOVY-7322, GROOVY-11267
    
    4_0_X backport
---
 .../transform/stc/TraitTypeCheckingExtension.java  |  119 +--
 .../groovy/transform/trait/TraitComposer.java      |    6 +-
 .../transform/trait/TraitReceiverTransformer.java  |   29 +-
 .../classgen/asm/sc/bugs/Groovy7322Bug.groovy      |   64 --
 .../groovy/transform/traitx/Groovy7255Bug.groovy   |   40 -
 .../traitx/TraitASTTransformationTest.groovy       | 1047 ++++++++++++--------
 .../traitx/TraitWithClosureOrLambda.groovy         |   26 +
 7 files changed, 702 insertions(+), 629 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java b/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
index 87a9483cb9..cb0e316409 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
@@ -25,125 +25,72 @@ import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.MethodCall;
 import org.codehaus.groovy.ast.expr.MethodCallExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.transform.trait.TraitASTTransformation;
 import org.codehaus.groovy.transform.trait.Traits;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.LinkedHashSet;
 import java.util.List;
 
 import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.isClassClassNodeWrappingConcreteType;
 
 /**
- * A type checking extension that will take care of handling errors which are specific to traits. In particular, it will
- * handle the "super" method calls within a trait.
+ * An extension that handles field, super and static method calls within a trait.
  *
  * @since 2.3.0
  */
 public class TraitTypeCheckingExtension extends AbstractTypeCheckingExtension {
-    private static final List<MethodNode> NOTFOUND = Collections.emptyList();
 
-    /**
-     * Builds a type checking extension relying on a Groovy script (type checking DSL).
-     *
-     * @param typeCheckingVisitor the type checking visitor
-     */
     public TraitTypeCheckingExtension(final StaticTypeCheckingVisitor typeCheckingVisitor) {
         super(typeCheckingVisitor);
     }
 
-    @Override
-    public void setup() {
-    }
-
     @Override
     public List<MethodNode> handleMissingMethod(final ClassNode receiver, final String name, final ArgumentListExpression argumentList, final ClassNode[] argumentTypes, final MethodCall call) {
         String[] decomposed = Traits.decomposeSuperCallName(name);
         if (decomposed != null) {
-            return convertToDynamicCall(call, receiver, decomposed, argumentTypes);
-        }
-        if (call instanceof MethodCallExpression) {
-            MethodCallExpression mce = (MethodCallExpression) call;
-            if (mce.getReceiver() instanceof VariableExpression) {
-                VariableExpression var = (VariableExpression) mce.getReceiver();
+            String traitName = decomposed[0], methodName = decomposed[1];
+            List<ClassNode> implementedTraits = Traits.findTraits(receiver);
 
-                // GROOVY-7322
-                // static method call in trait?
-                ClassNode type = null;
-                if (isStaticTraitReceiver(receiver, var)) {
-                    type = receiver.getGenericsTypes()[0].getType();
-                } else if (isThisTraitReceiver(var)) {
-                    type = receiver;
-                }
-                if (Traits.isTrait(type) && !(type instanceof UnionTypeClassNode)) {
-                    List<ClassNode> candidates = new ArrayList<ClassNode>();
-                    candidates.add(type);
-                    while (!candidates.isEmpty()) {
-                        ClassNode next = candidates.remove(0);
-                        if (!Traits.isTrait(next)) continue;
-                        ClassNode helper = Traits.findHelper(next);
-                        Parameter[] params = new Parameter[argumentTypes.length + 1];
-                        params[0] = new Parameter(ClassHelper.CLASS_Type.getPlainNodeReference(), "staticSelf");
-                        for (int i = 1; i < params.length; i++) {
-                            params[i] = new Parameter(argumentTypes[i-1], "p" + i);
-                        }
-                        MethodNode method = helper.getDeclaredMethod(name, params);
-                        if (method != null) {
-                            return Collections.singletonList(makeDynamic(call, method.getReturnType()));
-                        }
-                        // GROOVY-8272 support inherited static methods
-                        candidates.addAll(Arrays.asList(next.getInterfaces()));
-                    }
+            ClassNode nextTrait = null;
+            for (int i = 0; i < implementedTraits.size() - 1; i += 1) {
+                ClassNode implementedTrait = implementedTraits.get(i);
+                if (implementedTrait.getName().equals(traitName)) {
+                    nextTrait = implementedTraits.get(i + 1);
                 }
             }
 
-            ClassNode dynamic = mce.getNodeMetaData(TraitASTTransformation.DO_DYNAMIC);
-            if (dynamic!=null) {
-                return Collections.singletonList(makeDynamic(call, dynamic));
+            ClassNode returnType = ClassHelper.OBJECT_TYPE;
+            if (nextTrait != null) {
+                List<MethodNode> candidates = typeCheckingVisitor.findMethod(nextTrait, methodName, argumentTypes);
+                if (candidates.size() == 1) {
+                    returnType = candidates.get(0).getReturnType();
+                }
             }
+
+            return Collections.singletonList(makeDynamic(call, returnType));
         }
-        return NOTFOUND;
-    }
 
-    private static boolean isStaticTraitReceiver(final ClassNode receiver, final VariableExpression var) {
-        return Traits.STATIC_THIS_OBJECT.equals(var.getName()) && isClassClassNodeWrappingConcreteType(receiver);
-    }
+        if (call instanceof MethodCallExpression) {
+            MethodCallExpression mce = (MethodCallExpression) call;
+            ClassNode dynamic = mce.getNodeMetaData(TraitASTTransformation.DO_DYNAMIC);
+            if (dynamic != null) return Collections.singletonList(makeDynamic(call, dynamic));
 
-    private static boolean isThisTraitReceiver(final VariableExpression var) {
-        return Traits.THIS_OBJECT.equals(var.getName());
-    }
+            // GROOVY-7322, GROOVY-8272, GROOVY-8587, GROOVY-8854: trait: this.m($static$self)
+            ClassNode targetClass = isClassClassNodeWrappingConcreteType(receiver)? receiver.getGenericsTypes()[0].getType(): receiver;
+            if (Traits.isTrait(targetClass.getOuterClass()) && argumentTypes.length > 0 && ClassHelper.isClassType(argumentTypes[0])) {
+                Parameter[] signature = java.util.Arrays.stream(argumentTypes).map(t -> new Parameter(t,"")).toArray(Parameter[]::new);
+                List<ClassNode> traits = Traits.findTraits(targetClass.getOuterClass());
+                traits.remove(targetClass.getOuterClass());
 
-    private List<MethodNode> convertToDynamicCall(MethodCall call, ClassNode receiver, String[] decomposed, ClassNode[] argumentTypes) {
-        String traitName = decomposed[0];
-        String name = decomposed[1];
-        LinkedHashSet<ClassNode> traitsAsList = Traits.collectAllInterfacesReverseOrder(receiver, new LinkedHashSet<ClassNode>());
-        ClassNode[] implementedTraits = traitsAsList.toArray(ClassNode.EMPTY_ARRAY);
-        ClassNode nextTrait = null;
-        for (int i = 0; i < implementedTraits.length - 1; i++) {
-            ClassNode implementedTrait = implementedTraits[i];
-            if (implementedTrait.getName().equals(traitName)) {
-                nextTrait = implementedTraits[i + 1];
+                for (ClassNode trait : traits) { // check super trait for static method
+                    MethodNode method = Traits.findHelper(trait).getDeclaredMethod(name, signature);
+                    if (method != null && method.isStatic()) {
+                        return Collections.singletonList(makeDynamic(call, method.getReturnType()));
+                    }
+                }
             }
         }
-        ClassNode[] newArgs = new ClassNode[argumentTypes.length];
-        System.arraycopy(argumentTypes, 0, newArgs, 0, newArgs.length);
-        ClassNode inferredReturnType = inferTraitMethodReturnType(nextTrait, name, newArgs);
-
-        return Collections.singletonList(makeDynamic(call, inferredReturnType));
-    }
 
-    private ClassNode inferTraitMethodReturnType(ClassNode nextTrait, String methodName, ClassNode[] paramTypes) {
-        ClassNode result = ClassHelper.OBJECT_TYPE;
-        if (nextTrait != null) {
-            List<MethodNode> candidates = typeCheckingVisitor.findMethod(nextTrait, methodName, paramTypes);
-            if (candidates.size() == 1) {
-                result = candidates.get(0).getReturnType();
-            }
-        }
-        return result;
+        return Collections.emptyList();
     }
-
 }
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
index e13142502e..9520f59665 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
@@ -130,7 +130,7 @@ public abstract class TraitComposer {
         ClassNode staticFieldHelperClassNode = helpers.getStaticFieldHelper();
         Map<String, ClassNode> genericsSpec = GenericsUtils.createGenericsSpec(trait, GenericsUtils.createGenericsSpec(cNode));
 
-        for (MethodNode methodNode : helperClassNode.getAllDeclaredMethods()) {
+        for (MethodNode methodNode : helperClassNode.getMethods()) {
             String name = methodNode.getName();
             Parameter[] helperMethodParams = methodNode.getParameters();
             int nParams = helperMethodParams.length;
@@ -180,7 +180,7 @@ public abstract class TraitComposer {
             // implementation of methods
             List<MethodNode> declaredMethods = new LinkedList<>();
             int pos = 0; // keep direct getters at start but in declaration order
-            for (MethodNode declaredMethod : fieldHelperClassNode.getAllDeclaredMethods()) {
+            for (MethodNode declaredMethod : fieldHelperClassNode.getMethods()) {
                 if (declaredMethod.getName().endsWith(Traits.DIRECT_GETTER_SUFFIX)) {
                     declaredMethods.add(pos++, declaredMethod);
                 } else {
@@ -189,7 +189,7 @@ public abstract class TraitComposer {
             }
 
             if (staticFieldHelperClassNode != null) {
-                for (MethodNode declaredMethod : staticFieldHelperClassNode.getAllDeclaredMethods()) {
+                for (MethodNode declaredMethod : staticFieldHelperClassNode.getMethods()) {
                     if (declaredMethod.getName().endsWith(Traits.DIRECT_GETTER_SUFFIX)) {
                         declaredMethods.add(pos++, declaredMethod);
                     } else {
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
index 51efa1e7ca..8ccff4a9f4 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
@@ -99,13 +99,28 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
         ClassNode weavedType = weaved.getOriginType();
         if (exp instanceof BinaryExpression) {
             return transformBinaryExpression((BinaryExpression) exp, weavedType);
+        } else if (exp instanceof MethodCallExpression) {
+            MethodCallExpression mce = (MethodCallExpression) exp;
+            String obj = mce.getObjectExpression().getText();
+            if (mce.isImplicitThis() || "this".equals(obj)) {
+                return transformMethodCallOnThis(mce); // this.m(p) --> this.m($self, p)
+            } else if ("super".equals(obj)) {
+                return transformSuperMethodCall(mce); // super.m(p) --> $self.Ttrait$super$m(p)
+            }
         } else if (exp instanceof StaticMethodCallExpression) {
             StaticMethodCallExpression call = (StaticMethodCallExpression) exp;
             if (call.getOwnerType().equals(traitClass)) {
+                // GROOVY-7191, GROOVY-8272, GROOVY-8854, GROOVY-10312: T.m(p) --> this.m($static$self, p)
+                Expression staticSelf = varX(weaved);
+                if (!ClassHelper.isClassType(weavedType)) {
+                    staticSelf = callX(staticSelf, "getClass");
+                    ((MethodCallExpression) staticSelf).setImplicitThis(false);
+                    staticSelf = castX(ClassHelper.CLASS_Type.getPlainNodeReference(), staticSelf);
+                }
                 MethodCallExpression mce = callX(
-                        varX(weaved),
+                        varX("this"),
                         call.getMethod(),
-                        transform(call.getArguments())
+                        createArgumentList(staticSelf, call.getArguments())
                 );
                 mce.setSafe(false);
                 mce.setSpreadSafe(false);
@@ -113,14 +128,6 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
                 mce.setSourcePosition(exp);
                 return mce;
             }
-        } else if (exp instanceof MethodCallExpression) {
-            MethodCallExpression mce = (MethodCallExpression) exp;
-            String obj = mce.getObjectExpression().getText();
-            if (mce.isImplicitThis() || "this".equals(obj)) {
-                return transformMethodCallOnThis(mce);
-            } else if ("super".equals(obj)) {
-                return transformSuperMethodCall(mce);
-            }
         } else if (exp instanceof FieldExpression) {
             FieldNode fn = ((FieldExpression) exp).getField();
             return transformFieldReference(exp, fn, fn.isStatic());
@@ -311,7 +318,7 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
                         newCall.setImplicitThis(false);
                         newCall.setSafe(false);
                     } else {
-                        ArgumentListExpression newArgs = createArgumentList(methodNode.isStatic() ? asClass(varX("this")) : weaved, arguments);
+                        ArgumentListExpression newArgs = createArgumentList(methodNode.isStatic() ? asClass(thisExpr) : weaved, arguments);
                         newCall = callX(inClosure ? classX(traitHelperClass) : thisExpr, methodName, newArgs);
                         newCall.setImplicitThis(true);
                         newCall.setSafe(call.isSafe());
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7322Bug.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7322Bug.groovy
deleted file mode 100644
index 628b965930..0000000000
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7322Bug.groovy
+++ /dev/null
@@ -1,64 +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 org.codehaus.groovy.classgen.asm.sc.bugs
-
-import groovy.transform.stc.StaticTypeCheckingTestCase
-import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
-
-class Groovy7322Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
-    void testCallStaticTraitMethodFromTraitItself() {
-        assertScript '''
-            trait SomeTrait {
-
-                static someMethod() {
-                    List theNames = getNames()
-                    theNames
-                }
-
-                static List getNames() {
-                    ['Jeff', 'Betsy', 'Jake', 'Zack']
-                }
-            }
-
-            class SomeClass implements SomeTrait {}
-            assert SomeClass.someMethod() == ['Jeff', 'Betsy', 'Jake', 'Zack']
-        '''
-    }
-
-    // GROOVY-7191
-    void testCallStaticMethodFromInstanceMethodInTrait() {
-        assertScript '''
-            trait SomeTrait {
-                static int someStaticMethod(){ 1 }
-
-                int someInstanceMethod() {
-                    someStaticMethod()
-                }
-            }
-            class SomeClass implements SomeTrait {}
-            def o = new SomeClass()
-            assert o.someInstanceMethod() == 1
-        '''
-    }
-
-}
diff --git a/src/test/org/codehaus/groovy/transform/traitx/Groovy7255Bug.groovy b/src/test/org/codehaus/groovy/transform/traitx/Groovy7255Bug.groovy
deleted file mode 100644
index 7984486bf7..0000000000
--- a/src/test/org/codehaus/groovy/transform/traitx/Groovy7255Bug.groovy
+++ /dev/null
@@ -1,40 +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 org.codehaus.groovy.transform.traitx
-
-import groovy.test.GroovyTestCase
-
-class Groovy7255Bug extends GroovyTestCase {
-    void testShouldAllowSettingStaticFieldInTraitUsingCompileStatic() {
-        assertScript '''
-@groovy.transform.CompileStatic
-trait SomeTrait {
-    static List stuff = [1,2,3]
-
-    static void initStuff(List l) {
-        stuff = stuff + l
-    }
-}
-
-class A implements SomeTrait {}
-A.initStuff([4,5,6])
-assert A.stuff == [1,2,3,4,5,6]
-'''
-    }
-}
diff --git a/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy b/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
index 264dc9728a..07f48aff62 100644
--- a/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
@@ -18,6 +18,7 @@
  */
 package org.codehaus.groovy.transform.traitx
 
+import groovy.test.NotYetImplemented
 import groovy.transform.SelfType
 import org.codehaus.groovy.ast.ClassHelper
 import org.codehaus.groovy.ast.expr.ClassExpression
@@ -221,8 +222,9 @@ final class TraitASTTransformationTest {
                 void setLabel3(String val) { this.@name = val }
                 String getName() { name }
             }
+            class Person implements Named {
+            }
 
-            class Person implements Named {}
             def p = new Person()
             assert p.name == null
             p.setLabel('label')
@@ -280,6 +282,7 @@ final class TraitASTTransformationTest {
             })
             class Bob implements Foo {
             }
+
             def b = new Bob()
             assert b.sum(1) == 1
             b.index = 5
@@ -295,11 +298,11 @@ final class TraitASTTransformationTest {
                private String msg = 'foo'
                abstract String bar()
                public String foo() { bar()+msg }
-
             }
-
             @CompileStatic
-            class A implements Foo { String bar() {'bar'}}
+            class A implements Foo {
+                String bar() {'bar'}
+            }
 
             assert new A().foo() == 'barfoo'
         '''
@@ -401,100 +404,6 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test
-    void testClassImplementingTraitWithSameMethod() {
-        assertScript shell, '''
-            trait A {
-                int foo() { 1 }
-            }
-            trait B {
-                int foo() { 2 }
-            }
-            class AB implements A,B {
-            }
-            def x = new AB()
-            assert x.foo() == 2 // default order, B is first
-        '''
-
-        assertScript shell, '''
-            trait A {
-                int foo() { 1 }
-            }
-            trait B {
-                int foo() { 2 }
-            }
-            class AB implements B,A {
-            }
-            def x = new AB()
-            assert x.foo() == 1 // default order, A is first
-        '''
-
-        assertScript shell, '''
-            trait A {
-                int foo() { 1 }
-            }
-            trait B {
-                int foo() { 2 }
-            }
-            class AB implements A,B {
-                int foo() {
-                    A.super.foo() // explicit use of A
-                }
-            }
-            def x = new AB()
-            assert x.foo() == 1
-        '''
-
-        assertScript shell, '''
-            trait A {
-                int foo() { 1 }
-            }
-            trait B {
-                int foo() { 2 }
-            }
-            class AB implements A,B {
-                int foo() {
-                    A.super.foo()  // explicit take of A
-                }
-            }
-            def x = new AB()
-            assert x.foo() == 1
-        '''
-
-        // make sure it is compatible with @CompileStatic
-        assertScript shell, '''
-            trait A {
-                int foo() { 1 }
-            }
-            trait B {
-                int foo() { 2 }
-            }
-            @CompileStatic
-            class AB implements A,B {
-                int foo() {
-                    B.super.foo()
-                }
-            }
-            def x = new AB()
-            assert x.foo() == 2
-        '''
-
-        // GROOVY-10144
-        assertScript shell, '''
-            trait T {
-                def m() { 'T' }
-            }
-            class C implements T {
-                @Override
-                def m() {
-                    'C' + T.super.m()
-                }
-            }
-            String result = new C().m()
-            assert result == 'CT'
-        '''
-    }
-
     @Test
     void testTraitWithGenerics1() {
         for (mode in ['','@TypeChecked','@CompileStatic']) {
@@ -537,7 +446,8 @@ final class TraitASTTransformationTest {
         }
     }
 
-    @Test // GROOVY-9760
+    // GROOVY-9760
+    @Test
     void testTraitWithGenerics3() {
         for (mode in ['','@TypeChecked','@CompileStatic']) {
             assertScript shell, """
@@ -557,7 +467,8 @@ final class TraitASTTransformationTest {
         }
     }
 
-    @Test // GROOVY-11012
+    // GROOVY-11012
+    @Test
     void testTraitWithGenerics4() {
         for (mode in ['','@TypeChecked','@CompileStatic']) {
             assertScript shell, """
@@ -953,7 +864,9 @@ final class TraitASTTransformationTest {
                 String blah() { message }
                 void update(String msg ) { message = msg}
             }
-            class Foo implements TestTrait{}
+            class Foo implements TestTrait {
+            }
+
             def foo = new Foo()
             assert foo.message == 'Hello'
             assert foo.blah() == 'Hello'
@@ -970,7 +883,9 @@ final class TraitASTTransformationTest {
                 void update(String msg ) { message = msg}
             }
             @CompileStatic
-            class Foo implements TestTrait{}
+            class Foo implements TestTrait {
+            }
+
             @CompileStatic
             void test() {
                 def foo = new Foo()
@@ -983,7 +898,162 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9255
+    @Test
+    void testTraitMethodOverloadAndOverride() {
+        assertScript shell, '''
+            trait A {
+                int foo() { 1 }
+            }
+            trait B {
+                int foo() { 2 }
+            }
+            class AB implements A,B {
+            }
+
+            def x = new AB()
+            assert x.foo() == 2 // default order, B is first
+        '''
+
+        assertScript shell, '''
+            trait A {
+                int foo() { 1 }
+            }
+            trait B {
+                int foo() { 2 }
+            }
+            class BA implements B,A {
+            }
+
+            def x = new BA()
+            assert x.foo() == 1 // default order, A is first
+        '''
+
+        assertScript shell, '''
+            trait A {
+                int foo() { 1 }
+            }
+            trait B {
+                int foo() { 2 }
+            }
+            class AB implements A,B {
+                int foo() {
+                    A.super.foo() // explicit delegation to A
+                }
+            }
+
+            def x = new AB()
+            assert x.foo() == 1
+        '''
+
+        assertScript shell, '''
+            trait A {
+                int foo() { 1 }
+            }
+            trait B {
+                int foo() { 2 }
+            }
+            class AB implements A,B {
+                int foo() {
+                    A.super.foo()  // explicit delegation to A
+                }
+            }
+
+            def x = new AB()
+            assert x.foo() == 1
+        '''
+
+        // make sure it is compatible with @CompileStatic
+        assertScript shell, '''
+            trait A {
+                int foo() { 1 }
+            }
+            trait B {
+                int foo() { 2 }
+            }
+            @CompileStatic
+            class AB implements A,B {
+                int foo() {
+                    B.super.foo()
+                }
+            }
+
+            def x = new AB()
+            assert x.foo() == 2
+        '''
+
+        assertScript shell, '''
+            trait A {
+                int foo() { 1 }
+            }
+            trait B extends A {
+                int foo() {
+                    A.super.foo() * 2
+                }
+            }
+            class C implements B {
+            }
+
+            def c = new C()
+            assert c.foo() == 2
+        '''
+
+        assertScript shell, '''
+            @CompileStatic
+            trait A {
+                int foo() { 1 }
+            }
+            @CompileStatic
+            trait B extends A {
+                int foo() {
+                    A.super.foo() * 2
+                }
+            }
+            class C implements B {
+            }
+
+            def c = new C()
+            assert c.foo() == 2
+        '''
+
+        // GROOVY-10144
+        assertScript shell, '''
+            trait T {
+                def m() { 'T' }
+            }
+            class C implements T {
+                @Override
+                def m() {
+                    'C' + T.super.m()
+                }
+            }
+            String result = new C().m()
+            assert result == 'CT'
+        '''
+    }
+
+    // GROOVY-8587
+    @Test @NotYetImplemented
+    void testTraitSuperSuperMethod() {
+        assertScript shell, '''
+            trait A {
+                int foo() { 1 }
+            }
+            trait B extends A {
+            }
+            class C implements B {
+                @Override
+                int foo() {
+                    B.super.foo() * 2
+                }
+            }
+
+            def c = new C()
+            assert c.foo() == 2
+        '''
+    }
+
+    // GROOVY-9255
+    @Test
     void testTraitSuperPropertyGet() {
         assertScript shell, '''
             trait T {
@@ -1034,7 +1104,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9672
+    // GROOVY-9672
+    @Test
     void testTraitSuperPropertyGetStatic() {
         assertScript shell, '''
             trait T {
@@ -1157,7 +1228,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9672
+    // GROOVY-9672
+    @Test
     void testTraitSuperPropertySetStatic() {
         assertScript shell, '''
             trait T {
@@ -1214,7 +1286,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9673
+    // GROOVY-9673
+    @Test
     void testTraitSuperPropertySetWithOverloads() {
         assertScript shell, '''
             trait T {
@@ -1251,7 +1324,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9672
+    // GROOVY-9672
+    @Test
     void testTraitSuperCallStatic() {
         assertScript shell, '''
             trait A {
@@ -1269,40 +1343,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
+    // GROOVY-9256
     @Test
-    void testTraitSuperCallWhenExtendingAnotherTrait() {
-        assertScript shell, '''
-            trait Foo {
-                int foo() { 1 }
-            }
-            trait Bar extends Foo {
-                int foo() {
-                    2*Foo.super.foo()
-                }
-            }
-            class Baz implements Bar {}
-            def b = new Baz()
-            assert b.foo() == 2
-        '''
-
-        assertScript shell, '''
-            @CompileStatic
-            trait Foo {
-                int foo() { 1 }
-            }
-            @CompileStatic
-            trait Bar extends Foo {
-                int foo() {
-                    2*Foo.super.foo()
-                }
-            }
-            class Baz implements Bar {}
-            def b = new Baz()
-            assert b.foo() == 2
-        '''
-    }
-
-    @Test // GROOVY-9256
     void testTraitSuperCallWithinClosure() {
         assertScript shell, '''
             trait T {
@@ -1503,7 +1545,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8243
+    // GROOVY-8243
+    @Test
     void testSAMCoercion5() {
         assertScript shell, '''
             trait T {
@@ -1521,7 +1564,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8244
+    // GROOVY-8244
+    @Test
     void testSAMCoercion6() {
         assertScript shell, '''
             trait T {
@@ -1582,117 +1626,109 @@ final class TraitASTTransformationTest {
             trait Trait1 { private int v = 111; int getValueFromTrait1() { v } }
             trait Trait2 { private int v = 222; int getValueFromTrait2() { v } }
             class Impl implements Trait1,Trait2 {}
+
             def t = new Impl()
             assert t.valueFromTrait1 == 111
             assert t.valueFromTrait2 == 222
         '''
     }
 
+    // GROOVY-7213, GROOVY-8859
     @Test
     void testPrivateMethodInTrait() {
-        assertScript shell, '''
-            trait DoingSecretThings {
-                private String secret() { 'secret' }
-                String foo() { secret() }
-            }
-            class Foo implements DoingSecretThings {}
-            def foo = new Foo()
-            assert foo.foo() == 'secret'
-        '''
-    }
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait T {
+                    private String secret() { 'secret' }
+                    String foo() { secret() }
+                }
+                $mode
+                class C implements T {
+                }
 
-    @Test
-    void testPrivateMethodInTraitAccessingPrivateField() {
-        assertScript shell, '''
-            trait DoingSecretThings {
-                private int x = 0
-                private int secret() { x+=1; x }
-                int foo() { secret() }
-            }
-            class Foo implements DoingSecretThings {}
-            def foo = new Foo()
-            assert foo.foo() == 1
-        '''
-    }
+                assert new C().foo() == 'secret'
+            """
 
-    @Test
-    void testPrivateMethodInTraitWithCompileStatic() {
-        assertScript shell, '''
-            @CompileStatic
-            trait DoingSecretThings {
-                private String secret() { 'secret' }
-                String foo() { secret() }
-            }
-            class Foo implements DoingSecretThings {}
-            def foo = new Foo()
-            assert foo.foo() == 'secret'
-        '''
-    }
+            shouldFail shell, """
+                $mode
+                trait T {
+                    public String bar() {
+                        'public'
+                    }
+                    private String baz() {
+                        'private'
+                    }
+                }
+                $mode
+                class C implements T {
+                    def foo() {
+                        bar() + baz()
+                    }
+                }
 
-    @Test
-    void testPrivateMethodInTraitAccessingPrivateFieldCompileStatic() {
-        assertScript shell, '''
-            @CompileStatic
-            trait DoingSecretThings {
-                private int x = 0
-                private int secret() { x+=1; x }
-                int foo() { secret() }
-            }
-            class Foo implements DoingSecretThings {}
-            def foo = new Foo()
-            assert foo.foo() == 1
-            assert foo.foo() == 2
-        '''
+                assert new C().foo() == 'publicprivate'
+            """
+        }
     }
 
     @Test
-    void testNoShadowingPrivateMethodInTraitAccessingPrivateFieldCompileStatic() {
-        assertScript shell, '''
-            @CompileStatic
-            trait DoingSecretThings {
-                private int x = 0
-                private int secret() { x+=1; x }
-                int foo() { secret() }
-            }
-            class Foo implements DoingSecretThings {
-                int secret() { 666 }
-            }
-            def foo = new Foo()
-            assert foo.foo() == 1
-            assert foo.foo() == 2
-        '''
+    void testPrivateMethodInTraitAccessingPrivateField() {
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait T {
+                    private int x = 0
+                    private int secret() { x += 1 }
+                    int foo() { secret() }
+                }
+                $mode
+                class C implements T {
+                }
+
+                def c = new C()
+                assert c.foo() == 1
+                assert c.foo() == 2
+            """
+        }
     }
 
     @Test
-    void testNoShadowingPrivateMethodInTraitAccessingPrivateField() {
-        assertScript shell, '''
-            trait DoingSecretThings {
-                private int x = 0
-                private int secret() { x+=1; x }
-                int foo() { secret() }
-            }
-            class Foo implements DoingSecretThings {
-                int secret() { 666 }
-            }
-            def foo = new Foo()
-            assert foo.foo() == 1
-            assert foo.foo() == 2
-        '''
+    void testPrivateMethodInTraitAccessingPrivateFieldNoShadowing() {
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait T {
+                    private int x = 0
+                    private int secret() { x += 1 }
+                    int foo() { secret() }
+                }
+                $mode
+                class C implements T {
+                    int secret() { 666 }
+                }
+
+                def c = new C()
+                assert c.foo() == 1
+                assert c.foo() == 2
+            """
+        }
     }
 
     @Test
     void testMixPrivatePublicMethodsOfSameName() {
         def err = shouldFail shell, '''
-            trait DoingSecretThings {
+            trait T {
                 private String secret(String s) { s.toUpperCase() }
                 String secret() { 'public' }
                 String foo() { secret('secret') }
             }
-            class Foo implements DoingSecretThings {}
-            def foo = new Foo()
-            assert foo.foo() == 'SECRET'
-        '''
+            class C implements T {
+            }
 
+            def c = new C()
+            assert c.foo() == 'SECRET'
+        '''
         assert err =~ 'Mixing private and public/protected methods of the same name causes multimethods to be disabled'
     }
 
@@ -1703,13 +1739,14 @@ final class TraitASTTransformationTest {
                 void foo() { println 'A' }
             }
             trait B extends A {
-               void bar() {  println 'B'  }
+                void bar() { println 'B' }
             }
-
             interface C extends B {
                void baz()
             }
-            abstract class D implements C {}
+            abstract class D implements C {
+            }
+
             def d = { println 'BAZ' } as D
             d.foo()
             d.bar()
@@ -1721,7 +1758,7 @@ final class TraitASTTransformationTest {
     void testTraitWithDelegate() {
         assertScript shell, '''
             trait ListTrait<T> {
-                private @Delegate ArrayList<T> list = new ArrayList<T>()
+                private @Delegate List<T> list = new ArrayList<T>()
             }
             class Person implements ListTrait<String> {
                 void foo() {
@@ -1734,7 +1771,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-7288
+    // GROOVY-7288
+    @Test
     void testClassWithTraitDelegate() {
         assertScript shell, '''
             trait T {
@@ -1754,7 +1792,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9739
+    // GROOVY-9739
+    @Test
     void testTraitExtendsTraitWithDelegate() {
         assertScript shell, '''
             class Main implements ClientSupport {
@@ -1785,7 +1824,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9901
+    // GROOVY-9901
+    @Test
     void testTraitWithMemozied() {
         assertScript shell, '''
             trait Foo {
@@ -1828,7 +1868,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-10553
+    // GROOVY-10553
+    @Test
     void testAnnotationShouldBeCarriedOver2() {
         assertScript shell, '''
             import java.lang.annotation.*
@@ -1870,88 +1911,197 @@ final class TraitASTTransformationTest {
 
     @Test
     void testTraitStaticMethod() {
-        assertScript shell, '''
-            trait StaticProvider {
-                static String foo() { 'static method' }
-            }
-            class Foo implements StaticProvider {}
-            assert Foo.foo() == 'static method'
-        '''
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait T {
+                    static String foo() { 'static method' }
+                }
+                $mode
+                class C implements T {
+                }
+                $mode
+                class D extends C {
+                }
 
-        assertScript shell, '''
-            trait StaticProvider {
-                static String foo() { bar() }
-                static String bar() { 'static method' }
-            }
-            class Foo implements StaticProvider {}
-            assert Foo.foo() == 'static method'
-        '''
+                assert C.foo() == 'static method'
+                assert D.foo() == 'static method'
+                assert new C().foo() == 'static method'
+                assert new D().foo() == 'static method'
+            """
+
+            // GROOVY-7322
+            assertScript shell, """
+                $mode
+                trait T {
+                    static String bar() { 'static method' }
+                    static String foo() { bar() }
+                }
+                $mode
+                class C implements T {
+                }
+                $mode
+                class D extends C {
+                }
+
+                assert C.foo() == 'static method'
+                assert D.foo() == 'static method'
+                assert new C().foo() == 'static method'
+                assert new D().foo() == 'static method'
+            """
+
+            // GROOVY-7191
+            assertScript shell, """
+                $mode
+                trait T {
+                    static Number bar() { 1 }
+                           Number foo() { bar() }
+                }
+                $mode
+                class C implements T {
+                }
+                $mode
+                class D extends C {
+                }
+
+                assert new C().foo() == 1
+                assert new D().foo() == 1
+            """
+
+            // GROOVY-8854
+            assertScript shell, """
+                $mode
+                trait T {
+                    boolean passes
+                    void audit() {
+                        if (checkCondition()) {
+                            passes = true
+                        }
+                    }
+                    private static boolean checkCondition() {
+                        true
+                    }
+                }
+                $mode
+                class C implements T {
+                    String name
+                }
+                $mode
+                class D extends C {
+                }
+
+                def c = new C(name:'name')
+                c.audit(); assert c.passes
+
+                def d = new D(name:'name')
+                d.audit(); assert d.passes
+            """
+        }
     }
 
     @Test
     void testTraitStaticField() {
-        assertScript shell, '''
-            trait StaticFieldProvider {
-                public static int VAL = 123
-            }
-            class Foo implements StaticFieldProvider {}
-            assert Foo.StaticFieldProvider__VAL == 123
-        '''
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait T {
+                    public static int VAL = 123
+                }
+                $mode
+                class C implements T {
+                }
 
-        assertScript shell, '''
-            trait StaticFieldProvider {
-                public static int VAL = 123
-                public static void update(int x) { VAL = x }
-            }
-            class Foo implements StaticFieldProvider {}
-            assert Foo.StaticFieldProvider__VAL == 123
-            Foo.update(456)
-            assert Foo.StaticFieldProvider__VAL == 456
-        '''
+                assert C.T__VAL == 123
+            """
+
+            assertScript shell, """
+                $mode
+                trait T {
+                    public static int VAL = 123
+                    public static void update(int x) { VAL = x }
+                }
+                $mode
+                class C implements T {
+                }
+
+                assert C.T__VAL == 123
+                C.update(456)
+                assert C.T__VAL == 456
+            """
+        }
     }
 
     @Test
     void testTraitStaticProperty() {
-        assertScript shell, '''
-            trait StaticPropertyProvider {
-                static int VAL = 123
-                public static void update(int x) { VAL = x }
-            }
-            class Foo implements StaticPropertyProvider {
-            }
-            assert Foo.VAL == 123
-            Foo.update(456)
-            assert Foo.VAL == 456
-        '''
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait T {
+                    static int VAL = 123
+                    public static void update(int x) { VAL = x }
+                }
+                $mode
+                class C implements T {
+                }
 
-        assertScript shell, '''
-            trait T {
-                static p = 1
-            }
-            class C implements T {
-                static m() {
-                    setP(2)
-                    setP(getP() + 1)
-                    return getP()
+                assert C.VAL == 123
+                C.update(456)
+                assert C.VAL == 456
+            """
+
+            // GROOVY-7255
+            assertScript shell, """
+                $mode
+                trait T {
+                    static List stuff = [1,2,3]
+
+                    static initStuff(List list) {
+                        stuff = stuff + list
+                    }
+                }
+                $mode
+                class C implements T {
                 }
-            }
-            assert C.m() == 3
-        '''
 
-        // GROOVY-9678
-        assertScript shell, '''
-            trait T {
-                static p = 1
-            }
-            class C implements T {
-                static m() {
-                    p = 2
-                    p += 1
-                    return p
+                C.initStuff([4,5,6])
+                assert C.stuff == [1,2,3,4,5,6]
+            """
+
+            assertScript shell, """
+                $mode
+                trait T {
+                    static int p = 1
                 }
-            }
-            assert C.m() == 3
-        '''
+                $mode
+                class C implements T {
+                    static int m() {
+                        setP(2)
+                        setP(getP() + 1)
+                        return getP()
+                    }
+                }
+
+                assert C.m() == 3
+            """
+
+            // GROOVY-9678
+            assertScript shell, """
+                $mode
+                trait T {
+                    static int p = 1
+                }
+                $mode
+                class C implements T {
+                    static int m() {
+                        p = 2
+                        p += 1
+                        return p
+                    }
+                }
+
+                assert C.m() == 3
+            """
+        }
     }
 
     @Test
@@ -2052,9 +2202,9 @@ final class TraitASTTransformationTest {
         '''
     }
 
+    // GROOVY-6672
     @Test
     void testTraitShouldNotBeAllowedToExtendInterface() {
-        // GROOVY-6672
         def err = shouldFail shell, '''
             trait Foo extends Serializable {}
             Foo x = null
@@ -2207,7 +2357,8 @@ final class TraitASTTransformationTest {
         assert err =~ 'Prefix expressions on trait fields/properties are not supported in traits'
     }
 
-    @Test // GROOVY-6691
+    // GROOVY-6691
+    @Test
     void testTraitImplementingGenericSuperTrait() {
         assertScript shell, '''
             class App {}
@@ -2609,7 +2760,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-6708
+    // GROOVY-6708
+    @Test
     void testCovariantReturnTypeWithGenericsInheritance() {
         assertScript shell, '''
             trait Top<X> {
@@ -2695,7 +2847,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-7058
+    // GROOVY-7058
+    @Test
     void testShouldNotThrowNPEBecauseOfIncompleteGenericsTypeInformation() {
         assertScript shell, '''
             class Project { Task task(String name, Map args) {} }
@@ -2714,7 +2867,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-7123
+    // GROOVY-7123
+    @Test
     void testHelperSetterShouldNotReturnVoid() {
         assertScript shell, '''
             trait A {
@@ -2770,7 +2924,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-10767
+    // GROOVY-10767
+    @Test
     void testSimpleSelfTypeInSubTrait2() {
         assertScript shell, '''
             trait A {
@@ -2962,7 +3117,8 @@ final class TraitASTTransformationTest {
         }
     }
 
-    @Test // GROOVY-10521
+    // GROOVY-10521
+    @Test
     void testVariadicMethodOfPrecompiledTrait() {
         assertScript shell, """import org.codehaus.groovy.ast.*
             class CT implements ${T10521.name} {
@@ -2978,7 +3134,7 @@ final class TraitASTTransformationTest {
         """
 
         assertScript shell, """
-            @Grab('org.spockframework:spock-core:2.2-M3-groovy-4.0')
+            @Grab('org.spockframework:spock-core:2.4-M1-groovy-4.0')
             @GrabExclude('org.apache.groovy:*')
             import spock.lang.Specification
 
@@ -2995,7 +3151,8 @@ final class TraitASTTransformationTest {
         """
     }
 
-    @Test // GROOVY-7287
+    // GROOVY-7287
+    @Test
     void testTraitWithMethodLevelGenericsShadowing1() {
         assertScript shell, '''
             trait Configurable<ConfigObject> {
@@ -3042,7 +3199,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-7287
+    // GROOVY-7287
+    @Test
     void testTraitWithMethodLevelGenericsShadowing2() {
         assertScript shell, '''
             trait SomeTrait {
@@ -3066,7 +3224,8 @@ final class TraitASTTransformationTest {
         }
     }
 
-    @Test // GROOVY-7297
+    // GROOVY-7297
+    @Test
     void testMethodLevelGenericsFromPrecompiledClass() {
         assertScript shell, """
             class C implements ${T7297.name} {
@@ -3077,7 +3236,8 @@ final class TraitASTTransformationTest {
         """
     }
 
-    @Test // GROOVY-9763
+    // GROOVY-9763
+    @Test
     void testTraitWithStaticMethodGenericsSC() {
         assertScript shell, '''
             trait T {
@@ -3095,7 +3255,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8281
+    // GROOVY-8281
+    @Test
     void testFinalFieldsDependency() {
         assertScript shell, '''
             trait MyTrait {
@@ -3110,7 +3271,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8282
+    // GROOVY-8282
+    @Test
     void testBareNamedArgumentPrivateMethodCall() {
         assertScript shell, '''
             trait BugReproduction {
@@ -3128,7 +3290,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8730
+    // GROOVY-8730
+    @Test
     void testAbstractMethodsNotNeededInHelperClass() {
         assertScript shell, '''
             import static groovy.test.GroovyAssert.shouldFail
@@ -3147,32 +3310,37 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8731
+    // GROOVY-8731
+    @Test
     void testStaticMethodsIgnoredWhenExistingInstanceMethodsFound() {
-        assertScript shell, '''
-            trait StaticFooBarBaz {
-                static int foo() { 100 }
-                static int baz() { 200 }
-                static int bar() { 300 }
-            }
-
-            trait InstanceBar {
-                int bar() { -10 }
-            }
-
-            class FooBarBaz implements StaticFooBarBaz, InstanceBar {
-                int baz() { -20 }
-            }
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait StaticFooBarBaz {
+                    static int foo() { 100 }
+                    static int baz() { 200 }
+                    static int bar() { 300 }
+                }
+                $mode
+                trait InstanceBar {
+                    int bar() { -10 }
+                }
+                $mode
+                class FooBarBaz implements StaticFooBarBaz, InstanceBar {
+                    int baz() { -20 }
+                }
 
-            assert FooBarBaz.foo() == 100
-            new FooBarBaz().with {
-                assert bar() == -10
-                assert baz() == -20
-            }
-        '''
+                assert FooBarBaz.foo() == 100
+                new FooBarBaz().with {
+                    assert bar() == -10
+                    assert baz() == -20
+                }
+            """
+        }
     }
 
-    @Test // GROOVY-6716
+    // GROOVY-6716
+    @Test
     void testAnonymousInnerClassStyleTraitUsage() {
         assertScript shell, '''
             interface Foo { def foo() }
@@ -3189,7 +3357,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8722
+    // GROOVY-8722
+    @Test
     void testFinalModifierSupport() {
         assertScript shell, '''
             import static java.lang.reflect.Modifier.isFinal
@@ -3244,7 +3413,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8880
+    // GROOVY-8880
+    @Test
     void testTraitWithInitBlock() {
         assertScript shell, '''
             trait MyTrait {
@@ -3264,7 +3434,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8880
+    // GROOVY-8880
+    @Test
     void testTraitWithStaticInitBlock() {
         assertScript shell, '''
             trait MyTrait {
@@ -3282,7 +3453,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8892
+    // GROOVY-8892
+    @Test
     void testTraitWithStaticInitBlockWithAndWithoutProps() {
         assertScript shell, '''
             class Counter {
@@ -3306,108 +3478,127 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8954
-    void testTraitWithPropertyAlsoFromInterfaceSC() {
-        assertScript shell, '''
-            interface DomainProp {
-                boolean isNullable()
-            }
-
-            abstract class OrderedProp implements DomainProp { }
-
-            trait Nullable {
-                boolean nullable = true
-            }
-
-            @CompileStatic
-            abstract class CustomProp extends OrderedProp implements Nullable { }
+    // GROOVY-8954
+    @Test
+    void testTraitWithPropertyAlsoFromInterface() {
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                interface DomainProp {
+                    boolean isNullable()
+                }
+                $mode
+                abstract class OrderedProp implements DomainProp {
+                }
+                $mode
+                trait Nullable {
+                    boolean nullable = true
+                }
+                $mode
+                abstract class CustomProp extends OrderedProp implements Nullable {
+                }
 
-            assert new CustomProp() {}
-        '''
+                assert new CustomProp() {}
+            """
+        }
     }
 
-    @Test // GROOVY-8272
+    // GROOVY-8272
+    @Test @NotYetImplemented
     void testTraitAccessToInheritedStaticMethods() {
-        assertScript shell, '''
-            @CompileStatic
-            trait Foo {
-                static String go() {
-                    'Go!'
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait Foo {
+                    static String go() {
+                        'Go!'
+                    }
                 }
-            }
-
-            @CompileStatic
-            trait Bar extends Foo {
-                String doIt() {
-                    go().toUpperCase()
+                $mode
+                trait Bar extends Foo {
+                    String test() {
+                        go().toUpperCase()
+                    }
+                }
+                $mode
+                class Main implements Bar {
                 }
-            }
-
-            class Main implements Bar {}
 
-            assert new Main().doIt() == 'GO!'
-        '''
+                assert new Main().test() == 'GO!'
+            """
+        }
     }
 
-    @Test // GROOVY-10312
+    // GROOVY-10312
+    @Test @NotYetImplemented
     void testTraitAccessToInheritedStaticMethods2() {
-        assertScript shell, '''
-            trait Foo {
-                static String staticMethod(String string) {
-                    return string
-                }
-            }
-            trait Bar extends Foo {
-                static String staticMethodWithDefaultArgument(String string = 'works') {
-                    staticMethod(string) // MissingMethodException
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                trait Foo {
+                    static String staticMethod(String string) {
+                        return string
+                    }
                 }
-            }
-
-            class Main implements Bar {
-                static test1() {
-                    String result = staticMethodWithDefaultArgument()
-                    assert result == 'works'
+                $mode
+                trait Bar extends Foo {
+                    static String staticMethodWithDefaultArgument(String string = 'works') {
+                        staticMethod(string) // MissingMethodException
+                    }
                 }
-                void test2() {
-                    String result = staticMethodWithDefaultArgument()
-                    assert result == 'works'
+                $mode
+                class Main implements Bar {
+                    static test1() {
+                        String result = staticMethodWithDefaultArgument()
+                        assert result == 'works'
+                    }
+                    void test2() {
+                        String result = staticMethodWithDefaultArgument()
+                        assert result == 'works'
+                    }
                 }
-            }
 
-            Main.test1()
-            new Main().test2()
-        '''
+                Main.test1()
+                new Main().test2()
+            """
+        }
     }
 
-    @Test // GROOVY-10312
+    // GROOVY-10312
+    @Test
     void testTraitAccessToInheritedStaticMethods3() {
-        assertScript shell, '''
-            interface Foo {
-                public static final String BANG = '!'
-            }
-            trait Bar implements Foo {
-                static String staticMethodWithDefaultArgument(String string = 'works') {
-                    string + BANG
+        for (mode in ['','@TypeChecked','@CompileStatic']) {
+            assertScript shell, """
+                $mode
+                interface Foo {
+                    public static final String BANG = '!'
                 }
-            }
-
-            class Main implements Bar {
-                static test1() {
-                    String result = staticMethodWithDefaultArgument()
-                    assert result == 'works!'
+                $mode
+                trait Bar implements Foo {
+                    static String staticMethodWithDefaultArgument(String string = 'works') {
+                        string + BANG
+                    }
                 }
-                void test2() {
-                    String result = staticMethodWithDefaultArgument()
-                    assert result == 'works!'
+                $mode
+                class Main implements Bar {
+                    static test1() {
+                        String result = staticMethodWithDefaultArgument()
+                        assert result == 'works!'
+                    }
+                    void test2() {
+                        String result = staticMethodWithDefaultArgument()
+                        assert result == 'works!'
+                    }
                 }
-            }
 
-            Main.test1()
-            new Main().test2()
-        '''
+                Main.test1()
+                new Main().test2()
+            """
+        }
     }
 
-    @Test // GROOVY-9386
+    // GROOVY-9386
+    @Test
     void testTraitPropertyInitializedByTap() {
         assertScript shell, '''
             class P {
@@ -3426,7 +3617,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9386
+    // GROOVY-9386
+    @Test
     void testTraitPropertyInitializedByWith() {
         assertScript shell, '''
             class P {
@@ -3445,7 +3637,8 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-8000
+    // GROOVY-8000
+    @Test
     void testTraitMultiLevelGenerics() {
         assertScript shell, '''
             trait TopTrait<X> { X getSomeThing() {}
@@ -3474,17 +3667,20 @@ final class TraitASTTransformationTest {
         '''
     }
 
-    @Test // GROOVY-9660
+    // GROOVY-9660
+    @Test
     void testAsGenericsParam() {
         assertScript shell, '''
             trait Data {}
             class TestData implements Data {}
             class AbstractData<D extends Data>{ D data }
+
             new AbstractData<TestData>()
         '''
     }
 
     // GROOVY-10598
+    @Test
     void testAssignOperators() {
         assertScript shell, '''
             trait T {
@@ -3498,6 +3694,7 @@ final class TraitASTTransformationTest {
                     def var = null
                 }
             }
+
             new C().test()
         '''
     }
diff --git a/src/test/org/codehaus/groovy/transform/traitx/TraitWithClosureOrLambda.groovy b/src/test/org/codehaus/groovy/transform/traitx/TraitWithClosureOrLambda.groovy
index 7bc42106cf..50a98f7450 100644
--- a/src/test/org/codehaus/groovy/transform/traitx/TraitWithClosureOrLambda.groovy
+++ b/src/test/org/codehaus/groovy/transform/traitx/TraitWithClosureOrLambda.groovy
@@ -384,4 +384,30 @@ final class TraitWithClosureOrLambda {
             assert new C().f(8) == 18
         '''
     }
+
+    // GROOVY-11267
+    @Test
+    void testInvokeTraitStaticMethodFromTraitClosure() {
+        assertScript shell, '''
+            trait T {
+                @groovy.transform.CompileDynamic
+                static one() {
+                    def me = this
+                    two('good') + ' ' +
+                    'bad '.with { me.two(it) } +
+                    'ugly'.with {    two(it) }
+                }
+                static two(String s) {
+                    three(s)
+                }
+                static three(String s) {
+                    return s
+                }
+            }
+            class C implements T {
+            }
+
+            assert C.one() == 'good bad ugly'
+        '''
+    }
 }