Synopsis - Synopsis/Processors/ScopeStripper.py

File: Synopsis/Processors/ScopeStripper.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 *
     10from Synopsis import ASG
     11
     12class ScopeStripper(Processor, ASG.Visitor):
     13    """Strip common prefix from the declaration's name.
     14    Keep a list of root nodes, such that children whos parent
     15    scopes are not accepted but which themselfs are correct can
     16    be maintained as new root nodes."""
     17
     18    scope = Parameter('', 'strip all but the given scope')
     19
     20    def __init__(self, **kwds):
     21
     22        Processor.__init__(self, **kwds)
     23        self.declarations = []
     24        self.inside = False
     25        self._scope = ()
     26
     27    def process(self, ir, **kwds):
     28
     29        self.set_parameters(kwds)
     30        if not self.scope: raise MissingArgument('scope')
     31        self.ir = self.merge_input(ir)
     32        if '::' in self.scope:
     33            self._scope = tuple(self.scope.split('::'))
     34        else:
     35            self._scope = tuple(self.scope.split('.'))
     36
     37        # strip prefixes and remove non-matching declarations
     38        self.strip_declarations(self.ir.asg.declarations)
     39
     40        # Remove types not in strip
     41        self.strip_types(self.ir.asg.types)
     42
     43        return self.output_and_return_ir()
     44
     45
     46    def strip_name(self, name):
     47
     48        depth = len(self._scope)
     49        if name[:depth] == self._scope:
     50            if len(name) == depth: return None
     51            return name[depth:]
     52        return None
     53
     54
     55    def strip_declarations(self, declarations):
     56
     57        for decl in declarations:
     58            decl.accept(self)
     59        declarations[:] = self.declarations
     60
     61
     62    def strip_types(self, types):
     63        # Remove the empty type (caused by C++ with extract_tails)
     64        if types.has_key(()): del types[()]
     65        for name, type in types.items():
     66            try:
     67                del types[name]
     68                name = self.strip_name(name)
     69                if name:
     70                    type.name = name
     71                    types[name] = type
     72            except:
     73                print "ERROR Processing:", name, types[name]
     74                raise
     75
     76
     77    def strip(self, declaration):
     78        """test whether the declaration matches one of the prefixes, strip
     79        it off, and return success. Success means that the declaration matches
     80        the prefix set and thus should not be removed from the ASG."""
     81
     82        passed = False
     83        if not self._scope: return True
     84        depth = len(self._scope)
     85        name = declaration.name
     86        if name[:depth] == self._scope and len(name) > depth:
     87            if self.verbose: print "symbol", '::'.join(name),
     88            declaration.name = name[depth:]
     89            if self.verbose: print "stripped to", '::'.join(declaration.name)
     90            passed = True
     91        if self.verbose and not passed:
     92            print "symbol", '::'.join(declaration.name), "removed"
     93        return passed
     94
     95
     96    def visit_scope(self, scope):
     97
     98        root = self.strip(scope) and not self.inside
     99        if root:
    100            self.inside = True
    101            self.declarations.append(scope)
    102        for declaration in scope.declarations:
    103            declaration.accept(self)
    104        if root: self.inside = False
    105
    106
    107    def visit_class(self, class_):
    108
    109        self.visit_scope(class_)
    110
    111
    112    def visit_class_template(self, class_):
    113
    114        self.visit_class(class_)
    115        templ = class_.template
    116        if templ:
    117            name = self.strip_name(templ.name)
    118            if name: templ.name = name
    119
    120
    121    def visit_declaration(self, decl):
    122
    123        if self.strip(decl) and not self.inside:
    124            self.declarations.append(decl)
    125
    126
    127    def visit_enumerator(self, enumerator):
    128
    129        self.strip(enumerator)
    130
    131
    132    def visit_enum(self, enum):
    133
    134        self.visit_declaration(enum)
    135        for e in enum.enumerators:
    136            e.accept(self)
    137
    138
    139    def visit_function(self, function):
    140
    141        self.visit_declaration(function)
    142        for parameter in function.parameters:
    143            parameter.accept(self)
    144
    145
    146    def visit_parameter(self, parameter):
    147
    148        self.strip(parameter)
    149
    150
    151    def visit_function_template(self, function):
    152
    153        self.visit_function(function)
    154        if function.template:
    155            name = self.strip_name(function.template.name)
    156            if name: function.template.name = name
    157
    158
    159    def visit_operation(self, operation):
    160
    161        self.visit_function(operation)
    162
    163
    164    def visit_operation_template(self, operation):
    165
    166        self.visit_function_template(operation)
    167
    168
    169    def visit_meta_module(self, module):
    170
    171        self.visit_scope(module)
    172        for d in module.module_declarations:
    173            name = self.strip_name(d.name)
    174            if name: d.name = name
    175

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