[vala] Add CCode ordering attribute for interfaces



commit 2886366e6b5499b46e04029b9a257ae9dc880766
Author: Maciej Piechotka <uzytkownik2 gmail com>
Date:   Sat May 11 21:43:30 2013 +0100

    Add CCode ordering attribute for interfaces

 codegen/valagtypemodule.vala |  112 +++++++++++++++++++++---------------------
 vala/valainterface.vala      |   76 ++++++++++++++++++++++++++---
 2 files changed, 125 insertions(+), 63 deletions(-)
---
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 67d1051..5fd74a0 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -1987,73 +1987,73 @@ public class Vala.GTypeModule : GErrorModule {
                        }
                }
 
-               foreach (Method m in iface.get_methods ()) {
-                       generate_virtual_method_declaration (m, decl_space, type_struct);
-               }
-
-               foreach (Signal sig in iface.get_signals ()) {
-                       if (sig.default_handler != null) {
-                               generate_virtual_method_declaration (sig.default_handler, decl_space, 
type_struct);
-                       }
-               }
-
-               foreach (Property prop in iface.get_properties ()) {
-                       if (!prop.is_abstract && !prop.is_virtual) {
-                               continue;
-                       }
-                       generate_type_declaration (prop.property_type, decl_space);
+               foreach (Symbol sym in iface.get_virtuals ()) {
+                       Method m;
+                       Signal sig;
+                       Property prop;
+                       if ((m = sym as Method) != null) {
+                               generate_virtual_method_declaration (m, decl_space, type_struct);
+                       } else if ((sig = sym as Signal) != null) {
+                               if (sig.default_handler != null) {
+                                       generate_virtual_method_declaration (sig.default_handler, decl_space, 
type_struct);
+                               }
+                       } else if ((prop = sym as Property) != null) {
+                               generate_type_declaration (prop.property_type, decl_space);
 
-                       var t = (ObjectTypeSymbol) prop.parent_symbol;
+                               var t = (ObjectTypeSymbol) prop.parent_symbol;
 
-                       bool returns_real_struct = prop.property_type.is_real_non_null_struct_type ();
+                               bool returns_real_struct = prop.property_type.is_real_non_null_struct_type ();
 
-                       var this_type = new ObjectType (t);
-                       var cselfparam = new CCodeParameter ("self", get_ccode_name (this_type));
+                               var this_type = new ObjectType (t);
+                               var cselfparam = new CCodeParameter ("self", get_ccode_name (this_type));
 
-                       if (prop.get_accessor != null) {
-                               var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf (prop.name));
-                               vdeclarator.add_parameter (cselfparam);
-                               string creturn_type;
-                               if (returns_real_struct) {
-                                       var cvalueparam = new CCodeParameter ("value", get_ccode_name 
(prop.get_accessor.value_type) + "*");
-                                       vdeclarator.add_parameter (cvalueparam);
-                                       creturn_type = "void";
-                               } else {
-                                       creturn_type = get_ccode_name (prop.get_accessor.value_type);
-                               }
+                               if (prop.get_accessor != null) {
+                                       var vdeclarator = new CCodeFunctionDeclarator ("get_%s".printf 
(prop.name));
+                                       vdeclarator.add_parameter (cselfparam);
+                                       string creturn_type;
+                                       if (returns_real_struct) {
+                                               var cvalueparam = new CCodeParameter ("value", get_ccode_name 
(prop.get_accessor.value_type) + "*");
+                                               vdeclarator.add_parameter (cvalueparam);
+                                               creturn_type = "void";
+                                       } else {
+                                               creturn_type = get_ccode_name (prop.get_accessor.value_type);
+                                       }
 
-                               var array_type = prop.property_type as ArrayType;
-                               if (array_type != null) {
-                                       for (int dim = 1; dim <= array_type.rank; dim++) {
-                                               vdeclarator.add_parameter (new CCodeParameter 
(get_array_length_cname ("result", dim), "int*"));
+                                       var array_type = prop.property_type as ArrayType;
+                                       if (array_type != null) {
+                                               for (int dim = 1; dim <= array_type.rank; dim++) {
+                                                       vdeclarator.add_parameter (new CCodeParameter 
(get_array_length_cname ("result", dim), "int*"));
+                                               }
                                        }
-                               }
 
-                               var vdecl = new CCodeDeclaration (creturn_type);
-                               vdecl.add_declarator (vdeclarator);
-                               type_struct.add_declaration (vdecl);
-                       }
-                       if (prop.set_accessor != null) {
-                               var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf (prop.name));
-                               vdeclarator.add_parameter (cselfparam);
-                               if (returns_real_struct) {
-                                       var cvalueparam = new CCodeParameter ("value", get_ccode_name 
(prop.set_accessor.value_type) + "*");
-                                       vdeclarator.add_parameter (cvalueparam);
-                               } else {
-                                       var cvalueparam = new CCodeParameter ("value", get_ccode_name 
(prop.set_accessor.value_type));
-                                       vdeclarator.add_parameter (cvalueparam);
+                                       var vdecl = new CCodeDeclaration (creturn_type);
+                                       vdecl.add_declarator (vdeclarator);
+                                       type_struct.add_declaration (vdecl);
                                }
+                               if (prop.set_accessor != null) {
+                                       var vdeclarator = new CCodeFunctionDeclarator ("set_%s".printf 
(prop.name));
+                                       vdeclarator.add_parameter (cselfparam);
+                                       if (returns_real_struct) {
+                                               var cvalueparam = new CCodeParameter ("value", get_ccode_name 
(prop.set_accessor.value_type) + "*");
+                                               vdeclarator.add_parameter (cvalueparam);
+                                       } else {
+                                               var cvalueparam = new CCodeParameter ("value", get_ccode_name 
(prop.set_accessor.value_type));
+                                               vdeclarator.add_parameter (cvalueparam);
+                                       }
 
-                               var array_type = prop.property_type as ArrayType;
-                               if (array_type != null) {
-                                       for (int dim = 1; dim <= array_type.rank; dim++) {
-                                               vdeclarator.add_parameter (new CCodeParameter 
(get_array_length_cname ("value", dim), "int"));
+                                       var array_type = prop.property_type as ArrayType;
+                                       if (array_type != null) {
+                                               for (int dim = 1; dim <= array_type.rank; dim++) {
+                                                       vdeclarator.add_parameter (new CCodeParameter 
(get_array_length_cname ("value", dim), "int"));
+                                               }
                                        }
-                               }
 
-                               var vdecl = new CCodeDeclaration ("void");
-                               vdecl.add_declarator (vdeclarator);
-                               type_struct.add_declaration (vdecl);
+                                       var vdecl = new CCodeDeclaration ("void");
+                                       vdecl.add_declarator (vdeclarator);
+                                       type_struct.add_declaration (vdecl);
+                               }
+                       } else {
+                               assert_not_reached ();
                        }
                }
 
diff --git a/vala/valainterface.vala b/vala/valainterface.vala
index 5780837..49bc0ae 100644
--- a/vala/valainterface.vala
+++ b/vala/valainterface.vala
@@ -33,6 +33,7 @@ public class Vala.Interface : ObjectTypeSymbol {
        private List<Constant> constants = new ArrayList<Constant> ();
        private List<Property> properties = new ArrayList<Property> ();
        private List<Signal> signals = new ArrayList<Signal> ();
+       private List<Symbol> virtuals = new ArrayList<Symbol> ();
 
        // inner types
        private List<Class> classes = new ArrayList<Class> ();
@@ -231,6 +232,10 @@ public class Vala.Interface : ObjectTypeSymbol {
                return signals;
        }
 
+       public virtual List<Symbol> get_virtuals () {
+               return virtuals;
+       }
+
        /**
         * Adds the specified class as an inner class.
         *
@@ -415,8 +420,11 @@ public class Vala.Interface : ObjectTypeSymbol {
 
                foreach (Method m in methods) {
                        m.check (context);
+                       if (m.is_virtual || m.is_abstract) {
+                               virtuals.add (m);
+                       }
                }
-               
+
                foreach (Field f in fields) {
                        f.check (context);
                }
@@ -425,18 +433,24 @@ public class Vala.Interface : ObjectTypeSymbol {
                        c.check (context);
                }
 
-               foreach (Property prop in properties) {
-                       prop.check (context);
-               }
-               
                foreach (Signal sig in signals) {
                        sig.check (context);
+                       if (sig.is_virtual) {
+                               virtuals.add (sig);
+                       }
                }
-               
+
+               foreach (Property prop in properties) {
+                       prop.check (context);
+                       if (prop.is_virtual || prop.is_abstract) {
+                               virtuals.add (prop);
+                       }
+               }
+
                foreach (Class cl in classes) {
                        cl.check (context);
                }
-               
+
                foreach (Struct st in structs) {
                        st.check (context);
                }
@@ -445,6 +459,54 @@ public class Vala.Interface : ObjectTypeSymbol {
                        d.check (context);
                }
 
+               Map<int, Symbol>? positions = new HashMap<int, Symbol> ();
+               bool ordered_seen = false;
+               bool unordered_seen = false;
+               foreach (Symbol sym in virtuals) {
+                       int ordering = sym.get_attribute_integer ("CCode", "ordering", -1);
+                       if (ordering < -1) {
+                               Report.error (sym.source_reference, "%s: Invalid ordering".printf 
(sym.get_full_name ()));
+                               // Mark state as invalid
+                               error = true;
+                               ordered_seen = true;
+                               unordered_seen = true;
+                               continue;
+                       }
+                       bool ordered = ordering != -1;
+                       if (ordered && unordered_seen && !ordered_seen) {
+                               Report.error (sym.source_reference, "%s: Cannot mix ordered and unordered 
virtuals".printf (sym.get_full_name ()));
+                               error = true;
+                       }
+                       ordered_seen = ordered_seen || ordered;
+                       if (!ordered && !unordered_seen && ordered_seen) {
+                               Report.error (sym.source_reference, "%s: Cannot mix ordered and unordered 
virtuals".printf (sym.get_full_name ()));
+                               error = true;
+                       }
+                       unordered_seen = unordered_seen || !ordered;
+                       if (!ordered_seen || !unordered_seen) {
+                               if (ordered) {
+                                       Symbol? prev = positions[ordering];
+                                       if (prev != null) {
+                                               Report.error (sym.source_reference, "%s: Duplicate ordering 
(previous virtual with the same position is %s)".printf (sym.get_full_name (), prev.name));
+                                               error = true;
+                                       }
+                                       positions[ordering] = sym;
+                               }
+                       }
+               }
+               if (ordered_seen) {
+                       for (int i = 0; i < virtuals.size; i++) {
+                               Symbol? sym = positions[i];
+                               if (sym == null) {
+                                       Report.error (source_reference, "%s: Gap in ordering in position 
%d".printf (get_full_name (), i));
+                                       error = true;
+                               }
+                               if (!error) {
+                                       virtuals[i] = sym;
+                               }
+                       }
+               }
+
                context.analyzer.current_source_file = old_source_file;
                context.analyzer.current_symbol = old_symbol;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]