Treat the result of two concatenated string constants as constant, fixes
authorJürg Billeter <j@bitron.ch>
Fri, 17 Oct 2008 11:57:31 +0000 (11:57 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 17 Oct 2008 11:57:31 +0000 (11:57 +0000)
2008-10-17  Jürg Billeter  <j@bitron.ch>

* vala/valabinaryexpression.vala:
* vala/valaexpression.vala:
* vala/valaliteral.vala:
* vala/valamemberaccess.vala:
* vala/valasemanticanalyzer.vala:
* gobject/valaccodegenerator.vala:

Treat the result of two concatenated string constants as constant,
fixes bug 516287

svn path=/trunk/; revision=1848

ChangeLog
gobject/valaccodegenerator.vala
vala/valabinaryexpression.vala
vala/valaexpression.vala
vala/valaliteral.vala
vala/valamemberaccess.vala
vala/valasemanticanalyzer.vala

index d34702b..6dee068 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2008-10-17  Jürg Billeter  <j@bitron.ch>
 
+       * vala/valabinaryexpression.vala:
+       * vala/valaexpression.vala:
+       * vala/valaliteral.vala:
+       * vala/valamemberaccess.vala:
+       * vala/valasemanticanalyzer.vala:
+       * gobject/valaccodegenerator.vala:
+
+       Treat the result of two concatenated string constants as constant,
+       fixes bug 516287
+
+2008-10-17  Jürg Billeter  <j@bitron.ch>
+
        * vala/valasemanticanalyzer.vala:
        * gobject/valaccodegenerator.vala:
 
index 4412dff..2d5d45f 100644 (file)
@@ -3665,13 +3665,32 @@ public class Vala.CCodeGenerator : CodeGenerator {
                    && !(expr.right.value_type is NullType)
                    && expr.right.value_type.compatible (string_type)) {
                        if (expr.operator == BinaryOperator.PLUS) {
-                               /* string concatenation: convert to g_strconcat (a, b, NULL) */
-                               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat"));
-                               ccall.add_argument (cleft);
-                               ccall.add_argument (cright);
-                               ccall.add_argument (new CCodeConstant("NULL"));
-                               expr.ccodenode = ccall;
-                               return;
+                               // string concatenation
+                               if (expr.left.is_constant () && expr.right.is_constant ()) {
+                                       string left, right;
+
+                                       if (cleft is CCodeIdentifier) {
+                                               left = ((CCodeIdentifier) cleft).name;
+                                       } else if (cleft is CCodeConstant) {
+                                               left = ((CCodeConstant) cleft).name;
+                                       }
+                                       if (cright is CCodeIdentifier) {
+                                               right = ((CCodeIdentifier) cright).name;
+                                       } else if (cright is CCodeConstant) {
+                                               right = ((CCodeConstant) cright).name;
+                                       }
+
+                                       expr.ccodenode = new CCodeConstant ("%s %s".printf (left, right));
+                                       return;
+                               } else {
+                                       // convert to g_strconcat (a, b, NULL)
+                                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_strconcat"));
+                                       ccall.add_argument (cleft);
+                                       ccall.add_argument (cright);
+                                       ccall.add_argument (new CCodeConstant("NULL"));
+                                       expr.ccodenode = ccall;
+                                       return;
+                               }
                        } else if (expr.operator == BinaryOperator.EQUALITY
                                   || expr.operator == BinaryOperator.INEQUALITY
                                   || expr.operator == BinaryOperator.LESS_THAN
index 36cc432..7d11bbe 100644 (file)
@@ -126,6 +126,10 @@ public class Vala.BinaryExpression : Expression {
                return _left.to_string () + get_operator_string () + _right.to_string ();
        }
 
+       public override bool is_constant () {
+               return left.is_constant () && right.is_constant ();
+       }
+
        public override bool is_pure () {
                return left.is_pure () && right.is_pure ();
        }
index c37098c..3cf02ca 100644 (file)
@@ -61,6 +61,14 @@ public abstract class Vala.Expression : CodeNode {
        public ArrayList<LocalVariable> temp_vars = new ArrayList<LocalVariable> ();
 
        /**
+        * Returns whether this expression is constant, i.e. whether this
+        * expression only consists of literals and other constants.
+        */
+       public virtual bool is_constant () {
+               return false;
+       }
+
+       /**
         * Returns whether this expression is pure, i.e. whether this expression
         * is free of side-effects.
         */
index df5e8d4..62f17a3 100644 (file)
@@ -26,6 +26,10 @@ using GLib;
  * Base class for all literals in the source code.
  */
 public abstract class Vala.Literal : Expression {
+       public override bool is_constant () {
+               return true;
+       }
+
        public override bool is_pure () {
                return true;
        }
index e5b8540..25b282e 100644 (file)
@@ -161,4 +161,12 @@ public class Vala.MemberAccess : Expression {
        public override CodeBinding? create_code_binding (CodeGenerator codegen) {
                return codegen.create_member_access_binding (this);
        }
+
+       public override bool is_constant () {
+               if (symbol_reference is Constant) {
+                       return true;
+               } else {
+                       return false;
+               }
+       }
 }
index 2d1704a..536b9d9 100644 (file)
@@ -3156,7 +3156,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        }
 
                        expr.value_type = string_type.copy ();
-                       expr.value_type.value_owned = true;
+                       if (expr.left.is_constant () && expr.right.is_constant ()) {
+                               expr.value_type.value_owned = false;
+                       } else {
+                               expr.value_type.value_owned = true;
+                       }
                } else if (expr.operator == BinaryOperator.PLUS
                           || expr.operator == BinaryOperator.MINUS
                           || expr.operator == BinaryOperator.MUL