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