This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 9642e8584e GROOVY-11641: index trait field under original name (#2206)
9642e8584e is described below
commit 9642e8584ebe8e1904f6a0b8381aa2d5acc36379
Author: Eric Milles <[email protected]>
AuthorDate: Wed Apr 30 16:24:13 2025 -0500
GROOVY-11641: index trait field under original name (#2206)
* refactor compile mode inputs
* GROOVY-11641: index trait field under original name
---
src/main/java/groovy/lang/MetaClassImpl.java | 17 +-
.../transform/trait/TraitReceiverTransformer.java | 2 +
.../codehaus/groovy/transform/trait/Traits.java | 1 -
.../org/codehaus/groovy/vmplugin/v8/Selector.java | 4 +-
.../traitx/TraitASTTransformationTest.groovy | 1019 ++++++++++----------
5 files changed, 530 insertions(+), 513 deletions(-)
diff --git a/src/main/java/groovy/lang/MetaClassImpl.java
b/src/main/java/groovy/lang/MetaClassImpl.java
index 168c781216..a6e4264fd1 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -110,6 +110,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.BiConsumer;
+import java.util.regex.Pattern;
import static groovy.lang.Tuple.tuple;
import static java.lang.Character.isUpperCase;
@@ -144,6 +145,11 @@ public class MetaClassImpl implements MetaClass,
MutableMetaClass {
private static final MetaMethod AMBIGUOUS_LISTENER_METHOD = new
DummyMetaMethod();
private static final Comparator<CachedClass> CACHED_CLASS_NAME_COMPARATOR
= Comparator.comparing(CachedClass::getName);
private static final boolean PERMISSIVE_PROPERTY_ACCESS =
SystemUtil.getBooleanSafe("groovy.permissive.property.access");
+ private static final Pattern TRAIT_FIELD;
+ static {
+ final var identifier =
"[\\p{javaJavaIdentifierStart}&&[^_$]][\\p{javaJavaIdentifierPart}&&[^_$]]*";
// _ and $ are special
+ TRAIT_FIELD = Pattern.compile("(?:" + identifier + "_)*" + identifier
+ "(?:\\$" + identifier + ")*__(" + identifier + ")");
+ }
private static final VMPlugin VM_PLUGIN = VMPluginFactory.getPlugin();
protected final Class theClass;
@@ -2358,8 +2364,15 @@ public class MetaClassImpl implements MetaClass,
MutableMetaClass {
} else {
prop = null; // ignore all other types
}
-
- if (prop != null) staticPropertyIndex.put(name, prop);
+ if (prop != null) {
+ staticPropertyIndex.put(name, prop);
+ if (!name.startsWith("$") && name.contains("__")) {
+ var matcher = TRAIT_FIELD.matcher(name);
+ if (matcher.matches()) { // GROOVY-11641
+ staticPropertyIndex.putIfAbsent(matcher.group(1),
prop);
+ }
+ }
+ }
};
classPropertyIndex.computeIfAbsent(theCachedClass, x -> new
LinkedHashMap<>()).forEach(indexStaticProperty);
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 9d62cb37c0..9baf3bf1b8 100644
---
a/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
+++
b/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
@@ -55,6 +55,7 @@ import static
org.codehaus.groovy.ast.tools.GeneralUtils.isInstanceOfX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.ternaryX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
+import static
org.codehaus.groovy.transform.stc.StaticTypesMarker.DYNAMIC_RESOLUTION;
/**
* This expression transformer is used internally by the {@link
org.codehaus.groovy.transform.trait.TraitASTTransformation
@@ -123,6 +124,7 @@ class TraitReceiverTransformer extends
ClassCodeExpressionTransformer {
}
} else if (accessedVariable instanceof DynamicVariable &&
!inClosure) { // GROOVY-9386
PropertyExpression propertyExpression = propX(varX(weaved),
vexp.getName());
+ propertyExpression.putNodeMetaData(DYNAMIC_RESOLUTION,
Boolean.TRUE);
propertyExpression.getProperty().setSourcePosition(exp);
return propertyExpression;
}
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
b/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
index 31ca6a88e2..ce078f3789 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
@@ -244,7 +244,6 @@ public abstract class Traits {
return null;
}
-
/**
* Converts a class implementing some trait into a target class. If the
trait is a dynamic proxy and
* that the target class is assignable to the target object of the proxy,
then the target object is
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
b/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
index be586fdff0..8d7ea2c196 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
@@ -285,8 +285,8 @@ public abstract class Selector {
private static class PropertySelector extends MethodSelector {
private boolean insertName;
- public PropertySelector(CacheableCallSite callSite, Class<?> sender,
String methodName, CallType callType, boolean safeNavigation, boolean thisCall,
boolean spreadCall, Object[] arguments) {
- super(callSite, sender, methodName, callType, safeNavigation,
thisCall, spreadCall, arguments);
+ public PropertySelector(CacheableCallSite callSite, Class<?> sender,
String propertyName, CallType callType, boolean safeNavigation, boolean
thisCall, boolean spreadCall, Object[] arguments) {
+ super(callSite, sender, propertyName, callType, safeNavigation,
thisCall, spreadCall, arguments);
}
/**
diff --git
a/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
b/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
index 86514f6623..d90290e21e 100644
---
a/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
+++
b/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
@@ -18,18 +18,26 @@
*/
package org.codehaus.groovy.transform.traitx
+import groovy.transform.AnnotationCollector
import groovy.transform.SelfType
import org.codehaus.groovy.ast.ClassHelper
import org.codehaus.groovy.ast.expr.ClassExpression
import org.codehaus.groovy.ast.expr.ListExpression
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
+import org.junit.jupiter.params.ParameterizedTest
+import org.junit.jupiter.params.provider.ValueSource
import static groovy.test.GroovyAssert.assertScript
import static groovy.test.GroovyAssert.shouldFail
final class TraitASTTransformationTest {
+ @ParameterizedTest
+ @ValueSource(strings=['@CompileDynamic','@TypeChecked','@CompileStatic'])
+ @AnnotationCollector
+ @interface CompileModesTest { }
+
private final GroovyShell shell = GroovyShell.withConfig {
imports {
star 'groovy.transform'
@@ -477,159 +485,145 @@ final class TraitASTTransformationTest {
'''
}
- @Test
- void testTraitWithGenerics1() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait Provider<T> {
- T get() { null }
- }
- $mode
- class StringProvider implements Provider<String> {
- }
- $mode
- void test() {
- def c = new StringProvider()
- assert c.get() == null
- }
- test()
- """
- }
+ @CompileModesTest
+ void testTraitWithGenerics1(String mode) {
+ assertScript shell, """
+ $mode
+ trait Provider<T> {
+ T get() { null }
+ }
+ $mode
+ class StringProvider implements Provider<String> {
+ }
+ $mode
+ void test() {
+ def c = new StringProvider()
+ assert c.get() == null
+ }
+ test()
+ """
}
- @Test
- void testTraitWithGenerics2() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait Provider<T> {
- T get(T t) { t }
- }
- $mode
- class StringProvider implements Provider<String> {
- }
- $mode
- void test() {
- def p = new StringProvider()
- assert p.get('foo') == 'foo'
- }
- test()
- """
- }
+ @CompileModesTest
+ void testTraitWithGenerics2(String mode) {
+ assertScript shell, """
+ $mode
+ trait Provider<T> {
+ T get(T t) { t }
+ }
+ $mode
+ class StringProvider implements Provider<String> {
+ }
+ $mode
+ void test() {
+ def p = new StringProvider()
+ assert p.get('foo') == 'foo'
+ }
+ test()
+ """
}
// GROOVY-9760
- @Test
- void testTraitWithGenerics3() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait Provider<T> {
- T get(T t) { t }
- }
- $mode
- class UnspecifiedProvider implements Provider {
- }
- $mode
- void test() {
- assert new UnspecifiedProvider().get('foo') == 'foo'
- }
- test()
- """
- }
+ @CompileModesTest
+ void testTraitWithGenerics3(String mode) {
+ assertScript shell, """
+ $mode
+ trait Provider<T> {
+ T get(T t) { t }
+ }
+ $mode
+ class UnspecifiedProvider implements Provider {
+ }
+ $mode
+ void test() {
+ assert new UnspecifiedProvider().get('foo') == 'foo'
+ }
+ test()
+ """
}
// GROOVY-11012
- @Test
- void testTraitWithGenerics4() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait Provider<T> {
- T get(T t) { t }
- }
- $mode
- class Supplier<U> implements Provider<U> {
- }
- $mode
- void test() {
- def s = new Supplier<Number>()
- Number n = s.get(42)
- assert n == 42
- }
- test()
- """
- }
+ @CompileModesTest
+ void testTraitWithGenerics4(String mode) {
+ assertScript shell, """
+ $mode
+ trait Provider<T> {
+ T get(T t) { t }
+ }
+ $mode
+ class Supplier<U> implements Provider<U> {
+ }
+ $mode
+ void test() {
+ def s = new Supplier<Number>()
+ Number n = s.get(42)
+ assert n == 42
+ }
+ test()
+ """
}
- @Test
- void testTraitWithGenericProperty1() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait PropertyProvider<T> {
- T foo
- }
- $mode
- class StringProperty implements PropertyProvider<String> {
- }
- $mode
- void test() {
- def c = new StringProperty()
- c.foo = 'foo'
- assert c.foo == 'foo'
- }
- test()
- """
- }
+ @CompileModesTest
+ void testTraitWithGenericProperty1(String mode) {
+ assertScript shell, """
+ $mode
+ trait PropertyProvider<T> {
+ T foo
+ }
+ $mode
+ class StringProperty implements PropertyProvider<String> {
+ }
+ $mode
+ void test() {
+ def c = new StringProperty()
+ c.foo = 'foo'
+ assert c.foo == 'foo'
+ }
+ test()
+ """
}
- @Test
- void testTraitWithGenericProperty2() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait PropertyProvider<T> {
- List<T> foo
- }
- $mode
- class StringProperty implements PropertyProvider<String> {
- }
- $mode
- void test() {
- def c = new StringProperty()
- c.foo = ['foo']
- assert c.foo == ['foo']
- }
- test()
- """
- }
+ @CompileModesTest
+ void testTraitWithGenericProperty2(String mode) {
+ assertScript shell, """
+ $mode
+ trait PropertyProvider<T> {
+ List<T> foo
+ }
+ $mode
+ class StringProperty implements PropertyProvider<String> {
+ }
+ $mode
+ void test() {
+ def c = new StringProperty()
+ c.foo = ['foo']
+ assert c.foo == ['foo']
+ }
+ test()
+ """
}
- @Test
- void testTraitWithGenericProperty3() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait PropertyProvider<T> {
- private T foo
- T getFoo() { foo }
- void setFoo(T t) { foo = t }
- }
- $mode
- class StringProperty implements PropertyProvider<String> {
- }
- $mode
- void test() {
- def c = new StringProperty(foo:'bar')
- assert c.getFoo() == 'bar'
- c.setFoo('foo')
- assert c.getFoo() == 'foo'
- }
- test()
- """
- }
+ @CompileModesTest
+ void testTraitWithGenericProperty3(String mode) {
+ assertScript shell, """
+ $mode
+ trait PropertyProvider<T> {
+ private T foo
+ T getFoo() { foo }
+ void setFoo(T t) { foo = t }
+ }
+ $mode
+ class StringProperty implements PropertyProvider<String> {
+ }
+ $mode
+ void test() {
+ def c = new StringProperty(foo:'bar')
+ assert c.getFoo() == 'bar'
+ c.setFoo('foo')
+ assert c.getFoo() == 'foo'
+ }
+ test()
+ """
}
@Test
@@ -1722,105 +1716,99 @@ final class TraitASTTransformationTest {
}
// GROOVY-7213, GROOVY-8859
- @Test
- void testPrivateMethodInTrait() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait T {
- private String secret() { 'secret' }
- String foo() { secret() }
- }
- $mode
- class C implements T {
- }
+ @CompileModesTest
+ void testPrivateMethodInTrait(String mode) {
+ assertScript shell, """
+ $mode
+ trait T {
+ private String secret() { 'secret' }
+ String foo() { secret() }
+ }
+ $mode
+ class C implements T {
+ }
- assert new C().foo() == 'secret'
- """
+ assert new C().foo() == 'secret'
+ """
- shouldFail shell, """
- $mode
- trait T {
- public String bar() {
- 'public'
- }
- private String baz() {
- 'private'
- }
+ shouldFail shell, """
+ $mode
+ trait T {
+ public String bar() {
+ 'public'
}
- $mode
- class C implements T {
- def foo() {
- bar() + baz()
- }
+ private String baz() {
+ 'private'
}
+ }
+ $mode
+ class C implements T {
+ def foo() {
+ bar() + baz()
+ }
+ }
- assert new C().foo() == 'publicprivate'
- """
- }
+ assert new C().foo() == 'publicprivate'
+ """
}
- @Test
- 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 {
- }
+ @CompileModesTest
+ void testPrivateMethodInTraitAccessingPrivateField(String mode) {
+ 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
- """
+ def c = new C()
+ assert c.foo() == 1
+ assert c.foo() == 2
+ """
- // GROOVY-7214
- assertScript shell, """
- $mode
- trait T {
- private static int x = 0
- private static initX() {
- x = 42
- }
- static getValue() {
- initX()
- x
- }
+ // GROOVY-7214
+ assertScript shell, """
+ $mode
+ trait T {
+ private static int x = 0
+ private static initX() {
+ x = 42
}
- $mode
- class C implements T {
+ static getValue() {
+ initX()
+ x
}
+ }
+ $mode
+ class C implements T {
+ }
- assert C.value == 42
- """
- }
+ assert C.value == 42
+ """
}
- @Test
- 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 }
- }
+ @CompileModesTest
+ void testPrivateMethodInTraitAccessingPrivateFieldNoShadowing(String mode)
{
+ 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
- """
- }
+ def c = new C()
+ assert c.foo() == 1
+ assert c.foo() == 2
+ """
}
@Test
@@ -2017,199 +2005,193 @@ final class TraitASTTransformationTest {
assert err =~ 'Cannot return value of type java.lang.String for method
returning int'
}
- @Test
- void testTraitStaticMethod() {
- 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 {
- }
+ @CompileModesTest
+ void testTraitStaticMethod(String mode) {
+ assertScript shell, """
+ $mode
+ trait T {
+ static String foo() { 'static method' }
+ }
+ $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'
- """
+ 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 {
- }
+ // 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'
- """
+ 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 {
- }
+ // 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
- """
+ 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
+ // GROOVY-8854
+ assertScript shell, """
+ $mode
+ trait T {
+ boolean passes
+ void audit() {
+ if (checkCondition()) {
+ passes = true
}
}
- $mode
- class C implements T {
- String name
- }
- $mode
- class D extends C {
+ 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 c = new C(name:'name')
+ c.audit(); assert c.passes
- def d = new D(name:'name')
- d.audit(); assert d.passes
- """
- }
+ def d = new D(name:'name')
+ d.audit(); assert d.passes
+ """
}
- @Test
- void testTraitStaticField() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait T {
- public static int VAL = 123
- }
- $mode
- class C implements T {
- }
+ @CompileModesTest
+ void testTraitStaticField(String mode) {
+ assertScript shell, """
+ $mode
+ trait T {
+ public static int VAL = 123
+ }
+ $mode
+ class C implements T {
+ }
- assert C.T__VAL == 123
- """
+ 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 {
- }
+ 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
- """
- }
+ assert C.T__VAL == 123
+ C.update(456)
+ assert C.T__VAL == 456
+ """
}
- @Test
- void testTraitStaticProperty() {
- 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 {
- }
+ @CompileModesTest
+ void testTraitStaticProperty(String mode) {
+ assertScript shell, """
+ $mode
+ trait T {
+ static int VAL = 123
+ public static void update(int x) { VAL = x }
+ }
+ $mode
+ class C implements T {
+ }
- assert C.VAL == 123
- C.update(456)
- assert C.VAL == 456
- """
+ assert C.VAL == 123
+ C.update(456)
+ assert C.VAL == 456
+ """
- // GROOVY-7255
- assertScript shell, """
- $mode
- trait T {
- static List stuff = [1,2,3]
+ // 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 {
+ static initStuff(List list) {
+ stuff = stuff + list
}
+ }
+ $mode
+ class C implements T {
+ }
- C.initStuff([4,5,6])
- assert C.stuff == [1,2,3,4,5,6]
- """
+ C.initStuff([4,5,6])
+ assert C.stuff == [1,2,3,4,5,6]
+ """
- assertScript shell, """
- $mode
- trait T {
- static int p = 1
- }
- $mode
- class C implements T {
- static int m() {
- setP(2)
- setP(getP() + 1)
- return getP()
- }
+ assertScript shell, """
+ $mode
+ trait T {
+ static int p = 1
+ }
+ $mode
+ class C implements T {
+ static int m() {
+ setP(2)
+ setP(getP() + 1)
+ return getP()
}
+ }
- assert C.m() == 3
- """
+ 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
- }
+ // 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
- """
- }
+ assert C.m() == 3
+ """
}
@Test
@@ -3243,7 +3225,7 @@ final class TraitASTTransformationTest {
System.setProperty('spock.iKnowWhatImDoing.disableGroovyVersionCheck','true')
assertScript shell, """
- @Grab('org.spockframework:spock-core:2.4-M5-groovy-4.0')
+ @Grab('org.spockframework:spock-core:2.4-M6-groovy-4.0')
@GrabExclude('org.apache.groovy:*')
import spock.lang.Specification
@@ -3442,32 +3424,30 @@ final class TraitASTTransformationTest {
}
// GROOVY-8731
- @Test
- void testStaticMethodsIgnoredWhenExistingInstanceMethodsFound() {
- 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 }
- }
+ @CompileModesTest
+ void testStaticMethodsIgnoredWhenExistingInstanceMethodsFound(String mode)
{
+ 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
+ }
+ """
}
// GROOVY-6716
@@ -3627,122 +3607,145 @@ final class TraitASTTransformationTest {
}
// 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
+ @CompileModesTest
+ void testTraitWithPropertyAlsoFromInterface(String mode) {
+ 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() {}
+ """
+ }
+
+ // GROOVY-8272
+ @CompileModesTest
+ void testTraitAccessToInheritedStaticMethods(String mode) {
+ assertScript shell, """
+ $mode
+ trait Foo {
+ static String go() {
+ 'Go!'
}
- $mode
- abstract class CustomProp extends OrderedProp implements
Nullable {
+ }
+ $mode
+ trait Bar extends Foo {
+ String test() {
+ go().toUpperCase()
}
+ }
+ $mode
+ class Main implements Bar {
+ }
- assert new CustomProp() {}
- """
- }
+ assert new Main().test() == 'GO!'
+ """
}
- // GROOVY-8272
- @Test
- void testTraitAccessToInheritedStaticMethods() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait Foo {
- static String go() {
- 'Go!'
- }
+ // GROOVY-10312
+ @CompileModesTest
+ void testTraitAccessToInheritedStaticMethods2(String mode) {
+ assertScript shell, """
+ $mode
+ trait Foo {
+ static String staticMethod(String string) {
+ return string
}
- $mode
- trait Bar extends Foo {
- String test() {
- go().toUpperCase()
- }
+ }
+ $mode
+ trait Bar extends Foo {
+ static String staticMethodWithDefaultArgument(String string =
'works') {
+ staticMethod(string) // MissingMethodException
}
- $mode
- class Main implements Bar {
+ }
+ $mode
+ class Main implements Bar {
+ static test1() {
+ String result = staticMethodWithDefaultArgument()
+ assert result == 'works'
}
+ void test2() {
+ String result = staticMethodWithDefaultArgument()
+ assert result == 'works'
+ }
+ }
- assert new Main().test() == 'GO!'
- """
- }
+ Main.test1()
+ new Main().test2()
+ """
}
// GROOVY-10312
- @Test
- void testTraitAccessToInheritedStaticMethods2() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait Foo {
- static String staticMethod(String string) {
- return string
- }
+ @CompileModesTest
+ void testTraitAccessToInheritedStaticMethods3(String mode) {
+ assertScript shell, """
+ $mode
+ interface Foo {
+ public static final String BANG = '!'
+ }
+ $mode
+ trait Bar implements Foo {
+ static String staticMethodWithDefaultArgument(String string =
'works') {
+ string + BANG
}
- $mode
- trait Bar extends Foo {
- static String staticMethodWithDefaultArgument(String
string = 'works') {
- staticMethod(string) // MissingMethodException
- }
+ }
+ $mode
+ class Main implements Bar {
+ static test1() {
+ 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'
- }
+ void test2() {
+ String result = staticMethodWithDefaultArgument()
+ assert result == 'works!'
}
+ }
- Main.test1()
- new Main().test2()
- """
- }
+ Main.test1()
+ new Main().test2()
+ """
}
- // GROOVY-10312
- @Test
- void testTraitAccessToInheritedStaticMethods3() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- interface Foo {
- public static final String BANG = '!'
- }
- $mode
- trait Bar implements Foo {
- static String staticMethodWithDefaultArgument(String
string = 'works') {
- string + BANG
- }
+ // GROOVY-11641
+ @CompileModesTest
+ void testTraitAccessToInheritedStaticMethods4(String mode) {
+ assertScript shell, """
+ $mode
+ trait Foo {
+ public static final String BANG = '!'
+ }
+ $mode
+ trait Bar extends Foo {
+ static staticMethod(String string) {
+ string + BANG
}
- $mode
- class Main implements Bar {
- static test1() {
- String result = staticMethodWithDefaultArgument()
- assert result == 'works!'
- }
- void test2() {
- String result = staticMethodWithDefaultArgument()
- assert result == 'works!'
- }
+ }
+ $mode
+ class Main implements Bar {
+ static test1() {
+ String result = staticMethod('works')
+ assert result == 'works!'
}
+ void test2() {
+ String result = staticMethod('works')
+ assert result == 'works!'
+ }
+ }
- Main.test1()
- new Main().test2()
- """
- }
+ Main.test1()
+ new Main().test2()
+ """
}
// GROOVY-9386