On 01/23/2017 10:00 AM, Yuriy Tymchuk wrote:
I think that we hacked too much :). I like how ParsetreeRewriter is working, but I think that it would be nice to have some API to say: ok, I have this node, now I want to replace it (maybe it should generate a new changed tree), so the pattern syntax would be more of a nice interface instead of a single entry point.
Anyway, I also think that this substitution without reformatting is really cool. I need to double check it, because I think that many uses do not use auto fix from lint rules because it reformats their code.
The RB works at the AST level, so you always need to replace a node. If you want to specify your own custom source when doing a replacement, you could create a method like this: RBProgramNode>>replaceWith: aNode andSource: aString | method | parent ifNil: [ self error: 'This node doesn''t have a parent' ]. method := self methodNode. method notNil ifTrue: [ method map: self to: aNode ]. aNode parent: self parent. self addReplacement: (RBStringReplacement replaceFrom: self start to: self stop with: aString). parent replaceNode: self withNode: aNode Then you could use it with something like this: | source method | source := 'method ^1'. method := RBParser parseMethod: source. method body statements first value replaceWith: (RBParser parseExpression: '2 - 1') andSource: '2 - 1'. method newSource Here, the "-" and "1" should appear on separate lines. However, if you gave invalid source, you get the formatted version: | source method | source := 'method ^1'. method := RBParser parseMethod: source. method body statements first value replaceWith: (RBParser parseExpression: '2 - 1') andSource: '2 - 2'. method newSource Here the "2 - 2" expression in the replacement source, isn't equal to the "2 - 1" expression node that was provided so it uses the formatted code of the parse tree. John Brant