File: Synopsis/Processors/NameMapper.py
 1#
 2# Copyright (C) 2000 Stefan Seefeld
 3# Copyright (C) 2000 Stephen Davies
 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.Processor import Processor, Parameter
10from Synopsis import ASG
11
12class NameMapper(Processor, ASG.Visitor):
13    """Abstract base class for name mapping."""
14
15    def visit_scope(self, node):
16        """Recursively visits declarations under this scope."""
17
18        self.visit_declaration(node)
19        for d in node.declarations:
20            d.accept(self)
21
22    def visit_group(self, node):
23        """Recursively visits declarations under this group."""
24
25        self.visit_declaration(node)
26        for d in node.declarations:
27            d.accept(self)
28
29
30class NamePrefixer(NameMapper):
31    """This class adds a prefix to all declaration and type names."""
32
33    prefix = Parameter([], 'the prefix which to prepend to all declared types')
34    type = Parameter('Language', 'type to use for the new toplevel modules')
35
36    def process(self, ir, **kwds):
37
38        self.set_parameters(kwds)
39        self.ir = self.merge_input(ir)
40
41        if not self.prefix:
42            return self.output_and_return_ir()
43
44        for decl in self.ir.asg.declarations:
45            decl.accept(self)
46
47        # Now we need to put the declarations in actual nested MetaModules
48        for index in range(len(self.prefix), 0, -1):
49            module = ASG.MetaModule(self.type, self.prefix[:index])
50            module.declarations.extend(self.ir.asg.declarations)
51            self.ir.asg.types[module.name] = ASG.DeclaredTypeId('',
52                                                                module.name,
53                                                                module)
54            self.ir.asg.declarations[:] = [module]
55
56        return self.output_and_return_ir()
57
58    def visit_declaration(self, decl):
59        """Changes the name of this declaration and its associated type"""
60
61        # Change the name of the decl
62        name = decl.name
63        new_name = tuple(self.prefix + list(name))
64        decl.name = new_name
65        # Change the name of the associated type
66        try:
67            type = self.ir.asg.types[name]
68            del self.ir.asg.types[name]
69            type.name = new_name
70            self.ir.asg.types[new_name] = type
71        except KeyError, msg:
72            if self.verbose: print "Warning: Unable to map name of type:",msg
73
74