3
* Copyright (C) 2008-2010 Jürg Billeter
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library 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 GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
* Jürg Billeter <j@bitron.ch>
26
* Code visitor generating .gir file for the public interface.
28
public class Vala.GIRWriter : CodeVisitor {
29
private CodeContext context;
30
private string directory;
31
private string gir_namespace;
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>();
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);
65
* Writes the public interface of the specified code context into the
68
* @param context a code context
69
* @param filename a relative or absolute filename
71
public void write_file (CodeContext context, string directory, string gir_namespace, string gir_version, string package) {
72
this.context = context;
73
this.directory = directory;
74
this.gir_namespace = gir_namespace;
75
this.gir_version = gir_version;
77
var root_symbol = context.root;
78
var glib_ns = root_symbol.scope.lookup ("GLib");
79
gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object");
81
write_package (package);
83
context.accept (this);
86
buffer.append_printf ("</repository>\n");
88
string filename = "%s%c%s-%s.gir".printf (directory, Path.DIR_SEPARATOR, gir_namespace, gir_version);
89
stream = FileStream.open (filename, "w");
91
Report.error (null, "unable to open `%s' for writing".printf (filename));
95
stream.printf ("<?xml version=\"1.0\"?>\n");
97
stream.printf ("<repository version=\"1.2\"");
98
stream.printf (" xmlns=\"http://www.gtk.org/introspection/core/1.0\"");
99
stream.printf (" xmlns:c=\"http://www.gtk.org/introspection/c/1.0\"");
100
stream.printf (" xmlns:glib=\"http://www.gtk.org/introspection/glib/1.0\"");
101
stream.printf (">\n");
107
stream.puts (buffer.str);
110
foreach (var ns in unannotated_namespaces) {
111
if (!our_namespaces.contains(ns)) {
112
Report.warning (ns.source_reference, "Namespace %s does not have a GIR namespace and version annotation".printf (ns.name));
115
foreach (var ns in our_namespaces) {
116
ns.source_reference.file.gir_namespace = gir_namespace;
117
ns.source_reference.file.gir_version = gir_version;
121
private void write_package (string package) {
123
buffer.append_printf ("<package name=\"%s\"/>\n", package);
126
private void write_c_includes (Namespace ns) {
127
// Collect C header filenames
128
Set<string> header_filenames = new HashSet<string> (str_hash, str_equal);
129
foreach (string c_header_filename in ns.get_cheader_filenames ()) {
130
header_filenames.add (c_header_filename);
132
foreach (Symbol symbol in ns.scope.get_symbol_table ().get_values ()) {
133
foreach (string c_header_filename in symbol.get_cheader_filenames ()) {
134
header_filenames.add (c_header_filename);
138
// Generate c:include tags
139
foreach (string c_header_filename in header_filenames) {
140
write_c_include (c_header_filename);
144
private void write_c_include (string name) {
146
buffer.append_printf ("<c:include name=\"%s\"/>\n", name);
149
public override void visit_namespace (Namespace ns) {
150
if (ns.external_package) {
154
if (ns.name == null) {
156
ns.accept_children (this);
160
if (ns.parent_symbol.name != null) {
162
// not supported in GIR at the moment
166
write_c_includes (ns);
169
buffer.append_printf ("<namespace name=\"%s\" version=\"%s\"", gir_namespace, gir_version);
170
string? cprefix = ns.get_cprefix ();
171
if (cprefix != null) {
172
buffer.append_printf (" c:prefix=\"%s\"", cprefix);
174
buffer.append_printf (">\n");
177
write_annotations (ns);
179
ns.accept_children (this);
183
buffer.append_printf ("</namespace>\n");
184
our_namespaces.add(ns);
187
public override void visit_class (Class cl) {
188
if (cl.external_package) {
192
if (!check_accessibility (cl)) {
196
if (cl.is_subtype_of (gobject_type)) {
197
string gtype_struct_name = cl.name + "Class";
200
buffer.append_printf ("<class name=\"%s\"", cl.name);
201
write_gtype_attributes (cl);
202
buffer.append_printf (" glib:type-struct=\"%s\"", gtype_struct_name);
203
buffer.append_printf (" parent=\"%s\"", gi_type_name (cl.base_class));
204
if (cl.is_abstract) {
205
buffer.append_printf (" abstract=\"1\"");
207
buffer.append_printf (">\n");
210
// write implemented interfaces
211
foreach (DataType base_type in cl.get_base_types ()) {
212
var object_type = (ObjectType) base_type;
213
if (object_type.type_symbol is Interface) {
215
buffer.append_printf ("<implements name=\"%s\"/>\n", gi_type_name (object_type.type_symbol));
219
write_annotations (cl);
222
buffer.append_printf ("<field name=\"parent_instance\">\n");
225
buffer.append_printf ("<type name=\"%s\" c:type=\"%s\"/>\n", gi_type_name (cl.base_class), cl.base_class.get_cname ());
228
buffer.append_printf("</field>\n");
231
buffer.append_printf ("<field name=\"priv\">\n");
234
buffer.append_printf ("<type name=\"%sPrivate\" c:type=\"%sPrivate*\"/>\n", cl.name, cl.get_cname ());
237
buffer.append_printf("</field>\n");
239
cl.accept_children (this);
243
buffer.append_printf ("</class>\n");
246
buffer.append_printf ("<record name=\"%s\"", gtype_struct_name);
247
write_ctype_attributes (cl, "Class");
248
buffer.append_printf (" glib:is-gtype-struct-for=\"%s\"", cl.name);
249
buffer.append_printf (">\n");
253
buffer.append_printf ("<field name=\"parent_class\">\n");
256
buffer.append_printf ("<type name=\"%sClass\" c:type=\"%sClass\"/>\n", gi_type_name (cl.base_class), cl.base_class.get_cname ());
259
buffer.append_printf ("</field>\n");
261
foreach (Method m in cl.get_methods ()) {
262
if (m.is_abstract || m.is_virtual) {
264
buffer.append_printf("<field name=\"%s\">\n", m.name);
266
write_signature(m, "callback", true);
269
buffer.append_printf ("</field>\n");
273
foreach (Signal sig in cl.get_signals ()) {
274
if (sig.default_handler != null) {
276
buffer.append_printf ("<field name=\"%s\">\n", sig.name);
278
write_signature (sig.default_handler, "callback", true);
281
buffer.append_printf ("</field>\n");
288
buffer.append_printf ("</record>\n");
291
buffer.append_printf ("<record name=\"%sPrivate\" c:type=\"%sPrivate\" disguised=\"1\"/>\n", cl.name, cl.get_cname ());
294
buffer.append_printf ("<record name=\"%s\"", cl.name);
295
buffer.append_printf (">\n");
298
write_annotations (cl);
300
cl.accept_children (this);
304
buffer.append_printf ("</record>\n");
308
public override void visit_struct (Struct st) {
309
if (st.external_package) {
313
if (!check_accessibility (st)) {
318
buffer.append_printf ("<record name=\"%s\"", st.name);
319
buffer.append_printf (">\n");
322
write_annotations (st);
324
st.accept_children (this);
328
buffer.append_printf ("</record>\n");
331
public override void visit_interface (Interface iface) {
332
if (iface.external_package) {
336
if (!check_accessibility (iface)) {
340
string gtype_struct_name = iface.name + "Iface";
343
buffer.append_printf ("<interface name=\"%s\"", iface.name);
344
write_gtype_attributes (iface);
345
buffer.append_printf (" glib:type-struct=\"%s\"", gtype_struct_name);
346
buffer.append_printf (">\n");
349
// write prerequisites
350
if (iface.get_prerequisites ().size > 0) {
351
foreach (DataType base_type in iface.get_prerequisites ()) {
353
buffer.append_printf ("<prerequisite name=\"%s\"/>\n", gi_type_name (((ObjectType) base_type).type_symbol));
357
write_annotations (iface);
358
iface.accept_children (this);
362
buffer.append_printf ("</interface>\n");
365
buffer.append_printf ("<record name=\"%s\"", gtype_struct_name);
366
write_ctype_attributes (iface, "Iface");
367
buffer.append_printf (" glib:is-gtype-struct-for=\"%s\"", iface.name);
368
buffer.append_printf (">\n");
371
foreach (Method m in iface.get_methods ()) {
372
if (m.is_abstract || m.is_virtual) {
373
write_signature(m, "callback", true);
379
buffer.append_printf ("</record>\n");
382
public override void visit_enum (Enum en) {
383
if (en.external_package) {
387
if (!check_accessibility (en)) {
392
buffer.append_printf ("<enumeration name=\"%s\"", en.name);
393
write_gtype_attributes (en);
394
buffer.append_printf (">\n");
397
write_annotations (en);
400
en.accept_children (this);
404
buffer.append_printf ("</enumeration>\n");
407
private int enum_value;
409
public override void visit_enum_value (EnumValue ev) {
411
buffer.append_printf ("<member name=\"%s\" c:identifier=\"%s\"", ev.name.down (), ev.get_cname ());
412
if (ev.value != null) {
413
string value = literal_expression_to_value_string (ev.value);
414
buffer.append_printf (" value=\"%s\"", value);
416
buffer.append_printf (" value=\"%d\"", enum_value++);
418
buffer.append_printf ("/>\n");
421
public override void visit_error_domain (ErrorDomain edomain) {
422
if (edomain.external_package) {
426
if (!check_accessibility (edomain)) {
431
buffer.append_printf ("<errordomain name=\"%s\"", edomain.name);
432
buffer.append_printf (" get-quark=\"%squark\"", edomain.get_lower_case_cprefix ());
433
buffer.append_printf (" codes=\"%s\"", edomain.name);
434
buffer.append_printf (">\n");
436
write_annotations (edomain);
438
buffer.append_printf ("</errordomain>\n");
441
buffer.append_printf ("<enumeration name=\"%s\"", edomain.name);
442
write_ctype_attributes (edomain);
443
buffer.append_printf (">\n");
447
edomain.accept_children (this);
451
buffer.append_printf ("</enumeration>\n");
454
public override void visit_error_code (ErrorCode ecode) {
456
buffer.append_printf ("<member name=\"%s\" c:identifier=\"%s\"", ecode.name.down (), ecode.get_cname ());
457
if (ecode.value != null) {
458
string value = literal_expression_to_value_string (ecode.value);
459
buffer.append_printf (" value=\"%s\"", value);
461
buffer.append_printf (" value=\"%d\"", enum_value++);
463
buffer.append_printf ("/>\n");
466
public override void visit_constant (Constant c) {
467
if (c.external_package) {
471
if (!check_accessibility (c)) {
475
//TODO Add better constant evaluation
476
var initializer = c.value;
477
string value = literal_expression_to_value_string (initializer);
480
buffer.append_printf ("<constant name=\"%s\" c:identifier=\"%s\"", c.name, c.get_cname ());
481
buffer.append_printf (" value=\"%s\"", value);
482
buffer.append_printf (">\n");
485
write_type (initializer.value_type);
489
buffer.append_printf ("</constant>\n");
492
public override void visit_field (Field f) {
493
if (f.external_package) {
497
if (!check_accessibility (f)) {
502
buffer.append_printf ("<field name=\"%s\"", f.get_cname ());
503
if (f.variable_type.nullable) {
504
buffer.append_printf (" allow-none=\"1\"");
506
buffer.append_printf (">\n");
509
write_annotations (f);
511
write_type (f.variable_type);
515
buffer.append_printf ("</field>\n");
518
private void write_implicit_params (DataType type, ref int index, bool has_array_length, string name, ParameterDirection direction) {
519
if (type is ArrayType && has_array_length) {
520
var int_type = new IntegerType (CodeContext.get ().root.scope.lookup ("int") as Struct);
521
write_param_or_return (int_type, "parameter", ref index, has_array_length, "%s_length1".printf (name), direction);
522
} else if (type is DelegateType) {
523
var data_type = new PointerType (new VoidType ());
524
write_param_or_return (data_type, "parameter", ref index, false, "%s_target".printf (name), direction);
525
if (type.value_owned) {
526
var notify_type = new DelegateType (CodeContext.get ().root.scope.lookup ("GLib").scope.lookup ("DestroyNotify") as Delegate);
527
write_param_or_return (notify_type, "parameter", ref index, false, "%s_target_destroy_notify".printf (name), direction);
532
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) {
534
if (params.size != 0 || instance_type != null || (return_type is ArrayType && return_array_length) || (return_type is DelegateType)) {
536
buffer.append_printf ("<parameters>\n");
540
if (instance_type != null) {
541
write_param_or_return (instance_type, "parameter", ref index, false, "self");
544
foreach (FormalParameter param in params) {
545
write_param_or_return (param.variable_type, "parameter", ref index, !param.no_array_length, param.name, param.direction);
547
write_implicit_params (param.variable_type, ref index, !param.no_array_length, param.name, param.direction);
550
last_index = index - 1;
551
write_implicit_params (return_type, ref index, return_array_length, "result", ParameterDirection.OUT);
555
buffer.append_printf ("<parameter name=\"user_data\" transfer-ownership=\"none\" closure=\"%d\">\n", index);
558
buffer.append_printf ("<type name=\"gpointer\" c:type=\"void*\"/>\n");
561
buffer.append_printf ("</parameter>\n");
566
buffer.append_printf ("</parameters>\n");
569
if (return_type != null) {
570
write_param_or_return (return_type, "return-value", ref last_index, return_array_length, null, ParameterDirection.IN, constructor);
574
public override void visit_delegate (Delegate cb) {
575
if (cb.external_package) {
579
if (!check_accessibility (cb)) {
584
buffer.append_printf ("<callback name=\"%s\"", cb.name);
585
buffer.append_printf (" c:type=\"%s\"", cb.get_cname ());
586
if (cb.tree_can_fail) {
587
buffer.append_printf (" throws=\"1\"");
589
buffer.append_printf (">\n");
592
write_annotations (cb);
594
write_params_and_return (cb.get_parameters (), cb.return_type, !cb.no_array_length, false, null, cb.has_target);
598
buffer.append_printf ("</callback>\n");
601
public override void visit_method (Method m) {
602
if (m.external_package) {
606
// don't write interface implementation unless it's an abstract or virtual method
607
if (!check_accessibility (m) || m.overrides || (m.base_interface_method != null && !m.is_abstract && !m.is_virtual)) {
611
string tag_name = "method";
612
var parent = m.parent_symbol;
613
if (parent is Namespace || m.binding == MemberBinding.STATIC) {
614
tag_name = "function";
617
write_signature (m, tag_name);
619
if (m.is_abstract || m.is_virtual) {
620
write_signature (m, "virtual-method", false);
624
private void write_signature (Method m, string tag_name, bool instance = false) {
626
string finish_name = m.name;
627
if (finish_name.has_suffix ("_async")) {
628
finish_name = finish_name.substring (0, finish_name.length - "_async".length);
630
finish_name += "_finish";
631
do_write_signature (m, tag_name, instance, m.name, m.get_cname (), m.get_async_begin_parameters (), new VoidType (), false);
632
do_write_signature (m, tag_name, instance, finish_name, m.get_finish_cname (), m.get_async_end_parameters (), m.return_type, m.tree_can_fail);
634
do_write_signature (m, tag_name, instance, m.name, m.get_cname (), m.get_parameters (), m.return_type, m.tree_can_fail);
638
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) {
640
buffer.append_printf ("<%s name=\"%s\"", tag_name, name);
641
if (tag_name == "virtual-method") {
642
buffer.append_printf (" invoker=\"%s\"", name);
643
} else if (tag_name == "callback") {
644
/* this is only used for vfuncs */
645
buffer.append_printf (" c:type=\"%s\"", name);
647
buffer.append_printf (" c:identifier=\"%s\"", cname);
650
buffer.append_printf (" throws=\"1\"");
652
buffer.append_printf (">\n");
655
write_annotations (m);
657
DataType instance_type = null;
659
instance_type = CCodeBaseModule.get_data_type_for_symbol ((TypeSymbol) m.parent_symbol);
662
write_params_and_return (params, return_type, !m.no_array_length, false, instance_type);
666
buffer.append_printf ("</%s>\n", tag_name);
669
public override void visit_creation_method (CreationMethod m) {
670
if (m.external_package) {
674
if (!check_accessibility (m)) {
680
if (m.parent_symbol is Class && m == ((Class)m.parent_symbol).default_construction_method ||
681
m.parent_symbol is Struct && m == ((Struct)m.parent_symbol).default_construction_method) {
682
buffer.append_printf ("<constructor name=\"new\" c:identifier=\"%s\"", m.get_cname ());
684
buffer.append_printf ("<constructor name=\"%s\" c:identifier=\"%s\"", m.name, m.get_cname ());
687
if (m.tree_can_fail) {
688
buffer.append_printf (" throws=\"1\"");
690
buffer.append_printf (">\n");
693
write_annotations (m);
696
var datatype = CCodeBaseModule.get_data_type_for_symbol ((TypeSymbol) m.parent_symbol);
697
write_params_and_return (m.get_parameters (), datatype, false, true);
701
buffer.append_printf ("</constructor>\n");
704
public override void visit_property (Property prop) {
705
if (!check_accessibility (prop) || prop.overrides || (prop.base_interface_property != null && !prop.is_abstract && !prop.is_virtual)) {
710
buffer.append_printf ("<property name=\"%s\"", prop.get_canonical_name ());
711
if (prop.get_accessor == null) {
712
buffer.append_printf (" readable=\"0\"");
714
if (prop.set_accessor != null) {
715
buffer.append_printf (" writable=\"1\"");
716
if (prop.set_accessor.construction) {
717
if (!prop.set_accessor.writable) {
718
buffer.append_printf (" construct-only=\"1\"");
720
buffer.append_printf (" construct=\"1\"");
724
buffer.append_printf (">\n");
727
write_annotations (prop);
729
write_type (prop.property_type);
733
buffer.append_printf ("</property>\n");
736
public override void visit_signal (Signal sig) {
737
if (!check_accessibility (sig)) {
742
buffer.append_printf ("<glib:signal name=\"%s\"", sig.get_cname ());
743
buffer.append_printf (">\n");
746
write_annotations (sig);
748
write_params_and_return (sig.get_parameters (), sig.return_type, false);
752
buffer.append_printf ("</glib:signal>\n");
755
private void write_indent () {
758
for (i = 0; i < indent; i++) {
759
buffer.append_c ('\t');
763
private void write_indent_stream () {
766
for (i = 0; i < indent; i++) {
772
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) {
774
buffer.append_printf ("<%s", tag);
776
buffer.append_printf (" name=\"%s\"", name);
778
if (direction == ParameterDirection.REF) {
779
buffer.append_printf (" direction=\"inout\"");
780
} else if (direction == ParameterDirection.OUT) {
781
buffer.append_printf (" direction=\"out\"");
784
DelegateType delegate_type = type as DelegateType;
786
if ((type.value_owned && delegate_type == null) || constructor) {
787
buffer.append_printf (" transfer-ownership=\"full\"");
789
buffer.append_printf (" transfer-ownership=\"none\"");
792
buffer.append_printf (" allow-none=\"1\"");
795
if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
796
buffer.append_printf (" closure=\"%i\"", index + 1);
797
if (type.value_owned) {
798
buffer.append_printf (" destroy=\"%i\"", index + 2);
802
buffer.append_printf (">\n");
805
write_type (type, has_array_length ? index : -1);
809
buffer.append_printf ("</%s>\n", tag);
813
private void write_ctype_attributes (TypeSymbol symbol, string suffix = "") {
814
buffer.append_printf (" c:type=\"%s%s\"", symbol.get_cname (), suffix);
817
private void write_gtype_attributes (TypeSymbol symbol) {
818
write_ctype_attributes(symbol);
819
buffer.append_printf (" glib:type-name=\"%s\"", symbol.get_cname ());
820
buffer.append_printf (" glib:get-type=\"%sget_type\"", symbol.get_lower_case_cprefix ());
823
private void write_type (DataType type, int index = -1) {
824
if (type is ArrayType) {
825
var array_type = (ArrayType) type;
828
buffer.append_printf ("<array");
829
if (array_type.fixed_length) {
830
buffer.append_printf (" fixed-length\"%i\"", array_type.length);
831
} else if (index != -1) {
832
buffer.append_printf (" length=\"%i\"", index + 1);
834
buffer.append_printf (">\n");
837
write_type (array_type.element_type);
841
buffer.append_printf ("</array>\n");
842
} else if (type is VoidType) {
844
buffer.append_printf ("<type name=\"none\"/>\n");
845
} else if (type is PointerType) {
847
buffer.append_printf ("<type name=\"gpointer\" c:type=\"%s\"/>\n", type.get_cname ());
848
} else if (type.data_type != null) {
850
buffer.append_printf ("<type name=\"%s\" c:type=\"%s\"", gi_type_name (type.data_type), type.get_cname ());
852
List<DataType> type_arguments = type.get_type_arguments ();
853
if (type_arguments.size == 0) {
854
buffer.append_printf ("/>\n");
856
buffer.append_printf (">\n");
859
foreach (DataType type_argument in type_arguments) {
860
write_type (type_argument);
865
buffer.append_printf ("</type>\n");
867
} else if (type is DelegateType) {
868
var deleg_type = (DelegateType) type;
870
buffer.append_printf ("<type name=\"%s\" c:type=\"%s\"/>\n", gi_type_name (deleg_type.delegate_symbol), type.get_cname ());
871
} else if (type is GenericType) {
872
// generic type parameters not supported in GIR
874
buffer.append ("<type name=\"gpointer\" c:type=\"gpointer\"/>\n");
877
buffer.append_printf ("<type name=\"%s\"/>\n", type.to_string ());
881
private void write_annotations (CodeNode node) {
882
foreach (Attribute attr in node.attributes) {
883
string name = camel_case_to_canonical (attr.name);
884
foreach (string arg_name in attr.args.get_keys ()) {
885
var arg = attr.args.get (arg_name);
887
string value = literal_expression_to_value_string ((Literal) arg);
891
buffer.append_printf ("<annotation key=\"%s.%s\" value=\"%s\"/>\n",
892
name, camel_case_to_canonical (arg_name), value);
898
private string gi_type_name (TypeSymbol type_symbol) {
899
Symbol parent = type_symbol.parent_symbol;
900
if (parent is Namespace) {
901
Namespace ns = parent as Namespace;
902
if (ns.gir_name != null) {
903
if (type_symbol.source_reference.file.gir_namespace != null) {
904
GIRNamespace external = GIRNamespace (type_symbol.source_reference.file.gir_namespace, type_symbol.source_reference.file.gir_version);
905
if (!externals.contains (external)) {
906
externals.add (external);
908
return "%s.%s".printf (type_symbol.source_reference.file.gir_namespace, type_symbol.gir_name);
910
unannotated_namespaces.add(ns);
915
return type_symbol.get_full_gir_name();
918
private string? literal_expression_to_value_string (Expression literal) {
919
if (literal is StringLiteral) {
920
var lit = literal as StringLiteral;
922
return Markup.escape_text (lit.eval ());
924
} else if (literal is CharacterLiteral) {
925
return "%c".printf ((char) ((CharacterLiteral) literal).get_char ());
926
} else if (literal is BooleanLiteral) {
927
return ((BooleanLiteral) literal).value ? "true" : "false";
928
} else if (literal is RealLiteral) {
929
return ((RealLiteral) literal).value;
930
} else if (literal is IntegerLiteral) {
931
return ((IntegerLiteral) literal).value;
932
} else if (literal is UnaryExpression) {
933
var unary = (UnaryExpression) literal;
934
if (unary.operator == UnaryOperator.MINUS) {
935
if (unary.inner is RealLiteral) {
936
return "-" + ((RealLiteral) unary.inner).value;
937
} else if (unary.inner is IntegerLiteral) {
938
return "-" + ((IntegerLiteral) unary.inner).value;
945
private string camel_case_to_canonical (string name) {
946
string[] parts = Symbol.camel_case_to_lower_case (name).split ("_");
947
return string.joinv ("-", parts);
950
private bool check_accessibility (Symbol sym) {
951
if (sym.access == SymbolAccessibility.PUBLIC ||
952
sym.access == SymbolAccessibility.PROTECTED) {