Modules |
Files |
Inheritance Tree |
Inheritance Graph |
Name Index |
Config
File: Synopsis/Formatter/HTML/InheritanceGraph.py
1| # $Id: InheritanceGraph.py,v 1.24 2003/02/01 05:35:45 chalky Exp $
2| #
3| # This file is a part of Synopsis.
4| # Copyright (C) 2000, 2001 Stephen Davies
5| # Copyright (C) 2000, 2001 Stefan Seefeld
6| #
7| # Synopsis is free software; you can redistribute it and/or modify it
8| # under the terms of the GNU General Public License as published by
9| # the Free Software Foundation; either version 2 of the License, or
10| # (at your option) any later version.
11| #
12| # This program is distributed in the hope that it will be useful,
13| # but WITHOUT ANY WARRANTY; without even the implied warranty of
14| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15| # General Public License for more details.
16| #
17| # You should have received a copy of the GNU General Public License
18| # along with this program; if not, write to the Free Software
19| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20| # 02111-1307, USA.
21| #
22| # $Log: InheritanceGraph.py,v $
23| # Revision 1.24 2003/02/01 05:35:45 chalky
24| # Remove warning
25| #
26| # Revision 1.23 2002/12/09 04:00:59 chalky
27| # Added multiple file support to parsers, changed AST datastructure to handle
28| # new information, added a demo to demo/C++. AST Declarations now have a
29| # reference to a SourceFile (which includes a filename) instead of a filename.
30| #
31| # Revision 1.22 2002/10/28 16:27:22 chalky
32| # Support horizontal inheritance graphs
33| #
34| # Revision 1.21 2002/10/28 11:44:57 chalky
35| # Split graphs into groups based on common prefixes, and display each separately
36| #
37| # Revision 1.20 2002/10/28 06:13:07 chalky
38| # Fix typo
39| #
40| # Revision 1.19 2002/10/27 12:03:49 chalky
41| # Rename min_size option to min_group_size, add new min_size option
42| #
43| # Revision 1.18 2002/07/19 14:26:32 chalky
44| # Revert prefix in FileLayout but keep relative referencing elsewhere.
45| #
46| # Revision 1.17 2002/07/11 02:09:33 chalky
47| # Patch from Patrick Mauritz: Use png support in latest graphviz. If dot not
48| # present, don't subvert what the user asked for but instead tell them.
49| #
50| # Revision 1.16 2002/07/04 06:43:18 chalky
51| # Improved support for absolute references - pages known their full path.
52| #
53| # Revision 1.15 2001/07/19 04:03:05 chalky
54| # New .syn file format.
55| #
56| # Revision 1.14 2001/07/11 01:45:03 stefan
57| # fix Dot and HTML formatters to adjust the references depending on the filename of the output
58| #
59| # Revision 1.13 2001/07/05 05:39:58 stefan
60| # advanced a lot in the refactoring of the HTML module.
61| # Page now is a truely polymorphic (abstract) class. Some derived classes
62| # implement the 'filename()' method as a constant, some return a variable
63| # dependent on what the current scope is...
64| #
65| # Revision 1.12 2001/07/05 02:08:35 uid20151
66| # Changed the registration of pages to be part of a two-phase construction
67| #
68| # Revision 1.11 2001/06/28 07:22:18 stefan
69| # more refactoring/cleanup in the HTML formatter
70| #
71| # Revision 1.10 2001/06/26 04:32:16 stefan
72| # A whole slew of changes mostly to fix the HTML formatter's output generation,
73| # i.e. to make the output more robust towards changes in the layout of files.
74| #
75| # the rpm script now works, i.e. it generates source and binary packages.
76| #
77| # Revision 1.9 2001/06/06 04:44:11 uid20151
78| # Only create TOC once instead of for every graph
79| #
80| # Revision 1.8 2001/04/06 06:26:39 chalky
81| # No more warning on bad types
82| #
83| # Revision 1.7 2001/03/29 14:12:42 chalky
84| # Consolidate small graphs to speed up processing time (graphviz is slow)
85| #
86| # Revision 1.6 2001/02/13 06:55:23 chalky
87| # Made synopsis -l work again
88| #
89| # Revision 1.5 2001/02/06 16:54:15 chalky
90| # Added -n to Dot which stops those nested classes
91| #
92| # Revision 1.4 2001/02/06 16:02:23 chalky
93| # Fixes
94| #
95| # Revision 1.3 2001/02/06 05:13:05 chalky
96| # Fixes
97| #
98| # Revision 1.2 2001/02/05 05:26:24 chalky
99| # Graphs are separated. Misc changes
100| #
101| # Revision 1.1 2001/02/01 20:09:18 chalky
102| # Initial commit.
103| #
104| # Revision 1.3 2001/02/01 18:36:55 chalky
105| # Moved TOC out to Formatter/TOC.py
106| #
107| # Revision 1.2 2001/02/01 15:23:24 chalky
108| # Copywritten brown paper bag edition.
109| #
110| #
111|
112| import os
113|
114| from Synopsis.Core import AST, Type, Util
115|
116| import core, Page
117| from core import config
118| from Tags import *
119|
120| class ToDecl (Type.Visitor):
121| def __call__(self, name):
122| try:
123| typeobj = config.types[name]
124| except KeyError:
125| # Eg: Unknown parent which has been NameMapped
126| #if config.verbose: print "Warning: %s not found in types dict."%(name,)
127| return None
128| self.__decl = None
129| typeobj.accept(self)
130| #if self.__decl is None:
131| # return None
132| return self.__decl
133|
134| def visitBaseType(self, type): return
135| def visitUnknown(self, type): return
136| def visitDeclared(self, type): self.__decl = type.declaration()
137| def visitModifier(self, type): type.alias().accept(self)
138| def visitArray(self, type): type.alias().accept(self)
139| def visitTemplate(self, type): self.__decl = type.declaration()
140| def visitParametrized(self, type): type.template().accept(self)
141| def visitFunctionType(self, type): return
142|
143| def find_common_name(graph):
144| common_name = list(graph[0])
145| for decl_name in graph[1:]:
146| if len(common_name) > len(decl_name):
147| common_name = common_name[:len(decl_name)]
148| for i in range(min(len(decl_name), len(common_name))):
149| if decl_name[i] != common_name[i]:
150| common_name = common_name[:i]
151| break
152| return string.join(common_name, '::')
153|
154|
155| class InheritanceGraph(Page.Page):
156| def __init__(self, manager):
157| Page.Page.__init__(self, manager)
158| self.__todecl = ToDecl()
159| self.__direction = 'vertical'
160| if hasattr(config.obj,'InheritanceGraph'):
161| if hasattr(config.obj.InheritanceGraph,'direction'):
162| if config.obj.InheritanceGraph.direction == 'horizontal':
163| self.__direction = 'horizontal'
164|
165| def filename(self): return config.files.nameOfSpecial('InheritanceGraph')
166| def title(self): return 'Synopsis - Class Hierarchy'
167|
168| def register(self):
169| """Registers this page with the manager"""
170| self.manager.addRootPage(self.filename(), 'Inheritance Graph', 'main', 1)
171|
172| def consolidate(self, graphs):
173| """Consolidates small graphs into larger ones"""
174| try:
175| min_size = config.obj.InheritanceGraph.min_size
176| except:
177| if config.verbose:
178| print "Error getting InheritanceGraph.min_size value. Using 1."
179| min_size = 1
180| try:
181| min_group_size = config.obj.InheritanceGraph.min_group_size
182| except:
183| if config.verbose:
184| print "Error getting InheritanceGraph.min_group_size value. Using 5."
185| min_group_size = 5
186| # Weed out the small graphs and group by common base name
187| common = {}
188| for graph in graphs:
189| len_graph = len(graph)
190| if len_graph < min_size:
191| # Ignore the graph
192| continue
193| common.setdefault(find_common_name(graph), []).append(graph)
194| # Consolidate each group
195| for name, graphs in common.items():
196| conned = []
197| pending = []
198| for graph in graphs:
199| # Try adding to an already pending graph
200| for pend in pending:
201| if len_graph + len(pend) <= min_group_size:
202| pend.extend(graph)
203| graph = None
204| if len(pend) == min_group_size:
205| conned.append(pend)
206| pending.remove(pend)
207| break
208| if graph:
209| if len_graph >= min_group_size:
210| # Add to final list
211| conned.append(graph)
212| else:
213| # Add to pending list
214| pending.append(graph)
215| graphs[:] = conned + pending
216| return common
217|
218| def process(self, start):
219| """Creates a file with the inheritance graph"""
220| filename = self.filename()
221| self.start_file()
222| self.write(self.manager.formatHeader(filename))
223| self.write(entity('h1', "Inheritance Graph"))
224|
225| try:
226| from Synopsis.Formatter import Dot
227| except:
228| print "InheritanceGraph: Can't load the Dot formatter"
229| self.end_file()
230| return
231| # Create a toc file for Dot to use
232| toc_file = filename + "-dot.toc"
233| config.toc.store(toc_file)
234| graphs = config.classTree.graphs()
235| count = 0
236| # Consolidate the graphs, and sort to make the largest appear first
237| lensorter = lambda a, b: cmp(len(b),len(a))
238| common_graphs = self.consolidate(graphs)
239| names = common_graphs.keys()
240| names.sort()
241| for name in names:
242| graphs = common_graphs[name]
243| graphs.sort(lensorter)
244| if name:
245| self.write('<div class="inheritance-group">')
246| scoped_name = string.split(name,'::')
247| type_str = ''
248| if core.config.types.has_key(scoped_name):
249| type = core.config.types[scoped_name]
250| if isinstance(type, Type.Declared):
251| type_str = type.declaration().type() + ' '
252| self.write('Graphs in '+type_str+name+':<br>')
253| for graph in graphs:
254| try:
255| if core.verbose: print "Creating graph #%s - %s classes"%(count,len(graph))
256| # Find declarations
257| declarations = map(self.__todecl, graph)
258| declarations = filter(lambda x: x is not None, declarations)
259| # Call Dot formatter
260| output = os.path.join(config.basename, os.path.splitext(self.filename())[0]) + '-%s'%count
261| args = (
262| '-i','-f','html','-o',output,'-r',toc_file,
263| '-R',self.filename(),'-t','Synopsis %s'%count,'-n',
264| '-p',name,'-d',self.__direction)
265| temp_ast = AST.AST({}, declarations, config.types)
266| Dot.format(args, temp_ast, None)
267| dot_file = open(output + '.html', 'r')
268| self.write(dot_file.read())
269| dot_file.close()
270| os.remove(output + ".html")
271| except:
272| import traceback
273| traceback.print_exc()
274| print "Graph:",graph
275| print "Declarations:",declarations
276| count = count + 1
277| if name:
278| self.write('</div>')
279|
280| os.remove(toc_file)
281|
282| self.end_file()
283|
284|
285| htmlPageClass = InheritanceGraph