# HG changeset patch # User Claus Gittinger # Date 1462503521 -7200 # Node ID f29412454cd5bb4a8a71734866eb5c2fdc4d6c46 # Parent 30f8b248f77cf9b5f2bda2f07d0bc3c00a52ec43 #REFACTORING by cg class: MethodFinderWindow class definition added:6 methods removed: #mergReciever:WithArgument: #searchPatternChanged #selectorPattern comment/format in:16 methods changed:10 methods category of:14 methods diff -r 30f8b248f77c -r f29412454cd5 MethodFinderWindow.st --- a/MethodFinderWindow.st Thu May 05 20:46:35 2016 +0200 +++ b/MethodFinderWindow.st Fri May 06 04:58:41 2016 +0200 @@ -1,9 +1,35 @@ +" + Copyright (C) Original Authors (Kaehler, Scott Wallace and Dan Ingalls) + Copyright (C) 2001 eXept Software AG + + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the 'Software'), to deal in the + Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall + be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +" "{ Package: 'stx:libtool2' }" "{ NameSpace: Smalltalk }" ApplicationModel subclass:#MethodFinderWindow - instanceVariableNames:'argumentsEditor messageAnswerEditor receiverEditor receiver + instanceVariableNames:'resultHolder selectorPatternHolder classOfResultHolder + selectedClassOfResultHolder selectedImplementorsHolder + argumentsEditor messageAnswerEditor receiverEditor receiver resultSelectors arg2BoxVisible arg1BoxVisible arg4BoxVisible arg3BoxVisible argCountHolder argCountList argument1Editor argument2Editor argument3Editor argument4Editor resultSelected @@ -15,10 +41,44 @@ !MethodFinderWindow class methodsFor:'documentation'! +copyright +" + Copyright (C) Original Authors (Kaehler, Scott Wallace and Dan Ingalls) + Copyright (C) 2001 eXept Software AG + + Permission is hereby granted, free of charge, to any + person obtaining a copy of this software and associated + documentation files (the 'Software'), to deal in the + Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall + be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +" +! + documentation " + a tool to find implementing methods by example. + Give it values for a receiver, optional arguments and a desired result, + and it will find methods which do that for you. + Please read the online documentation for details (open via the tool's help menu). + [author:] - ported from Squeak and GUI enhanced by James Hayes james@exept.de + original squeak version by Ted Kaehler, Scott Wallace and Dan Ingalls. + ported from Squeak and GUI enhanced 2001 by James Hayes james@exept.de. + improved by Claus Gittinger. " ! ! @@ -40,6 +100,53 @@ "Modified: / 13.11.2001 / 12:11:57 / cg" ! ! +!MethodFinderWindow class methodsFor:'help specs'! + +flyByHelpSpec + "This resource specification was automatically generated + by the UIHelpTool of ST/X." + + "Do not manually edit this!! If it is corrupted, + the UIHelpTool may not be able to read the specification." + + " + UIHelpTool openOnClass:MethodFinderWindow + " + + + + ^ super flyByHelpSpec addPairsFrom:#( + +#receiverValue +'Enter a receiver value here.\Can be a constant (like ''hello'')\or an expression, such as "Rectangle basicNew".' + +#answerValue +'Enter result value here.\Can be a constant (like ''hello'')\or an expression, such as "Rectangle basicNew".' + +#arg1Value +'Enter a value for the first argument here.\Can be a constant or an expression.' + +#arg2Value +'Enter a value for the second argument here.\Can be a constant or an expression.' + +#arg3Value +'Enter a value for the third argument here.\Can be a constant or an expression.' + +#argumentCount +'Specify the number of arguments here.' + +#clearButton +'Clear all sample value fields.' + +#startSearchButton +'Search for methods which answer the desired value,\given the concrete arguments' + +#selectorPatternSearch +'Search by name.\You can use match characters '*' as in GLOB patterns (i.e. like filename patterns)' + +) +! ! + !MethodFinderWindow class methodsFor:'interface specs'! windowSpec @@ -98,7 +205,8 @@ ) (ComboListSpec name: 'allowedArgments' - layout: (LayoutFrame 0 0.34000000000000002 1 0 0 0.64000000000000024 28 0) + layout: (LayoutFrame 0 0.34000000000000002 1 0 0 0.64000000000000046 28 0) + activeHelpKey: argumentCount model: argCountHolder comboList: argCountList useIndex: true @@ -106,7 +214,8 @@ (LabelSpec label: 'Answer' name: 'MessageAnswerLabel' - layout: (LayoutFrame 0 0.64000000000000024 0 0 0 1 28 0) + layout: (LayoutFrame 0 0.64000000000000046 0 0 0 1 28 0) + activeHelpKey: arg1Value translateLabel: true ) (HorizontalPanelViewSpec @@ -121,6 +230,7 @@ collection: ( (WorkspaceSpec name: 'ReceiverEditor' + activeHelpKey: receiverValue tabable: true hasHorizontalScrollBar: true hasVerticalScrollBar: true @@ -149,6 +259,7 @@ (WorkspaceSpec name: 'Arg1Editor' layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + activeHelpKey: arg1Value tabable: true hasHorizontalScrollBar: true hasVerticalScrollBar: true @@ -172,6 +283,7 @@ (WorkspaceSpec name: 'TextEditor5' layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + activeHelpKey: arg2Value tabable: true hasHorizontalScrollBar: true hasVerticalScrollBar: true @@ -195,6 +307,7 @@ (WorkspaceSpec name: 'TextEditor6' layout: (LayoutFrame 0 0.0 0 0.0 0 1.0 0 1.0) + activeHelpKey: arg3Value tabable: true hasHorizontalScrollBar: true hasVerticalScrollBar: true @@ -216,6 +329,7 @@ ) (WorkspaceSpec name: 'AnswerEditor' + activeHelpKey: answerValue tabable: true hasHorizontalScrollBar: true hasVerticalScrollBar: true @@ -241,6 +355,7 @@ (SpecCollection collection: ( (ActionButtonSpec + activeHelpKey: clearButton label: 'Clear' name: 'Button2' layout: (LayoutFrame 5 0 0 0 -5 0.5 0 1) @@ -248,6 +363,7 @@ model: clear ) (ActionButtonSpec + activeHelpKey: startSearchButton label: 'Search' name: 'Button1' layout: (LayoutFrame 5 0.5 0 0 -5 1 0 1) @@ -275,7 +391,7 @@ (InputFieldSpec name: 'EntryField1' layout: (LayoutFrame 2 0 -54 1 -2 1 -29 1) - model: selectorPattern + model: selectorPatternHolder immediateAccept: true acceptOnReturn: true acceptOnTab: true @@ -333,6 +449,7 @@ autoHideScrollBars: true hasKeyboardFocusInitially: false postBuildCallback: sourceCodeWidgetCreated: + viewClassName: 'codeViewClass' ) ) @@ -342,7 +459,7 @@ ) ) - handles: (Any 0.37391304347826093 1.0) + handles: (Any 0.37391304347826104 1.0) ) ) @@ -484,7 +601,7 @@ app := self new. app allButOpen. - app selectorPattern value:selector. + app selectorPatternHolder value:selector. app openWindow. "/ app waitForBackgroundSearchFinished. @@ -505,67 +622,8 @@ !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 -associationKey associationValue| - -argCounter:=0. - -tempArgument1Editor:= (self cleanInputs: argument1Editor contents). -tempArgument2Editor:= (self cleanInputs: argument2Editor contents). -tempArgument3Editor:= (self cleanInputs: argument3Editor contents). - -tempArgument1Editor = '' ifFalse:[argCounter:=argCounter +1]. -tempArgument2Editor = '' ifFalse:[argCounter:=argCounter +1]. -tempArgument3Editor = '' ifFalse:[argCounter:=argCounter +1]. - - -argCounter:= (argCounter min: (self argCountHolder value -1)). -tempArguments:= OrderedDictionary new:argCounter. - -(argCounter value >= 1) - ifTrue:[associationValue:= (Compiler evaluate: tempArgument1Editor). - ((self isExpression:tempArgument1Editor) or:[ associationValue isNil]) ifTrue:[ "looks if an expression is typed in" - associationKey:=associationValue printString] - ifFalse:[ - associationKey:=tempArgument1Editor]. - - tempArguments add: associationKey-> associationValue. - ]. -(argCounter value >= 2) - ifTrue:[ associationValue:= (Compiler evaluate: tempArgument2Editor). - (((self isExpression:tempArgument2Editor) or:[ associationValue isNil])) ifTrue:[ "looks if an expression is typed in" - associationKey:=associationValue printString] - ifFalse:[ - associationKey:=tempArgument2Editor]. - - tempArguments add: associationKey-> associationValue]. - -(argCounter value >= 3) - ifTrue:[ associationValue:= (Compiler evaluate: tempArgument3Editor). - ((self isExpression:tempArgument3Editor) or:[ associationValue isNil]) ifTrue:[ "looks if an expression is typed in" - associationKey:=associationValue printString] - ifFalse:[ - associationKey:=tempArgument3Editor]. - - tempArguments add: associationKey-> associationValue]. - - -^tempArguments -! - clear - "Reset the contents of all the outputs. Return the receiver." + "Reset the contents of all the outputs." receiverEditor contents:nil. argument1Editor contents:nil. @@ -577,76 +635,6 @@ codeHolder value:nil. ! -extractClassAndSelectorFrom: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. Return the receiver." - - |aClass aSelector x theArgument marker| - - anArgument isNil ifTrue:[ - ^ nil - ]. - marker := self class markerForImplementingClass. - - theArgument := anArgument string withoutPrefix:marker. - aClass := theArgument copyUpTo:(Character space). - x := aClass size + 2. - aSelector := theArgument copyFrom:x. - aClass := Smalltalk classNamed:aClass. - (aSelector startsWith:'class ') ifTrue:[ - aSelector := aSelector withoutPrefix:'class '. - aClass := aClass class. - ]. - ^ aClass -> aSelector asSymbol - -" -MethodFinderWindow new extractClassAndSelectorFrom: '*SmallInteger +' -MethodFinderWindow new extractClassAndSelectorFrom: 'String ,' -MethodFinderWindow new extractClassAndSelectorFrom: 'Number detentBy:atMultiplesOf:snap:' - - -" - - "Modified: / 27-04-2012 / 15:05:53 / cg" -! - -isExpression:aString - "Return true or false depending on if the subString includes certain characters" - - (aString includesSubString:': ') ifTrue:[ - ^ true - ]. - (aString includes:$+) ifTrue:[ - ^ true - ]. - (aString includes:$-) ifTrue:[ - ^ true - ]. - (aString includes:$*) ifTrue:[ - ^ true - ]. - (aString includes:$/) ifTrue:[ - ^ true - ]. - (aString includes:$>) ifTrue:[ - ^ true - ]. - (aString includes:$<) ifTrue:[ - ^ true - ]. - (aString includesSubString:' new') ifTrue:[ - ^ true - ]. - (aString includes:$[) - & (aString includes:$]) - & (aString includes:$.) ifTrue:[ ^ false ]. - - (aString includes:$.) ifTrue:[ - ^ true - ]. - ^ false -! - 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 @@ -727,21 +715,6 @@ UserPreferences browserClass browseSendersOf:selector. ! -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). - compiledReceiver := Compiler evaluate:aCleanedRecieverString. - ((self isExpression:aCleanedRecieverString) or:[ compiledReceiver isNil ]) ifTrue:[ - aCleanedRecieverString := compiledReceiver printString - ]. - ^ aCleanedRecieverString -> compiledReceiver. -! - search "Do a search based on the input in the various text editors. Return the receiver." @@ -755,8 +728,8 @@ tempAnswer := self messageAnswerEditorContents. "self cleanInputRec:tempReceiver arg:tempArguments ans:tempAnswer." anArray := Array new:2. - receiverWithArgument := self mergReciever:(tempReceiver value) - WithArgument:(tempArguments values). + receiverWithArgument := self mergeReceiver:(tempReceiver value) + withArgument:(tempArguments values). anArray at:1 put:receiverWithArgument; at:2 put:tempAnswer value. @@ -806,12 +779,6 @@ "Modified: / 26-09-2011 / 12:42:28 / cg" ! -searchPatternChanged - self searchPatternMatchesInBackground - - "Created: / 01-06-2012 / 13:18:16 / cg" -! - searchPatternMatchesInBackground "Do a search based on the pattern match as a background task" @@ -822,7 +789,7 @@ p terminate. ]. - pattern := self selectorPattern value. + pattern := self selectorPatternHolder value. pattern isEmptyOrNil ifTrue:[ self resultHolder value:self resultInfoText. self classOfResultHolder value:nil. @@ -837,8 +804,13 @@ self withCursor:Cursor execute do:[ pattern includesMatchCharacters ifFalse:[ list := SystemBrowser findImplementorsOf:pattern in:Smalltalk allClasses ignoreCase:true. + list isEmptyOrNil ifTrue:[ + match := pattern,'*'. + list := SystemBrowser findImplementorsMatching:match in:Smalltalk allClasses ignoreCase:true. + ]. ] ifTrue:[ - match := '*',pattern,'*'. + "/ match := '*',pattern,'*'. + match := pattern. list := SystemBrowser findImplementorsMatching:match in:Smalltalk allClasses ignoreCase:true. ]. ]. @@ -878,40 +850,13 @@ ] ]. ]. + self enqueueDelayedAction:[ self updateListAfterPatternSearch: resultList ]. - "/ is it in the list? - idx := resultSelectors indexOf:pattern. - idx ~~ 0 ifTrue:[ - self enqueueDelayedAction:[ self selectedImplementorsHolder value:idx ]. - ]. - ] fork. "Created: / 01-06-2012 / 13:16:54 / cg" ! -selectedClassOfResultHolderChanged - |sel classAndSelector mthd| - - sel := self selectedClassOfResultHolder value. - - classAndSelector := self extractClassAndSelectorFrom:sel. - classAndSelector isNil ifTrue:[ - ^ self - ]. - mthd := classAndSelector key >> classAndSelector value. - mthd notNil ifTrue:[ - self withWaitCursorDo:[ - self codeHolder value:mthd source - ] - ] ifFalse:[ - self codeHolder value:nil - ]. - - "Created: / 13.11.2001 / 12:43:43 / cg" - "Modified: / 13.11.2001 / 12:48:56 / cg" -! - updateImplementorsOf:anInteger "Request the implementors of the selected argument provided by aNumber. Return the receiver." @@ -945,26 +890,28 @@ "Modified (comment): / 24-06-2012 / 18:41:45 / cg" ! -updateListAfterPatternSearch:resultList +updateListAfterPatternSearch:resultList + |searchPattern idx| + self classOfResultHolder value:nil. self codeHolder value:nil. self resultHolder value:resultList. - "Created: / 01-06-2012 / 13:17:34 / cg" -! - -waitForBackgroundSearchFinished - | p | - - (p := searchProcess) isNil ifTrue:[^ self]. - p isDead ifTrue:[^ self]. - p waitUntilTerminated + searchPattern := self selectorPatternHolder value. + "/ is the search pattern in the list (i.e. a perfect match)? + "/ Then select it. + idx := resultSelectors indexOf:searchPattern. + idx ~~ 0 ifTrue:[ + self selectedImplementorsHolder setValue:idx; changed + ]. ! ! !MethodFinderWindow methodsFor:'aspects'! arg1BoxVisible -"Determines if the box should be visble or not. Return true or false" + "Determines if the box should be visible or not. + Return a holder providing true or false" + arg1BoxVisible isNil ifTrue:[ arg1BoxVisible := BlockValue with:[:vh | vh value >= 2 ] @@ -974,7 +921,9 @@ ! arg2BoxVisible -"Determines if the box should be visble or not. Return true or false" + "Determines if the box should be visible or not. + Return a holder providing true or false" + arg2BoxVisible isNil ifTrue:[ arg2BoxVisible := BlockValue with:[:vh | vh value >= 3 ] @@ -984,7 +933,9 @@ ! arg3BoxVisible -"Determines if the box should be visble or not. Return true or false" + "Determines if the box should be visible or not. + Return a holder providing true or false" + arg3BoxVisible isNil ifTrue:[ arg3BoxVisible := BlockValue with:[:vh | vh value >= 4 ] @@ -994,7 +945,9 @@ ! arg4BoxVisible -"Determines if the box should be visble or not. Return true or false" + "Determines if the box should be visible or not. + Return a holder providing true or false" + arg4BoxVisible isNil ifTrue:[ arg4BoxVisible := BlockValue with:[:vh | vh value >= 5 ] @@ -1004,7 +957,8 @@ ! argCountHolder -"Return the value of argCounterHolder which is initialized at 2." + "Return an argCounterHolder which is initialized at 2." + argCountHolder isNil ifTrue:[ argCountHolder := 2 asValue. ]. @@ -1012,7 +966,8 @@ ! argCountList -"Return the argCountList" + "Return the argCountList (shown in the combo)" + argCountList isNil ifTrue:[ argCountList := #('0 arguments' '1 argument' '2 arguments' '3 arguments') asValue ]. @@ -1023,12 +978,10 @@ "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 + classOfResultHolder isNil ifTrue:[ + classOfResultHolder := ValueHolder new. ]. - ^ holder + ^ classOfResultHolder ! codeHolder @@ -1040,16 +993,20 @@ "Created: / 13.11.2001 / 12:44:11 / cg" ! +codeViewClass + "the species of view to be created as codeview" + + ^ Tools::CodeView2 ? CodeView +! + resultHolder "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. - holder value:(self resultInfoText collect:[:l | l withColor:Color darkGrey]). + resultHolder isNil ifTrue:[ + resultHolder := ValueHolder new. + resultHolder value:(self resultInfoText collect:[:l | l withColor:Color darkGrey]). ]. - ^ holder. + ^ resultHolder. "Modified: / 01-06-2012 / 13:06:02 / cg" ! @@ -1068,13 +1025,10 @@ selectedClassOfResultHolder "valueHolder which contains the index of the selected result class (right list)" - |holder| - - (holder := builder bindingAt:#selectedClassOfResultHolder) isNil ifTrue:[ - holder := ValueHolder new. - builder aspectAt:#selectedClassOfResultHolder put:holder + selectedClassOfResultHolder isNil ifTrue:[ + selectedClassOfResultHolder := ValueHolder new. ]. - ^ holder + ^ selectedClassOfResultHolder "Modified (comment): / 21-09-2012 / 11:10:29 / cg" ! @@ -1082,92 +1036,25 @@ selectedImplementorsHolder "valueHolder which contains the index of the selected implementors list (left list)" - |holder| - - (holder := builder bindingAt:#selectedImplementorsHolder) isNil ifTrue:[ - holder := ValueHolder new. - holder onChangeEvaluate:[self updateImplementorsOf:holder value]. - builder aspectAt:#selectedImplementorsHolder put:holder + selectedImplementorsHolder isNil ifTrue:[ + selectedImplementorsHolder := ValueHolder new. + selectedImplementorsHolder onChangeEvaluate:[self updateImplementorsOf:selectedImplementorsHolder value]. ]. - ^ holder + ^ selectedImplementorsHolder "Created: / 21-09-2012 / 11:10:13 / cg" ! -selectorPattern - |holder| - (holder := builder bindingAt:#selectorPattern) isNil ifTrue:[ - holder := ValueHolder new. - builder aspectAt:#selectorPattern put:holder. - holder onChangeSend:#searchPatternChanged to:self. +selectorPatternHolder + selectorPatternHolder isNil ifTrue:[ + selectorPatternHolder := ValueHolder new. + selectorPatternHolder onChangeSend:#selectorPatternChanged to:self. ]. - ^ holder + ^ selectorPatternHolder "Created: / 27-04-2012 / 14:44:01 / cg" ! ! -!MethodFinderWindow methodsFor:'callBacks'! - -argument1WidgetCreated: aWidget -"Store the widget as an instance variable. Return the receiver" - - - argument1Editor := aWidget scrolledView. - aWidget tabMeansNextField:true. - - "Modified: / 13.11.2001 / 12:21:41 / cg" -! - -argument2WidgetCreated: aWidget -"Store the widget as an instance variable. Return the receiver" - - - argument2Editor := aWidget scrolledView. - aWidget tabMeansNextField:true. - - "Modified: / 13.11.2001 / 12:21:45 / cg" -! - -argument3WidgetCreated: aWidget -"Store the widget as an instance variable. Return the receiver" - - - argument3Editor := aWidget scrolledView. - aWidget tabMeansNextField:true. - - "Modified: / 13.11.2001 / 12:21:49 / cg" -! - -messageAnswerWidgetCreated: aWidget -"Store the widget as an instance variable. Return the receiver" - - messageAnswerEditor := aWidget scrolledView. - aWidget tabMeansNextField:true. - - "Modified: / 13.11.2001 / 12:24:55 / cg" -! - -openHTMLDocumentation - HTMLDocumentView openFullOnDocumentationFile:'tools/misc/TOP.html#METHODFINDER' -! - -receiverWidgetCreated: aWidget -"Store the widget as an instance variable. Return the receiver" - - receiverEditor := aWidget scrolledView. - aWidget tabMeansNextField:true. - - "Modified: / 13.11.2001 / 12:24:49 / cg" -! - -sourceCodeWidgetCreated: aWidget - aWidget acceptAction:nil. - aWidget readOnly:true - - "Created: / 13.11.2001 / 12:50:27 / cg" - "Modified: / 13.11.2001 / 12:51:23 / cg" -! ! - !MethodFinderWindow methodsFor:'controlInput'! cleanInputs:aDirtyString @@ -1258,7 +1145,7 @@ "Modified: / 13.11.2001 / 12:16:05 / cg" ! -mergReciever: aReceiver WithArgument: arguments +mergeReceiver: 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." @@ -1298,17 +1185,267 @@ ^receiverWithArgument ! ! -!MethodFinderWindow methodsFor:'misc'! +!MethodFinderWindow methodsFor:'initialization'! + +argument1WidgetCreated: aWidget + "UI post creation hook. remember the widget as an instance variable." + + argument1Editor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:21:41 / cg" +! + +argument2WidgetCreated: aWidget + "UI post creation hook. remember the widget as an instance variable." + + argument2Editor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:21:45 / cg" +! + +argument3WidgetCreated: aWidget + "UI post creation hook. remember the widget as an instance variable" + + argument3Editor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:21:49 / cg" +! + +messageAnswerWidgetCreated: aWidget + "UI post creation hook. remember the widget as an instance variable." + + messageAnswerEditor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:24:55 / cg" +! + +receiverWidgetCreated: aWidget + "UI post creation hook. remember the widget as an instance variable." + + receiverEditor := aWidget scrolledView. + aWidget tabMeansNextField:true. + + "Modified: / 13.11.2001 / 12:24:49 / cg" +! + +sourceCodeWidgetCreated: aWidget + "UI post creation hook. make the codeView readonly" + + aWidget acceptAction:nil. + aWidget readOnly:true + + "Created: / 13.11.2001 / 12:50:27 / cg" + "Modified: / 13.11.2001 / 12:51:23 / cg" +! ! + +!MethodFinderWindow methodsFor:'menu actions'! aboutThisApplicationText |msg| msg := super aboutThisApplicationText. - msg := msg , '\\Ported from Squeak to ST/X by James Hayes (james@exept.de). -Original written by Ted Kaehler, Scott Wallace and Dan Ingalls.'. + msg := msg , '\\Original written by Ted Kaehler, Scott Wallace and Dan Ingalls. +Ported from Squeak to ST/X by James Hayes (2001 james@exept.de). +Improved by Claus Gittinger. +'. ^msg withCRs. "Modified: / 13.11.2001 / 12:56:44 / cg" +! + +openHTMLDocumentation + "about/help menu action" + + HTMLDocumentView openFullOnDocumentationFile:'tools/misc/TOP.html#METHODFINDER' +! ! + +!MethodFinderWindow methodsFor:'private'! + +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 +associationKey associationValue| + +argCounter:=0. + +tempArgument1Editor:= (self cleanInputs: argument1Editor contents). +tempArgument2Editor:= (self cleanInputs: argument2Editor contents). +tempArgument3Editor:= (self cleanInputs: argument3Editor contents). + +tempArgument1Editor = '' ifFalse:[argCounter:=argCounter +1]. +tempArgument2Editor = '' ifFalse:[argCounter:=argCounter +1]. +tempArgument3Editor = '' ifFalse:[argCounter:=argCounter +1]. + + +argCounter:= (argCounter min: (self argCountHolder value -1)). +tempArguments:= OrderedDictionary new:argCounter. + +(argCounter value >= 1) + ifTrue:[associationValue:= (Compiler evaluate: tempArgument1Editor). + ((self isExpression:tempArgument1Editor) or:[ associationValue isNil]) ifTrue:[ "looks if an expression is typed in" + associationKey:=associationValue printString] + ifFalse:[ + associationKey:=tempArgument1Editor]. + + tempArguments add: associationKey-> associationValue. + ]. +(argCounter value >= 2) + ifTrue:[ associationValue:= (Compiler evaluate: tempArgument2Editor). + (((self isExpression:tempArgument2Editor) or:[ associationValue isNil])) ifTrue:[ "looks if an expression is typed in" + associationKey:=associationValue printString] + ifFalse:[ + associationKey:=tempArgument2Editor]. + + tempArguments add: associationKey-> associationValue]. + +(argCounter value >= 3) + ifTrue:[ associationValue:= (Compiler evaluate: tempArgument3Editor). + ((self isExpression:tempArgument3Editor) or:[ associationValue isNil]) ifTrue:[ "looks if an expression is typed in" + associationKey:=associationValue printString] + ifFalse:[ + associationKey:=tempArgument3Editor]. + + tempArguments add: associationKey-> associationValue]. + + +^tempArguments +! + +extractClassAndSelectorFrom: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. Return the receiver." + + |aClass aSelector x theArgument marker| + + anArgument isNil ifTrue:[ + ^ nil + ]. + marker := self class markerForImplementingClass. + + theArgument := anArgument string withoutPrefix:marker. + aClass := theArgument copyUpTo:(Character space). + x := aClass size + 2. + aSelector := theArgument copyFrom:x. + aClass := Smalltalk classNamed:aClass. + (aSelector startsWith:'class ') ifTrue:[ + aSelector := aSelector withoutPrefix:'class '. + aClass := aClass class. + ]. + ^ aClass -> aSelector asSymbol + +" +MethodFinderWindow new extractClassAndSelectorFrom: '*SmallInteger +' +MethodFinderWindow new extractClassAndSelectorFrom: 'String ,' +MethodFinderWindow new extractClassAndSelectorFrom: 'Number detentBy:atMultiplesOf:snap:' + + +" + + "Modified: / 27-04-2012 / 15:05:53 / cg" +! + +isExpression:aString + "Return true or false depending on if the subString includes certain characters" + + "/ cg: this is naive - why not ask the parser, if it is a literal? + (aString includesSubString:': ') ifTrue:[ + ^ true + ]. + (aString includes:$+) ifTrue:[ + ^ true + ]. + (aString includes:$-) ifTrue:[ + ^ true + ]. + (aString includes:$*) ifTrue:[ + ^ true + ]. + (aString includes:$/) ifTrue:[ + ^ true + ]. + (aString includes:$>) ifTrue:[ + ^ true + ]. + (aString includes:$<) ifTrue:[ + ^ true + ]. + (aString includesSubString:' new') ifTrue:[ + ^ true + ]. + (aString includes:$[) + & (aString includes:$]) + & (aString includes:$.) ifTrue:[ ^ false ]. + + (aString includes:$.) ifTrue:[ + ^ true + ]. + ^ false +! + +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). + compiledReceiver := Compiler evaluate:aCleanedRecieverString. + ((self isExpression:aCleanedRecieverString) or:[ compiledReceiver isNil ]) ifTrue:[ + aCleanedRecieverString := compiledReceiver printString + ]. + ^ aCleanedRecieverString -> compiledReceiver. +! + +waitForBackgroundSearchFinished + | p | + + (p := searchProcess) isNil ifTrue:[^ self]. + p isDead ifTrue:[^ self]. + p waitUntilTerminated +! ! + +!MethodFinderWindow methodsFor:'user actions'! + +selectedClassOfResultHolderChanged + |sel classAndSelector mthd| + + sel := self selectedClassOfResultHolder value. + + classAndSelector := self extractClassAndSelectorFrom:sel. + classAndSelector isNil ifTrue:[ + ^ self + ]. + mthd := classAndSelector key >> classAndSelector value. + mthd notNil ifTrue:[ + self withWaitCursorDo:[ + self codeHolder value:mthd source + ] + ] ifFalse:[ + self codeHolder value:nil + ]. + + "Created: / 13.11.2001 / 12:43:43 / cg" + "Modified: / 13.11.2001 / 12:48:56 / cg" +! + +selectorPatternChanged + self searchPatternMatchesInBackground + + "Created: / 01-06-2012 / 13:18:16 / cg" ! ! !MethodFinderWindow class methodsFor:'documentation'!