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 2025/04/27 23:15:39 UTC
(groovy) branch GROOVY-11641 created (now 491c5e7a0d)
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a change to branch GROOVY-11641
in repository https://gitbox.apache.org/repos/asf/groovy.git
at 491c5e7a0d GROOVY-11641: index trait field under original name
This branch includes the following new commits:
new 064b645880 refactor compile mode inputs
new 491c5e7a0d GROOVY-11641: index trait field under original name
The 2 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.
(groovy) 02/02: GROOVY-11641: index trait field under original name
Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY-11641
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 491c5e7a0d62a60821c3ef1006dd8c9323809990
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Apr 27 18:15:20 2025 -0500
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 | 31 ++++++++++++++++++++++
5 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 495639eac8..0029c23c79 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;
@@ -2367,8 +2373,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 aa8357f963..d90290e21e 100644
--- a/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
+++ b/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
@@ -3717,6 +3717,37 @@ final class TraitASTTransformationTest {
"""
}
+ // 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 = staticMethod('works')
+ assert result == 'works!'
+ }
+ void test2() {
+ String result = staticMethod('works')
+ assert result == 'works!'
+ }
+ }
+
+ Main.test1()
+ new Main().test2()
+ """
+ }
+
// GROOVY-9386
@Test
void testTraitPropertyInitializedByTap() {
(groovy) 01/02: refactor compile mode inputs
Posted by em...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY-11641
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 064b645880b3c0cb625c776b033973f66ec89ef6
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Apr 27 18:12:25 2025 -0500
refactor compile mode inputs
---
.../traitx/TraitASTTransformationTest.groovy | 990 ++++++++++-----------
1 file changed, 481 insertions(+), 509 deletions(-)
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..aa8357f963 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,114 @@ 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
- }
- $mode
- abstract class CustomProp extends OrderedProp implements Nullable {
- }
+ @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() {}
- """
- }
+ assert new CustomProp() {}
+ """
}
// GROOVY-8272
- @Test
- void testTraitAccessToInheritedStaticMethods() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait Foo {
- static String go() {
- 'Go!'
- }
- }
- $mode
- trait Bar extends Foo {
- String test() {
- go().toUpperCase()
- }
+ @CompileModesTest
+ void testTraitAccessToInheritedStaticMethods(String mode) {
+ assertScript shell, """
+ $mode
+ trait Foo {
+ static String go() {
+ 'Go!'
}
- $mode
- class Main implements Bar {
+ }
+ $mode
+ trait Bar extends Foo {
+ String test() {
+ go().toUpperCase()
}
+ }
+ $mode
+ class Main implements Bar {
+ }
- assert new Main().test() == 'GO!'
- """
- }
+ assert new Main().test() == 'GO!'
+ """
}
// GROOVY-10312
- @Test
- void testTraitAccessToInheritedStaticMethods2() {
- for (mode in ['','@TypeChecked','@CompileStatic']) {
- assertScript shell, """
- $mode
- trait Foo {
- static String staticMethod(String string) {
- return string
- }
+ @CompileModesTest
+ void testTraitAccessToInheritedStaticMethods2(String mode) {
+ assertScript shell, """
+ $mode
+ trait Foo {
+ static String staticMethod(String string) {
+ return string
}
- $mode
- trait Bar extends Foo {
- static String staticMethodWithDefaultArgument(String string = 'works') {
- staticMethod(string) // MissingMethodException
- }
+ }
+ $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'
- }
- 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()
+ """
}
// 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
- }
+ @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
- 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 = staticMethodWithDefaultArgument()
+ assert result == 'works!'
}
+ void test2() {
+ String result = staticMethodWithDefaultArgument()
+ assert result == 'works!'
+ }
+ }
- Main.test1()
- new Main().test2()
- """
- }
+ Main.test1()
+ new Main().test2()
+ """
}
// GROOVY-9386