30
30
private string directory;
31
31
private string gir_namespace;
32
32
private string gir_version;
34
StringBuilder buffer = new StringBuilder();
36
Vala.HashSet<Namespace> unannotated_namespaces = new Vala.HashSet<Namespace>();
37
Vala.HashSet<Namespace> our_namespaces = new Vala.HashSet<Namespace>();
38
41
private TypeSymbol gobject_type;
43
private struct GIRNamespace {
44
public GIRNamespace (string ns, string version) {
45
this.ns = ns; this.version = version;
48
public string version;
49
public bool equal (GIRNamespace g) {
50
return ((ns == g.ns) && (version == g.version));
54
private ArrayList<GIRNamespace?> externals = new ArrayList<GIRNamespace?> ((EqualFunc) GIRNamespace.equal);
56
public void write_includes() {
57
foreach (var i in externals) {
58
write_indent_stream ();
59
stream.printf ("<include name=\"%s\" version=\"%s\"/>\n", i.ns, i.version);
41
65
* Writes the public interface of the specified code context into the
66
97
stream.printf (">\n");
69
write_package (package);
71
context.accept (this);
74
stream.printf ("</repository>\n");
103
stream.puts (buffer.str);
106
foreach (var ns in unannotated_namespaces) {
107
if (!our_namespaces.contains(ns)) {
108
Report.warning (ns.source_reference, "Namespace %s does not have a GIR namespace and version annotation".printf (ns.name));
111
foreach (var ns in our_namespaces) {
112
ns.source_reference.file.gir_namespace = gir_namespace;
113
ns.source_reference.file.gir_version = gir_version;
79
117
private void write_package (string package) {
81
stream.printf ("<package name=\"%s\"/>\n", package);
119
buffer.append_printf ("<package name=\"%s\"/>\n", package);
84
122
private void write_c_includes (Namespace ns) {
124
162
write_c_includes (ns);
127
stream.printf ("<namespace name=\"%s\" version=\"%s\"", gir_namespace, gir_version);
165
buffer.append_printf ("<namespace name=\"%s\" version=\"%s\"", gir_namespace, gir_version);
128
166
string? cprefix = ns.get_cprefix ();
129
167
if (cprefix != null) {
130
stream.printf (" c:prefix=\"%s\"", cprefix);
168
buffer.append_printf (" c:prefix=\"%s\"", cprefix);
132
stream.printf (">\n");
170
buffer.append_printf (">\n");
135
173
write_annotations (ns);
154
193
string gtype_struct_name = cl.name + "Class";
157
stream.printf ("<class name=\"%s\"", cl.name);
196
buffer.append_printf ("<class name=\"%s\"", cl.name);
158
197
write_gtype_attributes (cl);
159
stream.printf (" glib:type-struct=\"%s\"", gtype_struct_name);
160
stream.printf (" parent=\"%s\"", gi_type_name (cl.base_class));
198
buffer.append_printf (" glib:type-struct=\"%s\"", gtype_struct_name);
199
buffer.append_printf (" parent=\"%s\"", gi_type_name (cl.base_class));
161
200
if (cl.is_abstract) {
162
stream.printf (" abstract=\"1\"");
201
buffer.append_printf (" abstract=\"1\"");
164
stream.printf (">\n");
203
buffer.append_printf (">\n");
167
206
// write implemented interfaces
169
208
var object_type = (ObjectType) base_type;
170
209
if (object_type.type_symbol is Interface) {
172
stream.printf ("<implements name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
211
buffer.append_printf ("<implements name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
176
215
write_annotations (cl);
218
buffer.append_printf ("<field name=\"parent_instance\">\n");
221
buffer.append_printf ("<type name=\"%s\" c:type=\"%s\"/>\n", gi_type_name (cl.base_class), cl.base_class.get_cname ());
224
buffer.append_printf("</field>\n");
227
buffer.append_printf ("<field name=\"priv\">\n");
230
buffer.append_printf ("<type name=\"any\" c:type=\"%sPrivate*\"/>\n", cl.get_cname ());
233
buffer.append_printf("</field>\n");
178
235
cl.accept_children (this);
182
stream.printf ("</class>\n");
239
buffer.append_printf ("</class>\n");
185
stream.printf ("<record name=\"%s\"", gtype_struct_name);
242
buffer.append_printf ("<record name=\"%s\"", gtype_struct_name);
186
243
write_ctype_attributes (cl, "Class");
187
stream.printf (" glib:is-gtype-struct-for=\"%s\"", cl.name);
188
stream.printf (">\n");
244
buffer.append_printf (" glib:is-gtype-struct-for=\"%s\"", cl.name);
245
buffer.append_printf (">\n");
249
buffer.append_printf ("<field name=\"parent_class\">\n");
252
buffer.append_printf ("<type name=\"%sClass\" c:type=\"%sClass\"/>\n", gi_type_name (cl.base_class), cl.base_class.get_cname ());
255
buffer.append_printf ("</field>\n");
191
257
foreach (Method m in cl.get_methods ()) {
192
258
if (m.is_abstract || m.is_virtual) {
260
buffer.append_printf("<field name=\"%s\">\n", m.name);
193
262
write_signature(m, "callback", true);
265
buffer.append_printf ("</field>\n");
269
foreach (Signal sig in cl.get_signals ()) {
270
if (sig.default_handler != null) {
272
buffer.append_printf ("<field name=\"%s\">\n", sig.name);
274
write_signature (sig.default_handler, "callback", true);
277
buffer.append_printf ("</field>\n");
199
stream.printf ("</record>\n");
284
buffer.append_printf ("</record>\n");
202
stream.printf ("<record name=\"%s\"", cl.name);
203
stream.printf (">\n");
287
buffer.append_printf ("<record name=\"%s\"", cl.name);
288
buffer.append_printf (">\n");
206
291
write_annotations (cl);
248
333
string gtype_struct_name = iface.name + "Iface";
251
stream.printf ("<interface name=\"%s\"", iface.name);
336
buffer.append_printf ("<interface name=\"%s\"", iface.name);
252
337
write_gtype_attributes (iface);
253
stream.printf (" glib:type-struct=\"%s\"", gtype_struct_name);
254
stream.printf (">\n");
338
buffer.append_printf (" glib:type-struct=\"%s\"", gtype_struct_name);
339
buffer.append_printf (">\n");
257
342
// write prerequisites
258
343
if (iface.get_prerequisites ().size > 0) {
260
stream.printf ("<requires>\n");
345
buffer.append_printf ("<requires>\n");
263
348
foreach (DataType base_type in iface.get_prerequisites ()) {
264
349
var object_type = (ObjectType) base_type;
265
350
if (object_type.type_symbol is Class) {
267
stream.printf ("<object name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
352
buffer.append_printf ("<object name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
268
353
} else if (object_type.type_symbol is Interface) {
270
stream.printf ("<interface name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
355
buffer.append_printf ("<interface name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
272
357
assert_not_reached ();
287
stream.printf ("</interface>\n");
372
buffer.append_printf ("</interface>\n");
290
stream.printf ("<record name=\"%s\"", gtype_struct_name);
375
buffer.append_printf ("<record name=\"%s\"", gtype_struct_name);
291
376
write_ctype_attributes (iface, "Iface");
292
stream.printf (" glib:is-gtype-struct-for=\"%s\"", iface.name);
293
stream.printf (">\n");
377
buffer.append_printf (" glib:is-gtype-struct-for=\"%s\"", iface.name);
378
buffer.append_printf (">\n");
296
381
foreach (Method m in iface.get_methods ()) {
329
stream.printf ("</enumeration>\n");
414
buffer.append_printf ("</enumeration>\n");
332
417
private int enum_value;
334
419
public override void visit_enum_value (EnumValue ev) {
336
stream.printf ("<member name=\"%s\" c:identifier=\"%s\"", ev.name.down (), ev.get_cname ());
421
buffer.append_printf ("<member name=\"%s\" c:identifier=\"%s\"", ev.name.down (), ev.get_cname ());
337
422
if (ev.value != null) {
338
423
string value = literal_expression_to_value_string (ev.value);
339
stream.printf (" value=\"%s\"", value);
424
buffer.append_printf (" value=\"%s\"", value);
341
stream.printf (" value=\"%d\"", enum_value++);
426
buffer.append_printf (" value=\"%d\"", enum_value++);
343
stream.printf ("/>\n");
428
buffer.append_printf ("/>\n");
346
431
public override void visit_error_domain (ErrorDomain edomain) {
356
stream.printf ("<errordomain name=\"%s\"", edomain.name);
357
stream.printf (" get-quark=\"%squark\"", edomain.get_lower_case_cprefix ());
358
stream.printf (" codes=\"%s\"", edomain.name);
359
stream.printf (">\n");
441
buffer.append_printf ("<errordomain name=\"%s\"", edomain.name);
442
buffer.append_printf (" get-quark=\"%squark\"", edomain.get_lower_case_cprefix ());
443
buffer.append_printf (" codes=\"%s\"", edomain.name);
444
buffer.append_printf (">\n");
361
446
write_annotations (edomain);
363
stream.printf ("</errordomain>\n");
448
buffer.append_printf ("</errordomain>\n");
366
stream.printf ("<enumeration name=\"%s\"", edomain.name);
451
buffer.append_printf ("<enumeration name=\"%s\"", edomain.name);
367
452
write_ctype_attributes (edomain);
368
stream.printf (">\n");
453
buffer.append_printf (">\n");
376
stream.printf ("</enumeration>\n");
461
buffer.append_printf ("</enumeration>\n");
379
464
public override void visit_error_code (ErrorCode ecode) {
381
stream.printf ("<member name=\"%s\" c:identifier=\"%s\"", ecode.name.down (), ecode.get_cname ());
466
buffer.append_printf ("<member name=\"%s\" c:identifier=\"%s\"", ecode.name.down (), ecode.get_cname ());
382
467
if (ecode.value != null) {
383
468
string value = literal_expression_to_value_string (ecode.value);
384
stream.printf (" value=\"%s\"", value);
469
buffer.append_printf (" value=\"%s\"", value);
386
stream.printf (" value=\"%d\"", enum_value++);
471
buffer.append_printf (" value=\"%d\"", enum_value++);
388
stream.printf ("/>\n");
473
buffer.append_printf ("/>\n");
391
476
public override void visit_constant (Constant c) {
402
487
string value = literal_expression_to_value_string (initializer);
405
stream.printf ("<constant name=\"%s\" c:identifier=\"%s\"", c.name, c.get_cname ());
406
stream.printf (" value=\"%s\"", value);
407
stream.printf (">\n");
490
buffer.append_printf ("<constant name=\"%s\" c:identifier=\"%s\"", c.name, c.get_cname ());
491
buffer.append_printf (" value=\"%s\"", value);
492
buffer.append_printf (">\n");
410
495
write_type (initializer.value_type);
414
stream.printf ("</constant>\n");
499
buffer.append_printf ("</constant>\n");
417
502
public override void visit_field (Field f) {
457
private void write_params_and_return (List<FormalParameter> params, DataType? return_type, bool return_array_length, bool constructor = false, DataType? instance_type = null) {
542
private void write_params_and_return (List<FormalParameter> params, DataType? return_type, bool return_array_length, bool constructor = false, DataType? instance_type = null, bool user_data = false) {
458
543
int last_index = 0;
459
544
if (params.size != 0 || instance_type != null || (return_type is ArrayType && return_array_length) || (return_type is DelegateType)) {
461
stream.printf ("<parameters>\n");
546
buffer.append_printf ("<parameters>\n");
475
560
last_index = index - 1;
476
561
write_implicit_params (return_type, ref index, return_array_length, "result", ParameterDirection.OUT);
565
buffer.append_printf ("<parameter name=\"user_data\" transfer-ownership=\"none\" closure=\"%d\">\n", index);
568
buffer.append_printf ("<type name=\"any\" c:type=\"void*\"/>\n");
571
buffer.append_printf ("</parameter>\n");
480
stream.printf ("</parameters>\n");
576
buffer.append_printf ("</parameters>\n");
483
579
if (return_type != null) {
498
stream.printf ("<callback name=\"%s\"", cb.name);
499
stream.printf (" c:type=\"%s\"", cb.get_cname ());
594
buffer.append_printf ("<callback name=\"%s\"", cb.name);
595
buffer.append_printf (" c:type=\"%s\"", cb.get_cname ());
500
596
if (cb.tree_can_fail) {
501
stream.printf (" throws=\"1\"");
597
buffer.append_printf (" throws=\"1\"");
503
stream.printf (">\n");
599
buffer.append_printf (">\n");
506
602
write_annotations (cb);
508
write_params_and_return (cb.get_parameters (), cb.return_type, !cb.no_array_length);
604
write_params_and_return (cb.get_parameters (), cb.return_type, !cb.no_array_length, false, null, cb.has_target);
512
stream.printf ("</callback>\n");
608
buffer.append_printf ("</callback>\n");
515
611
public override void visit_method (Method m) {
552
648
private void do_write_signature (Method m, string tag_name, bool instance, string name, string cname, List<Vala.FormalParameter> params, DataType return_type, bool can_fail) {
554
stream.printf ("<%s name=\"%s\"", tag_name, name);
650
buffer.append_printf ("<%s name=\"%s\"", tag_name, name);
555
651
if (tag_name == "virtual-method") {
556
stream.printf (" invoker=\"%s\"", name);
652
buffer.append_printf (" invoker=\"%s\"", name);
557
653
} else if (tag_name == "callback") {
558
stream.printf (" c:type=\"%s\"", cname);
654
/* this is only used for vfuncs */
655
buffer.append_printf (" c:type=\"%s\"", name);
560
stream.printf (" c:identifier=\"%s\"", cname);
657
buffer.append_printf (" c:identifier=\"%s\"", cname);
563
stream.printf (" throws=\"1\"");
660
buffer.append_printf (" throws=\"1\"");
565
stream.printf (">\n");
662
buffer.append_printf (">\n");
568
665
write_annotations (m);
593
690
if (m == ((Class)m.parent_symbol).default_construction_method) {
594
stream.printf ("<constructor name=\"new\" c:identifier=\"%s\"", m.get_cname ());
691
buffer.append_printf ("<constructor name=\"new\" c:identifier=\"%s\"", m.get_cname ());
596
stream.printf ("<constructor name=\"%s\" c:identifier=\"%s\"", m.name, m.get_cname ());
693
buffer.append_printf ("<constructor name=\"%s\" c:identifier=\"%s\"", m.name, m.get_cname ());
599
696
if (m.tree_can_fail) {
600
stream.printf (" throws=\"1\"");
697
buffer.append_printf (" throws=\"1\"");
602
stream.printf (">\n");
699
buffer.append_printf (">\n");
605
702
write_annotations (m);
622
stream.printf ("<property name=\"%s\"", prop.get_canonical_name ());
719
buffer.append_printf ("<property name=\"%s\"", prop.get_canonical_name ());
623
720
if (prop.get_accessor == null) {
624
stream.printf (" readable=\"0\"");
721
buffer.append_printf (" readable=\"0\"");
626
723
if (prop.set_accessor != null) {
627
stream.printf (" writable=\"1\"");
724
buffer.append_printf (" writable=\"1\"");
628
725
if (prop.set_accessor.construction) {
629
726
if (!prop.set_accessor.writable) {
630
stream.printf (" construct-only=\"1\"");
727
buffer.append_printf (" construct-only=\"1\"");
632
stream.printf (" construct=\"1\"");
729
buffer.append_printf (" construct=\"1\"");
636
stream.printf (">\n");
733
buffer.append_printf (">\n");
639
736
write_annotations (prop);
664
stream.printf ("</glib:signal>\n");
761
buffer.append_printf ("</glib:signal>\n");
667
764
private void write_indent () {
670
767
for (i = 0; i < indent; i++) {
768
buffer.append_c ('\t');
772
private void write_indent_stream () {
775
for (i = 0; i < indent; i++) {
671
776
stream.putc ('\t');
675
781
private void write_param_or_return (DataType type, string tag, ref int index, bool has_array_length, string? name = null, ParameterDirection direction = ParameterDirection.IN, bool constructor = false) {
677
stream.printf ("<%s", tag);
783
buffer.append_printf ("<%s", tag);
678
784
if (name != null) {
679
stream.printf (" name=\"%s\"", name);
785
buffer.append_printf (" name=\"%s\"", name);
681
787
if (direction == ParameterDirection.REF) {
682
stream.printf (" direction=\"inout\"");
788
buffer.append_printf (" direction=\"inout\"");
683
789
} else if (direction == ParameterDirection.OUT) {
684
stream.printf (" direction=\"out\"");
790
buffer.append_printf (" direction=\"out\"");
687
793
Delegate delegate_type = type.data_type as Delegate;
689
795
if ((type.value_owned && delegate_type == null) || constructor) {
690
stream.printf (" transfer-ownership=\"full\"");
796
buffer.append_printf (" transfer-ownership=\"full\"");
692
stream.printf (" transfer-ownership=\"none\"");
798
buffer.append_printf (" transfer-ownership=\"none\"");
694
800
if (type.nullable) {
695
stream.printf (" allow-none=\"1\"");
801
buffer.append_printf (" allow-none=\"1\"");
698
804
if (delegate_type != null && delegate_type.has_target) {
699
stream.printf (" closure=\"%i\"", index + 1);
805
buffer.append_printf (" closure=\"%i\"", index + 1);
700
806
if (type.value_owned) {
701
stream.printf (" destroy=\"%i\"", index + 2);
807
buffer.append_printf (" destroy=\"%i\"", index + 2);
705
stream.printf (">\n");
811
buffer.append_printf (">\n");
708
814
write_type (type, has_array_length ? index : -1);
712
stream.printf ("</%s>\n", tag);
818
buffer.append_printf ("</%s>\n", tag);
716
822
private void write_ctype_attributes (TypeSymbol symbol, string suffix = "") {
717
stream.printf (" c:type=\"%s%s\"", symbol.get_cname (), suffix);
823
buffer.append_printf (" c:type=\"%s%s\"", symbol.get_cname (), suffix);
720
826
private void write_gtype_attributes (TypeSymbol symbol) {
721
827
write_ctype_attributes(symbol);
722
stream.printf (" glib:type-name=\"%s\"", symbol.get_cname ());
723
stream.printf (" glib:get-type=\"%sget_type\"", symbol.get_lower_case_cprefix ());
828
buffer.append_printf (" glib:type-name=\"%s\"", symbol.get_cname ());
829
buffer.append_printf (" glib:get-type=\"%sget_type\"", symbol.get_lower_case_cprefix ());
726
832
private void write_type (DataType type, int index = -1) {
728
834
var array_type = (ArrayType) type;
731
stream.printf ("<array");
837
buffer.append_printf ("<array");
732
838
if (array_type.fixed_length) {
733
stream.printf (" fixed-length\"%i\"", array_type.length);
839
buffer.append_printf (" fixed-length\"%i\"", array_type.length);
734
840
} else if (index != -1) {
735
stream.printf (" length=\"%i\"", index + 1);
841
buffer.append_printf (" length=\"%i\"", index + 1);
737
stream.printf (">\n");
843
buffer.append_printf (">\n");
740
846
write_type (array_type.element_type);
744
stream.printf ("</array>\n");
850
buffer.append_printf ("</array>\n");
745
851
} else if (type is VoidType) {
747
stream.printf ("<type name=\"none\"/>\n");
853
buffer.append_printf ("<type name=\"none\"/>\n");
748
854
} else if (type is PointerType) {
750
stream.printf ("<type name=\"any\" c:type=\"%s\"/>\n", type.get_cname ());
856
buffer.append_printf ("<type name=\"any\" c:type=\"%s\"/>\n", type.get_cname ());
751
857
} else if (type.data_type != null) {
753
stream.printf ("<type name=\"%s\" c:type=\"%s\"", gi_type_name (type.data_type), type.get_cname ());
859
buffer.append_printf ("<type name=\"%s\" c:type=\"%s\"", gi_type_name (type.data_type), type.get_cname ());
755
861
List<DataType> type_arguments = type.get_type_arguments ();
756
862
if (type_arguments.size == 0) {
757
stream.printf ("/>\n");
863
buffer.append_printf ("/>\n");
759
stream.printf (">\n");
865
buffer.append_printf (">\n");
762
868
foreach (DataType type_argument in type_arguments) {
768
stream.printf ("</type>\n");
874
buffer.append_printf ("</type>\n");
770
876
} else if (type is DelegateType) {
771
877
var deleg_type = (DelegateType) type;
773
stream.printf ("<type name=\"%s\" c:type=\"%s\"/>\n", gi_type_name (deleg_type.delegate_symbol), type.get_cname ());
879
buffer.append_printf ("<type name=\"%s\" c:type=\"%s\"/>\n", gi_type_name (deleg_type.delegate_symbol), type.get_cname ());
776
stream.printf ("<type name=\"%s\"/>\n", type.to_string ());
882
buffer.append_printf ("<type name=\"%s\"/>\n", type.to_string ());
797
903
private string gi_type_name (TypeSymbol type_symbol) {
904
Symbol parent = type_symbol.parent_symbol;
905
if (parent is Namespace) {
906
Namespace ns = parent as Namespace;
907
if (ns.name != null) {
908
if (type_symbol.source_reference.file.gir_namespace != null) {
909
GIRNamespace external = GIRNamespace (type_symbol.source_reference.file.gir_namespace, type_symbol.source_reference.file.gir_version);
910
if (!externals.contains (external)) {
911
externals.add (external);
913
return "%s.%s".printf (type_symbol.source_reference.file.gir_namespace, type_symbol.name);
915
unannotated_namespaces.add(ns);
798
920
return vala_to_gi_type_name (type_symbol.get_full_name());