2015-11-17 13:40 GMT+01:00 Peter Uhnák <i.uh...@gmail.com>: > > > On Tue, Nov 17, 2015 at 1:25 PM, Thierry Goubier < > thierry.goub...@gmail.com> wrote: > >> >> >> 2015-11-17 13:20 GMT+01:00 Peter Uhnák <i.uh...@gmail.com>: >> >>> Thanks! >>> >>> One more question though: is it possible to somehow reference the >>> method's name? >>> >>> For example I would like to rewrite method >>> >>> [[[ >>> navy >>> ^ self fromHexString: '000080' >>> ]]] >>> >>> to >>> >>> [[[ >>> navy >>> ^ ColorRegistry at: #navy ifAbsentPut: [ self fromHexString: '000080' ] >>> ]]] >>> >>> of course for that I would need to know the selector's name... >>> >>> ^ ColorRegistry at: ``@selector ifAbsentPut: [ self fromHexString: >>> ``@color ] >>> >>> Is it possible? >>> >> >> In RBParseTreeRewriter, yes. >> > > Could you give me an example? I am not sure how the "variable" parts are > expressed (since unlike RewriteTool there is not even a useful class > comment for the replacement). >
What you do is you add the necessary Smalltalk code to your meta variable in the RB 'search' pattern and there you can recover the method node and ask it the selector. I have an example in a Gist [1]: rewrite := RBParseTreeRewriter new replace: 'self parse: `#l `{:node :dic | | n | n := ''source'' , (node methodNode selector allButFirst: 4). dic at: #n put: n. PythonParserTests compile: (RBParser parseMethod: n, '' ^ '', `#l newSource) formattedCode classified: ''resources''. true }' with: 'self parse: `{:dic | RBParser parseExpression: ''self '', (dic at: #n) }'. What you do is, with the node you target (here the `#l), you add to it a block (the `{:node :dic | ... } ). The block usually refines the search (if the block returns true -> match, if it returns false -> match failed) but it can also execute arbitrary code and add contextual information for the rewrite. So, :node contains the matched node (here the literal) and, through it you can reach the method top node (#methodNode). And to use it in the rewrite, you store it in the :dic (this dictionary contains the variables matched); if you have multiple matches in the same method, then each time you will get a new dictionary. Beware: if your block is not in a message selector position in your pattern, then it behaves as a node (a variable) by itself. Using parenthesis in this case can help. Thierry [1]:https://gist.github.com/ThierryGoubier/54ba2fcf3cd2e7db9b1e > > Thanks, > Peter >