tools/JavaToolbox.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Tue, 10 Sep 2013 16:08:08 +0200
changeset 2692 fe83a843a7bf
parent 2678 c865275e48a7
child 2731 13f5be2bf83b
permissions -rw-r--r--
class: JavaToolbox changed: #searchForImplementorsOf:class:in:whenFoundDo: Fix for implementor searching.

"{ Package: 'stx:libjava/tools' }"

Tools::Toolbox subclass:#JavaToolbox
	instanceVariableNames:''
	classVariableNames:''
	poolDictionaries:''
	category:'Languages-Java-Tools'
!

!JavaToolbox class methodsFor:'documentation'!

documentation
"
    JavaToolbox contains various utility method used by other tools
    to perform language-specific tasks.

    [author:]
        Jan Vrany <jan.vrany@fit.cvut.cz>

    [instance variables:]

    [class variables:]

    [see also:]

"
! !

!JavaToolbox methodsFor:'browsing'!

spawnBrowserOnAllImplementorsOf: selector class: class 
    | label |

    self ensureBrowser.
    browser withWaitCursorDo:[
        label := browser resources string:'Implementors of %1' with: (self displayStringForSelector: selector in: class name).
        browser 
            spawnMethodBrowserForSearch:[self searchForImplementorsOf: selector class: class]
            sortBy:#class
            in:#newBuffer
            label:label.
    ]

    "Created: / 01-09-2013 / 17:59:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 05-09-2013 / 12:44:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

spawnBrowserOnAllSendersOf: selector class: class 
    | label search |

    self ensureBrowser.
    browser withWaitCursorDo:[
        label := browser resources string:'Senders of %1' with: (self displayStringForSelector: selector in: class name).
        search := selector upTo: $(.
        browser 
            spawnMethodBrowserForSearch:[self searchForSendersOf: selector class: class]
            sortBy:#class
            in:#newBuffer
            label:label.
        browser autoSearchSelector:search ignoreCase:false doMatch:false.     
    ]

    "Created: / 01-09-2013 / 17:59:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaToolbox methodsFor:'menus'!

messagesMenuFor:actionSelector
    withMethods: methods
    withMethodSelectors:withMethodSelectors
    withSentSelectors: withSentSelectors
    withSelfSelectorsOnly: withSelfSelectorsOnly    

    | xlatedSelector menu builder sent |

    actionSelector == #spawnBrowserOnAllSendersOf: ifTrue:[
        xlatedSelector := #spawnBrowserOnAllSendersOf:class:
    ] ifFalse:[actionSelector == #spawnBrowserOnAllImplementorsOf: ifTrue:[
        xlatedSelector := #spawnBrowserOnAllImplementorsOf:class:
    ] ifFalse:[
        ^ Menu new
            addItem: ((MenuItem label: 'Not supported for Java') enabled: false);
            yourself.
    ]].

    builder := [:class :selector |
        menu addItem:
            (MenuItem 
                label: (self displayStringForSelector: selector in: class name)
                itemValue: [ self perform: xlatedSelector with: selector with: class ])
    ].

    menu := Menu new.
    withMethodSelectors ifTrue:[
        methods do:[:m | builder value: m javaClass value: m selector ].
    ].
    withSentSelectors ifTrue:[
        sent := Set new.
        methods do:[:m | sent addAll: m analyzer methodsInvoked ].
        sent notEmptyOrNil ifTrue:[
            withMethodSelectors ifTrue:[
                menu addSeparator.
            ].
            sent := sent asSortedCollection:[:a :b|a selector < b selector ].
            sent do:[:mref |
                builder value: mref classRef javaClass value: mref selector
            ]
        ].
    ].
    ^ menu.

    "Created: / 01-09-2013 / 17:03:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 05-09-2013 / 13:38:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaToolbox methodsFor:'private-presentation'!

displayStringForSelector: selector in: className
    | i name descriptor package localName |

    i := selector indexOf: $(.
    name := selector copyTo: i - 1.
    name = #'<clinit>' ifTrue:[
        ^ 'static {}'
    ].

    descriptor := selector copyFrom: i.
    i := className lastIndexOf: $/.
    package := className copyTo: i - 1.


    name = '<init>' ifTrue:[
        localName := className copyFrom: i + 1.
        ^ JavaMethod specTextFromSignature:descriptor in: package withName: localName.         
    ].
    ^ JavaMethod specTextFromSignature:descriptor in: package withName: name

    "Created: / 31-08-2013 / 23:31:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaToolbox methodsFor:'searching'!

searchForDeclarationOf: selector class: class in: classes
    "Return 'declaration' of method with given selector in given class.
     By 'declaration' we mean top-most definition of the method or
     definition of the method in one of class's interface. 
     Returns the class (ot interface) in which the method is
     first declared."

    | current declaring |

    current := declaring := class.
    [ current ~~ JavaObject ] whileTrue:[
        (current canUnderstand: selector) ifTrue:[
            declaring := current.
        ].
        current allInterfaces do:[:iface|
            (iface canUnderstand: selector) ifTrue:[
                ^ iface
            ].
        ].
        current := current superclass.
    ].

    ^ declaring

    "Created: / 05-09-2013 / 13:10:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

searchForImplementorsOf: selector class: class
    ^ self searchForImplementorsOf: selector class: class in: environment allClasses

    "Created: / 05-09-2013 / 12:44:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

searchForImplementorsOf: selector class: class in: classes
    | senders |

    senders := Set new.
    self searchForImplementorsOf: selector class: class in: classes whenFoundDo: [:mthd | senders add: mthd ].
    ^ senders

    "Created: / 05-09-2013 / 12:45:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

searchForImplementorsOf: selector class: class in: classes whenFoundDo: block 
    | searchSelector searchClass |

    searchSelector := selector.
    searchClass := self searchForDeclarationOf: selector class: class in: classes.

    classes do: [:cls | 
        cls isJavaClass ifTrue: [
            | m |
            ((m := cls compiledMethodAt: searchSelector) notNil and:[ JavaVM canCast: cls javaClass to: searchClass]) ifTrue:[
                block value: m
            ]
        ]
    ].

    "Created: / 05-09-2013 / 12:45:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

searchForSendersOf: selector class: class
    ^ self searchForSendersOf: selector class: class in: environment allClasses

    "Created: / 01-09-2013 / 10:07:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 05-09-2013 / 12:46:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

searchForSendersOf: selector class: class in: classes
    | senders |

    senders := Set new.
    self searchForSendersOf: selector class: class in: classes whenFoundDo: [:mthd | senders add: mthd ].
    ^ senders

    "Created: / 01-09-2013 / 10:07:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

searchForSendersOf: selector class: class in: classes whenFoundDo: block 
    | searchSelector searchClass |

    searchSelector := selector.
    searchClass := self searchForDeclarationOf: selector class: class in: classes.

    classes do: [:cls | 
        cls isJavaClass ifTrue: [
            | matching |

            matching := Set new.
            "/ Quickly scan constant pool without need of analyzing
            "/ each method...
            cls constantPool do:[:ref|
                ref isJavaMethodRef ifTrue:[
                    (ref selector == searchSelector and:[ JavaVM canCast: ref classRef javaClass to: searchClass]) ifTrue:[
                        matching add: ref.
                    ]
                ]
            ].
            matching notEmpty ifTrue:[
                cls methodDictionary keysAndValuesDo:[:selector :method|
                    (method analyzer methodsInvoked includesAny: matching) ifTrue:[
                        block value: method
                    ]
                ]
            ]
        ]
    ]

    "Created: / 01-09-2013 / 03:11:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 05-09-2013 / 13:10:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!JavaToolbox class methodsFor:'documentation'!

version_CVS
    ^ '$Header: /cvs/stx/stx/libjava/tools/JavaToolbox.st,v 1.2 2013-09-10 14:08:08 vrany Exp $'
! !