]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
dova: Add implicit result variable
authorJürg Billeter <j@bitron.ch>
Sat, 13 Mar 2010 20:44:21 +0000 (21:44 +0100)
committerJürg Billeter <j@bitron.ch>
Sat, 13 Mar 2010 20:44:21 +0000 (21:44 +0100)
vala/valaclass.vala
vala/valaenum.vala
vala/valaflowanalyzer.vala
vala/valainterface.vala
vala/valalambdaexpression.vala
vala/valanamespace.vala
vala/valaparser.vala
vala/valapropertyaccessor.vala
vala/valareturnstatement.vala
vala/valastruct.vala

index 04342d0fb3dbc3ba12989770c6a1fbb9300c5416..dd39f8f18a3c368be294e7afc9f6c256c89a405f 100644 (file)
@@ -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) {
index 7c6391c54770975f4aa73ed6ffda72289771dd80..0e488adb61690dd0ce0ecaaf011b641fec2e1ac2 100644 (file)
@@ -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);
index a047128cfe82e97395d52adb9f806b01e49b4832..a90e157508cb0be0d92ba797a182179057467519 100644 (file)
@@ -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;
                        }
index 076ba2efce1aab443cfe538786826e9b56072ce4..a76998aa7055277797b8793fa8f8a346a497b844 100644 (file)
@@ -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;
                }
 
index facaed95b985057d03f83dacd20af4a052feb71a..a6c2dba9b53caf199fb7faa6cfd719acb5e9223a 100644 (file)
@@ -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));
                        }
index 8ddeb9dffd88af9e5e48d227149a629a982430b6..e3a0f9037079c28aa37ff1826392fb7dd7ec9b3c 100644 (file)
@@ -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;
                }
index 90ad36d6dbc5c880cfa13754a0739ac504b3a023..c7490e1ef169b71e4e433e16d4e3185de8d78e43 100644 (file)
@@ -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;
 
        }
index f9eaa79e9cf5eb82b1862de82c2a305bd6a4b4c5..0f02efb379b98cc6550255b7b6f359a210501b94 100644 (file)
@@ -89,6 +89,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);
                        }
index 26af73ead2c489e953150eb64461f37dbd856105..399ca696ef9fa7e3f1938384e1d6e879d0c69d03 100644 (file)
@@ -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;
index f5d73252965a0d077317de48bef3bdb8c956e034..73766357613e3c41e7bc1fcfea03bddfc0ccf376 100644 (file)
@@ -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) {