tools/JavaToolbox.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Mon, 02 Sep 2013 09:59:56 +0100
branchdevelopment
changeset 2703 cec245f60b30
child 2708 648286432b9a
permissions -rw-r--r--
Added JavaToolbox. JavaToolsbox aims to utility methods for working with Java code. Other tools such as browser may use toolbox to perform language-specific tasks.

"{ 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 
    self shouldImplement

    "Created: / 01-09-2013 / 17:59:53 / 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)
                itemValue: [ self perform: xlatedSelector with: selector with: class ])
    ].

    menu := Menu new.
    withMethodSelectors ifTrue:[
        methods do:[:m | builder value: m javaClass name 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 javaClassName value: mref selector
            ]
        ].
    ].
    ^ menu.

    "Created: / 01-09-2013 / 17:03:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 01-09-2013 / 18:11:18 / 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'!

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

    "Created: / 01-09-2013 / 10:07:20 / 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 := class.

    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: / 01-09-2013 / 09:52:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !