support casts to generic types support arrays of generic types don't take
authorJürg Billeter <j@bitron.ch>
Wed, 4 Apr 2007 12:24:42 +0000 (12:24 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 4 Apr 2007 12:24:42 +0000 (12:24 +0000)
2007-04-04  Jürg Billeter  <j@bitron.ch>

* vala/scanner.l: support casts to generic types
* vala/valasymbolresolver.vala, vala/valatypereference.vala: support
  arrays of generic types
* vala/valasymbolresolver.vala: don't take ownership of elements of weak
  arrays
* vala/valasemanticanalyzer.vala: accept uint as index value
* vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala,
  vala/valastatement.vala: minor cleanup of creation methods
* vala/valacodegenerator.vala: support creation methods for structs, fix
  pointer as return type
* vapi/glib-2.0.vala: add CLAMP and g_spaced_primes_closest

svn path=/trunk/; revision=277

vala/ChangeLog
vala/vala/scanner.l
vala/vala/valacodegenerator.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valastatement.vala
vala/vala/valasymbolresolver.vala
vala/vala/valatypereference.vala
vala/vapi/glib-2.0.vala

index 572b547..6114ad8 100644 (file)
@@ -1,3 +1,17 @@
+2007-04-04  Jürg Billeter  <j@bitron.ch>
+
+       * vala/scanner.l: support casts to generic types
+       * vala/valasymbolresolver.vala, vala/valatypereference.vala: support
+         arrays of generic types
+       * vala/valasymbolresolver.vala: don't take ownership of elements of weak
+         arrays
+       * vala/valasemanticanalyzer.vala: accept uint as index value
+       * vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala,
+         vala/valastatement.vala: minor cleanup of creation methods
+       * vala/valacodegenerator.vala: support creation methods for structs, fix
+         pointer as return type
+       * vapi/glib-2.0.vala: add CLAMP and g_spaced_primes_closest
+
 2007-04-03  Jürg Billeter  <j@bitron.ch>
 
        * vapi/math.vala: add mathematical functions, patch by
index c66ab00..52a20a0 100644 (file)
@@ -73,7 +73,7 @@ literal                               ({integer_literal}|{real_literal}|{character_literal}|{string_literal
 
 "{"            { uploc; return OPEN_BRACE; }
 "}"            { uploc; return CLOSE_BRACE; }
-"("{space}{ident}("."{ident})?("["{space}"]")*{space}")"{space}("("|{ident}|{literal}) { yyless (1); uploc; return OPEN_CAST_PARENS; }
+"("{space}{ident}("."{ident})?("<"({ident}".")?{ident}">")?("["{space}"]")*{space}")"{space}("("|{ident}|{literal})    { yyless (1); uploc; return OPEN_CAST_PARENS; }
 "("            { uploc; return OPEN_PARENS; }
 ")"            { uploc; return CLOSE_PARENS; }
 "[]"           { uploc; return BRACKET_PAIR; }
index 53ae79b..c54e8dc 100644 (file)
@@ -72,6 +72,7 @@ public class Vala.CodeGenerator : CodeVisitor {
        HashTable<string,bool> predefined_marshal_list;
        
        private int next_temp_var_id = 0;
+       private bool in_creation_method = false;
 
        TypeReference bool_type;
        TypeReference char_type;
@@ -1211,7 +1212,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                } else {
                        ccheck.call = new CCodeIdentifier ("g_return_val_if_fail");
                        
-                       if (ret_type.is_reference_type ()) {
+                       if (ret_type.is_reference_type () || ret_type is Pointer) {
                                ccheck.add_argument (new CCodeConstant ("NULL"));
                        } else if (ret_type.get_default_value () != null) {
                                ccheck.add_argument (new CCodeConstant (ret_type.get_default_value ()));
@@ -1367,19 +1368,29 @@ public class Vala.CodeGenerator : CodeVisitor {
                                }
                                source_type_member_definition.append (function);
                                
-                               if (m is CreationMethod && current_class != null) {
-                                       // declare construction parameter array
-                                       var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
-                                       cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
-                                       cparamsinit.add_argument (new CCodeConstant (((CreationMethod)m).n_construction_params.to_string ()));
-                                       
-                                       var cdecl = new CCodeDeclaration ("GParameter *");
-                                       cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
-                                       cinit.append (cdecl);
-                                       
-                                       cdecl = new CCodeDeclaration ("GParameter *");
-                                       cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
-                                       cinit.append (cdecl);
+                               if (m is CreationMethod) {
+                                       if (current_class != null) {
+                                               // declare construction parameter array
+                                               var cparamsinit = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+                                               cparamsinit.add_argument (new CCodeIdentifier ("GParameter"));
+                                               cparamsinit.add_argument (new CCodeConstant (((CreationMethod)m).n_construction_params.to_string ()));
+                                               
+                                               var cdecl = new CCodeDeclaration ("GParameter *");
+                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params", cparamsinit));
+                                               cinit.append (cdecl);
+                                               
+                                               cdecl = new CCodeDeclaration ("GParameter *");
+                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("__params_it", new CCodeIdentifier ("__params")));
+                                               cinit.append (cdecl);
+                                       } else {
+                                               var st = (Struct) m.symbol.parent_symbol.node;
+                                               var cdecl = new CCodeDeclaration (st.get_cname () + "*");
+                                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_new0"));
+                                               ccall.add_argument (new CCodeConstant (st.get_cname ()));
+                                               ccall.add_argument (new CCodeConstant ("1"));
+                                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("self", ccall));
+                                               cinit.append (cdecl);
+                                       }
                                }
 
                                if (context.module_init_method == m && in_plugin) {
@@ -1470,9 +1481,16 @@ public class Vala.CodeGenerator : CodeVisitor {
        public override void visit_begin_creation_method (CreationMethod! m) {
                current_symbol = m.symbol;
                current_return_type = m.return_type;
+               in_creation_method = true;
        }
        
        public override void visit_end_creation_method (CreationMethod! m) {
+               if (current_class != null && m.body != null) {
+                       add_object_creation ((CCodeBlock) m.body.ccodenode);
+               }
+
+               in_creation_method = false;
+
                visit_end_method (m);
        }
        
@@ -1959,17 +1977,9 @@ public class Vala.CodeGenerator : CodeVisitor {
                        decl.symbol.active = false;
                }
                
-               bool in_construction = b.construction;
-       
                var cblock = new CCodeBlock ();
                
                foreach (Statement stmt in b.get_statements ()) {
-                       if (in_construction && !stmt.construction) {
-                               // construction part of construction method ends here
-                               add_object_creation (cblock);
-                               in_construction = false;
-                       }
-               
                        var src = stmt.source_reference;
                        if (src != null && src.comment != null) {
                                cblock.add_statement (new CCodeComment (src.comment));
@@ -1984,11 +1994,6 @@ public class Vala.CodeGenerator : CodeVisitor {
                        }
                }
                
-               if (in_construction) {
-                       // construction method doesn't contain non-construction parts
-                       add_object_creation (cblock);
-               }
-               
                if (memory_management) {
                        foreach (VariableDeclarator decl in local_vars) {
                                if (decl.type_reference.data_type.is_reference_type () && decl.type_reference.takes_ownership) {
@@ -3714,8 +3719,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                if (a.left.symbol_reference != null && a.left.symbol_reference.node is Property) {
                        var prop = (Property) a.left.symbol_reference.node;
                        
-                       if (ma.inner == null && a.parent_node is Statement &&
-                           ((Statement) a.parent_node).construction) {
+                       if (current_class != null && ma.inner == null && in_creation_method) {
                                // this property is used as a construction parameter
                                var cpointer = new CCodeIdentifier ("__params_it");
                                
index 60d3c32..4e30fe2 100644 (file)
@@ -44,6 +44,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        TypeReference bool_type;
        TypeReference string_type;
        TypeReference int_type;
+       TypeReference uint_type;
        TypeReference type_type;
        DataType pointer_type;
        DataType initially_unowned_type;
@@ -73,6 +74,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                int_type = new TypeReference ();
                int_type.data_type = (DataType) root_symbol.lookup ("int").node;
                
+               uint_type = new TypeReference ();
+               uint_type.data_type = (DataType) root_symbol.lookup ("uint").node;
+               
                // TODO: don't require GLib namespace in semantic analyzer
                var glib_ns = root_symbol.lookup ("GLib");
                if (glib_ns != null) {
@@ -405,10 +409,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
                }
                
-               if (m.body != null) {
-                       m.body.construction = true;
-               }
-               
                current_symbol = m.symbol;
                current_return_type = m.return_type;
        }
@@ -416,17 +416,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        public override void visit_end_creation_method (CreationMethod! m) {
                visit_end_method (m);
                
-               if (m.body != null) {
+               if (m.body != null && current_class != null) {
                        int n_params = 0;
                        foreach (Statement stmt in m.body.get_statements ()) {
                                int params = stmt.get_number_of_set_construction_parameters ();
                                if (params == -1) {
                                        m.error = true;
-                                       Report.error (stmt.source_reference, "type creation methods only allow property assignment statements");
+                                       Report.error (stmt.source_reference, "class creation methods only allow property assignment statements");
                                        return;
                                }
                                n_params += params;
-                               stmt.construction = true;
                        }
                        m.n_construction_params = n_params;
                }
@@ -1381,9 +1380,9 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
                        
                        /* check if the index is of type integer */
-                       if (e.static_type.data_type != int_type.data_type) {
+                       if (e.static_type.data_type != int_type.data_type && e.static_type.data_type != uint_type.data_type) {
                                expr.error = true;
-                               Report.error (e.source_reference, "Expression of type `int' expected");
+                               Report.error (e.source_reference, "Expression of type `int' or `uint` expected");
                        }
                }
        }
index 33793fd..75cc69a 100644 (file)
@@ -1,6 +1,6 @@
 /* valastatement.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
@@ -27,12 +27,6 @@ using GLib;
  */
 public abstract class Vala.Statement : CodeNode {
        /**
-        * Specifies whether this statement is in the construction part
-        * of a construction method.
-        */
-       public bool construction { get; set; }
-       
-       /**
         * Returns the number of construction parameters this statement sets in
         * maximum or -1 if this statement may not be used in the construction
         * part of a construction method.
index 3aae39c..483871b 100644 (file)
@@ -220,10 +220,14 @@ public class Vala.SymbolResolver : CodeVisitor {
                        var element_type = new TypeReference ();
                        element_type.data_type = type.data_type;
                        element_type.type_parameter = type.type_parameter;
+                       foreach (TypeReference type_arg in type.get_type_arguments ()) {
+                               element_type.add_type_argument (type_arg);
+                       }
+                       type.remove_all_type_arguments ();
                        
                        if (type.data_type != null) {
                                if (type.data_type.is_reference_type ()) {
-                                       element_type.takes_ownership = true;
+                                       element_type.takes_ownership = type.takes_ownership;
                                }
                                type.data_type = element_type.data_type.get_array (type.array_rank);
                        } else {
index e9da29a..1303f78 100644 (file)
@@ -180,7 +180,14 @@ public class Vala.TypeReference : CodeNode {
        public ref List<weak TypeReference> get_type_arguments () {
                return type_argument_list.copy ();
        }
-       
+
+       /**
+        * Removes all generic type arguments.
+        */
+       public void remove_all_type_arguments () {
+               type_argument_list = null;
+       }
+
        public override void accept (CodeVisitor! visitor) {
                foreach (TypeReference type_arg in type_argument_list) {
                        type_arg.accept (visitor);
index dca3f7b..e168163 100644 (file)
@@ -60,6 +60,9 @@ public struct int {
        [InstanceLast ()]
        [CCode (cname = "g_strdup_printf")]
        public ref string! to_string (string! format = "%i");
+
+       [CCode (cname = "CLAMP")]
+       public int clamp (int low, int high);
 }
 
 [CCode (cname = "guint", cheader_filename = "glib.h", type_id = "G_TYPE_UINT", marshaller_type_name = "UINT", get_value_function = "g_value_get_uint", set_value_function = "g_value_set_uint", default_value = "0U")]
@@ -73,6 +76,9 @@ public struct uint {
        [InstanceLast ()]
        [CCode (cname = "g_strdup_printf")]
        public ref string! to_string (string! format = "%u");
+
+       [CCode (cname = "CLAMP")]
+       public uint clamp (uint low, uint high);
 }
 
 [CCode (cname = "gshort", cheader_filename = "glib.h", default_value = "0")]
@@ -1058,7 +1064,11 @@ namespace GLib {
                [CCode (cname = "g_build_filename")]
                public static ref string build_filename (string first_element, ...);
        }
-       
+
+       public static class SpacedPrimes {
+               public static uint closest (uint num);
+       }
+
        /* Lexical Scanner */
        
        [ReferenceType (free_function = "g_scanner_destroy")]