2007-03-07 Jürg Billeter <j@bitron.ch>
+ * vala/valasemanticanalyzer.vala: check whether a class implements all
+ abstract methods of base classes
+ * vala/valacodenode.vala, vala/valadatatype.vala,
+ vala/valaexpression.vala, vala/valaliteral.vala: fix build with added
+ checks
+
+2007-03-07 Jürg Billeter <j@bitron.ch>
+
* vala/valaclass.vala: implement get_type_parameter_index
2007-03-07 Raffaele Sandrini <rasa@gmx.ch>
*
* @param visitor the visitor to be called while traversing
*/
- public abstract void accept (CodeVisitor! visitor);
+ public virtual void accept (CodeVisitor! visitor) {
+ }
public virtual void replace (CodeNode! old_node, CodeNode! new_node) {
}
*
* @return a string representation
*/
- public ref string to_string () {
+ public virtual ref string! to_string () {
if (source_reference != null) {
return source_reference.to_string ();
}
- return null;
+ return "(unknown)";
}
}
* name or null
* @return the upper case name to be used in C code
*/
- public abstract ref string get_upper_case_cname (string infix = null);
+ public virtual ref string get_upper_case_cname (string infix = null) {
+ return null;
+ }
/**
* Returns the C name of this data type in lower case. Words are
* name or null
* @return the lower case name to be used in C code
*/
- public abstract ref string get_lower_case_cname (string infix = null);
+ public virtual ref string get_lower_case_cname (string infix = null) {
+ return null;
+ }
/**
* Returns the string to be prefixed to members of this data type in
*
* @return the lower case prefix to be used in C code
*/
- public abstract ref string get_lower_case_cprefix ();
+ public virtual ref string get_lower_case_cprefix () {
+ return null;
+ }
/**
* Returns a list of C header filenames users of this data type must
/* valaexpression.vala
*
- * Copyright (C) 2006 Jürg Billeter
+ * Copyright (C) 2006-2007 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* The code generator sets and uses them for memory management.
*/
public List<VariableDeclarator> temp_vars;
-
- public abstract ref string! to_string ();
}
/* valaliteral.vala
*
- * Copyright (C) 2006 Jürg Billeter
+ * Copyright (C) 2006-2007 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* Specifies the type of this literal.
*/
public TypeReference static_type { get; set; }
-
- public abstract ref string! to_string ();
}
Report.error (cl.source_reference, error_string);
}
- /* all virtual symbols defined in interfaces have to be at least defined (or implemented) also in this type */
+ /* all abstract symbols defined in base types have to be at least defined (or implemented) also in this type */
foreach (TypeReference base_type in cl.get_base_types ()) {
if (base_type.data_type is Interface) {
- Interface iface = (Interface)base_type.data_type;
-
+ Interface iface = (Interface) base_type.data_type;
+
/* We do not need to do expensive equality checking here since this is done
* already. We only need to guarantee the symbols are present.
*/
-
+
/* check methods */
foreach (Method m in iface.get_methods ()) {
- if (cl.symbol.lookup (m.name) == null && m.is_abstract) {
- cl.error = true;
- Report.error (cl.source_reference, "`%s' does not implement interface method `%s'".printf (cl.symbol.get_full_name (), m.symbol.get_full_name ()));
+ if (m.is_abstract) {
+ var sym = cl.symbol.lookup (m.name);
+ if (sym == null || !(sym.node is Method) || ((Method) sym.node).base_interface_method != m) {
+ cl.error = true;
+ Report.error (cl.source_reference, "`%s' does not implement interface method `%s'".printf (cl.symbol.get_full_name (), m.symbol.get_full_name ()));
+ }
+ }
+ }
+ }
+ }
+
+ /* all abstract symbols defined in base classes have to be implemented in non-abstract classes
+ * VAPI classes don't have to specify overridden methods
+ */
+ if (!cl.is_abstract && !cl.source_reference.file.pkg) {
+ var base_class = cl.base_class;
+ while (base_class != null && base_class.is_abstract) {
+ foreach (Method m in base_class.get_methods ()) {
+ if (m.is_abstract) {
+ var sym = cl.symbol.lookup (m.name);
+ if (sym == null || !(sym.node is Method) || ((Method) sym.node).base_method != m) {
+ cl.error = true;
+ Report.error (cl.source_reference, "`%s' does not implement abstract method `%s'".printf (cl.symbol.get_full_name (), m.symbol.get_full_name ()));
+ }
}
}
+ base_class = base_class.base_class;
}
}