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/07/02 18:29:04 UTC

(groovy) branch master updated: refactor checks for cast and null

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

emilles 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 9af3820ce4 refactor checks for cast and null
9af3820ce4 is described below

commit 9af3820ce4bc75a080d18c7aea635dd8ff792357
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Jul 2 13:30:37 2024 -0500

    refactor checks for cast and null
---
 .../transform/stc/StaticTypeCheckingSupport.java   |    9 +-
 .../transform/stc/StaticTypeCheckingVisitor.java   |   44 +-
 .../groovy/transform/stc/CoercionSTCTest.groovy    |  181 +++
 .../groovy/transform/stc/STCAssignmentTest.groovy  | 1227 +++++++++-----------
 4 files changed, 739 insertions(+), 722 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index 0a86a19471..177fdcfe45 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -97,7 +97,6 @@ import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.Short_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE;
-import static org.codehaus.groovy.ast.ClassHelper.boolean_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.byte_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.char_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.double_TYPE;
@@ -647,8 +646,8 @@ public abstract class StaticTypeCheckingSupport {
      * @see org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation#castToType(Object,Class)
      */
     public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final ClassNode right, final Expression rightExpression, final boolean allowConstructorCoercion) {
-        if (!isPrimitiveType(left) && isNullConstant(rightExpression)) {
-            return true;
+        if (isNullConstant(rightExpression)) { // TODO: left is @NonNull
+            return (!isPrimitiveType(left) || isPrimitiveBoolean(left)); // GROOVY-6577
         }
 
         if (left.isArray()) {
@@ -712,8 +711,8 @@ public abstract class StaticTypeCheckingSupport {
                 return true;
             }
         } else if (isWildcardLeftHandSide(leftRedirect)) {
-            // Object, String, [Bb]oolean or Class can be assigned anything (except null to boolean)
-            return !(leftRedirect == boolean_TYPE && isNullConstant(rightExpression));
+            // Object, String, [Bb]oolean or Class can be assigned any non-null value
+            return true;
         }
 
         // if right is array, map or collection we try invoking the constructor
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 59f97bd538..25b53362c0 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -848,8 +848,8 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                 rightExpression.visit(this);
             }
 
-            ClassNode rType = isNullConstant(rightExpression) && !isPrimitiveType(lType)
-                    ? UNKNOWN_PARAMETER_TYPE // null to primitive type is handled elsewhere
+            ClassNode rType = isNullConstant(rightExpression)
+                    ? isPrimitiveType(lType) ? OBJECT_TYPE : UNKNOWN_PARAMETER_TYPE
                     : getInferredTypeFromTempInfo(rightExpression, getType(rightExpression));
             ClassNode resultType;
 
@@ -4316,29 +4316,27 @@ trying: for (ClassNode[] signature : signatures) {
     }
 
     protected boolean checkCast(final ClassNode targetType, final Expression source) {
-        boolean sourceIsNull = isNullConstant(source);
-        ClassNode expressionType = getType(source);
-        if (targetType.isArray() && expressionType.isArray()) {
-            return checkCast(targetType.getComponentType(), varX("foo", expressionType.getComponentType()));
-        } else if (isPrimitiveChar(targetType) && isStringType(expressionType)
+        if (isNullConstant(source)) {
+            return !isPrimitiveType(targetType) || isPrimitiveBoolean(targetType); // GROOVY-6577
+        }
+        ClassNode sourceType = getType(source);
+        if (targetType.isArray() && sourceType.isArray()) {
+            return checkCast(targetType.getComponentType(), varX("_", sourceType.getComponentType()));
+        } else if (isPrimitiveChar(targetType) && isStringType(sourceType)
                 && source instanceof ConstantExpression && source.getText().length() == 1) {
             // ex: (char) 'c'
-        } else if (isWrapperCharacter(targetType) && (isStringType(expressionType) || sourceIsNull)
-                && (sourceIsNull || source instanceof ConstantExpression && source.getText().length() == 1)) {
-            // ex : (Character) 'c'
-        } else if (isNumberCategory(getWrapper(targetType)) && (isNumberCategory(getWrapper(expressionType)) || isPrimitiveChar(expressionType))) {
-            // ex: short s = (short) 0
-        } else if (sourceIsNull && !isPrimitiveType(targetType)) {
-            // ex: (Date)null
-        } else if (isPrimitiveChar(targetType) && isPrimitiveType(expressionType) && isNumberType(expressionType)) {
-            // char c = (char) ...
-        } else if (sourceIsNull && isPrimitiveType(targetType) && !isPrimitiveBoolean(targetType)) {
-            return false;
-        } else if (!Modifier.isFinal(expressionType.getModifiers()) && targetType.isInterface()) {
-            return true;
-        } else if (!Modifier.isFinal(targetType.getModifiers()) && expressionType.isInterface()) {
-            return true;
-        } else if (!isAssignableTo(targetType, expressionType) && !implementsInterfaceOrIsSubclassOf(expressionType, targetType)) {
+        } else if (isWrapperCharacter(targetType) && isStringType(sourceType)
+                && source instanceof ConstantExpression && source.getText().length() == 1) {
+            // ex: (Character) 'c'
+        } else if (isNumberCategory(getWrapper(targetType)) && (isNumberCategory(getWrapper(sourceType)) || isPrimitiveChar(sourceType))) {
+            // ex: (long) 0
+        } else if (isPrimitiveChar(targetType) && isPrimitiveType(sourceType) && isNumberType(sourceType)) {
+            // ex: (char) 0
+        } else if (!Modifier.isFinal(sourceType.getModifiers()) && targetType.isInterface()) {
+            // ex: TODO
+        } else if (!Modifier.isFinal(targetType.getModifiers()) && sourceType.isInterface()) {
+            // ex: TODO
+        } else if (!isAssignableTo(targetType, sourceType) && !implementsInterfaceOrIsSubclassOf(sourceType, targetType)) {
             return false;
         }
         return true;
diff --git a/src/test/groovy/transform/stc/CoercionSTCTest.groovy b/src/test/groovy/transform/stc/CoercionSTCTest.groovy
index aa2b1a0358..d48dbdf562 100644
--- a/src/test/groovy/transform/stc/CoercionSTCTest.groovy
+++ b/src/test/groovy/transform/stc/CoercionSTCTest.groovy
@@ -32,6 +32,179 @@ class CoercionSTCTest extends StaticTypeCheckingTestCase {
         )
     }
 
+    void testCastIntToShort() {
+        assertScript '''
+            short s = (short) 0
+        '''
+    }
+
+    void testCastIntToFloat() {
+        assertScript '''
+            float f = (float) 1
+        '''
+    }
+
+    void testCastCompatibleType() {
+        assertScript '''
+            String s = 'Hello'
+            ((CharSequence) s)
+        '''
+    }
+
+    void testCastIncompatibleType() {
+        shouldFailWithMessages '''
+            String s = 'Hello'
+            ((Set) s)
+        ''',
+        'Inconvertible types: cannot cast java.lang.String to java.util.Set'
+    }
+
+    void testCastIncompatibleTypeWithFlowType() {
+        shouldFailWithMessages '''
+            def s = 'Hello'
+            s = 1
+            ((Set) s)
+        ''',
+        'Inconvertible types: cannot cast java.lang.Integer to java.util.Set'
+    }
+
+    void testCastStringToChar() {
+        assertScript '''
+            def c = (char) 'a'
+            assert c === "a".charAt(0)
+        '''
+    }
+
+    void testCastCharToByte() {
+        assertScript '''
+            void foo(char c) {
+                byte b = (byte) c
+            }
+        '''
+    }
+
+    void testCastCharToInt() {
+        assertScript '''
+            void foo(char c) {
+                int b = (int) c
+            }
+        '''
+    }
+
+    void testCastStringLongerThan1ToChar() {
+        shouldFailWithMessages '''
+            def c = (char) 'aa'
+        ''',
+        'Inconvertible types: cannot cast java.lang.String to char'
+    }
+
+    // GROOVY-6577
+    void testCastNullToBoolean() {
+        assertScript '''
+            boolean b = (boolean) null
+            assert b === false
+        '''
+    }
+
+    void testCastNullToPrimitive() {
+        // boolean tested above and void cannot appear in cast expression
+        for (type in ['byte','char','double','float','int','long','short']) {
+            shouldFailWithMessages """
+                def v = ($type) null
+            """,
+            "Inconvertible types: cannot cast java.lang.Object to $type"
+        }
+    }
+
+    void testCastNullToCharacter() {
+        assertScript '''
+            def c = (Character) null
+            assert c === null
+        '''
+    }
+
+    void testCastStringToCharacter() {
+        assertScript '''
+            def c = (Character) 'a'
+            assert c instanceof Character
+            assert c.charValue() == "a".charAt(0)
+        '''
+    }
+
+    void testCastStringLongerThan1ToCharacter() {
+        shouldFailWithMessages '''
+            def c = (Character) 'aa'
+        ''',
+        'Inconvertible types: cannot cast java.lang.String to java.lang.Character'
+    }
+
+    void testCastArray() {
+        assertScript '''
+            List<String> src = ['a','b','c']
+            (String[]) src.toArray(src as String[])
+        '''
+    }
+
+    void testCastArrayIncompatible1() {
+        shouldFailWithMessages '''
+            String[] src = ['a','b','c']
+            (Set[]) src
+        ''',
+        'Inconvertible types: cannot cast java.lang.String[] to java.util.Set[]'
+    }
+
+    void testCastArrayIncompatible2() {
+        shouldFailWithMessages '''
+            (Set[]) ['a','b','c'].toArray(new String[3])
+        ''',
+        'Inconvertible types: cannot cast java.lang.String[] to java.util.Set[]'
+    }
+
+    void testCastArrayIncompatible3() {
+        shouldFailWithMessages '''
+            (Set[]) ['a','b','c'].toArray(String[]::new)
+        ''',
+        'Inconvertible types: cannot cast java.lang.String[] to java.util.Set[]'
+    }
+
+    void testCastObjectToSubclass() {
+        assertScript '''
+            Object o = null
+            ((Integer) o)?.intValue()
+        '''
+    }
+
+    void testCastInterfaceToSubclass() {
+        assertScript '''
+            interface A {
+            }
+            interface B extends A {
+            }
+            class C implements B {
+            }
+            def m(B b) {
+                C c = (C) b
+            }
+        '''
+    }
+
+    void testCastInterfaceToSubclass2() {
+        shouldFailWithMessages '''
+            interface I {
+            }
+            interface B extends I {
+            }
+            final class C implements I {
+            }
+            def m(B b) {
+                C c = (C) b
+            }
+        ''',
+        'Inconvertible types: cannot cast B to C'
+    }
+
+    //--------------------------------------------------------------------------
+
     void testCoerceToArray() {
         assertScript '''
             try {
@@ -137,6 +310,14 @@ class CoercionSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    void testCoerceIncompatibleType() {
+        // If the user uses explicit type coercion, there's nothing we can do
+        assertScript '''
+            String s = 'Hello'
+            s as Set
+        '''
+    }
+
     void testCoerceToFunctionalInterface1() {
         String sam = '@FunctionalInterface interface SAM { def foo() }'
 
diff --git a/src/test/groovy/transform/stc/STCAssignmentTest.groovy b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
index bfa56abf3c..46d8ab239d 100644
--- a/src/test/groovy/transform/stc/STCAssignmentTest.groovy
+++ b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
@@ -25,21 +25,21 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
 
     void testAssignmentFailure1() {
         shouldFailWithMessages '''
-            int x = new Object()
+            int i = new Object()
         ''',
         'Cannot assign value of type java.lang.Object to variable of type int'
     }
 
     void testAssignmentFailure2() {
         shouldFailWithMessages '''
-            Set set = new Object()
+            Set s = new Object()
         ''',
         'Cannot assign value of type java.lang.Object to variable of type java.util.Set'
     }
 
     void testAssignmentFailure3() {
         shouldFailWithMessages '''
-            Set set = new Integer(2)
+            Set s = new Integer(2)
         ''',
         'Cannot assign value of type java.lang.Integer to variable of type java.util.Set'
     }
@@ -47,7 +47,7 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
     void testAssignmentFailure4() {
         shouldFailWithMessages '''
             def o = new Object()
-            int x = o
+            int i = o
         ''',
         'Cannot assign value of type java.lang.Object to variable of type int'
     }
@@ -55,15 +55,15 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
     void testAssignmentFailure5() {
         shouldFailWithMessages '''
             def o = new Object()
-            Set set = o
+            Set s = o
         ''',
         'Cannot assign value of type java.lang.Object to variable of type java.util.Set'
     }
 
     void testAssignmentFailure6() {
         shouldFailWithMessages '''
-            int x = 2
-            Set set = x
+            int i = 2
+            Set s = i
         ''',
         'Cannot assign value of type int to variable of type java.util.Set'
     }
@@ -95,28 +95,56 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         'Cannot assign value of type int to variable of type MyEnum'
     }
 
+    void testAssignmentToArray() {
+        assertScript '''
+            String[] src = ['a','b','c']
+            Object[] arr = src
+        '''
+        assertScript '''
+            def a  = 1
+            Integer[] b = [a]
+        '''
+        assertScript '''
+            def a = new int[5]
+            int[][] b = [a]
+        '''
+    }
+
     void testAssignmentToClass() {
         assertScript '''
-            Class test = 'java.lang.String'
+            Class c = 'java.lang.String'
         '''
     }
 
     void testAssignmentToString() {
         assertScript '''
-            String str = new Object()
+            String s = new Object()
         '''
     }
 
     void testAssignmentToBoolean() {
         assertScript '''
-            boolean test = new Object()
+            boolean b = new Object()
+            assert b === true
+        '''
+    }
+
+    void testAssignmentToBoolean2() {
+        assertScript '''
+            Boolean b = new Object()
+            assert b == Boolean.TRUE
         '''
     }
 
-    void testAssignmentToBooleanClass() {
+    void testAssignmentToInterface() {
         assertScript '''
-            Boolean test = new Object()
+            Comparable<String> x = 'x'
+            CharSequence y = 'y'
         '''
+        shouldFailWithMessages '''
+            Collection z = 'z'
+        ''',
+        'Cannot assign value of type java.lang.String to variable of type java.util.Collection'
     }
 
     // GROOVY-10744
@@ -139,6 +167,135 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-6577
+    void testAssignNullToBoolean() {
+        assertScript '''
+            boolean b = null
+            assert b === false
+        '''
+    }
+
+    // GROOVY-11371
+    void testAssignNullToPrimitive() {
+        for (type in ['byte','char','double','float','int','long','short']) {
+            shouldFailWithMessages """
+                $type v = null
+            """,
+            "Cannot assign value of type java.lang.Object to variable of type $type"
+        }
+    }
+
+    void testAssignNullToCharacter() {
+        assertScript '''
+            Character c = null
+            assert  c === null
+        '''
+    }
+
+    void testAssignStringToChar() {
+        assertScript '''
+            char c = 'a'
+            assert c === "a".charAt(0)
+        '''
+    }
+
+    void testAssignStringToCharacter() {
+        assertScript '''
+            Character c = 'a'
+            assert c instanceof Character
+            assert c == Character.valueOf("a".charAt(0))
+        '''
+    }
+
+    void testAssignStringLongerThan1CharToChar() {
+        shouldFailWithMessages '''
+            char c = 'aa'
+        ''',
+        'Cannot assign value of type java.lang.String to variable of type char'
+    }
+
+    void testAssignStringLongerThan1CharToCharacter() {
+        shouldFailWithMessages '''
+            Character c = 'aa'
+        ''',
+        'Cannot assign value of type java.lang.String to variable of type java.lang.Character'
+    }
+
+    void testPossibleLossOfPrecision1() {
+        shouldFailWithMessages '''
+            long a = Long.MAX_VALUE
+            int b = a
+        ''',
+        'Possible loss of precision from long to int'
+    }
+
+    void testPossibleLossOfPrecision2() {
+        assertScript '''
+            int b = 0L
+        '''
+    }
+
+    void testPossibleLossOfPrecision3() {
+        assertScript '''
+            byte b = 127
+        '''
+    }
+
+    void testPossibleLossOfPrecision4() {
+        shouldFailWithMessages '''
+            byte b = 128 // will not fit in a byte
+        ''',
+        'Possible loss of precision from int to byte'
+    }
+
+    void testPossibleLossOfPrecision5() {
+        assertScript '''
+            short b = 128
+        '''
+    }
+
+    void testPossibleLossOfPrecision6() {
+        shouldFailWithMessages '''
+            short b = 32768 // will not fit in a short
+        ''',
+        'Possible loss of precision from int to short'
+    }
+
+    void testPossibleLossOfPrecision7() {
+        assertScript '''
+            int b = 32768L // mark it as a long, but it fits into an int
+        '''
+    }
+
+    void testPossibleLossOfPrecision8() {
+        assertScript '''
+            int b = 32768.0f // mark it as a float, but it fits into an int
+        '''
+    }
+
+    void testPossibleLossOfPrecision9() {
+        assertScript '''
+            int b = 32768.0d // mark it as a double, but it fits into an int
+        '''
+    }
+
+    void testPossibleLossOfPrecision10() {
+        shouldFailWithMessages '''
+            int b = 32768.1d
+        ''',
+        'Possible loss of precision from double to int'
+    }
+
+    //--------------------------------------------------------------------------
+
+    void testArrayLength() {
+        assertScript '''
+            String[] arr = [1,2,3]
+            int len = arr.length
+            assert len == 3
+        '''
+    }
+
     void testPlusEqualsOnInt() {
         assertScript '''
             int i = 0
@@ -252,487 +409,89 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testPossibleLossOfPrecision1() {
+    void testTernaryOperatorAssignmentShouldFailBecauseOfIncompatibleGenericTypes() {
         shouldFailWithMessages '''
-            long a = Long.MAX_VALUE
-            int b = a
+            List<Integer> foo = true ? new LinkedList<String>() : new LinkedList<Integer>()
         ''',
-        'Possible loss of precision from long to int'
-    }
-
-    void testPossibleLossOfPrecision2() {
-        assertScript '''
-            int b = 0L
-        '''
-    }
-
-    void testPossibleLossOfPrecision3() {
-        assertScript '''
-            byte b = 127
-        '''
+        'Incompatible generic argument types. Cannot assign java.util.LinkedList<? extends java.io.Serializable & java.lang.Comparable','> to: java.util.List<java.lang.Integer>'
     }
 
-    void testPossibleLossOfPrecision4() {
+    void testIfElseBranch() {
         shouldFailWithMessages '''
-            byte b = 128 // will not fit in a byte
+            def x
+            def y = 'foo'
+            if (y) {
+                x = new HashSet()
+            } else {
+                x = '123'
+            }
+            x.toInteger()
         ''',
-        'Possible loss of precision from int to byte'
-    }
-
-    void testPossibleLossOfPrecision5() {
-        assertScript '''
-            short b = 128
-        '''
+        'Cannot find matching method java.io.Serializable#toInteger()'
     }
 
-    void testPossibleLossOfPrecision6() {
+    void testIfElseBranchParameter() {
         shouldFailWithMessages '''
-            short b = 32768 // will not fit in a short
+            def foo(x) {
+                def y = 'foo'
+                if (y) {
+                    x = new HashSet()
+                } else {
+                    x = '123'
+                }
+                x.toInteger()
+            }
+            foo('bar')
         ''',
-        'Possible loss of precision from int to short'
-    }
-
-    void testPossibleLossOfPrecision7() {
-        assertScript '''
-            int b = 32768L // mark it as a long, but it fits into an int
-        '''
-    }
-
-    void testPossibleLossOfPrecision8() {
-        assertScript '''
-            int b = 32768.0f // mark it as a float, but it fits into an int
-        '''
-    }
-
-    void testPossibleLossOfPrecision9() {
-        assertScript '''
-            int b = 32768.0d // mark it as a double, but it fits into an int
-        '''
+        'Cannot find matching method java.lang.Object#toInteger()'
     }
 
-    void testPossibleLossOfPrecision10() {
+    void testIfOnly() {
         shouldFailWithMessages '''
-            int b = 32768.1d
+            def x = '123'
+            def y = 'foo'
+            if (y) {
+                x = new HashSet()
+            }
+            x.toInteger()
         ''',
-        'Possible loss of precision from double to int'
-    }
-
-    void testCastIntToShort() {
-        assertScript '''
-            short s = (short) 0
-        '''
-    }
-
-    void testCastIntToFloat() {
-        assertScript '''
-            float f = (float) 1
-        '''
-    }
-
-    void testCompatibleTypeCast() {
-        assertScript '''
-            String s = 'Hello'
-            ((CharSequence) s)
-        '''
+        'Cannot find matching method java.io.Serializable#toInteger()'
     }
 
-    void testIncompatibleTypeCast() {
+    void testIfOnlyParameter() {
         shouldFailWithMessages '''
-            String s = 'Hello'
-            ((Set) s)
+            def foo(x) {
+                def y = 'foo'
+                if (y) {
+                    x = new HashSet()
+                    assert x.isEmpty()
+                }
+                x.toInteger()
+            }
+            foo('123')
         ''',
-        'Inconvertible types: cannot cast java.lang.String to java.util.Set'
+        'Cannot find matching method java.lang.Object#toInteger()'
     }
 
-    void testIncompatibleTypeCastWithAsType() {
-        // If the user uses explicit type coercion, there's nothing we can do
+    void testIfWithCommonInterface() {
         assertScript '''
-            String s = 'Hello'
-            s as Set
-        '''
-    }
+            interface I {
+                def m()
+            }
+            class A implements I {
+                def m() { 'A' }
+            }
+            class B implements I {
+                def m() { 'B' }
+            }
 
-    void testIncompatibleTypeCastWithTypeInference() {
-        shouldFailWithMessages '''
-            def s = 'Hello'
-            s = 1
-            ((Set) s)
-        ''',
-        'Inconvertible types: cannot cast java.lang.Integer to java.util.Set'
-    }
-
-    void testArrayLength() {
-        assertScript '''
-            String[] arr = [1,2,3]
-            int len = arr.length
-        '''
-    }
-
-    void testMultipleAssignment1() {
-        assertScript '''
-            def (x,y) = [1,2]
-            assert x == 1
-            assert y == 2
-        '''
-    }
-
-    void testMultipleAssignmentWithExplicitTypes() {
-        assertScript '''
-            int x
-            int y
-            (x,y) = [1,2]
-            assert x == 1
-            assert y == 2
-        '''
-    }
-
-    void testMultipleAssignmentWithIncompatibleTypes() {
-        shouldFailWithMessages '''
-            List x
-            List y
-            (x,y) = [1,2]
-        ''',
-        'Cannot assign value of type int to variable of type java.util.List'
-    }
-
-    void testMultipleAssignmentWithoutEnoughArgs() {
-        shouldFailWithMessages '''
-            int x
-            int y
-            (x,y) = [1]
-        ''',
-        'Incorrect number of values. Expected:2 Was:1'
-    }
-
-    void testMultipleAssignmentTooManyArgs() {
-        assertScript '''
-            int x
-            int y
-            (x,y) = [1,2,3]
-            assert x == 1
-            assert y == 2
-        '''
-    }
-
-    void testMultipleAssignmentFromVariable() {
-        shouldFailWithMessages '''
-            def list = [1,2,3]
-            def (x,y) = list
-        ''',
-        'Multiple assignments without list or tuple on the right-hand side are unsupported in static type checking mode'
-    }
-
-    // GROOVY-8223, GROOVY-8887, GROOVY-10063
-    void testMultipleAssignmentFromTupleTypes() {
-        assertScript '''
-            def (String string) = Tuple.tuple('answer')
-            assert string == 'answer'
-        '''
-
-        assertScript '''
-            def (String string, Integer number) = Tuple.tuple('answer', 42)
-            assert string == 'answer'
-            assert number == 42
-        '''
-
-        shouldFailWithMessages '''
-            def (String string, Integer number) = Tuple.tuple('answer', '42')
-        ''',
-        'Cannot assign value of type java.lang.String to variable of type java.lang.Integer'
-
-        assertScript '''
-            def (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p) = Tuple.tuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
-            assert a == 1
-            assert b == 2
-            assert c == 3
-            assert d == 4
-            assert e == 5
-            assert f == 6
-            assert g == 7
-            assert h == 8
-            assert i == 9
-            assert j == 10
-            assert k == 11
-            assert l == 12
-            assert m == 13
-            assert n == 14
-            assert o == 15
-            assert p == 16
-        '''
-
-        assertScript '''
-            def (String string, Integer number) = new Tuple2<String, Integer>('answer', 42)
-            assert string == 'answer'
-            assert number == 42
-        '''
-
-        assertScript '''
-            Tuple2<String, Integer> m() {
-                new Tuple2<>('answer', 42)
-            }
-
-            def (String string, Integer number) = m()
-            assert string == 'answer'
-            assert number == 42
-        '''
-
-        assertScript '''
-            Tuple2<String, Integer> m() {
-                new Tuple2<>('answer', 42)
-            }
-
-            def tuple = m()
-            def (String string, Integer number) = tuple
-            assert string == 'answer'
-            assert number == 42
-        '''
-
-        assertScript '''
-            static Tuple2<String, Integer> m() {
-                new Tuple2<>('answer', 42)
-            }
-
-            def (String string, Integer number) = m()
-            assert string == 'answer'
-            assert number == 42
-        '''
-
-        assertScript '''
-            class C {
-                static Tuple2<String, Integer> m() {
-                    new Tuple2<>('answer', 42)
-                }
-            }
-
-            def (String string, Integer number) = C.m()
-            assert string == 'answer'
-            assert number == 42
-        '''
-
-        assertScript '''
-            class C {
-                Tuple2<String, Integer> getM() {
-                    new Tuple2<>('answer', 42)
-                }
-            }
-
-            def (String string, Integer number) = new C().m
-            assert string == 'answer'
-            assert number == 42
-        '''
-    }
-
-    void testAssignmentToInterface() {
-        assertScript '''
-            Comparable<String> x = 'x'
-            CharSequence y = 'y'
-        '''
-        shouldFailWithMessages '''
-            Collection z = 'z'
-        ''',
-        'Cannot assign value of type java.lang.String to variable of type java.util.Collection'
-    }
-
-    void testTernaryOperatorAssignmentShouldFailBecauseOfIncompatibleGenericTypes() {
-        shouldFailWithMessages '''
-            List<Integer> foo = true ? new LinkedList<String>() : new LinkedList<Integer>()
-        ''',
-        'Incompatible generic argument types. Cannot assign java.util.LinkedList<? extends java.io.Serializable & java.lang.Comparable','> to: java.util.List<java.lang.Integer>'
-    }
-
-    void testCastStringToChar() {
-        assertScript '''
-            char c = 'a'
-        '''
-    }
-
-    void testCastStringLongerThan1CharToChar() {
-        shouldFailWithMessages '''
-            char c = 'aa'
-        ''',
-        'Cannot assign value of type java.lang.String to variable of type char'
-    }
-
-    void testCastNullToChar() {
-        shouldFailWithMessages '''
-            char c = null
-        ''',
-        'Cannot assign value of type java.lang.Object to variable of type char'
-    }
-
-    // GROOVY-6577
-    void testCastNullToBoolean() {
-        assertScript '''
-            boolean c = null
-            assert c == false
-        '''
-    }
-
-    // GROOVY-6577
-    void testCastNullToBooleanWithExplicitCast() {
-        assertScript '''
-            boolean c = (boolean) null
-            assert c == false
-        '''
-    }
-
-    void testCastStringToCharacter() {
-        assertScript '''
-            Character c = 'a'
-        '''
-    }
-
-    void testCastStringLongerThan1CharToCharacter() {
-        shouldFailWithMessages '''
-            Character c = 'aa'
-        ''',
-        'Cannot assign value of type java.lang.String to variable of type java.lang.Character'
-    }
-
-    void testAssignNullToCharacter() {
-        assertScript '''
-            Character c = null
-        '''
-    }
-
-    void testCastStringToCharWithCast() {
-        assertScript '''
-            def c = (char) 'a'
-        '''
-    }
-
-    void testCastCharToByte() {
-        assertScript '''
-            void foo(char c) {
-                byte b = (byte) c
-            }
-        '''
-    }
-
-    void testCastCharToInt() {
-        assertScript '''
-            void foo(char c) {
-                int b = (int) c
-            }
-        '''
-    }
-
-    void testCastStringLongerThan1ToCharWithCast() {
-        shouldFailWithMessages '''
-            def c = (char) 'aa'
-        ''',
-        'Inconvertible types: cannot cast java.lang.String to char'
-    }
-
-    void testCastNullToCharWithCast() {
-        shouldFailWithMessages '''
-            def c = (char) null
-        ''',
-        'Inconvertible types: cannot cast java.lang.Object to char'
-    }
-
-    void testCastStringToCharacterWithCast() {
-        assertScript '''
-            def c = (Character) 'a'
-        '''
-    }
-
-    void testCastStringLongerThan1ToCharacterWithCast() {
-        shouldFailWithMessages '''
-            def c = (Character) 'aa'
-        ''',
-        'Inconvertible types: cannot cast java.lang.String to java.lang.Character'
-    }
-
-    void testCastNullToCharacterWithCast() {
-        assertScript '''
-            def c = (Character) null
-        '''
-    }
-
-    void testCastObjectToSubclass() {
-        assertScript '''
-            Object o = null
-            ((Integer) o)?.intValue()
-        '''
-    }
-
-    void testIfElseBranch() {
-        shouldFailWithMessages '''
-            def x
-            def y = 'foo'
-            if (y) {
-                x = new HashSet()
-            } else {
-                x = '123'
-            }
-            x.toInteger()
-        ''',
-        'Cannot find matching method java.io.Serializable#toInteger()'
-    }
-
-    void testIfElseBranchParameter() {
-        shouldFailWithMessages '''
-            def foo(x) {
-                def y = 'foo'
-                if (y) {
-                    x = new HashSet()
-                } else {
-                    x = '123'
-                }
-                x.toInteger()
-            }
-            foo('bar')
-        ''',
-        'Cannot find matching method java.lang.Object#toInteger()'
-    }
-
-    void testIfOnly() {
-        shouldFailWithMessages '''
-            def x = '123'
-            def y = 'foo'
-            if (y) {
-                x = new HashSet()
-            }
-            x.toInteger()
-        ''',
-        'Cannot find matching method java.io.Serializable#toInteger()'
-    }
-
-    void testIfOnlyParameter() {
-        shouldFailWithMessages '''
-            def foo(x) {
-                def y = 'foo'
-                if (y) {
-                    x = new HashSet()
-                    assert x.isEmpty()
-                }
-                x.toInteger()
-            }
-            foo('123')
-        ''',
-        'Cannot find matching method java.lang.Object#toInteger()'
-    }
-
-    void testIfWithCommonInterface() {
-        assertScript '''
-            interface I {
-                def m()
-            }
-            class A implements I {
-                def m() { 'A' }
-            }
-            class B implements I {
-                def m() { 'B' }
-            }
-
-            def x = new A()
-            def y = true
-            if (y) {
-                x = new B()
-            }
-            assert x.m() == 'B'
-        '''
+            def x = new A()
+            def y = true
+            if (y) {
+                x = new B()
+            }
+            assert x.m() == 'B'
+        '''
     }
 
     // GROOVY-5502
@@ -989,7 +748,7 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    //GROOVY-6435
+    // GROOVY-6435
     void testBigDecAndBigIntSubclass() {
         assertScript '''
             class MyDecimal extends BigDecimal {
@@ -1095,35 +854,6 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         'Cannot find matching method java.lang.Object#previous()'
     }
 
-    void testAssignArray() {
-        assertScript '''
-            String[] src = ['a','b','c']
-            Object[] arr = src
-        '''
-    }
-
-    void testCastArray() {
-        assertScript '''
-            List<String> src = ['a','b','c']
-            (String[]) src.toArray(src as String[])
-        '''
-    }
-
-    void testIncompatibleCastArray() {
-        shouldFailWithMessages '''
-            String[] src = ['a','b','c']
-            (Set[]) src
-        ''',
-        'Inconvertible types: cannot cast java.lang.String[] to java.util.Set[]'
-    }
-
-    void testIncompatibleToArray() {
-        shouldFailWithMessages '''
-            (Set[]) ['a','b','c'].toArray(new String[3])
-        ''',
-        'Inconvertible types: cannot cast java.lang.String[] to java.util.Set[]'
-    }
-
     // GROOVY-5535, GROOVY-10623
     void testAssignToNullInsideIf() {
         ['Date', 'def', 'var'].each {
@@ -1156,101 +886,335 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    // GROOVY-10308
-    void testAssignToNullAfterCall() {
+    // GROOVY-10308
+    void testAssignToNullAfterCall() {
+        assertScript '''
+            class C<T> {
+                T p
+            }
+            def x = { -> new C<String>() }
+            def y = x()
+            def z = y.p // false positive: field access error
+            y = null
+        '''
+    }
+
+    // GROOVY-10623
+    void testAssignToNullAfterInit() {
+        assertScript '''
+            class C {
+            }
+            def x = new C()
+            x = null
+            C c = x
+        '''
+    }
+
+    // GROOVY-5798
+    void testShouldNotThrowConversionError() {
+        assertScript '''
+            char m( int v ) {
+              char c = (char)v
+              c
+            }
+
+            println m( 65 )
+        '''
+    }
+
+    // GROOVY-6575
+    void testAssignmentOfObjectToArrayShouldFail() {
+        shouldFailWithMessages '''
+            Object o
+            int[] array = o
+        ''',
+        'Cannot assign value of type java.lang.Object to variable of type int[]'
+    }
+
+    // GROOVY-7015
+    void testAssingmentToSuperclassFieldWithDifferingGenerics() {
+        assertScript '''
+            class Base {}
+            class Derived extends Base {
+                public String sayHello() { 'hello' }
+            }
+
+            class GBase<T extends Base> {
+                T myVar;
+            }
+            class GDerived extends GBase<Derived> {
+                GDerived() { myVar = new Derived(); }
+                public String method() {myVar.sayHello()}
+            }
+
+            GDerived d = new GDerived();
+            assert d.method() == 'hello'
+        '''
+    }
+
+    // GROOVY-8157
+    void testFlowTypingAfterParameterAssignment() {
+        assertScript '''
+            class A {}
+            class B extends A { def bbb() { 42 } }
+
+            def fooParameterAssignment(A a) {
+                a = new B()
+                a.bbb()
+            }
+            assert fooParameterAssignment(null) == 42
+        '''
+    }
+
+    // GROOVY-8220
+    void testFlowTypingParameterTempTypeAssignmentTracking1() {
+        assertScript '''
+            class Foo {
+                CharSequence makeEnv( env, StringBuilder result = new StringBuilder() ) {
+                    if (env instanceof File) {
+                        env = env.toPath()
+                    }
+                    if (env instanceof String && env.contains('=')) {
+                        result << 'export ' << env << ';'
+                    }
+                    return result.toString()
+                }
+            }
+            assert new Foo().makeEnv('X=1') == 'export X=1;'
+        '''
+    }
+
+    // GROOVY-8237
+    void testFlowTypingParameterTempTypeAssignmentTracking2() {
+        assertScript '''
+            class Foo {
+                String parse(Reader reader) {
+                    if (reader == null)
+                        reader = new BufferedReader(reader)
+                    int i = reader.read()
+                    return (i != -1) ? 'bar' : 'baz'
+                }
+            }
+            assert new Foo().parse(new StringReader('foo')) == 'bar'
+        '''
+    }
+
+    void testFlowTypingParameterTempTypeAssignmentTracking3() {
+        assertScript '''
+            class M {
+                Map<String, List<Object>> mvm = new HashMap<String, List<Object>>()
+                void setProperty(String name, value) {
+                    if (value instanceof File) {
+                        value = new File(value, 'bar.txt')
+                    } else if (value instanceof URL) {
+                        value = value.toURI()
+                    } else if (value instanceof InputStream) {
+                        value = new BufferedInputStream(value)
+                    } else if (value instanceof GString) {
+                        value = value.toString()
+                    }
+                    mvm.computeIfAbsent(name, k -> [] as List<Object>).add(value)
+                }
+            }
+            new M().setProperty('foo', 'bar')
+        '''
+    }
+
+    //--------------------------------------------------------------------------
+
+    // GROOVY-10419
+    void testElvisAssignmentAndSetter1() {
+        assertScript '''
+            class C {
+                def p
+                void setP(p) {
+                    this.p = p
+                }
+            }
+            def c = new C()
+            c.p ?= 'x'
+            assert c.p == 'x'
+            c.with {
+                p ?= 'y'
+            }
+            assert c.p == 'x'
+        '''
+    }
+
+    // GROOVY-10628
+    void testElvisAssignmentAndSetter2() {
+        assertScript '''
+            class C {
+                String getFoo() {
+                }
+                void setFoo(String foo) {
+                }
+            }
+            new C().foo ?= 'bar'
+        '''
+    }
+
+    void testElvisAssignmentMismatched() {
+        shouldFailWithMessages '''
+            class C {
+                Number foo
+            }
+            new C().foo ?= 'bar'
+        ''',
+        'Cannot assign value of type java.io.Serializable to variable of type java.lang.Number'
+    }
+
+    void testMultipleAssignment1() {
+        assertScript '''
+            def (x,y) = [1,2]
+            assert x == 1
+            assert y == 2
+        '''
+    }
+
+    void testMultipleAssignmentWithExplicitTypes() {
+        assertScript '''
+            int x
+            int y
+            (x,y) = [1,2]
+            assert x == 1
+            assert y == 2
+        '''
+    }
+
+    void testMultipleAssignmentWithIncompatibleTypes() {
+        shouldFailWithMessages '''
+            List x
+            List y
+            (x,y) = [1,2]
+        ''',
+        'Cannot assign value of type int to variable of type java.util.List'
+    }
+
+    void testMultipleAssignmentWithoutEnoughArgs() {
+        shouldFailWithMessages '''
+            int x
+            int y
+            (x,y) = [1]
+        ''',
+        'Incorrect number of values. Expected:2 Was:1'
+    }
+
+    void testMultipleAssignmentTooManyArgs() {
         assertScript '''
-            class C<T> {
-                T p
-            }
-            def x = { -> new C<String>() }
-            def y = x()
-            def z = y.p // false positive: field access error
-            y = null
+            int x
+            int y
+            (x,y) = [1,2,3]
+            assert x == 1
+            assert y == 2
         '''
     }
 
-    // GROOVY-10623
-    void testAssignToNullAfterInit() {
-        assertScript '''
-            class C {
-            }
-            def x = new C()
-            x = null
-            C c = x
-        '''
+    void testMultipleAssignmentFromVariable() {
+        shouldFailWithMessages '''
+            def list = [1,2,3]
+            def (x,y) = list
+        ''',
+        'Multiple assignments without list or tuple on the right-hand side are unsupported in static type checking mode'
     }
 
-    // GROOVY-5798
-    void testShouldNotThrowConversionError() {
+    // GROOVY-8223, GROOVY-8887, GROOVY-10063
+    void testMultipleAssignmentFromTupleTypes() {
         assertScript '''
-            char m( int v ) {
-              char c = (char)v
-              c
-            }
+            def (String string) = Tuple.tuple('answer')
+            assert string == 'answer'
+        '''
 
-            println m( 65 )
+        assertScript '''
+            def (String string, Integer number) = Tuple.tuple('answer', 42)
+            assert string == 'answer'
+            assert number == 42
         '''
-    }
 
-    // GROOVY-6575
-    void testAssignmentOfObjectToArrayShouldFail() {
         shouldFailWithMessages '''
-            Object o
-            int[] array = o
+            def (String string, Integer number) = Tuple.tuple('answer', '42')
         ''',
-        'Cannot assign value of type java.lang.Object to variable of type int[]'
-    }
+        'Cannot assign value of type java.lang.String to variable of type java.lang.Integer'
 
-    // GROOVY-7015
-    void testAssingmentToSuperclassFieldWithDifferingGenerics() {
         assertScript '''
-            class Base {}
-            class Derived extends Base {
-                public String sayHello() { 'hello' }
-            }
+            def (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p) = Tuple.tuple(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
+            assert a == 1
+            assert b == 2
+            assert c == 3
+            assert d == 4
+            assert e == 5
+            assert f == 6
+            assert g == 7
+            assert h == 8
+            assert i == 9
+            assert j == 10
+            assert k == 11
+            assert l == 12
+            assert m == 13
+            assert n == 14
+            assert o == 15
+            assert p == 16
+        '''
 
-            class GBase<T extends Base> {
-                T myVar;
-            }
-            class GDerived extends GBase<Derived> {
-                GDerived() { myVar = new Derived(); }
-                public String method() {myVar.sayHello()}
+        assertScript '''
+            def (String string, Integer number) = new Tuple2<String, Integer>('answer', 42)
+            assert string == 'answer'
+            assert number == 42
+        '''
+
+        assertScript '''
+            Tuple2<String, Integer> m() {
+                new Tuple2<>('answer', 42)
             }
 
-            GDerived d = new GDerived();
-            assert d.method() == 'hello'
+            def (String string, Integer number) = m()
+            assert string == 'answer'
+            assert number == 42
         '''
-    }
 
-    //GROOVY-8157
-    void testFlowTypingAfterParameterAssignment() {
         assertScript '''
-            class A {}
-            class B extends A { def bbb() { 42 } }
+            Tuple2<String, Integer> m() {
+                new Tuple2<>('answer', 42)
+            }
 
-            def fooParameterAssignment(A a) {
-                a = new B()
-                a.bbb()
+            def tuple = m()
+            def (String string, Integer number) = tuple
+            assert string == 'answer'
+            assert number == 42
+        '''
+
+        assertScript '''
+            static Tuple2<String, Integer> m() {
+                new Tuple2<>('answer', 42)
             }
-            assert fooParameterAssignment(null) == 42
+
+            def (String string, Integer number) = m()
+            assert string == 'answer'
+            assert number == 42
         '''
-    }
 
-    void testIntegerArraySmartType() {
         assertScript '''
-            def m() {
-                def a  = 1
-                Integer[] b = [a]
+            class C {
+                static Tuple2<String, Integer> m() {
+                    new Tuple2<>('answer', 42)
+                }
             }
+
+            def (String string, Integer number) = C.m()
+            assert string == 'answer'
+            assert number == 42
         '''
-    }
 
-    void testIntegerSecondDimArraySmartType() {
         assertScript '''
-            def m() {
-                def a = new int[5]
-                int[][] b = [a]
+            class C {
+                Tuple2<String, Integer> getM() {
+                    new Tuple2<>('answer', 42)
+                }
             }
+
+            def (String string, Integer number) = new C().m
+            assert string == 'answer'
+            assert number == 42
         '''
     }
 
@@ -1279,24 +1243,6 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    // GROOVY-8220
-    void testFlowTypingParameterTempTypeAssignmentTracking1() {
-        assertScript '''
-            class Foo {
-                CharSequence makeEnv( env, StringBuilder result = new StringBuilder() ) {
-                    if (env instanceof File) {
-                        env = env.toPath()
-                    }
-                    if (env instanceof String && env.contains('=')) {
-                        result << 'export ' << env << ';'
-                    }
-                    return result.toString()
-                }
-            }
-            assert new Foo().makeEnv('X=1') == 'export X=1;'
-        '''
-    }
-
     // GROOVY-10943
     void testMultiAssignUnderscorePlaceholder1() {
         assertScript '''
@@ -1318,7 +1264,7 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
 
             m()
         ''',
-            'The variable [_] is undeclared'
+        'The variable [_] is undeclared'
     }
 
     // GROOVY-10943
@@ -1330,7 +1276,7 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
 
             m()
         ''',
-            'The variable [_] is undeclared'
+        'The variable [_] is undeclared'
     }
 
     // GROOVY-10943
@@ -1342,113 +1288,6 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
 
             m()
         ''',
-            'The variable [_] is undeclared'
-    }
-
-    // GROOVY-8237
-    void testFlowTypingParameterTempTypeAssignmentTracking2() {
-        assertScript '''
-            class Foo {
-                String parse(Reader reader) {
-                    if (reader == null)
-                        reader = new BufferedReader(reader)
-                    int i = reader.read()
-                    return (i != -1) ? 'bar' : 'baz'
-                }
-            }
-            assert new Foo().parse(new StringReader('foo')) == 'bar'
-        '''
-    }
-
-    void testFlowTypingParameterTempTypeAssignmentTracking3() {
-        assertScript '''
-            class M {
-                Map<String, List<Object>> mvm = new HashMap<String, List<Object>>()
-                void setProperty(String name, value) {
-                    if (value instanceof File) {
-                        value = new File(value, 'bar.txt')
-                    } else if (value instanceof URL) {
-                        value = value.toURI()
-                    } else if (value instanceof InputStream) {
-                        value = new BufferedInputStream(value)
-                    } else if (value instanceof GString) {
-                        value = value.toString()
-                    }
-                    mvm.computeIfAbsent(name, k -> [] as List<Object>).add(value)
-                }
-            }
-            new M().setProperty('foo', 'bar')
-        '''
-    }
-
-    void testNarrowingConversion() {
-        assertScript '''
-            interface A {
-            }
-            interface B extends A {
-            }
-            class C implements B {
-            }
-            def m(B b) {
-                C c = (C) b
-            }
-        '''
-    }
-
-    void testFinalNarrowingConversion() {
-        shouldFailWithMessages '''
-            interface I {
-            }
-            interface B extends I {
-            }
-            final class C implements I {
-            }
-            def m(B b) {
-                C c = (C) b
-            }
-        ''',
-        'Inconvertible types: cannot cast B to C'
-    }
-
-    // GROOVY-10419
-    void testElvisAssignmentAndSetter1() {
-        assertScript '''
-            class C {
-                def p
-                void setP(p) {
-                    this.p = p
-                }
-            }
-            def c = new C()
-            c.p ?= 'x'
-            assert c.p == 'x'
-            c.with {
-                p ?= 'y'
-            }
-            assert c.p == 'x'
-        '''
-    }
-
-    // GROOVY-10628
-    void testElvisAssignmentAndSetter2() {
-        assertScript '''
-            class C {
-                String getFoo() {
-                }
-                void setFoo(String foo) {
-                }
-            }
-            new C().foo ?= 'bar'
-        '''
-    }
-
-    void testElvisAssignmentMismatched() {
-        shouldFailWithMessages '''
-            class C {
-                Number foo
-            }
-            new C().foo ?= 'bar'
-        ''',
-        'Cannot assign value of type java.io.Serializable to variable of type java.lang.Number'
+        'The variable [_] is undeclared'
     }
 }