diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2021-01-14 17:55:34 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2021-01-14 17:55:34 +0100 |
commit | 34e96b785871497249a705260b8c694f7180a256 (patch) | |
tree | 87a548a523aa97f0cb8e5ce85c9bd2c7fad78d0b | |
parent | 5db0ee14afe1f9ece272a56745864e81aafa294a (diff) | |
download | vala-34e96b785871497249a705260b8c694f7180a256.tar.gz |
girparser: Handle anonymous delegate not backed by virtual-method or signal
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/gir/delegate-anonymous.test | 35 | ||||
-rw-r--r-- | vala/valagirparser.vala | 22 |
3 files changed, 58 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index bd4b19daa..bca714521 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -696,6 +696,7 @@ TESTS = \ gir/class.test \ gir/constant.test \ gir/delegate-alias-without-target.test \ + gir/delegate-anonymous.test \ gir/delegate-array-length-type.test \ gir/delegate-closure-destroy-index-conflict.test \ gir/delegate-error-pos.test \ diff --git a/tests/gir/delegate-anonymous.test b/tests/gir/delegate-anonymous.test new file mode 100644 index 000000000..0c4fd1626 --- /dev/null +++ b/tests/gir/delegate-anonymous.test @@ -0,0 +1,35 @@ +GIR + +Input: + +<record name="Foo" c:type="TestFoo"> + <field name="bar_callback"> + <callback name="bar_callback" throws="1"> + <return-value transfer-ownership="none"> + <type name="gpointer" c:type="gpointer"/> + </return-value> + <parameters> + <parameter name="func" + transfer-ownership="none" + closure="1"> + <type name="GLib.SourceFunc" c:type="GSourceFunc"/> + </parameter> + <parameter name="user_data" + transfer-ownership="none" + nullable="1" + allow-none="1"> + <type name="gpointer" c:type="gpointer"/> + </parameter> + </parameters> + </callback> + </field> +</record> + +Output: + +[CCode (cheader_filename = "test.h", has_type_id = false)] +public struct Foo { + public weak Test.FooBarCallbackFunc bar_callback; +} +[CCode (cheader_filename = "test.h", has_target = false, has_typedef = false)] +public delegate void* FooBarCallbackFunc (GLib.SourceFunc func) throws GLib.Error; diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala index 65de9ea85..cdea30f2a 100644 --- a/vala/valagirparser.vala +++ b/vala/valagirparser.vala @@ -1136,6 +1136,17 @@ public class Vala.GirParser : CodeVisitor { var d = ((DelegateType) field.variable_type).delegate_symbol; parser.process_virtual_method_field (this, d, parent.gtype_struct_for); merged = true; + } else if (field.variable_type is DelegateType) { + // anonymous delegate + var d = ((DelegateType) field.variable_type).delegate_symbol; + if (this.lookup (d.name).parent == this) { + d.set_attribute_bool ("CCode", "has_typedef", false); + if (d.has_target && !metadata.has_argument (ArgumentType.DELEGATE_TARGET)) { + field.set_attribute_bool ("CCode", "delegate_target", false); + } + d.name = "%s%sFunc".printf (parent.symbol.name, Symbol.lower_case_to_camel_case (d.name)); + get_parent_namespace (this).add_delegate (d); + } } else if (field.variable_type is ArrayType) { Node array_length; if (metadata.has_argument (ArgumentType.ARRAY_LENGTH_FIELD)) { @@ -1598,6 +1609,17 @@ public class Vala.GirParser : CodeVisitor { return sym is ObjectTypeSymbol || sym is Struct || sym is Namespace || sym is ErrorDomain || sym is Enum; } + static unowned Namespace get_parent_namespace (Node node) { + unowned Node? n = node.parent; + while (n != null) { + if (n.symbol is Namespace) { + return (Namespace) n.symbol; + } + n = n.parent; + } + assert_not_reached (); + } + UnresolvedSymbol? parse_symbol_from_string (string symbol_string, SourceReference? source_reference = null) { UnresolvedSymbol? sym = null; foreach (unowned string s in symbol_string.split (".")) { |