From dc68bd9aacf4ab05c3b24d79b44ed1c998192a15 Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Tue, 2 Feb 2010 22:16:30 +0000 Subject: [PATCH] Fix GIR writing to only add lines for API dependencies This refactors GIRWriter quite a bit so we can collect the GIR namespace dependencies when writing the type names, so only namespaces that are actually used get lines. --- codegen/valagirwriter.vala | 401 ++++++++++++++++++------------------- 1 file changed, 193 insertions(+), 208 deletions(-) diff --git a/codegen/valagirwriter.vala b/codegen/valagirwriter.vala index 122bba154..f9c5f3ce8 100644 --- a/codegen/valagirwriter.vala +++ b/codegen/valagirwriter.vala @@ -30,76 +30,37 @@ public class Vala.GIRWriter : CodeVisitor { private string directory; private string gir_namespace; private string gir_version; - + + StringBuilder buffer = new StringBuilder(); FileStream stream; - + Vala.HashSet unannotated_namespaces = new Vala.HashSet(); + Vala.HashSet our_namespaces = new Vala.HashSet(); + int indent; private TypeSymbol gobject_type; - private class ExternalNamespaceWriter : CodeVisitor { - private struct GIRNamespace { - public GIRNamespace (string ns, string version) { - this.ns = ns; this.version = version; - } - public string ns; - public string version; - public bool equal (GIRNamespace g) { - return ((ns == g.ns) && (version == g.version)); - } + private struct GIRNamespace { + public GIRNamespace (string ns, string version) { + this.ns = ns; this.version = version; } - private ArrayList externals = new ArrayList ((EqualFunc) GIRNamespace.equal); - private string gir_namespace; - private string gir_version; - private GIRWriter gir_writer; - private bool in_source_file = false; - - public ExternalNamespaceWriter (GIRWriter gir_writer, string gir_namespace, string gir_version) { - this.gir_writer = gir_writer; - this.gir_namespace = gir_namespace; - this.gir_version = gir_version; + public string ns; + public string version; + public bool equal (GIRNamespace g) { + return ((ns == g.ns) && (version == g.version)); } + } - public override void visit_namespace (Namespace ns) { - if (!in_source_file) { - return; - } - - if (ns.name == null) { - ns.accept_children (this); - return; - } - - if (!ns.external_package) { - ns.source_reference.file.gir_namespace = gir_namespace; - ns.source_reference.file.gir_version = gir_version; - return; - } - - if (ns.source_reference.file.gir_namespace != null) { - GIRNamespace external = GIRNamespace (ns.source_reference.file.gir_namespace, ns.source_reference.file.gir_version); - if (!externals.contains (external)) { - externals.add (external); - } - } else { - Report.warning (ns.source_reference, "Namespace %s does not have a GIR namespace and version annotation".printf (ns.name)); - } - } - - - public override void visit_source_file (SourceFile sf) { - in_source_file = true; - sf.accept_children (this); - in_source_file = false; - } + private ArrayList externals = new ArrayList ((EqualFunc) GIRNamespace.equal); - public void write_externals() { - foreach (var i in externals) { - gir_writer.write_gir_include(i.ns, i.version); - } + public void write_includes() { + foreach (var i in externals) { + write_indent_stream (); + stream.printf ("\n", i.ns, i.version); } } + /** * Writes the public interface of the specified code context into the * specified file. @@ -117,6 +78,13 @@ public class Vala.GIRWriter : CodeVisitor { var glib_ns = root_symbol.scope.lookup ("GLib"); gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object"); + write_package (package); + + context.accept (this); + + indent--; + buffer.append_printf ("\n"); + string filename = "%s%c%s-%s.gir".printf (directory, Path.DIR_SEPARATOR, gir_namespace, gir_version); stream = FileStream.open (filename, "w"); @@ -129,28 +97,26 @@ public class Vala.GIRWriter : CodeVisitor { stream.printf (">\n"); indent++; - ExternalNamespaceWriter env = new ExternalNamespaceWriter (this, gir_namespace, gir_version); - context.accept (env); - env.write_externals(); - - write_package (package); - - context.accept (this); - + write_includes(); indent--; - stream.printf ("\n"); + stream.puts (buffer.str); stream = null; - } - internal void write_gir_include (string name, string version) { - write_indent (); - stream.printf ("\n", name, version); + foreach (var ns in unannotated_namespaces) { + if (!our_namespaces.contains(ns)) { + Report.warning (ns.source_reference, "Namespace %s does not have a GIR namespace and version annotation".printf (ns.name)); + } + } + foreach (var ns in our_namespaces) { + ns.source_reference.file.gir_namespace = gir_namespace; + ns.source_reference.file.gir_version = gir_version; + } } private void write_package (string package) { write_indent (); - stream.printf ("\n", package); + buffer.append_printf ("\n", package); } private void write_c_includes (Namespace ns) { @@ -173,7 +139,7 @@ public class Vala.GIRWriter : CodeVisitor { private void write_c_include (string name) { write_indent (); - stream.printf ("\n", name); + buffer.append_printf ("\n", name); } public override void visit_namespace (Namespace ns) { @@ -196,12 +162,12 @@ public class Vala.GIRWriter : CodeVisitor { write_c_includes (ns); write_indent (); - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; write_annotations (ns); @@ -210,7 +176,8 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); + our_namespaces.add(ns); } public override void visit_class (Class cl) { @@ -226,14 +193,14 @@ public class Vala.GIRWriter : CodeVisitor { string gtype_struct_name = cl.name + "Class"; write_indent (); - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; // write implemented interfaces @@ -241,84 +208,84 @@ public class Vala.GIRWriter : CodeVisitor { var object_type = (ObjectType) base_type; if (object_type.type_symbol is Interface) { write_indent (); - stream.printf ("\n", gi_type_name (object_type.type_symbol)); + buffer.append_printf ("\n", gi_type_name (object_type.type_symbol)); } } write_annotations (cl); write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; write_indent (); - stream.printf ("\n", gi_type_name (cl.base_class), cl.base_class.get_cname ()); + buffer.append_printf ("\n", gi_type_name (cl.base_class), cl.base_class.get_cname ()); indent--; write_indent (); - stream.printf("\n"); + buffer.append_printf("\n"); write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; write_indent (); - stream.printf ("\n", cl.get_cname ()); + buffer.append_printf ("\n", cl.get_cname ()); indent--; write_indent (); - stream.printf("\n"); + buffer.append_printf("\n"); cl.accept_children (this); indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); write_indent (); - stream.printf ("\n"); + buffer.append_printf (" glib:is-gtype-struct-for=\"%s\"", cl.name); + buffer.append_printf (">\n"); indent++; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; write_indent (); - stream.printf ("\n", gi_type_name (cl.base_class), cl.base_class.get_cname ()); + buffer.append_printf ("\n", gi_type_name (cl.base_class), cl.base_class.get_cname ()); indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); foreach (Method m in cl.get_methods ()) { if (m.is_abstract || m.is_virtual) { write_indent (); - stream.printf("\n", m.name); + buffer.append_printf("\n", m.name); indent++; write_signature(m, "callback", true); indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } } foreach (Signal sig in cl.get_signals ()) { if (sig.default_handler != null) { write_indent (); - stream.printf ("\n", sig.name); + buffer.append_printf ("\n", sig.name); indent++; write_signature (sig.default_handler, "callback", true); indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } } indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } else { write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; write_annotations (cl); @@ -327,7 +294,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } } @@ -341,8 +308,8 @@ public class Vala.GIRWriter : CodeVisitor { } write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; write_annotations (st); @@ -351,7 +318,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } public override void visit_interface (Interface iface) { @@ -366,26 +333,26 @@ public class Vala.GIRWriter : CodeVisitor { string gtype_struct_name = iface.name + "Iface"; write_indent (); - stream.printf ("\n"); + buffer.append_printf (" glib:type-struct=\"%s\"", gtype_struct_name); + buffer.append_printf (">\n"); indent++; // write prerequisites if (iface.get_prerequisites ().size > 0) { write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; foreach (DataType base_type in iface.get_prerequisites ()) { var object_type = (ObjectType) base_type; if (object_type.type_symbol is Class) { write_indent (); - stream.printf ("\n", gi_type_name (object_type.type_symbol)); + buffer.append_printf ("\n", gi_type_name (object_type.type_symbol)); } else if (object_type.type_symbol is Interface) { write_indent (); - stream.printf ("\n", gi_type_name (object_type.type_symbol)); + buffer.append_printf ("\n", gi_type_name (object_type.type_symbol)); } else { assert_not_reached (); } @@ -393,7 +360,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } write_annotations (iface); @@ -402,13 +369,13 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); write_indent (); - stream.printf ("\n"); + buffer.append_printf (" glib:is-gtype-struct-for=\"%s\"", iface.name); + buffer.append_printf (">\n"); indent++; foreach (Method m in iface.get_methods ()) { @@ -419,7 +386,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } public override void visit_enum (Enum en) { @@ -432,9 +399,9 @@ public class Vala.GIRWriter : CodeVisitor { } write_indent (); - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; write_annotations (en); @@ -444,21 +411,21 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } private int enum_value; public override void visit_enum_value (EnumValue ev) { write_indent (); - stream.printf ("\n"); + buffer.append_printf ("/>\n"); } public override void visit_error_domain (ErrorDomain edomain) { @@ -471,19 +438,19 @@ public class Vala.GIRWriter : CodeVisitor { } write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); write_annotations (edomain); - stream.printf ("\n"); + buffer.append_printf ("\n"); write_indent (); - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; enum_value = 0; @@ -491,19 +458,19 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } public override void visit_error_code (ErrorCode ecode) { write_indent (); - stream.printf ("\n"); + buffer.append_printf ("/>\n"); } public override void visit_constant (Constant c) { @@ -520,16 +487,16 @@ public class Vala.GIRWriter : CodeVisitor { string value = literal_expression_to_value_string (initializer); write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; write_type (initializer.value_type); indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } public override void visit_field (Field f) { @@ -542,11 +509,11 @@ public class Vala.GIRWriter : CodeVisitor { } write_indent (); - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; write_annotations (f); @@ -555,7 +522,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } private void write_implicit_params (DataType type, ref int index, bool has_array_length, string name, ParameterDirection direction) { @@ -576,7 +543,7 @@ public class Vala.GIRWriter : CodeVisitor { int last_index = 0; if (params.size != 0 || instance_type != null || (return_type is ArrayType && return_array_length) || (return_type is DelegateType)) { write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; int index = 1; @@ -595,18 +562,18 @@ public class Vala.GIRWriter : CodeVisitor { if (user_data) { write_indent (); - stream.printf ("\n", index); + buffer.append_printf ("\n", index); indent++; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } if (return_type != null) { @@ -624,12 +591,12 @@ public class Vala.GIRWriter : CodeVisitor { } write_indent (); - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; write_annotations (cb); @@ -638,7 +605,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } public override void visit_method (Method m) { @@ -680,19 +647,19 @@ public class Vala.GIRWriter : CodeVisitor { private void do_write_signature (Method m, string tag_name, bool instance, string name, string cname, List params, DataType return_type, bool can_fail) { write_indent (); - stream.printf ("<%s name=\"%s\"", tag_name, name); + buffer.append_printf ("<%s name=\"%s\"", tag_name, name); if (tag_name == "virtual-method") { - stream.printf (" invoker=\"%s\"", name); + buffer.append_printf (" invoker=\"%s\"", name); } else if (tag_name == "callback") { /* this is only used for vfuncs */ - stream.printf (" c:type=\"%s\"", name); + buffer.append_printf (" c:type=\"%s\"", name); } else { - stream.printf (" c:identifier=\"%s\"", cname); + buffer.append_printf (" c:identifier=\"%s\"", cname); } if (can_fail) { - stream.printf (" throws=\"1\""); + buffer.append_printf (" throws=\"1\""); } - stream.printf (">\n"); + buffer.append_printf (">\n"); indent++; write_annotations (m); @@ -706,7 +673,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n", tag_name); + buffer.append_printf ("\n", tag_name); } public override void visit_creation_method (CreationMethod m) { @@ -721,15 +688,15 @@ public class Vala.GIRWriter : CodeVisitor { write_indent (); if (m == ((Class)m.parent_symbol).default_construction_method) { - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; write_annotations (m); @@ -740,7 +707,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } public override void visit_property (Property prop) { @@ -749,21 +716,21 @@ public class Vala.GIRWriter : CodeVisitor { } write_indent (); - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; write_annotations (prop); @@ -772,7 +739,7 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } public override void visit_signal (Signal sig) { @@ -781,8 +748,8 @@ public class Vala.GIRWriter : CodeVisitor { } write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); indent++; write_annotations (sig); @@ -791,66 +758,75 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } private void write_indent () { int i; + for (i = 0; i < indent; i++) { + buffer.append_c ('\t'); + } + } + + private void write_indent_stream () { + int i; + for (i = 0; i < indent; i++) { stream.putc ('\t'); } } + 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) { write_indent (); - stream.printf ("<%s", tag); + buffer.append_printf ("<%s", tag); if (name != null) { - stream.printf (" name=\"%s\"", name); + buffer.append_printf (" name=\"%s\"", name); } if (direction == ParameterDirection.REF) { - stream.printf (" direction=\"inout\""); + buffer.append_printf (" direction=\"inout\""); } else if (direction == ParameterDirection.OUT) { - stream.printf (" direction=\"out\""); + buffer.append_printf (" direction=\"out\""); } Delegate delegate_type = type.data_type as Delegate; if ((type.value_owned && delegate_type == null) || constructor) { - stream.printf (" transfer-ownership=\"full\""); + buffer.append_printf (" transfer-ownership=\"full\""); } else { - stream.printf (" transfer-ownership=\"none\""); + buffer.append_printf (" transfer-ownership=\"none\""); } if (type.nullable) { - stream.printf (" allow-none=\"1\""); + buffer.append_printf (" allow-none=\"1\""); } if (delegate_type != null && delegate_type.has_target) { - stream.printf (" closure=\"%i\"", index + 1); + buffer.append_printf (" closure=\"%i\"", index + 1); if (type.value_owned) { - stream.printf (" destroy=\"%i\"", index + 2); + buffer.append_printf (" destroy=\"%i\"", index + 2); } } - stream.printf (">\n"); + buffer.append_printf (">\n"); indent++; write_type (type, has_array_length ? index : -1); indent--; write_indent (); - stream.printf ("\n", tag); + buffer.append_printf ("\n", tag); index++; } private void write_ctype_attributes (TypeSymbol symbol, string suffix = "") { - stream.printf (" c:type=\"%s%s\"", symbol.get_cname (), suffix); + buffer.append_printf (" c:type=\"%s%s\"", symbol.get_cname (), suffix); } private void write_gtype_attributes (TypeSymbol symbol) { write_ctype_attributes(symbol); - stream.printf (" glib:type-name=\"%s\"", symbol.get_cname ()); - stream.printf (" glib:get-type=\"%sget_type\"", symbol.get_lower_case_cprefix ()); + buffer.append_printf (" glib:type-name=\"%s\"", symbol.get_cname ()); + buffer.append_printf (" glib:get-type=\"%sget_type\"", symbol.get_lower_case_cprefix ()); } private void write_type (DataType type, int index = -1) { @@ -858,35 +834,35 @@ public class Vala.GIRWriter : CodeVisitor { var array_type = (ArrayType) type; write_indent (); - stream.printf ("\n"); + buffer.append_printf (">\n"); indent++; write_type (array_type.element_type); indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } else if (type is VoidType) { write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } else if (type is PointerType) { write_indent (); - stream.printf ("\n", type.get_cname ()); + buffer.append_printf ("\n", type.get_cname ()); } else if (type.data_type != null) { write_indent (); - stream.printf (" type_arguments = type.get_type_arguments (); if (type_arguments.size == 0) { - stream.printf ("/>\n"); + buffer.append_printf ("/>\n"); } else { - stream.printf (">\n"); + buffer.append_printf (">\n"); indent++; foreach (DataType type_argument in type_arguments) { @@ -895,15 +871,15 @@ public class Vala.GIRWriter : CodeVisitor { indent--; write_indent (); - stream.printf ("\n"); + buffer.append_printf ("\n"); } } else if (type is DelegateType) { var deleg_type = (DelegateType) type; write_indent (); - stream.printf ("\n", gi_type_name (deleg_type.delegate_symbol), type.get_cname ()); + buffer.append_printf ("\n", gi_type_name (deleg_type.delegate_symbol), type.get_cname ()); } else { write_indent (); - stream.printf ("\n", type.to_string ()); + buffer.append_printf ("\n", type.to_string ()); } } @@ -917,7 +893,7 @@ public class Vala.GIRWriter : CodeVisitor { if (value != null) { write_indent (); - stream.printf ("\n", + buffer.append_printf ("\n", name, camel_case_to_canonical (arg_name), value); } } @@ -928,10 +904,19 @@ public class Vala.GIRWriter : CodeVisitor { Symbol parent = type_symbol.parent_symbol; if (parent is Namespace) { Namespace ns = parent as Namespace; - if (ns.name != null && type_symbol.source_reference.file.gir_namespace != null) { - return "%s.%s".printf (type_symbol.source_reference.file.gir_namespace, type_symbol.name); + if (ns.name != null) { + if (type_symbol.source_reference.file.gir_namespace != null) { + GIRNamespace external = GIRNamespace (type_symbol.source_reference.file.gir_namespace, type_symbol.source_reference.file.gir_version); + if (!externals.contains (external)) { + externals.add (external); + } + return "%s.%s".printf (type_symbol.source_reference.file.gir_namespace, type_symbol.name); + } else { + unannotated_namespaces.add(ns); + } } } + return vala_to_gi_type_name (type_symbol.get_full_name()); } -- 2.47.3