Commit 75ac8a9a authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter
Browse files

check whether a class implements all abstract methods of base classes fix

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

svn path=/trunk/; revision=228
parent 640f1db2
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
......
......@@ -79,7 +79,8 @@ public abstract class Vala.CodeNode {
*
* @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) {
}
......@@ -108,10 +109,10 @@ public abstract class Vala.CodeNode {
*
* @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)";
}
}
......@@ -173,7 +173,9 @@ public abstract class Vala.DataType : CodeNode {
* 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
......@@ -184,7 +186,9 @@ public abstract class Vala.DataType : CodeNode {
* 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
......@@ -192,7 +196,9 @@ public abstract class Vala.DataType : CodeNode {
*
* @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
......@@ -73,6 +73,4 @@ public abstract class Vala.Expression : CodeNode {
* 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
......@@ -30,6 +30,4 @@ public abstract class Vala.Literal : CodeNode {
* Specifies the type of this literal.
*/
public TypeReference static_type { get; set; }
public abstract ref string! to_string ();
}
......@@ -178,22 +178,44 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
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;
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment