[vala/staging] Add further support for params arrays in constructors
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging] Add further support for params arrays in constructors
- Date: Thu, 28 Jan 2021 16:48:27 +0000 (UTC)
commit 932965b4e630e78ebff50bad95dcff6494832a19
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Thu Jan 28 12:12:53 2021 +0100
Add further support for params arrays in constructors
In addition to 98ab3da89640b8b8a6c67044b4df1194672774bb
See https://gitlab.gnome.org/GNOME/vala/issues/128
codegen/valaccodearraymodule.vala | 16 +++++---
codegen/valaccodebasemodule.vala | 2 +-
codegen/valaccodemethodmodule.vala | 17 ++++++--
tests/Makefile.am | 2 +
tests/methods/params-array.vala | 45 ++++++++++++++++++++++
.../params-array-objectcreation-multiple.test | 9 +++++
.../params-array-objectcreation-struct-length.test | 14 +++++++
vala/valacreationmethod.vala | 25 ++++++++++++
vala/valamethod.vala | 2 +-
vala/valaobjectcreationexpression.vala | 14 ++++++-
10 files changed, 134 insertions(+), 12 deletions(-)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 9fac7349e..b2b2e7e1e 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -879,7 +879,8 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
return main_cparam;
}
- public override void append_params_array (LocalVariable local) {
+ public override void append_params_array (Method m) {
+ var local = m.params_array_var;
var array_type = (ArrayType) local.variable_type;
var local_length = new LocalVariable (array_type.length_type.copy (), get_array_length_cname
(local.name, 1), null, local.source_reference);
@@ -913,11 +914,14 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
if (context.profile == Profile.POSIX) {
cfile.add_include ("stdarg.h");
}
- ccode.add_declaration ("va_list", new CCodeVariableDeclarator ("_va_list_%s".printf
(get_ccode_name (local))));
- var vastart = new CCodeFunctionCall (new CCodeIdentifier ("va_start"));
- vastart.add_argument (new CCodeIdentifier ("_va_list_%s".printf (get_ccode_name (local))));
- vastart.add_argument (new CCodeIdentifier ("_first_%s".printf (get_ccode_name (local))));
- ccode.add_expression (vastart);
+
+ if (!(m is CreationMethod)) {
+ ccode.add_declaration ("va_list", new CCodeVariableDeclarator ("_va_list_%s".printf
(get_ccode_name (local))));
+ var vastart = new CCodeFunctionCall (new CCodeIdentifier ("va_start"));
+ vastart.add_argument (new CCodeIdentifier ("_va_list_%s".printf (get_ccode_name
(local))));
+ vastart.add_argument (new CCodeIdentifier ("_first_%s".printf (get_ccode_name
(local))));
+ ccode.add_expression (vastart);
+ }
ccode.add_assignment (get_local_cexpression (element), new CCodeIdentifier
("_first_%s".printf (get_ccode_name (local))));
ccode.open_while (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY,
get_local_cexpression (element), new CCodeConstant ("NULL")));
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 0c872775e..9f570049b 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -717,7 +717,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
public virtual void append_vala_array_length () {
}
- public virtual void append_params_array (LocalVariable local) {
+ public virtual void append_params_array (Method m) {
}
public void append_vala_clear_mutex (string typename, string funcprefix) {
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index c14d76120..ae05c917a 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -539,7 +539,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
foreach (Parameter param in m.get_parameters ()) {
if (param.ellipsis || param.params_array) {
if (param.params_array) {
- append_params_array (m.params_array_var);
+ append_params_array (m);
}
break;
}
@@ -885,6 +885,8 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
cparam.modifiers = CCodeModifiers.FORMAT_ARG;
}
} else {
+ var va_list_name = "_vala_va_list";
+
// Add _first_* parameter for the params array parameter
if (param.params_array) {
var param_type = ((ArrayType) param.variable_type).element_type;
@@ -908,10 +910,12 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
cparam = new CCodeParameter ("_first_%s".printf (get_ccode_name (param)),
ctypename);
cparam_map.set (get_param_pos (get_ccode_pos (param), false), cparam);
+
+ va_list_name = "_va_list_%s".printf (get_ccode_name (param));
}
if (ellipses_to_valist) {
- cparam = new CCodeParameter ("_vala_va_list", "va_list");
+ cparam = new CCodeParameter (va_list_name, "va_list");
} else {
cparam = new CCodeParameter.with_ellipsis ();
}
@@ -1287,9 +1291,16 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
}
}
+ var carg = carg_map.get (second_last_pos);
+ if (carg == null) {
+ // params arrays have an implicit first argument, refer to the cparameter name
+ carg = new CCodeIdentifier (cparam_map.get (second_last_pos).name);
+ vcall.add_argument (carg);
+ }
+
var va_start = new CCodeFunctionCall (new CCodeIdentifier ("va_start"));
va_start.add_argument (new CCodeIdentifier ("_vala_va_list_obj"));
- va_start.add_argument (carg_map.get (second_last_pos));
+ va_start.add_argument (carg);
ccode.add_declaration ("va_list", new CCodeVariableDeclarator ("_vala_va_list_obj"));
ccode.add_expression (va_start);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a46e47193..cadc9cb98 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1008,6 +1008,8 @@ TESTS = \
semantic/parameter-ref-default.test \
semantic/parameter-void.test \
semantic/params-array-multiple.test \
+ semantic/params-array-objectcreation-multiple.test \
+ semantic/params-array-objectcreation-struct-length.test \
semantic/params-array-struct-length.test \
semantic/pointer-indirection-type-not-supported.test \
semantic/pointer-indirection-void-not-supported.test \
diff --git a/tests/methods/params-array.vala b/tests/methods/params-array.vala
index 3c76d7048..12339e7d2 100644
--- a/tests/methods/params-array.vala
+++ b/tests/methods/params-array.vala
@@ -1,3 +1,40 @@
+class Foo {
+ public Foo (params string[] strv) {
+ assert (strv.length == 3);
+ assert (strv[0] == "foo");
+ assert (strv[1] == "bar");
+ assert (strv[2] == "manam");
+ }
+
+ public Foo.bar (params int[] intv) {
+ assert (intv.length == 3);
+ assert (intv[0] == 23);
+ assert (intv[1] == 42);
+ assert (intv[2] == 4711);
+ }
+
+ public Foo.manam (params Value?[] valuev) {
+ assert (valuev.length == 3);
+ assert (valuev[0] == "foo");
+ assert (valuev[1] == 4711);
+ assert (valuev[2] == 3.1415);
+ }
+
+ public Foo.manam_owned (params owned Value?[] valuev) {
+ assert (valuev.length == 3);
+ assert (valuev[0] == "foo");
+ assert (valuev[1] == 4711);
+ assert (valuev[2] == 3.1415);
+ }
+
+ public Foo.minim (params Variant[] variantv) {
+ assert (variantv.length == 3);
+ assert ((string) variantv[0] == "foo");
+ assert ((int) variantv[1] == 4711);
+ assert ((double) variantv[2] == 3.1415);
+ }
+}
+
void foo (params string[] strv) {
assert (strv.length == 3);
assert (strv[0] == "foo");
@@ -34,6 +71,14 @@ void minim (params Variant[] variantv) {
}
void main () {
+ Foo f;
+
+ f = new Foo ("foo", "bar", "manam");
+ f = new Foo.bar (23, 42, 4711);
+ f = new Foo.manam ("foo", 4711, 3.1415);
+ f = new Foo.manam_owned ("foo", 4711, 3.1415);
+ f = new Foo.minim ("foo", 4711, 3.1415);
+
foo ("foo", "bar", "manam");
bar (23, 42, 4711);
manam ("foo", 4711, 3.1415);
diff --git a/tests/semantic/params-array-objectcreation-multiple.test
b/tests/semantic/params-array-objectcreation-multiple.test
new file mode 100644
index 000000000..b128e92d0
--- /dev/null
+++ b/tests/semantic/params-array-objectcreation-multiple.test
@@ -0,0 +1,9 @@
+Invalid Code
+
+class Foo {
+ public Foo (params string[] strv, params int[] intv) {
+ }
+}
+
+void main () {
+}
diff --git a/tests/semantic/params-array-objectcreation-struct-length.test
b/tests/semantic/params-array-objectcreation-struct-length.test
new file mode 100644
index 000000000..b4cd0016e
--- /dev/null
+++ b/tests/semantic/params-array-objectcreation-struct-length.test
@@ -0,0 +1,14 @@
+Invalid Code
+
+struct Foo {
+ public int i;
+ public string s;
+}
+
+class Bar {
+ public Bar (params Foo foov[3]) {
+ }
+}
+
+void main () {
+}
diff --git a/vala/valacreationmethod.vala b/vala/valacreationmethod.vala
index c5a98dc08..77b311f31 100644
--- a/vala/valacreationmethod.vala
+++ b/vala/valacreationmethod.vala
@@ -115,6 +115,31 @@ public class Vala.CreationMethod : Method {
Report.error (param.source_reference, "Named parameter required before
`...'");
}
i++;
+
+ // Add local variable to provide access to params arrays which will be constructed
out of the given va-args
+ if (param.params_array && body != null) {
+ if (params_array_var != null) {
+ error = true;
+ Report.error (param.source_reference, "Only one params-array
parameter is allowed");
+ continue;
+ }
+ if (!context.experimental) {
+ Report.warning (param.source_reference, "Support of params-arrays is
experimental");
+ }
+ var type = (ArrayType) param.variable_type.copy ();
+ type.element_type.value_owned = type.value_owned;
+ type.value_owned = true;
+ if (type.element_type.is_real_struct_type () && !type.element_type.nullable) {
+ error = true;
+ Report.error (param.source_reference, "Only nullable struct elements
are supported in params-array");
+ }
+ if (type.length != null) {
+ error = true;
+ Report.error (param.source_reference, "Passing length to params-array
is not supported yet");
+ }
+ params_array_var = new LocalVariable (type, param.name, null,
param.source_reference);
+ body.insert_statement (0, new DeclarationStatement (params_array_var,
param.source_reference));
+ }
}
if (error_types != null) {
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 335bf4224..4a76c5d39 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -175,7 +175,7 @@ public class Vala.Method : Subroutine, Callable {
}
}
- public LocalVariable? params_array_var { get; private set; }
+ public LocalVariable? params_array_var { get; protected set; }
public weak Signal signal_reference { get; set; }
diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala
index 62e7b105e..1f792f30c 100644
--- a/vala/valaobjectcreationexpression.vala
+++ b/vala/valaobjectcreationexpression.vala
@@ -387,6 +387,18 @@ public class Vala.ObjectCreationExpression : Expression, CallableExpression {
break;
}
+ if (param.params_array) {
+ var array_type = (ArrayType) param.variable_type;
+ while (arg_it.next ()) {
+ Expression arg = arg_it.get ();
+
+ /* store expected type for callback parameters */
+ arg.target_type = array_type.element_type;
+ arg.target_type.value_owned = array_type.value_owned;
+ }
+ break;
+ }
+
if (arg_it.next ()) {
Expression arg = arg_it.get ();
@@ -415,7 +427,7 @@ public class Vala.ObjectCreationExpression : Expression, CallableExpression {
// recreate iterator and skip to right position
arg_it = argument_list.iterator ();
foreach (Parameter param in m.get_parameters ()) {
- if (param.ellipsis) {
+ if (param.ellipsis || param.params_array) {
break;
}
arg_it.next ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]