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 2020/05/31 15:29:19 UTC
[groovy] 01/01: GROOVY-9580: declaring class of getter/setter
should be same as property
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY-9580
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit c52c6275e77713ef47a582eaff1f0871f48a3e76
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun May 31 10:21:16 2020 -0500
GROOVY-9580: declaring class of getter/setter should be same as property
---
.../transform/stc/StaticTypeCheckingVisitor.java | 20 +--
src/test/groovy/bugs/Groovy7691Bug.groovy | 99 ------------
.../groovy/transform/stc/GenericsSTCTest.groovy | 169 +++++++++++++++++----
3 files changed, 145 insertions(+), 143 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 67e1d99..a0b10eb 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4636,14 +4636,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
curNode = curNode.getSuperClass();
}
if (property != null) {
- MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC, property.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
- if (property.isStatic()) {
- node.setModifiers(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC);
- }
- node.setDeclaringClass(receiver);
- return Collections.singletonList(
- node);
-
+ int mods = Opcodes.ACC_PUBLIC | (property.isStatic() ? Opcodes.ACC_STATIC : 0);
+ MethodNode node = new MethodNode(name, mods, property.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
+ node.setDeclaringClass(property.getDeclaringClass());
+ return Collections.singletonList(node);
}
}
} else if (methods.isEmpty() && args != null && args.length == 1) {
@@ -4659,11 +4655,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
if (property != null) {
ClassNode type = property.getOriginType();
if (implementsInterfaceOrIsSubclassOf(wrapTypeIfNecessary(args[0]), wrapTypeIfNecessary(type))) {
- MethodNode node = new MethodNode(name, Opcodes.ACC_PUBLIC, VOID_TYPE, new Parameter[]{new Parameter(type, "arg")}, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
- if (property.isStatic()) {
- node.setModifiers(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC);
- }
- node.setDeclaringClass(receiver);
+ int mods = Opcodes.ACC_PUBLIC | (property.isStatic() ? Opcodes.ACC_STATIC : 0);
+ MethodNode node = new MethodNode(name, mods, VOID_TYPE, new Parameter[]{new Parameter(type, name)}, ClassNode.EMPTY_ARRAY, GENERATED_EMPTY_STATEMENT);
+ node.setDeclaringClass(property.getDeclaringClass());
return Collections.singletonList(node);
}
}
diff --git a/src/test/groovy/bugs/Groovy7691Bug.groovy b/src/test/groovy/bugs/Groovy7691Bug.groovy
deleted file mode 100644
index 5ffe0ee..0000000
--- a/src/test/groovy/bugs/Groovy7691Bug.groovy
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package groovy.bugs
-
-import groovy.test.GroovyTestCase
-
-class Groovy7691Bug extends GroovyTestCase {
-// @NotYetImplemented
- void testCovariantGenericField() {
- assertScript '''
- @groovy.transform.CompileStatic
- abstract class AbstractNumberWrapper<S extends Number> {
- protected final S number;
-
- AbstractNumberWrapper(S number) {
- this.number = number
- }
- }
- @groovy.transform.CompileStatic
- class LongWrapper<S extends Long> extends AbstractNumberWrapper<S> {
- LongWrapper(S longNumber) {
- super(longNumber)
- }
-
- S getValue() {
- return number;
- }
- }
- assert new LongWrapper<Long>(42L).value == 42L
- '''
- }
-
- void testCovariantGenericProperty() {
- assertScript '''
- @groovy.transform.CompileStatic
- abstract class AbstractNumberWrapper<S extends Number> {
- def S number;
-
- AbstractNumberWrapper(S number) {
- this.number = number
- }
- }
- @groovy.transform.CompileStatic
- class LongWrapper<S extends Long> extends AbstractNumberWrapper<S> {
- LongWrapper(S longNumber) {
- super(longNumber)
- }
-
- S getValue() {
- return number;
- }
- }
- assert new LongWrapper<Long>(42L).value == 42L
- '''
- }
-
- // this test can pass even if GROOVY-7691 is not resolved, just for ensuring the common case will pass test all the time!
- void testCovariantGenericMethod() {
- assertScript '''
- @groovy.transform.CompileStatic
- abstract class AbstractNumberWrapper<S extends Number> {
- protected final S number;
-
- AbstractNumberWrapper(S number) {
- this.number = number
- }
-
- protected S getNumber() { return number; }
- }
- @groovy.transform.CompileStatic
- class LongWrapper<S extends Long> extends AbstractNumberWrapper<S> {
- LongWrapper(S longNumber) {
- super(longNumber)
- }
-
- S getValue() {
- return getNumber();
- }
- }
- assert new LongWrapper<Long>(42L).value == 42L
- '''
- }
-}
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 90c62ee..a924ab8 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -1697,42 +1697,45 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
// GROOVY-6731
void testContravariantMethodResolution() {
- assertScript '''interface Function<T, R> {
-
- R apply(T t)
+ assertScript '''
+ interface Function<T, R> {
+ R apply(T t)
+ }
-}
-public <I, O> void transform(Function<? super I, ? extends O> function) { function.apply('')}
+ public <I, O> void transform(Function<? super I, ? extends O> function) {
+ function.apply('')
+ }
-String result = null
-transform(new Function<String, String>() {
+ String result = null
+ transform(new Function<String, String>() {
+ String apply(String input) {
+ result = "ok"
+ }
+ })
- String apply(String input) {
- result = "ok"
+ assert result == 'ok'
+ '''
}
-})
-assert result == 'ok\''''
- }
void testContravariantMethodResolutionWithImplicitCoercion() {
- assertScript '''interface Function<T, R> {
-
- R apply(T t)
-
-}
-public <I, O> void transform(Function<? super I, ? extends O> function) { function.apply('')}
-
-String result = null
-transform {
- result = "ok"
-}
+ assertScript '''
+ interface Function<T, R> {
+ R apply(T t)
+ }
+ public <I, O> void transform(Function<? super I, ? extends O> function) {
+ function.apply('')
+ }
-assert result == 'ok'
-'''
+ String result = null
+ transform {
+ result = 'ok'
+ }
+ assert result == 'ok'
+ '''
}
- void testGROOVY5981(){
+ void testGROOVY5981() {
assertScript '''
import javax.swing.*
import java.awt.*
@@ -1772,6 +1775,113 @@ assert result == 'ok'
'''
}
+ // GROOVY-7691
+ void testCovariantReturnTypeInferredFromField() {
+ assertScript '''
+ import groovy.transform.*
+
+ @CompileStatic
+ @TupleConstructor(includeFields=true)
+ abstract class A<N extends Number> {
+ protected final N number
+ }
+
+ @CompileStatic
+ class C<L extends Long> extends A<L> { // further restriction of type parameter
+ C(L longNumber) {
+ super(longNumber)
+ }
+
+ L getValue() {
+ return number
+ }
+ }
+
+ assert new C<Long>(42L).value == 42L
+ '''
+ }
+
+ // GROOVY-7691
+ void testCovariantReturnTypeInferredFromProperty() {
+ assertScript '''
+ import groovy.transform.*
+
+ @CompileStatic
+ @TupleConstructor
+ abstract class A<N extends Number> {
+ final N number
+ }
+
+ @CompileStatic
+ class C<L extends Long> extends A<L> {
+ C(L longNumber) {
+ super(longNumber)
+ }
+
+ L getValue() {
+ return number
+ }
+ }
+
+ assert new C<Long>(42L).value == 42L
+ '''
+ }
+
+ void testCovariantReturnTypeInferredFromMethod1() {
+ assertScript '''
+ import groovy.transform.*
+
+ @CompileStatic
+ @TupleConstructor(includeFields=true)
+ abstract class A<N extends Number> {
+ protected final N number
+
+ protected N getNumber() {
+ return number
+ }
+ }
+
+ @CompileStatic
+ class C<L extends Long> extends A<L> {
+ C(L longNumber) {
+ super(longNumber)
+ }
+
+ L getValue() {
+ return getNumber()
+ }
+ }
+
+ assert new C<Long>(42L).value == 42L
+ '''
+ }
+
+ // GROOVY-9580
+ void testCovariantReturnTypeInferredFromMethod2() {
+ assertScript '''
+ import groovy.transform.*
+
+ @CompileStatic
+ @TupleConstructor(includeFields=true)
+ abstract class A<N extends Number> {
+ final N number
+ }
+
+ @CompileStatic
+ class C<L extends Long> extends A<L> {
+ C(L longNumber) {
+ super(longNumber)
+ }
+
+ L getValue() {
+ return getNumber() // property method stubbed by StaticTypeCheckingVisitor
+ }
+ }
+
+ assert new C<Long>(42L).value == 42L
+ '''
+ }
+
void testReturnTypeChecking() {
shouldFailWithMessages '''
class Foo {
@@ -1793,8 +1903,7 @@ assert result == 'ok'
'''
}
-
- //GROOVY-7804
+ // GROOVY-7804
void testParameterlessClosureToGenericSAMTypeArgumentCoercion() {
assertScript '''
interface Supplier<T> {
@@ -1807,7 +1916,7 @@ assert result == 'ok'
'''
}
- //GROOVY-7713
+ // GROOVY-7713
void testClosureReturnNull() {
assertScript '''
Closure<String> cl = {
@@ -1841,6 +1950,4 @@ assert result == 'ok'
public static <T> List<T> unwrap(Collection<? extends Container<T>> list) {
}
}
-
}
-