Commit 78992e88 authored by Stefan Behnel's avatar Stefan Behnel

make current scope available to FunctionState and CCodeWriter to give access...

make current scope available to FunctionState and CCodeWriter to give access to variable types from AnnotationCCodeWriter
parent dcd13ee0
...@@ -29,12 +29,14 @@ class AnnotationCCodeWriter(CCodeWriter): ...@@ -29,12 +29,14 @@ class AnnotationCCodeWriter(CCodeWriter):
self.annotation_buffer = StringIO() self.annotation_buffer = StringIO()
self.annotations = [] self.annotations = []
self.last_annotated_pos = None self.last_annotated_pos = None
self.code = defaultdict(partial(defaultdict, str)) self.code = defaultdict(partial(defaultdict, str)) # code[filename][line] -> str
self.scopes = defaultdict(partial(defaultdict, set)) # scopes[filename][line] -> set(scopes)
else: else:
# When creating an insertion point, keep references to the same database # When creating an insertion point, keep references to the same database
self.annotation_buffer = create_from.annotation_buffer self.annotation_buffer = create_from.annotation_buffer
self.annotations = create_from.annotations self.annotations = create_from.annotations
self.code = create_from.code self.code = create_from.code
self.scopes = create_from.scopes
self.last_annotated_pos = create_from.last_annotated_pos self.last_annotated_pos = create_from.last_annotated_pos
def create_new(self, create_from, buffer, copy_formatting): def create_new(self, create_from, buffer, copy_formatting):
...@@ -47,6 +49,9 @@ class AnnotationCCodeWriter(CCodeWriter): ...@@ -47,6 +49,9 @@ class AnnotationCCodeWriter(CCodeWriter):
def mark_pos(self, pos, trace=True): def mark_pos(self, pos, trace=True):
if pos is not None: if pos is not None:
CCodeWriter.mark_pos(self, pos, trace) CCodeWriter.mark_pos(self, pos, trace)
if self.funcstate and self.funcstate.scope:
# lambdas and genexprs can result in multiple scopes per line => keep them in a set
self.scopes[pos[0].filename][pos[1]].add(self.funcstate.scope)
if self.last_annotated_pos: if self.last_annotated_pos:
source_desc, line, _ = self.last_annotated_pos source_desc, line, _ = self.last_annotated_pos
pos_code = self.code[source_desc.filename] pos_code = self.code[source_desc.filename]
......
...@@ -20,6 +20,7 @@ cimport cython ...@@ -20,6 +20,7 @@ cimport cython
cdef class FunctionState: cdef class FunctionState:
cdef public set names_taken cdef public set names_taken
cdef public object owner cdef public object owner
cdef public object scope
cdef public object error_label cdef public object error_label
cdef public size_t label_counter cdef public size_t label_counter
......
...@@ -582,11 +582,13 @@ class FunctionState(object): ...@@ -582,11 +582,13 @@ class FunctionState(object):
# in_try_finally boolean inside try of try...finally # in_try_finally boolean inside try of try...finally
# exc_vars (string * 3) exception variables for reraise, or None # exc_vars (string * 3) exception variables for reraise, or None
# can_trace boolean line tracing is supported in the current context # can_trace boolean line tracing is supported in the current context
# scope Scope the scope object of the current function
# Not used for now, perhaps later # Not used for now, perhaps later
def __init__(self, owner, names_taken=set()): def __init__(self, owner, names_taken=set(), scope=None):
self.names_taken = names_taken self.names_taken = names_taken
self.owner = owner self.owner = owner
self.scope = scope
self.error_label = None self.error_label = None
self.label_counter = 0 self.label_counter = 0
...@@ -1627,8 +1629,8 @@ class CCodeWriter(object): ...@@ -1627,8 +1629,8 @@ class CCodeWriter(object):
def label_used(self, lbl): return self.funcstate.label_used(lbl) def label_used(self, lbl): return self.funcstate.label_used(lbl)
def enter_cfunc_scope(self): def enter_cfunc_scope(self, scope=None):
self.funcstate = FunctionState(self) self.funcstate = FunctionState(self, scope=scope)
def exit_cfunc_scope(self): def exit_cfunc_scope(self):
self.funcstate = None self.funcstate = None
......
...@@ -2101,7 +2101,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2101,7 +2101,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.exit_cfunc_scope() # done with labels code.exit_cfunc_scope() # done with labels
def generate_module_init_func(self, imported_modules, env, code): def generate_module_init_func(self, imported_modules, env, code):
code.enter_cfunc_scope() code.enter_cfunc_scope(self.scope)
code.putln("") code.putln("")
header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
......
...@@ -1732,7 +1732,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1732,7 +1732,7 @@ class FuncDefNode(StatNode, BlockNode):
UtilityCode.load_cached("Profile", "Profile.c")) UtilityCode.load_cached("Profile", "Profile.c"))
# Generate C code for header and body of function # Generate C code for header and body of function
code.enter_cfunc_scope() code.enter_cfunc_scope(lenv)
code.return_from_error_cleanup_label = code.new_label() code.return_from_error_cleanup_label = code.new_label()
code.funcstate.gil_owned = not lenv.nogil code.funcstate.gil_owned = not lenv.nogil
...@@ -3219,7 +3219,7 @@ class DefNodeWrapper(FuncDefNode): ...@@ -3219,7 +3219,7 @@ class DefNodeWrapper(FuncDefNode):
if preprocessor_guard: if preprocessor_guard:
code.putln(preprocessor_guard) code.putln(preprocessor_guard)
code.enter_cfunc_scope() code.enter_cfunc_scope(lenv)
code.return_from_error_cleanup_label = code.new_label() code.return_from_error_cleanup_label = code.new_label()
with_pymethdef = (self.target.needs_assignment_synthesis(env, code) or with_pymethdef = (self.target.needs_assignment_synthesis(env, code) or
...@@ -4045,7 +4045,7 @@ class GeneratorBodyDefNode(DefNode): ...@@ -4045,7 +4045,7 @@ class GeneratorBodyDefNode(DefNode):
self.body.generate_function_definitions(lenv, code) self.body.generate_function_definitions(lenv, code)
# Generate C code for header and body of function # Generate C code for header and body of function
code.enter_cfunc_scope() code.enter_cfunc_scope(lenv)
code.return_from_error_cleanup_label = code.new_label() code.return_from_error_cleanup_label = code.new_label()
# ----- Top-level constants used by this function # ----- Top-level constants used by this function
......
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