# HG changeset patch # User Paul Boddie # Date 1342287406 -7200 # Node ID a7d2b3dc0f65659e12717d25fcada79eae7f3a9b # Parent 948ff107ee00f4e06ccfa739135e5a3e8d28bb2d Introduced an AttributeUser superclass so that attribute usage annotations can be made on nodes without having to add attributes to nodes after their initialisation. diff -r 948ff107ee00 -r a7d2b3dc0f65 compiler/ast.py --- a/compiler/ast.py Sat Jul 14 19:32:22 2012 +0200 +++ b/compiler/ast.py Sat Jul 14 19:36:46 2012 +0200 @@ -40,17 +40,46 @@ nodes = {} -class Node: - """Abstract base class for ast nodes.""" +class AttributeUser: + + "Annotation-related node." + + def __init__(self): + + # Name and usage observations. + + self._attrnames = None + self._attrcombined = None + self._attrmerged = None + + # Related nodes. + + self._attrbranches = None + self._attrcontributors = None + self._attrdefs = None + + # Deductions. + + self._attrtypes = None + self._attrspecifictypes = None + +class Node(AttributeUser): + + "Abstract base class for ast nodes." + def getChildren(self): pass # implemented by subclasses + def __iter__(self): for n in self.getChildren(): yield n + def asList(self): # for backwards compatibility return self.getChildren() + def getChildNodes(self): pass # implemented by subclasses + def visit(self, visitor, *args): visitor.default(self, *args) @@ -61,6 +90,7 @@ # Expression is an artificial node class to support "eval" nodes["expression"] = "Expression" def __init__(self, node): + Node.__init__(self) self.node = node def getChildren(self): @@ -80,6 +110,7 @@ class Add(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -101,6 +132,7 @@ class And(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -123,11 +155,17 @@ class AssAttr(Node): def __init__(self, expr, attrname, flags, lineno=None): + Node.__init__(self) self.expr = expr self.attrname = attrname self.flags = flags self.lineno = lineno + # Additional annotations. + + self._attr = None + self._attrusers = None + def getChildren(self): return self.expr, self.attrname, self.flags @@ -148,6 +186,7 @@ class AssList(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -170,6 +209,7 @@ class AssName(Node): def __init__(self, name, flags, lineno=None): + Node.__init__(self) self.name = name self.flags = flags self.lineno = lineno @@ -194,6 +234,7 @@ class AssTuple(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -216,6 +257,7 @@ class Assert(Node): def __init__(self, test, fail, lineno=None): + Node.__init__(self) self.test = test self.fail = fail self.lineno = lineno @@ -244,6 +286,7 @@ class Assign(Node): def __init__(self, nodes, expr, lineno=None): + Node.__init__(self) self.nodes = nodes self.expr = expr self.lineno = lineno @@ -271,6 +314,7 @@ class AugAssign(Node): def __init__(self, node, op, expr, lineno=None): + Node.__init__(self) self.node = node self.op = op self.expr = expr @@ -293,6 +337,7 @@ class Backquote(Node): def __init__(self, expr, lineno=None): + Node.__init__(self) self.expr = expr self.lineno = lineno @@ -313,6 +358,7 @@ class Bitand(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -335,6 +381,7 @@ class Bitor(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -357,6 +404,7 @@ class Bitxor(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -379,6 +427,7 @@ class Break(Node): def __init__(self, lineno=None): + Node.__init__(self) self.lineno = lineno def getChildren(self): @@ -398,6 +447,7 @@ class CallFunc(Node): def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None): + Node.__init__(self) self.node = node self.args = args self.star_args = star_args @@ -435,6 +485,7 @@ class Class(Node): def __init__(self, name, bases, doc, code, decorators = None, lineno=None): + Node.__init__(self) self.name = name self.bases = bases self.doc = doc @@ -476,6 +527,7 @@ class Compare(Node): def __init__(self, expr, ops, lineno=None): + Node.__init__(self) self.expr = expr self.ops = ops self.lineno = lineno @@ -503,6 +555,7 @@ class Const(Node): def __init__(self, value, lineno=None): + Node.__init__(self) self.value = value self.lineno = lineno @@ -523,6 +576,7 @@ class Continue(Node): def __init__(self, lineno=None): + Node.__init__(self) self.lineno = lineno def getChildren(self): @@ -542,6 +596,7 @@ class Decorators(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -564,6 +619,7 @@ class Dict(Node): def __init__(self, items, lineno=None): + Node.__init__(self) self.items = items self.lineno = lineno @@ -586,6 +642,7 @@ class Discard(Node): def __init__(self, expr, lineno=None): + Node.__init__(self) self.expr = expr self.lineno = lineno @@ -606,6 +663,7 @@ class Div(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -627,6 +685,7 @@ class Ellipsis(Node): def __init__(self, lineno=None): + Node.__init__(self) self.lineno = lineno def getChildren(self): @@ -646,6 +705,7 @@ class Exec(Node): def __init__(self, expr, locals, globals, lineno=None): + Node.__init__(self) self.expr = expr self.locals = locals self.globals = globals @@ -679,6 +739,7 @@ class FloorDiv(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -700,6 +761,7 @@ class For(Node): def __init__(self, assign, list, body, else_, lineno=None): + Node.__init__(self) self.assign = assign self.list = list self.body = body @@ -738,6 +800,7 @@ class From(Node): def __init__(self, modname, names, level, lineno=None): + Node.__init__(self) self.modname = modname self.names = names self.level = level @@ -761,6 +824,7 @@ class Function(Node): def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None): + Node.__init__(self) self.decorators = decorators self.name = name self.argnames = argnames @@ -813,6 +877,7 @@ class GenExpr(Node): def __init__(self, code, lineno=None): + Node.__init__(self) self.code = code self.lineno = lineno self.argnames = ['.0'] @@ -835,6 +900,7 @@ class GenExprFor(Node): def __init__(self, assign, iter, ifs, lineno=None): + Node.__init__(self) self.assign = assign self.iter = iter self.ifs = ifs @@ -869,6 +935,7 @@ class GenExprIf(Node): def __init__(self, test, lineno=None): + Node.__init__(self) self.test = test self.lineno = lineno @@ -889,6 +956,7 @@ class GenExprInner(Node): def __init__(self, expr, quals, lineno=None): + Node.__init__(self) self.expr = expr self.quals = quals self.lineno = lineno @@ -916,10 +984,16 @@ class Getattr(Node): def __init__(self, expr, attrname, lineno=None): + Node.__init__(self) self.expr = expr self.attrname = attrname self.lineno = lineno + # Additional annotations. + + self._attr = None + self._attrusers = None + def getChildren(self): return self.expr, self.attrname @@ -937,6 +1011,7 @@ class Global(Node): def __init__(self, names, lineno=None): + Node.__init__(self) self.names = names self.lineno = lineno @@ -957,6 +1032,7 @@ class If(Node): def __init__(self, tests, else_, lineno=None): + Node.__init__(self) self.tests = tests self.else_ = else_ self.lineno = lineno @@ -989,6 +1065,7 @@ class IfExp(Node): def __init__(self, test, then, else_, lineno=None): + Node.__init__(self) self.test = test self.then = then self.else_ = else_ @@ -1011,6 +1088,7 @@ class Import(Node): def __init__(self, names, lineno=None): + Node.__init__(self) self.names = names self.lineno = lineno @@ -1032,6 +1110,7 @@ class Invert(Node): def __init__(self, expr, lineno=None): + Node.__init__(self) self.expr = expr self.lineno = lineno @@ -1052,6 +1131,7 @@ class Keyword(Node): def __init__(self, name, expr, lineno=None): + Node.__init__(self) self.name = name self.expr = expr self.lineno = lineno @@ -1073,6 +1153,7 @@ class Lambda(Node): def __init__(self, argnames, defaults, flags, code, lineno=None): + Node.__init__(self) self.argnames = argnames self.defaults = defaults self.flags = flags @@ -1110,6 +1191,7 @@ class LeftShift(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -1131,6 +1213,7 @@ class List(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -1153,6 +1236,7 @@ class ListComp(Node): def __init__(self, expr, quals, lineno=None): + Node.__init__(self) self.expr = expr self.quals = quals self.lineno = lineno @@ -1180,6 +1264,7 @@ class ListCompFor(Node): def __init__(self, assign, list, ifs, lineno=None): + Node.__init__(self) self.assign = assign self.list = list self.ifs = ifs @@ -1213,6 +1298,7 @@ class ListCompIf(Node): def __init__(self, test, lineno=None): + Node.__init__(self) self.test = test self.lineno = lineno @@ -1233,6 +1319,7 @@ class Mod(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -1254,6 +1341,7 @@ class Module(Node): def __init__(self, doc, node, lineno=None): + Node.__init__(self) self.doc = doc self.node = node self.lineno = lineno @@ -1275,6 +1363,7 @@ class Mul(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -1296,9 +1385,15 @@ class Name(Node): def __init__(self, name, lineno=None): + Node.__init__(self) self.name = name self.lineno = lineno + # Additional annotations. + + self._scope = None + self._attr = None + def getChildren(self): return self.name, @@ -1316,6 +1411,7 @@ class Not(Node): def __init__(self, expr, lineno=None): + Node.__init__(self) self.expr = expr self.lineno = lineno @@ -1336,6 +1432,7 @@ class Or(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -1358,6 +1455,7 @@ class Pass(Node): def __init__(self, lineno=None): + Node.__init__(self) self.lineno = lineno def getChildren(self): @@ -1377,6 +1475,7 @@ class Power(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -1398,6 +1497,7 @@ class Print(Node): def __init__(self, nodes, dest, lineno=None): + Node.__init__(self) self.nodes = nodes self.dest = dest self.lineno = lineno @@ -1427,6 +1527,7 @@ class Printnl(Node): def __init__(self, nodes, dest, lineno=None): + Node.__init__(self) self.nodes = nodes self.dest = dest self.lineno = lineno @@ -1456,6 +1557,7 @@ class Raise(Node): def __init__(self, expr1, expr2, expr3, lineno=None): + Node.__init__(self) self.expr1 = expr1 self.expr2 = expr2 self.expr3 = expr3 @@ -1492,6 +1594,7 @@ class Return(Node): def __init__(self, value, lineno=None): + Node.__init__(self) self.value = value self.lineno = lineno @@ -1512,6 +1615,7 @@ class RightShift(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -1533,6 +1637,7 @@ class Slice(Node): def __init__(self, expr, flags, lower, upper, lineno=None): + Node.__init__(self) self.expr = expr self.flags = flags self.lower = lower @@ -1570,6 +1675,7 @@ class Sliceobj(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -1592,6 +1698,7 @@ class Stmt(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -1614,6 +1721,7 @@ class Sub(Node): def __init__(self, leftright, lineno=None): + Node.__init__(self) self.left = leftright[0] self.right = leftright[1] self.lineno = lineno @@ -1635,6 +1743,7 @@ class Subscript(Node): def __init__(self, expr, flags, subs, lineno=None): + Node.__init__(self) self.expr = expr self.flags = flags self.subs = subs @@ -1664,6 +1773,7 @@ class TryExcept(Node): def __init__(self, body, handlers, else_, lineno=None): + Node.__init__(self) self.body = body self.handlers = handlers self.else_ = else_ @@ -1704,6 +1814,7 @@ class TryFinally(Node): def __init__(self, body, final, lineno=None): + Node.__init__(self) self.body = body self.final = final self.lineno = lineno @@ -1728,6 +1839,7 @@ class Tuple(Node): def __init__(self, nodes, lineno=None): + Node.__init__(self) self.nodes = nodes self.lineno = lineno @@ -1750,6 +1862,7 @@ class UnaryAdd(Node): def __init__(self, expr, lineno=None): + Node.__init__(self) self.expr = expr self.lineno = lineno @@ -1770,6 +1883,7 @@ class UnarySub(Node): def __init__(self, expr, lineno=None): + Node.__init__(self) self.expr = expr self.lineno = lineno @@ -1790,6 +1904,7 @@ class While(Node): def __init__(self, test, body, else_, lineno=None): + Node.__init__(self) self.test = test self.body = body self.else_ = else_ @@ -1825,6 +1940,7 @@ class With(Node): def __init__(self, expr, vars, body, lineno=None): + Node.__init__(self) self.expr = expr self.vars = vars self.body = body @@ -1860,6 +1976,7 @@ class Yield(Node): def __init__(self, value, lineno=None): + Node.__init__(self) self.value = value self.lineno = lineno