[vala/staging] vala: Add DelegateType.target/destroy fields to access its user-data
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/staging] vala: Add DelegateType.target/destroy fields to access its user-data
- Date: Thu, 3 Oct 2019 13:22:54 +0000 (UTC)
commit c054da918a40f8ef93c1a006034fb6ab4717c135
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Wed Oct 2 19:07:17 2019 +0200
vala: Add DelegateType.target/destroy fields to access its user-data
Fixes https://gitlab.gnome.org/GNOME/vala/issues/857
codegen/valaccodememberaccessmodule.vala | 13 +++++++++++
tests/Makefile.am | 1 +
tests/delegates/member-target-destroy.vala | 23 +++++++++++++++++++
vala/Makefile.am | 2 ++
vala/valaassignment.vala | 2 ++
vala/valadelegatedestroyfield.vala | 36 ++++++++++++++++++++++++++++++
vala/valadelegatetargetfield.vala | 36 ++++++++++++++++++++++++++++++
vala/valadelegatetype.vala | 28 +++++++++++++++++++++++
8 files changed, 141 insertions(+)
---
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 4c0c9f009..54a71a3e2 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -113,6 +113,19 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
Report.error (expr.source_reference, "unsupported use of length field of
multi-dimensional array");
}
set_cvalue (expr, get_array_length_cexpression (expr.inner, 1));
+ } else if (expr.symbol_reference is DelegateTargetField) {
+ if (!((DelegateType) expr.inner.value_type).delegate_symbol.has_target) {
+ Report.error (expr.source_reference, "unsupported use of target field of
delegate without target");
+ }
+ CCodeExpression delegate_target_destroy_notify;
+ set_cvalue (expr, get_delegate_target_cexpression (expr.inner, out
delegate_target_destroy_notify));
+ } else if (expr.symbol_reference is DelegateDestroyField) {
+ if (!((DelegateType) expr.inner.value_type).delegate_symbol.has_target) {
+ Report.error (expr.source_reference, "unsupported use of destroy field of
delegate without target");
+ }
+ CCodeExpression delegate_target_destroy_notify;
+ get_delegate_target_cexpression (expr.inner, out delegate_target_destroy_notify);
+ set_cvalue (expr, delegate_target_destroy_notify);
} else if (expr.symbol_reference is Field) {
var field = (Field) expr.symbol_reference;
if (expr.lvalue) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d0e75c29b..b404f7af3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -277,6 +277,7 @@ TESTS = \
delegates/instance-method-to-no-target.test \
delegates/lambda-mixed-instance-static.vala \
delegates/lambda-shared-closure.vala \
+ delegates/member-target-destroy.vala \
delegates/reference_transfer.vala \
delegates/return-array-null-terminated.vala \
delegates/wrapper.vala \
diff --git a/tests/delegates/member-target-destroy.vala b/tests/delegates/member-target-destroy.vala
new file mode 100644
index 000000000..468bff95f
--- /dev/null
+++ b/tests/delegates/member-target-destroy.vala
@@ -0,0 +1,23 @@
+delegate string Foo ();
+
+string bar (string s) {
+ return s;
+}
+
+void foo_free (void* data) {
+ GLib.free (data);
+}
+
+void main () {
+ Foo foo = (Foo) bar;
+ assert (foo.target == null);
+ assert (foo.destroy == null);
+
+ string* foo_data = "foo".dup ();
+ foo.target = foo_data;
+ foo.destroy = (GLib.DestroyNotify) foo_free;
+
+ assert (foo () == "foo");
+ assert (foo.target == foo_data);
+ assert (foo.destroy == (GLib.DestroyNotify) foo_free);
+}
diff --git a/vala/Makefile.am b/vala/Makefile.am
index 7fb1e26f7..57c758fdc 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -64,6 +64,8 @@ libvala_la_VALASOURCES = \
valadatatype.vala \
valadeclarationstatement.vala \
valadelegate.vala \
+ valadelegatedestroyfield.vala \
+ valadelegatetargetfield.vala \
valadelegatetype.vala \
valadeletestatement.vala \
valadestructor.vala \
diff --git a/vala/valaassignment.vala b/vala/valaassignment.vala
index 9a4c2c97e..c2ac1a189 100644
--- a/vala/valaassignment.vala
+++ b/vala/valaassignment.vala
@@ -451,6 +451,8 @@ public class Vala.Assignment : Expression {
(local != null || param != null || field != null) &&
!is_array_add () &&
!(field is ArrayLengthField) &&
+ !(field is DelegateTargetField) &&
+ !(field is DelegateDestroyField) &&
!(left.value_type.is_real_non_null_struct_type () && right is
ObjectCreationExpression)) {
// visit_assignment not necessary
if (instance && ma.inner != null) {
diff --git a/vala/valadelegatedestroyfield.vala b/vala/valadelegatedestroyfield.vala
new file mode 100644
index 000000000..e175b172a
--- /dev/null
+++ b/vala/valadelegatedestroyfield.vala
@@ -0,0 +1,36 @@
+/* valadelegatedestroyfield.vala
+ *
+ * Copyright (C) 2019 Rico Tzschichholz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Rico Tzschichholz <ricotz ubuntu com>
+ */
+
+/**
+ * Represents the Delegate.destroy field.
+ */
+public class Vala.DelegateDestroyField : Field {
+ /**
+ * Creates a new delegate destroy field.
+ *
+ * @return newly created field
+ */
+ public DelegateDestroyField (SourceReference source_reference) {
+ base ("destroy", CodeContext.get ().analyzer.delegate_target_destroy_type, null,
source_reference);
+ external = true;
+ }
+}
diff --git a/vala/valadelegatetargetfield.vala b/vala/valadelegatetargetfield.vala
new file mode 100644
index 000000000..6f3782782
--- /dev/null
+++ b/vala/valadelegatetargetfield.vala
@@ -0,0 +1,36 @@
+/* valadelegatetargetfield.vala
+ *
+ * Copyright (C) 2019 Rico Tzschichholz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Rico Tzschichholz <ricotz ubuntu com>
+ */
+
+/**
+ * Represents the Delegate.target field.
+ */
+public class Vala.DelegateTargetField : Field {
+ /**
+ * Creates a new delegate target field.
+ *
+ * @return newly created field
+ */
+ public DelegateTargetField (SourceReference source_reference) {
+ base ("target", new PointerType (new VoidType ()), null, source_reference);
+ external = true;
+ }
+}
diff --git a/vala/valadelegatetype.vala b/vala/valadelegatetype.vala
index 539b53050..2c5efb911 100644
--- a/vala/valadelegatetype.vala
+++ b/vala/valadelegatetype.vala
@@ -34,11 +34,39 @@ public class Vala.DelegateType : CallableType {
public bool is_called_once { get; set; }
+ DelegateTargetField? target_field;
+ DelegateDestroyField? destroy_field;
+
public DelegateType (Delegate delegate_symbol) {
base (delegate_symbol);
this.is_called_once = (delegate_symbol.get_attribute_string ("CCode", "scope") == "async");
}
+ public override Symbol? get_member (string member_name) {
+ if (member_name == "target") {
+ return get_target_field ();
+ } else if (member_name == "destroy") {
+ return get_destroy_field ();
+ }
+ return null;
+ }
+
+ unowned DelegateTargetField get_target_field () {
+ if (target_field == null) {
+ target_field = new DelegateTargetField (source_reference);
+ target_field.access = SymbolAccessibility.PUBLIC;
+ }
+ return target_field;
+ }
+
+ unowned DelegateDestroyField get_destroy_field () {
+ if (destroy_field == null) {
+ destroy_field = new DelegateDestroyField (source_reference);
+ destroy_field.access = SymbolAccessibility.PUBLIC;
+ }
+ return destroy_field;
+ }
+
public override DataType copy () {
var result = new DelegateType (delegate_symbol);
result.source_reference = source_reference;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]