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)
|