add support for construction methods add to_string method support storing
authorJürg Billeter <j@bitron.ch>
Wed, 2 Aug 2006 15:59:07 +0000 (15:59 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Wed, 2 Aug 2006 15:59:07 +0000 (15:59 +0000)
2006-08-02  Jürg Billeter  <j@bitron.ch>

* vala/parser.y, vala/valacodevisitor.vala, vala/valasymbolbuilder.vala,
  vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala,
  vala/valainterfacewriter.vala, vala/valaclass.vala,
  vala/valaexpressionstatement.vala, vala/valamethod.vala,
  vala/valaobjectcreationexpression.vala, vala/valastatement.vala,
  vala/valastruct.vala: add support for construction methods
* vala/valabooleanliteral.vala, vala/valaexpression.vala,
  vala/valaintegerliteral.vala, vala/valaliteral.vala,
  vala/valaliteralexpression.vala, vala/valamemberaccess.vala: add
  to_string method
* vala/valamemberaccess.vala, vala/valatypereference.vala: support
  storing type arguments in MemberAccess
* vala/valacodenode.vala: add parent_node property
* vala/parser.y, vala/valaifstatement.vala: only allow blocks as
  embedded statements
* vala/valaenum.vala: implement get_type_id method
* vala/valainterfacewriter.vala: output default expressions of formal
  parameters
* vala/valaformalparameter.vala: visit default expression
* vala/valaobjectcreationexpression.vala, vala/valanullliteral.vala,
  vala/valaproperty.vala, vala/valapropertyaccessor.vala: add interface
  documentation, use implicit namespace specification
* vala/vala.h: add valaelementaccess.h and valarealliteral.h
* ccode/valaccodememberaccess.vala: don't mark is_pointer as construct
* vapi/glib-2.0.vala: add GValue
* vapi/gtk+-2.0.vala: small updates

svn path=/trunk/; revision=88

31 files changed:
vala/ChangeLog
vala/ccode/valaccodememberaccess.vala
vala/vala/parser.y
vala/vala/vala.h
vala/vala/valabooleanliteral.vala
vala/vala/valaclass.vala
vala/vala/valacodegenerator.vala
vala/vala/valacodenode.vala
vala/vala/valacodevisitor.vala
vala/vala/valaenum.vala
vala/vala/valaexpression.vala
vala/vala/valaexpressionstatement.vala
vala/vala/valaformalparameter.vala
vala/vala/valaifstatement.vala
vala/vala/valaintegerliteral.vala
vala/vala/valainterfacewriter.vala
vala/vala/valaliteral.vala
vala/vala/valaliteralexpression.vala
vala/vala/valamemberaccess.vala
vala/vala/valamethod.vala
vala/vala/valanullliteral.vala
vala/vala/valaobjectcreationexpression.vala
vala/vala/valaproperty.vala
vala/vala/valapropertyaccessor.vala
vala/vala/valasemanticanalyzer.vala
vala/vala/valastatement.vala
vala/vala/valastruct.vala
vala/vala/valasymbolbuilder.vala
vala/vala/valatypereference.vala
vala/vapi/glib-2.0.vala
vala/vapi/gtk+-2.0.vala

index 473cc00..7476dc1 100644 (file)
@@ -1,3 +1,32 @@
+2006-08-02  Jürg Billeter  <j@bitron.ch>
+
+       * vala/parser.y, vala/valacodevisitor.vala, vala/valasymbolbuilder.vala,
+         vala/valasemanticanalyzer.vala, vala/valacodegenerator.vala,
+         vala/valainterfacewriter.vala, vala/valaclass.vala,
+         vala/valaexpressionstatement.vala, vala/valamethod.vala,
+         vala/valaobjectcreationexpression.vala, vala/valastatement.vala,
+         vala/valastruct.vala: add support for construction methods
+       * vala/valabooleanliteral.vala, vala/valaexpression.vala,
+         vala/valaintegerliteral.vala, vala/valaliteral.vala,
+         vala/valaliteralexpression.vala, vala/valamemberaccess.vala: add
+         to_string method
+       * vala/valamemberaccess.vala, vala/valatypereference.vala: support
+         storing type arguments in MemberAccess
+       * vala/valacodenode.vala: add parent_node property
+       * vala/parser.y, vala/valaifstatement.vala: only allow blocks as
+         embedded statements
+       * vala/valaenum.vala: implement get_type_id method
+       * vala/valainterfacewriter.vala: output default expressions of formal
+         parameters
+       * vala/valaformalparameter.vala: visit default expression
+       * vala/valaobjectcreationexpression.vala, vala/valanullliteral.vala,
+         vala/valaproperty.vala, vala/valapropertyaccessor.vala: add interface
+         documentation, use implicit namespace specification
+       * vala/vala.h: add valaelementaccess.h and valarealliteral.h
+       * ccode/valaccodememberaccess.vala: don't mark is_pointer as construct
+       * vapi/glib-2.0.vala: add GValue
+       * vapi/gtk+-2.0.vala: small updates
+
 2006-07-31  Jürg Billeter  <j@bitron.ch>
 
        * vala/parser.y: support prefix increment and decrement, fix parsing
index e317751..bad06e4 100644 (file)
@@ -39,7 +39,7 @@ public class Vala.CCodeMemberAccess : CCodeExpression {
        /**
         * Specifies whether the member access happens by pointer dereferencing.
         */
-       public bool is_pointer { get; set construct; }
+       public bool is_pointer { get; set; }
        
        public override void write (CCodeWriter! writer) {
                inner.write (writer);
index aa30ea4..7ac0d7b 100644 (file)
@@ -199,6 +199,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %token <str> STRING_LITERAL "string"
 
 %type <str> comment
+%type <str> opt_identifier
 %type <literal> literal
 %type <literal> boolean_literal
 %type <type_reference> type_name
@@ -210,7 +211,6 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %type <expression> simple_name
 %type <expression> parenthesized_expression
 %type <expression> member_access
-%type <str> identifier_or_new
 %type <expression> invocation_expression
 %type <expression> element_access
 %type <expression> post_increment_expression
@@ -330,6 +330,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %type <list> type_argument_list
 %type <list> type_arguments
 %type <type_reference> type_argument
+%type <expression> member_name
 
 /* expect shift/reduce conflict on if/else */
 %expect 1
@@ -343,6 +344,14 @@ opt_comma
        | COMMA
        ;
 
+opt_identifier
+       : /* empty */
+         {
+               $$ = NULL;
+         }
+       | IDENTIFIER
+       ;
+
 literal
        : boolean_literal
        | INTEGER_LITERAL
@@ -525,12 +534,21 @@ primary_expression
        ;
 
 simple_name
-       : IDENTIFIER
+       : IDENTIFIER opt_type_argument_list
          {
                ValaSourceReference *src = src(@1);
                $$ = VALA_EXPRESSION (vala_member_access_new (NULL, $1, src));
                g_free ($1);
                g_object_unref (src);
+
+               if ($2 != NULL) {
+                       GList *l;
+                       for (l = $2; l != NULL; l = l->next) {
+                               vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($2);
+               }
          }
        ;
 
@@ -545,21 +563,22 @@ parenthesized_expression
        ;
 
 member_access
-       : primary_expression DOT identifier_or_new
+       : primary_expression DOT IDENTIFIER opt_type_argument_list
          {
                ValaSourceReference *src = src(@3);
                $$ = VALA_EXPRESSION (vala_member_access_new ($1, $3, src));
-               g_object_unref (src);
                g_object_unref ($1);
                g_free ($3);
-         }
-       ;
+               g_object_unref (src);
 
-identifier_or_new
-       : IDENTIFIER
-       | NEW
-         {
-               $$ = g_strdup ("new");
+               if ($4 != NULL) {
+                       GList *l;
+                       for (l = $4; l != NULL; l = l->next) {
+                               vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($4);
+               }
          }
        ;
 
@@ -616,15 +635,23 @@ post_decrement_expression
        ;
 
 object_creation_expression
-       : NEW type open_parens opt_named_argument_list CLOSE_PARENS
+       : NEW member_name open_parens opt_argument_list CLOSE_PARENS
          {
                ValaSourceReference *src = src(@2);
-               $$ = VALA_EXPRESSION (vala_object_creation_expression_new ($2, $4, src));
+               ValaObjectCreationExpression *expr = vala_object_creation_expression_new ($2, src);
                g_object_unref ($2);
+               g_object_unref (src);
+               
                if ($4 != NULL) {
+                       GList *l;
+                       for (l = $4; l != NULL; l = l->next) {
+                               vala_object_creation_expression_add_argument (expr, l->data);
+                               g_object_unref (l->data);
+                       }
                        g_list_free ($4);
                }
-               g_object_unref (src);
+               
+               $$ = VALA_EXPRESSION (expr);
          }
        ;
 
@@ -1157,38 +1184,26 @@ local_variable_declaration
 
 /* don't use type to prevent reduce/reduce conflict */
 local_variable_type
-       : primary_expression opt_type_argument_list opt_op_neg
+       : primary_expression opt_op_neg
          {
                ValaSourceReference *src = src(@1);
                $$ = vala_type_reference_new_from_expression ($1, src);
+               g_object_unref ($1);
                g_object_unref (src);
-               if ($3) {
+               if ($2) {
                        vala_type_reference_set_non_null ($$, TRUE);
                }
-               GList *l;
-               for (l = $2; l != NULL; l = l->next) {
-                       vala_type_reference_add_type_argument ($$, l->data);
-                       g_object_unref (l->data);
-               }
-               g_list_free ($2);
-               g_object_unref ($1);
          }
-       | REF primary_expression opt_type_argument_list opt_op_neg
+       | REF primary_expression opt_op_neg
          {
                ValaSourceReference *src = src(@2);
                $$ = vala_type_reference_new_from_expression ($2, src);
+               g_object_unref ($2);
                g_object_unref (src);
                vala_type_reference_set_takes_ownership ($$, TRUE);
-               if ($4) {
+               if ($3) {
                        vala_type_reference_set_non_null ($$, TRUE);
                }
-               GList *l;
-               for (l = $3; l != NULL; l = l->next) {
-                       vala_type_reference_add_type_argument ($$, l->data);
-                       g_object_unref (l->data);
-               }
-               g_list_free ($3);
-               g_object_unref ($2);
          }
        | local_variable_type array_qualifier
          {
@@ -1214,6 +1229,7 @@ expression_statement
                ValaSourceReference *src = src_com(@2, $1);
                $$ = VALA_STATEMENT (vala_expression_statement_new ($2, src));
                g_object_unref (src);
+               vala_code_node_set_parent_node (VALA_CODE_NODE ($2), VALA_CODE_NODE ($$));
                g_object_unref ($2);
          }
        ;
@@ -1234,20 +1250,47 @@ selection_statement
 if_statement
        : comment IF open_parens expression CLOSE_PARENS embedded_statement
          {
+               ValaBlock *true_block;
+               if (VALA_IS_BLOCK ($6)) {
+                       true_block = VALA_BLOCK ($6);
+               } else {
+                       true_block = vala_block_new (vala_code_node_get_source_reference (VALA_CODE_NODE ($6)));
+                       vala_block_add_statement (true_block, $6);
+                       g_object_unref ($6);
+               }
+
                ValaSourceReference *src = src_com(@4, $1);
-               $$ = VALA_STATEMENT (vala_if_statement_new ($4, $6, NULL, src));
+               $$ = VALA_STATEMENT (vala_if_statement_new ($4, true_block, NULL, src));
                g_object_unref (src);
                g_object_unref ($4);
-               g_object_unref ($6);
+               g_object_unref (true_block);
          }
        | comment IF open_parens expression CLOSE_PARENS embedded_statement ELSE embedded_statement
          {
+               ValaBlock *true_block;
+               if (VALA_IS_BLOCK ($6)) {
+                       true_block = VALA_BLOCK ($6);
+               } else {
+                       true_block = vala_block_new (vala_code_node_get_source_reference (VALA_CODE_NODE ($6)));
+                       vala_block_add_statement (true_block, $6);
+                       g_object_unref ($6);
+               }
+
+               ValaBlock *false_block;
+               if (VALA_IS_BLOCK ($8)) {
+                       false_block = VALA_BLOCK ($8);
+               } else {
+                       false_block = vala_block_new (vala_code_node_get_source_reference (VALA_CODE_NODE ($8)));
+                       vala_block_add_statement (false_block, $8);
+                       g_object_unref ($8);
+               }
+
                ValaSourceReference *src = src_com(@4, $1);
-               $$ = VALA_STATEMENT (vala_if_statement_new ($4, $6, $8, src));
+               $$ = VALA_STATEMENT (vala_if_statement_new ($4, true_block, false_block, src));
                g_object_unref (src);
                g_object_unref ($4);
-               g_object_unref ($6);
-               g_object_unref ($8);
+               g_object_unref (true_block);
+               g_object_unref (false_block);
          }
        ;
 
@@ -2061,7 +2104,7 @@ method_declaration
        ;
 
 method_header
-       : comment opt_attributes opt_access_modifier opt_modifiers type identifier_or_new OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+       : comment opt_attributes opt_access_modifier opt_modifiers type IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
          {
                GList *l;
                
@@ -2100,6 +2143,29 @@ method_header
                g_object_unref ($5);
                g_free ($6);
          }
+       | comment opt_attributes opt_access_modifier CONSTRUCT opt_identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+         {
+               GList *l;
+               
+               ValaSourceReference *src = src_com(@4, $1);
+               $$ = vala_method_new ($5, NULL, src);
+               g_free ($5);
+               g_object_unref (src);
+               vala_method_set_construction ($$, TRUE);
+               vala_method_set_instance ($$, FALSE);
+               if ($3 != 0) {
+                       $$->access = $3;
+               }
+               VALA_CODE_NODE($$)->attributes = $2;
+               
+               if ($7 != NULL) {
+                       for (l = $7; l != NULL; l = l->next) {
+                               vala_method_add_parameter ($$, l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($7);
+               }
+         }
        ;
 
 method_body
@@ -2272,7 +2338,7 @@ set_accessor_declaration
        ;
 
 signal_declaration
-       : comment opt_attributes opt_access_modifier SIGNAL type identifier_or_new OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON
+       : comment opt_attributes opt_access_modifier SIGNAL type IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON
          {
                GList *l;
                
@@ -2808,6 +2874,42 @@ open_parens
        | OPEN_CAST_PARENS
        ;
 
+member_name
+       : IDENTIFIER opt_type_argument_list
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_EXPRESSION (vala_member_access_new (NULL, $1, src));
+               g_free ($1);
+               g_object_unref (src);
+
+               if ($2 != NULL) {
+                       GList *l;
+                       for (l = $2; l != NULL; l = l->next) {
+                               vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($2);
+               }
+         }
+       | member_name DOT IDENTIFIER opt_type_argument_list
+         {
+               ValaSourceReference *src = src(@1);
+               $$ = VALA_EXPRESSION (vala_member_access_new ($1, $3, src));
+               g_object_unref ($1);
+               g_free ($3);
+               g_object_unref (src);
+
+               if ($4 != NULL) {
+                       GList *l;
+                       for (l = $4; l != NULL; l = l->next) {
+                               vala_member_access_add_type_argument (VALA_MEMBER_ACCESS ($$), l->data);
+                               g_object_unref (l->data);
+                       }
+                       g_list_free ($4);
+               }
+         }
+       ;
+
 %%
 
 extern FILE *yyin;
index 68ee28e..6dc8914 100644 (file)
@@ -16,6 +16,7 @@
 #include <vala/valadeclarationstatement.h>
 #include <vala/valadestructor.h>
 #include <vala/valadostatement.h>
+#include <vala/valaelementaccess.h>
 #include <vala/valaemptystatement.h>
 #include <vala/valaenum.h>
 #include <vala/valaenumvalue.h>
@@ -47,6 +48,7 @@
 #include <vala/valapostfixexpression.h>
 #include <vala/valaproperty.h>
 #include <vala/valapropertyaccessor.h>
+#include <vala/valarealliteral.h>
 #include <vala/valareturnstatement.h>
 #include <vala/valasignal.h>
 #include <vala/valasourcefile.h>
index a0fac5f..e58fa52 100644 (file)
@@ -45,4 +45,12 @@ public class Vala.BooleanLiteral : Literal {
        public override void accept (CodeVisitor! visitor) {
                visitor.visit_boolean_literal (this);
        }
+
+       public override ref string! to_string () {
+               if (value) {
+                       return "true";
+               } else {
+                       return "false";
+               }
+       }
 }
index 7461143..ef0e30e 100644 (file)
@@ -63,6 +63,11 @@ public class Vala.Class : DataType {
        private List<Signal> signals;
        
        /**
+        * Specifies the default construction method.
+        */
+       public Method default_construction_method { get; set; }
+       
+       /**
         * Specifies the instance constructor.
         */
        public Constructor constructor { get; set; }
index 30b48e2..8eb53c6 100644 (file)
@@ -61,6 +61,7 @@ public class Vala.CodeGenerator : CodeVisitor {
        private int next_temp_var_id = 0;
 
        TypeReference bool_type;
+       TypeReference int_type;
        TypeReference string_type;
 
        /**
@@ -76,6 +77,9 @@ public class Vala.CodeGenerator : CodeVisitor {
                bool_type = new TypeReference ();
                bool_type.data_type = (DataType) root_symbol.lookup ("bool").node;
 
+               int_type = new TypeReference ();
+               int_type.data_type = (DataType) root_symbol.lookup ("int").node;
+
                string_type = new TypeReference ();
                string_type.data_type = (DataType) root_symbol.lookup ("string").node;
        
@@ -359,16 +363,16 @@ public class Vala.CodeGenerator : CodeVisitor {
                        if (prop.type_reference.data_type is Class) {
                                cspec.call = new CCodeIdentifier (name = "g_param_spec_object");
                                cspec.add_argument (new CCodeIdentifier (name = prop.type_reference.data_type.get_upper_case_cname ("TYPE_")));
-                       } else if (prop.type_reference.type_name == "string") {
+                       } else if (prop.type_reference.data_type == string_type.data_type) {
                                cspec.call = new CCodeIdentifier (name = "g_param_spec_string");
                                cspec.add_argument (new CCodeConstant (name = "NULL"));
-                       } else if (prop.type_reference.type_name == "int"
+                       } else if (prop.type_reference.data_type == int_type.data_type
                                   || prop.type_reference.data_type is Enum) {
                                cspec.call = new CCodeIdentifier (name = "g_param_spec_int");
                                cspec.add_argument (new CCodeConstant (name = "G_MININT"));
                                cspec.add_argument (new CCodeConstant (name = "G_MAXINT"));
                                cspec.add_argument (new CCodeConstant (name = "0"));
-                       } else if (prop.type_reference.type_name == "bool") {
+                       } else if (prop.type_reference.data_type == bool_type.data_type) {
                                cspec.call = new CCodeIdentifier (name = "g_param_spec_boolean");
                                cspec.add_argument (new CCodeConstant (name = "FALSE"));
                        } else {
@@ -381,7 +385,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                        }
                        if (prop.set_accessor != null) {
                                pflags = "%s%s".printf (pflags, " | G_PARAM_WRITABLE");
-                               if (prop.set_accessor.construct_) {
+                               if (prop.set_accessor.construction) {
                                        if (prop.set_accessor.writable) {
                                                pflags = "%s%s".printf (pflags, " | G_PARAM_CONSTRUCT");
                                        } else {
@@ -574,6 +578,21 @@ public class Vala.CodeGenerator : CodeVisitor {
                source_type_member_definition.append (function);
        }
        
+       private ref CCodeIdentifier! get_value_setter_function (TypeReference! type_reference) {
+               if (type_reference.data_type is Class) {
+                       return new CCodeIdentifier (name = "g_value_set_object");
+               } else if (type_reference.data_type == string_type.data_type) {
+                       return new CCodeIdentifier (name = "g_value_set_string");
+               } else if (type_reference.type_name == "int"
+                          || type_reference.data_type is Enum) {
+                       return new CCodeIdentifier (name = "g_value_set_int");
+               } else if (type_reference.data_type == bool_type.data_type) {
+                       return new CCodeIdentifier (name = "g_value_set_boolean");
+               } else {
+                       return new CCodeIdentifier (name = "g_value_set_pointer");
+               }
+       }
+       
        private void add_get_property_function (Class! cl) {
                var get_prop = new CCodeFunction (name = "%s_get_property".printf (cl.get_lower_case_cname (null)), return_type = "void");
                get_prop.add_parameter (new CCodeFormalParameter (type_name = "GObject *", name = "object"));
@@ -600,18 +619,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                        var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "%s_get_%s".printf (cl.get_lower_case_cname (null), prop.name)));
                        ccall.add_argument (new CCodeIdentifier (name = "self"));
                        var csetcall = new CCodeFunctionCall ();
-                       if (prop.type_reference.data_type is Class) {
-                               csetcall.call = new CCodeIdentifier (name = "g_value_set_object");
-                       } else if (prop.type_reference.type_name == "string") {
-                               csetcall.call = new CCodeIdentifier (name = "g_value_set_string");
-                       } else if (prop.type_reference.type_name == "int"
-                                  || prop.type_reference.data_type is Enum) {
-                               csetcall.call = new CCodeIdentifier (name = "g_value_set_int");
-                       } else if (prop.type_reference.type_name == "bool") {
-                               csetcall.call = new CCodeIdentifier (name = "g_value_set_boolean");
-                       } else {
-                               csetcall.call = new CCodeIdentifier (name = "g_value_set_pointer");
-                       }
+                       csetcall.call = get_value_setter_function (prop.type_reference);
                        csetcall.add_argument (new CCodeIdentifier (name = "value"));
                        csetcall.add_argument (ccall);
                        ccase.add_statement (new CCodeExpressionStatement (expression = csetcall));
@@ -867,10 +875,6 @@ public class Vala.CodeGenerator : CodeVisitor {
        public override void visit_end_method (Method! m) {
                current_symbol = current_symbol.parent_symbol;
 
-               if (m.name == "init") {
-                       return;
-               }
-       
                function = new CCodeFunction (name = m.get_real_cname (), return_type = m.return_type.get_cname ());
                CCodeFunctionDeclarator vdeclarator = null;
                
@@ -962,6 +966,21 @@ public class Vala.CodeGenerator : CodeVisitor {
                                        source_type_member_definition.append (new CCodeComment (text = m.source_reference.comment));
                                }
                                source_type_member_definition.append (function);
+                               
+                               if (m.construction) {
+                                       // declare construction parameter array
+                                       var cparamsinit = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_new0"));
+                                       cparamsinit.add_argument (new CCodeIdentifier (name = "GParameter"));
+                                       cparamsinit.add_argument (new CCodeConstant (name = m.n_construction_params.to_string ()));
+                                       
+                                       var cdecl = new CCodeDeclaration (type_name = "GParameter *");
+                                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "__params", initializer = cparamsinit));
+                                       cinit.append (cdecl);
+                                       
+                                       cdecl = new CCodeDeclaration (type_name = "GParameter *");
+                                       cdecl.add_declarator (new CCodeVariableDeclarator (name = "__params_it", initializer = new CCodeIdentifier (name = "__params")));
+                                       cinit.append (cdecl);
+                               }
                        }
                }
                
@@ -1006,7 +1025,13 @@ public class Vala.CodeGenerator : CodeVisitor {
                        source_type_member_definition.append (vfunc);
                }
                
-               if (m.name == "main") {
+               if (m.construction) {
+                       var creturn = new CCodeReturnStatement ();
+                       creturn.return_expression = new CCodeIdentifier (name = "self");
+                       function.block.add_statement (creturn);
+               }
+               
+               if (m.name != null && m.name == "main") {
                        var cmain = new CCodeFunction (name = "main", return_type = "int");
                        cmain.add_parameter (new CCodeFormalParameter (type_name = "int", name = "argc"));
                        cmain.add_parameter (new CCodeFormalParameter (type_name = "char **", name = "argv"));
@@ -1044,7 +1069,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                this_type.data_type = cl;
                var cparam = new CCodeFormalParameter (type_name = this_type.get_cname (), name = "self");
                function.add_parameter (cparam);
-               if (acc.writable || acc.construct_) {
+               if (acc.writable || acc.construction) {
                        function.add_parameter (new CCodeFormalParameter (type_name = prop.type_reference.get_cname (), name = "value"));
                }
                
@@ -1130,16 +1155,41 @@ public class Vala.CodeGenerator : CodeVisitor {
        public override void visit_begin_block (Block! b) {
                current_symbol = b.symbol;
        }
+       
+       private void add_object_creation (CCodeBlock! b) {
+               var cl = (Class) current_type_symbol.node;
+       
+               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_newv"));
+               ccall.add_argument (new CCodeConstant (name = cl.get_type_id ()));
+               ccall.add_argument (new CCodeConstant (name = "__params_it - __params"));
+               ccall.add_argument (new CCodeConstant (name = "__params"));
+               
+               var cdecl = new CCodeVariableDeclarator (name = "self");
+               cdecl.initializer = ccall;
+               
+               var cdeclaration = new CCodeDeclaration (type_name = "%s *".printf (cl.get_cname ()));
+               cdeclaration.add_declarator (cdecl);
+               
+               b.add_statement (cdeclaration);
+       }
 
        public override void visit_end_block (Block! b) {
                var local_vars = b.get_local_variables ();
                foreach (VariableDeclarator decl in local_vars) {
                        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 (text = src.comment));
@@ -1154,6 +1204,11 @@ 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) {
@@ -1969,25 +2024,81 @@ public class Vala.CodeGenerator : CodeVisitor {
                }
        }
 
-       public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
-               if (expr.type_reference.data_type is Class) {
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_new"));
-                       
-                       ccall.add_argument (new CCodeConstant (name = expr.type_reference.data_type.get_upper_case_cname ("TYPE_")));
+       public override void visit_end_object_creation_expression (ObjectCreationExpression! expr) {
+               if (expr.symbol_reference == null) {
+                       // no construction method
+                       if (expr.type_reference.data_type is Class) {
+                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_object_new"));
+                               
+                               ccall.add_argument (new CCodeConstant (name = expr.type_reference.data_type.get_type_id ()));
 
-                       foreach (NamedArgument arg in expr.named_argument_list) {
-                               ccall.add_argument (new CCodeConstant (name = "\"%s\"".printf (arg.name)));
-                               ccall.add_argument ((CCodeExpression) arg.argument.ccodenode);
+                               ccall.add_argument (new CCodeConstant (name = "NULL"));
+                               
+                               expr.ccodenode = ccall;
+                       } else {
+                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_new0"));
+                               
+                               ccall.add_argument (new CCodeConstant (name = expr.type_reference.data_type.get_cname ()));
+                               
+                               ccall.add_argument (new CCodeConstant (name = "1"));
+                               
+                               expr.ccodenode = ccall;
                        }
-                       ccall.add_argument (new CCodeConstant (name = "NULL"));
-                       
-                       expr.ccodenode = ccall;
                } else {
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_new0"));
+                       // use construction method
+                       var m = (Method) expr.symbol_reference.node;
+                       var params = m.get_parameters ();
+       
+                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = m.get_cname ()));
+
+                       var i = 1;
+                       foreach (Expression arg in expr.get_argument_list ()) {
+                               /* explicitly use strong reference as ccall gets
+                                * unrefed at end of inner block
+                                */
+                               ref CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
+                               if (params != null) {
+                                       var param = (FormalParameter) params.data;
+                                       if (!param.ellipsis
+                                           && param.type_reference.data_type != null
+                                           && param.type_reference.data_type.is_reference_type ()
+                                           && arg.static_type.data_type != null
+                                           && param.type_reference.data_type != arg.static_type.data_type) {
+                                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = param.type_reference.data_type.get_upper_case_cname (null)));
+                                               ccall.add_argument (cexpr);
+                                               cexpr = ccall;
+                                       }
+                               }
+                       
+                               ccall.add_argument (cexpr);
+                               i++;
+                               
+                               if (params != null) {
+                                       params = params.next;
+                               }
+                       }
+                       while (params != null) {
+                               var param = (FormalParameter) params.data;
+                               
+                               if (param.ellipsis) {
+                                       break;
+                               }
+                               
+                               if (param.default_expression == null) {
+                                       Report.error (expr.source_reference, "no default expression for argument %d".printf (i));
+                                       return;
+                               }
+                               
+                               /* evaluate default expression here as the code
+                                * generator might not have visited the formal
+                                * parameter yet */
+                               param.default_expression.accept (this);
                        
-                       ccall.add_argument (new CCodeConstant (name = expr.type_reference.data_type.get_cname ()));
+                               ccall.add_argument ((CCodeExpression) param.default_expression.ccodenode);
+                               i++;
                        
-                       ccall.add_argument (new CCodeConstant (name = "1"));
+                               params = params.next;
+                       }
                        
                        expr.ccodenode = ccall;
                }
@@ -2059,60 +2170,91 @@ public class Vala.CodeGenerator : CodeVisitor {
                if (a.left.symbol_reference.node is Property) {
                        var prop = (Property) a.left.symbol_reference.node;
                        var cl = (Class) prop.symbol.parent_symbol.node;
-
-                       var set_func = "g_object_set";
                        
-                       if (!prop.no_accessor_method) {
-                               set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
-                       }
-                       
-                       var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = set_func));
+                       if (ma.inner == null && a.parent_node is Statement &&
+                           ((Statement) a.parent_node).construction) {
+                               // this property is used as a construction parameter
+                               var cpointer = new CCodeIdentifier (name = "__params_it");
+                               
+                               var ccomma = new CCodeCommaExpression ();
+                               // set name in array for current parameter
+                               var cnamemember = new CCodeMemberAccess (inner = cpointer, member_name = "name", is_pointer = true);
+                               var cnameassign = new CCodeAssignment (left = cnamemember, right = prop.get_canonical_cconstant ());
+                               ccomma.append_expression (cnameassign);
+                               
+                               var gvaluearg = new CCodeUnaryExpression (operator = CCodeUnaryOperator.ADDRESS_OF, inner = new CCodeMemberAccess (inner = cpointer, member_name = "value", is_pointer = true));
+                               
+                               // initialize GValue in array for current parameter
+                               var cvalueinit = new CCodeFunctionCall (call = new CCodeIdentifier (name = "g_value_init"));
+                               cvalueinit.add_argument (gvaluearg);
+                               cvalueinit.add_argument (new CCodeIdentifier (name = prop.type_reference.data_type.get_type_id ()));
+                               ccomma.append_expression (cvalueinit);
+                               
+                               // set GValue for current parameter
+                               var cvalueset = new CCodeFunctionCall (call = get_value_setter_function (prop.type_reference));
+                               cvalueset.add_argument (gvaluearg);
+                               cvalueset.add_argument ((CCodeExpression) a.right.ccodenode);
+                               ccomma.append_expression (cvalueset);
+                               
+                               // move pointer to next parameter in array
+                               ccomma.append_expression (new CCodeUnaryExpression (operator = CCodeUnaryOperator.POSTFIX_INCREMENT, inner = cpointer));
+                               
+                               a.ccodenode = ccomma;
+                       } else {
+                               var set_func = "g_object_set";
+                               
+                               if (!prop.no_accessor_method) {
+                                       set_func = "%s_set_%s".printf (cl.get_lower_case_cname (null), prop.name);
+                               }
+                               
+                               var ccall = new CCodeFunctionCall (call = new CCodeIdentifier (name = set_func));
 
-                       /* target instance is first argument */
-                       ref CCodeExpression instance;
-                       var req_cast = false;
+                               /* target instance is first argument */
+                               ref CCodeExpression instance;
+                               var req_cast = false;
 
-                       if (ma.inner == null) {
-                               instance = new CCodeIdentifier (name = "self");
-                               /* require casts for inherited properties */
-                               req_cast = (prop.symbol.parent_symbol != current_type_symbol);
-                       } else {
-                               instance = (CCodeExpression) ma.inner.ccodenode;
-                               /* require casts if the type of the used instance is
-                                * different than the type which declared the property */
-                               req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.data_type;
-                       }
-                       
-                       if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
-                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
-                               ccast.add_argument (instance);
-                               instance = ccast;
-                       }
+                               if (ma.inner == null) {
+                                       instance = new CCodeIdentifier (name = "self");
+                                       /* require casts for inherited properties */
+                                       req_cast = (prop.symbol.parent_symbol != current_type_symbol);
+                               } else {
+                                       instance = (CCodeExpression) ma.inner.ccodenode;
+                                       /* require casts if the type of the used instance is
+                                        * different than the type which declared the property */
+                                       req_cast = prop.symbol.parent_symbol.node != ma.inner.static_type.data_type;
+                               }
+                               
+                               if (req_cast && ((DataType) prop.symbol.parent_symbol.node).is_reference_type ()) {
+                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = ((DataType) prop.symbol.parent_symbol.node).get_upper_case_cname (null)));
+                                       ccast.add_argument (instance);
+                                       instance = ccast;
+                               }
 
-                       ccall.add_argument (instance);
+                               ccall.add_argument (instance);
+                                       
+                               ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
                                
-                       ref CCodeExpression cexpr = (CCodeExpression) a.right.ccodenode;
-                       
-                       if (prop.no_accessor_method) {
-                               /* property name is second argument of g_object_set */
-                               ccall.add_argument (prop.get_canonical_cconstant ());
-                       } else if (prop.type_reference.data_type != null
-                           && prop.type_reference.data_type.is_reference_type ()
-                           && a.right.static_type.data_type != null
-                           && prop.type_reference.data_type != a.right.static_type.data_type) {
-                               /* cast is necessary */
-                               var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = prop.type_reference.data_type.get_upper_case_cname (null)));
-                               ccast.add_argument (cexpr);
-                               cexpr = ccast;
-                       }
+                               if (prop.no_accessor_method) {
+                                       /* property name is second argument of g_object_set */
+                                       ccall.add_argument (prop.get_canonical_cconstant ());
+                               } else if (prop.type_reference.data_type != null
+                                   && prop.type_reference.data_type.is_reference_type ()
+                                   && a.right.static_type.data_type != null
+                                   && prop.type_reference.data_type != a.right.static_type.data_type) {
+                                       /* cast is necessary */
+                                       var ccast = new CCodeFunctionCall (call = new CCodeIdentifier (name = prop.type_reference.data_type.get_upper_case_cname (null)));
+                                       ccast.add_argument (cexpr);
+                                       cexpr = ccast;
+                               }
+                                       
+                               ccall.add_argument (cexpr);
                                
-                       ccall.add_argument (cexpr);
-                       
-                       if (prop.no_accessor_method) {
-                               ccall.add_argument (new CCodeConstant (name = "NULL"));
+                               if (prop.no_accessor_method) {
+                                       ccall.add_argument (new CCodeConstant (name = "NULL"));
+                               }
+                               
+                               a.ccodenode = ccall;
                        }
-                       
-                       a.ccodenode = ccall;
                } else if (a.left.symbol_reference.node is Signal) {
                        var sig = (Signal) a.left.symbol_reference.node;
                        
index f0042f4..fec5c82 100644 (file)
@@ -30,6 +30,11 @@ using GLib;
  */
 public abstract class Vala.CodeNode {
        /**
+        * Parent of this code node.
+        */
+       public CodeNode parent_node { get; set; }
+       
+       /**
         * Symbol that corresponds to this code node.
         */
        public Symbol symbol { get; set; }
index 7f1e982..74d2883 100644 (file)
@@ -588,11 +588,20 @@ public abstract class Vala.CodeVisitor {
        }
 
        /**
-        * Visit operation called for object creation expressions.
+        * Visit operation called at beginning of object creation
+        * expressions.
         *
         * @param expr an object creation expression
         */
-       public virtual void visit_object_creation_expression (ObjectCreationExpression! expr) {
+       public virtual void visit_begin_object_creation_expression (ObjectCreationExpression! expr) {
+       }
+
+       /**
+        * Visit operation called at end of object creation expressions.
+        *
+        * @param expr an object creation expression
+        */
+       public virtual void visit_end_object_creation_expression (ObjectCreationExpression! expr) {
        }
 
        /**
index 4a9e38c..1e1dcef 100644 (file)
@@ -139,4 +139,9 @@ public class Vala.Enum : DataType {
                        }
                }
        }
+
+       public override string get_type_id () {
+               // FIXME: use GType-registered enums
+               return "G_TYPE_INT";
+       }
 }
index 6fe357b..38ee3a1 100644 (file)
@@ -68,4 +68,6 @@ 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 ();
 }
index 8234970..ff35a13 100644 (file)
@@ -48,4 +48,21 @@ public class Vala.ExpressionStatement : Statement {
 
                visitor.visit_expression_statement (this);
        }
+
+       public override int get_number_of_set_construction_parameters () {
+               if (expression is Assignment) {
+                       var assign = (Assignment) expression;
+                       if (assign.left is MemberAccess) {
+                               var ma = (MemberAccess) assign.left;
+                               if (ma.symbol_reference != null) {
+                                       if (ma.symbol_reference.node is Property) {
+                                               var prop = (Property) ma.symbol_reference.node;
+                                               return 1;
+                                       }
+                               }
+                       }
+               }
+
+               return -1;
+       }
 }
index ebaea26..a252e34 100644 (file)
@@ -71,6 +71,10 @@ public class Vala.FormalParameter : CodeNode {
        public override void accept (CodeVisitor! visitor) {
                if (!ellipsis) {
                        type_reference.accept (visitor);
+                       
+                       if (default_expression != null) {
+                               default_expression.accept (visitor);
+                       }
                }
                
                visitor.visit_formal_parameter (this);
index d0cf494..2e09666 100644 (file)
@@ -34,12 +34,12 @@ public class Vala.IfStatement : Statement {
        /**
         * The statement to be evaluated if the condition holds.
         */
-       public Statement! true_statement { get; set construct; }
+       public Block! true_statement { get; set construct; }
        
        /**
         * The optional statement to be evaluated if the condition doesn't hold.
         */
-       public Statement false_statement { get; set construct; }
+       public Block false_statement { get; set construct; }
 
        /**
         * Creates a new if statement.
@@ -49,7 +49,7 @@ public class Vala.IfStatement : Statement {
         * @param false_stmt statement to be evaluated if condition is false
         * @return           newly created if statement
         */
-       public static ref IfStatement! new (Expression! cond, Statement! true_stmt, Statement false_stmt, SourceReference source) {
+       public static ref IfStatement! new (Expression! cond, Block! true_stmt, Block false_stmt, SourceReference source) {
                return (new IfStatement (condition = cond, true_statement = true_stmt, false_statement = false_stmt, source_reference = source));
        }
        
index 5f95c38..f96e666 100644 (file)
@@ -45,4 +45,8 @@ public class Vala.IntegerLiteral : Literal {
        public override void accept (CodeVisitor! visitor) {
                visitor.visit_integer_literal (this);
        }
+
+       public override ref string! to_string () {
+               return value;
+       }
 }
index 91eb89a..46ca460 100644 (file)
@@ -221,7 +221,9 @@ public class Vala.InterfaceWriter : CodeVisitor {
                write_indent ();
                write_string ("public ");
                
-               if (!m.instance) {
+               if (m.construction) {
+                       write_string ("construct ");
+               } else if (!m.instance) {
                        write_string ("static ");
                } else if (m.is_abstract) {
                        write_string ("abstract ");
@@ -229,18 +231,23 @@ public class Vala.InterfaceWriter : CodeVisitor {
                        write_string ("virtual ");
                }
                
-               var type = m.return_type.data_type;
-               if (type == null) {
-                       write_string ("void");
-               } else {
-                       if (m.return_type.transfers_ownership) {
-                               write_string ("ref ");
+               if (!m.construction) {
+                       var type = m.return_type.data_type;
+                       if (type == null) {
+                               write_string ("void");
+                       } else {
+                               if (m.return_type.transfers_ownership) {
+                                       write_string ("ref ");
+                               }
+                               write_string (m.return_type.data_type.symbol.get_full_name ());
                        }
-                       write_string (m.return_type.data_type.symbol.get_full_name ());
                }
                
-               write_string (" ");
-               write_identifier (m.name);
+               if (m.name != null) {
+                       write_string (" ");
+                       write_identifier (m.name);
+               }
+               
                write_string (" (");
                
                bool first = true;
@@ -273,6 +280,11 @@ public class Vala.InterfaceWriter : CodeVisitor {
                        
                        write_string (" ");
                        write_identifier (param.name);
+                       
+                       if (param.default_expression != null) {
+                               write_string (" = ");
+                               write_string (param.default_expression.to_string ());
+                       }
                }
                
                write_string (");");
@@ -313,7 +325,7 @@ public class Vala.InterfaceWriter : CodeVisitor {
                        if (prop.set_accessor.writable) {
                                write_string (" set");
                        }
-                       if (prop.set_accessor.construct_) {
+                       if (prop.set_accessor.construction) {
                                write_string (" construct");
                        }
                        write_string (";");
index 6f06088..aab9f21 100644 (file)
@@ -30,4 +30,6 @@ public abstract class Vala.Literal : CodeNode {
         * Specifies the type of this literal.
         */
        public TypeReference static_type { get; set; }
+       
+       public abstract ref string! to_string ();
 }
index 5c740f2..6a29a03 100644 (file)
@@ -47,4 +47,8 @@ public class Vala.LiteralExpression : Expression {
        
                visitor.visit_literal_expression (this);
        }
+
+       public override ref string! to_string () {
+               return literal.to_string ();
+       }
 }
index bc77ad1..c0bdde6 100644 (file)
@@ -35,6 +35,8 @@ public class Vala.MemberAccess : Expression {
         * The name of the member.
         */
        public string! member_name { get; set construct; }
+
+       private List<TypeReference> type_argument_list;
        
        /**
         * Creates a new member access expression.
@@ -48,6 +50,24 @@ public class Vala.MemberAccess : Expression {
                return new MemberAccess (inner = inner, member_name = member, source_reference = source);
        }
        
+       /**
+        * Appends the specified type as generic type argument.
+        *
+        * @param arg a type reference
+        */
+       public void add_type_argument (TypeReference! arg) {
+               type_argument_list.append (arg);
+       }
+       
+       /**
+        * Returns a copy of the list of generic type arguments.
+        *
+        * @return type argument list
+        */
+       public ref List<TypeReference> get_type_arguments () {
+               return type_argument_list.copy ();
+       }
+       
        public override void accept (CodeVisitor! visitor) {
                if (inner != null) {
                        inner.accept (visitor);
@@ -55,4 +75,12 @@ public class Vala.MemberAccess : Expression {
 
                visitor.visit_member_access (this);
        }
+
+       public override ref string! to_string () {
+               if (inner == null) {
+                       return member_name;
+               } else {
+                       return "%s.%s".printf (inner.to_string (), member_name);
+               }
+       }
 }
index 2da57d5..2234ece 100644 (file)
@@ -29,14 +29,14 @@ public class Vala.Method : CodeNode {
        /**
         * The symbol name of this method.
         */
-       public string! name { get; set construct; }
+       public string name { get; set; }
 
        /**
         * The return type of this method.
         */
-       public TypeReference! return_type { get; set construct; }
+       public TypeReference return_type { get; set; }
        
-       public Statement body { get; set; }
+       public Block body { get; set; }
        
        /**
         * Specifies the accessibility of this method. Public accessibility
@@ -77,6 +77,16 @@ public class Vala.Method : CodeNode {
         * of a base type.
         */
        public bool overrides { get; set; }
+       
+       /**
+        * Specifies whether this is a construction method.
+        */
+       public bool construction { get; set; }
+       
+       /**
+        * Specifies the number of parameters this construction method sets.
+        */
+       public int n_construction_params { get; set; }
 
        /**
         * Specifies whether the C method returns a new instance pointer which
@@ -115,7 +125,7 @@ public class Vala.Method : CodeNode {
         * @param source      reference to source code
         * @return            newly created method
         */
-       public static ref Method! new (string! name, TypeReference! return_type, SourceReference source) {
+       public static ref Method! new (string name, TypeReference return_type, SourceReference source) {
                return (new Method (name = name, return_type = return_type, source_reference = source));
        }
        
@@ -140,7 +150,9 @@ public class Vala.Method : CodeNode {
        public override void accept (CodeVisitor! visitor) {
                visitor.visit_begin_method (this);
                
-               return_type.accept (visitor);
+               if (return_type != null) {
+                       return_type.accept (visitor);
+               }
                
                foreach (FormalParameter param in parameters) {
                        param.accept (visitor);
@@ -162,7 +174,15 @@ public class Vala.Method : CodeNode {
                if (cname == null) {
                        var parent = symbol.parent_symbol.node;
                        if (parent is DataType) {
-                               cname = "%s_%s".printf (((DataType) parent).get_lower_case_cname (null), name);
+                               if (construction) {
+                                       if (name == null) {
+                                               cname = "%s_new".printf (((DataType) parent).get_lower_case_cname (null));
+                                       } else {
+                                               cname = "%s_new_%s".printf (((DataType) parent).get_lower_case_cname (null), name);
+                                       }
+                               } else {
+                                       cname = "%s_%s".printf (((DataType) parent).get_lower_case_cname (null), name);
+                               }
                        } else if (parent is Namespace) {
                                cname = "%s%s".printf (((Namespace) parent).get_lower_case_cprefix (), name);
                        } else {
index b506947..f835b81 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class NullLiteral : Literal {
-               public static ref NullLiteral! new (SourceReference source) {
-                       return (new NullLiteral (source_reference = source));
-               }
-               
-               public override void accept (CodeVisitor! visitor) {
-                       visitor.visit_null_literal (this);
-               }
+/**
+ * Represents a literal `null' in the source code.
+ */
+public class Vala.NullLiteral : Literal {
+       /**
+        * Creates a new null literal.
+        *
+        * @param source reference to source code
+        * @return       newly created null literal
+        */
+       public static ref NullLiteral! new (SourceReference source) {
+               return (new NullLiteral (source_reference = source));
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               visitor.visit_null_literal (this);
+       }
+
+       public override ref string! to_string () {
+               return "null";
        }
 }
index e5f4917..a12a949 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class ObjectCreationExpression : Expression {
-               public TypeReference type_reference { get; construct; }
-               public List<NamedArgument> named_argument_list { get; construct; }
+/**
+ * Represents an object creation expression in the source code.
+ */
+public class Vala.ObjectCreationExpression : Expression {
+       /**
+        * The object type to create.
+        */
+       public TypeReference type_reference { get; set; }
 
-               public static ref ObjectCreationExpression new (TypeReference type, List<NamedArgument> named_argument_list, SourceReference source) {
-                       return (new ObjectCreationExpression (type_reference = type, named_argument_list = named_argument_list, source_reference = source));
-               }
-               
-               public override void accept (CodeVisitor! visitor) {
+       /**
+        * The construction method to use. May be null to indicate that
+        * the default construction method should be used.
+        */
+       public Method constructor { get; set; }
+
+       /**
+        * The construction method to use or the data type to be created
+        * with the default construction method.
+        */
+       public MemberAccess member_name { get; set; }
+
+       private List<Expression> argument_list;
+
+       /**
+        * Creates a new object creation expression.
+        *
+        * @param type   object type to create
+        * @param source reference to source code
+        * @return       newly created object creation expression
+        */
+       public static ref ObjectCreationExpression! new (MemberAccess! name, SourceReference source) {
+               return (new ObjectCreationExpression (member_name = name, source_reference = source));
+       }
+       
+       /**
+        * Appends the specified expression to the list of arguments.
+        *
+        * @param arg an argument
+        */
+       public void add_argument (Expression! arg) {
+               argument_list.append (arg);
+       }
+       
+       /**
+        * Returns a copy of the argument list.
+        *
+        * @return argument list
+        */
+       public ref List<Expression> get_argument_list () {
+               return argument_list.copy ();
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               if (type_reference != null) {
                        type_reference.accept (visitor);
-                       
-                       foreach (NamedArgument arg in named_argument_list) {
-                               arg.accept (visitor);
-                       }
+               }
+
+               if (member_name != null) {
+                       member_name.accept (visitor);
+               }
                
-                       visitor.visit_object_creation_expression (this);
+               visitor.visit_begin_object_creation_expression (this);
+
+               foreach (Expression arg in argument_list) {
+                       arg.accept (visitor);
                }
+       
+               visitor.visit_end_object_creation_expression (this);
        }
 }
index a0b6ee4..b33ff70 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class Property : CodeNode {
-               public string name { get; construct; }
-               public TypeReference type_reference { get; construct; }
-               public PropertyAccessor get_accessor { get; construct; }
-               public PropertyAccessor set_accessor { get; construct; }
-               public MemberAccessibility access;
-               public FormalParameter this_parameter;
-               public bool no_accessor_method;
-               
-               public static ref Property new (string name, TypeReference type, PropertyAccessor get_accessor, PropertyAccessor set_accessor, SourceReference source) {
-                       return (new Property (name = name, type_reference = type, get_accessor = get_accessor, set_accessor = set_accessor, source_reference = source));
-               }
-               
-               public override void accept (CodeVisitor! visitor) {
-                       visitor.visit_begin_property (this);
+/**
+ * Represents a property declaration in the source code.
+ */
+public class Vala.Property : CodeNode {
+       /**
+        * The property name.
+        */
+       public string! name { get; set construct; }
+       
+       /**
+        * The property type.
+        */
+       public TypeReference! type_reference { get; set construct; }
+       
+       /**
+        * The get accessor of this property if available.
+        */
+       public PropertyAccessor get_accessor { get; set; }
+       
+       /**
+        * The set/construct accessor of this property if available.
+        */
+       public PropertyAccessor set_accessor { get; set; }
+       
+       /**
+        * Specifies the accessibility of this property. Public accessibility
+        * doesn't limit access. Default accessibility limits access to this
+        * program or library. Private accessibility limits access to the parent
+        * class.
+        */
+       public MemberAccessibility access { get; set; }
+       
+       /**
+        * Represents the generated ´this' parameter in this property.
+        */
+       public FormalParameter this_parameter { get; set; }
+       
+       /**
+        * Specifies whether the implementation of this property does not
+        * provide getter/setter methods.
+        */
+       public bool no_accessor_method { get; set; }
+       
+       /**
+        * Creates a new property.
+        *
+        * @param name         property name
+        * @param type         property type
+        * @param get_accessor get accessor
+        * @param set_accessor set/construct accessor
+        * @param source       reference to source code
+        * @return             newly created property
+        */
+       public static ref Property! new (string! name, TypeReference! type, PropertyAccessor get_accessor, PropertyAccessor set_accessor, SourceReference source) {
+               return (new Property (name = name, type_reference = type, get_accessor = get_accessor, set_accessor = set_accessor, source_reference = source));
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               visitor.visit_begin_property (this);
 
-                       type_reference.accept (visitor);
-                       
-                       if (get_accessor != null) {
-                               get_accessor.accept (visitor);
-                       }
-                       if (set_accessor != null) {
-                               set_accessor.accept (visitor);
-                       }
+               type_reference.accept (visitor);
                
-                       visitor.visit_end_property (this);
+               if (get_accessor != null) {
+                       get_accessor.accept (visitor);
                }
-               
-               public ref string get_upper_case_cname () {
-                       return "%s_%s".printf (((Class) symbol.parent_symbol.node).get_lower_case_cname (null), Namespace.camel_case_to_lower_case (name)).up ();
+               if (set_accessor != null) {
+                       set_accessor.accept (visitor);
                }
+       
+               visitor.visit_end_property (this);
+       }
+       
+       /**
+        * Returns the C name of this property in upper case. Words are
+        * separated by underscores. The upper case C name of the class is
+        * prefix of the result.
+        *
+        * @return the upper case name to be used in C code
+        */
+       public ref string! get_upper_case_cname () {
+               return "%s_%s".printf (((Class) symbol.parent_symbol.node).get_lower_case_cname (null), Namespace.camel_case_to_lower_case (name)).up ();
+       }
+       
+       /**
+        * Returns the string literal of this property to be used in C code.
+        *
+        * @return string literal to be used in C code
+        */
+       public ref CCodeConstant! get_canonical_cconstant () {
+               var str = String.new ("\"");
                
-               public ref CCodeConstant get_canonical_cconstant () {
-                       var str = String.new ("\"");
-                       
-                       string i = name;
-                       
-                       while (i.len () > 0) {
-                               unichar c = i.get_char ();
-                               if (c == '_') {
-                                       str.append_c ('-');
-                               } else {
-                                       str.append_unichar (c);
-                               }
-                               
-                               i = i.next_char ();
+               string i = name;
+               
+               while (i.len () > 0) {
+                       unichar c = i.get_char ();
+                       if (c == '_') {
+                               str.append_c ('-');
+                       } else {
+                               str.append_unichar (c);
                        }
                        
-                       str.append_c ('"');
-                       
-                       return new CCodeConstant (name = str.str);
+                       i = i.next_char ();
                }
                
-               public void process_attributes () {
-                       foreach (Attribute a in attributes) {
-                               if (a.name == "NoAccessorMethod") {
-                                       no_accessor_method = true;
-                               }
+               str.append_c ('"');
+               
+               return new CCodeConstant (name = str.str);
+       }
+       
+       /**
+        * Process all associated attributes.
+        */
+       public void process_attributes () {
+               foreach (Attribute a in attributes) {
+                       if (a.name == "NoAccessorMethod") {
+                               no_accessor_method = true;
                        }
                }
        }
index fecbd3d..5d33c7b 100644 (file)
 
 using GLib;
 
-namespace Vala {
-       public class PropertyAccessor : CodeNode {
-               public bool readable { get; construct; }
-               public bool writable { get; construct; }
-               public bool construct_ { get; construct; }
-               public Statement body { get; construct; }
-               public FormalParameter value_parameter;
-               
-               public static ref PropertyAccessor new (bool readable, bool writable, bool construct_, Statement body, SourceReference source) {
-                       return (new PropertyAccessor (readable = readable, writable = writable, construct_ = construct_, body = body, source_reference = source));
-               }
-               
-               public override void accept (CodeVisitor! visitor) {
-                       visitor.visit_begin_property_accessor (this);
+/**
+ * Represents a get or set accessor of a property in the source code.
+ */
+public class Vala.PropertyAccessor : CodeNode {
+       /**
+        * Specifies whether this accessor may be used to get the property.
+        */
+       public bool readable { get; set; }
+       
+       /**
+        * Specifies whether this accessor may be used to set the property.
+        */
+       public bool writable { get; set; }
+       
+       /**
+        * Specifies whether this accessor may be used to construct the
+        * property.
+        */
+       public bool construction { get; set; }
+       
+       /**
+        * The accessor body.
+        */
+       public Statement body { get; set; }
+       
+       /**
+        * Represents the generated value parameter in a set accessor.
+        */
+       public FormalParameter value_parameter { get; set; }
+       
+       /**
+        * Creates a new property accessor.
+        *
+        * @param readable     true if get accessor, false otherwise
+        * @param writable     true if set accessor, false otherwise
+        * @param construction true if construct accessor, false otherwise
+        * @param body         accessor body
+        * @param source       reference to source code
+        * @return             newly created property accessor
+        */
+       public static ref PropertyAccessor! new (bool readable, bool writable, bool construction, Statement body, SourceReference source) {
+               return (new PropertyAccessor (readable = readable, writable = writable, construction = construction, body = body, source_reference = source));
+       }
+       
+       public override void accept (CodeVisitor! visitor) {
+               visitor.visit_begin_property_accessor (this);
 
-                       if (body != null) {
-                               body.accept (visitor);
-                       }
-               
-                       visitor.visit_end_property_accessor (this);
+               if (body != null) {
+                       body.accept (visitor);
                }
+       
+               visitor.visit_end_property_accessor (this);
        }
 }
index 53cbf01..fd12b6d 100644 (file)
@@ -128,6 +128,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public override void visit_begin_method (Method! m) {
+               if (m.construction) {
+                       m.return_type = new TypeReference ();
+                       m.return_type.data_type = (DataType) current_symbol.node;
+                       m.return_type.transfers_ownership = true;
+                       
+                       if (m.body != null) {
+                               m.body.construction = true;
+                       }
+               }
+       
                current_symbol = m.symbol;
                current_return_type = m.return_type;
                
@@ -193,6 +203,19 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                return;
                        }
                }
+               
+               if (m.construction && m.body != 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) {
+                                       break;
+                               }
+                               n_params += params;
+                               stmt.construction = true;
+                       }
+                       m.n_construction_params = n_params;
+               }
        }
 
        public override void visit_formal_parameter (FormalParameter! p) {
@@ -744,45 +767,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
                }
        }
-
-       public override void visit_end_invocation_expression (InvocationExpression! expr) {
-               if (expr.error) {
-                       return;
-               }
-               
-               var msym = expr.call.symbol_reference;
-               
-               TypeReference ret_type;
-               List<FormalParameter> params;
-               
-               if (msym.node is VariableDeclarator) {
-                       var decl = (VariableDeclarator) msym.node;
-                       var cb = (Callback) decl.type_reference.data_type;
-                       ret_type = cb.return_type;
-                       params = cb.get_parameters ();
-               } else if (msym.node is FormalParameter) {
-                       var param = (FormalParameter) msym.node;
-                       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;
-                       params = m.get_parameters ();
-               } else if (msym.node is Signal) {
-                       var sig = (Signal) msym.node;
-                       ret_type = sig.return_type;
-                       params = sig.get_parameters ();
-               }
        
-               expr.static_type = ret_type;
-               
-               var args = expr.get_argument_list ();
+       private bool check_arguments (Expression! expr, Symbol! msym, List<FormalParameter> params, List<Expression> args) {
                List arg_it = args;
                
                bool ellipsis = false;
@@ -800,16 +786,18 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                        if (arg_it == null) {
                                if (param.default_expression == null) {
+                                       expr.error = true;
                                        Report.error (expr.source_reference, "Too few arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), args.length ()));
-                                       return;
+                                       return false;
                                }
                        } else {
                                var arg = (Expression) arg_it.data;
                                if (arg.static_type != null && !is_type_compatible (arg.static_type, param.type_reference)) {
                                        /* if there was an error in the argument,
                                         * i.e. arg.static_type == null, skip type check */
+                                       expr.error = true;
                                        Report.error (expr.source_reference, "Argument %d: Cannot convert from `%s' to `%s'".printf (i + 1, arg.static_type.to_string (), param.type_reference.to_string ()));
-                                       return;
+                                       return false;
                                }
                                
                                arg_it = arg_it.next;
@@ -819,9 +807,52 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                }
                
                if (!ellipsis && arg_it != null) {
+                       expr.error = true;
                        Report.error (expr.source_reference, "Too many arguments, method `%s' does not take %d arguments".printf (msym.get_full_name (), args.length ()));
+                       return false;
+               }
+               
+               return true;
+       }
+
+       public override void visit_end_invocation_expression (InvocationExpression! expr) {
+               if (expr.error) {
                        return;
                }
+               
+               var msym = expr.call.symbol_reference;
+               
+               TypeReference ret_type;
+               List<FormalParameter> params;
+               
+               if (msym.node is VariableDeclarator) {
+                       var decl = (VariableDeclarator) msym.node;
+                       var cb = (Callback) decl.type_reference.data_type;
+                       ret_type = cb.return_type;
+                       params = cb.get_parameters ();
+               } else if (msym.node is FormalParameter) {
+                       var param = (FormalParameter) msym.node;
+                       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;
+                       params = m.get_parameters ();
+               } else if (msym.node is Signal) {
+                       var sig = (Signal) msym.node;
+                       ret_type = sig.return_type;
+                       params = sig.get_parameters ();
+               }
+       
+               expr.static_type = ret_type;
+               
+               check_arguments (expr, msym, params, expr.get_argument_list ());
        }       
        
        public override void visit_element_access (ElementAccess! expr) {
@@ -851,33 +882,74 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                expr.static_type = expr.inner.static_type;
        }
 
-       public override void visit_object_creation_expression (ObjectCreationExpression! expr) {
-               if (expr.type_reference.data_type == null) {
-                       /* if type resolving didn't succeed, skip this check */
-                       return;
-               }
+       public override void visit_end_object_creation_expression (ObjectCreationExpression! expr) {
+               DataType type = null;
                
-               if (!expr.type_reference.data_type.is_reference_type ()) {
+               if (expr.type_reference == null) {
+                       if (expr.member_name == null) {
+                               expr.error = true;
+                               Report.error (expr.source_reference, "Incomplete object creation expression");
+                               return;
+                       }
+                       
+                       if (expr.member_name.symbol_reference == null) {
+                               expr.error = true;
+                               return;
+                       }
+                       
+                       var constructor_node = expr.member_name.symbol_reference.node;
+                       var type_node = expr.member_name.symbol_reference.node;
+                       
+                       if (constructor_node is Method) {
+                               type_node = constructor_node.symbol.parent_symbol.node;
+                               
+                               var constructor = (Method) constructor_node;
+                               if (!constructor.construction) {
+                                       expr.error = true;
+                                       Report.error (expr.source_reference, "`%s' is not a construction method".printf (constructor.symbol.get_full_name ()));
+                                       return;
+                               }
+                               
+                               expr.symbol_reference = constructor.symbol;
+                       }
+                       
+                       if (type_node is Class || type_node is Struct) {
+                               type = (DataType) type_node;
+                       } else {
+                               expr.error = true;
+                               Report.error (expr.source_reference, "`%s' is not a class or struct".printf (type.symbol.get_full_name ()));
+                               return;
+                       }
+               }
+       
+               if (!type.is_reference_type ()) {
                        expr.error = true;
                        Report.error (expr.source_reference, "Can't create instance of value type `%s'".printf (expr.type_reference.to_string ()));
                        return;
                }
        
-               current_source_file.add_symbol_dependency (expr.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
+               current_source_file.add_symbol_dependency (type.symbol, SourceFileDependencyType.SOURCE);
+
+               expr.type_reference = new TypeReference ();
+               expr.type_reference.data_type = type;
 
                expr.static_type = expr.type_reference.copy ();
                expr.static_type.transfers_ownership = true;
                
-               if (expr.type_reference.data_type is Class) {
-                       var cl = (Class) expr.type_reference.data_type;
+               if (type is Class) {
+                       var cl = (Class) type;
                        
                        if (cl.is_abstract) {
                                expr.static_type = null;
                                expr.error = true;
-                               Report.error (expr.source_reference, "Can't create instance of abstract class `%s'".printf (expr.type_reference.to_string ()));
+                               Report.error (expr.source_reference, "Can't create instance of abstract class `%s'".printf (cl.symbol.get_full_name ()));
                                return;
                        }
                        
+                       if (expr.symbol_reference == null && cl.default_construction_method != null) {
+                               expr.symbol_reference = cl.default_construction_method.symbol;
+                       }
+                       
                        while (cl != null) {
                                if (cl == initially_unowned_type) {
                                        expr.static_type.floating_reference = true;
@@ -886,12 +958,25 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        
                                cl = cl.base_class;
                        }
-               } else if (expr.named_argument_list.length () != 0) {
+               } else if (type is Struct) {
+                       var st = (Struct) type;
+               
+                       if (expr.symbol_reference == null && st.default_construction_method != null) {
+                               expr.symbol_reference = st.default_construction_method.symbol;
+                       }
+               }
+
+               if (expr.symbol_reference == null && expr.get_argument_list ().length () != 0) {
                        expr.static_type = null;
                        expr.error = true;
-                       Report.error (expr.source_reference, "No arguments allowed when constructing struct `%s'".printf (expr.type_reference.to_string ()));
+                       Report.error (expr.source_reference, "No arguments allowed when constructing type `%s'".printf (type.symbol.get_full_name ()));
                        return;
                }
+
+               if (expr.symbol_reference != null) {
+                       var m = (Method) expr.symbol_reference.node;
+                       check_arguments (expr, m.symbol, m.get_parameters (), expr.get_argument_list ());
+               }
        }
 
        public override void visit_unary_expression (UnaryExpression! expr) {
index f38ea1a..33793fd 100644 (file)
@@ -26,4 +26,20 @@ using GLib;
  * Base class for all statement types.
  */
 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.
+        *
+        * @return number of construction parameters set or -1
+        */
+       public virtual int get_number_of_set_construction_parameters () {
+               return -1;
+       }
 }
index 4397e6d..bd8282a 100644 (file)
@@ -40,6 +40,11 @@ public class Vala.Struct : DataType {
        string marshaller_type_name;
        
        /**
+        * Specifies the default construction method.
+        */
+       public Method default_construction_method { get; set; }
+       
+       /**
         * Creates a new struct.
         *
         * @param name   type name
index 764d1d4..3288891 100644 (file)
@@ -65,14 +65,20 @@ public class Vala.SymbolBuilder : CodeVisitor {
                current_symbol = current_symbol.parent_symbol;
        }
        
-       private Symbol add_symbol (string! name, CodeNode! node) {
-               if (current_symbol.lookup (name) != null) {
-                       node.error = true;
-                       Report.error (node.source_reference, "`%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), name));
-                       return null;
+       private Symbol add_symbol (string name, CodeNode! node) {
+               if (name != null) {
+                       if (current_symbol.lookup (name) != null) {
+                               node.error = true;
+                               Report.error (node.source_reference, "`%s' already contains a definition for `%s'".printf (current_symbol.get_full_name (), name));
+                               return null;
+                       }
                }
                node.symbol = new Symbol (node = node);
-               current_symbol.add (name, node.symbol);
+               if (name != null) {
+                       current_symbol.add (name, node.symbol);
+               } else {
+                       node.symbol.parent_symbol = current_symbol;
+               }
                
                return node.symbol;
        }
@@ -180,7 +186,23 @@ public class Vala.SymbolBuilder : CodeVisitor {
                        return;
                }
                
-               if (m.instance) {
+               if (m.construction) {
+                       var type_node = m.symbol.parent_symbol.node;
+                       if (!(type_node is Class || type_node is Struct)) {
+                               Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
+                       
+                               m.error = true;
+                               return;
+                       }
+               
+                       if (m.name == null) {
+                               if (type_node is Class) {
+                                       ((Class) type_node).default_construction_method = m;
+                               } else if (type_node is Struct) {
+                                       ((Struct) type_node).default_construction_method = m;
+                               }
+                       }
+               } else if (m.instance) {
                        if (!(m.symbol.parent_symbol.node is DataType)) {
                                Report.error (m.source_reference, "instance methods not allowed outside of data types");
                        
@@ -243,7 +265,7 @@ public class Vala.SymbolBuilder : CodeVisitor {
                        return;
                }
 
-               if (acc.writable || acc.construct_) {
+               if (acc.writable || acc.construction) {
                        acc.value_parameter = new FormalParameter (name = "value", type_reference = ((Property) current_symbol.parent_symbol.node).type_reference);
                        acc.value_parameter.symbol = new Symbol (node = acc.value_parameter);
                        
index ef6ad80..708ef1f 100644 (file)
@@ -126,14 +126,25 @@ public class Vala.TypeReference : CodeNode {
                string ns = null;
                string type_name = null;
                if (expr is MemberAccess) {
+                       TypeReference type_ref = null;
+               
                        MemberAccess ma = (MemberAccess) expr;
                        if (ma.inner != null) {
                                if (ma.inner is MemberAccess) {
                                        var simple = (MemberAccess) ma.inner;
-                                       return (new TypeReference (namespace_name = simple.member_name, type_name = ma.member_name, source_reference = source));
+                                       type_ref = new TypeReference (namespace_name = simple.member_name, type_name = ma.member_name, source_reference = source);
                                }
                        } else {
-                               return (new TypeReference (type_name = ma.member_name, source_reference = source));
+                               type_ref = new TypeReference (type_name = ma.member_name, source_reference = source);
+                       }
+                       
+                       if (type_ref != null) {
+                               var type_args = ma.get_type_arguments ();
+                               foreach (TypeReference arg in type_args) {
+                                       type_ref.add_type_argument (arg);
+                               }
+                               
+                               return type_ref;
                        }
                }
                
index a1a086b..81a974e 100644 (file)
@@ -214,6 +214,11 @@ namespace GLib {
        public abstract class InitiallyUnowned : Object {
        }
        
+       [ReferenceType (free_function = "g_free")]
+       public struct Value {
+               public Object get_object ();
+       }
+       
        [ReferenceType (dup_function = "g_main_loop_ref", free_function = "g_main_loop_unref")]
        public struct MainLoop {
                public static ref MainLoop new (MainContext context, bool is_running);
index 5b6b2ef..3cf68a5 100644 (file)
@@ -87,6 +87,10 @@ namespace Gtk {
                public bool use_markup { get; set; }
        }
        
+       public class ProgressBar : Widget {
+               public void pulse ();
+       }
+       
        public class StatusIcon {
                public static ref StatusIcon! new_from_stock (string! stock_id);
                
@@ -121,6 +125,13 @@ namespace Gtk {
        }
        
        public interface TreeModel {
+               public abstract void get_value (ref TreeIter iter, int column, GLib.Value value);
+       }
+       
+       public class TreeSelection {
+               public bool get_selected (out TreeModel model, ref TreeIter iter);
+       
+               public signal void changed ();
        }
        
        public struct TreeIter {
@@ -130,14 +141,23 @@ namespace Gtk {
                public pointer user_data3;
        }
        
+       [CCode (cprefix = "GTK_TREE_VIEW_COLUMN_")]
+       public enum TreeViewColumnSizing {
+               FIXED
+       }
+       
        public class TreeViewColumn : Object {
                [FloatingReference ()]
                public static ref TreeViewColumn new_with_attributes (string title, CellRenderer cell, ...);
+               
+               public int fixed_width { get; set; }
+               public TreeViewColumnSizing sizing { get; set; }
        }
        
        public class TreeView : Container {
                public TreeModel model { get; set; }
                
+               public TreeSelection get_selection ();
                public int append_column (TreeViewColumn column);
        }
        
@@ -190,6 +210,9 @@ namespace Gtk {
                public static ref VBox new (bool homogeneous, int spacing);
        }
        
+       public class VPaned : Paned {
+       }
+       
        public class Notebook : Container {
                public int append_page (Widget child, Widget tab_label);
        }
@@ -222,9 +245,14 @@ namespace Gtk {
                public signal void destroy ();
        }
        
+       public abstract class Paned : Container {
+               public void pack2 (Widget! child, bool resize, bool shrink);
+       }
+       
        public abstract class Widget : Object {
                public void show ();
                public void show_all ();
+               public void hide ();
                
                [NoAccessorMethod ()]
                public bool visible { get; set; }