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 2021/03/07 02:36:41 UTC

[groovy] branch GROOVY_3_0_X updated: GROOVY-9967: makeGroovyObjectGetPropertySite: leverage property owner

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

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


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 486f353  GROOVY-9967: makeGroovyObjectGetPropertySite: leverage property owner
486f353 is described below

commit 486f3533c9ae082b81379a4b3c9eb572b6710ed5
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Mar 5 10:27:07 2021 -0600

    GROOVY-9967: makeGroovyObjectGetPropertySite: leverage property owner
---
 .../classgen/asm/sc/StaticTypesCallSiteWriter.java |  2 +-
 .../transform/stc/TypeInferenceSTCTest.groovy      | 52 +++++++++++++++-
 .../classgen/asm/sc/bugs/Groovy6276Bug.groovy      | 70 ++++++++++------------
 3 files changed, 83 insertions(+), 41 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
index 0789b6a..1c651f5 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
@@ -402,7 +402,7 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
     public void makeGroovyObjectGetPropertySite(final Expression receiver, final String propertyName, final boolean safe, final boolean implicitThis) {
         ClassNode receiverType = controller.getClassNode();
         if (!isThisExpression(receiver) || controller.isInGeneratedFunction()) {
-            receiverType = controller.getTypeChooser().resolveType(receiver, receiverType);
+            receiverType = getPropertyOwnerType(receiver); // GROOVY-9967, et al.
         }
 
         if (implicitThis && controller.getInvocationWriter() instanceof StaticInvocationWriter) {
diff --git a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
index b14427d..ec9119e 100644
--- a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
@@ -388,7 +388,7 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testInstanceOfInferenceWithField() {
+    void testInstanceOfInferenceWithProperty1() {
         assertScript '''
             class A {
                 int x
@@ -400,7 +400,7 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
-    void testInstanceOfInferenceWithFieldAndAssignment() {
+    void testInstanceOfInferenceWithProperty2() {
         shouldFailWithMessages '''
             class A {
                 int x
@@ -412,7 +412,7 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         ''', 'Cannot assign value of type java.lang.String to variable of type int'
     }
 
-    void testInstanceOfInferenceWithMissingField() {
+    void testInstanceOfInferenceWithMissingProperty() {
         shouldFailWithMessages '''
             class A {
                 int x
@@ -424,6 +424,52 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase {
         ''', 'No such property: y for class: A'
     }
 
+    // GROOVY-9967
+    void testInstanceOfInferenceWithSubclassProperty() {
+        assertScript '''
+            class A {
+                int i
+            }
+            class B extends A {
+                String s = 'foo'
+            }
+
+            String scenario1(x) {
+                (x instanceof String) ? x.toLowerCase() : 'bar'
+            }
+            String scenario2(B x) {
+                x.s
+            }
+            String scenario2a(B x) {
+                x.getS()
+            }
+            String scenario3(B x) {
+                (x instanceof B) ? x.s : 'bar'
+            }
+            String scenario3a(B x) {
+                (x instanceof B) ? x.getS() : 'bar'
+            }
+            String scenario4(A x) {
+                (x instanceof B) ? x.s : 'bar' // Access to A#s is forbidden
+            }
+            String scenario4a(A x) {
+                (x instanceof B) ? x.getS() : 'bar'
+            }
+
+            assert scenario1(null) == 'bar'
+            assert scenario1('Foo') == 'foo'
+            assert scenario2(new B()) == 'foo'
+            assert scenario2a(new B()) == 'foo'
+            assert scenario3(new B()) == 'foo'
+            assert scenario3a(new B()) == 'foo'
+
+            assert scenario4(new A()) == 'bar'
+            assert scenario4(new B()) == 'foo'
+            assert scenario4a(new A()) == 'bar'
+            assert scenario4a(new B()) == 'foo'
+        '''
+    }
+
     // GROOVY-9953
     void testInstanceOfPropagatesToLocalVariable() {
         assertScript '''
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6276Bug.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6276Bug.groovy
index 51fa3ce..171d006 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6276Bug.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy6276Bug.groovy
@@ -16,56 +16,52 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-
-
-
-
-
-
 package org.codehaus.groovy.classgen.asm.sc.bugs
 
 import groovy.transform.stc.StaticTypeCheckingTestCase
 import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
 
-class Groovy6276Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
+final class Groovy6276Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
+
     void testOuterClassMethodCall() {
-        assertScript '''class Outer {
-    private int outerField = 1
+        assertScript '''
+            class Outer {
+                private int outerField = 1
 
-    private int outerMethod() { 2 }
-    int outerProperty = 3
-    class Inner {
-        void assertions() {
-            assert outerField == 1            // #1
-            assert outerMethod() == 2         // #2
-            assert outerProperty == 3         // #3
-            assert getOuterProperty() == 3    // #4
-        }
-    }
+                private int outerMethod() { 2 }
+                int outerProperty = 3
+                class Inner {
+                    void assertions() {
+                        assert outerField == 1            // #1
+                        assert outerMethod() == 2         // #2
+                        assert outerProperty == 3         // #3
+                        assert getOuterProperty() == 3    // #4
+                    }
+                }
 
-    void test() {
-        new Inner().assertions()
-    }
-}
+                void test() {
+                    new Inner().assertions()
+                }
+            }
 
-new Outer().test()
-    '''
+            new Outer().test()
+        '''
     }
 
     void testAccessPrivateMethodFromClosure() {
         assertScript '''
-    class Outer {
-        private int foo(int x) {
-            2*x
-        }
+            class Outer {
+                private int foo(int x) {
+                    2*x
+                }
 
-        public int bar() {
-            (Integer) [1,2,3].collect {
-                foo(it)
-            }.sum()
-        }
-    }
-    new Outer().bar()
-'''
+                int bar() {
+                    (Integer) [1,2,3].collect {
+                        foo(it)
+                    }.sum()
+                }
+            }
+            new Outer().bar()
+        '''
     }
 }