LibCST icon indicating copy to clipboard operation
LibCST copied to clipboard

Cannot deep_replace multiple nodes

Open willcrichton opened this issue 4 years ago • 0 comments

One consequence of the issue mentioned here, where CSTTransformer always replaces nodes, is that methods that rely on nodes-by-identity become harder to use in bulk.

For example, I'm trying to implement a rename(mod, src, dst) function that takes all instances of a src variable and renames them to dst, using the ScopeProvider. However, this code does not work:

for access in scope.accesses[src]:
  mod = mod.deep_replace(access.node, cst.Name(dst))

This is because after the first deep_replace, all nodes have been replaced, and the original scope is now invalidated. To fix this, you either have to rebuild the scopes after every deep_replace (inefficient), or batch-replace all nodes at the same time.

Perhaps y'all can consider adding a deep_replace_many? That is, enhance the _ChildReplacementTransformer to take multiple nodes. For example, I'm using the following class:


class ReplaceNodes(cst.CSTTransformer):
    def __init__(self, replacements):
        self.replacements = replacements

    def on_leave(self, original_node, updated_node):
        return self.replacements.get(original_node, updated_node)

willcrichton avatar Mar 27 '20 21:03 willcrichton