def create_default_pipeline(context, options, result):
from ParseTreeTransforms import WithTransform, PostParse
from ParseTreeTransforms import AnalyseDeclarationsTransform, AnalyseExpressionsTransform
+ from ParseTreeTransforms import CreateClosureClasses
from ModuleNode import check_c_classes
return [
AnalyseDeclarationsTransform(),
check_c_classes,
AnalyseExpressionsTransform(),
+ CreateClosureClasses(),
create_generate_code(context, options, result)
]
from Cython.Compiler.Visitor import VisitorTransform, temp_name_handle
+from Cython.Compiler.ModuleNode import ModuleNode
from Cython.Compiler.Nodes import *
from Cython.Compiler.ExprNodes import *
from Cython.Compiler.TreeFragment import TreeFragment
-
class PostParse(VisitorTransform):
"""
This transform fixes up a few things after parsing
class AnalyseExpressionsTransform(VisitorTransform):
-
def visit_ModuleNode(self, node):
node.body.analyse_expressions(node.scope)
self.visitchildren(node)
self.visitchildren(node)
return node
+
+class CreateClosureClasses(VisitorTransform):
+ # Output closure classes in module scope for all functions
+ # that need it.
+
+ def visit_ModuleNode(self, node):
+ self.module_scope = node.scope
+ self.visitchildren(node)
+ return node
+
+ def create_class_from_scope(self, node, target_module_scope):
+ as_name = temp_name_handle("closure")
+ func_scope = node.local_scope
+
+ entry = target_module_scope.declare_c_class(name = as_name,
+ pos = node.pos, defining = True, implementing = True)
+ class_scope = entry.type.scope
+ for entry in func_scope.entries.values():
+ class_scope.declare_var(pos=node.pos,
+ name=entry.name,
+ cname=entry.cname,
+ type=entry.type,
+ is_cdef=True)
+
+ def visit_FuncDefNode(self, node):
+ self.create_class_from_scope(node, self.module_scope)
+ return node
+
+ def visit_Node(self, node):
+ self.visitchildren(node)
+ return node
+
if ctx.api:
error(s.pos, "'api' not allowed with this statement")
elif s.sy == 'def':
- if ctx.level not in ('module', 'class', 'c_class', 'property'):
+ if ctx.level not in ('module', 'class', 'c_class', 'function', 'property'):
s.error('def statement not allowed here')
s.level = ctx.level
return p_def_statement(s)
self.visitchildren(node)
self._indents -= 1
+def treetypes(root):
+ """Returns a string representing the tree by class names.
+ There's a leading and trailing whitespace so that it can be
+ compared by simple string comparison while still making test
+ cases look ok."""
+ w = NodeTypeWriter()
+ w.visit(root)
+ return u"\n".join([u""] + w.result + [u""])
+
class CythonTest(unittest.TestCase):
def assertLines(self, expected, result):
return TreeFragment(code, name, pxds)
def treetypes(self, root):
- """Returns a string representing the tree by class names.
- There's a leading and trailing whitespace so that it can be
- compared by simple string comparison while still making test
- cases look ok."""
- w = NodeTypeWriter()
- w.visit(root)
- return u"\n".join([u""] + w.result + [u""])
+ return treetypes(root)
class TransformTest(CythonTest):
"""