objects/interface-property-override.vala \
objects/interface-virtual-override.vala \
objects/member-initializer-base-properties.vala \
+ objects/member-initializer-chained.vala \
+ objects/member-initializer-chained-2.vala \
objects/member-initializer-property.vala \
objects/member-initializer-property-owned-setter.vala \
objects/methods.vala \
--- /dev/null
+class Foo : Object {
+}
+
+class Bar {
+ public Foo a;
+ public Foo b { get; set; }
+ public Foo c;
+}
+
+void main () {
+ var bar = new Bar () {
+ a = b = c = new Foo ()
+ };
+ assert (bar.a != null);
+ assert (bar.a == bar.b);
+ assert (bar.a == bar.c);
+ assert (bar.a.ref_count == 4);
+}
--- /dev/null
+class Foo {
+ public int x;
+ public int y { get; set; }
+ public int z;
+}
+
+class Bar : Foo {
+ public Bar () {
+ x = 4711;
+ y = 4711;
+ z = 4711;
+ {
+ var foo = new Foo () {
+ x = y = z = 23
+ };
+ assert (foo.x == 23);
+ assert (foo.y == 23);
+ assert (foo.y == 23);
+ }
+ {
+ var foo2 = new Foo () {
+ z = 42,
+ y = z,
+ x = y
+ };
+ assert (foo2.x == 4711);
+ assert (foo2.y == 4711);
+ assert (foo2.z == 42);
+ }
+ assert (x == 4711);
+ assert (y == 4711);
+ assert (z == 4711);
+ }
+}
+
+int i = 67;
+
+int get_int () {
+ return i++;
+}
+
+void main () {
+ {
+ var bar = new Bar () {
+ x = y = z = get_int ()
+ };
+ assert (bar.x == 67);
+ assert (bar.y == 67);
+ assert (bar.z == 67);
+ }
+ {
+ var bar = new Bar () {
+ x = 23,
+ y = 42,
+ z = 67
+ };
+ assert (bar.x == 23);
+ assert (bar.y == 42);
+ assert (bar.z == 67);
+ }
+}
var begin = get_location ();
string id = parse_identifier ();
expect (TokenType.ASSIGN);
- var expr = parse_expression ();
+ var inner = get_location ();
+ Expression expr;
+ try {
+ // chained member initializer
+ expr = parse_member_initializer ();
+ } catch {
+ rollback (inner);
+ expr = parse_expression ();
+ }
return new MemberInitializer (id, expr, get_src (begin));
}
* Represents a member initializer, i.e. an element of an object initializer, in
* the source code.
*/
-public class Vala.MemberInitializer : CodeNode {
+public class Vala.MemberInitializer : Expression {
/**
* Member name.
*/
}
}
- /**
- * The symbol this expression refers to.
- */
- public weak Symbol symbol_reference { get; set; }
-
Expression _initializer;
/**
this.name = name;
}
+ public override bool is_pure () {
+ return false;
+ }
+
public override void accept (CodeVisitor visitor) {
initializer.accept (visitor);
}
context.analyzer.check_type (type_reference);
}
+ // Unwrap chained member initializers
foreach (MemberInitializer init in get_object_initializer ()) {
+ if (!(init.initializer is MemberInitializer)) {
+ continue;
+ }
+
+ int index = object_initializer.index_of (init);
+ object_initializer.remove_at (index);
+ assert (index >= 0);
+
+ unowned MemberInitializer? inner_mi = (MemberInitializer) init.initializer;
+ while (inner_mi.initializer is MemberInitializer) {
+ inner_mi = (MemberInitializer) inner_mi.initializer;
+ }
+
+ var local = new LocalVariable (null, get_temp_name (), inner_mi.initializer, inner_mi.initializer.source_reference);
+ var decl = new DeclarationStatement (local, inner_mi.initializer.source_reference);
+ decl.check (context);
+ insert_statement (context.analyzer.insert_block, decl);
+
+ do {
+ var member_init = new MemberInitializer (inner_mi.name, new MemberAccess (null, local.name, inner_mi.source_reference), inner_mi.source_reference);
+ object_initializer.insert (index++, member_init);
+ inner_mi = inner_mi.parent_node as MemberInitializer;
+ } while (inner_mi != null);
+ }
+ foreach (MemberInitializer init in get_object_initializer ()) {
+ init.parent_node = this;
init.check (context);
}
var begin = get_location ();
string id = parse_identifier ();
expect (TokenType.ASSIGN);
- var expr = parse_expression ();
+ var inner = get_location ();
+ Expression expr;
+ try {
+ // chained member initializer
+ expr = parse_member_initializer ();
+ } catch {
+ rollback (inner);
+ expr = parse_expression ();
+ }
return new MemberInitializer (id, expr, get_src (begin));
}