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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#
# Copyright (C) 2003 Stefan Seefeld
# All rights reserved.
# Licensed to the public under the terms of the GNU LGPL (>= 2),
# see the file COPYING for details.
#
"""Scope sorting class module.
This module contains the class for sorting Scopes.
"""
from Synopsis.Processor import Parametrized, Parameter
from Synopsis import AST
import string
# The names of the access types
_axs_str = ('','Public ','Protected ','Private ')
# The predefined order for section names
_section_order = (
'Namespace', 'Module', 'Class', 'Typedef', 'Struct', 'Enum', 'Union',
'Group', 'Member function', 'Function'
)
# Compare two section names
def compare_sections(a, b):
# Determine access of each name
ai, bi = 0, 0
an, bn = a, b
for i in range(1,4):
access = _axs_str[i]
len_access = len(access)
is_a = (a[:len_access] == access)
is_b = (b[:len_access] == access)
if is_a:
if not is_b: return -1 # a before b
# Both matched
an = a[len_access:]
bn = b[len_access:]
break
if is_b:
return 1 # b before a
# Neither matched
# Same access, sort by predefined order
for section in _section_order:
if an == section: return -1 # a before b
if bn == section: return 1 # b before a
return 0
class ScopeSorter(Parametrized):
"""A class that takes a scope and sorts its children by type. To use it
call set_scope, then access the sorted list by the other methods."""
struct_as_class = Parameter(False, '')
def __init__(self, scope=None):
"Optional scope starts using that AST.Scope"
self.__scope = None
if scope: self.set_scope(scope)
def set_scope(self, scope):
"Sort children of given scope"
if scope is self.__scope: return
self.__sections = []
self.__section_dict = {}
self.__children = []
self.__child_dict = {}
self.__scope = scope
self.__sorted_sections = 0
self.__sorted_secnames = 0
scopename = scope.name()
for decl in scope.declarations():
if isinstance(decl, AST.Forward): continue
if isinstance(decl, AST.Builtin): continue
if isinstance(decl, AST.Group) and decl.__class__.__name__ == 'Group':
self._handle_group(decl)
continue
name, section = decl.name(), self._section_of(decl)
if len(name) > 1 and name[:-1] != scopename: continue
self._add_decl(decl, name, section)
self._sort_sections()
def _add_decl(self, decl, name, section):
"Adds the given decl with given name and section to the internal data"
if not self.__section_dict.has_key(section):
self.__section_dict[section] = []
self.__sections.append(section)
self.__section_dict[section].append(decl)
self.__children.append(decl)
self.__child_dict[tuple(name)] = decl
def _section_of(self, decl):
section = string.capitalize(decl.type())
if self.struct_as_class and section == 'Struct':
section = 'Class'
if decl.accessibility != AST.DEFAULT:
section = _axs_str[decl.accessibility()]+section
return section
def _sort_sections(self): pass
def sort_section_names(self):
"""Sorts sections names if they need it"""
if self.__sorted_secnames: return
self.__sections.sort(compare_sections)
self.__sorted_secnames = 1
def _set_section_names(self, sections): self.__sections = sections
def _handle_group(self, group):
"""Handles a group"""
section = group.name()[-1]
self._add_decl(group, group.name(), section)
for decl in group.declarations():
name = decl.name()
self._add_decl(decl, name, section)
def sort_sections(self):
"""Sorts the children of all sections, if they need it"""
if self.__sorted_sections: return
for children in self.__section_dict.values()+[self.__children]:
dict = {}
for child in children: dict[child.name()] = child
names = dict.keys()
names.sort()
del children[:]
for name in names: children.append(dict[name])
self.__sorted_sections = 1
def child(self, name):
"Returns the child with the given name. Throws KeyError if not found."
return self.__child_dict[name]
def sections(self):
"Returns a list of available section names"
return self.__sections
def children(self, section=None):
"Returns list of children in given section, or all children"
if section is None: return self.__children
if self.__section_dict.has_key(section):
return self.__section_dict[section]
return {}
|