Hi Mariano,

Le 20/11/2015 20:58, Mariano Martinez Peck a écrit :
Thierry,

Sorry to bother again. Unfortunately, RB does not work out of the box in
GemStone .... only the formatter part. grrr.

There is maybe a message to send to the maintainer of RB in Gemstone :)

Anyway, I am trying to make it work, and it's failing in this easy example:

/| tree rewriter |/
/tree := RBParser parseMethod: 'DoIt ^ [:proxy | proxy at: #oldSelector.
]'./
/rewriter := RBParseTreeRewriter new./
/rewriter /
/replace: ('`#oldSelector `{:node | node value isSymbol and: [node value
matchesRegex: ''.*oldSelector.*''] }')/
/with: ('`{RBLiteralNode value: (`#oldSelector value copyReplaceAll:
''oldSelector'' with: ''newSelector'') asSymbol }')./
/rewriter executeTree: tree./
/rewriter tree newSource/
And the problem is the line:

/with: ('`{RBLiteralNode value: (`#oldSelector value copyReplaceAll:
''oldSelector'' with: ''newSelector'') asSymbol }')./

which gets translated to:

[ :aDictionary |
RBLiteralNode
   value:
     ((*self* lookupMatchFor: '`#oldSelector' in: aDictionary) value
       copyReplaceAll: 'oldSelector'
       with: 'newSelector') asSymbol ]

The problem in GemStone is that that "self" is binded to nil and not to
the receiver instance (RBPatternBlockNode). And so I get a Nil dnu..
*And I don't know how that closure is finally generated.*

The message node:

/(*self* lookupMatchFor: '`#oldSelector' in: aDictionary) /

Its generated in:

RBPatternBlockNode >> constructLookupNodeFor: aString in: aRBBlockNode
| argumentNode |
argumentNode := RBLiteralNode value: aString.

^RBMessageNode
receiver:* (RBVariableNode named: 'self')*
selector: #lookupMatchFor:in:
arguments: (Array with: argumentNode with: aRBBlockNode arguments last)

Any ideas?

Yes. I think it is possible to work around it by using the dictionary itself, storing the node selector in it in the replace: pattern and retrieving it in the with: pattern.

rewriter
replace: ('`#oldSelector `{:node :dic | (node value isSymbol and: [node value matchesRegex: ''.*oldSelector.*'']) ifTrue: [dic at: #selector put: node value. true] ifFalse: [false] }') with: ('`{:dic | RBLiteralNode value: ((dic at: #selector) copyReplaceAll: ''oldSelector'' with: ''newSelector'') asSymbol }').

Now, maybe correcting RB in Gemstone is something to do, as well.

Regards,

Thierry

thanks in advance,


On Mon, Nov 9, 2015 at 2:39 PM, Thierry Goubier
<[email protected] <mailto:[email protected]>> wrote:

    Le 09/11/2015 17:38, Mariano Martinez Peck a écrit :

        Thierry, I have a last question. My last requirement will
        basically be
        to find ANY node that would match the regex *oldSelector* and
        rename it
        to *newSelector* being that.. a literal string, a literal symbol, a
        message send, a tempVar name, a comment, etc... I guess there is a
        simpler way that defining rewrite for each type of node right?
        I can always do a "(methodSource substrings detect: [:each | each
        matches: '*oldSelector'] ifNone: [#()] )   each2: [:each2 |
        copReplace.
        .... ]


    I think that if it is really everywhere, then it may works better to
    just do text replace (methodSource copyReplaceAll: 'oldSelector'
    with: 'newSelector').

    But remember that it will touch everything (pragmas, varNames,
    comments, etc.)

        but RB is probably better.


    It gives you more control to what you will change. But then you will
    have to write rewrites for all types of nodes (around 6 or 7?).

        Any clues in this last requirement?


    Well, one thing which may be interesting would be to consider
    encapsulating the rewrites in refactoring commands, and bring them
    as a composite change, so that you could launch a rewrite, recover
    all those method changes, apply (execute) them, check the result
    with the possibility of undoing them.

    But I'm not familiar with that part of RB. I do consider it could
    become significant with EPICEA. It has been a long term project to
    have AltBrowser make all coding actions as refactoring commands so
    that EPICEA could log them properly, but its only partly there (and
    has been for years now)... and EPICEA is not yet here as well (but
    could be soon).

    Thierry




--
Mariano
http://marianopeck.wordpress.com


Reply via email to