From: Jürg Billeter Date: Fri, 7 Nov 2008 09:27:50 +0000 (+0000) Subject: Move return statement checking to ReturnStatement.check X-Git-Tag: VALA_0_5_2~115 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da89ecc15c743406bc6f4f2a6c9017742336586e;p=thirdparty%2Fvala.git Move return statement checking to ReturnStatement.check 2008-11-07 Jürg Billeter * vala/valareturnstatement.vala: * vala/valasemanticanalyzer.vala: Move return statement checking to ReturnStatement.check svn path=/trunk/; revision=1996 --- diff --git a/ChangeLog b/ChangeLog index 4d0319c04..731ed19ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-07 Jürg Billeter + + * vala/valareturnstatement.vala: + * vala/valasemanticanalyzer.vala: + + Move return statement checking to ReturnStatement.check + 2008-11-07 Jürg Billeter * vala/valaforeachstatement.vala: diff --git a/vala/valareturnstatement.vala b/vala/valareturnstatement.vala index fe9614491..8ea4a7d6d 100644 --- a/vala/valareturnstatement.vala +++ b/vala/valareturnstatement.vala @@ -70,4 +70,77 @@ public class Vala.ReturnStatement : CodeNode, Statement { return_expression = new_node; } } + + public override bool check (SemanticAnalyzer analyzer) { + if (checked) { + return !error; + } + + checked = true; + + if (return_expression != null) { + return_expression.target_type = analyzer.current_return_type; + } + + accept_children (analyzer); + + if (return_expression != null && return_expression.error) { + // ignore inner error + error = true; + return false; + } + + if (analyzer.current_return_type == null) { + error = true; + Report.error (source_reference, "Return not allowed in this context"); + return false; + } + + if (return_expression == null) { + if (!(analyzer.current_return_type is VoidType)) { + error = true; + Report.error (source_reference, "Return without value in non-void function"); + } + return !error; + } + + if (analyzer.current_return_type is VoidType) { + Report.error (source_reference, "Return with value in void function"); + return false; + } + + if (return_expression.value_type == null) { + error = true; + Report.error (source_reference, "Invalid expression in return value"); + return false; + } + + if (!return_expression.value_type.compatible (analyzer.current_return_type)) { + error = true; + Report.error (source_reference, "Return: Cannot convert from `%s' to `%s'".printf (return_expression.value_type.to_string (), analyzer.current_return_type.to_string ())); + return false; + } + + if (return_expression.value_type.is_disposable () && + !analyzer.current_return_type.value_owned) { + error = true; + Report.error (source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership"); + return false; + } + + if (return_expression.symbol_reference is LocalVariable && + return_expression.value_type.is_disposable () && + !analyzer.current_return_type.value_owned) { + Report.warning (source_reference, "Local variable with strong reference used as return value and method return type hasn't been declared to transfer ownership"); + } + + if (analyzer.context.non_null && return_expression is NullLiteral + && !analyzer.current_return_type.nullable) { + Report.warning (source_reference, "`null' incompatible with return type `%s`".printf (analyzer.current_return_type.to_string ())); + } + + add_error_types (return_expression.get_error_types ()); + + return !error; + } } diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 0a4a7a2e4..5a481a962 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -721,70 +721,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } public override void visit_return_statement (ReturnStatement stmt) { - if (stmt.return_expression != null) { - stmt.return_expression.target_type = current_return_type; - } - - stmt.accept_children (this); - - if (stmt.return_expression != null && stmt.return_expression.error) { - // ignore inner error - stmt.error = true; - return; - } - - if (current_return_type == null) { - stmt.error = true; - Report.error (stmt.source_reference, "Return not allowed in this context"); - return; - } - - if (stmt.return_expression == null) { - if (current_return_type is VoidType) { - return; - } else { - stmt.error = true; - Report.error (stmt.source_reference, "Return without value in non-void function"); - return; - } - } - - if (current_return_type is VoidType) { - Report.error (stmt.source_reference, "Return with value in void function"); - return; - } - - if (stmt.return_expression.value_type == null) { - stmt.error = true; - Report.error (stmt.source_reference, "Invalid expression in return value"); - return; - } - - if (!stmt.return_expression.value_type.compatible (current_return_type)) { - stmt.error = true; - Report.error (stmt.source_reference, "Return: Cannot convert from `%s' to `%s'".printf (stmt.return_expression.value_type.to_string (), current_return_type.to_string ())); - return; - } - - if (stmt.return_expression.value_type.is_disposable () && - !current_return_type.value_owned) { - stmt.error = true; - Report.error (stmt.source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership"); - return; - } - - if (stmt.return_expression.symbol_reference is LocalVariable && - stmt.return_expression.value_type.is_disposable () && - !current_return_type.value_owned) { - Report.warning (stmt.source_reference, "Local variable with strong reference used as return value and method return type hasn't been declared to transfer ownership"); - } - - if (context.non_null && stmt.return_expression is NullLiteral - && !current_return_type.nullable) { - Report.warning (stmt.source_reference, "`null' incompatible with return type `%s`".printf (current_return_type.to_string ())); - } - - stmt.add_error_types (stmt.return_expression.get_error_types ()); + stmt.check (this); } public override void visit_yield_statement (YieldStatement stmt) {