"====================================================================== | | Smalltalk GUI method set browser | | $Revision: 1.7.5$ | $Date: 2000/05/28 16:56:52$ | $Author: pb$ | ======================================================================" "====================================================================== | | Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc. | Written by Brad Diller. Namespace support by Paolo Bonzini. | | This file is part of GNU Smalltalk. | | GNU Smalltalk is free software; you can redistribute it and/or modify it | under the terms of the GNU General Public License as published by the Free | Software Foundation; either version 2, or (at your option) any later version. | | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | details. | | You should have received a copy of the GNU General Public License along with | GNU Smalltalk; see the file COPYING. If not, write to the Free Software | Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ====================================================================== " GuiData subclass: #MethodSetBrowser instanceVariableNames: 'methodList theClass theSelector selection ' classVariableNames: '' poolDictionaries: '' category: 'Graphics-Browser' ! !MethodSetBrowser class methodsFor: 'instance creation'! implementorsOf: aSymbol parent: listView "Opens a message set browser on all methods that implement selected method" | col | col := SortedCollection new. "Collect all methods which implement selected method. Collection is sorted alphabetically" Namespace current allClassObjectsDo: [:subclass | (subclass includesSelector: aSymbol) ifTrue: [ col add: (subclass >> aSymbol) printString ]]. MethodSetBrowser new openOn: col title: 'Implementors of ', aSymbol selection: nil. ! sendersOf: aSymbol parent: listView | alert sender specialSelector | sender := SortedCollection new. Namespace current allClassObjectsDo: [:subclass | (subclass whichSelectorsReferTo: aSymbol) do: [ :sel | sender add: (subclass >> sel) printString ]]. sender isEmpty ifTrue: [^alert := ModalDialog new alertMessage: 'No senders for ', aSymbol in: listView]. ^self new openOn: sender title: 'Senders of ', aSymbol selection: aSymbol. ! ! !MethodSetBrowser methodsFor: 'initializing'! openOn: aMethodDictionary title: name selection: aSymbol "Open a method set browser. The argument aMethodDictionary consists of alpha-sorted collection of strings. Each element is of two forms: 1) className class selector, or 2) className selector. This browser consists of two vertically placed panes. The top pane is a list which displays the sorted methods in aMethodDictionary. The bottom pane is a text view which will display the source code for a selector which is selected from the top pane. In general, aSymbol denotes a selector. If this parameter is non-nil, the first occurence of aSymbol will be selected in the text view when a selector is first selected from the top pane" | topView childView aStream listView textView container | aSymbol notNil "Parse selector expression, aSymbol, inclusive of first colon" ifTrue:[aStream := WriteStream on: (String new: 0). aSymbol detect: [ :ch | aStream nextPut: ch. ch == $:] ifNone: [0]. selection := aStream contents]. topView := BrowserShell new: name, ' (', aMethodDictionary size printString, ')'. topView data: self. topView blox x: 0. topView blox y: 330. topView blox height: 308. topView blox width: 408. "Use Form class to manage the list and text view panes" childView := Form new: 'Form' in: topView. topView addChildView: childView. container := childView blox. "Create a list in top half of window" childView addChildView: ((listView := PList new: 'MethodSet' in: childView) initialize; data: self; stateChange: #methodList; handleUserChange: #methodSelection:; listMsg: #methodList; yourself). listView blox xPixels: 4; yPixels: 4; width: 400 height: 150. "Create a text view and install in lower half of window" childView addChildView: ((textView := PCode new: childView) data: self; stateChange: #text; handleUserChange: #compile:from:; textMsg: #text; selection: selection; yourself). textView menuInit: ((PopupMenu new: textView label: '') selectors: #(('Cut' gstCut) ('Copy' gstCopy) ('Paste' gstPaste) () ('Clear' gstClear) () ('Line...' line) ('Find...' find) () ('Do it' eval) ('Print it' evalAndPrintResult) ('Inspect' evalAndInspectResult) () ('Accept' compileIt) ('Cancel' revert) () ('Close' close)) receiver: textView argument: nil). textView blox width: 400 height: 150. textView blox posVert: (listView blox). textView blox xOffset: 4; yOffset: 4. "Initialize instance variable, methodList, which governs list display" methodList := aMethodDictionary. self changeState: #methodList. Primitive updateViews. "Initialize all the manufactured widgets" topView display ! ! !MethodSetBrowser methodsFor: 'accessing'! methodList ^methodList ! methodSelection: assoc "Derive class and selector from list selection. The selection is derived from an item in the method list pane. A list item may be of two forms: 1) className class selector, or 2) className selector. Form (1) contains 3 string tokens and form (2) contains 2. To derive the class from form (1), the instance class is derived from the Smallltalk dictionary using the first string token as a key. Then class is sent to the instance class to derive the class of the instance class. The selector is derived from the third token. In form (2), the instance class is derived directly from the first string token. The selector is obtained from the second token" | parsing className | assoc value isNil ifTrue: [^theSelector := nil]. parsing := ReadStream on: assoc value. className := parsing upToAll: '>>#'. theSelector := parsing upToEnd asSymbol. (className includes: Character space) ifTrue: [ parsing position: 1. className := parsing upTo: Character space. theClass := (Smalltalk at: className asSymbol) class ] ifFalse: [ theClass := Smalltalk at: className asSymbol]. self changeState: #text. Primitive updateViews. ! text "Return source code for the selected method" theSelector notNil ifTrue: [^theClass -> (theClass sourceCodeAt: theSelector) ]. ^''. ! ! !MethodSetBrowser methodsFor: 'text view blue button menu'! compile: aString from: aView "Compile aString derived from text in text view for the selected selector" theSelector isNil ifTrue: [^aView beep]. theClass compile: aString classified: ((theClass compiledMethodAt: theSelector) methodCategory) ifError: [:fname :lineNo :errorString | aView displayError: errorString at: lineNo. ^nil ]. ! selection ^selection ! !