[vala/staging] codegen: Support chain up to simple generics constructor
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging] codegen: Support chain up to simple generics constructor
- Date: Wed, 30 Dec 2020 14:08:44 +0000 (UTC)
commit 189c9093115802bb3b6170f280393076660d0097
Author: Simon Werbeck <simon werbeck gmail com>
Date: Tue Mar 24 16:47:18 2020 +0100
codegen: Support chain up to simple generics constructor
This allows subclassing bindings like GLib.HashTable and GLib.Sequence
that require implicit DestroyNotify parameters to chain up.
Fixes https://gitlab.gnome.org/GNOME/vala/issues/342
codegen/valaccodebasemodule.vala | 26 +++++++++++++-------------
codegen/valaccodemethodcallmodule.vala | 15 +++++++++++++--
tests/Makefile.am | 1 +
tests/objects/simple-generics-chainup.vala | 29 +++++++++++++++++++++++++++++
4 files changed, 56 insertions(+), 15 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 393bb16ff..b1f7e6869 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -4744,9 +4744,19 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
public virtual void generate_error_domain_declaration (ErrorDomain edomain, CCodeFile decl_space) {
}
- public void add_generic_type_arguments (Map<int,CCodeExpression> arg_map, List<DataType> type_args,
CodeNode expr, bool is_chainup = false, List<TypeParameter>? type_parameters = null) {
+ public void add_generic_type_arguments (Method m, Map<int,CCodeExpression> arg_map, List<DataType>
type_args, CodeNode expr, bool is_chainup = false, List<TypeParameter>? type_parameters = null) {
int type_param_index = 0;
foreach (var type_arg in type_args) {
+ if (get_ccode_simple_generics (m)) {
+ if (requires_copy (type_arg)) {
+ arg_map.set (get_param_pos (-1 + 0.1 * type_param_index + 0.03),
get_destroy0_func_expression (type_arg, is_chainup));
+ } else {
+ arg_map.set (get_param_pos (-1 + 0.1 * type_param_index + 0.03), new
CCodeConstant ("NULL"));
+ }
+ type_param_index++;
+ continue;
+ }
+
if (type_parameters != null) {
var type_param_name = type_parameters.get (type_param_index).name.ascii_down
().replace ("_", "-");
arg_map.set (get_param_pos (0.1 * type_param_index + 0.01), new CCodeConstant
("\"%s-type\"".printf (type_param_name)));
@@ -4898,18 +4908,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
out_arg_map.set (get_param_pos (get_ccode_async_result_pos (m)), new
CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_res_"));
}
- if (cl != null && !cl.is_compact) {
- add_generic_type_arguments (in_arg_map,
expr.type_reference.get_type_arguments (), expr);
- } else if (cl != null && get_ccode_simple_generics (m)) {
- int type_param_index = 0;
- foreach (var type_arg in expr.type_reference.get_type_arguments ()) {
- if (requires_copy (type_arg)) {
- in_arg_map.set (get_param_pos (-1 + 0.1 * type_param_index +
0.03), get_destroy0_func_expression (type_arg));
- } else {
- in_arg_map.set (get_param_pos (-1 + 0.1 * type_param_index +
0.03), new CCodeConstant ("NULL"));
- }
- type_param_index++;
- }
+ if (cl != null && (!cl.is_compact || get_ccode_simple_generics (m))) {
+ add_generic_type_arguments (m, in_arg_map,
expr.type_reference.get_type_arguments (), expr);
}
bool ellipsis = false;
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index bf99ee011..74e22fb64 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -151,7 +151,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
// gobject-style chainup
type_parameters = ((Class)
base_type.type_symbol).get_type_parameters ();
}
- add_generic_type_arguments (in_arg_map,
base_type.get_type_arguments (), expr, true, type_parameters);
+ add_generic_type_arguments (m, in_arg_map,
base_type.get_type_arguments (), expr, true, type_parameters);
break;
}
}
@@ -181,13 +181,24 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
csizeof.add_argument (new CCodeIdentifier (get_ccode_name (current_class)));
ccall.add_argument (csizeof);
+ } else if (current_class.base_class != null && get_ccode_simple_generics (m)) {
+ if (current_class != m.parent_symbol) {
+ foreach (DataType base_type in current_class.get_base_types ()) {
+ if (base_type.type_symbol is Class) {
+ add_generic_type_arguments (m, in_arg_map,
base_type.get_type_arguments (), expr);
+ break;
+ }
+ }
+ } else {
+ // TODO: simple generics are only supported in bindings.
+ }
}
} else if (m is CreationMethod && m.parent_symbol is Struct) {
ccall.add_argument (get_this_cexpression ());
} else if (m != null && m.has_type_parameters () && !get_ccode_has_generic_type_parameter (m)
&& !get_ccode_simple_generics (m) && (ccall != finish_call || expr.is_yield_expression)) {
// generic method
// don't add generic arguments for .end() calls
- add_generic_type_arguments (in_arg_map, ma.get_type_arguments (), expr);
+ add_generic_type_arguments (m, in_arg_map, ma.get_type_arguments (), expr);
}
// the complete call expression, might include casts, comma expressions, and/or assignments
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 67ec8aeb7..517d5746a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -482,6 +482,7 @@ TESTS = \
objects/signals-prototype-access-invalid.test \
objects/signals-prototype-access-invalid-2.test \
objects/signals-struct-return.vala \
+ objects/simple-generics-chainup.vala \
objects/singleton.vala \
objects/type-narrowing.vala \
objects/type-narrowing-fallback.vala \
diff --git a/tests/objects/simple-generics-chainup.vala b/tests/objects/simple-generics-chainup.vala
new file mode 100644
index 000000000..6cfd02311
--- /dev/null
+++ b/tests/objects/simple-generics-chainup.vala
@@ -0,0 +1,29 @@
+class IntSequence : Sequence<int> {
+}
+
+class StringSequence : Sequence<string> {
+}
+
+class StringIntMap : HashTable<string,int> {
+ public StringIntMap () {
+ base (str_hash, str_equal);
+ }
+}
+
+void main () {
+ {
+ var seq = new IntSequence ();
+ seq.append (23);
+ assert (seq.get_begin_iter ().get () == 23);
+ }
+ {
+ var seq = new StringSequence ();
+ seq.append ("foo");
+ assert (seq.get_begin_iter ().get () == "foo");
+ }
+ {
+ var map = new StringIntMap ();
+ map["foo"] = 42;
+ assert (map["foo"] == 42);
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]