On Fri, Nov 6, 2015 at 12:33 PM, Thierry Goubier <[email protected]> wrote:
> > > 2015-11-06 16:17 GMT+01:00 Mariano Martinez Peck <[email protected]>: > >> 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 "* * ]'* > 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
