On 21/03/15 05:51, tsuna wrote:
> (resurrecting an old thread)
>
> I just found myself in a similar situation. I have a large code base
> in which I’m trying to change a lot of &foo{a: 1, b: “two”} to
> newFoo(1, “two”). In just 100 lines I was able to write a Go program
> that does almost that – really cool!
>
> The “almost” part is because I match on an UnaryExpr that is made of
> Op == “&” and CompositeLit with Name == “foo”. But I can’t replace
> the UnaryExpr itself. So my program rewrites &foo{a: 1, b: “two”} to
> &newFoo(1, “two”) … bleh.
>
> I didn’t find any way to get rid of the “&”, so I had to use my
> program to rewrite the code base and then sed the extra ampersand out.
>
> This made me think that an elegant solution to this problem would be
> to have another version of ast.Walk() that is implemented slightly
> differently. Walk() is basically just a big switch on the node type
> to recursively invoke the Visitor. But if we had a Visitor that
> returned (Node, Visitor) and simply re-inserted the returned Node in
> the original AST, where the original was found, then we could rewrite
> the entire AST as we go.
>
> I implemented this idea here, based on the original code from
> ast.Walk():
https://github.com/tsuna/gorewrite
> I easily migrated my code from Visitor + Walk() to Rewriter +
> Rewrite() – basically just had to change a method name and return the
> modified Node, and it worked just fine.