From: Rico Tzschichholz Date: Wed, 30 Aug 2017 19:10:09 +0000 (+0200) Subject: codegen: Add support for "type-func" in ui-files X-Git-Tag: 0.38.0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f778ba49312c6a026cab6fee9babd8c73aaa532d;p=thirdparty%2Fvala.git codegen: Add support for "type-func" in ui-files If "type-func" attribute is given then prefer it over "class" if matching it to a known object is possible. https://bugzilla.gnome.org/show_bug.cgi?id=787033 --- diff --git a/codegen/valagtkmodule.vala b/codegen/valagtkmodule.vala index 5d8787092..6ef3766c2 100644 --- a/codegen/valagtkmodule.vala +++ b/codegen/valagtkmodule.vala @@ -23,6 +23,8 @@ public class Vala.GtkModule : GSignalModule { + /* C type-func name to Vala class mapping */ + private HashMap type_id_to_vala_map = null; /* C class name to Vala class mapping */ private HashMap cclass_to_vala_map = null; /* GResource name to real file name mapping */ @@ -34,6 +36,36 @@ public class Vala.GtkModule : GSignalModule { /* Required custom application-specific gtype classes to be ref'd before initializing the template */ private List current_required_app_classes = new ArrayList(); + private void ensure_type_id_to_vala_map () { + // map C type-func name of gtypeinstance classes to Vala classes + if (type_id_to_vala_map != null) { + return; + } + type_id_to_vala_map = new HashMap(str_hash, str_equal); + recurse_type_id_to_vala_map (context.root); + } + + private void recurse_type_id_to_vala_map (Namespace ns) { + foreach (var cl in ns.get_classes()) { + if (!cl.is_compact) { + var type_id = get_ccode_type_id (cl); + if (type_id == null) + continue; + + var i = type_id.index_of_char ('('); + if (i > 0) { + type_id = type_id.substring (0, i - 1).strip (); + } else { + type_id = type_id.strip (); + } + type_id_to_vala_map.set (type_id, cl); + } + } + foreach (var inner in ns.get_namespaces()) { + recurse_type_id_to_vala_map (inner); + } + } + private void ensure_cclass_to_vala_map () { // map C name of gtypeinstance classes to Vala classes if (cclass_to_vala_map != null) { @@ -96,6 +128,7 @@ public class Vala.GtkModule : GSignalModule { private void process_current_ui_resource (string ui_resource, CodeNode node) { /* Scan a single gtkbuilder file for signal handlers in elements, and save an handler string -> Vala.Signal mapping for each of them */ + ensure_type_id_to_vala_map (); ensure_cclass_to_vala_map(); ensure_gresource_to_file_map(); @@ -116,20 +149,36 @@ public class Vala.GtkModule : GSignalModule { bool template_tag_found = false; MarkupTokenType current_token = reader.read_token (null, null); while (current_token != MarkupTokenType.EOF) { - if (current_token == MarkupTokenType.START_ELEMENT && (reader.name == "template" || reader.name == "object")) { - if (reader.name == "template") { + unowned string current_name = reader.name; + if (current_token == MarkupTokenType.START_ELEMENT && (current_name == "object" || current_name == "template")) { + current_class = null; + + if (current_name == "object") { + var type_id = reader.get_attribute ("type-func"); + if (type_id != null) { + current_class = type_id_to_vala_map.get (type_id); + } + } else if (current_name == "template") { template_tag_found = true; } - var class_name = reader.get_attribute ("class"); - if (class_name != null) { + + if (current_class == null) { + var class_name = reader.get_attribute ("class"); + if (class_name == null) { + Report.error (node.source_reference, "Invalid %s in ui file `%s'".printf (current_name, ui_file)); + current_token = reader.read_token (null, null); + continue; + } current_class = cclass_to_vala_map.get (class_name); + } + if (current_class != null) { var child_name = reader.get_attribute ("id"); if (child_name != null) { current_child_to_class_map.set (child_name, current_class); } } - } else if (current_class != null && current_token == MarkupTokenType.START_ELEMENT && reader.name == "signal") { + } else if (current_class != null && current_token == MarkupTokenType.START_ELEMENT && current_name == "signal") { var signal_name = reader.get_attribute ("name"); var handler_name = reader.get_attribute ("handler");