[vala/staging] codegen: Support gobject property of null-terminated array without length
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging] codegen: Support gobject property of null-terminated array without length
- Date: Wed, 2 Oct 2019 10:22:33 +0000 (UTC)
commit f3248c8531e1500db79f73fb01c426f7c3dfeeff
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Wed Oct 2 09:29:06 2019 +0200
codegen: Support gobject property of null-terminated array without length
Properly evaluate given array_length and array_null_terminated attributes
on properties to create the expected API.
Fixes https://gitlab.gnome.org/GNOME/vala/issues/855
codegen/valaccodebasemodule.vala | 14 +++----
codegen/valagobjectmodule.vala | 16 ++++----
codegen/valagtypemodule.vala | 8 ++--
tests/Makefile.am | 1 +
tests/objects/property-array.vala | 84 +++++++++++++++++++++++++++++++++++++++
vala/valapropertyaccessor.vala | 3 ++
vala/valasemanticanalyzer.vala | 7 +++-
7 files changed, 114 insertions(+), 19 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 012c78081..548ec58a6 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1586,7 +1586,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
function.add_parameter (cvalueparam);
}
- if (acc.value_type is ArrayType) {
+ if (acc.value_type is ArrayType && get_ccode_array_length (prop)) {
var array_type = (ArrayType) acc.value_type;
var length_ctype = get_ccode_array_length_type (array_type);
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -1680,7 +1680,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
function.add_parameter (cvalueparam);
}
- if (acc.value_type is ArrayType) {
+ if (acc.value_type is ArrayType && get_ccode_array_length (prop)) {
var array_type = (ArrayType) acc.value_type;
var length_ctype = get_ccode_array_length_type (array_type);
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -1734,7 +1734,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
vcall.add_argument (new CCodeIdentifier ("result"));
ccode.add_expression (vcall);
} else {
- if (acc.value_type is ArrayType) {
+ if (acc.value_type is ArrayType && get_ccode_array_length (prop)) {
var array_type = (ArrayType) acc.value_type;
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -1752,7 +1752,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
vcall.add_argument (new CCodeIdentifier ("self"));
vcall.add_argument (new CCodeIdentifier ("value"));
- if (acc.value_type is ArrayType) {
+ if (acc.value_type is ArrayType && get_ccode_array_length (prop)) {
var array_type = (ArrayType) acc.value_type;
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -1804,7 +1804,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
function.add_parameter (cvalueparam);
}
- if (acc.value_type is ArrayType) {
+ if (acc.value_type is ArrayType && get_ccode_array_length (prop)) {
var array_type = (ArrayType) acc.value_type;
var length_ctype = get_ccode_array_length_type (array_type);
for (int dim = 1; dim <= array_type.rank; dim++) {
@@ -1862,7 +1862,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
var get_call = new CCodeFunctionCall (new CCodeIdentifier
(get_ccode_real_name (get_accessor)));
get_call.add_argument (new CCodeIdentifier (is_virtual ? "base" :
"self"));
- if (property_type is ArrayType) {
+ if (property_type is ArrayType && get_ccode_array_length (prop)) {
ccode.add_declaration (get_ccode_array_length_type
(property_type), new CCodeVariableDeclarator ("old_value_length"));
get_call.add_argument (new CCodeUnaryExpression
(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("old_value_length")));
ccode.open_if (new CCodeBinaryExpression
(CCodeBinaryOperator.INEQUALITY, get_call, new CCodeIdentifier ("value")));
@@ -3852,7 +3852,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
// return array length if appropriate
- if (((current_method != null && get_ccode_array_length (current_method)) ||
current_property_accessor != null) && current_return_type is ArrayType) {
+ if (((current_method != null && get_ccode_array_length (current_method)) ||
(current_property_accessor != null && get_ccode_array_length (current_property_accessor.prop))) &&
current_return_type is ArrayType) {
var temp_value = store_temp_value (stmt.return_expression.target_value, stmt);
var array_type = (ArrayType) current_return_type;
diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala
index a54242882..65726fe68 100644
--- a/codegen/valagobjectmodule.vala
+++ b/codegen/valagobjectmodule.vala
@@ -263,7 +263,7 @@ public class Vala.GObjectModule : GTypeModule {
ccall = new CCodeFunctionCall (cfunc);
ccall.add_argument (cself);
var array_type = prop.property_type as ArrayType;
- if (array_type != null && array_type.element_type.type_symbol ==
string_type.type_symbol) {
+ if (array_type != null && get_ccode_array_length (prop) &&
array_type.element_type.type_symbol == string_type.type_symbol) {
// G_TYPE_STRV
ccode.open_block ();
ccode.add_declaration ("int", new CCodeVariableDeclarator ("length"));
@@ -278,7 +278,7 @@ public class Vala.GObjectModule : GTypeModule {
csetcall.add_argument (new CCodeIdentifier ("value"));
csetcall.add_argument (ccall);
add_guarded_expression (prop, csetcall);
- if (array_type != null && array_type.element_type.type_symbol ==
string_type.type_symbol) {
+ if (array_type != null && get_ccode_array_length (prop) &&
array_type.element_type.type_symbol == string_type.type_symbol) {
ccode.close ();
}
}
@@ -355,12 +355,14 @@ public class Vala.GObjectModule : GTypeModule {
ccode.add_assignment (new CCodeIdentifier ("boxed"), cgetcall);
ccall.add_argument (new CCodeIdentifier ("boxed"));
- var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new
CCodeIdentifier ("boxed"), new CCodeConstant ("NULL"));
- var cstrvlen = new CCodeFunctionCall (new CCodeIdentifier ("g_strv_length"));
- cstrvlen.add_argument (new CCodeIdentifier ("boxed"));
- var ccond = new CCodeConditionalExpression (cisnull, new CCodeConstant ("0"),
cstrvlen);
+ if (get_ccode_array_length (prop)) {
+ var cisnull = new CCodeBinaryExpression
(CCodeBinaryOperator.EQUALITY, new CCodeIdentifier ("boxed"), new CCodeConstant ("NULL"));
+ var cstrvlen = new CCodeFunctionCall (new CCodeIdentifier
("g_strv_length"));
+ cstrvlen.add_argument (new CCodeIdentifier ("boxed"));
+ var ccond = new CCodeConditionalExpression (cisnull, new
CCodeConstant ("0"), cstrvlen);
- ccall.add_argument (ccond);
+ ccall.add_argument (ccond);
+ }
add_guarded_expression (prop, ccall);
ccode.close ();
} else {
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 56bf3188d..7f05bfd7c 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -348,7 +348,7 @@ public class Vala.GTypeModule : GErrorModule {
}
var array_type = prop.property_type as ArrayType;
- if (array_type != null) {
+ if (array_type != null && get_ccode_array_length (prop)) {
var length_ctype = get_ccode_array_length_type (array_type) + "*";
for (int dim = 1; dim <= array_type.rank; dim++) {
vdeclarator.add_parameter (new CCodeParameter (get_array_length_cname
("result", dim), length_ctype));
@@ -379,7 +379,7 @@ public class Vala.GTypeModule : GErrorModule {
vdeclarator.add_parameter (cvalueparam);
var array_type = prop.property_type as ArrayType;
- if (array_type != null) {
+ if (array_type != null && get_ccode_array_length (prop)) {
var length_ctype = get_ccode_array_length_type (array_type);
for (int dim = 1; dim <= array_type.rank; dim++) {
vdeclarator.add_parameter (new CCodeParameter (get_array_length_cname
("value", dim), length_ctype));
@@ -2156,7 +2156,7 @@ public class Vala.GTypeModule : GErrorModule {
}
var array_type = prop.property_type as ArrayType;
- if (array_type != null) {
+ if (array_type != null && get_ccode_array_length (prop)) {
var length_ctype = get_ccode_array_length_type (array_type) +
"*";
for (int dim = 1; dim <= array_type.rank; dim++) {
vdeclarator.add_parameter (new CCodeParameter
(get_array_length_cname ("result", dim), length_ctype));
@@ -2179,7 +2179,7 @@ public class Vala.GTypeModule : GErrorModule {
}
var array_type = prop.property_type as ArrayType;
- if (array_type != null) {
+ if (array_type != null && get_ccode_array_length (prop)) {
var length_ctype = get_ccode_array_length_type (array_type);
for (int dim = 1; dim <= array_type.rank; dim++) {
vdeclarator.add_parameter (new CCodeParameter
(get_array_length_cname ("value", dim), length_ctype));
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3efdffbba..bc3f0773e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -321,6 +321,7 @@ TESTS = \
objects/paramspec.vala \
objects/plugin-module-init.vala \
objects/properties.vala \
+ objects/property-array.vala \
objects/property-notify.vala \
objects/property-ownership.vala \
objects/property-read-only-auto.vala \
diff --git a/tests/objects/property-array.vala b/tests/objects/property-array.vala
new file mode 100644
index 000000000..0c7eaae0c
--- /dev/null
+++ b/tests/objects/property-array.vala
@@ -0,0 +1,84 @@
+public struct Manam {
+ public int i;
+}
+
+public class Foo {
+ public Manam?[] array { get; set; }
+
+ public virtual Manam?[] array_v { get; set; }
+
+ [CCode (array_length = false, array_null_terminated = true)]
+ public Manam?[] array_no_length { get; set; }
+
+ [CCode (array_length = false, array_null_terminated = true)]
+ public virtual Manam?[] array_no_length_v { get; set; }
+
+ [CCode (array_length = false, array_null_terminated = true)]
+ public string[] strv { set; get; }
+
+ [CCode (array_length = false, array_null_terminated = true)]
+ public virtual string[] strv_v { set; get; }
+}
+
+public class Bar : Object {
+ [CCode (array_length = false, array_null_terminated = true)]
+ public Manam?[] array { get; set; }
+
+ [CCode (array_length = false, array_null_terminated = true)]
+ public virtual Manam?[] array_v { get; set; }
+
+ [CCode (array_length = false, array_null_terminated = true)]
+ public string[] strv { set; get; }
+
+ [CCode (array_length = false, array_null_terminated = true)]
+ public virtual string[] strv_v { set; get; }
+}
+
+void main () {
+ Manam?[] manam = { Manam () { i = 23 }, Manam () { i = 42 }, null };
+ string[] minim = { "foo", "bar", null };
+
+ {
+ var foo = new Foo ();
+
+ foo.array = manam;
+ assert (foo.array[0].i == 23);
+ foo.array_v = manam;
+ assert (foo.array_v[1].i == 42);
+
+ foo.array_no_length = manam;
+ assert (foo.array_no_length[0].i == 23);
+ foo.array_no_length_v = manam;
+ assert (foo.array_no_length_v[1].i == 42);
+
+ foo.strv = minim;
+ assert (foo.strv[0] == "foo");
+ foo.strv_v = minim;
+ assert (foo.strv_v[1] == "bar");
+ }
+ {
+ var bar = new Bar ();
+
+ bar.array = manam;
+ assert (bar.array[0].i == 23);
+ bar.array_v = manam;
+ assert (bar.array_v[1].i == 42);
+
+ bar.strv = minim;
+ assert (bar.strv[0] == "foo");
+ bar.strv_v = minim;
+ assert (bar.strv_v[1] == "bar");
+
+ unowned Manam?[] res;
+ bar.get ("array", out res);
+ assert (res[0].i == 23);
+ bar.get ("array-v", out res);
+ assert (res[1].i == 42);
+
+ unowned string[] strv;
+ bar.get ("strv", out strv);
+ assert (strv[0] == "foo");
+ bar.get ("strv-v", out strv);
+ assert (strv[1] == "bar");
+ }
+}
diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala
index d98aebc3a..553777afb 100644
--- a/vala/valapropertyaccessor.vala
+++ b/vala/valapropertyaccessor.vala
@@ -156,6 +156,9 @@ public class Vala.PropertyAccessor : Subroutine {
if (writable || construction) {
value_parameter = new Parameter ("value", value_type, source_reference);
+ // Inherit important atttributes
+ value_parameter.copy_attribute_bool (prop, "CCode", "array_length");
+ value_parameter.copy_attribute_bool (prop, "CCode", "array_null_terminated");
}
if (context.profile == Profile.GOBJECT
diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala
index 30c4dadf3..f9eae2b07 100644
--- a/vala/valasemanticanalyzer.vala
+++ b/vala/valasemanticanalyzer.vala
@@ -432,7 +432,12 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
}
if (!is_gobject_property_type (prop.property_type)) {
- return false;
+ if (prop.property_type is ArrayType && (!prop.get_attribute_bool ("CCode",
"array_length", true)
+ && prop.get_attribute_bool ("CCode", "array_null_terminated", false))) {
+ // null-terminated arrays without length are allowed
+ } else {
+ return false;
+ }
}
if (type_sym is Class && prop.base_interface_property != null &&
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]