[vala/staging] 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/staging] codegen: Use G_TYPE_INSTANCE_GET_INTERFACE to get vtable for base-access
- Date: Thu, 17 Oct 2019 18:35:50 +0000 (UTC)
commit 81dbabcc8535a28f660e3b28a21f8e44f3a74647
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
Using the pre-assigned *_parent_iface field it error prone. It only works
for direct implementations in the same source file.
codegen/valaccodebasemodule.vala | 16 +++++++++++++--
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 ++++++++++++++++++
tests/objects/methods.vala | 2 +-
vala/valaclass.vala | 10 ++++-----
9 files changed, 100 insertions(+), 15 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 83f028013..1db8066f1 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2385,6 +2385,18 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
return get_cexpression ("self");
}
+ public CCodeExpression get_this_interface_cexpression (Interface 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));
}
@@ -6039,9 +6051,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 54a71a3e2..2a37ceb5c 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;
}
}
@@ -219,9 +219,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 3c3290092..fc0561dd7 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 6578f43ab..b0a89eb41 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -323,9 +323,12 @@ TESTS = \
objects/gsource.vala \
objects/instance-comparison.vala \
objects/interface_only.vala \
+ objects/interface-async-base-access.vala
+ objects/interface-base-access.vala
objects/interface-inner-types.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/tests/objects/methods.vala b/tests/objects/methods.vala
index 9a950c322..018aac8ba 100644
--- a/tests/objects/methods.vala
+++ b/tests/objects/methods.vala
@@ -151,7 +151,7 @@ namespace Maman.BaseAccess {
}
}
- public class FooBar : Foo, IFoo {
+ public class FooBar : Foo {
public int interface_method () {
return base.interface_method () * 10 + 6;
}
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 507a10d23..92096fcff 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -469,14 +469,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.type_symbol is Class) {
- if (class_is_a ((Class) base_type.type_symbol, t)) {
+ if (((Class) base_type.type_symbol).is_a (t)) {
return true;
}
} else if (base_type.type_symbol == t) {
@@ -671,7 +671,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]