From: Luca Bruno Date: Wed, 1 Sep 2010 22:52:57 +0000 (+0200) Subject: girparser: Set type_cname of interfaces from the relative struct cname. X-Git-Tag: 0.11.2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=283a7fcb70fe68a79174cd7e1ff37c8aa07281a9;p=thirdparty%2Fvala.git girparser: Set type_cname of interfaces from the relative struct cname. Fixes bug 625026. --- diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala index 8b3bf7d9f..3cc8929ac 100644 --- a/vala/valacodewriter.vala +++ b/vala/valacodewriter.vala @@ -495,6 +495,8 @@ public class Vala.CodeWriter : CodeVisitor { write_string ("[CCode (cheader_filename = \"%s\"".printf (get_cheaders(iface))); if (iface.get_lower_case_csuffix () != iface.get_default_lower_case_csuffix ()) write_string (", lower_case_csuffix = \"%s\"".printf (iface.get_lower_case_csuffix ())); + if (iface.get_type_cname () != iface.get_default_type_cname ()) + write_string (", type_cname = \"%s\"".printf (iface.get_type_cname ())); write_string (")]"); write_newline (); diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala index b31b01c6a..83e01e8ae 100644 --- a/vala/valagirparser.vala +++ b/vala/valagirparser.vala @@ -32,6 +32,7 @@ using GLib; * 4) Reparent nodes * 5) Process callbacks/virtual * 6) Process aliases + * 7) Autoreparent static methods * * Best hacking practices: * - Keep GIR parsing bloat-free, it must contain the logic @@ -486,6 +487,8 @@ public class Vala.GirParser : CodeVisitor { class SymbolInfo { public Symbol symbol; public Metadata metadata; + // additional information from GIR + public HashMap girdata; } class CallbackScope { @@ -518,6 +521,8 @@ public class Vala.GirParser : CodeVisitor { ArrayList metadata_stack; Metadata metadata; + ArrayList> girdata_stack; + HashMap girdata; HashMap> current_symbols_info; @@ -575,9 +580,11 @@ public class Vala.GirParser : CodeVisitor { } public void parse_file (SourceFile source_file) { - // load metadata metadata_stack = new ArrayList (); metadata = Metadata.empty; + girdata_stack = new ArrayList> (); + + // load metadata string metadata_filename = "%s.metadata".printf (source_file.filename.ndup (source_file.filename.length - ".gir".length)); if (FileUtils.test (metadata_filename, FileTest.EXISTS)) { var metadata_parser = new MetadataParser (); @@ -784,6 +791,7 @@ public class Vala.GirParser : CodeVisitor { var info = new SymbolInfo (); info.symbol = symbol; info.metadata = metadata; + info.girdata = girdata; var colliding = current_symbols_info[name]; if (colliding == null) { colliding = new ArrayList (); @@ -825,7 +833,17 @@ public class Vala.GirParser : CodeVisitor { } void merge (SymbolInfo info, ArrayList colliding, ArrayList merged) { - if (info.symbol is Property) { + if (info.symbol is Struct) { + var gtype_struct_for = info.girdata["glib:is-gtype-struct-for"]; + if (gtype_struct_for != null && current_symbols_info.contains (gtype_struct_for)) { + var iface = current_symbols_info.get (gtype_struct_for).get (0).symbol as Interface; + if (iface != null) { + // set the interface struct name + iface.set_type_cname (((Struct) info.symbol).get_cname ()); + } + merged.add (info); + } + } else if (info.symbol is Property) { foreach (var cinfo in colliding) { var sym = cinfo.symbol; if (sym is Signal || sym is Field) { @@ -985,12 +1003,17 @@ public class Vala.GirParser : CodeVisitor { metadata_stack.add (metadata); metadata = new_metadata; + girdata_stack.add (girdata); + girdata = new HashMap (str_hash, str_equal); + return true; } void pop_metadata () { metadata = metadata_stack[metadata_stack.size - 1]; metadata_stack.remove_at (metadata_stack.size - 1); + girdata = girdata_stack[girdata_stack.size - 1]; + girdata_stack.remove_at (girdata_stack.size - 1); } bool parse_type_arguments_from_string (DataType parent_type, string type_arguments, SourceReference? source_reference = null) { @@ -1361,10 +1384,7 @@ public class Vala.GirParser : CodeVisitor { if (reader.get_attribute ("glib:get-type") != null) { add_symbol_info (parse_boxed ()); } else { - var record = parse_record (); - if (record != null) { - add_symbol_info (record); - } + add_symbol_info (parse_record ()); } } else if (reader.name == "class") { add_symbol_info (parse_class ()); @@ -1804,14 +1824,22 @@ public class Vala.GirParser : CodeVisitor { return type; } - Struct? parse_record () { + Struct parse_record () { start_element ("record"); var st = new Struct (reader.get_attribute ("name"), get_current_src ()); st.external = true; + st.access = SymbolAccessibility.PUBLIC; + + string cname = reader.get_attribute ("c:type"); + if (cname != null) { + st.set_cname (cname); + } current_gtype_struct_for = reader.get_attribute ("glib:is-gtype-struct-for"); + if (current_gtype_struct_for != null) { + girdata["glib:is-gtype-struct-for"] = current_gtype_struct_for; + } - st.access = SymbolAccessibility.PUBLIC; next (); while (current_token == MarkupTokenType.START_ELEMENT) { if (!push_metadata ()) { @@ -1843,12 +1871,7 @@ public class Vala.GirParser : CodeVisitor { } end_element ("record"); - if (current_gtype_struct_for != null) { - // skip *Class or *Iface - current_gtype_struct_for = null; - return null; - } - + current_gtype_struct_for = null; return st; } @@ -1957,7 +1980,7 @@ public class Vala.GirParser : CodeVisitor { next (); end_element ("prerequisite"); } else if (reader.name == "field") { - parse_field (); + add_symbol_info (parse_field ()); } else if (reader.name == "property") { add_symbol_info (parse_property ()); } else if (reader.name == "virtual-method") { diff --git a/vala/valainterface.vala b/vala/valainterface.vala index f5f9d08a6..eef3f3fe1 100644 --- a/vala/valainterface.vala +++ b/vala/valainterface.vala @@ -331,6 +331,15 @@ public class Vala.Interface : ObjectTypeSymbol { return result; } + + /** + * Returns default string for the type struct when used in C code. + * + * @return the type struct to be used in C code + */ + public string get_default_type_cname () { + return "%sIface".printf (get_cname ()); + } /** * Sets the string to be prepended to the name of members of this @@ -495,7 +504,7 @@ public class Vala.Interface : ObjectTypeSymbol { */ public string get_type_cname () { if (type_cname == null) { - type_cname = "%sIface".printf (get_cname ()); + type_cname = get_default_type_cname (); } return type_cname; }