From 489dc9ea8bbb65537289519883595e5d9812233b Mon Sep 17 00:00:00 2001 From: Raffaele Sandrini Date: Thu, 28 Sep 2006 12:21:08 +0000 Subject: [PATCH] add one dimensional array assignment support testcase for array 2006-09-28 Raffaele Sandrini * vala/valacodegenerator.vala, vala/valasemanticanalyzer.vala, vala/valamemorymanager.vala: add one dimensional array assignment support * tests/test-022.vala: testcase for array creation/assignment * tests/Makefile.am: update svn path=/trunk/; revision=137 --- vala/ChangeLog | 7 ++ vala/tests/Makefile.am | 1 + vala/tests/test-022.vala | 36 ++++++ vala/vala/valacodegenerator.vala | 10 +- vala/vala/valamemorymanager.vala | 2 +- vala/vala/valasemanticanalyzer.vala | 235 +++++++++++++++++++----------------- 6 files changed, 173 insertions(+), 118 deletions(-) create mode 100644 vala/tests/test-022.vala diff --git a/vala/ChangeLog b/vala/ChangeLog index 355a911..ffaa05d 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,3 +1,10 @@ +2006-09-28 Raffaele Sandrini + * vala/valacodegenerator.vala, vala/valasemanticanalyzer.vala, + vala/valamemorymanager.vala: add one dimensional array assignment + support + * tests/test-022.vala: testcase for array creation/assignment + * tests/Makefile.am: update + 2006-09-28 Jürg Billeter * vapi/glib-2.0.vala: add and improve various types diff --git a/vala/tests/Makefile.am b/vala/tests/Makefile.am index 128c8f4..b2a8ec8 100644 --- a/vala/tests/Makefile.am +++ b/vala/tests/Makefile.am @@ -22,4 +22,5 @@ EXTRA_DIST = \ test-019.vala \ test-020.vala \ test-021.vala \ + test-022.vala \ $(NULL) diff --git a/vala/tests/test-022.vala b/vala/tests/test-022.vala new file mode 100644 index 0000000..011f803 --- /dev/null +++ b/vala/tests/test-022.vala @@ -0,0 +1,36 @@ +using GLib; + +class Maman.Foo { + static int main (string[] args) { + stdout.printf ("One dimensional array creation and assignment: 1"); + + var a = new int[4] {1,2}; + + stdout.printf (" 2"); + + a[2] = 3; + + stdout.printf (" 3"); + + a[3] = 4; + + stdout.printf (" 4"); + + if (a[0] == 1) { + stdout.printf (" 5"); + } + if (a[1] == 2) { + stdout.printf (" 6"); + } + if (a[2] == 3) { + stdout.printf (" 7"); + } + if (a[3] == 4) { + stdout.printf (" 8"); + } + + stdout.printf (" 9\n"); + + return 0; + } +} diff --git a/vala/vala/valacodegenerator.vala b/vala/vala/valacodegenerator.vala index 774cff6..012349b 100644 --- a/vala/vala/valacodegenerator.vala +++ b/vala/vala/valacodegenerator.vala @@ -2671,9 +2671,13 @@ public class Vala.CodeGenerator : CodeVisitor { } public override void visit_end_assignment (Assignment! a) { - var ma = (MemberAccess) a.left; + MemberAccess ma = null; + + if (a.left is MemberAccess) { + ma = (MemberAccess)a.left; + } - if (a.left.symbol_reference.node is Property) { + if (a.left.symbol_reference != null && a.left.symbol_reference.node is Property) { var prop = (Property) a.left.symbol_reference.node; var cl = (Class) prop.symbol.parent_symbol.node; @@ -2787,7 +2791,7 @@ public class Vala.CodeGenerator : CodeVisitor { a.ccodenode = ccall; } - } else if (a.left.symbol_reference.node is Signal) { + } else if (a.left.symbol_reference != null && a.left.symbol_reference.node is Signal) { var sig = (Signal) a.left.symbol_reference.node; var m = (Method) a.right.symbol_reference.node; diff --git a/vala/vala/valamemorymanager.vala b/vala/vala/valamemorymanager.vala index 8abae2b..9182268 100644 --- a/vala/vala/valamemorymanager.vala +++ b/vala/vala/valamemorymanager.vala @@ -182,7 +182,7 @@ public class Vala.MemoryManager : CodeVisitor { } public override void visit_end_assignment (Assignment! a) { - if (a.left.symbol_reference.node is Signal) { + if (a.left is ElementAccess || a.left.symbol_reference.node is Signal) { } else { if (a.left.static_type.takes_ownership) { visit_possibly_missing_copy_expression (a.right); diff --git a/vala/vala/valasemanticanalyzer.vala b/vala/vala/valasemanticanalyzer.vala index a22897a..e22a03e 100644 --- a/vala/vala/valasemanticanalyzer.vala +++ b/vala/vala/valasemanticanalyzer.vala @@ -1009,7 +1009,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { expr.error = true; Report.error (e.source_reference, "Expression of type `int' expected"); } - } + } } public override void visit_postfix_expression (PostfixExpression! expr) { @@ -1435,25 +1435,26 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } public override void visit_begin_assignment (Assignment! a) { - if (!(a.left is MemberAccess)) { + if (a.left is MemberAccess) { + var ma = (MemberAccess) a.left; + + if (ma.error || ma.symbol_reference == null) { + a.error = true; + /* if no symbol found, skip this check */ + return; + } + + if (ma.symbol_reference.node is Signal) { + var sig = (Signal) ma.symbol_reference.node; + + a.right.expected_type = new TypeReference (); + a.right.expected_type.data_type = sig.get_callback (); + } + } else if (a.left is ElementAccess) { + // do nothing + } else { a.error = true; Report.error (a.source_reference, "unsupported lvalue in assignment"); - return; - } - - var ma = (MemberAccess) a.left; - - if (ma.error || ma.symbol_reference == null) { - a.error = true; - /* if no symbol found, skip this check */ - return; - } - - if (ma.symbol_reference.node is Signal) { - var sig = (Signal) ma.symbol_reference.node; - - a.right.expected_type = new TypeReference (); - a.right.expected_type.data_type = sig.get_callback (); } } @@ -1463,116 +1464,122 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return; } - var ma = (MemberAccess) a.left; - - if (ma.symbol_reference.node is Signal) { - var sig = (Signal) ma.symbol_reference.node; - - if (a.right.symbol_reference == null) { - a.error = true; - Report.error (a.right.source_reference, "unsupported expression for signal handler"); - return; - } - - var m = (Method) a.right.symbol_reference.node; + if (a.left is MemberAccess) { + var ma = (MemberAccess) a.left; - if (m.instance && m.access != MemberAccessibility.PRIVATE) { - /* TODO: generate wrapper function */ + if (ma.symbol_reference.node is Signal) { + var sig = (Signal) ma.symbol_reference.node; + + if (a.right.symbol_reference == null) { + a.error = true; + Report.error (a.right.source_reference, "unsupported expression for signal handler"); + return; + } - ma.error = true; - Report.error (a.right.source_reference, "public instance methods not yet supported as signal handlers"); - return; - } - - if (m.instance) { - /* instance signal handlers must have the self - * parameter at the end - * do not use G_CONNECT_SWAPPED as this would - * rearrange the parameters for instance - * methods and non-instance methods - */ - m.instance_last = true; - } - } else if (ma.symbol_reference.node is Property) { - var prop = (Property) ma.symbol_reference.node; - - if (prop.set_accessor == null) { - ma.error = true; - Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.symbol.get_full_name ())); - return; - } - } else if (ma.symbol_reference.node is VariableDeclarator && a.right.static_type == null) { - var decl = (VariableDeclarator) ma.symbol_reference.node; - - var right_ma = (MemberAccess) a.right; - if (right_ma.symbol_reference.node is Method && - decl.type_reference.data_type is Callback) { - var m = (Method) right_ma.symbol_reference.node; - var cb = (Callback) decl.type_reference.data_type; + var m = (Method) a.right.symbol_reference.node; - /* check whether method matches callback type */ - if (!cb.matches_method (m)) { - decl.error = true; - Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.symbol.get_full_name (), cb.symbol.get_full_name ())); + if (m.instance && m.access != MemberAccessibility.PRIVATE) { + /* TODO: generate wrapper function */ + + ma.error = true; + Report.error (a.right.source_reference, "public instance methods not yet supported as signal handlers"); return; } - a.right.static_type = decl.type_reference; - } else { - a.error = true; - Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt"); - return; - } - } else if (ma.symbol_reference.node is Field && a.right.static_type == null) { - var f = (Field) ma.symbol_reference.node; - - var right_ma = (MemberAccess) a.right; - if (right_ma.symbol_reference.node is Method && - f.type_reference.data_type is Callback) { - var m = (Method) right_ma.symbol_reference.node; - var cb = (Callback) f.type_reference.data_type; + if (m.instance) { + /* instance signal handlers must have the self + * parameter at the end + * do not use G_CONNECT_SWAPPED as this would + * rearrange the parameters for instance + * methods and non-instance methods + */ + m.instance_last = true; + } + } else if (ma.symbol_reference.node is Property) { + var prop = (Property) ma.symbol_reference.node; - /* check whether method matches callback type */ - if (!cb.matches_method (m)) { - f.error = true; - Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.symbol.get_full_name (), cb.symbol.get_full_name ())); + if (prop.set_accessor == null) { + ma.error = true; + Report.error (ma.source_reference, "Property `%s' is read-only".printf (prop.symbol.get_full_name ())); return; } + } else if (ma.symbol_reference.node is VariableDeclarator && a.right.static_type == null) { + var decl = (VariableDeclarator) ma.symbol_reference.node; - a.right.static_type = f.type_reference; - } else { - a.error = true; - Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt"); - return; - } - } else if (a.left.static_type != null && a.right.static_type != null) { - if (!is_type_compatible (a.right.static_type, a.left.static_type)) { - /* if there was an error on either side, - * i.e. a.{left|right}.static_type == null, skip type check */ - Report.error (a.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (a.right.static_type.to_string (), a.left.static_type.to_string ())); - return; - } - - if (memory_management) { - if (a.right.static_type.transfers_ownership) { - /* rhs transfers ownership of the expression */ - if (!a.left.static_type.takes_ownership) { - /* lhs doesn't own the value - * promote lhs type if it is a local variable - * error if it's not a local variable */ - if (!(ma.symbol_reference.node is VariableDeclarator)) { - Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable"); + var right_ma = (MemberAccess) a.right; + if (right_ma.symbol_reference.node is Method && + decl.type_reference.data_type is Callback) { + var m = (Method) right_ma.symbol_reference.node; + var cb = (Callback) decl.type_reference.data_type; + + /* check whether method matches callback type */ + if (!cb.matches_method (m)) { + decl.error = true; + Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.symbol.get_full_name (), cb.symbol.get_full_name ())); + return; + } + + a.right.static_type = decl.type_reference; + } else { + a.error = true; + Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt"); + return; + } + } else if (ma.symbol_reference.node is Field && a.right.static_type == null) { + var f = (Field) ma.symbol_reference.node; + + var right_ma = (MemberAccess) a.right; + if (right_ma.symbol_reference.node is Method && + f.type_reference.data_type is Callback) { + var m = (Method) right_ma.symbol_reference.node; + var cb = (Callback) f.type_reference.data_type; + + /* check whether method matches callback type */ + if (!cb.matches_method (m)) { + f.error = true; + Report.error (a.source_reference, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m.symbol.get_full_name (), cb.symbol.get_full_name ())); + return; + } + + a.right.static_type = f.type_reference; + } else { + a.error = true; + Report.error (a.source_reference, "Assignment: Invalid callback assignment attempt"); + return; + } + } else if (a.left.static_type != null && a.right.static_type != null) { + if (!is_type_compatible (a.right.static_type, a.left.static_type)) { + /* if there was an error on either side, + * i.e. a.{left|right}.static_type == null, skip type check */ + Report.error (a.source_reference, "Assignment: Cannot convert from `%s' to `%s'".printf (a.right.static_type.to_string (), a.left.static_type.to_string ())); + return; + } + + if (memory_management) { + if (a.right.static_type.transfers_ownership) { + /* rhs transfers ownership of the expression */ + if (!a.left.static_type.takes_ownership) { + /* lhs doesn't own the value + * promote lhs type if it is a local variable + * error if it's not a local variable */ + if (!(ma.symbol_reference.node is VariableDeclarator)) { + Report.error (a.source_reference, "Invalid assignment from owned expression to unowned variable"); + } + + a.left.static_type.takes_ownership = true; } - - a.left.static_type.takes_ownership = true; + } else if (a.left.static_type.takes_ownership) { + /* lhs wants to own the value + * rhs doesn't transfer the ownership + * code generator needs to add reference + * increment calls */ } - } else if (a.left.static_type.takes_ownership) { - /* lhs wants to own the value - * rhs doesn't transfer the ownership - * code generator needs to add reference - * increment calls */ } } + } else if (a.left is ElementAccess) { + // do nothing + } else { + return; } a.static_type = a.left.static_type; -- 2.7.4