[vala] dova: Add implicit result variable
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] dova: Add implicit result variable
- Date: Sat, 13 Mar 2010 20:52:40 +0000 (UTC)
commit 6cb86f046f334eb092358ac0ba23e450a9845ed3
Author: Jürg Billeter <j bitron ch>
Date: Sat Mar 13 21:44:21 2010 +0100
dova: Add implicit result variable
vala/valaclass.vala | 4 ++--
vala/valaenum.vala | 4 ++++
vala/valaflowanalyzer.vala | 18 ++++++++++++++++--
vala/valainterface.vala | 4 ++--
vala/valalambdaexpression.vala | 7 ++++++-
vala/valanamespace.vala | 2 +-
vala/valaparser.vala | 31 ++++++++++++++++++++++++++++++-
vala/valapropertyaccessor.vala | 23 +++++++++++++++++++++--
vala/valareturnstatement.vala | 5 +++++
vala/valastruct.vala | 4 ++--
10 files changed, 89 insertions(+), 13 deletions(-)
---
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 04342d0..dd39f8f 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -322,11 +322,11 @@ public class Vala.Class : ObjectTypeSymbol {
m.this_parameter = new FormalParameter ("this", get_this_type ());
m.scope.add (m.this_parameter.name, m.this_parameter);
}
- if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
+ if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
if (m.result_var != null) {
m.scope.remove (m.result_var.name);
}
- m.result_var = new LocalVariable (m.return_type.copy (), "result");
+ m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
m.result_var.is_result = true;
}
if (m is CreationMethod) {
diff --git a/vala/valaenum.vala b/vala/valaenum.vala
index 7c6391c..0e488ad 100644
--- a/vala/valaenum.vala
+++ b/vala/valaenum.vala
@@ -81,6 +81,10 @@ public class Vala.Enum : TypeSymbol {
m.this_parameter = new FormalParameter ("this", new EnumValueType (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
+ if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
+ m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
+ m.result_var.is_result = true;
+ }
methods.add (m);
scope.add (m.name, m);
diff --git a/vala/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index a047128..a90e157 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -168,6 +168,13 @@ public class Vala.FlowAnalyzer : CodeVisitor {
m.entry_block = new BasicBlock.entry ();
m.exit_block = new BasicBlock.exit ();
+ if (context.profile == Profile.DOVA && !(m.return_type is VoidType)) {
+ // ensure result is defined at end of method
+ var result_ma = new MemberAccess.simple ("result", m.source_reference);
+ result_ma.symbol_reference = m.result_var;
+ m.exit_block.add_node (result_ma);
+ }
+
current_block = new BasicBlock ();
m.entry_block.connect (current_block);
current_block.add_node (m);
@@ -181,7 +188,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
if (current_block != null) {
// end of method body reachable
- if (!(m.return_type is VoidType)) {
+ if (context.profile != Profile.DOVA && !(m.return_type is VoidType)) {
Report.error (m.source_reference, "missing return statement at end of method or lambda body");
m.error = true;
}
@@ -483,6 +490,13 @@ public class Vala.FlowAnalyzer : CodeVisitor {
acc.entry_block = new BasicBlock.entry ();
acc.exit_block = new BasicBlock.exit ();
+ if (context.profile == Profile.DOVA && acc.readable) {
+ // ensure result is defined at end of method
+ var result_ma = new MemberAccess.simple ("result", acc.source_reference);
+ result_ma.symbol_reference = acc.result_var;
+ acc.exit_block.add_node (result_ma);
+ }
+
current_block = new BasicBlock ();
acc.entry_block.connect (current_block);
@@ -495,7 +509,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
if (current_block != null) {
// end of property accessor body reachable
- if (acc.readable) {
+ if (context.profile != Profile.DOVA && acc.readable) {
Report.error (acc.source_reference, "missing return statement at end of property getter body");
acc.error = true;
}
diff --git a/vala/valainterface.vala b/vala/valainterface.vala
index 076ba2e..a76998a 100644
--- a/vala/valainterface.vala
+++ b/vala/valainterface.vala
@@ -138,8 +138,8 @@ public class Vala.Interface : ObjectTypeSymbol {
m.this_parameter = new FormalParameter ("this", get_this_type ());
m.scope.add (m.this_parameter.name, m.this_parameter);
}
- if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
- m.result_var = new LocalVariable (m.return_type.copy (), "result");
+ if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
+ m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
m.result_var.is_result = true;
}
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index facaed9..a6c2dba 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -200,7 +200,12 @@ public class Vala.LambdaExpression : Expression {
block.scope.parent_scope = method.scope;
if (method.return_type.data_type != null) {
- block.add_statement (new ReturnStatement (expression_body, source_reference));
+ if (analyzer.context.profile == Profile.DOVA) {
+ block.add_statement (new ExpressionStatement (new Assignment (new MemberAccess.simple ("result", source_reference), expression_body, AssignmentOperator.SIMPLE, source_reference), source_reference));
+ block.add_statement (new ReturnStatement (null, source_reference));
+ } else {
+ block.add_statement (new ReturnStatement (expression_body, source_reference));
+ }
} else {
block.add_statement (new ExpressionStatement (expression_body, source_reference));
}
diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala
index 8ddeb9d..e3a0f90 100644
--- a/vala/valanamespace.vala
+++ b/vala/valanamespace.vala
@@ -391,7 +391,7 @@ public class Vala.Namespace : Symbol {
m.error = true;
return;
}
- if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
+ if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
m.result_var.is_result = true;
}
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 90ad36d..c7490e1 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1418,6 +1418,19 @@ public class Vala.Parser : CodeVisitor {
}
if (!is_decl) {
+ if (context.profile == Profile.DOVA && stmt is ReturnStatement) {
+ // split
+ // return foo;
+ // into
+ // result = foo;
+ // return;
+ var ret_stmt = (ReturnStatement) stmt;
+ if (ret_stmt.return_expression != null) {
+ var assignment = new Assignment (new MemberAccess.simple ("result"), ret_stmt.return_expression);
+ ret_stmt.return_expression = null;
+ block.add_statement (new ExpressionStatement (assignment));
+ }
+ }
block.add_statement (stmt);
}
} catch (ParseError e) {
@@ -1475,7 +1488,23 @@ public class Vala.Parser : CodeVisitor {
comment = scanner.pop_comment ();
var block = new Block (get_src (get_location ()));
- block.add_statement (parse_embedded_statement_without_block ());
+
+ var stmt = parse_embedded_statement_without_block ();
+ if (context.profile == Profile.DOVA && stmt is ReturnStatement) {
+ // split
+ // return foo;
+ // into
+ // result = foo;
+ // return;
+ var ret_stmt = (ReturnStatement) stmt;
+ if (ret_stmt.return_expression != null) {
+ var assignment = new Assignment (new MemberAccess.simple ("result"), ret_stmt.return_expression);
+ ret_stmt.return_expression = null;
+ block.add_statement (new ExpressionStatement (assignment));
+ }
+ }
+ block.add_statement (stmt);
+
return block;
}
diff --git a/vala/valapropertyaccessor.vala b/vala/valapropertyaccessor.vala
index f9eaa79..0f02efb 100644
--- a/vala/valapropertyaccessor.vala
+++ b/vala/valapropertyaccessor.vala
@@ -90,6 +90,11 @@ public class Vala.PropertyAccessor : Symbol {
public FormalParameter value_parameter { get; set; }
/**
+ * Specifies the generated `result' variable in a get accessor.
+ */
+ public LocalVariable? result_var { get; set; }
+
+ /**
* The publicly accessible name of the function that performs the
* access in C code.
*/
@@ -137,6 +142,10 @@ public class Vala.PropertyAccessor : Symbol {
public override void accept_children (CodeVisitor visitor) {
value_type.accept (visitor);
+ if (result_var != null) {
+ result_var.accept (visitor);
+ }
+
if (body != null) {
body.accept (visitor);
}
@@ -186,7 +195,12 @@ public class Vala.PropertyAccessor : Symbol {
body = new Block (source_reference);
var ma = new MemberAccess.simple ("_%s".printf (prop.name), source_reference);
if (readable) {
- body.add_statement (new ReturnStatement (ma, source_reference));
+ if (analyzer.context.profile == Profile.DOVA) {
+ body.add_statement (new ExpressionStatement (new Assignment (new MemberAccess.simple ("result", source_reference), ma, AssignmentOperator.SIMPLE, source_reference), source_reference));
+ body.add_statement (new ReturnStatement (null, source_reference));
+ } else {
+ body.add_statement (new ReturnStatement (ma, source_reference));
+ }
} else {
var assignment = new Assignment (ma, new MemberAccess.simple ("value", source_reference), AssignmentOperator.SIMPLE, source_reference);
body.add_statement (new ExpressionStatement (assignment));
@@ -195,7 +209,12 @@ public class Vala.PropertyAccessor : Symbol {
}
if (body != null) {
- if (writable || construction) {
+ if (readable && analyzer.context.profile == Profile.DOVA) {
+ result_var = new LocalVariable (value_type.copy (), "result", null, source_reference);
+ result_var.is_result = true;
+
+ result_var.check (analyzer);
+ } else if (writable || construction) {
value_parameter = new FormalParameter ("value", value_type, source_reference);
body.scope.add (value_parameter.name, value_parameter);
}
diff --git a/vala/valareturnstatement.vala b/vala/valareturnstatement.vala
index 26af73e..399ca69 100644
--- a/vala/valareturnstatement.vala
+++ b/vala/valareturnstatement.vala
@@ -93,6 +93,11 @@ public class Vala.ReturnStatement : CodeNode, Statement {
return false;
}
+ if (analyzer.context.profile == Profile.DOVA) {
+ // no return expressions in Dova profile
+ return !error;
+ }
+
if (return_expression == null) {
if (!(analyzer.current_return_type is VoidType)) {
error = true;
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
index f5d7325..7376635 100644
--- a/vala/valastruct.vala
+++ b/vala/valastruct.vala
@@ -181,8 +181,8 @@ public class Vala.Struct : TypeSymbol {
m.this_parameter = new FormalParameter ("this", SemanticAnalyzer.get_data_type_for_symbol (this));
m.scope.add (m.this_parameter.name, m.this_parameter);
}
- if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
- m.result_var = new LocalVariable (m.return_type.copy (), "result");
+ if (!(m.return_type is VoidType) && (CodeContext.get ().profile == Profile.DOVA || m.get_postconditions ().size > 0)) {
+ m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
m.result_var.is_result = true;
}
if (m is CreationMethod) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]