[vala/0.46] codegen: Use G_TYPE_INSTANCE_GET_INTERFACE to get vtable for base-access
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/0.46] codegen: Use G_TYPE_INSTANCE_GET_INTERFACE to get vtable for base-access
- Date: Wed, 30 Oct 2019 07:44:34 +0000 (UTC)
commit 9863d3dec36984dbce550c8c45cd932ebcd72275
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Thu Oct 17 14:04:15 2019 +0200
codegen: Use G_TYPE_INSTANCE_GET_INTERFACE to get vtable for base-access
Usage of the pre-assigned *_parent_iface field is only possible in classes
which explicitly implement an interface.
codegen/valaccodebasemodule.vala | 20 ++++++++++++++++--
codegen/valaccodememberaccessmodule.vala | 8 ++++----
codegen/valaccodemethodcallmodule.vala | 6 +++---
tests/Makefile.am | 3 +++
tests/objects/interface-async-base-access.vala | 25 +++++++++++++++++++++++
tests/objects/interface-base-access.vala | 25 +++++++++++++++++++++++
tests/objects/interface-property-base-access.vala | 20 ++++++++++++++++++
vala/valaclass.vala | 20 +++++++++++++-----
8 files changed, 113 insertions(+), 14 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 750257d33..fccc80dbe 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2395,6 +2395,22 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
return get_cexpression ("self");
}
+ public CCodeExpression get_this_interface_cexpression (Interface iface) {
+ if (current_class.implements (iface)) {
+ return new CCodeIdentifier ("%s_%s_parent_iface".printf (get_ccode_lower_case_name
(current_class), get_ccode_lower_case_name (iface)));
+ }
+
+ if (!current_class.is_a (iface)) {
+ Report.warning (current_class.source_reference, "internal: `%s' is not a `%s'".printf
(current_class.get_full_name (), iface.get_full_name ()));
+ }
+
+ var vcast = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_INSTANCE_GET_INTERFACE"));
+ vcast.add_argument (get_this_cexpression ());
+ vcast.add_argument (new CCodeIdentifier (get_ccode_type_id (iface)));
+ vcast.add_argument (new CCodeIdentifier (get_ccode_type_name (iface)));
+ return vcast;
+ }
+
public CCodeExpression get_inner_error_cexpression () {
return get_cexpression ("_inner_error%d_".printf (current_inner_error_id));
}
@@ -6165,9 +6181,9 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
ccode.add_expression (ccall);
} else if (prop.base_interface_property != null) {
var base_iface = (Interface) prop.base_interface_property.parent_symbol;
- string parent_iface_var = "%s_%s_parent_iface".printf
(get_ccode_lower_case_name (current_class), get_ccode_lower_case_name (base_iface));
+ var vcast = get_this_interface_cexpression (base_iface);
- var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new
CCodeIdentifier (parent_iface_var), "set_%s".printf (prop.name)));
+ var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast,
"set_%s".printf (prop.name)));
ccall.add_argument ((CCodeExpression) get_ccodenode (instance));
var cexpr = get_cvalue_ (value);
if (prop.property_type.is_real_non_null_struct_type ()) {
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 8fb01eaa6..2359f4ba8 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -58,9 +58,9 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
return;
} else if (m.base_interface_method != null) {
var base_iface = (Interface) m.base_interface_method.parent_symbol;
- string parent_iface_var = "%s_%s_parent_iface".printf
(get_ccode_lower_case_name (current_class), get_ccode_lower_case_name (base_iface));
+ var vcast = get_this_interface_cexpression (base_iface);
- set_cvalue (expr, new CCodeMemberAccess.pointer (new CCodeIdentifier
(parent_iface_var), get_ccode_vfunc_name (m)));
+ set_cvalue (expr, new CCodeMemberAccess.pointer (vcast,
get_ccode_vfunc_name (m)));
return;
}
}
@@ -206,9 +206,9 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
} else if (base_prop.parent_symbol is Interface) {
var base_iface = (Interface) base_prop.parent_symbol;
- string parent_iface_var = "%s_%s_parent_iface".printf
(get_ccode_lower_case_name (current_class), get_ccode_lower_case_name (base_iface));
+ var vcast = get_this_interface_cexpression (base_iface);
- var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new
CCodeIdentifier (parent_iface_var), "get_%s".printf (prop.name)));
+ var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer
(vcast, "get_%s".printf (prop.name)));
ccall.add_argument (get_cvalue (expr.inner));
if (prop.property_type.is_real_non_null_struct_type ()) {
var temp_value = (GLibValue) create_temp_value
(prop.get_accessor.value_type, false, expr);
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 4e5cb10b8..4d7cf1d8e 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -104,10 +104,10 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
finish_call.call = new CCodeMemberAccess.pointer (vcast,
get_ccode_finish_vfunc_name (m));
} else if (m.base_interface_method != null) {
var base_iface = (Interface) m.base_interface_method.parent_symbol;
- string parent_iface_var = "%s_%s_parent_iface".printf
(get_ccode_lower_case_name (current_class), get_ccode_lower_case_name (base_iface));
+ var vcast = get_this_interface_cexpression (base_iface);
- async_call.call = new CCodeMemberAccess.pointer (new CCodeIdentifier
(parent_iface_var), get_ccode_vfunc_name (m));
- finish_call.call = new CCodeMemberAccess.pointer (new CCodeIdentifier
(parent_iface_var), get_ccode_finish_vfunc_name (m));
+ async_call.call = new CCodeMemberAccess.pointer (vcast,
get_ccode_vfunc_name (m));
+ finish_call.call = new CCodeMemberAccess.pointer (vcast,
get_ccode_finish_vfunc_name (m));
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6f16d9569..f5bf01eb3 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -319,8 +319,11 @@ TESTS = \
objects/gsource.vala \
objects/instance-comparison.vala \
objects/interface_only.vala \
+ objects/interface-async-base-access.vala \
+ objects/interface-base-access.vala \
objects/interfaces.vala \
objects/interface-generics.vala \
+ objects/interface-property-base-access.vala \
objects/interface-virtual-override.vala \
objects/methods.vala \
objects/paramspec.vala \
diff --git a/tests/objects/interface-async-base-access.vala b/tests/objects/interface-async-base-access.vala
new file mode 100644
index 000000000..2c8bccfd9
--- /dev/null
+++ b/tests/objects/interface-async-base-access.vala
@@ -0,0 +1,25 @@
+interface IFoo {
+ public abstract async void foo ();
+}
+
+class Bar : IFoo {
+ public async void foo () {
+ reached = true;
+ }
+}
+
+class Foo : Bar {
+ public async void bar () {
+ yield base.foo ();
+ }
+}
+
+bool reached = false;
+
+void main () {
+ var foo = new Foo ();
+ assert (foo is IFoo);
+
+ foo.bar.begin ();
+ assert (reached);
+}
diff --git a/tests/objects/interface-base-access.vala b/tests/objects/interface-base-access.vala
new file mode 100644
index 000000000..f0e853e25
--- /dev/null
+++ b/tests/objects/interface-base-access.vala
@@ -0,0 +1,25 @@
+interface IFoo {
+ public abstract void foo ();
+}
+
+class Bar : IFoo {
+ public void foo () {
+ reached = true;
+ }
+}
+
+class Foo : Bar {
+ public void bar () {
+ base.foo ();
+ }
+}
+
+bool reached = false;
+
+void main () {
+ var foo = new Foo ();
+ assert (foo is IFoo);
+
+ foo.bar ();
+ assert (reached);
+}
diff --git a/tests/objects/interface-property-base-access.vala
b/tests/objects/interface-property-base-access.vala
new file mode 100644
index 000000000..036ce8b1e
--- /dev/null
+++ b/tests/objects/interface-property-base-access.vala
@@ -0,0 +1,20 @@
+interface IFoo {
+ public abstract string foo { get; set; }
+}
+
+class Bar : IFoo {
+ public string foo { get; set; }
+}
+
+class Foo : Bar {
+ public string bar (string s) {
+ base.foo = s;
+ return base.foo;
+ }
+}
+
+void main () {
+ var foo = new Foo ();
+ assert (foo is IFoo);
+ assert (foo.bar ("foo") == "foo");
+}
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 933a67c26..d61e47a51 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -507,14 +507,14 @@ public class Vala.Class : ObjectTypeSymbol {
}
}
- private bool class_is_a (Class cl, TypeSymbol t) {
- if (cl == t) {
+ public bool is_a (ObjectTypeSymbol t) {
+ if (this == t) {
return true;
}
- foreach (DataType base_type in cl.get_base_types ()) {
+ foreach (DataType base_type in get_base_types ()) {
if (base_type.data_type is Class) {
- if (class_is_a ((Class) base_type.data_type, t)) {
+ if (((Class) base_type.data_type).is_a (t)) {
return true;
}
} else if (base_type.data_type == t) {
@@ -525,6 +525,16 @@ public class Vala.Class : ObjectTypeSymbol {
return false;
}
+ public bool implements (Interface i) {
+ foreach (DataType base_type in get_base_types ()) {
+ if (base_type.data_type == i) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
public override bool check (CodeContext context) {
if (checked) {
return !error;
@@ -705,7 +715,7 @@ public class Vala.Class : ObjectTypeSymbol {
/* check whether all prerequisites are met */
List<string> missing_prereqs = new ArrayList<string> ();
foreach (TypeSymbol prereq in prerequisites) {
- if (!class_is_a (this, prereq)) {
+ if (!is_a ((ObjectTypeSymbol) prereq)) {
missing_prereqs.insert (0, prereq.get_full_name ());
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]