File: ScopeStripper.py

package info (click to toggle)
synopsis 0.8.0-5
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 10,112 kB
  • ctags: 12,996
  • sloc: cpp: 34,254; ansic: 33,620; python: 10,975; sh: 7,261; xml: 6,369; makefile: 773; asm: 445
file content (135 lines) | stat: -rw-r--r-- 4,437 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#
# Copyright (C) 2000 Stefan Seefeld
# Copyright (C) 2000 Stephen Davies
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#

from Synopsis.Processor import Processor, Parameter
from Synopsis import AST, Type, Util

class ScopeStripper(Processor, AST.Visitor):
    """Strip common prefix from the declaration's name.
    Keep a list of root nodes, such that children whos parent
    scopes are not accepted but which themselfs are correct can
    be maintained as new root nodes."""

    scope = Parameter([], 'strip all but the given scope')

    def __init__(self, **kwds):

        Processor.__init__(self, **kwds)
        self.__root = []
        self.__in = 0

    def process(self, ast, **kwds):

        self.set_parameters(kwds)
        self.ast = self.merge_input(ast)
        if self.scope:

            self.__scope = tuple('::'.split(self.scope))
            # strip prefixes and remove non-matching declarations
            self.strip_declarations(self.ast.declarations())

            # Remove types not in strip
            self.strip_types(self.ast.types())

        return self.output_and_return_ast()
      
    def strip_name(self, name):
        #for scope in self.__scopes:
        depth = len(self.scope)
        if name[0:depth] == self.scope:
            if len(name) == depth: return None
            return name[depth:]
        return None
    
    def strip_declarations(self, declarations):

        for decl in declarations:
            decl.accept(self)
        declarations[:] = self.declarations()
	
    def strip_types(self, types):
        # Remove the empty type (caused by C++ with extract_tails)
        if types.has_key(()): del types[()]
        for name, type in types.items():
            try:
                del types[name]
                name = self.strip_name(name)
                if name:
                    type.set_name(name)
                    types[name] = type
            except:
                print "ERROR Processing:", name, types[name]
                raise

    def declarations(self): return self.__root
   
    def strip(self, declaration):
        """test whether the declaration matches one of the prefixes, strip
        it off, and return success. Success means that the declaration matches
        the prefix set and thus should not be removed from the AST."""
        passed = 0
        if not self.__scope: return 1
        for scope in [self.__scope]:
            depth = len(scope)
            name = declaration.name()
            if name[0:depth] == scope:
                if len(name) == depth: break
                if self.verbose: print "symbol", '::'.join(name),
                declaration.set_name(name[depth:])
                if self.verbose: print "stripped to", '::'.join(name)
                passed = 1
            else: break
        if self.verbose and not passed:
            print "symbol", '::'.join(declaration.name()), "removed"
        return passed

    def visitScope(self, scope):
        root = self.strip(scope) and not self.__in
        if root:
            self.__in = 1
            self.__root.append(scope)
        for declaration in scope.declarations():
            declaration.accept(self)
        if root: self.__in = 0

    def visitClass(self, clas):
        self.visitScope(clas)
        templ = clas.template()
        if templ:
            name = self.strip_name(templ.name())
            if name: templ.set_name(name)

    def visitDeclaration(self, decl):
        if self.strip(decl) and not self.__in:
            self.__root.append(decl)

    def visitEnumerator(self, enumerator):
        self.strip(enumerator)

    def visitEnum(self, enum):
        self.visitDeclaration(enum)
        for e in enum.enumerators():
            e.accept(self)

    def visitFunction(self, function):
        self.visitDeclaration(function)
        for parameter in function.parameters():
            parameter.accept(self)
        templ = function.template()
        if templ:
            name = self.strip_name(templ.name())
            if name: templ.set_name(name)

    def visitOperation(self, operation):
        self.visitFunction(operation)

    def visitMetaModule(self, module):
        self.visitScope(module)
        for decl in module.module_declarations():
            name = self.strip_name(decl.name())
            if name: decl.set_name(name)