2007-03-04 Jürg Billeter <j@bitron.ch>
+ * vala/parser.y, vala/valainterface.vala,
+ vala/valasemanticanalyzer.vala: rename base_types of interfaces to
+ prerequisites to follow GObject terminology
+ * vala/valamethod.vala, vala/valasemanticanalyzer.vala,
+ vala/valacodegenerator.vala: move interface usage part from
+ base_method to base_interface_method property
+ * vala/valasemanticanalyzer.vala: don't require interface
+ implementations to specify override
+ * vala/valacodegenerator.vala: support base access in interface
+ implementations
+ * tests/test-017.vala: remove override in method declaration
+
+2007-03-04 Jürg Billeter <j@bitron.ch>
+
* vala/valasemanticanalyzer.vala: support lambda expressions in
constructors
* tests/test-029.vala: remove extra printf argument
}
class Maman.Baz : Ibaz {
- public override void do_action () {
+ public void do_action () {
stdout.printf (" 2");
}
if ($8 != NULL) {
GList *l;
for (l = $8; l != NULL; l = l->next) {
- vala_interface_add_base_type (current_interface, l->data);
+ vala_interface_add_prerequisite (current_interface, l->data);
g_object_unref (l->data);
}
g_list_free ($8);
/* connect overridden methods */
var methods = cl.get_methods ();
foreach (Method m in methods) {
- if (!m.is_virtual && !m.overrides) {
+ if (m.base_method == null) {
continue;
}
-
var base_type = m.base_method.symbol.parent_symbol.node;
- if (base_type is Interface) {
- continue;
- }
var ccast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (((Class) base_type).get_upper_case_cname (null))));
ccast.add_argument (new CCodeIdentifier ("klass"));
ref CCodeFunctionCall ccall;
+ /* save pointer to parent vtable */
+ string parent_iface_var = "%s_%s_parent_iface".printf (cl.get_lower_case_cname (null), iface.get_lower_case_cname (null));
+ var parent_decl = new CCodeDeclaration (iface.get_type_cname () + "*");
+ var parent_var_decl = new CCodeVariableDeclarator (parent_iface_var);
+ parent_var_decl.initializer = new CCodeConstant ("NULL");
+ parent_decl.add_declarator (parent_var_decl);
+ parent_decl.modifiers = CCodeModifiers.STATIC;
+ source_type_member_declaration.append (parent_decl);
+ ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_interface_peek_parent"));
+ ccall.add_argument (new CCodeIdentifier ("iface"));
+ var parent_assignment = new CCodeAssignment (new CCodeIdentifier (parent_iface_var), ccall);
+ init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
+
var methods = cl.get_methods ();
foreach (Method m in methods) {
- if (!m.overrides) {
+ if (m.base_interface_method == null) {
continue;
}
-
- var base_type = m.base_method.symbol.parent_symbol.node;
+
+ var base_type = m.base_interface_method.symbol.parent_symbol.node;
if (base_type != iface) {
continue;
}
if (m.instance) {
var this_type = new TypeReference ();
this_type.data_type = find_parent_type (m);
- if (!m.overrides) {
+ if (m.base_interface_method != null) {
+ var base_type = new TypeReference ();
+ base_type.data_type = (DataType) m.base_interface_method.symbol.parent_symbol.node;
+ instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
+ } else if (m.overrides) {
+ var base_type = new TypeReference ();
+ base_type.data_type = (DataType) m.base_method.symbol.parent_symbol.node;
+ instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
+ } else {
if (m.instance_by_reference) {
instance_param = new CCodeFormalParameter ("*self", this_type.get_cname ());
} else {
instance_param = new CCodeFormalParameter ("self", this_type.get_cname ());
}
- } else {
- var base_type = new TypeReference ();
- base_type.data_type = (DataType) m.base_method.symbol.parent_symbol.node;
- instance_param = new CCodeFormalParameter ("base", base_type.get_cname ());
}
if (!m.instance_last) {
function.add_parameter (instance_param);
/* real function declaration and definition not needed
* for abstract methods */
if (!m.is_abstract) {
- if (m.access != MemberAccessibility.PRIVATE && !(m.is_virtual || m.overrides)) {
+ if (m.access != MemberAccessibility.PRIVATE && m.base_method == null && m.base_interface_method == null) {
/* public methods need function declaration in
* header file except virtual/overridden methods */
header_type_member_declaration.append (function.copy ());
if (m.symbol.parent_symbol.node is Class) {
var cl = (Class) m.symbol.parent_symbol.node;
- if (m.overrides) {
+ if (m.overrides || m.base_interface_method != null) {
var ccall = new CCodeFunctionCall (new CCodeIdentifier (cl.get_upper_case_cname (null)));
ccall.add_argument (new CCodeIdentifier ("base"));
if (expr.symbol_reference.node is Method) {
var m = (Method) expr.symbol_reference.node;
- if (expr.inner is BaseAccess && (m.is_virtual || m.overrides)) {
- var base_class = (Class) m.base_method.symbol.parent_symbol.node;
- var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
- vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
-
- expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
- return;
+ if (expr.inner is BaseAccess) {
+ if (m.base_interface_method != null) {
+ var base_iface = (Interface) m.base_interface_method.symbol.parent_symbol.node;
+ string parent_iface_var = "%s_%s_parent_iface".printf (current_class.get_lower_case_cname (null), base_iface.get_lower_case_cname (null));
+
+ expr.ccodenode = new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), m.name);
+ return;
+ } else if (m.base_method != null) {
+ var base_class = (Class) m.base_method.symbol.parent_symbol.node;
+ var vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf (base_class.get_upper_case_cname (null))));
+ vcast.add_argument (new CCodeIdentifier ("%s_parent_class".printf (current_class.get_lower_case_cname (null))));
+
+ expr.ccodenode = new CCodeMemberAccess.pointer (vcast, m.name);
+ return;
+ }
}
- if (!m.overrides) {
- expr.ccodenode = new CCodeIdentifier (m.get_cname ());
- } else {
+ if (m.base_interface_method != null) {
+ expr.ccodenode = new CCodeIdentifier (m.base_interface_method.get_cname ());
+ } else if (m.base_method != null) {
expr.ccodenode = new CCodeIdentifier (m.base_method.get_cname ());
+ } else {
+ expr.ccodenode = new CCodeIdentifier (m.get_cname ());
}
} else if (expr.symbol_reference.node is ArrayLengthField) {
expr.ccodenode = get_array_length_cexpression (expr.inner, 1);
ref CCodeExpression instance;
if (m != null && m.instance) {
var base_method = m;
- if (m.overrides) {
+ if (m.base_interface_method != null) {
+ base_method = m.base_interface_method;
+ } else if (m.base_method != null) {
base_method = m.base_method;
}
if (ma.inner == null) {
instance = new CCodeIdentifier ("self");
/* require casts for overriden and inherited methods */
- req_cast = m.overrides || (m.symbol.parent_symbol != current_type_symbol);
+ req_cast = m.overrides || m.base_interface_method != null || (m.symbol.parent_symbol != current_type_symbol);
} else {
instance = (CCodeExpression) ma.inner.ccodenode;
/* reqiure casts if the type of the used instance is
public class Vala.Interface : DataType {
private List<TypeParameter> type_parameters;
- private List<TypeReference> base_types;
+ private List<TypeReference> prerequisites;
private List<Method> methods;
private List<Property> properties;
}
/**
- * Adds the specified interface to the list of prerequisites of this
- * interface.
+ * Adds the specified interface or class to the list of prerequisites of
+ * this interface.
*
- * @param type an interface reference
+ * @param type an interface or class reference
*/
- public void add_base_type (TypeReference! type) {
- base_types.append (type);
+ public void add_prerequisite (TypeReference! type) {
+ prerequisites.append (type);
}
/**
*
* @return list of base types
*/
- public ref List<weak TypeReference> get_base_types () {
- return base_types.copy ();
+ public ref List<weak TypeReference> get_prerequisites () {
+ return prerequisites.copy ();
}
/**
public override void accept (CodeVisitor! visitor) {
visitor.visit_begin_interface (this);
- foreach (TypeReference type in base_types) {
+ foreach (TypeReference type in prerequisites) {
type.accept (visitor);
}
}
public override bool is_subtype_of (DataType! t) {
- foreach (TypeReference base_type in base_types) {
- if (base_type.data_type == t ||
- base_type.data_type.is_subtype_of (t)) {
+ foreach (TypeReference prerequisite in prerequisites) {
+ if (prerequisite.data_type == t ||
+ prerequisite.data_type.is_subtype_of (t)) {
return true;
}
}
public weak Method base_method { get; set; }
/**
+ * Specifies the abstract interface method this method implements.
+ */
+ public Method base_interface_method { get; set; }
+
+ /**
* Specifies the generated `this' parameter for instance methods.
*/
public FormalParameter this_parameter { get; set; }
* @return the name to be used in C code
*/
public ref string! get_real_cname () {
- if (is_virtual || overrides) {
+ if (base_method != null || base_interface_method != null) {
var parent = (Class) symbol.parent_symbol.node;
return "%s_real_%s".printf (parent.get_lower_case_cname (null), name);
} else {
public override void visit_begin_interface (Interface! iface) {
current_symbol = iface.symbol;
- foreach (TypeReference base_type_reference in iface.get_base_types ()) {
- current_source_file.add_symbol_dependency (base_type_reference.data_type.symbol, SourceFileDependencyType.HEADER_FULL);
+ foreach (TypeReference prerequisite_reference in iface.get_prerequisites ()) {
+ current_source_file.add_symbol_dependency (prerequisite_reference.data_type.symbol, SourceFileDependencyType.HEADER_FULL);
}
}
}
}
- private void find_base_method (Method! m, DataType! datatype) {
- var sym = datatype.symbol.lookup (m.name);
+ private void find_base_class_method (Method! m, Class! cl) {
+ var sym = cl.symbol.lookup (m.name);
if (sym != null && sym.node is Method) {
var base_method = (Method) sym.node;
if (base_method.is_abstract || base_method.is_virtual) {
}
}
+ if (cl.base_class != null) {
+ find_base_class_method (m, cl.base_class);
+ }
+ }
+
+ private void find_base_interface_method (Method! m, Class! cl) {
// FIXME report error if multiple possible base methods are found
- if (datatype is Class) {
- var cl = (Class) datatype;
- foreach (TypeReference type in cl.get_base_types ()) {
- find_base_method (m, type.data_type);
- if (m.base_method != null) {
- return;
- }
- }
- } else {
- var iface = (Interface) datatype;
- foreach (TypeReference type in iface.get_base_types ()) {
- find_base_method (m, type.data_type);
- if (m.base_method != null) {
- return;
+ foreach (TypeReference type in cl.get_base_types ()) {
+ if (type.data_type is Interface) {
+ var sym = type.data_type.symbol.lookup (m.name);
+ if (sym != null && sym.node is Method) {
+ var base_method = (Method) sym.node;
+ if (base_method.is_abstract) {
+ if (!m.equals (base_method)) {
+ m.error = true;
+ Report.error (m.source_reference, "Return type and/or parameters of overriding method `%s' do not match overridden method `%s'.".printf (m.symbol.get_full_name (), base_method.symbol.get_full_name ()));
+ return;
+ }
+
+ m.base_interface_method = base_method;
+ return;
+ }
}
}
}
current_return_type = up_method.return_type;
}
- if (m.is_virtual || m.overrides) {
- if (current_symbol.node is Class) {
- find_base_method (m, (Class) current_symbol.node);
- if (m.base_method == null) {
- Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.symbol.get_full_name ()));
+ if (current_symbol.node is Class) {
+ if (!(m is CreationMethod)) {
+ find_base_interface_method (m, (Class) current_symbol.node);
+ if (m.is_virtual || m.overrides) {
+ find_base_class_method (m, (Class) current_symbol.node);
+ if (m.base_method == null) {
+ // FIXME remove check after interface override transition
+ if (m.base_interface_method == null) {
+ Report.error (m.source_reference, "%s: no suitable method found to override".printf (m.symbol.get_full_name ()));
+ }
+ }
}
- } else if (current_symbol.node is Struct) {
+ }
+ } else if (current_symbol.node is Struct) {
+ if (m.is_abstract || m.is_virtual || m.overrides) {
Report.error (m.source_reference, "A struct member `%s' cannot be marked as override, virtual, or abstract".printf (m.symbol.get_full_name ()));
return;
}
}
} else if (sym.node is Interface) {
var iface = (Interface) sym.node;
- foreach (TypeReference base_type in iface.get_base_types ()) {
- result = symbol_lookup_inherited (base_type.data_type.symbol, name);
+ foreach (TypeReference prerequisite in iface.get_prerequisites ()) {
+ result = symbol_lookup_inherited (prerequisite.data_type.symbol, name);
if (result != null) {
return result;
}