~ubuntu-branches/ubuntu/maverick/vala/maverick

« back to all changes in this revision

Viewing changes to codegen/valagirwriter.vala

  • Committer: Bazaar Package Importer
  • Author(s): Julien Lavergne
  • Date: 2010-02-13 17:59:22 UTC
  • mfrom: (7.3.7 sid)
  • Revision ID: james.westby@ubuntu.com-20100213175922-n8bq2xv2q1hihhqb
Tags: 0.7.10-1ubuntu1
* Sync with Debian unstable.
* Remaining changes :
 - debian/rules: Don't make unit test failures fatal to fix FTBFS. It was
   needed if vala need to enter main but it's not the case for now. 
   (See #374151)

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
        private string directory;
31
31
        private string gir_namespace;
32
32
        private string gir_version;
33
 
        
 
33
 
 
34
        StringBuilder buffer = new StringBuilder();
34
35
        FileStream stream;
35
 
        
 
36
        Vala.HashSet<Namespace> unannotated_namespaces = new Vala.HashSet<Namespace>();
 
37
        Vala.HashSet<Namespace> our_namespaces = new Vala.HashSet<Namespace>();
 
38
 
36
39
        int indent;
37
40
 
38
41
        private TypeSymbol gobject_type;
39
42
 
 
43
        private struct GIRNamespace {
 
44
                public GIRNamespace (string ns, string version) {
 
45
                        this.ns = ns; this.version = version;
 
46
                }
 
47
                public string ns;
 
48
                public string version;
 
49
                public bool equal (GIRNamespace g) {
 
50
                        return ((ns == g.ns) && (version == g.version));
 
51
                }
 
52
        }
 
53
 
 
54
        private ArrayList<GIRNamespace?> externals = new ArrayList<GIRNamespace?> ((EqualFunc) GIRNamespace.equal);
 
55
 
 
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);
 
60
                }
 
61
        }
 
62
 
 
63
 
40
64
        /**
41
65
         * Writes the public interface of the specified code context into the
42
66
         * specified file.
54
78
                var glib_ns = root_symbol.scope.lookup ("GLib");
55
79
                gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object");
56
80
 
 
81
                write_package (package);
 
82
 
 
83
                context.accept (this);
 
84
 
 
85
                indent--;
 
86
                buffer.append_printf ("</repository>\n");
 
87
 
57
88
                string filename = "%s%c%s-%s.gir".printf (directory, Path.DIR_SEPARATOR, gir_namespace, gir_version);
58
89
                stream = FileStream.open (filename, "w");
59
90
 
66
97
                stream.printf (">\n");
67
98
                indent++;
68
99
 
69
 
                write_package (package);
70
 
 
71
 
                context.accept (this);
72
 
 
 
100
                write_includes();
73
101
                indent--;
74
 
                stream.printf ("</repository>\n");
75
102
 
 
103
                stream.puts (buffer.str);
76
104
                stream = null;
 
105
 
 
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));
 
109
                        }
 
110
                }
 
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;
 
114
                }
77
115
        }
78
116
 
79
117
        private void write_package (string package) {
80
118
                write_indent ();
81
 
                stream.printf ("<package name=\"%s\"/>\n", package);
 
119
                buffer.append_printf ("<package name=\"%s\"/>\n", package);
82
120
        }
83
121
 
84
122
        private void write_c_includes (Namespace ns) {
101
139
 
102
140
        private void write_c_include (string name) {
103
141
                write_indent ();
104
 
                stream.printf ("<c:include name=\"%s\"/>\n", name);
 
142
                buffer.append_printf ("<c:include name=\"%s\"/>\n", name);
105
143
        }
106
144
 
107
145
        public override void visit_namespace (Namespace ns) {
124
162
                write_c_includes (ns);
125
163
 
126
164
                write_indent ();
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);
131
169
                }
132
 
                stream.printf (">\n");
 
170
                buffer.append_printf (">\n");
133
171
                indent++;
134
172
 
135
173
                write_annotations (ns);
138
176
 
139
177
                indent--;
140
178
                write_indent ();
141
 
                stream.printf ("</namespace>\n");
 
179
                buffer.append_printf ("</namespace>\n");
 
180
                our_namespaces.add(ns);
142
181
        }
143
182
 
144
183
        public override void visit_class (Class cl) {
154
193
                        string gtype_struct_name = cl.name + "Class";
155
194
 
156
195
                        write_indent ();
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\"");
163
202
                        }
164
 
                        stream.printf (">\n");
 
203
                        buffer.append_printf (">\n");
165
204
                        indent++;
166
205
 
167
206
                        // write implemented interfaces
169
208
                                var object_type = (ObjectType) base_type;
170
209
                                if (object_type.type_symbol is Interface) {
171
210
                                        write_indent ();
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));
173
212
                                }
174
213
                        }
175
214
 
176
215
                        write_annotations (cl);
177
216
 
 
217
                        write_indent ();
 
218
                        buffer.append_printf ("<field name=\"parent_instance\">\n");
 
219
                        indent++;
 
220
                        write_indent ();
 
221
                        buffer.append_printf ("<type name=\"%s\" c:type=\"%s\"/>\n", gi_type_name (cl.base_class), cl.base_class.get_cname ());
 
222
                        indent--;
 
223
                        write_indent ();
 
224
                        buffer.append_printf("</field>\n");
 
225
 
 
226
                        write_indent ();
 
227
                        buffer.append_printf ("<field name=\"priv\">\n");
 
228
                        indent++;
 
229
                        write_indent ();
 
230
                        buffer.append_printf ("<type name=\"any\" c:type=\"%sPrivate*\"/>\n", cl.get_cname ());
 
231
                        indent--;
 
232
                        write_indent ();
 
233
                        buffer.append_printf("</field>\n");
 
234
 
178
235
                        cl.accept_children (this);
179
236
 
180
237
                        indent--;
181
238
                        write_indent ();
182
 
                        stream.printf ("</class>\n");
 
239
                        buffer.append_printf ("</class>\n");
183
240
 
184
241
                        write_indent ();
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");
189
 
                        indent++;
 
244
                        buffer.append_printf (" glib:is-gtype-struct-for=\"%s\"", cl.name);
 
245
                        buffer.append_printf (">\n");
 
246
                        indent++;
 
247
 
 
248
                        write_indent ();
 
249
                        buffer.append_printf ("<field name=\"parent_class\">\n");
 
250
                        indent++;
 
251
                        write_indent ();
 
252
                        buffer.append_printf ("<type name=\"%sClass\" c:type=\"%sClass\"/>\n", gi_type_name (cl.base_class), cl.base_class.get_cname ());
 
253
                        indent--;
 
254
                        write_indent ();
 
255
                        buffer.append_printf ("</field>\n");
190
256
 
191
257
                        foreach (Method m in cl.get_methods ()) {
192
258
                                if (m.is_abstract || m.is_virtual) {
 
259
                                        write_indent ();
 
260
                                        buffer.append_printf("<field name=\"%s\">\n", m.name);
 
261
                                        indent++;
193
262
                                        write_signature(m, "callback", true);
194
 
                                }
195
 
                        }
 
263
                                        indent--;
 
264
                                        write_indent ();
 
265
                                        buffer.append_printf ("</field>\n");
 
266
                                }
 
267
                        }
 
268
 
 
269
                        foreach (Signal sig in cl.get_signals ()) {
 
270
                                if (sig.default_handler != null) {
 
271
                                        write_indent ();
 
272
                                        buffer.append_printf ("<field name=\"%s\">\n", sig.name);
 
273
                                        indent++;
 
274
                                        write_signature (sig.default_handler, "callback", true);
 
275
                                        indent--;
 
276
                                        write_indent ();
 
277
                                        buffer.append_printf ("</field>\n");
 
278
                                }
 
279
                        }
 
280
 
196
281
 
197
282
                        indent--;
198
283
                        write_indent ();
199
 
                        stream.printf ("</record>\n");
 
284
                        buffer.append_printf ("</record>\n");
200
285
                } else {
201
286
                        write_indent ();
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");
204
289
                        indent++;
205
290
 
206
291
                        write_annotations (cl);
209
294
 
210
295
                        indent--;
211
296
                        write_indent ();
212
 
                        stream.printf ("</record>\n");
 
297
                        buffer.append_printf ("</record>\n");
213
298
                }
214
299
        }
215
300
 
223
308
                }
224
309
 
225
310
                write_indent ();
226
 
                stream.printf ("<record name=\"%s\"", st.name);
227
 
                stream.printf (">\n");
 
311
                buffer.append_printf ("<record name=\"%s\"", st.name);
 
312
                buffer.append_printf (">\n");
228
313
                indent++;
229
314
 
230
315
                write_annotations (st);
233
318
 
234
319
                indent--;
235
320
                write_indent ();
236
 
                stream.printf ("</record>\n");
 
321
                buffer.append_printf ("</record>\n");
237
322
        }
238
323
 
239
324
        public override void visit_interface (Interface iface) {
248
333
                string gtype_struct_name = iface.name + "Iface";
249
334
 
250
335
                write_indent ();
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");
255
340
                indent++;
256
341
 
257
342
                // write prerequisites
258
343
                if (iface.get_prerequisites ().size > 0) {
259
344
                        write_indent ();
260
 
                        stream.printf ("<requires>\n");
 
345
                        buffer.append_printf ("<requires>\n");
261
346
                        indent++;
262
347
 
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) {
266
351
                                        write_indent ();
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) {
269
354
                                        write_indent ();
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));
271
356
                                } else {
272
357
                                        assert_not_reached ();
273
358
                                }
275
360
 
276
361
                        indent--;
277
362
                        write_indent ();
278
 
                        stream.printf ("</requires>\n");
 
363
                        buffer.append_printf ("</requires>\n");
279
364
                }
280
365
 
281
366
                write_annotations (iface);
284
369
 
285
370
                indent--;
286
371
                write_indent ();
287
 
                stream.printf ("</interface>\n");
 
372
                buffer.append_printf ("</interface>\n");
288
373
 
289
374
                write_indent ();
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");
294
379
                indent++;
295
380
 
296
381
                foreach (Method m in iface.get_methods ()) {
301
386
 
302
387
                indent--;
303
388
                write_indent ();
304
 
                stream.printf ("</record>\n");
 
389
                buffer.append_printf ("</record>\n");
305
390
        }
306
391
 
307
392
        public override void visit_enum (Enum en) {
314
399
                }
315
400
 
316
401
                write_indent ();
317
 
                stream.printf ("<enumeration name=\"%s\"", en.name);
 
402
                buffer.append_printf ("<enumeration name=\"%s\"", en.name);
318
403
                write_gtype_attributes (en);
319
 
                stream.printf (">\n");
 
404
                buffer.append_printf (">\n");
320
405
                indent++;
321
406
 
322
407
                write_annotations (en);
326
411
 
327
412
                indent--;
328
413
                write_indent ();
329
 
                stream.printf ("</enumeration>\n");
 
414
                buffer.append_printf ("</enumeration>\n");
330
415
        }
331
416
 
332
417
        private int enum_value;
333
418
 
334
419
        public override void visit_enum_value (EnumValue ev) {
335
420
                write_indent ();
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);
340
425
                } else {
341
 
                        stream.printf (" value=\"%d\"", enum_value++);
 
426
                        buffer.append_printf (" value=\"%d\"", enum_value++);
342
427
                }
343
 
                stream.printf ("/>\n");
 
428
                buffer.append_printf ("/>\n");
344
429
        }
345
430
 
346
431
        public override void visit_error_domain (ErrorDomain edomain) {
353
438
                }
354
439
 
355
440
                write_indent ();
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");
360
445
 
361
446
                write_annotations (edomain);
362
447
 
363
 
                stream.printf ("</errordomain>\n");
 
448
                buffer.append_printf ("</errordomain>\n");
364
449
 
365
450
                write_indent ();
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");
369
454
                indent++;
370
455
 
371
456
                enum_value = 0;
373
458
 
374
459
                indent--;
375
460
                write_indent ();
376
 
                stream.printf ("</enumeration>\n");
 
461
                buffer.append_printf ("</enumeration>\n");
377
462
        }
378
463
 
379
464
        public override void visit_error_code (ErrorCode ecode) {
380
465
                write_indent ();
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);
385
470
                } else {
386
 
                        stream.printf (" value=\"%d\"", enum_value++);
 
471
                        buffer.append_printf (" value=\"%d\"", enum_value++);
387
472
                }
388
 
                stream.printf ("/>\n");
 
473
                buffer.append_printf ("/>\n");
389
474
        }
390
475
 
391
476
        public override void visit_constant (Constant c) {
402
487
                string value = literal_expression_to_value_string (initializer);
403
488
 
404
489
                write_indent ();
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");
408
493
                indent++;
409
494
 
410
495
                write_type (initializer.value_type);
411
496
 
412
497
                indent--;
413
498
                write_indent ();
414
 
                stream.printf ("</constant>\n");
 
499
                buffer.append_printf ("</constant>\n");
415
500
        }
416
501
 
417
502
        public override void visit_field (Field f) {
424
509
                }
425
510
 
426
511
                write_indent ();
427
 
                stream.printf ("<field name=\"%s\"", f.get_cname ());
 
512
                buffer.append_printf ("<field name=\"%s\"", f.get_cname ());
428
513
                if (f.field_type.nullable) {
429
 
                        stream.printf (" allow-none=\"1\"");
 
514
                        buffer.append_printf (" allow-none=\"1\"");
430
515
                }
431
 
                stream.printf (">\n");
 
516
                buffer.append_printf (">\n");
432
517
                indent++;
433
518
 
434
519
                write_annotations (f);
437
522
 
438
523
                indent--;
439
524
                write_indent ();
440
 
                stream.printf ("</field>\n");
 
525
                buffer.append_printf ("</field>\n");
441
526
        }
442
527
 
443
528
        private void write_implicit_params (DataType type, ref int index, bool has_array_length, string name, ParameterDirection direction) {
454
539
                }
455
540
        }
456
541
 
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)) {
460
545
                        write_indent ();
461
 
                        stream.printf ("<parameters>\n");
 
546
                        buffer.append_printf ("<parameters>\n");
462
547
                        indent++;
463
548
                        int index = 1;
464
549
 
475
560
                        last_index = index - 1;
476
561
                        write_implicit_params (return_type, ref index, return_array_length, "result", ParameterDirection.OUT);
477
562
 
 
563
                        if (user_data) {
 
564
                                write_indent ();
 
565
                                buffer.append_printf ("<parameter name=\"user_data\" transfer-ownership=\"none\" closure=\"%d\">\n", index);
 
566
                                indent++;
 
567
                                write_indent ();
 
568
                                buffer.append_printf ("<type name=\"any\" c:type=\"void*\"/>\n");
 
569
                                indent--;
 
570
                                write_indent ();
 
571
                                buffer.append_printf ("</parameter>\n");
 
572
                        }
 
573
 
478
574
                        indent--;
479
575
                        write_indent ();
480
 
                        stream.printf ("</parameters>\n");
 
576
                        buffer.append_printf ("</parameters>\n");
481
577
                }
482
578
 
483
579
                if (return_type != null) {
495
591
                }
496
592
 
497
593
                write_indent ();
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\"");
502
598
                }
503
 
                stream.printf (">\n");
 
599
                buffer.append_printf (">\n");
504
600
                indent++;
505
601
 
506
602
                write_annotations (cb);
507
603
 
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);
509
605
 
510
606
                indent--;
511
607
                write_indent ();
512
 
                stream.printf ("</callback>\n");
 
608
                buffer.append_printf ("</callback>\n");
513
609
        }
514
610
 
515
611
        public override void visit_method (Method m) {
551
647
 
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) {
553
649
                write_indent ();
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);
559
656
                } else {
560
 
                        stream.printf (" c:identifier=\"%s\"", cname);
 
657
                        buffer.append_printf (" c:identifier=\"%s\"", cname);
561
658
                }
562
659
                if (can_fail) {
563
 
                        stream.printf (" throws=\"1\"");
 
660
                        buffer.append_printf (" throws=\"1\"");
564
661
                }
565
 
                stream.printf (">\n");
 
662
                buffer.append_printf (">\n");
566
663
                indent++;
567
664
 
568
665
                write_annotations (m);
576
673
 
577
674
                indent--;
578
675
                write_indent ();
579
 
                stream.printf ("</%s>\n", tag_name);
 
676
                buffer.append_printf ("</%s>\n", tag_name);
580
677
        }
581
678
        
582
679
        public override void visit_creation_method (CreationMethod m) {
591
688
                write_indent ();
592
689
 
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 ());
595
692
                } else {
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 ());
597
694
                }
598
695
 
599
696
                if (m.tree_can_fail) {
600
 
                        stream.printf (" throws=\"1\"");
 
697
                        buffer.append_printf (" throws=\"1\"");
601
698
                }
602
 
                stream.printf (">\n");
 
699
                buffer.append_printf (">\n");
603
700
                indent++;
604
701
 
605
702
                write_annotations (m);
610
707
 
611
708
                indent--;
612
709
                write_indent ();
613
 
                stream.printf ("</constructor>\n");
 
710
                buffer.append_printf ("</constructor>\n");
614
711
        }
615
712
 
616
713
        public override void visit_property (Property prop) {
619
716
                }
620
717
 
621
718
                write_indent ();
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\"");
625
722
                }
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\"");
631
728
                                } else {
632
 
                                        stream.printf (" construct=\"1\"");
 
729
                                        buffer.append_printf (" construct=\"1\"");
633
730
                                }
634
731
                        }
635
732
                }
636
 
                stream.printf (">\n");
 
733
                buffer.append_printf (">\n");
637
734
                indent++;
638
735
 
639
736
                write_annotations (prop);
642
739
 
643
740
                indent--;
644
741
                write_indent ();
645
 
                stream.printf ("</property>\n");
 
742
                buffer.append_printf ("</property>\n");
646
743
        }
647
744
 
648
745
        public override void visit_signal (Signal sig) {
651
748
                }
652
749
                
653
750
                write_indent ();
654
 
                stream.printf ("<glib:signal name=\"%s\"", sig.get_cname ());
655
 
                stream.printf (">\n");
 
751
                buffer.append_printf ("<glib:signal name=\"%s\"", sig.get_cname ());
 
752
                buffer.append_printf (">\n");
656
753
                indent++;
657
754
 
658
755
                write_annotations (sig);
661
758
 
662
759
                indent--;
663
760
                write_indent ();
664
 
                stream.printf ("</glib:signal>\n");
 
761
                buffer.append_printf ("</glib:signal>\n");
665
762
        }
666
763
 
667
764
        private void write_indent () {
668
765
                int i;
669
766
                
670
767
                for (i = 0; i < indent; i++) {
 
768
                        buffer.append_c ('\t');
 
769
                }
 
770
        }
 
771
 
 
772
        private void write_indent_stream () {
 
773
                int i;
 
774
 
 
775
                for (i = 0; i < indent; i++) {
671
776
                        stream.putc ('\t');
672
777
                }
673
778
        }
674
779
 
 
780
 
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) {
676
782
                write_indent ();
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);
680
786
                }
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\"");
685
791
                }
686
792
 
687
793
                Delegate delegate_type = type.data_type as Delegate;
688
794
 
689
795
                if ((type.value_owned && delegate_type == null) || constructor) {
690
 
                        stream.printf (" transfer-ownership=\"full\"");
 
796
                        buffer.append_printf (" transfer-ownership=\"full\"");
691
797
                } else {
692
 
                        stream.printf (" transfer-ownership=\"none\"");
 
798
                        buffer.append_printf (" transfer-ownership=\"none\"");
693
799
                }
694
800
                if (type.nullable) {
695
 
                        stream.printf (" allow-none=\"1\"");
 
801
                        buffer.append_printf (" allow-none=\"1\"");
696
802
                }
697
803
 
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);
702
808
                        }
703
809
                }
704
810
 
705
 
                stream.printf (">\n");
 
811
                buffer.append_printf (">\n");
706
812
                indent++;
707
813
 
708
814
                write_type (type, has_array_length ? index : -1);
709
815
 
710
816
                indent--;
711
817
                write_indent ();
712
 
                stream.printf ("</%s>\n", tag);
 
818
                buffer.append_printf ("</%s>\n", tag);
713
819
                index++;
714
820
        }
715
821
 
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);
718
824
        }
719
825
 
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 ());
724
830
        }
725
831
 
726
832
        private void write_type (DataType type, int index = -1) {
728
834
                        var array_type = (ArrayType) type;
729
835
 
730
836
                        write_indent ();
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);
736
842
                        }
737
 
                        stream.printf (">\n");
 
843
                        buffer.append_printf (">\n");
738
844
                        indent++;
739
845
 
740
846
                        write_type (array_type.element_type);
741
847
 
742
848
                        indent--;
743
849
                        write_indent ();
744
 
                        stream.printf ("</array>\n");
 
850
                        buffer.append_printf ("</array>\n");
745
851
                } else if (type is VoidType) {
746
852
                        write_indent ();
747
 
                        stream.printf ("<type name=\"none\"/>\n");
 
853
                        buffer.append_printf ("<type name=\"none\"/>\n");
748
854
                } else if (type is PointerType) {
749
855
                        write_indent ();
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) {
752
858
                        write_indent ();
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 ());
754
860
 
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");
758
864
                        } else {
759
 
                                stream.printf (">\n");
 
865
                                buffer.append_printf (">\n");
760
866
                                indent++;
761
867
 
762
868
                                foreach (DataType type_argument in type_arguments) {
765
871
 
766
872
                                indent--;
767
873
                                write_indent ();
768
 
                                stream.printf ("</type>\n");
 
874
                                buffer.append_printf ("</type>\n");
769
875
                        }
770
876
                } else if (type is DelegateType) {
771
877
                        var deleg_type = (DelegateType) type;
772
878
                        write_indent ();
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 ());
774
880
                } else {
775
881
                        write_indent ();
776
 
                        stream.printf ("<type name=\"%s\"/>\n", type.to_string ());
 
882
                        buffer.append_printf ("<type name=\"%s\"/>\n", type.to_string ());
777
883
                }
778
884
        }
779
885
 
787
893
 
788
894
                                if (value != null) {
789
895
                                        write_indent ();
790
 
                                        stream.printf ("<annotation key=\"%s.%s\" value=\"%s\"/>\n",
 
896
                                        buffer.append_printf ("<annotation key=\"%s.%s\" value=\"%s\"/>\n",
791
897
                                                name, camel_case_to_canonical (arg_name), value);
792
898
                                }
793
899
                        }
795
901
        }
796
902
 
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);
 
912
                                        }
 
913
                                        return "%s.%s".printf (type_symbol.source_reference.file.gir_namespace, type_symbol.name);
 
914
                                } else {
 
915
                                        unannotated_namespaces.add(ns);
 
916
                                }
 
917
                        }
 
918
                }
 
919
 
798
920
                return vala_to_gi_type_name (type_symbol.get_full_name());
799
921
        }
800
922
 
814
936
                        for (int i = 1; i < split_name.length; i++) {
815
937
                                type_name.append (split_name[i]);
816
938
                        }
817
 
 
818
 
                        if (type_name.str == "GLib.Object") {
819
 
                                return "GObject.Object";
820
 
                        }
821
939
                        return type_name.str;
822
940
                }
823
941
        }