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


On Fri, Nov 6, 2015 at 12:33 PM, Thierry Goubier <thierry.goubier@gmail.com> wrote:


2015-11-06 16:17 GMT+01:00 Mariano Martinez Peck <marianopeck@gmail.com>:
Hi guys,

I have a very large kind of "rule engine" in which rules are written in smalltalk. These rules are saved as domain objects (imagine a rule kind of object) which end up having a closure. The code of those closure most of the time receives an argument and send messages to it.��
I want to add automatic method rename for rules. Let's say i have plenty of rules sending the message (rule) #price and now I want to refactor all senders to actually send #lastPrice.

I am taking a look to��RBRenameMethodRefactoring and friends. But I wonder if there is something specifically for managing blocks rather than methods/classes?

Just write a RBParseTreeRewriter rule with specific elements to only activate inside blocks.


Thanks Thierry, �� that helped me to get started. Note that all my closures are clean (#isClean answering true, that is, they are all self contained), and I also have the 'string' of them. So I have no problem to just re generate them :)

So this kind of worked:

| rewriter tree oldSeletor newSelector |
"next: build the method-like string out of our closure strings"
tree := RBParser parseMethod: 'DoIt ^ [:proxy |��
proxy at: #oldSelector.
proxy oldSelector.��
proxy oldSelectorAnotherMethod.
proxy do: ''oldSelectorAndSomething''.
"a comment with #oldSelector ��"
]'.
oldSeletor := #oldSelector.��
newSelector := #newSelector.

oldSeletor numArgs > 0 ifTrue: [ self error: 'For the moment we only support renaming selectors without arguments'].
rewriter := RBParseTreeRewriter replaceLiteral: oldSeletor with: newSelector.��
rewriter��
replace: '``@object ' , oldSeletor
with: '``@object ' , newSelector.

rewriter executeTree: tree.
tree ��newSource


And that answers:

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

��

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 'preoldSelectorpost' and I want it to be replaced by 'prenewSelectorpost'. And of course, I don't know in advance what pre and post strings there could be.

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 .. ��?

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,��




--



--