#self.c_output_file = options.output_file
self.c_output_file = result.c_file
+ # Closure support, basically treat nested functions as if the AST were
+ # never nested
+ self.in_funcdef = False
+ self.nested_funcdefs = []
+
# tells visit_NameNode whether it should register step-into functions
self.register_stepinto = False
# serialize functions
self.tb.start('Functions')
self.visitchildren(node)
+ for nested_funcdef in self.nested_funcdefs:
+ self.visit_FuncDefNode(nested_funcdef)
self.tb.end('Functions')
# 2.3 compatibility. Serialize global variables
# Cython.Compiler.ModuleNode.ModuleNode._serialize_lineno_map
return node
- def visit_FuncDefNode(self, node):
+ def visit_FuncDefNode(self, node):
self.visited.add(node.local_scope.qualified_name)
+
+ if self.in_funcdef:
+ if not self.register_stepinto:
+ self.nested_funcdefs.append(node)
+ return node
+
# node.entry.visibility = 'extern'
if node.py_func is None:
pf_cname = ''
self.tb.start('StepIntoFunctions')
self.register_stepinto = True
+ self.in_funcdef = True
self.visitchildren(node)
+ self.in_funcdef = False
self.register_stepinto = False
self.tb.end('StepIntoFunctions')
self.tb.end('Function')
self.assertEqual('PythonObject', xml_globals.get('python_var'))
# test functions
- funcnames = 'codefile.spam', 'codefile.ham', 'codefile.eggs'
+ funcnames = ('codefile.spam', 'codefile.ham', 'codefile.eggs',
+ 'codefile.closure', 'codefile.inner')
required_xml_attrs = 'name', 'cname', 'qualified_name'
assert all([f in xml_funcs for f in funcnames])
spam, ham, eggs = [xml_funcs[funcname] for funcname in funcnames]
'codefile.SomeClass.spam')
self.assertEqual(self.spam_func.module, self.module)
- assert self.eggs_func.pf_cname
+ assert self.eggs_func.pf_cname, (self.eggs_func, self.eggs_func.pf_cname)
assert not self.ham_func.pf_cname
assert not self.spam_func.pf_cname
assert not self.spam_meth.pf_cname