From: Raffaele Sandrini Date: Mon, 5 Mar 2007 13:10:00 +0000 (+0000) Subject: add `g_type_interface_add_prerequisite' calls during interface type X-Git-Tag: VALA_0_0_8~39 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c3d2f4eae4c51ce9463f50a1ef20ee961cbc08ae;p=platform%2Fupstream%2Fvala.git add `g_type_interface_add_prerequisite' calls during interface type 2007-03-05 Raffaele Sandrini * vala/valainterfaceregisterfunction.vala: add `g_type_interface_add_prerequisite' calls during interface type creation * vala/valasemanticanalyzer.vala: add checks for consistent interface prerequisites and whether classes are obeying them svn path=/trunk/; revision=224 --- diff --git a/vala/ChangeLog b/vala/ChangeLog index 1820894..5dd80d1 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,3 +1,11 @@ +2007-03-05 Raffaele Sandrini + + * vala/valainterfaceregisterfunction.vala: add + `g_type_interface_add_prerequisite' calls during interface type + creation + * vala/valasemanticanalyzer.vala: add checks for consistent interface + prerequisites and whether classes are obeying them + 2007-03-04 Jürg Billeter * configure.ac: Post-release version bump diff --git a/vala/vala/valainterfaceregisterfunction.vala b/vala/vala/valainterfaceregisterfunction.vala index 2c9de10..42fcbaf 100644 --- a/vala/vala/valainterfaceregisterfunction.vala +++ b/vala/vala/valainterfaceregisterfunction.vala @@ -1,6 +1,6 @@ /* valainterfaceregisterfunction.vala * - * Copyright (C) 2006 Jürg Billeter + * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,6 +18,7 @@ * * Author: * Jürg Billeter + * Raffaele Sandrini */ using GLib; @@ -62,6 +63,17 @@ public class Vala.InterfaceRegisterFunction : TypeRegisterFunction { public override ref CCodeFragment! get_type_interface_init_statements () { var frag = new CCodeFragment (); + /* register all prerequisites */ + foreach (TypeReference prereq_ref in interface_reference.get_prerequisites ()) { + var prereq = prereq_ref.data_type; + + var func = new CCodeFunctionCall (new CCodeIdentifier ("g_type_interface_add_prerequisite")); + func.add_argument (new CCodeIdentifier ("g_define_type_id")); + func.add_argument (new CCodeIdentifier (prereq.get_type_id())); + + frag.append (new CCodeExpressionStatement (func)); + } + return frag; } } diff --git a/vala/vala/valasemanticanalyzer.vala b/vala/vala/valasemanticanalyzer.vala index 34aa9a6..4857c14 100644 --- a/vala/vala/valasemanticanalyzer.vala +++ b/vala/vala/valasemanticanalyzer.vala @@ -117,8 +117,67 @@ public class Vala.SemanticAnalyzer : CodeVisitor { current_source_file.add_symbol_dependency (base_type_reference.data_type.symbol, SourceFileDependencyType.HEADER_FULL); } } - + + private ref List get_all_prerequisites (Interface! iface) { + List ret = null; + + foreach (TypeReference prereq in iface.get_prerequisites ()) { + DataType type = prereq.data_type; + /* skip on previous errors */ + if (type == null) { + continue; + } + + ret.prepend (type); + if (type is Interface) { + ret.concat (get_all_prerequisites ((Interface)type)); + + } + } + + return ret.reverse (); + } + public override void visit_end_class (Class! cl) { + /* gather all prerequisites */ + List prerequisites = null; + foreach (TypeReference base_type in cl.get_base_types ()) { + if (base_type.data_type is Interface) { + prerequisites.concat (get_all_prerequisites ((Interface)base_type.data_type)); + } + } + /* check whether all prerequisites are met */ + List missing_prereqs = null; + foreach (DataType prereq in prerequisites) { + bool found = false; + foreach (TypeReference base_type in cl.get_base_types ()) { + if (base_type.data_type == prereq) { + found = true; + break; + } + } + if (!found) { + missing_prereqs.prepend (prereq.symbol.get_full_name ()); + } + } + /* report any missing prerequisites */ + if (missing_prereqs != null) { + cl.error = true; + + string error_string = "%s: some prerequisites (".printf (cl.symbol.get_full_name ()); + bool first = true; + foreach (string s in missing_prereqs) { + if (first) { + error_string = "%s`%s'".printf (error_string, s); + first = false; + } else { + error_string = "%s, `%s'".printf (error_string, s); + } + } + error_string += ") are not met"; + Report.error (cl.source_reference, error_string); + } + current_symbol = current_symbol.parent_symbol; current_class = null; } @@ -142,6 +201,27 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } public override void visit_end_interface (Interface! iface) { + /* check prerequisites */ + Class prereq_class; + foreach (TypeReference prereq in iface.get_prerequisites ()) { + DataType class_or_interface = prereq.data_type; + /* skip on previous errors */ + if (class_or_interface == null) { + iface.error = true; + continue; + } + /* interfaces are not allowed to have multiple instantiable prerequisites */ + if (class_or_interface is Class) { + if (prereq_class != null) { + iface.error = true; + Report.error (iface.source_reference, "%s: Interfaces cannot have multiple instantiable prerequisites (`%s' and `%s')".printf (iface.symbol.get_full_name (), class_or_interface.symbol.get_full_name (), prereq_class.symbol.get_full_name ())); + return; + } + + prereq_class = (Class)class_or_interface; + } + } + current_symbol = current_symbol.parent_symbol; }