2 # GObject-Introspection - a framework for introspecting GObject libraries
3 # Copyright (C) 2008 Johan Dahlin
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 from __future__ import with_statement
22 from .glibtransformer import (GLibBoxed, GLibEnum, GLibEnumMember,
23 GLibFlags, GLibObject, GLibInterface)
24 from .transformer import Callback, Class, Enum, Function, Interface
25 from .xmlwriter import XMLWriter
28 class GIRWriter(XMLWriter):
29 def __init__(self, namespace, nodes):
30 super(GIRWriter, self).__init__()
31 self._write_repository(namespace, nodes)
33 def _write_repository(self, namespace, nodes):
36 ('xmlns', 'http://www.gtk.org/introspection/core/1.0'),
37 ('xmlns:c', 'http://www.gtk.org/introspection/c/1.0'),
38 ('xmlns:glib', 'http://www.gtk.org/introspection/glib/1.0'),
40 with self.tagcontext('repository', attrs):
41 self._write_namespace(namespace, nodes)
43 def _write_namespace(self, namespace, nodes):
44 with self.tagcontext('namespace', [('name', namespace)]):
46 self._write_node(node)
48 def _write_node(self, node):
49 if isinstance(node, Function):
50 self._write_function(node)
51 elif isinstance(node, Enum):
52 self._write_enum(node)
53 elif isinstance(node, (Class, Interface)):
54 self._write_class(node)
55 elif isinstance(node, GLibBoxed):
56 self._write_boxed(node)
57 elif isinstance(node, Callback):
58 self._write_callback(node)
60 print 'WRITER: Unhandled node', node
62 def _write_function(self, func, tag_name='function'):
63 attrs = [('name', func.name),
64 ('c:identifier', func.symbol)]
65 with self.tagcontext(tag_name, attrs):
66 self._write_return_type(func.retval)
67 self._write_parameters(func.parameters)
69 def _write_method(self, method):
70 self._write_function(method, tag_name='method')
72 def _write_constructor(self, method):
73 self._write_function(method, tag_name='constructor')
75 def _write_return_type(self, return_):
78 with self.tagcontext('return-values'):
79 with self.tagcontext('return-value'):
80 attrs = [('name', return_.type)]
81 if return_.transfer != 'none':
82 attrs.append(('transfer', return_.transfer))
83 self.write_tag('type', attrs)
85 def _write_parameters(self, parameters):
88 with self.tagcontext('parameters'):
89 for parameter in parameters:
90 self._write_parameter(parameter)
92 def _write_parameter(self, parameter):
93 attrs = [('name', parameter.name)]
94 if parameter.direction != 'in':
95 attrs.append(('direction', parameter.direction))
96 if parameter.transfer != 'none':
97 attrs.append(('transfer', parameter.transfer))
98 with self.tagcontext('parameters', attrs):
99 self.write_tag('type', [('name', parameter.type)])
101 def _write_enum(self, enum):
102 attrs = [('name', enum.name)]
103 tag_name = 'enumeration'
104 if isinstance(enum, GLibEnum):
105 attrs.extend([('glib:type-name', enum.type_name),
106 ('glib:get-type', enum.get_type)])
107 if isinstance(enum, GLibFlags):
108 tag_name = 'bitfield'
110 with self.tagcontext(tag_name, attrs):
111 for member in enum.members:
112 self._write_member(member)
114 def _write_member(self, member):
115 attrs = [('name', member.name),
116 ('value', str(member.value))]
117 if isinstance(member, GLibEnumMember):
118 attrs.append(('glib:nick', member.nick))
119 self.write_tag('member', attrs)
121 def _write_class(self, node):
122 attrs = [('name', node.name)]
123 if isinstance(node, Class):
125 if node.parent is not None:
126 attrs.append(('parent', node.parent))
128 tag_name = 'interface'
129 if isinstance(node, (GLibObject, GLibInterface)):
130 attrs.append(('glib:type-name', node.type_name))
131 attrs.append(('glib:get-type', node.get_type))
132 with self.tagcontext(tag_name, attrs):
133 if isinstance(node, Class):
134 for method in node.constructors:
135 self._write_constructor(method)
136 for method in node.methods:
137 self._write_method(method)
138 for prop in node.properties:
139 self._write_property(prop)
141 def _write_boxed(self, boxed):
142 attrs = [('glib:name', boxed.name),
143 ('glib:type-name', boxed.type_name),
144 ('glib:get-type', boxed.get_type)]
146 with self.tagcontext('glib:boxed', attrs):
147 for method in boxed.constructors:
148 self._write_constructor(method)
149 for method in boxed.methods:
150 self._write_method(method)
152 def _write_property(self, prop):
153 attrs = [('name', prop.name),
155 self.write_tag('property', attrs)
157 def _write_callback(self, callback):
158 attrs = [('name', callback.name)]
159 with self.tagcontext('callback', attrs):
160 self._write_return_type(callback.retval)
161 self._write_parameters(callback.parameters)