From bd8563e212c7025adbca65d530dbf17977f6353c Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 20 Jan 2018 22:04:07 -0500 Subject: [PATCH] Add missing linemap.py file --- uncompyle6/main.py | 1 - uncompyle6/semantics/linemap.py | 50 +++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 uncompyle6/semantics/linemap.py diff --git a/uncompyle6/main.py b/uncompyle6/main.py index 95c55b59..9fa1e2d7 100644 --- a/uncompyle6/main.py +++ b/uncompyle6/main.py @@ -5,7 +5,6 @@ from uncompyle6 import verify, IS_PYPY from xdis.code import iscode from uncompyle6.disas import check_object_path from uncompyle6.semantics import pysource -from uncompyle6.semantics import linemap from uncompyle6.parser import ParserError from uncompyle6.version import VERSION from uncompyle6.linenumbers import line_number_mapping diff --git a/uncompyle6/semantics/linemap.py b/uncompyle6/semantics/linemap.py new file mode 100644 index 00000000..14177776 --- /dev/null +++ b/uncompyle6/semantics/linemap.py @@ -0,0 +1,50 @@ +from uncompyle6.semantics.pysource import SourceWalker, deparse_code + +# FIXME: does this handle nested code, and lambda properly +class LineMapWalker(SourceWalker): + def __init__(self, *args, first_line=0, **kwargs): + super(LineMapWalker, self).__init__(*args, **kwargs) + self.source_linemap = {} + self.current_line_number = first_line + + def write(self, *data): + """Augment write routine to keep track of current line""" + for l in data: + for i in str(l): + if i == '\n': + self.current_line_number += 1 + pass + pass + pass + return super(LineMapWalker, self).write(*data) + + def default(self, node): + """Augment write default routine to record line number changes""" + if hasattr(node, 'linestart'): + if node.linestart: + self.source_linemap[self.current_line_number] = node.linestart + return super(LineMapWalker, self).default(node) + +def deparse_code_with_map(*args, first_line=0, **kwargs): + """ + Like deparse_code but saves line number correspondences. + """ + kwargs['walker'] = LineMapWalker + return deparse_code(*args, **kwargs) + +if __name__ == '__main__': + def deparse_test(co): + "This is a docstring" + import sys + sys_version = float(sys.version[0:3]) + # deparsed = deparse_code(sys_version, co, showasm=True, showast=True) + deparsed = deparse_code_with_map(sys_version, co, showasm=False, showast=False, + showgrammar=False) + a = 1; b = 2 + print("\n") + linemap = [(line_no, deparsed.source_linemap[line_no]) + for line_no in + sorted(deparsed.source_linemap.keys())] + print(linemap) + return + deparse_test(deparse_test.__code__)