<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p>Hi Nicolas,</p>
<p><br>
</p>
<p>thank you for the details. Could you also say something about the Ocompletion question? Can I merge this? =D</p>
<p><br>
</p>
<p>Best,</p>
<p>Christoph</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com><br>
<b>Gesendet:</b> Montag, 14. Februar 2022 09:31:45<br>
<b>An:</b> The general-purpose Squeak developers list<br>
<b>Betreff:</b> Re: [squeak-dev] The Inbox: Tools-ct.1130.mcz</font>
<div> </div>
</div>
<div>
<div dir="ltr">
<div dir="ltr">Hi Christoph,<br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">Le lun. 14 févr. 2022 à 01:02, <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> a écrit :<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
A new version of Tools was added to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Tools-ct.1130.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/inbox/Tools-ct.1130.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Tools-ct.1130<br>
Author: ct<br>
Time: 14 February 2022, 1:02:43.784188 am<br>
UUID: e802d5d5-1c10-1146-9570-47e16bfc1f44<br>
Ancestors: Tools-mt.1129<br>
<br>
Fixes selection in SelectorBrowser aka Method Finder when the receiver is a brace array such as in:<br>
<br>
        {1. 2. 3}. 1<br>
<br>
Also simplies the reparsing logic of the example string slightly.<br>
<br>
Inbox because of two open questions:<br>
<br>
1) Does this break the selection of "external search results" (see #searchResult:)? It has zero senders in the Trunk and in Ocompletion.<br>
<br>
2) Is it a bug that "Scanner new scanTokens: '{1. 2. 3}'" does not answer a single item? If yes, shall we merge this patch anyway as a general refactoring?<br>
<br>
</blockquote>
<div>IMO it is not a bug.</div>
<div>The scanner only scans for lexical atoms (tokens).<br>
</div>
<div>A brace array shall not be parsed at lexical stage because it can contain arbitrarily complex grammatical expressions.</div>
<div>The job of assembling tokens in grammatical expressions belongs to Parser, and Parser does not output a stream of tokens,</div>
<div>it outputs an abstract syntax tree.</div>
<div>The fact that composed literals (literal arrays) can be scanned as atomic tokens could eventually be questioned, since the limit between lexical and grammatical scope is always somehow arbitrary, but it's rather a convenient split of responsibility.</div>
<div><br>
</div>
<div>Nicolas<br>
</div>
<div><br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
=============== Diff against Tools-mt.1129 ===============<br>
<br>
Item was changed:<br>
  ----- Method: SelectorBrowser>>markMatchingClasses (in category 'message list') -----<br>
  markMatchingClasses<br>
        "If an example is used, mark classes matching the example instance with an asterisk."<br>
<br>
        | unmarkedClassList firstPartOfSelector receiverString receiver |<br>
<br>
        self flag: #mref.       "allows for old-fashioned style"<br>
<br>
        "Only 'example' queries can be marked."<br>
        (contents asString includes: $.) ifFalse: [^ self].<br>
<br>
        unmarkedClassList := classList copy.<br>
<br>
        "Get the receiver object of the selected statement in the message list."<br>
+       firstPartOfSelector := self selectedMessageName keywords first.<br>
-       firstPartOfSelector := (Scanner new scanTokens: (selectorList at: selectorIndex)) second.<br>
        receiverString := (ReadStream on: (selectorList at: selectorIndex))<br>
                                                upToAll: firstPartOfSelector.<br>
        receiver := Compiler evaluate: receiverString.<br>
<br>
        unmarkedClassList do: [ :classAndMethod | | class |<br>
                (classAndMethod isKindOf: MethodReference) ifTrue: [<br>
                        (receiver isKindOf: classAndMethod actualClass) ifTrue: [<br>
                                classAndMethod stringVersion: '*', classAndMethod stringVersionDefault.<br>
                        ]<br>
                ] ifFalse: [<br>
                        class := Compiler evaluate:<br>
                                        ((ReadStream on: classAndMethod) upToAll: firstPartOfSelector).<br>
                        (receiver isKindOf: class) ifTrue: [<br>
                                classList add: '*', classAndMethod.<br>
                                classList remove: classAndMethod<br>
                        ]<br>
                ].<br>
        ].<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: SelectorBrowser>>quickList (in category 'selector finding') -----<br>
  quickList<br>
        "Compute the selectors for the single example of receiver and args, in the very top pane"
<br>
<br>
        | data result resultArray dataStrings mf dataObjects aa statements |<br>
        data := contents asString withBlanksTrimmed.<br>
        mf := MethodFinder new.<br>
        data := mf cleanInputs: data.   "remove common mistakes"<br>
        dataObjects := Compiler evaluate: '{', data, '}'. "#( data1 data2 result )"<br>
        statements := (Compiler new parse: 'zort ' , data in: Object notifying: nil)<br>
                                body statements select: [:each | (each isKindOf: ReturnNode) not].<br>
        dataStrings := statements collect:<br>
                                [:node | String streamContents:<br>
                                        [:strm | (node isMessage) ifTrue: [strm nextPut: $(].<br>
                                        node shortPrintOn: strm.<br>
                                        (node isMessage) ifTrue: [strm nextPut: $)].]].<br>
        dataObjects size < 2 ifTrue: [self inform: 'If you are giving an example of receiver, \args, and result, please put periods between the parts.\Otherwise just type one selector fragment' withCRs. ^#()].<br>
        dataObjects := Array with: dataObjects allButLast with: dataObjects last. "#( (data1<br>
    data2) result )" <br>
        result := mf load: dataObjects; findMessage.<br>
        (result first beginsWith: 'no single method') ifFalse: [<br>
                aa := self testObjects: dataObjects strings: dataStrings.<br>
                dataObjects := aa second.  dataStrings := aa third].<br>
        resultArray := self listFromResult: result. <br>
        resultArray isEmpty ifTrue: [self inform: result first].<br>
<br>
        dataStrings size = (dataObjects first size + 1) ifTrue:<br>
                [resultArray := resultArray collect: [:expression | | newExp |<br>
                newExp := expression.<br>
                dataObjects first withIndexDo: [:lit :i |<br>
                        newExp := newExp copyReplaceAll: 'data', i printString<br>
                                                        with: (dataStrings at: i)].<br>
+               newExp, self resultSeparator, dataStrings last]].<br>
-               newExp, ' --> ', dataStrings last]].<br>
<br>
        ^ resultArray!<br>
<br>
Item was added:<br>
+ ----- Method: SelectorBrowser>>resultSeparator (in category 'private') -----<br>
+ resultSeparator<br>
+ <br>
+       ^ ' --> '!<br>
<br>
Item was changed:<br>
  ----- Method: SelectorBrowser>>selectedMessageName (in category 'accessing') -----<br>
  selectedMessageName<br>
        "Answer the name of the currently selected message or nil if not a known Symbol."<br>
<br>
+       | example expression |<br>
-       | example tokens |<br>
        selectorIndex = 0 ifTrue: [^nil].<br>
        example := selectorList at: selectorIndex.<br>
+       example isSymbol ifTrue: [^ example].<br>
+       expression := example first: (example findLastOccurrenceOfString: self resultSeparator startingAt: 1) - 1.<br>
+       ^ expression findSelector!<br>
-       tokens := Scanner new scanTokens: example.<br>
-       tokens size = 1 ifTrue: [^ tokens first].<br>
-       tokens first == #'^' ifTrue: [^ nil].<br>
-       (tokens second includes: $:) ifTrue: [^ example findSelector].<br>
-       ^Symbol lookup: tokens second!<br>
<br>
<br>
</blockquote>
</div>
</div>
</div>
</body>
</html>