2015-11-09 13:58 GMT+01:00 Mariano Martinez Peck <marianopeck@gmail.com>:


On Mon, Nov 9, 2015 at 6:07 AM, Thierry Goubier <thierry.goubier@gmail.com> wrote:


2015-11-09 6:38 GMT+01:00 Thierry Goubier <thierry.goubier@gmail.com>:
Hi Mariano,

Le 09/11/2015 01:13, Mariano Martinez Peck a ��crit :


On Fri, Nov 6, 2015 at 1:59 PM, Mariano Martinez Peck
<marianopeck@gmail.com <mailto:marianopeck@gmail.com>> wrote:

...

Hi Thierry,

I am trying to achieve a similar case like the one I commented in this
post but I am unable to find the way.
Previously I wanted to replace say the literal #oldSelector to
#newSelector. Now,�� I need to use regular expressions. I mean, I would
need to find matches of '*oldSelector*' and do the replace with
'newSelector'. For example,�� the search may find
'*pre*oldSelector*post*' and I want it to be replaced by
'*pre*newSelector*post'. *And of course, I don't know in advance what
pre and post strings there could be.

What you need to do there is to use a match block after the @selector

`{:node | node selector matches: '.*oldSelector.*'}

Which would mean that your patterns become:

rewriter
�� �� �� �� replace: '``@object `oldSelector {:node | node selector matches: '.*oldSelector.*'}'
�� �� �� �� with: '``@object `newSelector {:node | node selector }'.


OK, thanks for the explanation.��

��

Wait, not entirely sure. I think you need to add a dictionary in the block to give the with: argument the pre and post string. And I'm not sure about the regular expression above as well.

I need to have access to the SmaCC code source, so I'll answer to you a bit later.

Ok, here is a first try that make a change pre and post included:

| tree |
RBParseTreeRewriter new
replace: '`@object `oldSelector `{:node | node selector asString matchesRegex: ''.*oldSelector.*''}'
with: '`@object newSelector';
executeTree:
(tree := RBParser
parseMethod:
'DoIt ^ [:proxy |��
proxy at: #oldSelector.
proxy preoldSelector.��
proxy oldSelectorAnotherMethod.
proxy do: ''oldSelectorAndSomething''.
"a comment with #oldSelector ��"
]').
tree newSource

But it does not replace yet the right selector.


Yes, this one replaced both #oldSelector and #preoldSelector to #newSelector right?

��
For that, I will recreate a message send:

| tree |
RBParseTreeRewriter new
replace: '`object `oldSelector `{:node | node selector asString matchesRegex: ''.*oldSelector.*''} `@args'
with: '`{RBMessageNode receiver: `object selector: (`oldSelector selector copyReplaceAll: ''oldSelector'' with: ''newSelector'') asSymbol arguments: `@args}';
executeTree:
(tree := RBParser
parseMethod:
'DoIt ^ [:proxy |��
proxy at: #oldSelector.
proxy preoldSelector.��
proxy oldSelectorAnotherMethod.
proxy do: ''oldSelectorAndSomething''.
"a comment with #oldSelector ��"
]').
tree newSource



Thanks Thierry for your efforts. Very much appreciated.
I tried the above but still did not work. I executed the very same example of yours (I pasted it) but the #newSource was:

DoIt ^ [:proxy |��
proxy at: #oldSelector.
proxy preoldSelector.��
proxy oldSelectorAnotherMethod.
proxy do: 'oldSelectorAndSomething'.
"a comment with #oldSelector ��"
]

I am trying in Pharo 4.0. And you?��

Pharo 4.0 as well. I made a mistake in my example :(, so I'm adding more test cases to check ;).

| tree |
RBParseTreeRewriter new
replace: '``@object `oldSelector `{:node | node selector asString matchesRegex: ''.*oldSelector.*''}'
with: '`{RBMessageNode receiver: ``@object selector: (`oldSelector copyReplaceAll: ''oldSelector'' with: ''newSelector'') asSymbol arguments: #()}';
executeTree:
(tree := RBParser
parseMethod:
'DoIt ^ [:proxy |��
proxy at: #oldSelector.
proxy preoldSelector.��
self preoldSelector oldSelectorPost.
proxy preoldSelector: proxy.
proxy oldSelectorAnotherMethod.
proxy do: ''oldSelectorAndSomething''.
"a comment with #oldSelector ��"
]').
tree newSource.

��
Now, I haven't tested with arguments on the message.

Yes..that's a different story. But for the time being, I can live without that :)

I'm trying it, but I end up in a subscriptOutOfBounds: error :(
��
��

Look how you can use pattern variables inside the blocks :)

This is very cool and extremely powerfull.


Yes, I saw it. I wasn't aware of that. Super powerful but I think it has some learning curve to master it, right?

Me too... Time to ask for some help.

Thierry
��
��
Thierry


��



Also..do you know where can I find some more info about RB? For example,
if I read this:

rewriter
replace: '``@object ' , oldSeletor
with: '``@object ' , newSelector.

Where can I read that�� ``@object�� ��means XXX ..�� ?

There is a first level of explanation in the Pharo for the Enterprise book; but, yes the pattern language is fairly complex.

Are you going to Smalltalks? John Brant is there and will give a talk on RB and SmaCC (two talks, I believe).

Thierry


Thanks in advance!



�� �� �� �� Or a cascade: a RBParseTreeSearcher which matches blocks; on
�� �� �� �� each block node you activate a rewriter.

�� �� �� �� However, there is an issue in rewriting blocks contents, because
�� �� �� �� it supposes that the method defining the block is recompiled;
�� �� �� �� it's significantly harder to make changes to the code of live
�� �� �� �� blocks (change the bytescode itself? What if the block has
�� �� �� �� multiples instances?).

�� �� �� �� Thierry


�� �� �� �� �� �� If not, I think my easiest path is to automatically compile
�� �� �� �� �� �� dummy/temporal�� classes/methods from the rules, perform the
�� �� �� �� �� �� refactor, then move source from methods to block closures,
�� �� �� �� �� �� and finally remove created classes.

�� �� �� �� �� �� Any pointer is appreciated.

�� �� �� �� �� �� best,

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





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




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





--