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));
}
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 ()) {
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;
}
}
}
} 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);
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));
}
}
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 \
--- /dev/null
+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);
+}
--- /dev/null
+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);
+}
--- /dev/null
+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");
+}
}
}
- 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) {
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;
/* 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 ());
}
}