add support for construct formal creation method parameters add testcase
authorRaffaele Sandrini <rasa@gmx.ch>
Sun, 4 Mar 2007 15:22:33 +0000 (15:22 +0000)
committerRaffaele Sandrini <rasa@src.gnome.org>
Sun, 4 Mar 2007 15:22:33 +0000 (15:22 +0000)
2007-03-04  Raffaele Sandrini  <rasa@gmx.ch>

* vala/valasemanticanalyzer.vala, vala/parser.y,
  vala/valaformalparameter.vala: add support for construct formal
  creation method parameters
* tests/test-029.vala, tests/test-029.out: add testcase for construct
  formal parameters
* tests/Makefile.am: update

svn path=/trunk/; revision=216

vala/ChangeLog
vala/tests/Makefile.am
vala/tests/test-029.out [new file with mode: 0644]
vala/tests/test-029.vala [new file with mode: 0644]
vala/vala/parser.y
vala/vala/valaformalparameter.vala
vala/vala/valasemanticanalyzer.vala

index fe23be7..1a089b7 100644 (file)
@@ -1,5 +1,14 @@
 2007-03-04  Raffaele Sandrini  <rasa@gmx.ch>
 
+       * vala/valasemanticanalyzer.vala, vala/parser.y,
+         vala/valaformalparameter.vala: add support for construct formal
+         creation method parameters
+       * tests/test-029.vala, tests/test-029.out: add testcase for construct
+         formal parameters
+       * tests/Makefile.am: update
+
+2007-03-04  Raffaele Sandrini  <rasa@gmx.ch>
+
        * vala/valaattributeprocessor.vala, vala/valacharacterliteral.vala,
          vala/valamethod.vala, vala/valasymbolbuilder.vala,
          vala/valacodevisitor.vala, vala/valainterfacewriter.vala,
index b1f77e5..be001c2 100644 (file)
@@ -31,6 +31,7 @@ TESTS = \
        test-026.vala \
        test-027.vala \
        test-028.vala \
+       test-029.vala \
        $(NULL)
 
 EXTRA_DIST = \
@@ -63,6 +64,7 @@ EXTRA_DIST = \
        test-026.vala \
        test-027.vala \
        test-028.vala \
+       test-029.vala \
        test-001.out \
        test-002.out \
        test-003.out \
@@ -91,4 +93,5 @@ EXTRA_DIST = \
        test-026.out \
        test-027.out \
        test-028.out \
+       test-029.out \
        $(NULL)
diff --git a/vala/tests/test-029.out b/vala/tests/test-029.out
new file mode 100644 (file)
index 0000000..4dcfda1
--- /dev/null
@@ -0,0 +1 @@
+Construct Formal Parameter Test: 1 2 3 4 5
diff --git a/vala/tests/test-029.vala b/vala/tests/test-029.vala
new file mode 100644 (file)
index 0000000..e913e82
--- /dev/null
@@ -0,0 +1,24 @@
+using GLib;
+
+class Maman.Foo {
+       public int p1 { get; set; }
+       public int p2 { get; set; }
+       
+       public Foo (int i, construct int p2) {
+               p1 = 2 * i;
+       }
+       
+       public static int main (string[] args) {
+               stdout.printf ("Construct Formal Parameter Test: 1");
+               
+               var foo = new Foo (2, 3);
+               
+               stdout.printf (" 2");
+               stdout.printf (" %d", foo.p2);
+               stdout.printf (" %d", foo.p1);
+               
+               stdout.printf (" 5\n", foo.p2);
+               
+               return 0;
+       }
+}
index 2c1a1c7..974286d 100644 (file)
@@ -324,6 +324,7 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
 %type <statement> method_body
 %type <list> opt_formal_parameter_list
 %type <list> formal_parameter_list
+%type <num> opt_construct
 %type <list> fixed_parameters
 %type <formal_parameter> fixed_parameter
 %type <signal> signal_declaration
@@ -2365,34 +2366,47 @@ fixed_parameters
          }
        ;
 
+opt_construct
+       : /* empty */
+         {
+               $$ = FALSE;
+         }
+       | CONSTRUCT
+         {
+               $$ = TRUE;
+         }
+       ;
+
 fixed_parameter
-       : opt_attributes type IDENTIFIER
+       : opt_attributes opt_construct type IDENTIFIER
          {
-               if (vala_type_reference_get_is_ref ($2) && vala_type_reference_get_is_out ($2)) {
-                       vala_type_reference_set_takes_ownership ($2, TRUE);
-                       vala_type_reference_set_is_ref ($2, FALSE);
+               if (vala_type_reference_get_is_ref ($3) && vala_type_reference_get_is_out ($3)) {
+                       vala_type_reference_set_takes_ownership ($3, TRUE);
+                       vala_type_reference_set_is_ref ($3, FALSE);
                }
 
-               ValaSourceReference *src = src(@2);
-               $$ = vala_formal_parameter_new ($3, $2, src);
+               ValaSourceReference *src = src(@3);
+               $$ = vala_formal_parameter_new ($4, $3, src);
                g_object_unref (src);
-               g_object_unref ($2);
-               g_free ($3);
+               vala_formal_parameter_set_construct_parameter ($$, $2);
+               g_object_unref ($3);
+               g_free ($4);
          }
-       | opt_attributes type IDENTIFIER ASSIGN expression
+       | opt_attributes opt_construct type IDENTIFIER ASSIGN expression
          {
-               if (vala_type_reference_get_is_ref ($2) && vala_type_reference_get_is_out ($2)) {
-                       vala_type_reference_set_takes_ownership ($2, TRUE);
-                       vala_type_reference_set_is_ref ($2, FALSE);
+               if (vala_type_reference_get_is_ref ($3) && vala_type_reference_get_is_out ($3)) {
+                       vala_type_reference_set_takes_ownership ($3, TRUE);
+                       vala_type_reference_set_is_ref ($3, FALSE);
                }
 
-               ValaSourceReference *src = src(@2);
-               $$ = vala_formal_parameter_new ($3, $2, src);
+               ValaSourceReference *src = src(@3);
+               $$ = vala_formal_parameter_new ($4, $3, src);
                g_object_unref (src);
-               vala_formal_parameter_set_default_expression ($$, $5);
-               g_object_unref ($2);
-               g_free ($3);
-               g_object_unref ($5);
+               vala_formal_parameter_set_default_expression ($$, $6);
+               vala_formal_parameter_set_construct_parameter ($$, $2);
+               g_object_unref ($3);
+               g_free ($4);
+               g_object_unref ($6);
          }
        ;
 
index 9bdf96e..c699a18 100644 (file)
@@ -1,6 +1,6 @@
 /* valaformalparameter.vala
  *
- * Copyright (C) 2006  Jürg Billeter
+ * Copyright (C) 2006-2007  Jürg Billeter, Raffaele Sandrini
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,6 +18,7 @@
  *
  * Author:
  *     Jürg Billeter <j@bitron.ch>
+ *     Raffaele Sandrini <rasa@gmx.ch>
  */
 
 using GLib;
@@ -55,6 +56,12 @@ public class Vala.FormalParameter : CodeNode, Invokable {
        public bool no_array_length { get; set; }
        
        /**
+        * Specifies whether this parameter holds a value to be assigned to a
+        * construct property. This is only allowed in CreationMethod headers.
+        */
+       public bool construct_parameter { get; set; }
+       
+       /**
         * Creates a new formal parameter.
         *
         * @param name   parameter name
index 07a2ccc..956d6f2 100644 (file)
@@ -291,6 +291,32 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                                current_source_file.add_symbol_dependency (p.type_reference.data_type.symbol, SourceFileDependencyType.SOURCE);
                        }
                }
+               
+               /* special treatment for construct formal parameters used in creation methods */
+               if (p.construct_parameter) {
+                       if (!(p.symbol.parent_symbol.node is CreationMethod)) {
+                               p.error = true;
+                               Report.error (p.source_reference, "construct parameters are only allowed in type creation methods");
+                               return;
+                       }
+                       
+                       var method_body = ((CreationMethod)p.symbol.parent_symbol.node).body;
+                       var left = new MemberAccess.simple (p.name);
+                       var right = new MemberAccess.simple (p.name);
+                       
+                       /* try to lookup the requeted property */
+                       var prop_sym = current_class.symbol.lookup (p.name);
+                       if (prop_sym == null || !(prop_sym.node is Property)) {
+                               p.error = true;
+                               Report.error (p.source_reference, "class `%s' does not contain a property named `%s'".printf (current_class.symbol.get_full_name (), p.name));
+                               return;
+                       }
+                       left.symbol_reference = prop_sym;
+                       
+                       right.symbol_reference = p.symbol;
+                       
+                       method_body.add_statement (new ExpressionStatement (new Assignment (left, right)));
+               }
        }
 
        public override void visit_end_property (Property! prop) {