""" Generic AST transformation classes. """ class Transformer: """ Base class for AST transformers. """ def transform(self, ast): """ Transform the given AST and return the resulting AST. :param ast: The AST to transform :return: A 2-tuple: the transformed AST and a boolean indicating whether the transformation actually changed anything. The change detection is useful in situations where a transformation needs to be repeated until the AST stops changing. """ raise NotImplementedError("transform") class ChainTransformer(Transformer): """ A composite transformer which consists of a sequence of sub-transformers. Applying this transformer applies all sub-transformers in sequence, as a group. """ def __init__(self, *transformers): self.__transformers = transformers def transform(self, ast): changed = False for transformer in self.__transformers: ast, this_changed = transformer.transform(ast) if this_changed: changed = True return ast, changed class SettleTransformer(Transformer): """ A transformer that repeatedly performs a transformation until that transformation no longer changes the AST. I.e. the AST has "settled". """ def __init__(self, transform): self.__transformer = transform def transform(self, ast): changed = False ast, this_changed = self.__transformer.transform(ast) while this_changed: changed = True ast, this_changed = self.__transformer.transform(ast) return ast, changed