Synopsis - Synopsis/Formatters/HTML/Views/XRef.py

File: Synopsis/Formatters/HTML/Views/XRef.py

      1#
      2# Copyright (C) 2000 Stephen Davies
      3# Copyright (C) 2000 Stefan Seefeld
      4# All rights reserved.
      5# Licensed to the public under the terms of the GNU LGPL (>= 2),
      6# see the file COPYING for details.
      7#
      8
      9from Synopsis import config
     10from Synopsis.Processor import Parameter
     11from Synopsis import ASG
     12from Synopsis.Formatters.TOC import TOC, Linker
     13from Synopsis.Formatters.HTML.View import View
     14from Synopsis.Formatters.HTML.Tags import *
     15import os, time
     16
     17class XRef(View):
     18    """A module for creating views full of xref infos"""
     19
     20    link_to_scope = Parameter(True, '')
     21
     22    def register(self, frame):
     23
     24        super(XRef, self).register(frame)
     25        self.__filename = None
     26        self.__title = None
     27        self.__toc = TOC(None)
     28
     29        if self.processor.sxr_prefix is None: return
     30
     31        self.icon = 'xref.png'
     32        share = config.datadir
     33        src = os.path.join(share, 'xref.png')
     34        self.directory_layout.copy_file(src, self.icon)
     35
     36        # Add an entry for every xref
     37        for name in self.processor.ir.sxr.keys():
     38            page = self.processor.xref.get(name)
     39            file = self.directory_layout.special('xref%d'%page)
     40            file += '#' + quote_as_id(str(name))
     41            self.__toc.insert(TOC.Entry(name, file, 'C++', 'xref'))
     42
     43    def toc(self, start):
     44
     45        return self.__toc
     46
     47    def filename(self):
     48
     49        return self.__filename
     50
     51    def title(self):
     52
     53        return self.__title
     54
     55    def process(self):
     56
     57        if self.processor.sxr_prefix is None: return
     58
     59        pages = self.processor.xref.pages()
     60        if not pages: return
     61        for p in range(len(pages)):
     62            self.__filename = self.directory_layout.xref(p)
     63
     64            first, last = pages[p][0], pages[p][-1]
     65            self.__title = 'Cross Reference : %s - %s'%(escape(str(first)), escape(str(last)))
     66
     67            self.start_file()
     68            self.write_navigation_bar()
     69            self.write(element('h1', self.title()))
     70            for name in pages[p]:
     71                self.write('<div class="xref-name">')
     72                self.process_name(name)
     73                self.write('</div>')
     74            self.end_file()
     75
     76    def register_filenames(self):
     77        """Registers each view"""
     78
     79        if self.processor.sxr_prefix is None: return
     80
     81        pages = self.processor.xref.pages()
     82        if not pages: return
     83        for p in range(len(pages)):
     84            filename = self.directory_layout.special('xref%d'%p)
     85            self.processor.register_filename(filename, self, p)
     86
     87    def process_link(self, file, line, scope):
     88        """Outputs the info for one link"""
     89
     90        file_link = self.directory_layout.file_source(file)
     91        file_link = rel(self.filename(), file_link) + "#%d"%line
     92        desc = ''
     93        type = self.processor.ir.asg.types.get(scope)
     94        if isinstance(type, ASG.DeclaredTypeId):
     95            desc = ' ' + type.declaration.type
     96        entry = self.processor.toc[scope]
     97        if entry:
     98            label = href(rel(self.filename(), entry.link), escape(str(scope)))
     99        else:
    100            label = escape(str(scope))
    101        self.write('<li><a href="%s">%s:%s</a>: in%s %s</li>\n'%(
    102            file_link, file, line, desc, label))
    103
    104    def describe_declaration(self, decl):
    105        """Returns a description of the declaration. Detects constructors and
    106        destructors"""
    107
    108        name = decl.name
    109        if isinstance(decl, ASG.Function) and len(name) > 1:
    110            real = decl.real_name[-1]
    111            if name[-2] == real:
    112                return 'Constructor '
    113            elif real[0] == '~' and name[-2] == real[1:]:
    114                return 'Destructor '
    115        return decl.type.capitalize() + ' '
    116
    117    def process_name(self, name):
    118        """Outputs the info for a given name"""
    119
    120        entry = self.processor.ir.sxr.get(name)
    121        if not entry: return
    122        self.write(element('a', '', id=quote_as_id(str(name))))
    123        desc = ''
    124        decl = None
    125        type = self.processor.ir.asg.types.get(name)
    126        if isinstance(type, ASG.DeclaredTypeId):
    127            decl = type.declaration
    128            desc = self.describe_declaration(decl)
    129        self.write(element('h2', desc + escape(str(name))) + '<ul>\n')
    130
    131        if self.link_to_scope:
    132            type = self.processor.ir.asg.types.get(name, None)
    133            if isinstance(type, ASG.DeclaredTypeId):
    134                link = self.directory_layout.link(type.declaration)
    135                self.write('<li>'+href(rel(self.__filename, link), 'Documentation')+'</li>')
    136        if entry.definitions:
    137            self.write('<li>Defined at:\n<ul>\n')
    138            for file, line, scope in entry.definitions:
    139                self.process_link(file, line, scope)
    140            self.write('</ul></li>\n')
    141        if entry.calls:
    142            self.write('<li>Called from:\n<ul>\n')
    143            for file, line, scope in entry.calls:
    144                self.process_link(file, line, scope)
    145            self.write('</ul></li>\n')
    146        if entry.references:
    147            self.write('<li>Referenced from:\n<ul>\n')
    148            for file, line, scope in entry.references:
    149                self.process_link(file, line, scope)
    150            self.write('</ul></li>\n')
    151        if isinstance(decl, ASG.Scope) and decl.declarations:
    152            self.write('<li>Declarations:\n<ul>\n')
    153            for child in decl.declarations:
    154                if isinstance(child, ASG.Builtin) and child.type == 'EOS':
    155                    continue
    156                file, line = child.file.name, child.line
    157                file_link = self.directory_layout.file_source(file)
    158                file_link = rel(self.filename(),file_link) + '#%d'%line
    159                file_href = '<a href="%s">%s:%s</a>: '%(file_link,file,line)
    160                cname = child.name
    161                entry = self.processor.toc[cname]
    162                type = self.describe_declaration(child)
    163                if entry:
    164                    link = href(rel(self.filename(), entry.link), escape(str(name.prune(cname))))
    165                    self.write(element('li', file_href + type + link))
    166                else:
    167                    self.write(element('li', file_href + type + str(name.prune(cname))))
    168            self.write('</ul>\n</li>\n')
    169        self.write('</ul>\n')
    170
    171    def end_file(self):
    172        """Overrides end_file to provide synopsis logo"""
    173
    174        self.write('\n')
    175        now = time.strftime(r'%c', time.localtime(time.time()))
    176        logo = img(src=rel(self.filename(), 'synopsis.png'), alt='logo')
    177        logo = href('http://synopsis.fresco.org', logo + ' synopsis', target='_blank')
    178        logo += ' (version %s)'%config.version
    179        self.write(div('logo', 'Generated on ' + now + ' by \n<br/>\n' + logo))
    180        View.end_file(self)
    181

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