JavaResolver.st
changeset 3553 5329fb7027e8
parent 3412 df11bb428463
child 3860 e87f2f1439e9
--- a/JavaResolver.st	Wed Mar 23 19:45:10 2016 +0000
+++ b/JavaResolver.st	Sun Mar 27 22:29:04 2016 +0100
@@ -20,6 +20,8 @@
 "
 "{ Package: 'stx:libjava' }"
 
+"{ NameSpace: Smalltalk }"
+
 Object subclass:#JavaResolver
 	instanceVariableNames:'exceptionThrower'
 	classVariableNames:'uniqueInstance'
@@ -445,7 +447,7 @@
     "Modified: / 04-08-2014 / 15:52:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
-!JavaResolver methodsFor:'field resolving helpers'!
+!JavaResolver methodsFor:'field resolving-helpers'!
 
 checkPermissionsForField: aJavaField from: accessingJavaClass to: resolvedJavaClass     
     ^ self 
@@ -474,19 +476,41 @@
     "Modified: / 01-12-2012 / 13:46:02 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
 ! !
 
-!JavaResolver methodsFor:'interface method resolving'!
+!JavaResolver methodsFor:'method resolving'!
 
 resolveInterfaceMethodIdentifiedByRef: aJavaInterfaceMethodRef 
-    | result  class |
+    | result  class search selector |
     self validateInterfaceMethodRef: aJavaInterfaceMethodRef.
-    result := self 
-            lookupInterfaceMethodIfAlreadyResolved: aJavaInterfaceMethodRef.
-    result notNil ifTrue: [ ^ result ].
     class := aJavaInterfaceMethodRef classRef resolve: false.
-    class isNil ifTrue: [ self error: 'should not happen - tell mh' ].
+    class isNil ifTrue: [ 
+        self error: 'should not happen - tell mh' 
+    ].
+    "Array types responds to all method of class java.lang.Object"
+    class isJavaArrayClass ifTrue:[
+        class := JavaVM classForName:'java.lang.Object'.
+    ].
     class isInterface ifFalse: [ self throwIncompatibleClassChangeError ].
-    result := class 
-            lookupMethodByNameAndType: aJavaInterfaceMethodRef nameAndType.
+
+    search := class.
+    selector := aJavaInterfaceMethodRef nameAndType selector.
+    [ search notNil and:[result isNil] ] whileTrue:[
+        result := search compiledMethodAt: selector.
+        search := search superclass.
+    ].  
+    result isNil ifTrue:[ 
+        | queue |
+
+        queue := OrderedCollection withAll: class allInterfaces.
+        [ result isNil and:[queue notEmpty ] ] whileTrue:[ 
+            search := queue removeFirst.
+            result := search compiledMethodAt: selector.
+            result isNil ifTrue:[ 
+                search interfaces do:[:interface | 
+                    (queue includes: interface) ifFalse:[ queue add: interface ].
+                ].
+            ].
+        ].
+    ].  
     result isNil ifTrue: [ self throwNoSuchMethodError ].
     (self 
         checkPermissionsForMethod: result
@@ -515,51 +539,26 @@
 loading constraints TiL1 = TiL2 for i = 0 to n (§5.3.4)."
 
     "Modified: / 01-12-2012 / 13:46:09 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 09-11-2013 / 00:12:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-! !
-
-!JavaResolver methodsFor:'interface method resolving helpers'!
-
-lookupInterfaceMethodIfAlreadyResolved: aJavaInterfaceMethodRef 
-    ^  nil.
-
-    "Created: / 13-04-2011 / 11:53:36 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 27-03-2016 / 22:18:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-validateInterfaceMethodRef: aJavaInterfaceMethodRef 
-    aJavaInterfaceMethodRef isJavaRef ifFalse: [
-        self error: 'I expected JavaRef instance as an argument'
-    ].
-    aJavaInterfaceMethodRef isJavaInterfaceMethodRef ifFalse: [
-        self error: 'I expected JavaMethodRef instance as an argument'
-    ].
-
-    "Created: / 13-04-2011 / 11:53:34 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 01-12-2012 / 13:46:20 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-! !
-
-!JavaResolver methodsFor:'method resolving'!
-
 resolveMethodIndentifiedByRef:aJavaMethodRef 
-    | result  class |
+    | result class selector search |
 
     self validateMethodRef:aJavaMethodRef.
-    result := self lookupMethodIfAlreadyResolved:aJavaMethodRef.
-    result notNil ifTrue:[
-        ^ result
-    ].
+
     class := aJavaMethodRef classRef resolve:false.
     class isNil ifTrue:[
         self error:'should not happen - tell mh'
     ].
-     "Array types responds to all method of class java.lang.Object"
+    "Array types responds to all method of class java.lang.Object"
     class isJavaArrayClass ifTrue:[
         class := JavaVM classForName:'java.lang.Object'.
     ].
      "
      To resolve an unresolved symbolic reference from D to a method in
      a class C, the symbolic reference to C given by the method reference
-     is first resolved (§5.4.3.1). Therefore, any exceptions that can be
+     is first resolved (5.4.3.1). Therefore, any exceptions that can be
      thrown due to resolution of a class reference can be thrown as a result
      of method resolution. If the reference to C can be successfully resolved,
      exceptions relating to the resolution of the method reference itself
@@ -571,23 +570,41 @@
     class isInterface ifTrue:[
         self throwIncompatibleClassChangeError
     ].
-     "Method resolution attempts to look up the referenced method in C and its
+    "Method resolution attempts to look up the referenced method in C and its
      superclasses:
      If C declares a method with the name and descriptor specified by the method
      reference, method lookup succeeds.
      Otherwise, if C has a superclass, step 2 of method lookup is recursively
-     invoked on the direct superclass of C.
-     
-     Otherwise, method lookup attempts to locate the referenced method in any of
+     invoked on the direct superclass of C."
+    search := class.
+    selector := aJavaMethodRef nameAndType selector.
+    [ search notNil and:[result isNil] ] whileTrue:[
+        result := search compiledMethodAt: selector.
+        search := search superclass.
+    ].
+    "Otherwise, method lookup attempts to locate the referenced method in any of
      the superinterfaces of the specified class C.
      If any superinterface of C declares a method with the name and descriptor
-     specified by the method reference, method lookup succeeds.
-     Otherwise, method lookup fails.
+     specified by the method reference, method lookup succeeds."
+    result isNil ifTrue:[ 
+        | queue |
+
+        queue := OrderedCollection withAll: class allInterfaces.
+        [ result isNil and:[queue notEmpty ] ] whileTrue:[ 
+            search := queue removeFirst.
+            result := search compiledMethodAt: selector.
+            result isNil ifTrue:[ 
+                search interfaces do:[:interface | 
+                    (queue includes: interface) ifFalse:[ queue add: interface ].
+                ].
+            ].
+        ].
+    ].
+    "Otherwise, method lookup fails.
      If method lookup fails, method resolution throws a NoSuchMethodError. If method
      lookup succeeds and the method is abstract, but C is not abstract, method resolution
      throws an AbstractMethodError. Otherwise, if the referenced method is not accessible
-     (§5.4.4) to D, method resolution throws an IllegalAccessError."
-    result := class lookupMethodByNameAndType:aJavaMethodRef nameAndType.
+     (§5.4.4) to D, method resolution throws an IllegalAccessError."
     result isNil ifTrue:[
         self throwNoSuchMethodError
     ].
@@ -609,10 +626,10 @@
     "Created: / 11-04-2011 / 19:45:34 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
     "Modified: / 14-04-2011 / 00:01:34 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
     "Modified (format): / 01-12-2012 / 13:46:25 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 04-08-2014 / 15:55:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 27-03-2016 / 22:19:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
-!JavaResolver methodsFor:'method resolving helpers'!
+!JavaResolver methodsFor:'method resolving-helpers'!
 
 checkPermissionsForMethod: aJavaMethod from: accessingJavaClass to: resolvedJavaClass    
     ^ self 
@@ -626,11 +643,16 @@
     "Modified: / 01-12-2012 / 13:46:58 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
 !
 
-lookupMethodIfAlreadyResolved: aJavaMethodRef 
-    ^ nil.
+validateInterfaceMethodRef: aJavaInterfaceMethodRef 
+    aJavaInterfaceMethodRef isJavaRef ifFalse: [
+        self error: 'I expected JavaRef instance as an argument'
+    ].
+    aJavaInterfaceMethodRef isJavaInterfaceMethodRef ifFalse: [
+        self error: 'I expected JavaMethodRef instance as an argument'
+    ].
 
-    "Created: / 11-04-2011 / 19:50:38 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
-    "Modified: / 13-04-2011 / 11:57:00 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Created: / 13-04-2011 / 11:53:34 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
+    "Modified: / 01-12-2012 / 13:46:20 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
 !
 
 validateMethodRef: aJavaMethodRef