From: Juerg Billeter Date: Mon, 14 Apr 2008 06:15:19 +0000 (+0000) Subject: don't require `new' operator for struct initialization, fixes bug 526547 X-Git-Tag: VALA_0_3_1~83 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3207fbbd5f3199feebcda29e1545b02cb637cbb7;p=thirdparty%2Fvala.git don't require `new' operator for struct initialization, fixes bug 526547 2008-04-14 Juerg Billeter * vala/valaobjectcreationexpression.vala, vala/valaparser.vala, vala/valasemanticanalyzer.vala: don't require `new' operator for struct initialization, fixes bug 526547 * tests/structs.vala: port to new syntax svn path=/trunk/; revision=1219 --- diff --git a/ChangeLog b/ChangeLog index 1bd8d3cd4..59be67010 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-04-14 Jürg Billeter + + * vala/valaobjectcreationexpression.vala, vala/valaparser.vala, + vala/valasemanticanalyzer.vala: don't require `new' operator for + struct initialization, fixes bug 526547 + + * tests/structs.vala: port to new syntax + 2008-04-13 Jürg Billeter * gobject/valaccodegeneratormethod.vala: remove warning about diff --git a/tests/structs.vala b/tests/structs.vala index 5f096f885..85db4a82f 100644 --- a/tests/structs.vala +++ b/tests/structs.vala @@ -35,7 +35,7 @@ static class StructsTest { } static void test_out_parameter (out SimpleStruct st) { - st = new SimpleStruct (); + st = SimpleStruct (); st.field = 3; } @@ -43,16 +43,16 @@ static class StructsTest { stdout.printf ("Structs Test:\n"); stdout.printf ("new SimpleStruct ()\n"); - var simple_struct = new SimpleStruct (); + var simple_struct = SimpleStruct (); stdout.printf ("new PublicStruct ()\n"); - var public_struct = new PublicStruct (); + var public_struct = PublicStruct (); stdout.printf ("new StructWithCreationMethod ()\n"); - var struct_with_creation_method = new StructWithCreationMethod (); + var struct_with_creation_method = StructWithCreationMethod (); stdout.printf ("new StructWithNamedCreationMethod ()\n"); - var struct_with_named_creation_method = new StructWithNamedCreationMethod.named (); + var struct_with_named_creation_method = StructWithNamedCreationMethod.named (); stdout.printf ("new SimpleStruct () { field = 1 }\n"); - simple_struct = new SimpleStruct () { field = 1 }; + simple_struct = SimpleStruct () { field = 1 }; stdout.printf ("simple_struct.field = %d\n", simple_struct.field); test_in_parameter (simple_struct); diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index 97653d42e..fb59e0256 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -50,6 +50,8 @@ public class Vala.ObjectCreationExpression : Expression { */ public MemberAccess member_name { get; set; } + public bool struct_creation { get; set; } + private Gee.List argument_list = new ArrayList (); private Gee.List object_initializer = new ArrayList (); diff --git a/vala/valaparser.vala b/vala/valaparser.vala index 0f67b22a3..503d61efd 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -537,12 +537,29 @@ public class Vala.Parser : CodeVisitor { expect (TokenType.OPEN_PARENS); var arg_list = parse_argument_list (); expect (TokenType.CLOSE_PARENS); + var init_list = parse_object_initializer (); - var expr = context.create_invocation_expression (inner, get_src (begin)); - foreach (Expression arg in arg_list) { - expr.add_argument (arg); + if (init_list.size > 0 && inner is MemberAccess) { + // struct creation expression + var member = (MemberAccess) inner; + member.creation_member = true; + + var expr = context.create_object_creation_expression (member, get_src (begin)); + expr.struct_creation = true; + foreach (Expression arg in arg_list) { + expr.add_argument (arg); + } + foreach (MemberInitializer initializer in init_list) { + expr.add_member_initializer (initializer); + } + return expr; + } else { + var expr = context.create_invocation_expression (inner, get_src (begin)); + foreach (Expression arg in arg_list) { + expr.add_argument (arg); + } + return expr; } - return expr; } Expression parse_element_access (SourceLocation begin, Expression inner) throws ParseError { @@ -1048,7 +1065,7 @@ public class Vala.Parser : CodeVisitor { if (operator != AssignmentOperator.NONE) { next (); var rhs = parse_expression (); - expr = context.create_assignment (expr, rhs, operator); + expr = context.create_assignment (expr, rhs, operator, get_src (begin)); } else if (current () == TokenType.OP_GT) { // >>= char* first_gt_pos = tokens[index].begin.pos; next (); @@ -1056,7 +1073,7 @@ public class Vala.Parser : CodeVisitor { if (current () == TokenType.OP_GE && tokens[index].begin.pos == first_gt_pos + 1) { next (); var rhs = parse_expression (); - expr = context.create_assignment (expr, rhs, AssignmentOperator.SHIFT_RIGHT); + expr = context.create_assignment (expr, rhs, AssignmentOperator.SHIFT_RIGHT, get_src (begin)); } else { prev (); break; diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index ecebf76ec..3172ff016 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -1551,6 +1551,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor { may_access_instance_members = true; } } + + if (expr.symbol_reference == null && expr.inner is MemberAccess && base_symbol is Struct) { + // check for named struct creation method + expr.symbol_reference = base_symbol.scope.lookup (".new." + expr.member_name); + } } if (expr.symbol_reference == null) { @@ -1682,6 +1687,20 @@ public class Vala.SemanticAnalyzer : CodeVisitor { var mtype = expr.call.static_type; + // check for struct construction + if (expr.call is MemberAccess && + (expr.call.symbol_reference is CreationMethod + || expr.call.symbol_reference is Struct)) { + var struct_creation_expression = context.create_object_creation_expression ((MemberAccess) expr.call, expr.source_reference); + struct_creation_expression.struct_creation = true; + foreach (Expression arg in expr.get_argument_list ()) { + struct_creation_expression.add_argument (arg); + } + expr.parent_node.replace_expression (expr, struct_creation_expression); + struct_creation_expression.accept (this); + return; + } + Collection params; if (mtype != null && mtype.is_invokable ()) { @@ -2211,6 +2230,12 @@ public class Vala.SemanticAnalyzer : CodeVisitor { if (type is Class) { var cl = (Class) type; + if (expr.struct_creation) { + expr.error = true; + Report.error (expr.source_reference, "syntax error, use `new' to create new objects"); + return; + } + if (cl.is_abstract) { expr.static_type = null; expr.error = true; @@ -2233,6 +2258,10 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } else if (type is Struct) { var st = (Struct) type; + if (!expr.struct_creation) { + Report.warning (expr.source_reference, "deprecated syntax, don't use `new' to initialize structs"); + } + expr.static_type.transfers_ownership = false; if (expr.symbol_reference == null) { @@ -2291,38 +2320,42 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } foreach (MemberInitializer init in expr.get_object_initializer ()) { - init.accept (this); + visit_member_initializer (init, expr.type_reference); + } + } - init.symbol_reference = symbol_lookup_inherited (expr.type_reference.data_type, init.name); - if (!(init.symbol_reference is Field || init.symbol_reference is Property)) { - expr.error = true; - Report.error (expr.source_reference, "Invalid member `%s' in `%s'".printf (init.name, expr.type_reference.data_type.get_full_name ())); - return; - } - if (init.symbol_reference.access != SymbolAccessibility.PUBLIC) { - expr.error = true; - Report.error (expr.source_reference, "Access to private member `%s' denied".printf (init.symbol_reference.get_full_name ())); - return; - } - DataType member_type; - if (init.symbol_reference is Field) { - var f = (Field) init.symbol_reference; - member_type = f.type_reference; - } else if (init.symbol_reference is Property) { - var prop = (Property) init.symbol_reference; - member_type = prop.type_reference; - if (prop.set_accessor == null || !prop.set_accessor.writable) { - expr.error = true; - Report.error (expr.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ())); - return; - } - } - if (init.initializer.static_type == null || !init.initializer.static_type.compatible (member_type)) { - expr.error = true; - Report.error (init.source_reference, "Invalid type for member `%s'".printf (init.name)); + void visit_member_initializer (MemberInitializer init, DataType type) { + init.accept (this); + + init.symbol_reference = symbol_lookup_inherited (type.data_type, init.name); + if (!(init.symbol_reference is Field || init.symbol_reference is Property)) { + init.error = true; + Report.error (init.source_reference, "Invalid member `%s' in `%s'".printf (init.name, type.data_type.get_full_name ())); + return; + } + if (init.symbol_reference.access != SymbolAccessibility.PUBLIC) { + init.error = true; + Report.error (init.source_reference, "Access to private member `%s' denied".printf (init.symbol_reference.get_full_name ())); + return; + } + DataType member_type; + if (init.symbol_reference is Field) { + var f = (Field) init.symbol_reference; + member_type = f.type_reference; + } else if (init.symbol_reference is Property) { + var prop = (Property) init.symbol_reference; + member_type = prop.type_reference; + if (prop.set_accessor == null || !prop.set_accessor.writable) { + init.error = true; + Report.error (init.source_reference, "Property `%s' is read-only".printf (prop.get_full_name ())); return; } } + if (init.initializer.static_type == null || !init.initializer.static_type.compatible (member_type)) { + init.error = true; + Report.error (init.source_reference, "Invalid type for member `%s'".printf (init.name)); + return; + } } public override void visit_sizeof_expression (SizeofExpression expr) {