Commit 566d9347 authored by Jeremy Hylton's avatar Jeremy Hylton

compiler.transformer: correct lineno attribute when possible

SF patch #1015989

The basic idea of this patch is to compute lineno attributes for all AST nodes.  The actual
implementation lead to a lot of restructing and code cleanup.

The generated AST nodes now have an optional lineno argument to constructor.  Remove the
top-level asList(), since it didn't seem to serve any purpose.  Add an __iter__ to ast nodes.
Use isinstance() instead of explicit type tests.

Change transformer to use the new lineno attribute, which replaces three lines of code with one.
Use universal newlines so that we can get rid of special-case code for line endings.  Use
lookup_node() in a few more frequently called, but simple com_xxx methods().  Change string
exception to class exception.
parent 2ad68e69
"""Python abstract syntax node definitions """Python abstract syntax node definitions
This file is automatically generated. This file is automatically generated by Tools/compiler/astgen.py
""" """
from types import TupleType, ListType
from consts import CO_VARARGS, CO_VARKEYWORDS from consts import CO_VARARGS, CO_VARKEYWORDS
def flatten(list): def flatten(list):
l = [] l = []
for elt in list: for elt in list:
t = type(elt) t = type(elt)
if t is TupleType or t is ListType: if t is tuple or t is list:
for elt2 in flatten(elt): for elt2 in flatten(elt):
l.append(elt2) l.append(elt2)
else: else:
...@@ -19,29 +18,17 @@ def flatten(list): ...@@ -19,29 +18,17 @@ def flatten(list):
def flatten_nodes(list): def flatten_nodes(list):
return [n for n in flatten(list) if isinstance(n, Node)] return [n for n in flatten(list) if isinstance(n, Node)]
def asList(nodearg):
l = []
for item in nodearg:
if hasattr(item, "asList"):
l.append(item.asList())
else:
t = type(item)
if t is TupleType or t is ListType:
l.append(tuple(asList(item)))
else:
l.append(item)
return l
nodes = {} nodes = {}
class Node: # an abstract base class class Node:
lineno = None # provide a lineno for nodes that don't have one """Abstract base class for ast nodes."""
def getType(self):
pass # implemented by subclass
def getChildren(self): def getChildren(self):
pass # implemented by subclasses pass # implemented by subclasses
def asList(self): def __iter__(self):
return tuple(asList(self.getChildren())) for n in self.getChildren():
yield n
def asList(self): # for backwards compatibility
return self.getChildren()
def getChildNodes(self): def getChildNodes(self):
pass # implemented by subclasses pass # implemented by subclasses
...@@ -64,10 +51,10 @@ class Expression(Node): ...@@ -64,10 +51,10 @@ class Expression(Node):
return "Expression(%s)" % (repr(self.node)) return "Expression(%s)" % (repr(self.node))
class Add(Node): class Add(Node):
nodes["add"] = "Add" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -79,14 +66,12 @@ class Add(Node): ...@@ -79,14 +66,12 @@ class Add(Node):
return "Add((%s, %s))" % (repr(self.left), repr(self.right)) return "Add((%s, %s))" % (repr(self.left), repr(self.right))
class And(Node): class And(Node):
nodes["and"] = "And" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -97,11 +82,11 @@ class And(Node): ...@@ -97,11 +82,11 @@ class And(Node):
return "And(%s)" % (repr(self.nodes),) return "And(%s)" % (repr(self.nodes),)
class AssAttr(Node): class AssAttr(Node):
nodes["assattr"] = "AssAttr" def __init__(self, expr, attrname, flags, lineno=None):
def __init__(self, expr, attrname, flags):
self.expr = expr self.expr = expr
self.attrname = attrname self.attrname = attrname
self.flags = flags self.flags = flags
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.expr, self.attrname, self.flags return self.expr, self.attrname, self.flags
...@@ -113,14 +98,12 @@ class AssAttr(Node): ...@@ -113,14 +98,12 @@ class AssAttr(Node):
return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags)) return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags))
class AssList(Node): class AssList(Node):
nodes["asslist"] = "AssList" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -131,10 +114,10 @@ class AssList(Node): ...@@ -131,10 +114,10 @@ class AssList(Node):
return "AssList(%s)" % (repr(self.nodes),) return "AssList(%s)" % (repr(self.nodes),)
class AssName(Node): class AssName(Node):
nodes["assname"] = "AssName" def __init__(self, name, flags, lineno=None):
def __init__(self, name, flags):
self.name = name self.name = name
self.flags = flags self.flags = flags
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.name, self.flags return self.name, self.flags
...@@ -146,14 +129,12 @@ class AssName(Node): ...@@ -146,14 +129,12 @@ class AssName(Node):
return "AssName(%s, %s)" % (repr(self.name), repr(self.flags)) return "AssName(%s, %s)" % (repr(self.name), repr(self.flags))
class AssTuple(Node): class AssTuple(Node):
nodes["asstuple"] = "AssTuple" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -164,10 +145,10 @@ class AssTuple(Node): ...@@ -164,10 +145,10 @@ class AssTuple(Node):
return "AssTuple(%s)" % (repr(self.nodes),) return "AssTuple(%s)" % (repr(self.nodes),)
class Assert(Node): class Assert(Node):
nodes["assert"] = "Assert" def __init__(self, test, fail, lineno=None):
def __init__(self, test, fail):
self.test = test self.test = test
self.fail = fail self.fail = fail
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -178,17 +159,18 @@ class Assert(Node): ...@@ -178,17 +159,18 @@ class Assert(Node):
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
nodelist.append(self.test) nodelist.append(self.test)
if self.fail is not None: nodelist.append(self.fail) if self.fail is not None:
nodelist.append(self.fail)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "Assert(%s, %s)" % (repr(self.test), repr(self.fail)) return "Assert(%s, %s)" % (repr(self.test), repr(self.fail))
class Assign(Node): class Assign(Node):
nodes["assign"] = "Assign" def __init__(self, nodes, expr, lineno=None):
def __init__(self, nodes, expr):
self.nodes = nodes self.nodes = nodes
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -206,11 +188,11 @@ class Assign(Node): ...@@ -206,11 +188,11 @@ class Assign(Node):
return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr)) return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr))
class AugAssign(Node): class AugAssign(Node):
nodes["augassign"] = "AugAssign" def __init__(self, node, op, expr, lineno=None):
def __init__(self, node, op, expr):
self.node = node self.node = node
self.op = op self.op = op
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.node, self.op, self.expr return self.node, self.op, self.expr
...@@ -222,9 +204,9 @@ class AugAssign(Node): ...@@ -222,9 +204,9 @@ class AugAssign(Node):
return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr)) return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr))
class Backquote(Node): class Backquote(Node):
nodes["backquote"] = "Backquote" def __init__(self, expr, lineno=None):
def __init__(self, expr):
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.expr, return self.expr,
...@@ -236,14 +218,12 @@ class Backquote(Node): ...@@ -236,14 +218,12 @@ class Backquote(Node):
return "Backquote(%s)" % (repr(self.expr),) return "Backquote(%s)" % (repr(self.expr),)
class Bitand(Node): class Bitand(Node):
nodes["bitand"] = "Bitand" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -254,14 +234,12 @@ class Bitand(Node): ...@@ -254,14 +234,12 @@ class Bitand(Node):
return "Bitand(%s)" % (repr(self.nodes),) return "Bitand(%s)" % (repr(self.nodes),)
class Bitor(Node): class Bitor(Node):
nodes["bitor"] = "Bitor" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -272,14 +250,12 @@ class Bitor(Node): ...@@ -272,14 +250,12 @@ class Bitor(Node):
return "Bitor(%s)" % (repr(self.nodes),) return "Bitor(%s)" % (repr(self.nodes),)
class Bitxor(Node): class Bitxor(Node):
nodes["bitxor"] = "Bitxor" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -290,9 +266,8 @@ class Bitxor(Node): ...@@ -290,9 +266,8 @@ class Bitxor(Node):
return "Bitxor(%s)" % (repr(self.nodes),) return "Bitxor(%s)" % (repr(self.nodes),)
class Break(Node): class Break(Node):
nodes["break"] = "Break" def __init__(self, lineno=None):
def __init__(self, ): self.lineno = lineno
pass
def getChildren(self): def getChildren(self):
return () return ()
...@@ -304,12 +279,12 @@ class Break(Node): ...@@ -304,12 +279,12 @@ class Break(Node):
return "Break()" return "Break()"
class CallFunc(Node): class CallFunc(Node):
nodes["callfunc"] = "CallFunc" def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None):
def __init__(self, node, args, star_args = None, dstar_args = None):
self.node = node self.node = node
self.args = args self.args = args
self.star_args = star_args self.star_args = star_args
self.dstar_args = dstar_args self.dstar_args = dstar_args
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -323,20 +298,22 @@ class CallFunc(Node): ...@@ -323,20 +298,22 @@ class CallFunc(Node):
nodelist = [] nodelist = []
nodelist.append(self.node) nodelist.append(self.node)
nodelist.extend(flatten_nodes(self.args)) nodelist.extend(flatten_nodes(self.args))
if self.star_args is not None: nodelist.append(self.star_args) if self.star_args is not None:
if self.dstar_args is not None: nodelist.append(self.dstar_args) nodelist.append(self.star_args)
if self.dstar_args is not None:
nodelist.append(self.dstar_args)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args)) return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args))
class Class(Node): class Class(Node):
nodes["class"] = "Class" def __init__(self, name, bases, doc, code, lineno=None):
def __init__(self, name, bases, doc, code):
self.name = name self.name = name
self.bases = bases self.bases = bases
self.doc = doc self.doc = doc
self.code = code self.code = code
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -356,10 +333,10 @@ class Class(Node): ...@@ -356,10 +333,10 @@ class Class(Node):
return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code)) return "Class(%s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code))
class Compare(Node): class Compare(Node):
nodes["compare"] = "Compare" def __init__(self, expr, ops, lineno=None):
def __init__(self, expr, ops):
self.expr = expr self.expr = expr
self.ops = ops self.ops = ops
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -377,9 +354,9 @@ class Compare(Node): ...@@ -377,9 +354,9 @@ class Compare(Node):
return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops)) return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops))
class Const(Node): class Const(Node):
nodes["const"] = "Const" def __init__(self, value, lineno=None):
def __init__(self, value):
self.value = value self.value = value
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.value, return self.value,
...@@ -391,9 +368,8 @@ class Const(Node): ...@@ -391,9 +368,8 @@ class Const(Node):
return "Const(%s)" % (repr(self.value),) return "Const(%s)" % (repr(self.value),)
class Continue(Node): class Continue(Node):
nodes["continue"] = "Continue" def __init__(self, lineno=None):
def __init__(self, ): self.lineno = lineno
pass
def getChildren(self): def getChildren(self):
return () return ()
...@@ -405,28 +381,28 @@ class Continue(Node): ...@@ -405,28 +381,28 @@ class Continue(Node):
return "Continue()" return "Continue()"
class Decorators(Node): class Decorators(Node):
nodes["decorators"] = "Decorators" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
return tuple(flatten(self.nodes)) return tuple(flatten(self.nodes))
def getChildNodes(self): def getChildNodes(self):
return flatten_nodes(self.nodes) nodelist = []
nodelist.extend(flatten_nodes(self.nodes))
return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "Decorators(%s)" % (repr(self.nodes),) return "Decorators(%s)" % (repr(self.nodes),)
class Dict(Node): class Dict(Node):
nodes["dict"] = "Dict" def __init__(self, items, lineno=None):
def __init__(self, items):
self.items = items self.items = items
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.items))
children.extend(flatten(self.items))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -437,9 +413,9 @@ class Dict(Node): ...@@ -437,9 +413,9 @@ class Dict(Node):
return "Dict(%s)" % (repr(self.items),) return "Dict(%s)" % (repr(self.items),)
class Discard(Node): class Discard(Node):
nodes["discard"] = "Discard" def __init__(self, expr, lineno=None):
def __init__(self, expr):
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.expr, return self.expr,
...@@ -451,10 +427,10 @@ class Discard(Node): ...@@ -451,10 +427,10 @@ class Discard(Node):
return "Discard(%s)" % (repr(self.expr),) return "Discard(%s)" % (repr(self.expr),)
class Div(Node): class Div(Node):
nodes["div"] = "Div" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -466,9 +442,8 @@ class Div(Node): ...@@ -466,9 +442,8 @@ class Div(Node):
return "Div((%s, %s))" % (repr(self.left), repr(self.right)) return "Div((%s, %s))" % (repr(self.left), repr(self.right))
class Ellipsis(Node): class Ellipsis(Node):
nodes["ellipsis"] = "Ellipsis" def __init__(self, lineno=None):
def __init__(self, ): self.lineno = lineno
pass
def getChildren(self): def getChildren(self):
return () return ()
...@@ -480,11 +455,11 @@ class Ellipsis(Node): ...@@ -480,11 +455,11 @@ class Ellipsis(Node):
return "Ellipsis()" return "Ellipsis()"
class Exec(Node): class Exec(Node):
nodes["exec"] = "Exec" def __init__(self, expr, locals, globals, lineno=None):
def __init__(self, expr, locals, globals):
self.expr = expr self.expr = expr
self.locals = locals self.locals = locals
self.globals = globals self.globals = globals
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -496,18 +471,20 @@ class Exec(Node): ...@@ -496,18 +471,20 @@ class Exec(Node):
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
nodelist.append(self.expr) nodelist.append(self.expr)
if self.locals is not None: nodelist.append(self.locals) if self.locals is not None:
if self.globals is not None: nodelist.append(self.globals) nodelist.append(self.locals)
if self.globals is not None:
nodelist.append(self.globals)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals)) return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals))
class FloorDiv(Node): class FloorDiv(Node):
nodes["floordiv"] = "FloorDiv" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -519,12 +496,12 @@ class FloorDiv(Node): ...@@ -519,12 +496,12 @@ class FloorDiv(Node):
return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right)) return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right))
class For(Node): class For(Node):
nodes["for"] = "For" def __init__(self, assign, list, body, else_, lineno=None):
def __init__(self, assign, list, body, else_):
self.assign = assign self.assign = assign
self.list = list self.list = list
self.body = body self.body = body
self.else_ = else_ self.else_ = else_
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -539,17 +516,18 @@ class For(Node): ...@@ -539,17 +516,18 @@ class For(Node):
nodelist.append(self.assign) nodelist.append(self.assign)
nodelist.append(self.list) nodelist.append(self.list)
nodelist.append(self.body) nodelist.append(self.body)
if self.else_ is not None: nodelist.append(self.else_) if self.else_ is not None:
nodelist.append(self.else_)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_)) return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_))
class From(Node): class From(Node):
nodes["from"] = "From" def __init__(self, modname, names, lineno=None):
def __init__(self, modname, names):
self.modname = modname self.modname = modname
self.names = names self.names = names
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.modname, self.names return self.modname, self.names
...@@ -561,8 +539,7 @@ class From(Node): ...@@ -561,8 +539,7 @@ class From(Node):
return "From(%s, %s)" % (repr(self.modname), repr(self.names)) return "From(%s, %s)" % (repr(self.modname), repr(self.names))
class Function(Node): class Function(Node):
nodes["function"] = "Function" def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None):
def __init__(self, decorators, name, argnames, defaults, flags, doc, code):
self.decorators = decorators self.decorators = decorators
self.name = name self.name = name
self.argnames = argnames self.argnames = argnames
...@@ -570,18 +547,18 @@ class Function(Node): ...@@ -570,18 +547,18 @@ class Function(Node):
self.flags = flags self.flags = flags
self.doc = doc self.doc = doc
self.code = code self.code = code
self.lineno = lineno
self.varargs = self.kwargs = None self.varargs = self.kwargs = None
if flags & CO_VARARGS: if flags & CO_VARARGS:
self.varargs = 1 self.varargs = 1
if flags & CO_VARKEYWORDS: if flags & CO_VARKEYWORDS:
self.kwargs = 1 self.kwargs = 1
def getChildren(self): def getChildren(self):
children = [] children = []
if self.decorators: children.append(self.decorators)
children.append(flatten(self.decorators.nodes))
children.append(self.name) children.append(self.name)
children.append(self.argnames) children.append(self.argnames)
children.extend(flatten(self.defaults)) children.extend(flatten(self.defaults))
...@@ -592,8 +569,8 @@ class Function(Node): ...@@ -592,8 +569,8 @@ class Function(Node):
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
if self.decorators: if self.decorators is not None:
nodelist.extend(flatten_nodes(self.decorators.nodes)) nodelist.append(self.decorators)
nodelist.extend(flatten_nodes(self.defaults)) nodelist.extend(flatten_nodes(self.defaults))
nodelist.append(self.code) nodelist.append(self.code)
return tuple(nodelist) return tuple(nodelist)
...@@ -602,12 +579,12 @@ class Function(Node): ...@@ -602,12 +579,12 @@ class Function(Node):
return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code)) return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code))
class GenExpr(Node): class GenExpr(Node):
nodes["genexpr"] = "GenExpr" def __init__(self, code, lineno=None):
def __init__(self, code):
self.code = code self.code = code
self.lineno = lineno
self.argnames = ['[outmost-iterable]'] self.argnames = ['[outmost-iterable]']
self.varargs = self.kwargs = None self.varargs = self.kwargs = None
def getChildren(self): def getChildren(self):
...@@ -620,11 +597,11 @@ class GenExpr(Node): ...@@ -620,11 +597,11 @@ class GenExpr(Node):
return "GenExpr(%s)" % (repr(self.code),) return "GenExpr(%s)" % (repr(self.code),)
class GenExprFor(Node): class GenExprFor(Node):
nodes["genexprfor"] = "GenExprFor" def __init__(self, assign, iter, ifs, lineno=None):
def __init__(self, assign, iter, ifs):
self.assign = assign self.assign = assign
self.iter = iter self.iter = iter
self.ifs = ifs self.ifs = ifs
self.lineno = lineno
self.is_outmost = False self.is_outmost = False
...@@ -646,9 +623,9 @@ class GenExprFor(Node): ...@@ -646,9 +623,9 @@ class GenExprFor(Node):
return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs)) return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs))
class GenExprIf(Node): class GenExprIf(Node):
nodes["genexprif"] = "GenExprIf" def __init__(self, test, lineno=None):
def __init__(self, test):
self.test = test self.test = test
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.test, return self.test,
...@@ -660,10 +637,10 @@ class GenExprIf(Node): ...@@ -660,10 +637,10 @@ class GenExprIf(Node):
return "GenExprIf(%s)" % (repr(self.test),) return "GenExprIf(%s)" % (repr(self.test),)
class GenExprInner(Node): class GenExprInner(Node):
nodes["genexprinner"] = "GenExprInner" def __init__(self, expr, quals, lineno=None):
def __init__(self, expr, quals):
self.expr = expr self.expr = expr
self.quals = quals self.quals = quals
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -681,10 +658,10 @@ class GenExprInner(Node): ...@@ -681,10 +658,10 @@ class GenExprInner(Node):
return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals)) return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals))
class Getattr(Node): class Getattr(Node):
nodes["getattr"] = "Getattr" def __init__(self, expr, attrname, lineno=None):
def __init__(self, expr, attrname):
self.expr = expr self.expr = expr
self.attrname = attrname self.attrname = attrname
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.expr, self.attrname return self.expr, self.attrname
...@@ -696,9 +673,9 @@ class Getattr(Node): ...@@ -696,9 +673,9 @@ class Getattr(Node):
return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname)) return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname))
class Global(Node): class Global(Node):
nodes["global"] = "Global" def __init__(self, names, lineno=None):
def __init__(self, names):
self.names = names self.names = names
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.names, return self.names,
...@@ -710,10 +687,10 @@ class Global(Node): ...@@ -710,10 +687,10 @@ class Global(Node):
return "Global(%s)" % (repr(self.names),) return "Global(%s)" % (repr(self.names),)
class If(Node): class If(Node):
nodes["if"] = "If" def __init__(self, tests, else_, lineno=None):
def __init__(self, tests, else_):
self.tests = tests self.tests = tests
self.else_ = else_ self.else_ = else_
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -724,16 +701,17 @@ class If(Node): ...@@ -724,16 +701,17 @@ class If(Node):
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
nodelist.extend(flatten_nodes(self.tests)) nodelist.extend(flatten_nodes(self.tests))
if self.else_ is not None: nodelist.append(self.else_) if self.else_ is not None:
nodelist.append(self.else_)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "If(%s, %s)" % (repr(self.tests), repr(self.else_)) return "If(%s, %s)" % (repr(self.tests), repr(self.else_))
class Import(Node): class Import(Node):
nodes["import"] = "Import" def __init__(self, names, lineno=None):
def __init__(self, names):
self.names = names self.names = names
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.names, return self.names,
...@@ -745,9 +723,9 @@ class Import(Node): ...@@ -745,9 +723,9 @@ class Import(Node):
return "Import(%s)" % (repr(self.names),) return "Import(%s)" % (repr(self.names),)
class Invert(Node): class Invert(Node):
nodes["invert"] = "Invert" def __init__(self, expr, lineno=None):
def __init__(self, expr):
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.expr, return self.expr,
...@@ -759,10 +737,10 @@ class Invert(Node): ...@@ -759,10 +737,10 @@ class Invert(Node):
return "Invert(%s)" % (repr(self.expr),) return "Invert(%s)" % (repr(self.expr),)
class Keyword(Node): class Keyword(Node):
nodes["keyword"] = "Keyword" def __init__(self, name, expr, lineno=None):
def __init__(self, name, expr):
self.name = name self.name = name
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.name, self.expr return self.name, self.expr
...@@ -774,18 +752,18 @@ class Keyword(Node): ...@@ -774,18 +752,18 @@ class Keyword(Node):
return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr)) return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr))
class Lambda(Node): class Lambda(Node):
nodes["lambda"] = "Lambda" def __init__(self, argnames, defaults, flags, code, lineno=None):
def __init__(self, argnames, defaults, flags, code):
self.argnames = argnames self.argnames = argnames
self.defaults = defaults self.defaults = defaults
self.flags = flags self.flags = flags
self.code = code self.code = code
self.lineno = lineno
self.varargs = self.kwargs = None self.varargs = self.kwargs = None
if flags & CO_VARARGS: if flags & CO_VARARGS:
self.varargs = 1 self.varargs = 1
if flags & CO_VARKEYWORDS: if flags & CO_VARKEYWORDS:
self.kwargs = 1 self.kwargs = 1
def getChildren(self): def getChildren(self):
...@@ -806,10 +784,10 @@ class Lambda(Node): ...@@ -806,10 +784,10 @@ class Lambda(Node):
return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code)) return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code))
class LeftShift(Node): class LeftShift(Node):
nodes["leftshift"] = "LeftShift" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -821,14 +799,12 @@ class LeftShift(Node): ...@@ -821,14 +799,12 @@ class LeftShift(Node):
return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right)) return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right))
class List(Node): class List(Node):
nodes["list"] = "List" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -839,10 +815,10 @@ class List(Node): ...@@ -839,10 +815,10 @@ class List(Node):
return "List(%s)" % (repr(self.nodes),) return "List(%s)" % (repr(self.nodes),)
class ListComp(Node): class ListComp(Node):
nodes["listcomp"] = "ListComp" def __init__(self, expr, quals, lineno=None):
def __init__(self, expr, quals):
self.expr = expr self.expr = expr
self.quals = quals self.quals = quals
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -860,11 +836,11 @@ class ListComp(Node): ...@@ -860,11 +836,11 @@ class ListComp(Node):
return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals)) return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals))
class ListCompFor(Node): class ListCompFor(Node):
nodes["listcompfor"] = "ListCompFor" def __init__(self, assign, list, ifs, lineno=None):
def __init__(self, assign, list, ifs):
self.assign = assign self.assign = assign
self.list = list self.list = list
self.ifs = ifs self.ifs = ifs
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -884,9 +860,9 @@ class ListCompFor(Node): ...@@ -884,9 +860,9 @@ class ListCompFor(Node):
return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs)) return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs))
class ListCompIf(Node): class ListCompIf(Node):
nodes["listcompif"] = "ListCompIf" def __init__(self, test, lineno=None):
def __init__(self, test):
self.test = test self.test = test
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.test, return self.test,
...@@ -898,10 +874,10 @@ class ListCompIf(Node): ...@@ -898,10 +874,10 @@ class ListCompIf(Node):
return "ListCompIf(%s)" % (repr(self.test),) return "ListCompIf(%s)" % (repr(self.test),)
class Mod(Node): class Mod(Node):
nodes["mod"] = "Mod" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -913,10 +889,10 @@ class Mod(Node): ...@@ -913,10 +889,10 @@ class Mod(Node):
return "Mod((%s, %s))" % (repr(self.left), repr(self.right)) return "Mod((%s, %s))" % (repr(self.left), repr(self.right))
class Module(Node): class Module(Node):
nodes["module"] = "Module" def __init__(self, doc, node, lineno=None):
def __init__(self, doc, node):
self.doc = doc self.doc = doc
self.node = node self.node = node
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.doc, self.node return self.doc, self.node
...@@ -928,10 +904,10 @@ class Module(Node): ...@@ -928,10 +904,10 @@ class Module(Node):
return "Module(%s, %s)" % (repr(self.doc), repr(self.node)) return "Module(%s, %s)" % (repr(self.doc), repr(self.node))
class Mul(Node): class Mul(Node):
nodes["mul"] = "Mul" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -943,9 +919,9 @@ class Mul(Node): ...@@ -943,9 +919,9 @@ class Mul(Node):
return "Mul((%s, %s))" % (repr(self.left), repr(self.right)) return "Mul((%s, %s))" % (repr(self.left), repr(self.right))
class Name(Node): class Name(Node):
nodes["name"] = "Name" def __init__(self, name, lineno=None):
def __init__(self, name):
self.name = name self.name = name
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.name, return self.name,
...@@ -957,9 +933,9 @@ class Name(Node): ...@@ -957,9 +933,9 @@ class Name(Node):
return "Name(%s)" % (repr(self.name),) return "Name(%s)" % (repr(self.name),)
class Not(Node): class Not(Node):
nodes["not"] = "Not" def __init__(self, expr, lineno=None):
def __init__(self, expr):
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.expr, return self.expr,
...@@ -971,14 +947,12 @@ class Not(Node): ...@@ -971,14 +947,12 @@ class Not(Node):
return "Not(%s)" % (repr(self.expr),) return "Not(%s)" % (repr(self.expr),)
class Or(Node): class Or(Node):
nodes["or"] = "Or" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -989,9 +963,8 @@ class Or(Node): ...@@ -989,9 +963,8 @@ class Or(Node):
return "Or(%s)" % (repr(self.nodes),) return "Or(%s)" % (repr(self.nodes),)
class Pass(Node): class Pass(Node):
nodes["pass"] = "Pass" def __init__(self, lineno=None):
def __init__(self, ): self.lineno = lineno
pass
def getChildren(self): def getChildren(self):
return () return ()
...@@ -1003,10 +976,10 @@ class Pass(Node): ...@@ -1003,10 +976,10 @@ class Pass(Node):
return "Pass()" return "Pass()"
class Power(Node): class Power(Node):
nodes["power"] = "Power" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -1018,10 +991,10 @@ class Power(Node): ...@@ -1018,10 +991,10 @@ class Power(Node):
return "Power((%s, %s))" % (repr(self.left), repr(self.right)) return "Power((%s, %s))" % (repr(self.left), repr(self.right))
class Print(Node): class Print(Node):
nodes["print"] = "Print" def __init__(self, nodes, dest, lineno=None):
def __init__(self, nodes, dest):
self.nodes = nodes self.nodes = nodes
self.dest = dest self.dest = dest
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -1032,17 +1005,18 @@ class Print(Node): ...@@ -1032,17 +1005,18 @@ class Print(Node):
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
nodelist.extend(flatten_nodes(self.nodes)) nodelist.extend(flatten_nodes(self.nodes))
if self.dest is not None: nodelist.append(self.dest) if self.dest is not None:
nodelist.append(self.dest)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest)) return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest))
class Printnl(Node): class Printnl(Node):
nodes["printnl"] = "Printnl" def __init__(self, nodes, dest, lineno=None):
def __init__(self, nodes, dest):
self.nodes = nodes self.nodes = nodes
self.dest = dest self.dest = dest
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -1053,18 +1027,19 @@ class Printnl(Node): ...@@ -1053,18 +1027,19 @@ class Printnl(Node):
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
nodelist.extend(flatten_nodes(self.nodes)) nodelist.extend(flatten_nodes(self.nodes))
if self.dest is not None: nodelist.append(self.dest) if self.dest is not None:
nodelist.append(self.dest)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest)) return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest))
class Raise(Node): class Raise(Node):
nodes["raise"] = "Raise" def __init__(self, expr1, expr2, expr3, lineno=None):
def __init__(self, expr1, expr2, expr3):
self.expr1 = expr1 self.expr1 = expr1
self.expr2 = expr2 self.expr2 = expr2
self.expr3 = expr3 self.expr3 = expr3
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -1075,18 +1050,21 @@ class Raise(Node): ...@@ -1075,18 +1050,21 @@ class Raise(Node):
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
if self.expr1 is not None: nodelist.append(self.expr1) if self.expr1 is not None:
if self.expr2 is not None: nodelist.append(self.expr2) nodelist.append(self.expr1)
if self.expr3 is not None: nodelist.append(self.expr3) if self.expr2 is not None:
nodelist.append(self.expr2)
if self.expr3 is not None:
nodelist.append(self.expr3)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3)) return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3))
class Return(Node): class Return(Node):
nodes["return"] = "Return" def __init__(self, value, lineno=None):
def __init__(self, value):
self.value = value self.value = value
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.value, return self.value,
...@@ -1098,10 +1076,10 @@ class Return(Node): ...@@ -1098,10 +1076,10 @@ class Return(Node):
return "Return(%s)" % (repr(self.value),) return "Return(%s)" % (repr(self.value),)
class RightShift(Node): class RightShift(Node):
nodes["rightshift"] = "RightShift" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -1113,12 +1091,12 @@ class RightShift(Node): ...@@ -1113,12 +1091,12 @@ class RightShift(Node):
return "RightShift((%s, %s))" % (repr(self.left), repr(self.right)) return "RightShift((%s, %s))" % (repr(self.left), repr(self.right))
class Slice(Node): class Slice(Node):
nodes["slice"] = "Slice" def __init__(self, expr, flags, lower, upper, lineno=None):
def __init__(self, expr, flags, lower, upper):
self.expr = expr self.expr = expr
self.flags = flags self.flags = flags
self.lower = lower self.lower = lower
self.upper = upper self.upper = upper
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -1131,22 +1109,22 @@ class Slice(Node): ...@@ -1131,22 +1109,22 @@ class Slice(Node):
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
nodelist.append(self.expr) nodelist.append(self.expr)
if self.lower is not None: nodelist.append(self.lower) if self.lower is not None:
if self.upper is not None: nodelist.append(self.upper) nodelist.append(self.lower)
if self.upper is not None:
nodelist.append(self.upper)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper)) return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper))
class Sliceobj(Node): class Sliceobj(Node):
nodes["sliceobj"] = "Sliceobj" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -1157,14 +1135,12 @@ class Sliceobj(Node): ...@@ -1157,14 +1135,12 @@ class Sliceobj(Node):
return "Sliceobj(%s)" % (repr(self.nodes),) return "Sliceobj(%s)" % (repr(self.nodes),)
class Stmt(Node): class Stmt(Node):
nodes["stmt"] = "Stmt" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -1175,10 +1151,10 @@ class Stmt(Node): ...@@ -1175,10 +1151,10 @@ class Stmt(Node):
return "Stmt(%s)" % (repr(self.nodes),) return "Stmt(%s)" % (repr(self.nodes),)
class Sub(Node): class Sub(Node):
nodes["sub"] = "Sub" def __init__(self, (left, right), lineno=None):
def __init__(self, (left, right)):
self.left = left self.left = left
self.right = right self.right = right
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.left, self.right return self.left, self.right
...@@ -1190,11 +1166,11 @@ class Sub(Node): ...@@ -1190,11 +1166,11 @@ class Sub(Node):
return "Sub((%s, %s))" % (repr(self.left), repr(self.right)) return "Sub((%s, %s))" % (repr(self.left), repr(self.right))
class Subscript(Node): class Subscript(Node):
nodes["subscript"] = "Subscript" def __init__(self, expr, flags, subs, lineno=None):
def __init__(self, expr, flags, subs):
self.expr = expr self.expr = expr
self.flags = flags self.flags = flags
self.subs = subs self.subs = subs
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -1213,11 +1189,11 @@ class Subscript(Node): ...@@ -1213,11 +1189,11 @@ class Subscript(Node):
return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs)) return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs))
class TryExcept(Node): class TryExcept(Node):
nodes["tryexcept"] = "TryExcept" def __init__(self, body, handlers, else_, lineno=None):
def __init__(self, body, handlers, else_):
self.body = body self.body = body
self.handlers = handlers self.handlers = handlers
self.else_ = else_ self.else_ = else_
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -1230,17 +1206,18 @@ class TryExcept(Node): ...@@ -1230,17 +1206,18 @@ class TryExcept(Node):
nodelist = [] nodelist = []
nodelist.append(self.body) nodelist.append(self.body)
nodelist.extend(flatten_nodes(self.handlers)) nodelist.extend(flatten_nodes(self.handlers))
if self.else_ is not None: nodelist.append(self.else_) if self.else_ is not None:
nodelist.append(self.else_)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_)) return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_))
class TryFinally(Node): class TryFinally(Node):
nodes["tryfinally"] = "TryFinally" def __init__(self, body, final, lineno=None):
def __init__(self, body, final):
self.body = body self.body = body
self.final = final self.final = final
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.body, self.final return self.body, self.final
...@@ -1252,14 +1229,12 @@ class TryFinally(Node): ...@@ -1252,14 +1229,12 @@ class TryFinally(Node):
return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final)) return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final))
class Tuple(Node): class Tuple(Node):
nodes["tuple"] = "Tuple" def __init__(self, nodes, lineno=None):
def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] return tuple(flatten(self.nodes))
children.extend(flatten(self.nodes))
return tuple(children)
def getChildNodes(self): def getChildNodes(self):
nodelist = [] nodelist = []
...@@ -1270,9 +1245,9 @@ class Tuple(Node): ...@@ -1270,9 +1245,9 @@ class Tuple(Node):
return "Tuple(%s)" % (repr(self.nodes),) return "Tuple(%s)" % (repr(self.nodes),)
class UnaryAdd(Node): class UnaryAdd(Node):
nodes["unaryadd"] = "UnaryAdd" def __init__(self, expr, lineno=None):
def __init__(self, expr):
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.expr, return self.expr,
...@@ -1284,9 +1259,9 @@ class UnaryAdd(Node): ...@@ -1284,9 +1259,9 @@ class UnaryAdd(Node):
return "UnaryAdd(%s)" % (repr(self.expr),) return "UnaryAdd(%s)" % (repr(self.expr),)
class UnarySub(Node): class UnarySub(Node):
nodes["unarysub"] = "UnarySub" def __init__(self, expr, lineno=None):
def __init__(self, expr):
self.expr = expr self.expr = expr
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.expr, return self.expr,
...@@ -1298,11 +1273,11 @@ class UnarySub(Node): ...@@ -1298,11 +1273,11 @@ class UnarySub(Node):
return "UnarySub(%s)" % (repr(self.expr),) return "UnarySub(%s)" % (repr(self.expr),)
class While(Node): class While(Node):
nodes["while"] = "While" def __init__(self, test, body, else_, lineno=None):
def __init__(self, test, body, else_):
self.test = test self.test = test
self.body = body self.body = body
self.else_ = else_ self.else_ = else_
self.lineno = lineno
def getChildren(self): def getChildren(self):
children = [] children = []
...@@ -1315,16 +1290,17 @@ class While(Node): ...@@ -1315,16 +1290,17 @@ class While(Node):
nodelist = [] nodelist = []
nodelist.append(self.test) nodelist.append(self.test)
nodelist.append(self.body) nodelist.append(self.body)
if self.else_ is not None: nodelist.append(self.else_) if self.else_ is not None:
nodelist.append(self.else_)
return tuple(nodelist) return tuple(nodelist)
def __repr__(self): def __repr__(self):
return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_))
class Yield(Node): class Yield(Node):
nodes["yield"] = "Yield" def __init__(self, value, lineno=None):
def __init__(self, value):
self.value = value self.value = value
self.lineno = lineno
def getChildren(self): def getChildren(self):
return self.value, return self.value,
...@@ -1335,6 +1311,6 @@ class Yield(Node): ...@@ -1335,6 +1311,6 @@ class Yield(Node):
def __repr__(self): def __repr__(self):
return "Yield(%s)" % (repr(self.value),) return "Yield(%s)" % (repr(self.value),)
klasses = globals() for name, obj in globals().items():
for k in nodes.keys(): if isinstance(obj, type) and issubclass(obj, Node):
nodes[k] = klasses[nodes[k]] nodes[name.lower()] = obj
...@@ -14,7 +14,10 @@ parseFile(path) -> AST ...@@ -14,7 +14,10 @@ parseFile(path) -> AST
# #
# Modifications and improvements for Python 2.0 by Jeremy Hylton and # Modifications and improvements for Python 2.0 by Jeremy Hylton and
# Mark Hammond # Mark Hammond
#
# Some fixes to try to have correct line number on almost all nodes
# (except Module, Discard and Stmt) added by Sylvain Thenault
#
# Portions of this file are: # Portions of this file are:
# Copyright (C) 1997-1998 Greg Stein. All Rights Reserved. # Copyright (C) 1997-1998 Greg Stein. All Rights Reserved.
# #
...@@ -22,21 +25,20 @@ parseFile(path) -> AST ...@@ -22,21 +25,20 @@ parseFile(path) -> AST
# http://www.opensource.org/licenses/bsd-license.html # http://www.opensource.org/licenses/bsd-license.html
# and replace OWNER, ORGANIZATION, and YEAR as appropriate. # and replace OWNER, ORGANIZATION, and YEAR as appropriate.
from ast import * from compiler.ast import *
import parser import parser
# Care must be taken to use only symbols and tokens defined in Python
# 1.5.2 for code branches executed in 1.5.2
import symbol import symbol
import token import token
import sys import sys
error = 'walker.error' class WalkerError(StandardError):
pass
from consts import CO_VARARGS, CO_VARKEYWORDS from consts import CO_VARARGS, CO_VARKEYWORDS
from consts import OP_ASSIGN, OP_DELETE, OP_APPLY from consts import OP_ASSIGN, OP_DELETE, OP_APPLY
def parseFile(path): def parseFile(path):
f = open(path) f = open(path, "U")
# XXX The parser API tolerates files without a trailing newline, # XXX The parser API tolerates files without a trailing newline,
# but not strings without a trailing newline. Always add an extra # but not strings without a trailing newline. Always add an extra
# newline to the file contents, since we're going through the string # newline to the file contents, since we're going through the string
...@@ -68,6 +70,16 @@ def asList(nodes): ...@@ -68,6 +70,16 @@ def asList(nodes):
l.append(item) l.append(item)
return l return l
def extractLineNo(ast):
if not isinstance(ast[1], tuple):
# get a terminal node
return ast[2]
for child in ast[1:]:
if isinstance(child, tuple):
lineno = extractLineNo(child)
if lineno is not None:
return lineno
def Node(*args): def Node(*args):
kind = args[0] kind = args[0]
if nodes.has_key(kind): if nodes.has_key(kind):
...@@ -77,7 +89,7 @@ def Node(*args): ...@@ -77,7 +89,7 @@ def Node(*args):
print nodes[kind], len(args), args print nodes[kind], len(args), args
raise raise
else: else:
raise error, "Can't find appropriate Node type: %s" % str(args) raise WalkerEror, "Can't find appropriate Node type: %s" % str(args)
#return apply(ast.Node, args) #return apply(ast.Node, args)
class Transformer: class Transformer:
...@@ -108,17 +120,14 @@ class Transformer: ...@@ -108,17 +120,14 @@ class Transformer:
def transform(self, tree): def transform(self, tree):
"""Transform an AST into a modified parse tree.""" """Transform an AST into a modified parse tree."""
if type(tree) != type(()) and type(tree) != type([]): if not (isinstance(tree, tuple) or isinstance(tree, list)):
tree = parser.ast2tuple(tree, line_info=1) tree = parser.ast2tuple(tree, line_info=1)
return self.compile_node(tree) return self.compile_node(tree)
def parsesuite(self, text): def parsesuite(self, text):
"""Return a modified parse tree for the given suite text.""" """Return a modified parse tree for the given suite text."""
# Hack for handling non-native line endings on non-DOS like OSs.
# this can go now we have universal newlines?
text = text.replace('\x0d', '')
return self.transform(parser.suite(text)) return self.transform(parser.suite(text))
def parseexpr(self, text): def parseexpr(self, text):
"""Return a modified parse tree for the given expression text.""" """Return a modified parse tree for the given expression text."""
return self.transform(parser.expr(text)) return self.transform(parser.expr(text))
...@@ -156,7 +165,7 @@ class Transformer: ...@@ -156,7 +165,7 @@ class Transformer:
if n == symbol.classdef: if n == symbol.classdef:
return self.classdef(node[1:]) return self.classdef(node[1:])
raise error, ('unexpected node type', n) raise WalkerEror, ('unexpected node type', n)
def single_input(self, node): def single_input(self, node):
### do we want to do anything about being "interactive" ? ### do we want to do anything about being "interactive" ?
...@@ -254,9 +263,8 @@ class Transformer: ...@@ -254,9 +263,8 @@ class Transformer:
assert isinstance(code, Stmt) assert isinstance(code, Stmt)
assert isinstance(code.nodes[0], Discard) assert isinstance(code.nodes[0], Discard)
del code.nodes[0] del code.nodes[0]
n = Function(decorators, name, names, defaults, flags, doc, code) return Function(decorators, name, names, defaults, flags, doc, code,
n.lineno = lineno lineno=lineno)
return n
def lambdef(self, nodelist): def lambdef(self, nodelist):
# lambdef: 'lambda' [varargslist] ':' test # lambdef: 'lambda' [varargslist] ':' test
...@@ -269,9 +277,7 @@ class Transformer: ...@@ -269,9 +277,7 @@ class Transformer:
# code for lambda # code for lambda
code = self.com_node(nodelist[-1]) code = self.com_node(nodelist[-1])
n = Lambda(names, defaults, flags, code) return Lambda(names, defaults, flags, code, lineno=nodelist[1][2])
n.lineno = nodelist[1][2]
return n
def classdef(self, nodelist): def classdef(self, nodelist):
# classdef: 'class' NAME ['(' testlist ')'] ':' suite # classdef: 'class' NAME ['(' testlist ')'] ':' suite
...@@ -291,9 +297,7 @@ class Transformer: ...@@ -291,9 +297,7 @@ class Transformer:
assert isinstance(code.nodes[0], Discard) assert isinstance(code.nodes[0], Discard)
del code.nodes[0] del code.nodes[0]
n = Class(name, bases, doc, code) return Class(name, bases, doc, code, lineno=nodelist[1][2])
n.lineno = nodelist[1][2]
return n
def stmt(self, nodelist): def stmt(self, nodelist):
return self.com_stmt(nodelist[0]) return self.com_stmt(nodelist[0])
...@@ -310,31 +314,31 @@ class Transformer: ...@@ -310,31 +314,31 @@ class Transformer:
return Stmt(stmts) return Stmt(stmts)
def parameters(self, nodelist): def parameters(self, nodelist):
raise error raise WalkerEror
def varargslist(self, nodelist): def varargslist(self, nodelist):
raise error raise WalkerEror
def fpdef(self, nodelist): def fpdef(self, nodelist):
raise error raise WalkerEror
def fplist(self, nodelist): def fplist(self, nodelist):
raise error raise WalkerEror
def dotted_name(self, nodelist): def dotted_name(self, nodelist):
raise error raise WalkerEror
def comp_op(self, nodelist): def comp_op(self, nodelist):
raise error raise WalkerEror
def trailer(self, nodelist): def trailer(self, nodelist):
raise error raise WalkerEror
def sliceop(self, nodelist): def sliceop(self, nodelist):
raise error raise WalkerEror
def argument(self, nodelist): def argument(self, nodelist):
raise error raise WalkerEror
# -------------------------------------------------------------- # --------------------------------------------------------------
# #
...@@ -346,21 +350,17 @@ class Transformer: ...@@ -346,21 +350,17 @@ class Transformer:
en = nodelist[-1] en = nodelist[-1]
exprNode = self.lookup_node(en)(en[1:]) exprNode = self.lookup_node(en)(en[1:])
if len(nodelist) == 1: if len(nodelist) == 1:
n = Discard(exprNode) return Discard(exprNode, lineno=exprNode.lineno)
n.lineno = exprNode.lineno
return n
if nodelist[1][0] == token.EQUAL: if nodelist[1][0] == token.EQUAL:
nodesl = [] nodesl = []
for i in range(0, len(nodelist) - 2, 2): for i in range(0, len(nodelist) - 2, 2):
nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN)) nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN))
n = Assign(nodesl, exprNode) return Assign(nodesl, exprNode, lineno=nodelist[1][2])
n.lineno = nodelist[1][2]
else: else:
lval = self.com_augassign(nodelist[0]) lval = self.com_augassign(nodelist[0])
op = self.com_augassign_op(nodelist[1]) op = self.com_augassign_op(nodelist[1])
n = AugAssign(lval, op[1], exprNode) return AugAssign(lval, op[1], exprNode, lineno=op[2])
n.lineno = op[2] raise WalkerError, "can't get here"
return n
def print_stmt(self, nodelist): def print_stmt(self, nodelist):
# print ([ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ]) # print ([ test (',' test)* [','] ] | '>>' test [ (',' test)+ [','] ])
...@@ -379,45 +379,29 @@ class Transformer: ...@@ -379,45 +379,29 @@ class Transformer:
for i in range(start, len(nodelist), 2): for i in range(start, len(nodelist), 2):
items.append(self.com_node(nodelist[i])) items.append(self.com_node(nodelist[i]))
if nodelist[-1][0] == token.COMMA: if nodelist[-1][0] == token.COMMA:
n = Print(items, dest) return Print(items, dest, lineno=nodelist[0][2])
n.lineno = nodelist[0][2] return Printnl(items, dest, lineno=nodelist[0][2])
return n
n = Printnl(items, dest)
n.lineno = nodelist[0][2]
return n
def del_stmt(self, nodelist): def del_stmt(self, nodelist):
return self.com_assign(nodelist[1], OP_DELETE) return self.com_assign(nodelist[1], OP_DELETE)
def pass_stmt(self, nodelist): def pass_stmt(self, nodelist):
n = Pass() return Pass(lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def break_stmt(self, nodelist): def break_stmt(self, nodelist):
n = Break() return Break(lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def continue_stmt(self, nodelist): def continue_stmt(self, nodelist):
n = Continue() return Continue(lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def return_stmt(self, nodelist): def return_stmt(self, nodelist):
# return: [testlist] # return: [testlist]
if len(nodelist) < 2: if len(nodelist) < 2:
n = Return(Const(None)) return Return(Const(None), lineno=nodelist[0][2])
n.lineno = nodelist[0][2] return Return(self.com_node(nodelist[1]), lineno=nodelist[0][2])
return n
n = Return(self.com_node(nodelist[1]))
n.lineno = nodelist[0][2]
return n
def yield_stmt(self, nodelist): def yield_stmt(self, nodelist):
n = Yield(self.com_node(nodelist[1])) return Yield(self.com_node(nodelist[1]), lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def raise_stmt(self, nodelist): def raise_stmt(self, nodelist):
# raise: [test [',' test [',' test]]] # raise: [test [',' test [',' test]]]
...@@ -433,9 +417,7 @@ class Transformer: ...@@ -433,9 +417,7 @@ class Transformer:
expr1 = self.com_node(nodelist[1]) expr1 = self.com_node(nodelist[1])
else: else:
expr1 = None expr1 = None
n = Raise(expr1, expr2, expr3) return Raise(expr1, expr2, expr3, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def import_stmt(self, nodelist): def import_stmt(self, nodelist):
# import_stmt: import_name | import_from # import_stmt: import_name | import_from
...@@ -444,9 +426,8 @@ class Transformer: ...@@ -444,9 +426,8 @@ class Transformer:
def import_name(self, nodelist): def import_name(self, nodelist):
# import_name: 'import' dotted_as_names # import_name: 'import' dotted_as_names
n = Import(self.com_dotted_as_names(nodelist[1])) return Import(self.com_dotted_as_names(nodelist[1]),
n.lineno = nodelist[0][2] lineno=nodelist[0][2])
return n
def import_from(self, nodelist): def import_from(self, nodelist):
# import_from: 'from' dotted_name 'import' ('*' | # import_from: 'from' dotted_name 'import' ('*' |
...@@ -456,21 +437,19 @@ class Transformer: ...@@ -456,21 +437,19 @@ class Transformer:
assert nodelist[2][1] == 'import' assert nodelist[2][1] == 'import'
fromname = self.com_dotted_name(nodelist[1]) fromname = self.com_dotted_name(nodelist[1])
if nodelist[3][0] == token.STAR: if nodelist[3][0] == token.STAR:
n = From(fromname, [('*', None)]) # TODO(jhylton): where is the lineno?
return From(fromname, [('*', None)])
else: else:
node = nodelist[3 + (nodelist[3][0] == token.LPAR)] node = nodelist[3 + (nodelist[3][0] == token.LPAR)]
n = From(fromname, self.com_import_as_names(node)) return From(fromname, self.com_import_as_names(node),
n.lineno = nodelist[0][2] lineno=nodelist[0][2])
return n
def global_stmt(self, nodelist): def global_stmt(self, nodelist):
# global: NAME (',' NAME)* # global: NAME (',' NAME)*
names = [] names = []
for i in range(1, len(nodelist), 2): for i in range(1, len(nodelist), 2):
names.append(nodelist[i][1]) names.append(nodelist[i][1])
n = Global(names) return Global(names, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def exec_stmt(self, nodelist): def exec_stmt(self, nodelist):
# exec_stmt: 'exec' expr ['in' expr [',' expr]] # exec_stmt: 'exec' expr ['in' expr [',' expr]]
...@@ -484,9 +463,7 @@ class Transformer: ...@@ -484,9 +463,7 @@ class Transformer:
else: else:
expr2 = expr3 = None expr2 = expr3 = None
n = Exec(expr1, expr2, expr3) return Exec(expr1, expr2, expr3, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def assert_stmt(self, nodelist): def assert_stmt(self, nodelist):
# 'assert': test, [',' test] # 'assert': test, [',' test]
...@@ -495,9 +472,7 @@ class Transformer: ...@@ -495,9 +472,7 @@ class Transformer:
expr2 = self.com_node(nodelist[3]) expr2 = self.com_node(nodelist[3])
else: else:
expr2 = None expr2 = None
n = Assert(expr1, expr2) return Assert(expr1, expr2, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def if_stmt(self, nodelist): def if_stmt(self, nodelist):
# if: test ':' suite ('elif' test ':' suite)* ['else' ':' suite] # if: test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
...@@ -512,9 +487,7 @@ class Transformer: ...@@ -512,9 +487,7 @@ class Transformer:
## elseNode.lineno = nodelist[-1][1][2] ## elseNode.lineno = nodelist[-1][1][2]
else: else:
elseNode = None elseNode = None
n = If(tests, elseNode) return If(tests, elseNode, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def while_stmt(self, nodelist): def while_stmt(self, nodelist):
# 'while' test ':' suite ['else' ':' suite] # 'while' test ':' suite ['else' ':' suite]
...@@ -527,9 +500,7 @@ class Transformer: ...@@ -527,9 +500,7 @@ class Transformer:
else: else:
elseNode = None elseNode = None
n = While(testNode, bodyNode, elseNode) return While(testNode, bodyNode, elseNode, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def for_stmt(self, nodelist): def for_stmt(self, nodelist):
# 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite]
...@@ -543,9 +514,8 @@ class Transformer: ...@@ -543,9 +514,8 @@ class Transformer:
else: else:
elseNode = None elseNode = None
n = For(assignNode, listNode, bodyNode, elseNode) return For(assignNode, listNode, bodyNode, elseNode,
n.lineno = nodelist[0][2] lineno=nodelist[0][2])
return n
def try_stmt(self, nodelist): def try_stmt(self, nodelist):
# 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] # 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
...@@ -601,9 +571,7 @@ class Transformer: ...@@ -601,9 +571,7 @@ class Transformer:
# 'not' not_test | comparison # 'not' not_test | comparison
result = self.com_node(nodelist[-1]) result = self.com_node(nodelist[-1])
if len(nodelist) == 2: if len(nodelist) == 2:
n = Not(result) return Not(result, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
return result return result
def comparison(self, nodelist): def comparison(self, nodelist):
...@@ -637,9 +605,7 @@ class Transformer: ...@@ -637,9 +605,7 @@ class Transformer:
# the two have very different semantics and results (note that the # the two have very different semantics and results (note that the
# latter form is always true) # latter form is always true)
n = Compare(node, results) return Compare(node, results, lineno=lineno)
n.lineno = lineno
return n
def expr(self, nodelist): def expr(self, nodelist):
# xor_expr ('|' xor_expr)* # xor_expr ('|' xor_expr)*
...@@ -659,11 +625,9 @@ class Transformer: ...@@ -659,11 +625,9 @@ class Transformer:
for i in range(2, len(nodelist), 2): for i in range(2, len(nodelist), 2):
right = self.com_node(nodelist[i]) right = self.com_node(nodelist[i])
if nodelist[i-1][0] == token.LEFTSHIFT: if nodelist[i-1][0] == token.LEFTSHIFT:
node = LeftShift([node, right]) node = LeftShift([node, right], lineno=nodelist[1][2])
node.lineno = nodelist[1][2]
elif nodelist[i-1][0] == token.RIGHTSHIFT: elif nodelist[i-1][0] == token.RIGHTSHIFT:
node = RightShift([node, right]) node = RightShift([node, right], lineno=nodelist[1][2])
node.lineno = nodelist[1][2]
else: else:
raise ValueError, "unexpected token: %s" % nodelist[i-1][0] raise ValueError, "unexpected token: %s" % nodelist[i-1][0]
return node return node
...@@ -673,11 +637,9 @@ class Transformer: ...@@ -673,11 +637,9 @@ class Transformer:
for i in range(2, len(nodelist), 2): for i in range(2, len(nodelist), 2):
right = self.com_node(nodelist[i]) right = self.com_node(nodelist[i])
if nodelist[i-1][0] == token.PLUS: if nodelist[i-1][0] == token.PLUS:
node = Add([node, right]) node = Add([node, right], lineno=nodelist[1][2])
node.lineno = nodelist[1][2]
elif nodelist[i-1][0] == token.MINUS: elif nodelist[i-1][0] == token.MINUS:
node = Sub([node, right]) node = Sub([node, right], lineno=nodelist[1][2])
node.lineno = nodelist[1][2]
else: else:
raise ValueError, "unexpected token: %s" % nodelist[i-1][0] raise ValueError, "unexpected token: %s" % nodelist[i-1][0]
return node return node
...@@ -703,17 +665,14 @@ class Transformer: ...@@ -703,17 +665,14 @@ class Transformer:
def factor(self, nodelist): def factor(self, nodelist):
elt = nodelist[0] elt = nodelist[0]
t = elt[0] t = elt[0]
node = self.com_node(nodelist[-1]) node = self.lookup_node(nodelist[-1])(nodelist[-1][1:])
# need to handle (unary op)constant here... # need to handle (unary op)constant here...
if t == token.PLUS: if t == token.PLUS:
node = UnaryAdd(node) return UnaryAdd(node, lineno=elt[2])
node.lineno = elt[2]
elif t == token.MINUS: elif t == token.MINUS:
node = UnarySub(node) return UnarySub(node, lineno=elt[2])
node.lineno = elt[2]
elif t == token.TILDE: elif t == token.TILDE:
node = Invert(node) node = Invert(node, lineno=elt[2])
node.lineno = elt[2]
return node return node
def power(self, nodelist): def power(self, nodelist):
...@@ -722,31 +681,26 @@ class Transformer: ...@@ -722,31 +681,26 @@ class Transformer:
for i in range(1, len(nodelist)): for i in range(1, len(nodelist)):
elt = nodelist[i] elt = nodelist[i]
if elt[0] == token.DOUBLESTAR: if elt[0] == token.DOUBLESTAR:
n = Power([node, self.com_node(nodelist[i+1])]) return Power([node, self.com_node(nodelist[i+1])],
n.lineno = elt[2] lineno=elt[2])
return n
node = self.com_apply_trailer(node, elt) node = self.com_apply_trailer(node, elt)
return node return node
def atom(self, nodelist): def atom(self, nodelist):
n = self._atom_dispatch[nodelist[0][0]](nodelist) return self._atom_dispatch[nodelist[0][0]](nodelist)
n.lineno = nodelist[0][2] n.lineno = nodelist[0][2]
return n return n
def atom_lpar(self, nodelist): def atom_lpar(self, nodelist):
if nodelist[1][0] == token.RPAR: if nodelist[1][0] == token.RPAR:
n = Tuple(()) return Tuple(())
n.lineno = nodelist[0][2]
return n
return self.com_node(nodelist[1]) return self.com_node(nodelist[1])
def atom_lsqb(self, nodelist): def atom_lsqb(self, nodelist):
if nodelist[1][0] == token.RSQB: if nodelist[1][0] == token.RSQB:
n = List(()) return List(())
n.lineno = nodelist[0][2]
return n
return self.com_list_constructor(nodelist[1]) return self.com_list_constructor(nodelist[1])
def atom_lbrace(self, nodelist): def atom_lbrace(self, nodelist):
...@@ -755,16 +709,12 @@ class Transformer: ...@@ -755,16 +709,12 @@ class Transformer:
return self.com_dictmaker(nodelist[1]) return self.com_dictmaker(nodelist[1])
def atom_backquote(self, nodelist): def atom_backquote(self, nodelist):
n = Backquote(self.com_node(nodelist[1])) return Backquote(self.com_node(nodelist[1]))
n.lineno = nodelist[0][2]
return n
def atom_number(self, nodelist): def atom_number(self, nodelist):
### need to verify this matches compile.c ### need to verify this matches compile.c
k = eval(nodelist[0][1]) k = eval(nodelist[0][1])
n = Const(k) return Const(k, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def decode_literal(self, lit): def decode_literal(self, lit):
if self.encoding: if self.encoding:
...@@ -781,15 +731,10 @@ class Transformer: ...@@ -781,15 +731,10 @@ class Transformer:
k = '' k = ''
for node in nodelist: for node in nodelist:
k += self.decode_literal(node[1]) k += self.decode_literal(node[1])
n = Const(k) return Const(k, lineno=nodelist[0][2])
n.lineno = nodelist[0][2]
return n
def atom_name(self, nodelist): def atom_name(self, nodelist):
### any processing to do? return Name(nodelist[0][1], lineno=nodelist[0][2])
n = Name(nodelist[0][1])
n.lineno = nodelist[0][2]
return n
# -------------------------------------------------------------- # --------------------------------------------------------------
# #
...@@ -807,6 +752,8 @@ class Transformer: ...@@ -807,6 +752,8 @@ class Transformer:
def lookup_node(self, node): def lookup_node(self, node):
return self._dispatch[node[0]] return self._dispatch[node[0]]
_callers = {}
def com_node(self, node): def com_node(self, node):
# Note: compile.c has handling in com_node for del_stmt, pass_stmt, # Note: compile.c has handling in com_node for del_stmt, pass_stmt,
# break_stmt, stmt, small_stmt, flow_stmt, simple_stmt, # break_stmt, stmt, small_stmt, flow_stmt, simple_stmt,
...@@ -865,6 +812,7 @@ class Transformer: ...@@ -865,6 +812,7 @@ class Transformer:
i = i + 2 i = i + 2
elif len(defaults): elif len(defaults):
# Treat "(a=1, b)" as "(a=1, b=None)" # Treat "(a=1, b)" as "(a=1, b=None)"
print nodelist[i]
defaults.append(Const(None)) defaults.append(Const(None))
i = i + 1 i = i + 1
...@@ -938,10 +886,9 @@ class Transformer: ...@@ -938,10 +886,9 @@ class Transformer:
def com_try_finally(self, nodelist): def com_try_finally(self, nodelist):
# try_fin_stmt: "try" ":" suite "finally" ":" suite # try_fin_stmt: "try" ":" suite "finally" ":" suite
n = TryFinally(self.com_node(nodelist[2]), return TryFinally(self.com_node(nodelist[2]),
self.com_node(nodelist[5])) self.com_node(nodelist[5]),
n.lineno = nodelist[0][2] lineno=nodelist[0][2])
return n
def com_try_except(self, nodelist): def com_try_except(self, nodelist):
# try_except: 'try' ':' suite (except_clause ':' suite)* ['else' suite] # try_except: 'try' ':' suite (except_clause ':' suite)* ['else' suite]
...@@ -965,9 +912,8 @@ class Transformer: ...@@ -965,9 +912,8 @@ class Transformer:
if node[0] == token.NAME: if node[0] == token.NAME:
elseNode = self.com_node(nodelist[i+2]) elseNode = self.com_node(nodelist[i+2])
n = TryExcept(self.com_node(nodelist[2]), clauses, elseNode) return TryExcept(self.com_node(nodelist[2]), clauses, elseNode,
n.lineno = nodelist[0][2] lineno=nodelist[0][2])
return n
def com_augassign_op(self, node): def com_augassign_op(self, node):
assert node[0] == symbol.augassign assert node[0] == symbol.augassign
...@@ -1031,7 +977,7 @@ class Transformer: ...@@ -1031,7 +977,7 @@ class Transformer:
assigns = [] assigns = []
for i in range(1, len(node), 2): for i in range(1, len(node), 2):
assigns.append(self.com_assign(node[i], assigning)) assigns.append(self.com_assign(node[i], assigning))
return AssTuple(assigns) return AssTuple(assigns, lineno=extractLineNo(node))
def com_assign_list(self, node, assigning): def com_assign_list(self, node, assigning):
assigns = [] assigns = []
...@@ -1041,12 +987,10 @@ class Transformer: ...@@ -1041,12 +987,10 @@ class Transformer:
raise SyntaxError, "can't assign to list comprehension" raise SyntaxError, "can't assign to list comprehension"
assert node[i + 1][0] == token.COMMA, node[i + 1] assert node[i + 1][0] == token.COMMA, node[i + 1]
assigns.append(self.com_assign(node[i], assigning)) assigns.append(self.com_assign(node[i], assigning))
return AssList(assigns) return AssList(assigns, lineno=extractLineNo(node))
def com_assign_name(self, node, assigning): def com_assign_name(self, node, assigning):
n = AssName(node[1], assigning) return AssName(node[1], assigning, lineno=node[2])
n.lineno = node[2]
return n
def com_assign_trailer(self, primary, node, assigning): def com_assign_trailer(self, primary, node, assigning):
t = node[1][0] t = node[1][0]
...@@ -1059,7 +1003,7 @@ class Transformer: ...@@ -1059,7 +1003,7 @@ class Transformer:
raise SyntaxError, "unknown trailer type: %s" % t raise SyntaxError, "unknown trailer type: %s" % t
def com_assign_attr(self, primary, node, assigning): def com_assign_attr(self, primary, node, assigning):
return AssAttr(primary, node[1], assigning) return AssAttr(primary, node[1], assigning, lineno=node[-1])
def com_binary(self, constructor, nodelist): def com_binary(self, constructor, nodelist):
"Compile 'NODE (OP NODE)*' into (type, [ node1, ..., nodeN ])." "Compile 'NODE (OP NODE)*' into (type, [ node1, ..., nodeN ])."
...@@ -1071,7 +1015,7 @@ class Transformer: ...@@ -1071,7 +1015,7 @@ class Transformer:
for i in range(0, l, 2): for i in range(0, l, 2):
n = nodelist[i] n = nodelist[i]
items.append(self.lookup_node(n)(n[1:])) items.append(self.lookup_node(n)(n[1:]))
return constructor(items) return constructor(items, lineno=extractLineNo(nodelist))
def com_stmt(self, node): def com_stmt(self, node):
result = self.lookup_node(node)(node[1:]) result = self.lookup_node(node)(node[1:])
...@@ -1081,7 +1025,7 @@ class Transformer: ...@@ -1081,7 +1025,7 @@ class Transformer:
return Stmt([result]) return Stmt([result])
def com_append_stmt(self, stmts, node): def com_append_stmt(self, stmts, node):
result = self.com_node(node) result = self.lookup_node(node)(node[1:])
assert result is not None assert result is not None
if isinstance(result, Stmt): if isinstance(result, Stmt):
stmts.extend(result.nodes) stmts.extend(result.nodes)
...@@ -1100,7 +1044,7 @@ class Transformer: ...@@ -1100,7 +1044,7 @@ class Transformer:
elif nodelist[i][0] == token.COMMA: elif nodelist[i][0] == token.COMMA:
continue continue
values.append(self.com_node(nodelist[i])) values.append(self.com_node(nodelist[i]))
return List(values) return List(values, lineno=values[0].lineno)
def com_list_comprehension(self, expr, node): def com_list_comprehension(self, expr, node):
# list_iter: list_for | list_if # list_iter: list_for | list_if
...@@ -1125,8 +1069,7 @@ class Transformer: ...@@ -1125,8 +1069,7 @@ class Transformer:
node = self.com_list_iter(node[5]) node = self.com_list_iter(node[5])
elif t == 'if': elif t == 'if':
test = self.com_node(node[2]) test = self.com_node(node[2])
newif = ListCompIf(test) newif = ListCompIf(test, lineno=node[1][2])
newif.lineno = node[1][2]
newfor.ifs.append(newif) newfor.ifs.append(newif)
if len(node) == 3: if len(node) == 3:
node = None node = None
...@@ -1136,9 +1079,7 @@ class Transformer: ...@@ -1136,9 +1079,7 @@ class Transformer:
raise SyntaxError, \ raise SyntaxError, \
("unexpected list comprehension element: %s %d" ("unexpected list comprehension element: %s %d"
% (node, lineno)) % (node, lineno))
n = ListComp(expr, fors) return ListComp(expr, fors, lineno=lineno)
n.lineno = lineno
return n
def com_list_iter(self, node): def com_list_iter(self, node):
assert node[0] == symbol.list_iter assert node[0] == symbol.list_iter
...@@ -1163,8 +1104,8 @@ class Transformer: ...@@ -1163,8 +1104,8 @@ class Transformer:
if t == 'for': if t == 'for':
assignNode = self.com_assign(node[2], OP_ASSIGN) assignNode = self.com_assign(node[2], OP_ASSIGN)
genNode = self.com_node(node[4]) genNode = self.com_node(node[4])
newfor = GenExprFor(assignNode, genNode, []) newfor = GenExprFor(assignNode, genNode, [],
newfor.lineno = node[1][2] lineno=node[1][2])
fors.append(newfor) fors.append(newfor)
if (len(node)) == 5: if (len(node)) == 5:
node = None node = None
...@@ -1172,8 +1113,7 @@ class Transformer: ...@@ -1172,8 +1113,7 @@ class Transformer:
node = self.com_gen_iter(node[5]) node = self.com_gen_iter(node[5])
elif t == 'if': elif t == 'if':
test = self.com_node(node[2]) test = self.com_node(node[2])
newif = GenExprIf(test) newif = GenExprIf(test, lineno=node[1][2])
newif.lineno = node[1][2]
newfor.ifs.append(newif) newfor.ifs.append(newif)
if len(node) == 3: if len(node) == 3:
node = None node = None
...@@ -1184,9 +1124,7 @@ class Transformer: ...@@ -1184,9 +1124,7 @@ class Transformer:
("unexpected generator expression element: %s %d" ("unexpected generator expression element: %s %d"
% (node, lineno)) % (node, lineno))
fors[0].is_outmost = True fors[0].is_outmost = True
n = GenExpr(GenExprInner(expr, fors)) return GenExpr(GenExprInner(expr, fors), lineno=lineno)
n.lineno = lineno
return n
def com_gen_iter(self, node): def com_gen_iter(self, node):
assert node[0] == symbol.gen_iter assert node[0] == symbol.gen_iter
...@@ -1214,13 +1152,11 @@ class Transformer: ...@@ -1214,13 +1152,11 @@ class Transformer:
def com_select_member(self, primaryNode, nodelist): def com_select_member(self, primaryNode, nodelist):
if nodelist[0] != token.NAME: if nodelist[0] != token.NAME:
raise SyntaxError, "member must be a name" raise SyntaxError, "member must be a name"
n = Getattr(primaryNode, nodelist[1]) return Getattr(primaryNode, nodelist[1], lineno=nodelist[2])
n.lineno = nodelist[2]
return n
def com_call_function(self, primaryNode, nodelist): def com_call_function(self, primaryNode, nodelist):
if nodelist[0] == token.RPAR: if nodelist[0] == token.RPAR:
return CallFunc(primaryNode, []) return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist))
args = [] args = []
kw = 0 kw = 0
len_nodelist = len(nodelist) len_nodelist = len(nodelist)
...@@ -1253,8 +1189,8 @@ class Transformer: ...@@ -1253,8 +1189,8 @@ class Transformer:
dstar_node = self.com_node(ch) dstar_node = self.com_node(ch)
else: else:
raise SyntaxError, 'unknown node type: %s' % tok raise SyntaxError, 'unknown node type: %s' % tok
return CallFunc(primaryNode, args, star_node, dstar_node,
return CallFunc(primaryNode, args, star_node, dstar_node) lineno=extractLineNo(nodelist))
def com_argument(self, nodelist, kw): def com_argument(self, nodelist, kw):
if len(nodelist) == 3 and nodelist[2][0] == symbol.gen_for: if len(nodelist) == 3 and nodelist[2][0] == symbol.gen_for:
...@@ -1270,8 +1206,7 @@ class Transformer: ...@@ -1270,8 +1206,7 @@ class Transformer:
n = n[1] n = n[1]
if n[0] != token.NAME: if n[0] != token.NAME:
raise SyntaxError, "keyword can't be an expression (%s)"%n[0] raise SyntaxError, "keyword can't be an expression (%s)"%n[0]
node = Keyword(n[1], result) node = Keyword(n[1], result, lineno=n[2])
node.lineno = n[2]
return 1, node return 1, node
def com_subscriptlist(self, primary, nodelist, assigning): def com_subscriptlist(self, primary, nodelist, assigning):
...@@ -1291,8 +1226,8 @@ class Transformer: ...@@ -1291,8 +1226,8 @@ class Transformer:
subscripts = [] subscripts = []
for i in range(1, len(nodelist), 2): for i in range(1, len(nodelist), 2):
subscripts.append(self.com_subscript(nodelist[i])) subscripts.append(self.com_subscript(nodelist[i]))
return Subscript(primary, assigning, subscripts,
return Subscript(primary, assigning, subscripts) lineno=extractLineNo(nodelist))
def com_subscript(self, node): def com_subscript(self, node):
# slice_item: expression | proper_slice | ellipsis # slice_item: expression | proper_slice | ellipsis
...@@ -1338,8 +1273,7 @@ class Transformer: ...@@ -1338,8 +1273,7 @@ class Transformer:
items.append(Const(None)) items.append(Const(None))
else: else:
items.append(self.com_node(ch[2])) items.append(self.com_node(ch[2]))
return Sliceobj(items, lineno=extractLineNo(node))
return Sliceobj(items)
def com_slice(self, primary, node, assigning): def com_slice(self, primary, node, assigning):
# short_slice: [lower_bound] ":" [upper_bound] # short_slice: [lower_bound] ":" [upper_bound]
...@@ -1352,7 +1286,8 @@ class Transformer: ...@@ -1352,7 +1286,8 @@ class Transformer:
elif len(node) == 4: elif len(node) == 4:
lower = self.com_node(node[1]) lower = self.com_node(node[1])
upper = self.com_node(node[3]) upper = self.com_node(node[3])
return Slice(primary, assigning, lower, upper) return Slice(primary, assigning, lower, upper,
lineno=extractLineNo(node))
def get_docstring(self, node, n=None): def get_docstring(self, node, n=None):
if n is None: if n is None:
......
...@@ -33,6 +33,65 @@ class CompilerTest(unittest.TestCase): ...@@ -33,6 +33,65 @@ class CompilerTest(unittest.TestCase):
else: else:
compiler.compile(buf, basename, "exec") compiler.compile(buf, basename, "exec")
def testLineNo(self):
# Test that all nodes except Module have a correct lineno attribute.
filename = __file__
if filename.endswith(".pyc") or filename.endswith(".pyo"):
filename = filename[:-1]
tree = compiler.parseFile(filename)
self.check_lineno(tree)
def check_lineno(self, node):
try:
self._check_lineno(node)
except AssertionError:
print node.__class__, node.lineno
raise
def _check_lineno(self, node):
if not node.__class__ in NOLINENO:
self.assert_(isinstance(node.lineno, int),
"lineno=%s on %s" % (node.lineno, node.__class__))
self.assert_(node.lineno > 0,
"lineno=%s on %s" % (node.lineno, node.__class__))
for child in node.getChildNodes():
self.check_lineno(child)
NOLINENO = (compiler.ast.Module, compiler.ast.Stmt, compiler.ast.Discard)
###############################################################################
# code below is just used to trigger some possible errors, for the benefit of
# testLineNo
###############################################################################
class Toto:
"""docstring"""
pass
a, b = 2, 3
[c, d] = 5, 6
l = [(x, y) for x, y in zip(range(5), range(5,10))]
l[0]
l[3:4]
if l:
pass
else:
a, b = b, a
try:
print yo
except:
yo = 3
else:
yo += 3
try:
a += b
finally:
b = 0
###############################################################################
def test_main(): def test_main():
global TEST_ALL global TEST_ALL
TEST_ALL = test.test_support.is_resource_enabled("compiler") TEST_ALL = test.test_support.is_resource_enabled("compiler")
......
...@@ -29,9 +29,7 @@ class Tests(unittest.TestCase): ...@@ -29,9 +29,7 @@ class Tests(unittest.TestCase):
assert vals['b'] == 2 assert vals['b'] == 2
def test_main(): def test_main():
test_support.run_unittest( test_support.run_unittest(Tests)
Tests
)
if __name__ == "__main__": if __name__ == "__main__":
test_main() test_main()
...@@ -563,6 +563,7 @@ Michael Stone ...@@ -563,6 +563,7 @@ Michael Stone
Ken Stox Ken Stox
Daniel Stutzbach Daniel Stutzbach
Paul Swartz Paul Swartz
Thenault Sylvain
Geoff Talvola Geoff Talvola
William Tanksley William Tanksley
Christian Tanzer Christian Tanzer
......
...@@ -94,7 +94,6 @@ class NodeInfo: ...@@ -94,7 +94,6 @@ class NodeInfo:
def gen_source(self): def gen_source(self):
buf = StringIO() buf = StringIO()
print >> buf, "class %s(Node):" % self.name print >> buf, "class %s(Node):" % self.name
print >> buf, ' nodes["%s"] = "%s"' % (self.name.lower(), self.name)
self._gen_init(buf) self._gen_init(buf)
print >> buf print >> buf
self._gen_getChildren(buf) self._gen_getChildren(buf)
...@@ -106,12 +105,14 @@ class NodeInfo: ...@@ -106,12 +105,14 @@ class NodeInfo:
return buf.read() return buf.read()
def _gen_init(self, buf): def _gen_init(self, buf):
print >> buf, " def __init__(self, %s):" % self.args if self.args:
print >> buf, " def __init__(self, %s, lineno=None):" % self.args
else:
print >> buf, " def __init__(self, lineno=None):"
if self.argnames: if self.argnames:
for name in self.argnames: for name in self.argnames:
print >> buf, " self.%s = %s" % (name, name) print >> buf, " self.%s = %s" % (name, name)
else: print >> buf, " self.lineno = lineno"
print >> buf, " pass"
if self.init: if self.init:
print >> buf, "".join([" " + line for line in self.init]) print >> buf, "".join([" " + line for line in self.init])
...@@ -128,15 +129,18 @@ class NodeInfo: ...@@ -128,15 +129,18 @@ class NodeInfo:
else: else:
print >> buf, " return %s" % clist print >> buf, " return %s" % clist
else: else:
print >> buf, " children = []" if len(self.argnames) == 1:
template = " children.%s(%sself.%s%s)" print >> buf, " return tuple(flatten(self.%s))" % self.argnames[0]
for name in self.argnames: else:
if self.argprops[name] == P_NESTED: print >> buf, " children = []"
print >> buf, template % ("extend", "flatten(", template = " children.%s(%sself.%s%s)"
name, ")") for name in self.argnames:
else: if self.argprops[name] == P_NESTED:
print >> buf, template % ("append", "", name, "") print >> buf, template % ("extend", "flatten(",
print >> buf, " return tuple(children)" name, ")")
else:
print >> buf, template % ("append", "", name, "")
print >> buf, " return tuple(children)"
def _gen_getChildNodes(self, buf): def _gen_getChildNodes(self, buf):
print >> buf, " def getChildNodes(self):" print >> buf, " def getChildNodes(self):"
...@@ -158,7 +162,7 @@ class NodeInfo: ...@@ -158,7 +162,7 @@ class NodeInfo:
template = " nodelist.%s(%sself.%s%s)" template = " nodelist.%s(%sself.%s%s)"
for name in self.argnames: for name in self.argnames:
if self.argprops[name] == P_NONE: if self.argprops[name] == P_NONE:
tmp = (" if self.%s is not None:" tmp = (" if self.%s is not None:\n"
" nodelist.append(self.%s)") " nodelist.append(self.%s)")
print >> buf, tmp % (name, name) print >> buf, tmp % (name, name)
elif self.argprops[name] == P_NESTED: elif self.argprops[name] == P_NESTED:
...@@ -226,16 +230,15 @@ if __name__ == "__main__": ...@@ -226,16 +230,15 @@ if __name__ == "__main__":
### PROLOGUE ### PROLOGUE
"""Python abstract syntax node definitions """Python abstract syntax node definitions
This file is automatically generated. This file is automatically generated by Tools/compiler/astgen.py
""" """
from types import TupleType, ListType
from consts import CO_VARARGS, CO_VARKEYWORDS from consts import CO_VARARGS, CO_VARKEYWORDS
def flatten(list): def flatten(list):
l = [] l = []
for elt in list: for elt in list:
t = type(elt) t = type(elt)
if t is TupleType or t is ListType: if t is tuple or t is list:
for elt2 in flatten(elt): for elt2 in flatten(elt):
l.append(elt2) l.append(elt2)
else: else:
...@@ -245,29 +248,17 @@ def flatten(list): ...@@ -245,29 +248,17 @@ def flatten(list):
def flatten_nodes(list): def flatten_nodes(list):
return [n for n in flatten(list) if isinstance(n, Node)] return [n for n in flatten(list) if isinstance(n, Node)]
def asList(nodearg):
l = []
for item in nodearg:
if hasattr(item, "asList"):
l.append(item.asList())
else:
t = type(item)
if t is TupleType or t is ListType:
l.append(tuple(asList(item)))
else:
l.append(item)
return l
nodes = {} nodes = {}
class Node: # an abstract base class class Node:
lineno = None # provide a lineno for nodes that don't have one """Abstract base class for ast nodes."""
def getType(self):
pass # implemented by subclass
def getChildren(self): def getChildren(self):
pass # implemented by subclasses pass # implemented by subclasses
def asList(self): def __iter__(self):
return tuple(asList(self.getChildren())) for n in self.getChildren():
yield n
def asList(self): # for backwards compatibility
return self.getChildren()
def getChildNodes(self): def getChildNodes(self):
pass # implemented by subclasses pass # implemented by subclasses
...@@ -290,6 +281,6 @@ class Expression(Node): ...@@ -290,6 +281,6 @@ class Expression(Node):
return "Expression(%s)" % (repr(self.node)) return "Expression(%s)" % (repr(self.node))
### EPILOGUE ### EPILOGUE
klasses = globals() for name, obj in globals().items():
for k in nodes.keys(): if isinstance(obj, type) and issubclass(obj, Node):
nodes[k] = klasses[nodes[k]] nodes[name.lower()] = obj
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment