123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- """Defines source maps: dictionaries that map lines in generated source to debug information."""
- class SourceMapBase(object):
- """Define a base class for source maps: objects that can convert line numbers
- to debug information."""
- def get_debug_info(self, line_number):
- """Gets the debug information for the given line number, or None if no debug info was
- found."""
- raise NotImplementedError()
- class SourceMap(SourceMapBase):
- """A source map, which converts generated source lines to debug information."""
- def __init__(self):
- SourceMapBase.__init__(self)
- self.lines = {}
- def map_line(self, line_number, debug_info):
- """Assigns the given debug information to the given line."""
- self.lines[line_number] = debug_info
- def get_debug_info(self, line_number):
- """Gets the debug information for the given line number, or None if no debug info was
- found."""
- if line_number in self.lines:
- return self.lines[line_number]
- else:
- return None
- def __str__(self):
- return '\n'.join(
- ['%d: %s' % pair
- for pair in sorted(self.lines.items(), key=lambda (key, _): key)])
- class SourceMapBuilder(object):
- """A type of object that makes it easy to build source maps for hierarchical instructions."""
- def __init__(self, initial_line_number=0):
- self.source_map = SourceMap()
- self.debug_info_stack = []
- self.line_number = initial_line_number - 1
- def push_debug_info(self, debug_info):
- """Informs the source map that subsequent lines of code will have the given debug
- information associated with them."""
- self.debug_info_stack.append(debug_info)
- def pop_debug_info(self):
- """Informs the source map that the debug information that was pushed last should
- be discarded in favor of the debug information that was pushed onto the stack
- just prior to it."""
- return self.debug_info_stack.pop()
- def append_line(self):
- """Has the source map builder increment its line number counter, and assigns the debug
- information that is at the top of the debug information stack to that line."""
- self.line_number += 1
- if len(self.debug_info_stack) > 0:
- self.source_map.map_line(self.line_number, self.debug_info_stack[-1])
- def __str__(self):
- return str(self.source_map)
- class ManualSourceMap(SourceMapBase):
- """A source map whose debug information can be set and reset. Line numbers are ignored."""
- def __init__(self):
- SourceMapBase.__init__(self)
- self.debug_information = None
- def get_debug_info(self, _):
- """Gets the debug information for the given line number, or None if no debug info was
- found."""
- return self.debug_information
- def __str__(self):
- return str(self.debug_information)
- class InterpreterSourceMap(SourceMapBase):
- """A source map that extracts debug information from the reference interpreter's debug info
- stack. Line numbers are ignored."""
- def __init__(self, kernel, task_name, stack_index):
- SourceMapBase.__init__(self)
- self.kernel = kernel
- self.task_name = task_name
- self.stack_index = stack_index
- def get_debug_info(self, _):
- """Gets the debug information for the given line number, or None if no debug info was
- found."""
- return self.kernel.debug_info[self.task_name][self.stack_index]
- def __str__(self):
- return str(self.get_debug_info(None))
|