bugfix - interop - narrowed return type synthetic methods development
authorMarcel Hlopko <marcel.hlopko@fit.cvut.cz>
Sun, 16 Dec 2012 14:16:59 +0100
branchdevelopment
changeset 1893 167f2898b9ad
parent 1892 1761ac0beb04
child 1894 d1b5ffa1f991
bugfix - interop - narrowed return type synthetic methods When class A overrides method B, but declares narrower return type, java compiler generates synthetic method which just delegates to overriden method. In smalltalk 2 java interop, we don't want to count these synthetic methods as candidates.
JavaLookup.st
JavaLookupResolutionAlgorithmTests.st
JavaLookupTests.st
ProxyMethod.st
extensions.st
stx_libjava.st
--- a/JavaLookup.st	Sun Dec 16 14:08:27 2012 +0100
+++ b/JavaLookup.st	Sun Dec 16 14:16:59 2012 +0100
@@ -311,7 +311,7 @@
      As a courtesy to a Smalltalker, try to map smalltalk selectors to a java ones.
      Returns JavaMethodDescriptor or nil."
     
-    | name  nameSizePlusOne  candidates  finder  static  cls  m | 
+    | name  nameSizePlusOne  candidates  finder  static  cls  m |
     name := selector upTo: $:.
     nameSizePlusOne := name size + 1.
     static := receiver isBehavior.
@@ -343,6 +343,24 @@
         ]
     ].
     candidates notEmpty ifTrue: [
+        "because java compiler generates synthetic method, when overriden
+         method has narrower return type than method from superclass/interface,
+         we don't take these particular synthetic methods as candidates, they just
+         delegate to overridden methods."
+
+        ((candidates size > 1) and:[candidates anySatisfy:[:each|each isSynthetic]]) ifTrue:[
+            | candidatesPerNameAndArg |
+
+            candidatesPerNameAndArg := Dictionary new.
+            candidates do:[:each|
+                | nameAndArgs |
+
+                nameAndArgs := each selector upTo:$).
+                candidatesPerNameAndArg at: nameAndArgs ifAbsentPut:[each]. 
+            ].
+            candidates := candidatesPerNameAndArg values.
+
+        ].        
         m := self 
                 compileProxyWithSelector: selector
                 in: receiver class
@@ -387,6 +405,7 @@
     "Modified (comment): / 02-01-2012 / 10:35:25 / kursjan <kursjan@fit.cvut.cz>"
     "Modified: / 17-03-2012 / 17:22:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 18-11-2012 / 18:17:28 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 16-12-2012 / 13:59:55 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
 ! !
 
 !JavaLookup::Smalltalk2Java methodsFor:'lookup (old)'!
--- a/JavaLookupResolutionAlgorithmTests.st	Sun Dec 16 14:08:27 2012 +0100
+++ b/JavaLookupResolutionAlgorithmTests.st	Sun Dec 16 14:16:59 2012 +0100
@@ -194,6 +194,11 @@
 
 !JavaLookupResolutionAlgorithmTests class methodsFor:'documentation'!
 
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
 version_SVN
-    ^ '$Id$'
+    ^ '§Id§'
 ! !
--- a/JavaLookupTests.st	Sun Dec 16 14:08:27 2012 +0100
+++ b/JavaLookupTests.st	Sun Dec 16 14:16:59 2012 +0100
@@ -99,10 +99,11 @@
 
     md := self javaTestClass methodDictionary.
     md copy keysAndValuesDo:[:sel :m|
-        m isSynthetic ifTrue:[md removeKey: sel]
+        m isProxyMethod ifTrue:[md removeKey: sel]
     ].
 
     "Created: / 03-12-2012 / 17:50:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-12-2012 / 13:35:52 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
 ! !
 
 !JavaLookupTests methodsFor:'support'!
@@ -212,6 +213,19 @@
     "Created: / 30-08-2011 / 22:06:16 / Jan Kurs <kursjan@fit.cvut.cz>"
 !
 
+testInterfaceMethodsWithNarrowerReturnType
+    "when a class A implements an interface I, and overridden method has narrower 
+    return type (e.g. method in I should return java.lang.Object, but overridden 
+    method in A declares return type of java.lang.String), java compiler generates
+    synthetic method with the same name and return type declared in I, which just
+    delegates to overridden method. This situation should not be considered
+    as error case, instead, one of the methods should be returned."
+
+self assert: (self javaTestClass new getMethodReturningObject) = 'working'.
+
+    "Created: / 16-12-2012 / 12:56:01 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+!
+
 testMultipleParameters
     "test multiple parameters"
     
--- a/ProxyMethod.st	Sun Dec 16 14:08:27 2012 +0100
+++ b/ProxyMethod.st	Sun Dec 16 14:16:59 2012 +0100
@@ -273,6 +273,15 @@
 
 !ProxyMethod methodsFor:'testing'!
 
+isProxyMethod
+    "return true, if the receiver is a proxy method.
+    True is returned here."
+
+    ^true.
+
+    "Created: / 16-12-2012 / 13:35:08 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+!
+
 isStatic
     ^self mclass isMetaclass
 
--- a/extensions.st	Sun Dec 16 14:08:27 2012 +0100
+++ b/extensions.st	Sun Dec 16 14:16:59 2012 +0100
@@ -749,6 +749,17 @@
     "Created: / 31-07-2012 / 18:42:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!ExecutableFunction methodsFor:'queries'!
+
+isProxyMethod
+    "return true, if the receiver is a proxy method.
+    false is returned here, true is returned in ProxyMethod."
+
+    ^ false.
+
+    "Created: / 16-12-2012 / 13:35:41 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+! !
+
 !Float class methodsFor:'queries'!
 
 isJavaPrimitiveType
--- a/stx_libjava.st	Sun Dec 16 14:08:27 2012 +0100
+++ b/stx_libjava.st	Sun Dec 16 14:16:59 2012 +0100
@@ -582,7 +582,10 @@
         Object javaWrapRequired
         'Boolean class' javaWrapRequired
         CharacterArray withoutSuffix:
+        ExecutableFunction isProxyMethod
     )
+
+    "Modified: / 16-12-2012 / 14:11:37 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
 ! !
 
 !stx_libjava class methodsFor:'description - java'!