1 /* valareturnstatement.vala
3 * Copyright (C) 2006-2010 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Jürg Billeter <j@bitron.ch>
25 * Represents a return statement in the source code.
27 public class Vala
.ReturnStatement
: CodeNode
, Statement
{
29 * The optional expression to return.
31 public Expression? return_expression
{
32 get { return _return_expression
; }
34 _return_expression
= value
;
35 if (_return_expression
!= null) {
36 _return_expression
.parent_node
= this
;
41 private Expression _return_expression
;
44 * Creates a new return statement.
46 * @param return_expression the return expression
47 * @param source_reference reference to source code
48 * @return newly created return statement
50 public ReturnStatement (Expression? return_expression
= null, SourceReference? source_reference
= null) {
51 this
.source_reference
= source_reference
;
52 this
.return_expression
= return_expression
;
55 public override void accept (CodeVisitor visitor
) {
56 visitor
.visit_return_statement (this
);
59 public override void accept_children (CodeVisitor visitor
) {
60 if (return_expression
!= null) {
61 return_expression
.accept (visitor
);
63 visitor
.visit_end_full_expression (return_expression
);
67 public override void replace_expression (Expression old_node
, Expression new_node
) {
68 if (return_expression
== old_node
) {
69 return_expression
= new_node
;
73 public override bool check (CodeContext context
) {
80 if (return_expression
!= null) {
81 return_expression
.target_type
= context
.analyzer
.current_return_type
;
84 if (return_expression
!= null && !return_expression
.check (context
)) {
90 if (context
.analyzer
.current_return_type
== null) {
92 Report
.error (source_reference
, "Return not allowed in this context");
96 if (return_expression
== null) {
97 if (!(context
.analyzer
.current_return_type is VoidType
)) {
99 Report
.error (source_reference
, "Return without value in non-void function");
104 if (context
.analyzer
.current_return_type is VoidType
) {
105 Report
.error (source_reference
, "Return with value in void function");
109 if (return_expression
.value_type
== null) {
111 Report
.error (source_reference
, "Invalid expression in return value");
115 if (!return_expression
.value_type
.compatible (context
.analyzer
.current_return_type
)) {
117 Report
.error (source_reference
, "Return: Cannot convert from `%s' to `%s'".printf (return_expression
.value_type
.to_string (), context
.analyzer
.current_return_type
.to_string ()));
121 if (return_expression
.value_type
.is_disposable () &&
122 !context
.analyzer
.current_return_type
.value_owned
) {
124 Report
.error (source_reference
, "Return value transfers ownership but method return type hasn't been declared to transfer ownership");
128 var local
= return_expression
.symbol_reference as LocalVariable
;
129 if (local
!= null && local
.variable_type
.is_disposable () &&
130 !context
.analyzer
.current_return_type
.value_owned
) {
132 Report
.error (source_reference
, "Local variable with strong reference used as return value and method return type has not been declared to transfer ownership");
136 if (return_expression is NullLiteral
137 && !context
.analyzer
.current_return_type
.nullable
) {
138 Report
.warning (source_reference
, "`null' incompatible with return type `%s`".printf (context
.analyzer
.current_return_type
.to_string ()));
141 add_error_types (return_expression
.get_error_types ());
146 public override void emit (CodeGenerator codegen
) {
147 if (return_expression
!= null) {
148 return_expression
.emit (codegen
);
150 codegen
.visit_end_full_expression (return_expression
);
153 codegen
.visit_return_statement (this
);
156 public override void get_defined_variables (Collection
<Variable
> collection
) {
157 if (return_expression
!= null) {
158 return_expression
.get_defined_variables (collection
);
162 public override void get_used_variables (Collection
<Variable
> collection
) {
163 if (return_expression
!= null) {
164 return_expression
.get_used_variables (collection
);