Has anyone built a source code tool to extract a specific argument from specific message sends?

64 views
Skip to first unread message

Richard Sargent

unread,
Sep 20, 2019, 8:12:13 PM9/20/19
to VA Smalltalk
I have a lot of methods which send messages similar to the following, but with varying numbers of arguments. I want to be able to automatically extract the symbols used as the argument to the #statusTag: keyword (to be able to keep a #packagerKnownSymbols implementation up to date).

    self gbsMessenger
        statusTag: #atOop:putClient:
        message: '%1 atOop: %2 putClient: %3'
        with: self
        with: (oop printStringRadix: 16)
        with: obj identityHash.

Any such tool or script would be welcome. Absent such a result, guidance on doing so effectively would also be appreciated.

Gabriel Cotelli

unread,
Sep 21, 2019, 3:36:52 PM9/21/19
to VA Smalltalk
You can use the rewrite searcher on the rewrite tools. I have some code doing something similar. If you don't figure it out for the Monday ping me and I can lookup the code for doing it

Steven LaFavor

unread,
Sep 22, 2019, 10:39:31 AM9/22/19
to VA Smalltalk
Does the symbol actually represent a Smalltalk message that will be performed or invoked?  If not, you could consider converting them into instances of EsAtom (##notAMessageButSomeSortOfState) so that you don't need to maintain the packagerKnownSymbols method at all.....

*Steve* 

Steven LaFavor

unread,
Sep 22, 2019, 3:20:42 PM9/22/19
to VA Smalltalk


On Sunday, September 22, 2019 at 9:39:31 AM UTC-5, Steven LaFavor wrote:
Does the symbol actually represent a Smalltalk message that will be performed or invoked?  If not, you could consider converting them into instances of EsAtom (##notAMessageButSomeSortOfState) so that you don't need to maintain the packagerKnownSymbols method at all.....

*Steve* 
 
Something was bothering me when I wrote this message, and in looking at it again, I now see the string in the message: argument that actually *is* the invocation of the method, so please ignore my response.

*Steve*

Gabriel Cotelli

unread,
Sep 23, 2019, 8:04:04 AM9/23/19
to VA Smalltalk
Richard, something like this should do the trick:

    | searcher symbols|

    symbols := Set new.
    searcher := ParseTreeSearcher new.
    searcher
        answer: false;
        matches: 'self gbsMessenger
        statusTag: `@symbol
        message: `@message
        with: `@first
        with: `@second
        with: `@third'
        do: [:node :answer | | literalValue |
            literalValue := node  arguments first value.
            literalValue isSymbol
                ifTrue: [symbols add: literalValue].
            false].

    SmalllintChecker newWithContext
        rule: (
            TransformationRule new
                rewriteUsing: searcher;
                yourself);
        environment: (
            ClassEnvironment
                onEnvironment: BrowserEnvironment new
                classes: ((System loadedApplications select: [:app | app name beginsWith: #Gb ] )
                inject: OrderedCollection new into: [:classes :app |
                    app withAllSubApplications do: [:subapp |
                classes addAll: subapp defined;yourself ].
            classes]));
        run.
        symbols

Richard Sargent

unread,
Sep 23, 2019, 12:43:14 PM9/23/19
to VA Smalltalk
Steve,

Your original response was fine. I don't understand your latest response. :-)

Atoms are not an option for me here because I need to maintain source code compatibility with other Smalltalks (as much as possible).

Richard Sargent

unread,
Sep 23, 2019, 2:15:59 PM9/23/19
to VA Smalltalk
On Monday, September 23, 2019 at 5:04:04 AM UTC-7, Gabriel Cotelli wrote:
Richard, something like this should do the trick:

Thanks, Gabriel. That will be helpful. Do you know if I can generalize the message pattern to include all variants of #statusTag:message:*? i.e. 0 to n #with: keywords and the most general #withArguments: keywords?

At this point, I am only asking to get a better understanding. I have scripted enumerating the list of selectors and finding the methods that send each. Getting the parse tree of each method is easy (#stsParseTree) and enumerating the nodes to find the appropriate EsKeywordPattern instance and extracting the #statusTag: argument is now relatively easy. (#allNodesDo:, #isKeywordPattern, arguments first, etc.)

Richard Sargent

unread,
Sep 23, 2019, 2:56:12 PM9/23/19
to VA Smalltalk
For those who care, the attached file is a script which does what I was seeking. Feel free to adapt it to your own needs.
(Note, a real object-oriented solution would utilize the parse tree visitor pattern defined for the Code Assist tools. This one is quick and dirty.)

ExampleProcessingParseTreeOfSendersOfSpecificSelectors.st
Reply all
Reply to author
Forward
0 new messages