vala r2083 - in trunk: . gobject vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r2083 - in trunk: . gobject vala
- Date: Sat, 29 Nov 2008 12:20:31 +0000 (UTC)
Author: juergbi
Date: Sat Nov 29 12:20:30 2008
New Revision: 2083
URL: http://svn.gnome.org/viewvc/vala?rev=2083&view=rev
Log:
2008-11-29 JÃrg Billeter <j bitron ch>
* vala/Makefile.am:
* vala/valablock.vala:
* vala/valacodenode.vala:
* vala/valaconditionalexpression.vala:
* vala/valadeclarationstatement.vala:
* vala/valaexpression.vala:
* vala/valanullchecker.vala:
* vala/valastatementlist.vala:
* gobject/valaccodebasemodule.vala:
* gobject/valaccodegenerator.vala:
* gobject/valaccodemodule.vala:
Convert ternary conditionals into if statements,
fixes bug 543870 and bug 554594
Added:
trunk/vala/valastatementlist.vala
Modified:
trunk/ChangeLog
trunk/gobject/valaccodebasemodule.vala
trunk/gobject/valaccodegenerator.vala
trunk/gobject/valaccodemodule.vala
trunk/vala/Makefile.am
trunk/vala/valablock.vala
trunk/vala/valacodenode.vala
trunk/vala/valaconditionalexpression.vala
trunk/vala/valadeclarationstatement.vala
trunk/vala/valaexpression.vala
trunk/vala/valanullchecker.vala
Modified: trunk/gobject/valaccodebasemodule.vala
==============================================================================
--- trunk/gobject/valaccodebasemodule.vala (original)
+++ trunk/gobject/valaccodebasemodule.vala Sat Nov 29 12:20:30 2008
@@ -135,6 +135,8 @@
public Set<string> wrappers;
+ Map<string,string> variable_name_map = new HashMap<string,string> (str_hash, str_equal);
+
public CCodeBaseModule (CCodeGenerator codegen, CCodeModule? next) {
base (codegen, next);
@@ -1276,7 +1278,14 @@
}
public string get_variable_cname (string name) {
- if (c_keywords.contains (name)) {
+ if (name[0] == '.') {
+ // compiler-internal variable
+ if (!variable_name_map.contains (name)) {
+ variable_name_map.set (name, "_tmp%d".printf (next_temp_var_id));
+ next_temp_var_id++;
+ }
+ return variable_name_map.get (name);
+ } else if (c_keywords.contains (name)) {
return name + "_";
} else {
return name;
@@ -2886,10 +2895,6 @@
expr.ccodenode = create_type_check (expr.expression.ccodenode, expr.type_reference);
}
- public override void visit_conditional_expression (ConditionalExpression expr) {
- expr.ccodenode = new CCodeConditionalExpression ((CCodeExpression) expr.condition.ccodenode, (CCodeExpression) expr.true_expression.ccodenode, (CCodeExpression) expr.false_expression.ccodenode);
- }
-
public override void visit_lambda_expression (LambdaExpression l) {
// use instance position from delegate
var dt = (DelegateType) l.target_type;
Modified: trunk/gobject/valaccodegenerator.vala
==============================================================================
--- trunk/gobject/valaccodegenerator.vala (original)
+++ trunk/gobject/valaccodegenerator.vala Sat Nov 29 12:20:30 2008
@@ -323,10 +323,6 @@
head.visit_type_check (expr);
}
- public override void visit_conditional_expression (ConditionalExpression expr) {
- head.visit_conditional_expression (expr);
- }
-
public override void visit_lambda_expression (LambdaExpression l) {
head.visit_lambda_expression (l);
}
Modified: trunk/gobject/valaccodemodule.vala
==============================================================================
--- trunk/gobject/valaccodemodule.vala (original)
+++ trunk/gobject/valaccodemodule.vala Sat Nov 29 12:20:30 2008
@@ -320,10 +320,6 @@
next.visit_type_check (expr);
}
- public virtual void visit_conditional_expression (ConditionalExpression expr) {
- next.visit_conditional_expression (expr);
- }
-
public virtual void visit_lambda_expression (LambdaExpression l) {
next.visit_lambda_expression (l);
}
Modified: trunk/vala/Makefile.am
==============================================================================
--- trunk/vala/Makefile.am (original)
+++ trunk/vala/Makefile.am Sat Nov 29 12:20:30 2008
@@ -122,6 +122,7 @@
valasourcelocation.vala \
valasourcereference.vala \
valastatement.vala \
+ valastatementlist.vala \
valastringliteral.vala \
valastruct.vala \
valaswitchlabel.vala \
Modified: trunk/vala/valablock.vala
==============================================================================
--- trunk/vala/valablock.vala (original)
+++ trunk/vala/valablock.vala Sat Nov 29 12:20:30 2008
@@ -64,7 +64,18 @@
* @return statement list
*/
public Gee.List<Statement> get_statements () {
- return new ReadOnlyList<Statement> (statement_list);
+ var list = new ArrayList<Statement> ();
+ foreach (Statement stmt in statement_list) {
+ var stmt_list = stmt as StatementList;
+ if (stmt_list != null) {
+ for (int i = 0; i < stmt_list.length; i++) {
+ list.add (stmt_list.get (i));
+ }
+ } else {
+ list.add (stmt);
+ }
+ }
+ return list;
}
/**
@@ -75,7 +86,11 @@
public void add_local_variable (LocalVariable local) {
local_variables.add (local);
}
-
+
+ public void remove_local_variable (LocalVariable local) {
+ local_variables.remove (local);
+ }
+
/**
* Returns a copy of the list of local variables.
*
@@ -103,22 +118,60 @@
checked = true;
owner = analyzer.current_symbol.scope;
+
+ var old_symbol = analyzer.current_symbol;
analyzer.current_symbol = this;
- foreach (Statement stmt in statement_list) {
- stmt.check (analyzer);
+ for (int i = 0; i < statement_list.size; i++) {
+ statement_list[i].check (analyzer);
}
foreach (LocalVariable local in get_local_variables ()) {
local.active = false;
}
- foreach (Statement stmt in get_statements ()) {
+ foreach (Statement stmt in statement_list) {
add_error_types (stmt.get_error_types ());
}
- analyzer.current_symbol = analyzer.current_symbol.parent_symbol;
+ analyzer.current_symbol = old_symbol;
return !error;
}
+
+ public void insert_before (Statement stmt, Statement new_stmt) {
+ for (int i = 0; i < statement_list.size; i++) {
+ var stmt_list = statement_list[i] as StatementList;
+ if (stmt_list != null) {
+ for (int j = 0; j < stmt_list.length; j++) {
+ if (stmt_list.get (j) == stmt) {
+ stmt_list.insert (j, new_stmt);
+ break;
+ }
+ }
+ } else if (statement_list[i] == stmt) {
+ stmt_list = new StatementList (source_reference);
+ stmt_list.add (new_stmt);
+ stmt_list.add (stmt);
+ statement_list[i] = stmt_list;
+ }
+ }
+ }
+
+ public void replace_statement (Statement old_stmt, Statement new_stmt) {
+ for (int i = 0; i < statement_list.size; i++) {
+ var stmt_list = statement_list[i] as StatementList;
+ if (stmt_list != null) {
+ for (int j = 0; j < stmt_list.length; j++) {
+ if (stmt_list.get (j) == old_stmt) {
+ stmt_list.set (j, new_stmt);
+ break;
+ }
+ }
+ } else if (statement_list[i] == old_stmt) {
+ statement_list[i] = new_stmt;
+ break;
+ }
+ }
+ }
}
Modified: trunk/vala/valacodenode.vala
==============================================================================
--- trunk/vala/valacodenode.vala (original)
+++ trunk/vala/valacodenode.vala Sat Nov 29 12:20:30 2008
@@ -83,6 +83,8 @@
private CCodeNode? _ccodenode;
+ static int last_temp_nr = 0;
+
/**
* Specifies the exceptions that can be thrown by this node or a child node
*/
@@ -183,4 +185,8 @@
public virtual void get_used_variables (Collection<LocalVariable> collection) {
}
+
+ public string get_temp_name () {
+ return "." + (++last_temp_nr).to_string ();
+ }
}
Modified: trunk/vala/valaconditionalexpression.vala
==============================================================================
--- trunk/vala/valaconditionalexpression.vala (original)
+++ trunk/vala/valaconditionalexpression.vala Sat Nov 29 12:20:30 2008
@@ -29,18 +29,46 @@
/**
* The condition.
*/
- public Expression condition { get; set; }
-
+ public Expression condition {
+ get {
+ return _condition;
+ }
+ set {
+ _condition = value;
+ _condition.parent_node = this;
+ }
+ }
+
/**
* The expression to be evaluated if the condition holds.
*/
- public Expression true_expression { get; set; }
+ public Expression true_expression {
+ get {
+ return _true_expression;
+ }
+ set {
+ _true_expression = value;
+ _true_expression.parent_node = this;
+ }
+ }
/**
* The expression to be evaluated if the condition doesn't hold.
*/
- public Expression false_expression { get; set; }
-
+ public Expression false_expression {
+ get {
+ return _false_expression;
+ }
+ set {
+ _false_expression = value;
+ _false_expression.parent_node = this;
+ }
+ }
+
+ Expression _condition;
+ Expression _true_expression;
+ Expression _false_expression;
+
/**
* Creates a new conditional expression.
*
@@ -77,17 +105,35 @@
checked = true;
- if (!condition.check (analyzer) || !false_expression.check (analyzer) || !true_expression.check (analyzer)) {
- return false;
- }
+ // convert ternary expression into if statement
+ // required for flow analysis and exception handling
- if (!condition.value_type.compatible (analyzer.bool_type)) {
- error = true;
- Report.error (condition.source_reference, "Condition must be boolean");
+ string temp_name = get_temp_name ();
+
+ true_expression.target_type = target_type;
+ false_expression.target_type = target_type;
+
+ var true_local = new LocalVariable (null, temp_name, true_expression, true_expression.source_reference);
+ var true_block = new Block (true_expression.source_reference);
+ var true_decl = new DeclarationStatement (true_local, true_expression.source_reference);
+ true_block.add_statement (true_decl);
+
+ var false_local = new LocalVariable (null, temp_name, false_expression, false_expression.source_reference);
+ var false_block = new Block (false_expression.source_reference);
+ var false_decl = new DeclarationStatement (false_local, false_expression.source_reference);
+ false_block.add_statement (false_decl);
+
+ var if_stmt = new IfStatement (condition, true_block, false_block, source_reference);
+ if (!if_stmt.check (analyzer)) {
return false;
}
- /* FIXME: support memory management */
+ true_expression = true_local.initializer;
+ false_expression = false_local.initializer;
+
+ true_block.remove_local_variable (true_local);
+ false_block.remove_local_variable (false_local);
+
if (false_expression.value_type.compatible (true_expression.value_type)) {
value_type = true_expression.value_type.copy ();
} else if (true_expression.value_type.compatible (false_expression.value_type)) {
@@ -98,6 +144,33 @@
return false;
}
- return !error;
+ value_type.value_owned = (true_expression.value_type.value_owned || false_expression.value_type.value_owned);
+
+ var local = new LocalVariable (value_type, temp_name, null, source_reference);
+ var decl = new DeclarationStatement (local, source_reference);
+ decl.check (analyzer);
+
+ true_expression.target_type = value_type;
+ false_expression.target_type = value_type;
+
+ var true_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, true_expression.source_reference), true_expression, AssignmentOperator.SIMPLE, true_expression.source_reference), true_expression.source_reference);
+ true_stmt.check (analyzer);
+
+ var false_stmt = new ExpressionStatement (new Assignment (new MemberAccess.simple (local.name, false_expression.source_reference), false_expression, AssignmentOperator.SIMPLE, false_expression.source_reference), false_expression.source_reference);
+ false_stmt.check (analyzer);
+
+ true_block.replace_statement (true_decl, true_stmt);
+ false_block.replace_statement (false_decl, false_stmt);
+
+ insert_statement ((Block) analyzer.current_symbol, decl);
+ insert_statement ((Block) analyzer.current_symbol, if_stmt);
+
+ var ma = new MemberAccess.simple (local.name, source_reference);
+ ma.target_type = target_type;
+ ma.check (analyzer);
+
+ parent_node.replace_expression (this, ma);
+
+ return true;
}
}
Modified: trunk/vala/valadeclarationstatement.vala
==============================================================================
--- trunk/vala/valadeclarationstatement.vala (original)
+++ trunk/vala/valadeclarationstatement.vala Sat Nov 29 12:20:30 2008
@@ -29,7 +29,19 @@
/**
* The local variable or constant declaration.
*/
- public Symbol declaration { get; set; }
+ public Symbol declaration {
+ get {
+ return _declaration;
+ }
+ set {
+ _declaration = value;
+ if (_declaration != null) {
+ _declaration.parent_node = this;
+ }
+ }
+ }
+
+ Symbol _declaration;
/**
* Creates a new declaration statement.
Modified: trunk/vala/valaexpression.vala
==============================================================================
--- trunk/vala/valaexpression.vala (original)
+++ trunk/vala/valaexpression.vala Sat Nov 29 12:20:30 2008
@@ -84,4 +84,25 @@
public virtual bool is_non_null () {
return false;
}
+
+ public Statement? parent_statement {
+ get {
+ var expr = parent_node as Expression;
+ var stmt = parent_node as Statement;
+ var local = parent_node as LocalVariable;
+ if (stmt != null) {
+ return stmt;
+ } else if (expr != null) {
+ return expr.parent_statement;
+ } else if (local != null) {
+ return (Statement) local.parent_node;
+ } else {
+ return null;
+ }
+ }
+ }
+
+ public void insert_statement (Block block, Statement stmt) {
+ block.insert_before (parent_statement, stmt);
+ }
}
Modified: trunk/vala/valanullchecker.vala
==============================================================================
--- trunk/vala/valanullchecker.vala (original)
+++ trunk/vala/valanullchecker.vala Sat Nov 29 12:20:30 2008
@@ -235,10 +235,6 @@
expr.accept_children (this);
}
- public override void visit_conditional_expression (ConditionalExpression expr) {
- check_non_null (expr.condition);
- }
-
public override void visit_lambda_expression (LambdaExpression l) {
l.accept_children (this);
}
Added: trunk/vala/valastatementlist.vala
==============================================================================
--- (empty file)
+++ trunk/vala/valastatementlist.vala Sat Nov 29 12:20:30 2008
@@ -0,0 +1,57 @@
+/* valastatementlist.vala
+ *
+ * Copyright (C) 2008 JÃrg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * JÃrg Billeter <j bitron ch>
+ */
+
+using Gee;
+
+public class Vala.StatementList : CodeNode, Statement {
+ private Gee.List<Statement> list = new ArrayList<Statement> ();
+
+ public int length {
+ get { return list.size; }
+ }
+
+ public StatementList (SourceReference source_reference) {
+ this.source_reference = source_reference;
+ }
+
+ public Statement get (int index) {
+ return list.get (index);
+ }
+
+ public void set (int index, Statement stmt) {
+ list.set (index, stmt);
+ }
+
+ public void add (Statement stmt) {
+ list.add (stmt);
+ }
+
+ public void insert (int index, Statement stmt) {
+ list.insert (index, stmt);
+ }
+
+ public override void accept (CodeVisitor visitor) {
+ foreach (Statement stmt in list) {
+ stmt.accept (visitor);
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]