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 .ast import (Callback, Class, Enum, Function, Interface, Sequence)
23 from .glibast import (GLibBoxed, GLibEnum, GLibEnumMember,
24 GLibFlags, GLibObject, GLibInterface)
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 attrs = [('c:identifer', return_.type.name)]
79 with self.tagcontext('return-value', attrs):
80 if isinstance(return_.type, Sequence):
81 self._write_sequence(return_.type)
83 self._write_type(return_.type)
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('parameter', attrs):
99 self._write_type(parameter.type)
101 def _write_type(self, type):
102 self.write_tag('type', [('name', type.name)])
104 def _write_sequence(self, sequence):
105 attrs = [('c:owner', sequence.cowner)]
106 with self.tagcontext('sequence', attrs):
107 attrs = [('c:identifier', sequence.element_type)]
108 self.write_tag('element-type', attrs)
110 def _write_enum(self, enum):
111 attrs = [('name', enum.name)]
112 tag_name = 'enumeration'
113 if isinstance(enum, GLibEnum):
114 attrs.extend([('glib:type-name', enum.type_name),
115 ('glib:get-type', enum.get_type)])
116 if isinstance(enum, GLibFlags):
117 tag_name = 'bitfield'
119 with self.tagcontext(tag_name, attrs):
120 for member in enum.members:
121 self._write_member(member)
123 def _write_member(self, member):
124 attrs = [('name', member.name),
125 ('value', str(member.value))]
126 if isinstance(member, GLibEnumMember):
127 attrs.append(('glib:nick', member.nick))
128 self.write_tag('member', attrs)
130 def _write_class(self, node):
131 attrs = [('name', node.name)]
132 if isinstance(node, Class):
134 if node.parent is not None:
135 attrs.append(('parent', node.parent))
137 tag_name = 'interface'
138 if isinstance(node, (GLibObject, GLibInterface)):
139 attrs.append(('glib:type-name', node.type_name))
140 attrs.append(('glib:get-type', node.get_type))
141 with self.tagcontext(tag_name, attrs):
142 if isinstance(node, Class):
143 for method in node.constructors:
144 self._write_constructor(method)
145 for method in node.methods:
146 self._write_method(method)
147 for prop in node.properties:
148 self._write_property(prop)
150 def _write_boxed(self, boxed):
151 attrs = [('glib:name', boxed.name),
152 ('glib:type-name', boxed.type_name),
153 ('glib:get-type', boxed.get_type)]
155 with self.tagcontext('glib:boxed', attrs):
156 for method in boxed.constructors:
157 self._write_constructor(method)
158 for method in boxed.methods:
159 self._write_method(method)
161 def _write_property(self, prop):
162 attrs = [('name', prop.name)]
163 with self.tagcontext('property', attrs):
164 self._write_type(prop.type)
166 def _write_callback(self, callback):
167 attrs = [('name', callback.name)]
168 with self.tagcontext('callback', attrs):
169 self._write_return_type(callback.retval)
170 self._write_parameters(callback.parameters)