File: Synopsis/Processors/SXRCompiler.py
 1#
 2# Copyright (C) 2008 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
 8from Synopsis import SXR
 9from Synopsis.Processor import *
10from Synopsis.QualifiedName import *
11from xml.dom.minidom import parse
12import os.path
13
14class SXRCompiler(Processor):
15    """This class compiles symbol references stored in sxr files into a single symbol table."""
16
17    prefix = Parameter('', 'where to look for sxr files')
18    no_locals = Parameter(True, '')
19
20    def process(self, ir, **kwds):
21
22        self.set_parameters(kwds)
23        if not self.prefix: raise MissingArgument('prefix')
24        self.ir = self.merge_input(ir)
25
26        def prefix(filename):
27            "Map filename to sxr filename."
28
29            # Even though filenames shouldn't be absolute, we protect ourselves
30            # against accidents.
31            if os.path.isabs(filename):
32                filename = os.path.splitdrive(filename)[1][1:]
33            return os.path.join(self.prefix, filename) + '.sxr'
34
35        for f in self.ir.files.values():
36            if f.annotations['primary'] and os.path.exists(prefix(f.name)):
37                self.compile(prefix(f.name), f.annotations['language'])
38
39        self.ir.sxr.generate_index()
40
41        return self.ir
42
43    def compile(self, filename, language):
44
45        if language == 'Python':
46            QName = lambda name: QualifiedPythonName(str(name).split('.'))
47        else:
48            QName = lambda name: QualifiedCxxName(str(name).split('::'))
49
50
51        if self.verbose: print "SXRCompiler: Reading", filename
52        try:
53            document = parse(filename)
54        except:
55            if self.debug:
56                print 'Error parsing', filename
57                raise
58            else:
59                raise InternalError('parsing %s'%filename)
60        sxr = document.documentElement
61        filename = sxr.getAttribute('filename')
62        lines = sxr.getElementsByTagName('line')
63        for lineno, line in enumerate(lines):
64            for a in line.getElementsByTagName('a'):
65                if a.getAttribute('continuation') == 'true':
66                    continue
67                qname = QName(a.getAttribute('href'))
68                origin = QName(a.getAttribute('from'))
69                type = str(a.getAttribute('type'))
70                if self.no_locals:
71                    bad = False
72                    for i in range(len(qname)):
73                        if len(qname[i]) > 0 and qname[i][0] == '`':
74                            # Don't store local function variables
75                            bad = True
76                            break
77                    if bad: continue
78
79                    for i in range(len(origin)):
80                        if len(origin[i]) > 0 and origin[i][0] == '`':
81                            # Function scope, truncate here
82                            origin = origin[:i] + (origin[i][1:],)
83                            break
84                entry = self.ir.sxr.setdefault(qname, SXR.Entry())
85                if type == 'definition':
86                    entry.definitions.append((filename, lineno + 1, origin))
87                elif type == 'call':
88                    entry.calls.append((filename, lineno + 1, origin))
89                elif type == 'reference':
90                    entry.references.append((filename, lineno + 1, origin))
91                else:
92                    print 'Warning: Unknown sxr type in %s:%d : %s'%(filename, lineno + 1, type)
93
94
95