metadata.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. """
  2. This module provides a way to pass information between passes as metadata.
  3. * add attaches a metadata to a node
  4. * get retrieves all metadata from a particular class attached to a node
  5. """
  6. from gast import AST # so that metadata are walkable as regular ast nodes
  7. class Metadata(AST):
  8. """ Base class to add information on a node to improve code generation. """
  9. def __init__(self):
  10. """ Initialize content of these metadata. """
  11. self.data = list()
  12. self._fields = ('data',)
  13. super(Metadata, self).__init__()
  14. def __iter__(self):
  15. """ Enable iteration over every metadata informations. """
  16. return iter(self.data)
  17. def append(self, data):
  18. """ Add a metadata information. """
  19. self.data.append(data)
  20. class Lazy(AST):
  21. """ Metadata to mark variable which doesn't need to be evaluated now. """
  22. class Comprehension(AST):
  23. def __init__(self, *args): # no positional argument to be deep copyable
  24. super(Comprehension, self).__init__()
  25. if args:
  26. self.target = args[0]
  27. class StaticReturn(AST):
  28. """ Metadata to mark return with a constant value. """
  29. class Local(AST):
  30. """ Metadata to mark function as non exported. """
  31. def add(node, data):
  32. if not hasattr(node, 'metadata'):
  33. node.metadata = Metadata()
  34. node._fields += ('metadata',)
  35. node.metadata.append(data)
  36. def get(node, class_):
  37. if hasattr(node, 'metadata'):
  38. return [s for s in node.metadata if isinstance(s, class_)]
  39. else:
  40. return []
  41. def clear(node, class_):
  42. if hasattr(node, 'metadata'):
  43. node.metadata.data = [s for s in node.metadata
  44. if not isinstance(s, class_)]
  45. if not node.metadata.data:
  46. del node.metadata
  47. assert node._fields[-1] == 'metadata'
  48. node._fields = node._fields[:-1]
  49. def visit(self, node):
  50. if hasattr(node, 'metadata'):
  51. self.visit(node.metadata)