Synopsis - Synopsis/Formatters/Dump.py

File: Synopsis/Formatters/Dump.py

      1#
      2# Copyright (C) 2003 Stefan Seefeld
      3# All rights reserved.
      4# Licensed to the public under the terms of the GNU LGPL (>= 2),
      5# see the file COPYING for details.
      6#
      7
      8"""
      9Verbose attribute-oriented xml dump of ASG, useful for validation,
     10introspection, and debugging.
     11"""
     12
     13from Synopsis import config
     14from Synopsis.Processor import *
     15from Synopsis.SourceFile import SourceFile
     16from Synopsis.DocString import DocString
     17from Synopsis.QualifiedName import *
     18
     19import sys, getopt, os, os.path, string, types
     20from xml.dom.minidom import getDOMImplementation
     21
     22dom = getDOMImplementation().createDocument(None, 'dump', None)
     23
     24class Formatter(Processor):
     25
     26    show_ids = Parameter(True, 'output object ids as attributes')
     27    show_declarations = Parameter(True, 'output declarations')
     28    show_types = Parameter(True, 'output types')
     29    show_files = Parameter(True, 'output files')
     30    stylesheet = Parameter(config.datadir + '/dump.css', 'stylesheet to be referenced for rendering')
     31
     32    def process(self, ir, **kwds):
     33
     34        self.set_parameters(kwds)
     35        if not self.output: raise MissingArgument('output')
     36        self.ir = self.merge_input(ir)
     37
     38        self.handlers = {type(None) : self.visit_none,
     39                         type : self.visit_type,
     40                         int : self.visit_string,
     41                         long : self.visit_string,
     42                         float : self.visit_string,
     43                         str : self.visit_string,
     44                         bool : self.visit_string,
     45                         tuple : self.visit_tuple,
     46                         list : self.visit_list,
     47                         dict : self.visit_dict,
     48                         types.InstanceType : self.visit_instance,
     49                         QualifiedName : self.visit_string,
     50                         QualifiedCxxName : self.visit_string,
     51                         QualifiedPythonName : self.visit_string,
     52                         SourceFile : self.visit_sourcefile,
     53                         DocString : self.visit_docstring}
     54        self.visited = []
     55
     56        self.os = open(self.output, 'w')
     57        self.os.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
     58        if self.stylesheet:
     59            self.os.write('<?xml-stylesheet href="%s" type="text/css"?>\n'%self.stylesheet)
     60
     61        self.os.write('<ir>\n')
     62        self.os.write('<asg>\n')
     63
     64        if self.show_declarations:
     65            self.write_declarations(self.ir.asg.declarations)
     66
     67        if self.show_types:
     68            self.write_types(self.ir.asg.types)
     69        self.os.write('</asg>\n')
     70
     71        if self.show_files:
     72            self.write_files(self.ir.files)
     73
     74        self.os.write('</ir>\n')
     75
     76        return self.ir
     77
     78    def push(self, name):
     79
     80        element = dom.createElement(name)
     81        self.node.appendChild(element)
     82        self.node = element
     83
     84    def pop(self):
     85
     86        self.node = self.node.parentNode
     87
     88    def add_text(self, text):
     89
     90        node = dom.createTextNode(text)
     91        self.node.appendChild(node)
     92
     93    def visit(self, obj):
     94        i,t = id(obj), type(obj)
     95        if i in self.visited:
     96            if self.show_ids:
     97                self.node.setAttribute('xref', str(i))
     98            return
     99        if self.handlers.has_key(t):
    100            self.handlers[t](obj)
    101        elif issubclass(t, object):
    102            self.visit_instance(obj)
    103        else:
    104            print 'Unknown type %s for object: "%s"'%(t,obj)
    105
    106    def visit_none(self, obj): pass
    107    def visit_string(self, obj): self.add_text(str(obj))
    108    def visit_type(self, obj): self.write(obj) # where is that used ??
    109
    110    def visit_tuple(self, obj):
    111
    112        if len(obj) == 0: return
    113        for i in obj:
    114            self.push('item')
    115            self.visit(i)
    116            self.pop()
    117
    118    def visit_list(self, obj):
    119
    120        if len(obj) == 0: return
    121        for i in obj:
    122            self.push('item')
    123            self.visit(i)
    124            self.pop()
    125
    126    def visit_dict(self, dict):
    127
    128        items = dict.items()
    129        if len(items) == 0: return
    130        items.sort()
    131        for i in items:
    132            self.push('key')
    133            self.visit(i[0])
    134            self.pop()
    135            self.push('value')
    136            self.visit(i[1])
    137            self.pop()
    138
    139
    140    def visit_sourcefile(self, obj):
    141
    142        self.node.setAttribute('name', obj.name)
    143        self.node.setAttribute('language', obj.annotations.get('language', ''))
    144        self.node.setAttribute('primary', str(obj.annotations.get('primary', False)))
    145
    146        includes = getattr(obj, 'includes')
    147        if includes:
    148            self.push('includes')
    149            self.visit(includes)
    150            self.pop()
    151
    152        if self.show_declarations:
    153            for name in ['declarations', 'macro_calls']:
    154                self.push(name)
    155                self.visit(getattr(obj, name))
    156                self.pop()
    157
    158    def visit_docstring(self, obj):
    159
    160        self.node.setAttribute('markup', obj.markup)
    161        self.push('text')
    162        self.visit(obj.text)
    163        self.pop()
    164
    165
    166    def visit_instance(self, obj):
    167        self.visited.append(id(obj))
    168        self.push('instance')
    169        self.node.setAttribute('class', '%s.%s'%(obj.__class__.__module__,obj.__class__.__name__))
    170        if self.show_ids:
    171            self.node.setAttribute('id', str(id(obj)))
    172        if self.handlers.has_key(obj.__class__):
    173            self.handlers[obj.__class__](obj)
    174        else:
    175            attrs = obj.__dict__.items()
    176            attrs.sort()
    177            for name, value in attrs:
    178                # ignore None values
    179                if value in (None, [], ()):
    180                    continue
    181                # ignore private attributes
    182                if name[0] == '_':
    183                    continue
    184
    185                # String attributes map to xml attributes.
    186                if self.handlers.get(type(value)) == self.visit_string:
    187                    self.node.setAttribute(name, str(value))
    188                    # Everything else maps to sub-elements.
    189                else:
    190                    self.push(name)
    191                    self.visit(value)
    192                    self.pop()
    193        self.pop()
    194
    195    def write_declarations(self, declarations):
    196
    197        self.node = dom.createElement('declarations')
    198        for d in declarations:
    199            self.push('item')
    200            self.visit(d)
    201            self.pop()
    202        self.node.writexml(self.os, indent=' ', addindent=' ', newl='\n')
    203        self.node.unlink()
    204        del self.node
    205
    206    def write_types(self, types):
    207
    208        self.node = dom.createElement('types')
    209        values = types.values()
    210        values.sort()
    211        for t in values: self.visit(t)
    212        self.node.writexml(self.os, indent=' ', addindent=' ', newl='\n')
    213        self.node.unlink()
    214        del self.node
    215
    216    def write_files(self, files):
    217
    218        self.node = dom.createElement('files')
    219        for f in files: self.visit(files[f])
    220        self.node.writexml(self.os, indent=' ', addindent=' ', newl='\n')
    221        self.node.unlink()
    222        del self.node
    223
    224

Generated on Thu Apr 16 16:27:13 2009 by
synopsis (version devel)