--- 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
+ "
+
+ <resource: #help>
+
+ ^ 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'!