NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

ast.py (6135B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\ast.py
      2 from _ast import *
      3 from _ast import __version__
      4 
      5 def parse(expr, filename = '<unknown>', mode = 'exec'):
      6     return compile(expr, filename, mode, PyCF_ONLY_AST)
      7 
      8 
      9 def literal_eval(node_or_string):
     10     _safe_names = {'None': None,
     11      'True': True,
     12      'False': False}
     13     if isinstance(node_or_string, basestring):
     14         node_or_string = parse(node_or_string, mode='eval')
     15     if isinstance(node_or_string, Expression):
     16         node_or_string = node_or_string.body
     17 
     18     def _convert(node):
     19         if isinstance(node, Str):
     20             return node.s
     21         if isinstance(node, Num):
     22             return node.n
     23         if isinstance(node, Tuple):
     24             return tuple(map(_convert, node.elts))
     25         if isinstance(node, List):
     26             return list(map(_convert, node.elts))
     27         if isinstance(node, Dict):
     28             return dict(((_convert(k), _convert(v)) for k, v in zip(node.keys, node.values)))
     29         if isinstance(node, Name):
     30             if node.id in _safe_names:
     31                 return _safe_names[node.id]
     32         elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)) and isinstance(node.right, Num) and isinstance(node.right.n, complex) and isinstance(node.left, Num):
     33             if isinstance(node.left.n, (int, long, float)):
     34                 left = node.left.n
     35                 right = node.right.n
     36                 if isinstance(node.op, Add):
     37                     return left + right
     38                 return left - right
     39         raise ValueError('malformed string')
     40 
     41     return _convert(node_or_string)
     42 
     43 
     44 def dump(node, annotate_fields = True, include_attributes = False):
     45 
     46     def _format(node):
     47         if isinstance(node, AST):
     48             fields = [ (a, _format(b)) for a, b in iter_fields(node) ]
     49             rv = '%s(%s' % (node.__class__.__name__, ', '.join(('%s=%s' % field for field in fields) if annotate_fields else (b for a, b in fields)))
     50             if include_attributes and node._attributes:
     51                 rv += fields and ', ' or ' '
     52                 rv += ', '.join(('%s=%s' % (a, _format(getattr(node, a))) for a in node._attributes))
     53             return rv + ')'
     54         if isinstance(node, list):
     55             return '[%s]' % ', '.join((_format(x) for x in node))
     56         return repr(node)
     57 
     58     if not isinstance(node, AST):
     59         raise TypeError('expected AST, got %r' % node.__class__.__name__)
     60     return _format(node)
     61 
     62 
     63 def copy_location(new_node, old_node):
     64     for attr in ('lineno', 'col_offset'):
     65         if attr in old_node._attributes and attr in new_node._attributes and hasattr(old_node, attr):
     66             setattr(new_node, attr, getattr(old_node, attr))
     67 
     68     return new_node
     69 
     70 
     71 def fix_missing_locations(node):
     72 
     73     def _fix(node, lineno, col_offset):
     74         if 'lineno' in node._attributes:
     75             if not hasattr(node, 'lineno'):
     76                 node.lineno = lineno
     77             else:
     78                 lineno = node.lineno
     79         if 'col_offset' in node._attributes:
     80             if not hasattr(node, 'col_offset'):
     81                 node.col_offset = col_offset
     82             else:
     83                 col_offset = node.col_offset
     84         for child in iter_child_nodes(node):
     85             _fix(child, lineno, col_offset)
     86 
     87     _fix(node, 1, 0)
     88     return node
     89 
     90 
     91 def increment_lineno(node, n = 1):
     92     if 'lineno' in node._attributes:
     93         node.lineno = getattr(node, 'lineno', 0) + n
     94     for child in walk(node):
     95         if 'lineno' in child._attributes:
     96             child.lineno = getattr(child, 'lineno', 0) + n
     97 
     98     return node
     99 
    100 
    101 def iter_fields(node):
    102     for field in node._fields:
    103         try:
    104             yield (field, getattr(node, field))
    105         except AttributeError:
    106             pass
    107 
    108 
    109 def iter_child_nodes(node):
    110     for name, field in iter_fields(node):
    111         if isinstance(field, AST):
    112             yield field
    113         elif isinstance(field, list):
    114             for item in field:
    115                 if isinstance(item, AST):
    116                     yield item
    117 
    118 
    119 def get_docstring(node, clean = True):
    120     if not isinstance(node, (FunctionDef, ClassDef, Module)):
    121         raise TypeError("%r can't have docstrings" % node.__class__.__name__)
    122     if node.body and isinstance(node.body[0], Expr) and isinstance(node.body[0].value, Str):
    123         if clean:
    124             import inspect
    125             return inspect.cleandoc(node.body[0].value.s)
    126         return node.body[0].value.s
    127 
    128 
    129 def walk(node):
    130     from collections import deque
    131     todo = deque([node])
    132     while todo:
    133         node = todo.popleft()
    134         todo.extend(iter_child_nodes(node))
    135         yield node
    136 
    137 
    138 class NodeVisitor(object):
    139 
    140     def visit(self, node):
    141         method = 'visit_' + node.__class__.__name__
    142         visitor = getattr(self, method, self.generic_visit)
    143         return visitor(node)
    144 
    145     def generic_visit(self, node):
    146         for field, value in iter_fields(node):
    147             if isinstance(value, list):
    148                 for item in value:
    149                     if isinstance(item, AST):
    150                         self.visit(item)
    151 
    152             elif isinstance(value, AST):
    153                 self.visit(value)
    154 
    155 
    156 class NodeTransformer(NodeVisitor):
    157 
    158     def generic_visit(self, node):
    159         for field, old_value in iter_fields(node):
    160             old_value = getattr(node, field, None)
    161             if isinstance(old_value, list):
    162                 new_values = []
    163                 for value in old_value:
    164                     if isinstance(value, AST):
    165                         value = self.visit(value)
    166                         if value is None:
    167                             continue
    168                         elif not isinstance(value, AST):
    169                             new_values.extend(value)
    170                             continue
    171                     new_values.append(value)
    172 
    173                 old_value[:] = new_values
    174             elif isinstance(old_value, AST):
    175                 new_node = self.visit(old_value)
    176                 if new_node is None:
    177                     delattr(node, field)
    178                 else:
    179                     setattr(node, field, new_node)
    180 
    181         return node