Skip to content

Commit

Permalink
GROOVY-8983, GROOVY-8984
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Apr 3, 2021
1 parent 81f32c2 commit f863d7e
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,140 @@ public void testTypeChecked8909a() {
"----------\n");
}

@Test
public void testTypeChecked8983() {
//@formatter:off
String[] sources = {
"Main.groovy",
"List<String> m() { ['foo'] }\n" +
"@groovy.transform.TypeChecked\n" +
"void test(Set<String> set) {\n" +
" String[] one = m()\n" +
" String[] two = set\n" +
" print(one + two)\n" +
"}\n" +
"test(['bar'].toSet())\n",
};
//@formatter:on

runConformTest(sources, "[foo, bar]");
}

@Test
public void testTypeChecked8983a() {
//@formatter:off
String[] sources = {
"Main.groovy",
"List<String> m() { ['foo'] }\n" +
"@groovy.transform.TypeChecked\n" +
"void test(Set<String> set) {\n" +
" CharSequence[] one = m()\n" +
" CharSequence[] two = set\n" +
" print(one + two)\n" +
"}\n" +
"test(['bar'].toSet())\n",
};
//@formatter:on

runConformTest(sources, "[foo, bar]");
}

@Test
public void testTypeChecked8983b() {
//@formatter:off
String[] sources = {
"Main.groovy",
"List<String> m() { ['foo'] }\n" +
"@groovy.transform.TypeChecked\n" +
"void test(Set<String> set) {\n" +
" Object[] one = m()\n" +
" Object[] two = set\n" +
" print(one + two)\n" +
"}\n" +
"test(['bar'].toSet())\n",
};
//@formatter:on

runConformTest(sources, "[foo, bar]");
}

@Test
public void testTypeChecked8983c() {
//@formatter:off
String[] sources = {
"Main.groovy",
"List<? extends CharSequence> m() { ['foo'] }\n" +
"@groovy.transform.TypeChecked\n" +
"void test(Set<? extends CharSequence> set) {\n" +
" CharSequence[] one = m()\n" +
" CharSequence[] two = set\n" +
" print(one + two)\n" +
"}\n" +
"test(['bar'].toSet())\n",
};
//@formatter:on

runConformTest(sources, "[foo, bar]");
}

@Test
public void testTypeChecked8984() {
//@formatter:off
String[] sources = {
"Main.groovy",
"List<? super CharSequence> m() { [null] }\n" +
"@groovy.transform.TypeChecked\n" +
"void test(Set<? super CharSequence> set) {\n" +
" CharSequence[] one = m()\n" +
" CharSequence[] two = set\n" +
"}\n" +
"test([null].toSet())\n",
};
//@formatter:on

runNegativeTest(sources,
"----------\n" +
"1. ERROR in Main.groovy (at line 4)\n" +
"\tCharSequence[] one = m()\n" +
"\t ^^^\n" +
"Groovy:[Static type checking] - Cannot assign value of type java.util.List <? super java.lang.CharSequence> to variable of type java.lang.CharSequence[]\n" +
"----------\n" +
"2. ERROR in Main.groovy (at line 5)\n" +
"\tCharSequence[] two = set\n" +
"\t ^^^\n" +
"Groovy:[Static type checking] - Cannot assign value of type java.util.Set <? super java.lang.CharSequence> to variable of type java.lang.CharSequence[]\n" +
"----------\n");
}

@Test
public void testTypeChecked8984a() {
//@formatter:off
String[] sources = {
"Main.groovy",
"List<String> m() { ['foo'] }\n" +
"@groovy.transform.TypeChecked\n" +
"void test(Set<String> set) {\n" +
" Number[] one = m()\n" +
" Number[] two = set\n" +
"}\n" +
"test(['bar'].toSet())\n",
};
//@formatter:on

runNegativeTest(sources,
"----------\n" +
"1. ERROR in Main.groovy (at line 4)\n" +
"\tNumber[] one = m()\n" +
"\t ^^^\n" +
"Groovy:[Static type checking] - Cannot assign value of type java.util.List <String> to variable of type java.lang.Number[]\n" +
"----------\n" +
"2. ERROR in Main.groovy (at line 5)\n" +
"\tNumber[] two = set\n" +
"\t ^^^\n" +
"Groovy:[Static type checking] - Cannot assign value of type java.util.Set <String> to variable of type java.lang.Number[]\n" +
"----------\n");
}

@Test
public void testTypeChecked9460() {
//@formatter:off
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ public static ClassNode parameterizeType(final ClassNode hint, final ClassNode t
}
return target;
}
if (hint.isGenericsPlaceHolder()) {
ClassNode bound = hint.redirect();
return parameterizeType(bound, target);
}
if (target.redirect().getGenericsTypes() == null) {
return target;
}
if (!target.equals(hint) && implementsInterfaceOrIsSubclassOf(target, hint)) {
ClassNode nextSuperClass = ClassHelper.getNextSuperClass(target, hint);
if (!hint.equals(nextSuperClass)) {
Expand Down Expand Up @@ -425,9 +432,9 @@ public static ClassNode correctToGenericsSpec(Map<String, ClassNode> genericsSpe
String name = type.getName();
ret = genericsSpec.get(name);
}
// GRECLIPSE add -- GROOVY-9891
// GRECLIPSE add -- GROOVY-8984, GROOVY-9891
else if (type.isWildcard()) {
ret = type.getLowerBound(); // use lower or upper
//ret = type.getLowerBound(); // use lower or upper
if (ret == null && type.getUpperBounds() != null) {
ret = type.getUpperBounds()[0]; // ? supports 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.codehaus.groovy.ast.expr.MapExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.ReturnStatement;
import org.codehaus.groovy.ast.tools.GeneralUtils;
import org.codehaus.groovy.ast.tools.GenericsUtils;
import org.codehaus.groovy.ast.tools.ParameterUtils;
import org.codehaus.groovy.ast.tools.WideningCategories;
Expand Down Expand Up @@ -691,9 +692,26 @@ public static boolean checkCompatibleAssignmentTypes(ClassNode left, ClassNode r
return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType(), rightExpression, false);
}

/* GRECLIPSE edit -- GROOVY-8983
if (rightRedirect == VOID_TYPE || rightRedirect == void_WRAPPER_TYPE) {
return leftRedirect == VOID_TYPE || leftRedirect == void_WRAPPER_TYPE;
}
*/
if (rightRedirect == void_WRAPPER_TYPE) return leftRedirect == VOID_TYPE;
if (rightRedirect == VOID_TYPE) return leftRedirect == void_WRAPPER_TYPE;

if (left.isArray()) {
if (right.isArray()) {
return checkCompatibleAssignmentTypes(left.getComponentType(), right.getComponentType(), rightExpression, false);
}
if (GeneralUtils.isOrImplements(right, Collection_TYPE) && !(rightExpression instanceof ListExpression)) {
GenericsType elementType = GenericsUtils.parameterizeType(right, Collection_TYPE).getGenericsTypes()[0];
return OBJECT_TYPE.equals(left.getComponentType()) // Object[] can accept any collection element type(s)
|| (elementType.getLowerBound() == null && isCovariant(extractType(elementType), left.getComponentType()));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GROOVY-8984: "? super T" is only compatible with an Object[] target
}
}
// GRECLIPSE end

if (isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect)) {
if (leftRedirect.equals(BigDecimal_TYPE) || leftRedirect.equals(Number_TYPE)) { // GRECLIPSE add -- GROOVY-9935
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,13 @@ public static ClassNode parameterizeType(final ClassNode hint, final ClassNode t
}
return target;
}
if (hint.isGenericsPlaceHolder()) {
ClassNode bound = hint.redirect();
return parameterizeType(bound, target);
}
if (target.redirect().getGenericsTypes() == null) {
return target;
}
if (!target.equals(hint) && implementsInterfaceOrIsSubclassOf(target, hint)) {
ClassNode nextSuperClass = ClassHelper.getNextSuperClass(target, hint);
if (!hint.equals(nextSuperClass)) {
Expand Down Expand Up @@ -421,9 +428,9 @@ public static ClassNode correctToGenericsSpec(Map<String, ClassNode> genericsSpe
String name = type.getName();
ret = genericsSpec.get(name);
}
// GRECLIPSE add -- GROOVY-9891
// GRECLIPSE add -- GROOVY-8984, GROOVY-9891
else if (type.isWildcard()) {
ret = type.getLowerBound(); // use lower or upper
//ret = type.getLowerBound(); // use lower or upper
if (ret == null && type.getUpperBounds() != null) {
ret = type.getUpperBounds()[0]; // ? supports 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.codehaus.groovy.ast.expr.MapExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.ReturnStatement;
import org.codehaus.groovy.ast.tools.GeneralUtils;
import org.codehaus.groovy.ast.tools.GenericsUtils;
import org.codehaus.groovy.ast.tools.ParameterUtils;
import org.codehaus.groovy.ast.tools.WideningCategories;
Expand Down Expand Up @@ -654,13 +655,30 @@ public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final
ClassNode rightRedirect = right.redirect();
if (leftRedirect == rightRedirect) return true;

/* GRECLIPSE edit -- GROOVY-8983
if (leftRedirect.isArray() && rightRedirect.isArray()) {
return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType(), rightExpression, false);
}
if (rightRedirect == VOID_TYPE || rightRedirect == void_WRAPPER_TYPE) {
return leftRedirect == VOID_TYPE || leftRedirect == void_WRAPPER_TYPE;
}
*/
if (rightRedirect == void_WRAPPER_TYPE) return leftRedirect == VOID_TYPE;
if (rightRedirect == VOID_TYPE) return leftRedirect == void_WRAPPER_TYPE;

if (left.isArray()) {
if (right.isArray()) {
return checkCompatibleAssignmentTypes(left.getComponentType(), right.getComponentType(), rightExpression, false);
}
if (GeneralUtils.isOrImplements(right, Collection_TYPE) && !(rightExpression instanceof ListExpression)) {
GenericsType elementType = GenericsUtils.parameterizeType(right, Collection_TYPE).getGenericsTypes()[0];
return OBJECT_TYPE.equals(left.getComponentType()) // Object[] can accept any collection element type(s)
|| (elementType.getLowerBound() == null && isCovariant(extractType(elementType), left.getComponentType()));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GROOVY-8984: "? super T" is only compatible with an Object[] target
}
}
// GRECLIPSE end

if (isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect)) {
if (leftRedirect.equals(BigDecimal_TYPE) || leftRedirect.equals(Number_TYPE)) { // GRECLIPSE add -- GROOVY-9935
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,13 @@ public static ClassNode parameterizeType(final ClassNode hint, final ClassNode t
}
return target;
}
if (hint.isGenericsPlaceHolder()) {
ClassNode bound = hint.redirect();
return parameterizeType(bound, target);
}
if (target.redirect().getGenericsTypes() == null) {
return target;
}
if (!target.equals(hint) && implementsInterfaceOrIsSubclassOf(target, hint)) {
ClassNode nextSuperClass = ClassHelper.getNextSuperClass(target, hint);
if (!hint.equals(nextSuperClass)) {
Expand Down Expand Up @@ -421,9 +428,9 @@ public static ClassNode correctToGenericsSpec(Map<String, ClassNode> genericsSpe
String name = type.getName();
ret = genericsSpec.get(name);
}
// GRECLIPSE add -- GROOVY-9891
// GRECLIPSE add -- GROOVY-8984, GROOVY-9891
else if (type.isWildcard()) {
ret = type.getLowerBound(); // use lower or upper
//ret = type.getLowerBound(); // use lower or upper
if (ret == null && type.getUpperBounds() != null) {
ret = type.getUpperBounds()[0]; // ? supports 1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.codehaus.groovy.ast.expr.MapExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.ReturnStatement;
import org.codehaus.groovy.ast.tools.GeneralUtils;
import org.codehaus.groovy.ast.tools.GenericsUtils;
import org.codehaus.groovy.ast.tools.ParameterUtils;
import org.codehaus.groovy.ast.tools.WideningCategories;
Expand Down Expand Up @@ -653,13 +654,30 @@ public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final
ClassNode rightRedirect = right.redirect();
if (leftRedirect == rightRedirect) return true;

/* GRECLIPSE edit -- GROOVY-8983
if (leftRedirect.isArray() && rightRedirect.isArray()) {
return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType(), rightExpression, false);
}
if (rightRedirect == VOID_TYPE || rightRedirect == void_WRAPPER_TYPE) {
return leftRedirect == VOID_TYPE || leftRedirect == void_WRAPPER_TYPE;
}
*/
if (rightRedirect == void_WRAPPER_TYPE) return leftRedirect == VOID_TYPE;
if (rightRedirect == VOID_TYPE) return leftRedirect == void_WRAPPER_TYPE;

if (left.isArray()) {
if (right.isArray()) {
return checkCompatibleAssignmentTypes(left.getComponentType(), right.getComponentType(), rightExpression, false);
}
if (GeneralUtils.isOrImplements(right, Collection_TYPE) && !(rightExpression instanceof ListExpression)) {
GenericsType elementType = GenericsUtils.parameterizeType(right, Collection_TYPE).getGenericsTypes()[0];
return OBJECT_TYPE.equals(left.getComponentType()) // Object[] can accept any collection element type(s)
|| (elementType.getLowerBound() == null && isCovariant(extractType(elementType), left.getComponentType()));
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GROOVY-8984: "? super T" is only compatible with an Object[] target
}
}
// GRECLIPSE end

if (isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect)) {
if (leftRedirect.equals(BigDecimal_TYPE) || leftRedirect.equals(Number_TYPE)) { // GRECLIPSE add -- GROOVY-9935
Expand Down

0 comments on commit f863d7e

Please sign in to comment.