summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2017-03-12 20:32:26 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2017-03-14 10:27:38 +0100
commitf6e29bd10dd5c3cd1e222b78ce107d4921769452 (patch)
tree44bbadebb13c4ffeb2329b981c9dc1f25ebd5964
parentaf239ed5a14ff288770627f1a789ec829cb03afd (diff)
downloadvala-f6e29bd10dd5c3cd1e222b78ce107d4921769452.tar.gz
signalmodule: Handle nullable ValueTypes properly and treat them as pointer
Nullable value-types are actually pointers to heap-allocated structures. Therefore a pointer-based marshaller is required for those types. https://bugzilla.gnome.org/show_bug.cgi?id=758816
-rw-r--r--codegen/valagsignalmodule.vala22
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/objects/bug758816.vala70
3 files changed, 91 insertions, 2 deletions
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index 9eb567cd1..00c06c196 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -36,7 +36,11 @@ public class Vala.GSignalModule : GObjectModule {
}
}
- ret = "%s_%s_".printf (prefix, get_ccode_marshaller_type_name (return_type));
+ if (return_type is ValueType && return_type.nullable) {
+ ret = "%s_POINTER_".printf (prefix);
+ } else {
+ ret = "%s_%s_".printf (prefix, get_ccode_marshaller_type_name (return_type));
+ }
if (params == null || params.size == 0) {
ret = ret + "_VOID";
@@ -58,6 +62,8 @@ public class Vala.GSignalModule : GObjectModule {
return "const char*";
} else if (t.data_type is Class || t.data_type is Interface) {
return "gpointer";
+ } else if (t is ValueType && t.nullable) {
+ return "gpointer";
} else if (t.data_type is Struct) {
var st = (Struct) t.data_type;
if (st.is_simple_type ()) {
@@ -87,7 +93,11 @@ public class Vala.GSignalModule : GObjectModule {
private string get_marshaller_signature (List<Parameter> params, DataType return_type) {
string signature;
- signature = "%s:".printf (get_ccode_marshaller_type_name (return_type));
+ if (return_type is ValueType && return_type.nullable) {
+ signature = "POINTER:";
+ } else {
+ signature = "%s:".printf (get_ccode_marshaller_type_name (return_type));
+ }
if (params == null || params.size == 0) {
signature = signature + "VOID";
} else {
@@ -283,6 +293,8 @@ public class Vala.GSignalModule : GObjectModule {
get_value_function = "g_value_get_pointer";
} else if (p.variable_type is ErrorType) {
get_value_function = "g_value_get_pointer";
+ } else if (p.variable_type is ValueType && p.variable_type.nullable) {
+ get_value_function = "g_value_get_pointer";
} else {
get_value_function = get_ccode_get_value_function (p.variable_type.data_type);
}
@@ -319,6 +331,8 @@ public class Vala.GSignalModule : GObjectModule {
set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_string"));
} else if (return_type.data_type is Class || return_type.data_type is Interface) {
set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_take_object"));
+ } else if (return_type is ValueType && return_type.nullable) {
+ set_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_set_pointer"));
} else {
set_fc = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_set_value_function (return_type.data_type)));
}
@@ -398,6 +412,8 @@ public class Vala.GSignalModule : GObjectModule {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else if (sig.return_type is ErrorType) {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
+ } else if (sig.return_type is ValueType && sig.return_type.nullable) {
+ csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else if (sig.return_type.data_type == null) {
csignew.add_argument (new CCodeConstant ("G_TYPE_NONE"));
} else {
@@ -427,6 +443,8 @@ public class Vala.GSignalModule : GObjectModule {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else if (param.variable_type is ErrorType) {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
+ } else if (param.variable_type is ValueType && param.variable_type.nullable) {
+ csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else {
csignew.add_argument (new CCodeConstant (get_ccode_type_id (param.variable_type.data_type)));
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b1d3ea299..6a50505bb 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -206,6 +206,7 @@ TESTS = \
objects/bug702736.vala \
objects/bug702846.vala \
objects/bug751338.vala \
+ objects/bug758816.vala \
objects/bug760031.test \
objects/bug764481.vala \
objects/bug767092.test \
diff --git a/tests/objects/bug758816.vala b/tests/objects/bug758816.vala
new file mode 100644
index 000000000..733d004e1
--- /dev/null
+++ b/tests/objects/bug758816.vala
@@ -0,0 +1,70 @@
+enum Bar {
+ FAIL,
+ FOO,
+ BAR,
+ BAZ
+}
+
+public struct Manam {
+ public int i;
+ public int j;
+}
+
+class Foo : Object {
+ public signal Bar? bar ();
+ public signal Bar? bar2 (Bar? bar);
+
+ public signal Manam? manam ();
+ public signal Manam? manam2 (Manam? manam);
+
+ public void emit_bar () {
+ assert (bar () == Bar.FOO);
+ }
+
+ public void emit_bar2 () {
+ assert (bar2 (Bar.BAZ) == Bar.BAZ);
+ }
+
+ public void emit_manam () {
+ Manam? m = {23, 42};
+ assert (manam () == m);
+ }
+
+ public void emit_manam2 () {
+ Manam? m = {23, 42};
+ assert (manam2 ({23, 42}) == m);
+ }
+}
+
+Bar? callback_bar () {
+ return Bar.FOO;
+}
+
+Bar? callback_bar2 (Bar? bar) {
+ assert (bar == Bar.BAZ);
+ return bar;
+}
+
+Manam? callback_manam () {
+ return {23, 42};
+}
+
+Manam? callback_manam2 (Manam? manam) {
+ Manam? m = {23, 42};
+ assert (manam == m);
+ return manam;
+}
+
+void main () {
+ var foo = new Foo ();
+
+ foo.bar.connect (callback_bar);
+ foo.emit_bar ();
+ foo.bar2.connect (callback_bar2);
+ foo.emit_bar2 ();
+
+ foo.manam.connect (callback_manam);
+ foo.emit_manam ();
+ foo.manam2.connect (callback_manam2);
+ foo.emit_manam2 ();
+}