Commits

Georg Brandl committed 966c4a4

Fix line numbering and With expansion bug. Update to release 0.2.

  • Participants
  • Parent commits 365f66d
  • Tags 0.2

Comments (0)

Files changed (2)

 
     AST macros for Python.
 
-    :copyright: Copyright 2010 by Georg Brandl.
+    :copyright: Copyright 2010, 2011 by Georg Brandl.
     :license: BSD, see LICENSE for details.
 """
 
     return macros
 
 
+def fix_locations(node, old_node):
+    """Replace all code locations (lineno and col_offset) with the one from
+    *old_node* (we cannot preserve original location information for code from
+    macros since the compiler cannot know that it's from different files.
+    """
+    def _fix(node, lineno, col_offset):
+        node.lineno = lineno
+        node.col_offset = col_offset
+        for child in ast.iter_child_nodes(node):
+            _fix(child, lineno, col_offset)
+    _fix(node, old_node.lineno, old_node.col_offset)
+    return node
+
+
+
 class MacroCallError(Exception):
     """Raised when an invalid macro call is encountered."""
 
         node = self.generic_visit(node)
         if self.body and isinstance(node.value, ast.Name) and \
            node.value.id == '__body__':
-            new_node = ast.fix_missing_locations(ast.If(ast.Num(1),
-                                                        self.body, []))
-            return new_node
+            return fix_locations(ast.If(ast.Num(1), self.body, []), node)
 
 
 class BodyVisitor(ast.NodeVisitor):
             raise MacroCallError(node, 'invalid number of arguments')
         stmts = deepcopy(self.stmts)
         argdict = dict(izip(self.args, call_args))
-        new_node = ast.fix_missing_locations(ast.If(ast.Num(1), stmts, []))
+        new_node = fix_locations(ast.If(ast.Num(1), stmts, []), node)
         return CallTransformer(argdict, body).visit(new_node)
 
 
     AST visitor that expands macros.
     """
 
-    def __init__(self, module, macro_definitions=None):
+    def __init__(self, module, macro_definitions=None, debug=False):
         self.module = module
+        self.debug=debug
         self.defs = macro_definitions or {}
 
     def visit_ImportFrom(self, node):
             if not macro_def.has_body:
                 raise MacroCallError(node, 'macro has no __body__ substitution')
             return macro_def.expand(node, expr.args, expanded_body)
-        return node
+        else:
+            new_node = ast.With(node.context_expr, node.optional_vars, expanded_body)
+            new_node.lineno, new_node.col_offset = node.lineno, node.col_offset
+            return new_node
 
     def _handle_call(self, node, macrotype):
         if node.keywords or node.starargs or node.kwargs:
            isinstance(value.func, ast.Name) and value.func.id in self.defs:
             ret = self._handle_call(value, (ExprMacroDef, BlockMacroDef))
             if isinstance(ret, ast.expr):
-                ret = ast.fix_missing_locations(ast.Expr(ret))
+                ret = fix_locations(ast.Expr(ret), node)
             return ret
         return node
 
                 module.__path__ = newpath
             tree = ast.parse(code)
             try:
-                transformed = Expander(module).visit(tree)
+                transformed = Expander(module, debug=name=='domination.gameengine').visit(tree)
             except MacroCallError, err:
                 err.add_filename(filename)
                 raise
 
 setup(
     name='karnickel',
-    version='0.1',
+    version='0.2',
     url='http://dev.pocoo.org/',
     download_url='http://pypi.python.org/pypi/karnickel',
     license='BSD',
     long_description=long_desc,
     zip_safe=False,
     classifiers=[
-        'Development Status :: 3 - Alpha',
+        'Development Status :: 4 - Beta',
         'Intended Audience :: Developers',
         'License :: OSI Approved :: BSD License',
         'Operating System :: OS Independent',