[squeak-dev] Review Request: browseMethodReference.1.cs

christoph.thiede at student.hpi.uni-potsdam.de christoph.thiede at student.hpi.uni-potsdam.de
Mon Nov 28 18:10:25 UTC 2022


=============== Summary ===============

Change Set:        browseMethodReference
Date:            28 November 2022
Author:            Christoph Thiede

Adds support for method references in editors's 'Browse it' and 'iMplmentors' shortcuts. Method references can have different formats such as String findMethodReference or String>>#findMethodReference. Includes tests and proper support for message traces.

Performance: <1.1 ms per run if you select an entire line, which should be fine. :-)

Also makes sure that no debuggers opens up when you browse the iMplementors of an incomplete literal such as a single quote.

=============== Diff ===============

MessageTrace>>browseMethod:requestor: {actions} · ct 11/28/2022 18:00
+ browseMethod: aMethodReference requestor: requestor
+     "Overwritten to modify the trace if the request origins from a model-menu command such as the message-list menu (shortcut)."
+ 
+     (Preferences traceMessages and: [ self hasUnacceptedEdits not ])
+         ifTrue: [ self
+             addChildMessages: (OrderedCollection with: aMethodReference)
+             autoSelectString: '' ]
+         ifFalse: [ super browseAllImplementorsOf: aMethodReference requestor: requestor ].

Model>>browseMethod: {*Tools-MessageSets} · ct 11/28/2022 18:58
+ browseMethod: aMethodReference
+     "A tool's widget/view (i.e., 'requestor') requested to browse aMethodReference. By default, dispatch back to the reference."
+ 
+     ^ aMethodReference browse

Model>>browseMethod:requestor: {*Tools-MessageSets} · ct 11/28/2022 18:58
+ browseMethod: aMethodReference requestor: requestor
+     "A tool's widget/view (i.e., 'requestor') requested to browse aMethodReference. By default, dispatch back to the reference."
+ 
+     ^ self browseMethod: aMethodReference

ParagraphEditor>>selectedLiteral {menu messages} · ct 11/28/2022 18:18 (changed)
selectedLiteral
    "Try to make a Smalltalk literal out of the current text selection."

-     ^ self selection string findLiteral
+     ^ [self selection string findLiteral] ifError: ["e.g., incomplete string"]

String>>findMethodReference {converting} · ct 11/28/2022 19:03
+ findMethodReference
+     "Find and parse a method reference within the receiver. Answer a MethodReference or nil if none is found. Heuristic."
+ 
+     | str substrings |
+     str := self copyReplaceAll: '>>' with: ' >> '.
+     str := str copyWithRegex: '(?=(?<![^\p{L}\:\s])[^\p{L}#\:\s]|(?<=[^\p{L}#\:\s])[\p{L}#\:\s])' matchesReplacedWith: ' '. "beginning or end of token"
+     substrings := str substrings.
+     substrings size - 1 to: 1 by: -1 do: [:classIndex | | classStr |
+         classStr := substrings at: classIndex.
+         (self environment classNamed: classStr) ifNotNil: [:class |
+             (classIndex + 1 + ((substrings at: classIndex + 1) = '>>') asBit clampHigh: substrings size) to: classIndex + 1 by: -1 do: [:selIndex |
+                 | ref selStr |
+                 selStr := substrings at: selIndex.
+                 (selStr size > 1 and: [selStr first = $#]) ifTrue: [selStr := selStr allButFirst].
+                 (Symbol lookup: selStr) ifNotNil: [:sel |
+                     ref := MethodReference
+                         class: class
+                         selector: sel.
+                     ref isValid ifTrue: [^ ref]]]]].
+     ^ nil

StringTest>>testFindMethodReference {tests - finding} · ct 11/28/2022 18:11
+ testFindMethodReference
+ 
+     {
+         Number >> #negated. 'Number negated'.
+         Number >> #negated. 'Number>>negated'.
+         Number >> #negated. 'Number>>#negated'.
+         Number >> #negated. 'Number >> #negated'.
+         
+         Number >> #negated. 'Number >> #negated.'.
+         Number >> #negated. '"Number >> #negated"'.
+         Number >> #negated. 'For more information, see Number>>#negated or run the tests.'.
+         
+         nil. 'Number absentSelector'.
+         nil. ''.
+         
+         Morph >> #drawOn:. 'Morph drawOn:'.
+         nil. 'Morph drawOn'. "Do not add colons."
+         
+         Number >> #+. 'Number +'.
+         Number >> #+. 'Number>>+'.
+         Number >> #+. 'Number>>#+'.
+         Number >> #+. 'Number+'.
+         
+         Behavior >> #>>. 'Behavior >>'.
+         Behavior >> #>>. 'Behavior>>'.
+         Behavior >> #>>. 'Behavior>> >>'.
+     } pairsDo: [:method :string |
+         self
+             assert: (method ifNotNil: [method asCodeReference])
+             equals: string findMethodReference].

TextEditor>>browseIt {menu messages} · ct 11/28/2022 17:53 (changed)
browseIt
    "Launch a browser for the current selection, if appropriate."

+     self selectedMethodReference ifNotNil:
+         [:methodReference | ^self model browseMethod: methodReference requestor: morph].
    Preferences alternativeBrowseIt ifTrue: [^ self browseClassFromIt].

    self lineSelectAndEmptyCheck: [^ morph flash].

    "First, try to show all accesses to instance or class variables."
    self selectedInstanceVariable ifNotNil:
        [:nameToClass | self systemNavigation
            browseAllAccessesTo: nameToClass key
            from: nameToClass value].
    self selectedClassVariable ifNotNil:
        [:binding | self model browseAllCallsOn: binding].

    "Then, either browse the class (from a binding) or all implementors of a selector."
    self selectedBinding ifNotNil:
        [:binding | ^ self systemNavigation browseClass: binding].
    self selectedSelector ifNotNil:
        [:selector | ^ self model browseAllImplementorsOf: selector requestor: morph].
    
    morph flash

TextEditor>>implementorsOfIt {menu messages} · ct 11/28/2022 17:05 (changed)
implementorsOfIt
    "Open an implementors browser on the selected selector"

    self lineSelectAndEmptyCheck: [^ self].
+     self selectedMethodReference ifNotNil:
+         [:methodReference | ^self model browseMethod: methodReference requestor: morph].
    self selectedSelector ifNotNil:
        [:aSelector| ^self model browseAllImplementorsOf: aSelector requestor: morph].
    self selectedLiteral ifNotNil:
        [:aLiteral| ^self model browseAllImplementorsOf: aLiteral requestor: morph].
    morph flash.

TextEditor>>selectedLiteral {menu messages} · ct 11/28/2022 18:18 (changed)
selectedLiteral
    "Try to make a Smalltalk literal out of the current text selection."

-     ^ self selection string findLiteral
+     ^ [self selection string findLiteral] ifError: ["e.g., incomplete string"]

TextEditor>>selectedMethodReference {menu messages} · ct 11/28/2022 17:06
+ selectedMethodReference
+     "Try to make a method reference out of the current text selection."
+ 
+     ^ self selection string findMethodReference

---
Sent from Squeak Inbox Talk
["browseMethodReference.1.cs"]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20221128/9900749b/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: browseMethodReference.1.cs
Type: application/octet-stream
Size: 5980 bytes
Desc: not available
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20221128/9900749b/attachment.obj>


More information about the Squeak-dev mailing list