1 #!/usr/bin/env python 2 3 """ 4 View annotated sources. 5 6 Copyright (C) 2006 Paul Boddie <paul@boddie.org.uk> 7 8 This software is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License as 10 published by the Free Software Foundation; either version 2 of 11 the License, or (at your option) any later version. 12 13 This software is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public 19 License along with this library; see the file LICENCE.txt 20 If not, write to the Free Software Foundation, Inc., 21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 22 """ 23 24 from compiler.visitor import ASTVisitor 25 import sys 26 27 class Viewer(ASTVisitor): 28 29 """ 30 A viewing visitor for AST nodes. 31 """ 32 33 def __init__(self, stream): 34 ASTVisitor.__init__(self) 35 self.cached_files = {} 36 self.printed_lines = {} 37 self.visitor = self 38 self.stream = stream 39 40 def process(self, module): 41 self.dispatch(module) 42 43 def dispatch(self, node): 44 self.dispatch_only(node) 45 ASTVisitor.dispatch(self, node) 46 47 def dispatch_only(self, node, every_time=0): 48 self.print_line(getattr(node, "filename", None), getattr(node, "lineno", None), every_time) 49 50 def print_line(self, filename, lineno, every_time): 51 last_printed = self.printed_lines.get(filename, 0) 52 if lineno > last_printed or every_time: 53 self.stream.write(self.get_line(filename, lineno)) 54 self.printed_lines[filename] = lineno 55 56 def get_line(self, filename, lineno): 57 if filename is None or lineno is None: 58 return "" 59 60 if self.cached_files.has_key(filename): 61 lines = self.cached_files[filename] 62 else: 63 f = open(filename) 64 try: 65 self.cached_files[filename] = lines = f.readlines() 66 finally: 67 f.close() 68 69 try: 70 return lines[lineno - 1] 71 except IndexError: 72 return "" 73 74 def report(self, exc): 75 self.stream.write("Exception was:\n\n" + str(exc.exc) + "\n\n") 76 self.stream.write("Nodes:\n\n") 77 for node in exc.nodes: 78 self.stream.write(repr(node) + "\n") 79 self.dispatch_only(node.original, every_time=1) 80 self.stream.write("\nOriginal node was:\n\n" + repr(exc.nodes[0].original) + "\n") 81 self.stream.write("\nSimplified node was:\n\n") 82 exc.nodes[0].pprint(stream=self.stream) 83 84 # Convenience functions. 85 86 def view(module, stream=None): 87 viewer = Viewer(stream or sys.stdout) 88 viewer.process(module.original) 89 90 # vim: tabstop=4 expandtab shiftwidth=4