You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/03/14 06:34:12 UTC

[groovy] 02/05: GROOVY-9455: !(x instanceof T) shouldn't propagate T as inferred type

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

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 43ddb282848c0fb741320f28049c44ae0036da8f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Mar 10 11:39:24 2020 -0500

    GROOVY-9455: !(x instanceof T) shouldn't propagate T as inferred type
    
    (cherry picked from commit d5e217aa6fa17b5b015a9f7120ba77817ddbb127)
---
 .../transform/stc/StaticTypeCheckingVisitor.java   |   8 ++
 src/test/groovy/bugs/Groovy8523Bug.groovy          | 143 ---------------------
 .../transform/stc/TypeInferenceSTCTest.groovy      | 133 +++++++++++++++++++
 3 files changed, 141 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 ca9f616..7160016 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -723,6 +723,14 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
     }
 
     @Override
+    public void visitNotExpression(final NotExpression expression) {
+        // GROOVY-9455: !(x instanceof T) shouldn't propagate T as inferred type
+        typeCheckingContext.pushTemporaryTypeInfo();
+        super.visitNotExpression(expression);
+        typeCheckingContext.popTemporaryTypeInfo();
+    }
+
+    @Override
     public void visitBinaryExpression(final BinaryExpression expression) {
         BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
         typeCheckingContext.pushEnclosingBinaryExpression(expression);
diff --git a/src/test/groovy/bugs/Groovy8523Bug.groovy b/src/test/groovy/bugs/Groovy8523Bug.groovy
deleted file mode 100755
index a0450e4..0000000
--- a/src/test/groovy/bugs/Groovy8523Bug.groovy
+++ /dev/null
@@ -1,143 +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 Groovy8523Bug extends GroovyTestCase {
-    void testInstanceofNot1() {
-        assertScript '''
-        import groovy.transform.CompileStatic
-        @CompileStatic
-        class Test1 {
-            static int checkRes = 0
-
-            static void f1(Object var1) {
-                if (!(var1 instanceof Runnable)){
-                    checkRes = 3
-                    return
-                }
-                f2(var1)
-            }
-
-            static void f2(Runnable var2) {
-                checkRes = 4
-            }
-        }
-
-        Runnable r = {}
-        Test1.f1(r)
-        assert Test1.checkRes == 4
-        Test1.f1(42)
-        assert Test1.checkRes == 3
-        '''
-    }
-
-    void testNotInstanceof1() {
-        assertScript '''
-        import groovy.transform.CompileStatic
-        @CompileStatic
-        class Test1 {
-            static int checkRes = 0
-
-            static void f1(Object var1) {
-                if (var1 !instanceof Runnable){
-                    checkRes = 3
-                    return
-                }
-                f2(var1)
-            }
-
-            static void f2(Runnable var2) {
-                checkRes = 4
-            }
-        }
-
-        Runnable r = {}
-        Test1.f1(r)
-        assert Test1.checkRes == 4
-        Test1.f1(42)
-        assert Test1.checkRes == 3
-        '''
-    }
-
-
-    void testInstanceofNot2() {
-        assertScript '''
-        import groovy.transform.CompileStatic
-        @CompileStatic
-        class Test1 {
-            static int checkRes = 0
-
-            static void f1(Object var1) {
-                if (!(var1 instanceof Runnable)){
-                    checkRes = 3
-                    return
-                }
-                if (!(var1 instanceof List)){
-                    checkRes = 5
-                    return
-                }
-                f2(var1)
-            }
-
-            static void f2(Runnable var2) {
-                checkRes = 4
-            }
-        }
-
-        Runnable r = {}
-        Test1.f1(r)
-        assert Test1.checkRes == 5
-        '''
-    }
-
-
-    void testInstanceofNot3() {
-        assertScript '''
-        import groovy.transform.CompileStatic
-        @CompileStatic
-        class Test1 {
-            static int checkRes = 0
-
-            static void f1(Object var1) {
-                if (!(var1 instanceof Runnable)){
-                    checkRes = 3
-                    return
-                }
-                if (!(var1 instanceof Thread)){
-                    checkRes = 5
-                    return
-                }
-                f2(var1)
-            }
-
-            static void f2(Runnable var2) {
-                checkRes = 4
-            }
-        }
-
-        Runnable r = {}
-        Test1.f1(r)
-        assert Test1.checkRes == 5
-        '''
-    }
-
-
-}
diff --git a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
index 2562166..b928a8c 100644
--- a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
@@ -209,6 +209,139 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-8523
+    void testNotInstanceof1() {
+        assertScript '''
+            class Test1 {
+                static int checkRes = 0
+
+                static void f1(Object var1) {
+                    if (!(var1 instanceof Runnable)){
+                        checkRes = 3
+                        return
+                    }
+                    f2(var1)
+                }
+
+                static void f2(Runnable var2) {
+                    checkRes = 4
+                }
+            }
+
+            Runnable r = {}
+            Test1.f1(r)
+            assert Test1.checkRes == 4
+            Test1.f1(42)
+            assert Test1.checkRes == 3
+        '''
+    }
+
+    // GROOVY-8523
+    void testNotInstanceOf2() {
+        assertScript '''
+            class Test1 {
+                static int checkRes = 0
+
+                static void f1(Object var1) {
+                    if (var1 !instanceof Runnable){
+                        checkRes = 3
+                        return
+                    }
+                    f2(var1)
+                }
+
+                static void f2(Runnable var2) {
+                    checkRes = 4
+                }
+            }
+
+            Runnable r = {}
+            Test1.f1(r)
+            assert Test1.checkRes == 4
+            Test1.f1(42)
+            assert Test1.checkRes == 3
+        '''
+    }
+
+    // GROOVY-8523
+    void testNotInstanceOf3() {
+        assertScript '''
+            class Test1 {
+                static int checkRes = 0
+
+                static void f1(Object var1) {
+                    if (!(var1 instanceof Runnable)){
+                        checkRes = 3
+                        return
+                    }
+                    if (!(var1 instanceof List)){
+                        checkRes = 5
+                        return
+                    }
+                    f2(var1)
+                }
+
+                static void f2(Runnable var2) {
+                    checkRes = 4
+                }
+            }
+
+            Runnable r = {}
+            Test1.f1(r)
+            assert Test1.checkRes == 5
+        '''
+    }
+
+    // GROOVY-8523
+    void testNotInstanceOf4() {
+        assertScript '''
+            class Test1 {
+                static int checkRes = 0
+
+                static void f1(Object var1) {
+                    if (!(var1 instanceof Runnable)){
+                        checkRes = 3
+                        return
+                    }
+                    if (!(var1 instanceof Thread)){
+                        checkRes = 5
+                        return
+                    }
+                    f2(var1)
+                }
+
+                static void f2(Runnable var2) {
+                    checkRes = 4
+                }
+            }
+
+            Runnable r = {}
+            Test1.f1(r)
+            assert Test1.checkRes == 5
+        '''
+    }
+
+    // GROOVY-9455
+    void testNotInstanceOf5() {
+        shouldFailWithMessages '''
+            void test(object) {
+                if (!(object instanceof String)) {
+                    object.toUpperCase()
+                }
+            }
+        ''', 'Cannot find matching method java.lang.Object#toUpperCase()'
+    }
+
+    void testNotInstanceOf6() {
+        shouldFailWithMessages '''
+            void test(object) {
+                if (object !instanceof String) {
+                    object.toUpperCase()
+                }
+            }
+        ''', 'Cannot find matching method java.lang.Object#toUpperCase()'
+    }
+
     void testShouldNotAllowDynamicVariable() {
         shouldFailWithMessages '''
             String name = 'Guillaume'