Commit 9140d0f9 authored by Mark Florisson's avatar Mark Florisson

Debugger closure support

parent e5bb833d
......@@ -1591,6 +1591,11 @@ class DebugTransform(CythonTransform):
#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
......@@ -1606,6 +1611,8 @@ class DebugTransform(CythonTransform):
# 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
......@@ -1625,8 +1632,14 @@ class DebugTransform(CythonTransform):
# 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 = ''
......@@ -1654,7 +1667,9 @@ class DebugTransform(CythonTransform):
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')
......
......@@ -182,7 +182,8 @@ class TestDebugTransform(DebuggerTestCase):
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]
......
......@@ -21,16 +21,22 @@ def spam(a=0):
puts("spam")
os.path.join("foo", "bar")
some_c_function()
cpdef eggs():
pass
cdef ham():
pass
cpdef eggs():
pass
cdef class SomeClass(object):
def spam(self):
pass
def closure():
a = 1
def inner():
b = 2
return inner
spam()
print "bye!"
......@@ -98,7 +98,7 @@ class TestDebugInformationClasses(DebugTestCase):
'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
......
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