diff -r 4efbd088b787 -r c91fbd9f8338 MethodFinderWindow.st --- a/MethodFinderWindow.st Mon Nov 05 18:28:16 2001 +0100 +++ b/MethodFinderWindow.st Tue Nov 06 16:42:01 2001 +0100 @@ -8,7 +8,7 @@ lookAtResultEditor' classVariableNames:'' poolDictionaries:'' - category:'MethodFinder-James' + category:'MethodFinder' ! @@ -36,38 +36,18 @@ #(#WindowSpec #label: 'MethodFinder' #name: 'MethodFinder' - #min: #(#Point 10 10) - #max: #(#Point 1280 1024) - #bounds: #(#Rectangle 16 47 818 718) + #min: #(#Point nil nil) + #max: #(#Point nil nil) + #bounds: #(#Rectangle 16 47 566 447) + #menu: #menu + #forceRecursiveBackground: false ) #component: #(#SpecCollection #collection: #( - #(#ComboListSpec - #name: 'allowedArgments' - #layout: #(#LayoutFrame 0 0.201912 4 0 0 0.364397 22 0) - #model: #argCountHolder - #comboList: #argCountList - #useIndex: true - ) - #(#ActionButtonSpec - #label: 'Search' - #name: 'Button1' - #layout: #(#LayoutFrame 0 0.426523 132 0 0 0.575866 154 0) - #translateLabel: true - #tabable: true - #model: #search - ) - #(#ActionButtonSpec - #label: 'Clear' - #name: 'Button2' - #layout: #(#LayoutFrame 0 0.258065 132 0 0 0.407407 154 0) - #translateLabel: true - #model: #clear - ) #(#SequenceViewSpec #name: 'List1' - #layout: #(#LayoutFrame 0 0 161 0 0 0.6 0 0.5) + #layout: #(#LayoutFrame 0 0 0 0.5 0 0.7 0 1) #hasHorizontalScrollBar: true #hasVerticalScrollBar: true #autoHideScrollBars: true @@ -77,7 +57,7 @@ ) #(#SequenceViewSpec #name: 'List2' - #layout: #(#LayoutFrame 0 0.6 0 0 0 1 0 0.5) + #layout: #(#LayoutFrame 0 0.65 0 0 0 1 0 1) #hasHorizontalScrollBar: true #hasVerticalScrollBar: true #autoHideScrollBars: true @@ -85,27 +65,36 @@ #useIndex: false #sequenceList: #classOfResultHolder ) - #(#HorizontalPanelViewSpec - #name: 'HorizontalPanel1' - #layout: #(#LayoutFrame 6 0 26 0 0 0.6 129 0) - #horizontalLayout: #fit - #verticalLayout: #fit - #horizontalSpace: 3 - #verticalSpace: 3 + #(#ViewSpec + #name: 'Box4' + #layout: #(#LayoutFrame 0 0 0 0 0 0.65 0 0.43) #component: #(#SpecCollection #collection: #( - #(#WorkspaceSpec - #name: 'ReceiverEditor' - #tabable: true - #hasHorizontalScrollBar: false - #hasVerticalScrollBar: false - #autoHideScrollBars: true - #extent: #(#Point 156 103) - #postBuildCallback: #receiverWidgetCreated: + #(#LabelSpec + #label: 'Reciever' + #name: 'RecieverLabel' + #layout: #(#LayoutFrame -4 0.0162791 7 0 -4 0.293023 18 0) + #translateLabel: true + #adjust: #left ) - #(#VerticalPanelViewSpec - #name: 'VerticalPanel1' + #(#ComboListSpec + #name: 'allowedArgments' + #layout: #(#LayoutFrame 0 0.339535 2 0 0 0.653488 19 0) + #model: #argCountHolder + #comboList: #argCountList + #useIndex: true + ) + #(#LabelSpec + #label: 'MessageAnswer' + #name: 'MessageAnswerLabel' + #layout: #(#LayoutFrame 0 0.6693 5 0 0 0.99023 17 0) + #translateLabel: true + #adjust: #left + ) + #(#HorizontalPanelViewSpec + #name: 'HorizontalPanel1' + #layout: #(#LayoutFrame 0 0 20 0 0 1 0 1) #horizontalLayout: #fit #verticalLayout: #fit #horizontalSpace: 3 @@ -113,112 +102,130 @@ #component: #(#SpecCollection #collection: #( - #(#ViewSpec - #name: 'Box1' - #visibilityChannel: #arg1BoxVisible + #(#WorkspaceSpec + #name: 'ReceiverEditor' + #tabable: true + #hasHorizontalScrollBar: false + #hasVerticalScrollBar: false + #autoHideScrollBars: true + #extent: #(#Point 117 152) + #postBuildCallback: #receiverWidgetCreated: + ) + #(#VerticalPanelViewSpec + #name: 'VerticalPanel1' + #horizontalLayout: #fit + #verticalLayout: #fit + #horizontalSpace: 3 + #verticalSpace: 3 #component: #(#SpecCollection #collection: #( - #(#WorkspaceSpec - #name: 'Arg1Editor' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #tabable: true - #hasHorizontalScrollBar: false - #hasVerticalScrollBar: false - #autoHideScrollBars: true - #postBuildCallback: #argument1WidgetCreated: + #(#ViewSpec + #name: 'Box1' + #visibilityChannel: #arg1BoxVisible + #component: + #(#SpecCollection + #collection: #( + #(#WorkspaceSpec + #name: 'Arg1Editor' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #tabable: true + #hasHorizontalScrollBar: false + #hasVerticalScrollBar: false + #autoHideScrollBars: true + #postBuildCallback: #argument1WidgetCreated: + ) + ) + + ) + #extent: #(#Point 117 49) + ) + #(#ViewSpec + #name: 'Box2' + #visibilityChannel: #arg2BoxVisible + #component: + #(#SpecCollection + #collection: #( + #(#WorkspaceSpec + #name: 'TextEditor5' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #tabable: true + #hasHorizontalScrollBar: false + #hasVerticalScrollBar: false + #autoHideScrollBars: true + #postBuildCallback: #argument2WidgetCreated: + ) + ) + + ) + #extent: #(#Point 117 48) + ) + #(#ViewSpec + #name: 'Box3' + #visibilityChannel: #arg3BoxVisible + #component: + #(#SpecCollection + #collection: #( + #(#WorkspaceSpec + #name: 'TextEditor6' + #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + #tabable: true + #hasHorizontalScrollBar: false + #hasVerticalScrollBar: false + #autoHideScrollBars: true + #postBuildCallback: #argument3WidgetCreated: + ) + ) + + ) + #extent: #(#Point 117 49) ) ) ) - #extent: #(#Point 156 32) + #extent: #(#Point 117 152) ) - #(#ViewSpec - #name: 'Box2' - #visibilityChannel: #arg2BoxVisible - #component: - #(#SpecCollection - #collection: #( - #(#WorkspaceSpec - #name: 'TextEditor5' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #tabable: true - #hasHorizontalScrollBar: false - #hasVerticalScrollBar: false - #autoHideScrollBars: true - #postBuildCallback: #argument2WidgetCreated: - ) - ) - - ) - #extent: #(#Point 156 33) - ) - #(#ViewSpec - #name: 'Box3' - #visibilityChannel: #arg3BoxVisible - #component: - #(#SpecCollection - #collection: #( - #(#WorkspaceSpec - #name: 'TextEditor6' - #layout: #(#LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) - #tabable: true - #hasHorizontalScrollBar: false - #hasVerticalScrollBar: false - #autoHideScrollBars: true - #postBuildCallback: #argument3WidgetCreated: - ) - ) - - ) - #extent: #(#Point 156 32) + #(#WorkspaceSpec + #name: 'AnswerEditor' + #tabable: true + #hasHorizontalScrollBar: false + #hasVerticalScrollBar: false + #autoHideScrollBars: true + #extent: #(#Point 118 152) + #postBuildCallback: #messageAnswerWidgetCreated: ) ) ) - #extent: #(#Point 156 103) - ) - #(#WorkspaceSpec - #name: 'AnswerEditor' - #tabable: true - #hasHorizontalScrollBar: false - #hasVerticalScrollBar: false - #autoHideScrollBars: true - #extent: #(#Point 157 103) - #postBuildCallback: #messageAnswerWidgetCreated: ) ) ) ) - #(#LabelSpec - #label: 'MessageAnswer' - #name: 'MessageAnswerLabel' - #layout: #(#LayoutFrame 325 0 2 0 475 0 25 0) - #translateLabel: true - #adjust: #left - ) - #(#LabelSpec - #label: 'Reciever' - #name: 'RecieverLabel' - #layout: #(#LayoutFrame 7 0 3 0 126 0 26 0) - #translateLabel: true - #adjust: #left - ) - #(#WorkspaceSpec - #name: 'TextEditor4' - #layout: #(#LayoutFrame 0 0 0 0.5 0 1 0 1) - #model: #provideHelpComment - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - ) - #(#WorkspaceSpec - #name: 'Workspace1' - #layout: #(#LayoutFrame 0 0 0 0.5 0 0.5 0 1) - #model: #resultSelected - #hasHorizontalScrollBar: true - #hasVerticalScrollBar: true - #postBuildCallback: #lookAtResultEditor: + #(#ViewSpec + #name: 'Box5' + #layout: #(#LayoutFrame 53 0.224737 0 0.44 0 0.65 0 0.495578) + #component: + #(#SpecCollection + #collection: #( + #(#ActionButtonSpec + #label: 'Clear' + #name: 'Button2' + #layout: #(#LayoutFrame 0 0 0 0 -5 0.5 0 1) + #translateLabel: true + #model: #clear + ) + #(#ActionButtonSpec + #label: 'Search' + #name: 'Button1' + #layout: #(#LayoutFrame 5 0.5 0 0 0 1 0 1) + #translateLabel: true + #tabable: true + #model: #search + ) + ) + + ) ) ) @@ -226,10 +233,72 @@ ) ! ! +!MethodFinderWindow class methodsFor:'menu specs'! + +menu + "This resource specification was automatically generated + by the MenuEditor of ST/X." + + "Do not manually edit this!! If it is corrupted, + the MenuEditor may not be able to read the specification." + + " + MenuEditor new openOnClass:MethodFinderWindow andSelector:#menu + (Menu new fromLiteralArrayEncoding:(MethodFinderWindow menu)) startUp + " + + + + ^ + #(#Menu + #( + #(#MenuItem + #label: '&File' + #activeHelpKey: #file + #submenu: + #(#Menu + #( + #(#MenuItem + #label: 'Exit' + #value: #closeRequest + #activeHelpKey: #fileExit + ) + ) + nil + nil + ) + ) + #(#MenuItem + #label: 'Help' + #startGroup: #right + #submenu: + #(#Menu + #( + #(#MenuItem + #label: 'Documentation' + #value: #openHTMLDocumentation + #activeHelpKey: #helpTutorial + ) + #(#MenuItem + #label: 'About MenuEditor...' + #value: #openAboutThisApplication + #activeHelpKey: #aboutThisAppliaction + ) + ) + nil + nil + ) + ) + ) + nil + nil + ) +! ! + !MethodFinderWindow methodsFor:'accessing'! receiver - "return the value of the instance variable 'receiver' (automatically generated)" + "Return a copy of the value of the instance variable 'receiver' " ^ receiver copy ! ! @@ -237,6 +306,16 @@ !MethodFinderWindow methodsFor:'actions'! argumentEditorsContents + +"Determine how many text editors of the arguments are used and store the result +as argCounter. The result being the minimum between how many editors have +expressions in and how many are displayed. + +Add each argument string (key)and the evaluated version (value) to an Ordered Dictionary +from each of the text editors. + +Return the OrderedDictionary with the expressions from all the text editors. " + | tempArguments argCounter tempArgument1Editor tempArgument2Editor tempArgument3Editor tempArgument4Editor associationKey associationValue| @@ -286,15 +365,7 @@ ! clear - "automatically generated by UIPainter ..." - - "*** the code below performs no action" - - "*** (except for some feedback on the Transcript)" - - "*** Please change as required and accept in the browser." - - "action to be added ..." + "Reset the contents of all the outputs. Return the receiver." receiverEditor contents:nil. argument1Editor contents:nil. @@ -302,11 +373,11 @@ argument3Editor contents:nil. messageAnswerEditor contents:nil. self resultHolder value:nil. - Transcript showCR:self class name , ': action for reset ...' + self classOfResultHolder value: nil. ! isExpression: aString - + "Return true or false depending on if the subString includes certain characters" (aString includesSubString:': ') ifTrue:[^true]. (aString includesSubString:'+') ifTrue:[^true]. (aString includesSubString:'-') ifTrue:[^true]. @@ -322,17 +393,10 @@ ^false ! -lookAtMessage: anArgument - "Opens browser on theArgument of a specific class. anArgument being a string with the - Class and the selector upon which the browser is to be opened." - - |aClass aSelector x theArgument| - self halt. - - -! - messageAnswerEditorContents + "Return a cleaned up version of message answer taken from the messageAnswerEditor + as an association. The association has cleanedAnswerString as a key and the + compiledAnswer as value." | aCleanedAnswerString compiledAnswer | @@ -347,26 +411,38 @@ openBrowserOn:anArgument "Opens browser on theArgument of a specific class. anArgument being a string with the - Class and the selector upon which the browser is to be opened." + Class and the selector upon which the browser is to be opened. Return the receiver." |aClass aSelector x theArgument| anArgument isNil ifTrue:[ - ^ self + ^ self ]. (anArgument at:1) == $* ifTrue:[ - theArgument := anArgument copyFrom:2 + theArgument := anArgument copyFrom:2 ] ifFalse:[ - theArgument := anArgument + theArgument := anArgument ]. aClass := theArgument copyUpTo:(Character space). x := aClass size + 2. aSelector := theArgument copyFrom:x. aClass := Smalltalk classNamed:aClass. - SystemBrowser openInClass:(aClass) selector:(aSelector asSymbol) "/ Compiler evaluate: (aClass asSymbol). + SystemBrowser openInClass:(aClass) selector:(aSelector asSymbol) + +" +MethodFinderWindow new openBrowserOn: '*SmallInteger +' +MethodFinderWindow new openBrowserOn: 'String ,' +MethodFinderWindow new openBrowserOn: 'Number detentBy:atMultiplesOf:snap:' + + +" ! receiverEditorContents + "Return a cleaned up version of receiver taken from the receiverEditor + as an association. The association has aCleanedRecieverString as a key and the + compiledReceiver as value." + | aCleanedRecieverString compiledReceiver | aCleanedRecieverString:=self cleanInputs: (receiverEditor contents). @@ -379,8 +455,8 @@ ! search +"Do a search based on the input in the various text editors. Return the receiver." | tempReceiver tempAnswer tempArguments anArray resultArray receiverWithArgument mf| - self resultHolder value: nil. "reset the result list" self classOfResultHolder value: nil. "reset the implementorOf list" @@ -400,7 +476,6 @@ "an array now holds the following array #(#(receiver argument) answer) or #(#(reciever) answer). which should be suitable input for the method finder." -self halt. mf:= MethodFinder new. resultArray:= mf load: anArray; findMessage. @@ -436,32 +511,26 @@ ! updateImplementorsOf:anInteger - " Request the implementors of the selected arguments " + "Request the implementors of the selected argument provided by aNumber. + Return the receiver. " |methods classList aNumber| - self updateWorkSpace: anInteger . + (anInteger isNil) ifTrue:[^self]. anInteger isNil ifTrue:[aNumber:=1] ifFalse:[aNumber:=anInteger]. - methods _ SystemBrowser findImplementorsOf: (resultSelectors at:aNumber) in:Smalltalk allClasses ignoreCase:false. - classList _ methods asOrderedCollection collect:[:m | m mclass name , ' ' , m selector]. + methods:=SystemBrowser findImplementorsOf: (resultSelectors at:aNumber) in:Smalltalk allClasses ignoreCase:false. + classList:=methods asOrderedCollection collect:[:m | m mclass name , ' ' , m selector]. classList:=(self markMatchingClasses:(resultSelectors at:aNumber) classesWithSelector:classList). self classOfResultHolder value: classList. -! - -updateWorkSpace: anInteger - - - anInteger isNil ifTrue:[^self]. - resultSelected:= (self resultHolder value at:anInteger). - lookAtResultEditor replace:(resultSelected). ! ! !MethodFinderWindow methodsFor:'aspects'! arg1BoxVisible +"Determines if the box should be visble or not. Return true or false" arg1BoxVisible isNil ifTrue:[ arg1BoxVisible := BlockValue with:[:vh | vh value >= 2 ] @@ -471,6 +540,7 @@ ! arg2BoxVisible +"Determines if the box should be visble or not. Return true or false" arg2BoxVisible isNil ifTrue:[ arg2BoxVisible := BlockValue with:[:vh | vh value >= 3 ] @@ -480,6 +550,7 @@ ! arg3BoxVisible +"Determines if the box should be visble or not. Return true or false" arg3BoxVisible isNil ifTrue:[ arg3BoxVisible := BlockValue with:[:vh | vh value >= 4 ] @@ -489,6 +560,7 @@ ! arg4BoxVisible +"Determines if the box should be visble or not. Return true or false" arg4BoxVisible isNil ifTrue:[ arg4BoxVisible := BlockValue with:[:vh | vh value >= 5 ] @@ -498,6 +570,7 @@ ! argCountHolder +"Return the value of argCounterHolder which is initialized at 2." argCountHolder isNil ifTrue:[ argCountHolder := 2 asValue. ]. @@ -505,6 +578,7 @@ ! argCountList +"Return the argCountList" argCountList isNil ifTrue:[ argCountList := #('0 arguments' '1 argument' '2 arguments' '3 arguments') asValue ]. @@ -512,33 +586,24 @@ ! classOfResultHolder - "Stores a valueHolder for " + "Return a valueHolder which contains a collection with the names of the + implementors of a specific message. " |holder| - (holder := builder bindingAt:#classOfResultHolder) isNil ifTrue:[ - holder := ValueHolder new. - builder aspectAt:#classOfResultHolder put:holder + holder := ValueHolder new. + builder aspectAt:#classOfResultHolder put:holder ]. ^ holder ! resultHolder - "automatically generated by UIPainter ..." - - "*** the code below creates a default model when invoked." - "*** (which may not be the one you wanted)" - "*** Please change as required and accept it in the browser." - "*** (and replace this comment by something more useful ;-)" + "Return a value holder which contains the results of a search as a collection." |holder| - (holder := builder bindingAt:#resultHolder) isNil ifTrue:[ - holder := ValueHolder new. - builder aspectAt:#resultHolder put:holder. -"/ if your app needs to be notified of changes, uncomment one of the lines below: -"/ holder addDependent:self. -"/ holder onChangeSend:#resultHolderChanged to:self. + holder := ValueHolder new. + builder aspectAt:#resultHolder put:holder. ]. ^ holder. ! ! @@ -546,40 +611,38 @@ !MethodFinderWindow methodsFor:'callBacks'! argument1WidgetCreated: aWidget +"Store the widget as an instance variable. Return the receiver" + + argument1Editor := aWidget scrolledView. ! argument2WidgetCreated: aWidget +"Store the widget as an instance variable. Return the receiver" + argument2Editor := aWidget scrolledView. ! argument3WidgetCreated: aWidget +"Store the widget as an instance variable. Return the receiver" + argument3Editor := aWidget scrolledView. ! -argumentsWidgetCreated: aWidget +messageAnswerWidgetCreated: aWidget +"Store the widget as an instance variable. Return the receiver" - argumentsEditor := aWidget scrolledView. + messageAnswerEditor := aWidget scrolledView. ! -lookAtResultEditor: aWidget - - lookAtResultEditor := aWidget scrolledView. -! - -messageAnswerWidgetCreated: aWidget - - messageAnswerEditor := aWidget scrolledView. -! - -provideHelpComment - self halt. -^'test' +openHTMLDocumentation + HTMLDocumentView openFullOnDocumentationFile:'tools/misc/TOP.html#METHODFINDER' ! receiverWidgetCreated: aWidget +"Store the widget as an instance variable. Return the receiver" receiverEditor := aWidget scrolledView. ! ! @@ -587,7 +650,8 @@ !MethodFinderWindow methodsFor:'controlInput'! cleanInputs: aDirtyString - "Find an remove common mistakes. Complain when ill formed." + "Find and remove common mistakes made by the user. Return the + 'aStringToBeCleaned' variable" | aStringToBeCleaned rs position| aStringToBeCleaned:=aDirtyString. @@ -618,60 +682,38 @@ ^aStringToBeCleaned ! -markMatchingClasses - "If an example is used, mark classes matching the example instance with an asterisk." - - | unmarkedClassList firstPartOfSelector receiverString receiver | - - "Only 'example' queries can be marked." - - unmarkedClassList _ resultSelectors copy. - +markMatchingClasses: aSelector classesWithSelector:anOrderedCollection + " Matches the class of the receiver with all the elements in anOrderedCollection + (which are classes with selectors). If a match is found it is marked with an asterisk. + The classes are then sorted so the the asterisk appears first. Return the + markedClassList." - - - unmarkedClassList do: - [:classAndMethod | | class | - class _ Compiler evaluate: - ((ReadStream on: classAndMethod) upToAll: firstPartOfSelector). - (receiver class == class) ifTrue: - [resultSelectors add: '*', classAndMethod. - resultSelectors remove: classAndMethod]]. + | unmarkedClassList firstPartOfSelector markedClassList| - resultSelectors sort:[:a :b | |rawA rawB| - rawA := (a startsWith:'*') ifTrue:[a copyFrom:2] ifFalse:[a]. - rawB := (b startsWith:'*') ifTrue:[b copyFrom:2] ifFalse:[b]. - rawA > rawB. ] -! - -markMatchingClasses: aSelector classesWithSelector:anOrderedCollection - "If an example is used, mark classes matching the example instance with an asterisk." - - | unmarkedClassList firstPartOfSelector | + unmarkedClassList:=anOrderedCollection copy. - "Only 'example' queries can be marked." - unmarkedClassList _ anOrderedCollection copy. - - - - - unmarkedClassList do: - [:classAndMethod | | class | - class _ Compiler evaluate: - ((ReadStream on: classAndMethod) upToAll: aSelector). - (receiver value class == class) ifTrue: - [unmarkedClassList add: '*', classAndMethod. - unmarkedClassList remove: classAndMethod]]. + unmarkedClassList do: + [:classAndMethod | | class | + class:=Compiler evaluate: + ((ReadStream on: classAndMethod) upToAll: aSelector). + (receiver value class == class) ifTrue: + [unmarkedClassList add: '*', classAndMethod. + unmarkedClassList remove: classAndMethod]]. unmarkedClassList sort:[:a :b | |rawA rawB| - rawA := (a startsWith:'*') ifTrue:[a copyFrom:2] ifFalse:[a]. - rawB := (b startsWith:'*') ifTrue:[b copyFrom:2] ifFalse:[b]. - rawA > rawB. ]. - ^unmarkedClassList + rawA := (a startsWith:'*') ifTrue:[a copyFrom:2] ifFalse:[a]. + rawB := (b startsWith:'*') ifTrue:[b copyFrom:2] ifFalse:[b]. + rawA > rawB. ]. + markedClassList:= unmarkedClassList. + + ^markedClassList ! mergReciever: aReceiver WithArgument: arguments +"Puts the receiver and arguments into an array so it can be of a suitable input for the + MethodFinder. Return an array." + | tempReceiver tempArguments receiverWithArgument| tempReceiver:= aReceiver. @@ -702,15 +744,6 @@ (receiverWithArgument at:4 put: (tempArguments at:3)). ]. "a receiver with an argument" - (tempArguments size = 4) - ifTrue:[ receiverWithArgument:=Array new:5. - receiverWithArgument at:1 put: tempReceiver. - (receiverWithArgument at:2 put: (tempArguments at:1)). - (receiverWithArgument at:3 put: (tempArguments at:2)). - (receiverWithArgument at:4 put: (tempArguments at:3)). - (receiverWithArgument at:5 put: (tempArguments at:4)). - - ]. "a receiver with an argument" ]. ^receiverWithArgument