From: Jürg Billeter Date: Thu, 27 Jul 2006 07:51:42 +0000 (+0000) Subject: don't require developer to explicitly write static in namespace field X-Git-Tag: VALA_0_0_2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8a0f8cc2c7f0d99613aff9f2b8fe3347613383cd;p=thirdparty%2Fvala.git don't require developer to explicitly write static in namespace field 2006-07-27 Jürg Billeter * vala/parser.y: don't require developer to explicitly write static in namespace field declarations, support type parameters in interfaces and callbacks * vala/valasymbolresolver.vala: support interfaces and callbacks * vala/valasemanticanalyzer.vala: use is_subtype_of method, support callbacks in fields * vala/valamemorymanager.vala: support callbacks in fields * vala/valacodegenerator.vala: support callbacks in fields * vala/valacallback.vala: support type parameters * vala/valaclass.vala: add is_subtype_of method * vala/valadatatype.vala: add is_subtype_of method * vala/valainterface.vala: add is_subtype_of method svn path=/trunk/; revision=84 --- diff --git a/vala/ChangeLog b/vala/ChangeLog index 0b176e58b..35865463e 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,3 +1,18 @@ +2006-07-27 Jürg Billeter + + * vala/parser.y: don't require developer to explicitly write static in + namespace field declarations, support type parameters in interfaces + and callbacks + * vala/valasymbolresolver.vala: support interfaces and callbacks + * vala/valasemanticanalyzer.vala: use is_subtype_of method, support + callbacks in fields + * vala/valamemorymanager.vala: support callbacks in fields + * vala/valacodegenerator.vala: support callbacks in fields + * vala/valacallback.vala: support type parameters + * vala/valaclass.vala: add is_subtype_of method + * vala/valadatatype.vala: add is_subtype_of method + * vala/valainterface.vala: add is_subtype_of method + 2006-07-26 Jürg Billeter * vala/scanner.l: support casting arrays diff --git a/vala/vala/parser.y b/vala/vala/parser.y index 7c7e52b1f..4962e7e35 100644 --- a/vala/vala/parser.y +++ b/vala/vala/parser.y @@ -1511,6 +1511,10 @@ namespace_member_declaration { /* skip declarations with errors */ if ($1 != NULL) { + /* field must be static, don't require developer + * to explicitly state it */ + vala_field_set_instance ($1, FALSE); + vala_namespace_add_field (current_namespace, $1); g_object_unref ($1); } @@ -1560,13 +1564,19 @@ class_declaration if (($4 & VALA_MODIFIER_ABSTRACT) == VALA_MODIFIER_ABSTRACT) { vala_class_set_is_abstract (current_class, TRUE); } - for (l = $8; l != NULL; l = l->next) { - vala_class_add_type_parameter (current_class, l->data); - g_object_unref (l->data); + if ($8 != NULL) { + for (l = $8; l != NULL; l = l->next) { + vala_class_add_type_parameter (current_class, l->data); + g_object_unref (l->data); + } + g_list_free ($8); } - for (l = $9; l != NULL; l = l->next) { - vala_class_add_base_type (current_class, l->data); - g_object_unref (l->data); + if ($9 != NULL) { + for (l = $9; l != NULL; l = l->next) { + vala_class_add_base_type (current_class, l->data); + g_object_unref (l->data); + } + g_list_free ($9); } } class_body @@ -2207,7 +2217,7 @@ struct_member_declaration ; interface_declaration - : comment opt_attributes opt_access_modifier INTERFACE IDENTIFIER opt_name_specifier + : comment opt_attributes opt_access_modifier INTERFACE IDENTIFIER opt_name_specifier opt_type_parameter_list { char *name = $5; @@ -2228,6 +2238,15 @@ interface_declaration current_interface = vala_interface_new (name, src); g_free (name); g_object_unref (src); + + if ($7 != NULL) { + GList *l; + for (l = $7; l != NULL; l = l->next) { + vala_interface_add_type_parameter (current_interface, l->data); + g_object_unref (l->data); + } + g_list_free ($7); + } } interface_body { @@ -2390,7 +2409,7 @@ flags_member_declaration ; callback_declaration - : comment opt_attributes opt_access_modifier CALLBACK type IDENTIFIER opt_name_specifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON + : comment opt_attributes opt_access_modifier CALLBACK type IDENTIFIER opt_name_specifier opt_type_parameter_list OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON { GList *l; char *name = $6; @@ -2410,22 +2429,28 @@ callback_declaration ValaSourceReference *src = src_com(@6, $1); $$ = vala_callback_new (name, $5, src); + g_free (name); + g_object_unref ($5); g_object_unref (src); if ($3 != 0) { VALA_DATA_TYPE($$)->access = $3; } VALA_CODE_NODE($$)->attributes = $2; - for (l = $9; l != NULL; l = l->next) { - vala_callback_add_parameter ($$, l->data); - g_object_unref (l->data); + if ($8 != NULL) { + for (l = $8; l != NULL; l = l->next) { + vala_callback_add_type_parameter ($$, l->data); + g_object_unref (l->data); + } + g_list_free ($8); } - if ($9 != NULL) { - g_list_free ($9); + if ($10 != NULL) { + for (l = $10; l != NULL; l = l->next) { + vala_callback_add_parameter ($$, l->data); + g_object_unref (l->data); + } + g_list_free ($10); } - - g_object_unref ($5); - g_free (name); } ; diff --git a/vala/vala/valacallback.vala b/vala/vala/valacallback.vala index 4934ae722..968f553ea 100644 --- a/vala/vala/valacallback.vala +++ b/vala/vala/valacallback.vala @@ -38,6 +38,8 @@ public class Vala.Callback : DataType { */ public bool instance { get; set; } + private List type_parameters; + private List parameters; private string cname; @@ -52,6 +54,16 @@ public class Vala.Callback : DataType { public static ref Callback new (string! name, TypeReference return_type, SourceReference source) { return (new Callback (name = name, return_type = return_type, source_reference = source)); } + + /** + * Appends the specified parameter to the list of type parameters. + * + * @param p a type parameter + */ + public void add_type_parameter (TypeParameter! p) { + type_parameters.append (p); + p.type = this; + } /** * Appends paramater to this callback function. @@ -109,6 +121,10 @@ public class Vala.Callback : DataType { public override void accept (CodeVisitor! visitor) { visitor.visit_begin_callback (this); + + foreach (TypeParameter p in type_parameters) { + p.accept (visitor); + } return_type.accept (visitor); diff --git a/vala/vala/valaclass.vala b/vala/vala/valaclass.vala index dd0f4d394..7461143df 100644 --- a/vala/vala/valaclass.vala +++ b/vala/vala/valaclass.vala @@ -52,15 +52,15 @@ public class Vala.Class : DataType { private bool _has_private_fields; - List type_parameters; + private List type_parameters; private List base_types; - List constants; - List fields; - List methods; - List properties; - List signals; + private List constants; + private List fields; + private List methods; + private List properties; + private List signals; /** * Specifies the instance constructor. @@ -346,4 +346,15 @@ public class Vala.Class : DataType { public override string get_unref_function () { return "g_object_unref"; } + + 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)) { + return true; + } + } + + return false; + } } diff --git a/vala/vala/valacodegenerator.vala b/vala/vala/valacodegenerator.vala index 18ab8e944..440fb1f61 100644 --- a/vala/vala/valacodegenerator.vala +++ b/vala/vala/valacodegenerator.vala @@ -1776,10 +1776,14 @@ public class Vala.CodeGenerator : CodeVisitor { var param = (FormalParameter) expr.call.symbol_reference.node; var cb = (Callback) param.type_reference.data_type; params = cb.get_parameters (); + } else if (expr.call.symbol_reference.node is Field) { + var f = (Field) expr.call.symbol_reference.node; + var cb = (Callback) f.type_reference.data_type; + params = cb.get_parameters (); } else if (expr.call.symbol_reference.node is Method) { m = (Method) expr.call.symbol_reference.node; params = m.get_parameters (); - } else { + } else if (expr.call.symbol_reference.node is Signal) { var sig = (Signal) expr.call.symbol_reference.node; params = sig.get_parameters (); diff --git a/vala/vala/valadatatype.vala b/vala/vala/valadatatype.vala index 316fec5a1..85fe19467 100644 --- a/vala/vala/valadatatype.vala +++ b/vala/vala/valadatatype.vala @@ -46,6 +46,9 @@ public abstract class Vala.DataType : CodeNode { */ public weak Namespace @namespace; + private List cheader_filenames; + private Array array_type; + /** * Returns the name of this data type as it is used in C code. * @@ -192,11 +195,10 @@ public abstract class Vala.DataType : CodeNode { cheader_filenames.append (filename); } - private List cheader_filenames; - - private Array array_type; /** - * Retrieves for a given DataType its corresponding Array. + * Returns the array type for elements of this data type. + * + * @return array type for this data type */ public Array! get_array () { if (array_type == null) { @@ -213,4 +215,15 @@ public abstract class Vala.DataType : CodeNode { return array_type; } + + /** + * Checks whether this data type is a subtype of the specified data + * type. + * + * @param t a data type + * @return true if t is a supertype of this data type, false otherwise + */ + public virtual bool is_subtype_of (DataType! t) { + return false; + } } diff --git a/vala/vala/valainterface.vala b/vala/vala/valainterface.vala index 0efedf4e5..3283455c0 100644 --- a/vala/vala/valainterface.vala +++ b/vala/vala/valainterface.vala @@ -26,12 +26,13 @@ using GLib; * Represents a class declaration in the source code. */ public class Vala.Interface : DataType { - List type_parameters; + private List type_parameters; + private List base_types; - List methods; - List properties; - List signals; + private List methods; + private List properties; + private List signals; /** * Creates a new interface. @@ -199,4 +200,15 @@ public class Vala.Interface : DataType { public override string get_unref_function () { return "g_object_unref"; } + + 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)) { + return true; + } + } + + return false; + } } diff --git a/vala/vala/valamemorymanager.vala b/vala/vala/valamemorymanager.vala index 62cbe519a..69d35fc25 100644 --- a/vala/vala/valamemorymanager.vala +++ b/vala/vala/valamemorymanager.vala @@ -131,10 +131,14 @@ public class Vala.MemoryManager : CodeVisitor { var param = (FormalParameter) msym.node; var cb = (Callback) param.type_reference.data_type; params = cb.get_parameters (); + } else if (msym.node is Field) { + var f = (Field) msym.node; + var cb = (Callback) f.type_reference.data_type; + params = cb.get_parameters (); } else if (msym.node is Method) { var m = (Method) msym.node; params = m.get_parameters (); - } else { + } else if (msym.node is Signal) { var sig = (Signal) msym.node; params = sig.get_parameters (); } diff --git a/vala/vala/valasemanticanalyzer.vala b/vala/vala/valasemanticanalyzer.vala index 1fecb5ff1..ce1b1b714 100644 --- a/vala/vala/valasemanticanalyzer.vala +++ b/vala/vala/valasemanticanalyzer.vala @@ -381,12 +381,14 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } if (stmt.return_expression == null && current_return_type.data_type != null) { - Report.error (stmt.source_reference, "Return with value in void function"); + Report.error (stmt.source_reference, "Return without value in non-void function"); return; } - if (stmt.return_expression != null && current_return_type.data_type == null) { - Report.error (stmt.source_reference, "Return without value in non-void function"); + if (stmt.return_expression != null && + current_return_type.data_type == null && + current_return_type.type_parameter == null) { + Report.error (stmt.source_reference, "Return with value in void function"); return; } @@ -655,21 +657,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return true; } - /* non-class types must match exactly */ - if (!(expression_type.data_type is Class)) { - return false; - } - - var cl = (Class) expression_type.data_type; - - var base_class = cl.base_class; - for (; base_class != null; base_class = base_class.base_class) { - if (base_class == expected_type.data_type) { - return true; - } - } - - return false; + return expression_type.data_type.is_subtype_of (expected_type.data_type); } public override void visit_begin_invocation_expression (InvocationExpression! expr) { @@ -703,6 +691,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor { Report.error (expr.source_reference, "invocation not supported in this context"); return; } + } else if (msym.node is Field) { + var f = (Field) msym.node; + if (f.type_reference.data_type is Callback) { + var cb = (Callback) f.type_reference.data_type; + params = cb.get_parameters (); + } else { + expr.error = true; + Report.error (expr.source_reference, "invocation not supported in this context"); + return; + } } else if (msym.node is Method) { var m = (Method) msym.node; params = m.get_parameters (); @@ -753,6 +751,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor { var cb = (Callback) param.type_reference.data_type; ret_type = cb.return_type; params = cb.get_parameters (); + } else if (msym.node is Field) { + var f = (Field) msym.node; + var cb = (Callback) f.type_reference.data_type; + ret_type = cb.return_type; + params = cb.get_parameters (); } else if (msym.node is Method) { var m = (Method) msym.node; ret_type = m.return_type; diff --git a/vala/vala/valasymbolresolver.vala b/vala/vala/valasymbolresolver.vala index 1dd22cc05..a622a3eca 100644 --- a/vala/vala/valasymbolresolver.vala +++ b/vala/vala/valasymbolresolver.vala @@ -93,6 +93,22 @@ public class Vala.SymbolResolver : CodeVisitor { current_scope = current_scope.parent_symbol; } + public override void visit_begin_interface (Interface! iface) { + current_scope = iface.symbol; + } + + public override void visit_end_interface (Interface! iface) { + current_scope = current_scope.parent_symbol; + } + + public override void visit_begin_callback (Callback! cb) { + current_scope = cb.symbol; + } + + public override void visit_end_callback (Callback! cb) { + current_scope = current_scope.parent_symbol; + } + public override void visit_formal_parameter (FormalParameter! p) { if (!p.ellipsis && p.type_reference.is_ref) { if ((p.type_reference.data_type != null &&