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,
test-026.vala \
test-027.vala \
test-028.vala \
+ test-029.vala \
$(NULL)
EXTRA_DIST = \
test-026.vala \
test-027.vala \
test-028.vala \
+ test-029.vala \
test-001.out \
test-002.out \
test-003.out \
test-026.out \
test-027.out \
test-028.out \
+ test-029.out \
$(NULL)
--- /dev/null
+Construct Formal Parameter Test: 1 2 3 4 5
--- /dev/null
+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;
+ }
+}
%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
}
;
+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);
}
;
/* 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
*
* Author:
* Jürg Billeter <j@bitron.ch>
+ * Raffaele Sandrini <rasa@gmx.ch>
*/
using GLib;
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
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) {