179
189
def _write_constructor(self, method):
180
190
self._write_function(method, tag_name='constructor')
182
def _write_return_type(self, return_):
192
def _write_return_type(self, return_, parent=None):
186
assert return_.transfer is not None, return_
189
attrs.append(('transfer-ownership', return_.transfer))
191
attrs.append(('doc', return_.doc))
198
attrs.append(('transfer-ownership', return_.transfer))
192
199
with self.tagcontext('return-value', attrs):
193
self._write_type(return_.type)
200
self._write_generic(return_)
201
self._write_type(return_.type, function=parent)
195
def _write_parameters(self, parameters):
203
def _write_parameters(self, parent, parameters):
196
204
if not parameters:
198
206
with self.tagcontext('parameters'):
199
207
for parameter in parameters:
200
self._write_parameter(parameter)
202
def _write_parameter(self, parameter):
203
assert parameter.transfer is not None, parameter
208
self._write_parameter(parent, parameter)
210
def _write_parameter(self, parent, parameter):
206
if parameter.name is not None:
207
attrs.append(('name', parameter.name))
208
if parameter.direction != 'in':
212
if parameter.argname is not None:
213
attrs.append(('name', parameter.argname))
214
if (parameter.direction is not None) and (parameter.direction != 'in'):
209
215
attrs.append(('direction', parameter.direction))
210
216
attrs.append(('caller-allocates',
211
217
'1' if parameter.caller_allocates else '0'))
212
attrs.append(('transfer-ownership',
218
if parameter.transfer:
219
attrs.append(('transfer-ownership',
214
221
if parameter.allow_none:
215
222
attrs.append(('allow-none', '1'))
216
223
if parameter.scope:
217
224
attrs.append(('scope', parameter.scope))
218
if parameter.closure_index >= 0:
219
attrs.append(('closure', '%d' % parameter.closure_index))
220
if parameter.destroy_index >= 0:
221
attrs.append(('destroy', '%d' % parameter.destroy_index))
223
attrs.append(('doc', parameter.doc))
225
if parameter.closure_name is not None:
226
idx = parent.get_parameter_index(parameter.closure_name)
227
attrs.append(('closure', '%d' % (idx, )))
228
if parameter.destroy_name is not None:
229
idx = parent.get_parameter_index(parameter.destroy_name)
230
attrs.append(('destroy', '%d' % (idx, )))
224
231
with self.tagcontext('parameter', attrs):
225
self._write_type(parameter.type)
227
def _type_to_string(self, ntype):
228
if isinstance(ntype, basestring):
232
def _write_type(self, ntype, relation=None):
233
if isinstance(ntype, basestring):
232
self._write_generic(parameter)
233
self._write_type(parameter.type, function=parent)
235
def _type_to_name(self, typeval):
236
if not typeval.resolved:
237
raise AssertionError("Caught unresolved type %r (ctype=%r)" % (typeval, typeval.ctype))
238
assert typeval.target_giname is not None
239
prefix = self._namespace.name + '.'
240
if typeval.target_giname.startswith(prefix):
241
return typeval.target_giname[len(prefix):]
242
return typeval.target_giname
244
def _write_type_ref(self, ntype):
245
""" Like _write_type, but only writes the type name rather than the full details """
246
assert isinstance(ntype, ast.Type), ntype
249
attrs.append(('c:type', ntype.ctype))
250
if isinstance(ntype, ast.Array):
251
if ntype.array_type != ast.Array.C:
252
attrs.insert(0, ('name', ntype.array_type))
253
elif isinstance(ntype, ast.List):
255
attrs.insert(0, ('name', ntype.name))
256
elif isinstance(ntype, ast.Map):
257
attrs.insert(0, ('name', 'GLib.HashTable'))
237
typename = ntype.name
238
type_cname = ntype.ctype
239
if isinstance(ntype, Varargs):
259
if ntype.target_giname:
260
attrs.insert(0, ('name', self._type_to_name(ntype)))
261
elif ntype.target_fundamental:
262
attrs.insert(0, ('name', ntype.target_fundamental))
264
self.write_tag('type', attrs)
266
def _write_type(self, ntype, relation=None, function=None):
267
assert isinstance(ntype, ast.Type), ntype
270
attrs.append(('c:type', ntype.ctype))
271
if isinstance(ntype, ast.Varargs):
240
272
with self.tagcontext('varargs', []):
243
if isinstance(ntype, Array):
274
elif isinstance(ntype, ast.Array):
275
if ntype.array_type != ast.Array.C:
276
attrs.insert(0, ('name', ntype.array_type))
245
277
if not ntype.zeroterminated:
246
attrs.append(('zero-terminated', '0'))
247
if ntype.length_param_index >= 0:
248
attrs.append(('length', '%d' % (ntype.length_param_index, )))
249
if ntype.name in ['GLib.Array', 'GLib.PtrArray', 'GLib.ByteArray']:
250
attrs.append(('name', ntype.name))
251
attrs.append(('c:type', ntype.ctype))
278
attrs.insert(0, ('zero-terminated', '0'))
252
279
if ntype.size is not None:
253
attrs.append(('fixed-size', ntype.size))
280
attrs.append(('fixed-size', '%d' % (ntype.size, )))
281
if ntype.length_param_name is not None:
283
attrs.insert(0, ('length', '%d'
284
% (function.get_parameter_index(ntype.length_param_name, ))))
255
286
with self.tagcontext('array', attrs):
256
if ntype.element_type is not None:
257
self._write_type(ntype.element_type)
259
attrs = [('name', self._type_to_string(ntype))]
260
# FIXME: figure out if type references a basic type
261
# or a boxed/class/interface etc. and skip
262
# writing the ctype if the latter.
263
if type_cname is not None:
264
attrs.append(('c:type', type_cname))
265
if isinstance(ntype, List) and ntype.element_type:
287
self._write_type(ntype.element_type)
288
elif isinstance(ntype, ast.List):
290
attrs.insert(0, ('name', ntype.name))
266
291
with self.tagcontext('type', attrs):
267
292
self._write_type(ntype.element_type)
269
if isinstance(ntype, Map) and ntype.key_type:
293
elif isinstance(ntype, ast.Map):
294
attrs.insert(0, ('name', 'GLib.HashTable'))
270
295
with self.tagcontext('type', attrs):
271
296
self._write_type(ntype.key_type)
272
297
self._write_type(ntype.value_type)
274
# Not a special type, just write it out
275
self.write_tag('type', attrs)
299
# REWRITEFIXME - enable this for 1.2
300
if ntype.target_giname:
301
attrs.insert(0, ('name', self._type_to_name(ntype)))
302
elif ntype.target_fundamental:
303
# attrs = [('fundamental', ntype.target_fundamental)]
304
attrs.insert(0, ('name', ntype.target_fundamental))
305
elif ntype.target_foreign:
306
attrs.insert(0, ('foreign', '1'))
307
self.write_tag('type', attrs)
309
def _append_registered(self, node, attrs):
310
assert isinstance(node, ast.Registered)
312
attrs.extend([('glib:type-name', node.gtype_name),
313
('glib:get-type', node.get_type)])
277
315
def _write_enum(self, enum):
278
316
attrs = [('name', enum.name)]
280
attrs.append(('doc', enum.doc))
281
317
self._append_version(enum, attrs)
282
self._append_deprecated(enum, attrs)
283
if isinstance(enum, GLibEnum):
284
attrs.extend([('glib:type-name', enum.type_name),
285
('glib:get-type', enum.get_type),
286
('c:type', enum.ctype)])
288
attrs.append(('c:type', enum.symbol))
289
if hasattr(enum, 'error_quark') and enum.error_quark:
318
self._append_node_generic(enum, attrs)
319
self._append_registered(enum, attrs)
320
attrs.append(('c:type', enum.ctype))
290
322
attrs.append(('glib:error-quark', enum.error_quark))
292
324
with self.tagcontext('enumeration', attrs):
293
self._write_attributes(enum)
325
self._write_generic(enum)
294
326
for member in enum.members:
295
327
self._write_member(member)
297
329
def _write_bitfield(self, bitfield):
298
330
attrs = [('name', bitfield.name)]
300
attrs.append(('doc', bitfield.doc))
301
331
self._append_version(bitfield, attrs)
302
self._append_deprecated(bitfield, attrs)
303
if isinstance(bitfield, GLibFlags):
304
attrs.extend([('glib:type-name', bitfield.type_name),
305
('glib:get-type', bitfield.get_type),
306
('c:type', bitfield.ctype)])
308
attrs.append(('c:type', bitfield.symbol))
332
self._append_node_generic(bitfield, attrs)
333
self._append_registered(bitfield, attrs)
334
attrs.append(('c:type', bitfield.ctype))
309
335
with self.tagcontext('bitfield', attrs):
310
self._write_attributes(bitfield)
336
self._write_generic(bitfield)
311
337
for member in bitfield.members:
312
338
self._write_member(member)
314
340
def _write_member(self, member):
317
341
attrs = [('name', member.name),
318
342
('value', str(member.value)),
319
343
('c:identifier', member.symbol)]
320
if isinstance(member, GLibEnumMember):
344
if member.nick is not None:
321
345
attrs.append(('glib:nick', member.nick))
322
346
self.write_tag('member', attrs)
324
348
def _write_constant(self, constant):
325
attrs = [('name', constant.name),
326
('value', str(constant.value))]
349
attrs = [('name', constant.name), ('value', constant.value)]
327
350
with self.tagcontext('constant', attrs):
328
self._write_type(constant.type)
351
self._write_type(constant.value_type)
330
353
def _write_class(self, node):
331
354
attrs = [('name', node.name),
355
('c:symbol-prefix', node.c_symbol_prefix),
332
356
('c:type', node.ctype)]
334
attrs.append(('doc', node.doc))
335
357
self._append_version(node, attrs)
336
self._append_deprecated(node, attrs)
337
if isinstance(node, Class):
358
self._append_node_generic(node, attrs)
359
if isinstance(node, ast.Class):
338
360
tag_name = 'class'
339
361
if node.parent is not None:
340
attrs.append(('parent', node.parent))
362
attrs.append(('parent',
363
self._type_to_name(node.parent)))
341
364
if node.is_abstract:
342
365
attrs.append(('abstract', '1'))
367
assert isinstance(node, ast.Interface)
344
368
tag_name = 'interface'
345
if isinstance(node, (GLibObject, GLibInterface)):
346
attrs.append(('glib:type-name', node.type_name))
348
attrs.append(('glib:get-type', node.get_type))
349
if node.glib_type_struct:
350
attrs.append(('glib:type-struct', node.glib_type_struct.name))
369
attrs.append(('glib:type-name', node.gtype_name))
370
if node.get_type is not None:
371
attrs.append(('glib:get-type', node.get_type))
372
if node.glib_type_struct is not None:
373
attrs.append(('glib:type-struct',
374
self._type_to_name(node.glib_type_struct)))
375
if isinstance(node, ast.Class):
377
attrs.append(('glib:fundamental', '1'))
379
attrs.append(('glib:ref-func', node.ref_func))
381
attrs.append(('glib:unref-func', node.unref_func))
382
if node.set_value_func:
383
attrs.append(('glib:set-value-func', node.set_value_func))
384
if node.get_value_func:
385
attrs.append(('glib:get-value-func', node.get_value_func))
351
386
with self.tagcontext(tag_name, attrs):
352
self._write_attributes(node)
353
if isinstance(node, GLibObject):
354
for iface in node.interfaces:
355
self.write_tag('implements', [('name', iface)])
356
if isinstance(node, Interface):
357
for iface in node.prerequisites:
358
self.write_tag('prerequisite', [('name', iface)])
359
if isinstance(node, Class):
360
for method in node.constructors:
387
self._write_generic(node)
388
if isinstance(node, ast.Class):
389
for iface in sorted(node.interfaces):
390
self.write_tag('implements',
391
[('name', self._type_to_name(iface))])
392
if isinstance(node, ast.Interface):
393
for iface in sorted(node.prerequisites):
394
self.write_tag('prerequisite',
395
[('name', self._type_to_name(iface))])
396
if isinstance(node, ast.Class):
397
for method in sorted(node.constructors):
361
398
self._write_constructor(method)
362
for method in node.static_methods:
399
if isinstance(node, (ast.Class, ast.Interface)):
400
for method in sorted(node.static_methods):
363
401
self._write_static_method(method)
364
for vfunc in node.virtual_methods:
402
for vfunc in sorted(node.virtual_methods):
365
403
self._write_vfunc(vfunc)
366
for method in node.methods:
404
for method in sorted(node.methods):
367
405
self._write_method(method)
368
for prop in node.properties:
406
for prop in sorted(node.properties):
369
407
self._write_property(prop)
370
408
for field in node.fields:
371
409
self._write_field(field)
372
for signal in node.signals:
410
for signal in sorted(node.signals):
373
411
self._write_signal(signal)
375
413
def _write_boxed(self, boxed):
376
attrs = [('c:type', boxed.ctype),
377
('glib:name', boxed.name)]
379
attrs.append(('doc', boxed.doc))
380
attrs.extend(self._boxed_attrs(boxed))
414
attrs = [('glib:name', boxed.name)]
415
if boxed.c_symbol_prefix is not None:
416
attrs.append(('c:symbol-prefix', boxed.c_symbol_prefix))
417
self._append_registered(boxed, attrs)
381
418
with self.tagcontext('glib:boxed', attrs):
382
self._write_attributes(boxed)
383
for method in boxed.constructors:
419
self._write_generic(boxed)
420
for method in sorted(boxed.constructors):
384
421
self._write_constructor(method)
385
for method in boxed.methods:
422
for method in sorted(boxed.methods):
386
423
self._write_method(method)
424
for method in sorted(boxed.static_methods):
425
self._write_static_method(method)
388
427
def _write_property(self, prop):
391
428
attrs = [('name', prop.name)]
392
429
self._append_version(prop, attrs)
393
self._append_deprecated(prop, attrs)
430
self._append_node_generic(prop, attrs)
394
431
# Properties are assumed to be readable (see also generate.c)
395
432
if not prop.readable:
396
433
attrs.append(('readable', '0'))
413
450
self._write_callable(vf, 'virtual-method', attrs)
415
452
def _write_callback(self, callback):
416
attrs = [('c:type', callback.ctype)]
454
if callback.namespace:
455
attrs.append(('c:type', callback.ctype or callback.c_name))
417
456
self._write_callable(callback, 'callback', attrs)
419
def _boxed_attrs(self, boxed):
420
return [('glib:type-name', boxed.type_name),
421
('glib:get-type', boxed.get_type)]
423
458
def _write_record(self, record, extra_attrs=[]):
424
459
is_gtype_struct = False
425
460
attrs = list(extra_attrs)
426
461
if record.name is not None:
427
462
attrs.append(('name', record.name))
428
if record.symbol is not None: # the record might be anonymous
429
attrs.append(('c:type', record.symbol))
463
if record.ctype is not None: # the record might be anonymous
464
attrs.append(('c:type', record.ctype))
430
465
if record.disguised:
431
466
attrs.append(('disguised', '1'))
432
467
if record.foreign:
433
468
attrs.append(('foreign', '1'))
434
if isinstance(record, GLibRecord):
435
if record.is_gtype_struct_for:
436
is_gtype_struct = True
437
attrs.append(('glib:is-gtype-struct-for',
438
record.is_gtype_struct_for))
440
attrs.append(('doc', record.doc))
469
if record.is_gtype_struct_for is not None:
470
is_gtype_struct = True
471
attrs.append(('glib:is-gtype-struct-for',
472
self._type_to_name(record.is_gtype_struct_for)))
441
473
self._append_version(record, attrs)
442
self._append_deprecated(record, attrs)
443
if isinstance(record, GLibBoxed):
444
attrs.extend(self._boxed_attrs(record))
474
self._append_node_generic(record, attrs)
475
self._append_registered(record, attrs)
476
if record.c_symbol_prefix:
477
attrs.append(('c:symbol-prefix', record.c_symbol_prefix))
445
478
with self.tagcontext('record', attrs):
446
self._write_attributes(record)
479
self._write_generic(record)
447
480
if record.fields:
448
481
for field in record.fields:
449
482
self._write_field(field, is_gtype_struct)
450
for method in record.constructors:
483
for method in sorted(record.constructors):
451
484
self._write_constructor(method)
452
for method in record.methods:
485
for method in sorted(record.methods):
453
486
self._write_method(method)
487
for method in sorted(record.static_methods):
488
self._write_static_method(method)
455
490
def _write_union(self, union):
457
492
if union.name is not None:
458
493
attrs.append(('name', union.name))
459
if union.symbol is not None: # the union might be anonymous
460
attrs.append(('c:type', union.symbol))
462
attrs.append(('doc', union.doc))
494
if union.ctype is not None: # the union might be anonymous
495
attrs.append(('c:type', union.ctype))
463
496
self._append_version(union, attrs)
464
self._append_deprecated(union, attrs)
465
if isinstance(union, GLibBoxed):
466
attrs.extend(self._boxed_attrs(union))
497
self._append_node_generic(union, attrs)
498
self._append_registered(union, attrs)
499
if union.c_symbol_prefix:
500
attrs.append(('c:symbol-prefix', union.c_symbol_prefix))
467
501
with self.tagcontext('union', attrs):
468
self._write_attributes(union)
502
self._write_generic(union)
470
504
for field in union.fields:
471
505
self._write_field(field)
472
for method in union.constructors:
506
for method in sorted(union.constructors):
473
507
self._write_constructor(method)
474
for method in union.methods:
508
for method in sorted(union.methods):
475
509
self._write_method(method)
510
for method in sorted(union.static_methods):
511
self._write_static_method(method)
477
513
def _write_field(self, field, is_gtype_struct=False):
478
if isinstance(field, Function):
479
self._write_method(field)
482
if isinstance(field, Callback):
483
attrs = [('name', field.name)]
484
with self.tagcontext('field', attrs):
485
self._write_attributes(field)
487
self._write_callback(field)
489
attrs = [('name', 'any'), ('c:type', 'pointer')]
490
self.write_tag('type', attrs)
491
elif isinstance(field, Struct):
492
self._write_record(field)
493
elif isinstance(field, Union):
494
self._write_union(field)
514
if field.anonymous_node:
515
if isinstance(field.anonymous_node, ast.Callback):
516
attrs = [('name', field.name)]
517
self._append_node_generic(field, attrs)
518
with self.tagcontext('field', attrs):
519
self._write_callback(field.anonymous_node)
520
elif isinstance(field.anonymous_node, ast.Record):
521
self._write_record(field.anonymous_node)
522
elif isinstance(field.anonymous_node, ast.Union):
523
self._write_union(field.anonymous_node)
525
raise AssertionError("Unknown field anonymous: %r" \
526
% (field.anonymous_node, ))
496
528
attrs = [('name', field.name)]
529
self._append_node_generic(field, attrs)
497
530
# Fields are assumed to be read-only
498
531
# (see also girparser.c and generate.c)
499
532
if not field.readable: