From: Luca Bruno Date: Thu, 30 Jan 2014 23:10:57 +0000 (+0100) Subject: Fix coalescing operator X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c62bfa6b6d25b323b7dff2faa0709df33a51de72;p=thirdparty%2Fvala.git Fix coalescing operator --- diff --git a/codegen/valaccodetransformer.vala b/codegen/valaccodetransformer.vala index 6473a99ca..8e28b1f97 100644 --- a/codegen/valaccodetransformer.vala +++ b/codegen/valaccodetransformer.vala @@ -369,15 +369,15 @@ public class Vala.CCodeTransformer : CodeTransformer { } else { // store parent_node as we need to replace the expression in the old parent node later on var old_parent_node = expr.parent_node; - var formal_target_type = expr.target_type != null ? expr.target_type.copy () : null; - var target_type = expr.target_type != null ? expr.target_type.copy () : null; + var formal_target_type = copy_type (expr.target_type); + var target_type = copy_type (expr.target_type); push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); // FIXME: use create_temp_access behavior - var replacement = expression (b.add_temp_declaration (expr.value_type.copy (), expr, true)); + var replacement = expression (b.add_temp_declaration (copy_type (expr.value_type), expr, true)); - replacement.target_type = target_type.copy (); - replacement.formal_target_type = formal_target_type.copy (); + replacement.target_type = copy_type (target_type); + replacement.formal_target_type = copy_type (formal_target_type); context.analyzer.replaced_nodes.add (expr); old_parent_node.replace_expression (expr, replacement); b.check (this); @@ -391,8 +391,8 @@ public class Vala.CCodeTransformer : CodeTransformer { // convert to if statement Expression replacement = null; var old_parent_node = expr.parent_node; - var formal_target_type = expr.target_type != null ? expr.target_type.copy () : null; - var target_type = expr.target_type != null ? expr.target_type.copy () : null; + var formal_target_type = copy_type (expr.target_type); + var target_type = copy_type (expr.target_type); push_builder (new CodeBuilder (context, expr.parent_statement, expr.source_reference)); var result = b.add_temp_declaration (expr.value_type); @@ -443,7 +443,13 @@ public class Vala.CCodeTransformer : CodeTransformer { b.close (); replacement = expression (result); } else if (expr.operator == BinaryOperator.COALESCE) { - replacement = new ConditionalExpression (new BinaryExpression (BinaryOperator.EQUALITY, expr.left, new NullLiteral (expr.source_reference), expr.source_reference), expr.right, expr.left, expr.source_reference); + var is_owned = expr.left.value_type.value_owned || expr.right.value_type.value_owned; + var result = b.add_temp_declaration (copy_type (expr.value_type, is_owned, true), expr.left); + + b.open_if (expression (@"$result == null")); + b.add_assignment (expression (result), expr.right); + b.close (); + replacement = expression (result); } else if (expr.operator == BinaryOperator.IN && !(expr.left.value_type.compatible (context.analyzer.int_type) && expr.right.value_type.compatible (context.analyzer.int_type)) && !(expr.right.value_type is ArrayType)) { // neither enums nor array, it's contains() var call = new MethodCall (new MemberAccess (expr.right, "contains", expr.source_reference), expr.source_reference); @@ -519,4 +525,8 @@ public class Vala.CCodeTransformer : CodeTransformer { } } } + + public override void visit_assignment (Assignment a) { + a.accept_children (this); + } } diff --git a/vala/valacodetransformer.vala b/vala/valacodetransformer.vala index 31bed91f3..86e3a2d01 100644 --- a/vala/valacodetransformer.vala +++ b/vala/valacodetransformer.vala @@ -63,7 +63,11 @@ public class Vala.CodeTransformer : CodeVisitor { } } - public static DataType copy_type (DataType type, bool? value_owned = null, bool? nullable = null) { + public static DataType? copy_type (DataType? type, bool? value_owned = null, bool? nullable = null) { + if (type == null) { + return null; + } + var ret = type.copy (); if (value_owned != null) { ret.value_owned = value_owned;