Insert "%s" argument in printf calls with non-literal format string
[vala-lang.git] / vala / valareturnstatement.vala
blob79e2fbaae4b5437cc8791c96ec5985cd4179b1cd
1 /* valareturnstatement.vala
3 * Copyright (C) 2006-2009 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
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
23 using Gee;
25 /**
26 * Represents a return statement in the source code.
28 public class Vala.ReturnStatement : CodeNode, Statement {
29 /**
30 * The optional expression to return.
32 public Expression? return_expression {
33 get { return _return_expression; }
34 set {
35 _return_expression = value;
36 if (_return_expression != null) {
37 _return_expression.parent_node = this;
42 private Expression _return_expression;
44 /**
45 * Creates a new return statement.
47 * @param return_expression the return expression
48 * @param source_reference reference to source code
49 * @return newly created return statement
51 public ReturnStatement (Expression? return_expression = null, SourceReference? source_reference = null) {
52 this.source_reference = source_reference;
53 this.return_expression = return_expression;
56 public override void accept (CodeVisitor visitor) {
57 visitor.visit_return_statement (this);
60 public override void accept_children (CodeVisitor visitor) {
61 if (return_expression != null) {
62 return_expression.accept (visitor);
64 visitor.visit_end_full_expression (return_expression);
68 public override void replace_expression (Expression old_node, Expression new_node) {
69 if (return_expression == old_node) {
70 return_expression = new_node;
74 public override bool check (SemanticAnalyzer analyzer) {
75 if (checked) {
76 return !error;
79 checked = true;
81 if (return_expression != null) {
82 return_expression.target_type = analyzer.current_return_type;
85 if (return_expression != null && !return_expression.check (analyzer)) {
86 // ignore inner error
87 error = true;
88 return false;
91 if (analyzer.current_return_type == null) {
92 error = true;
93 Report.error (source_reference, "Return not allowed in this context");
94 return false;
97 if (return_expression == null) {
98 if (!(analyzer.current_return_type is VoidType)) {
99 error = true;
100 Report.error (source_reference, "Return without value in non-void function");
102 return !error;
105 if (analyzer.current_return_type is VoidType) {
106 Report.error (source_reference, "Return with value in void function");
107 return false;
110 if (return_expression.value_type == null) {
111 error = true;
112 Report.error (source_reference, "Invalid expression in return value");
113 return false;
116 if (!return_expression.value_type.compatible (analyzer.current_return_type)) {
117 error = true;
118 Report.error (source_reference, "Return: Cannot convert from `%s' to `%s'".printf (return_expression.value_type.to_string (), analyzer.current_return_type.to_string ()));
119 return false;
122 if (return_expression.value_type.is_disposable () &&
123 !analyzer.current_return_type.value_owned) {
124 error = true;
125 Report.error (source_reference, "Return value transfers ownership but method return type hasn't been declared to transfer ownership");
126 return false;
129 var local = return_expression.symbol_reference as LocalVariable;
130 if (local != null && local.variable_type.is_disposable () &&
131 !analyzer.current_return_type.value_owned) {
132 error = true;
133 Report.error (source_reference, "Local variable with strong reference used as return value and method return type has not been declared to transfer ownership");
134 return false;
137 if (return_expression is NullLiteral
138 && !analyzer.current_return_type.nullable) {
139 Report.warning (source_reference, "`null' incompatible with return type `%s`".printf (analyzer.current_return_type.to_string ()));
142 add_error_types (return_expression.get_error_types ());
144 return !error;
147 public override void get_defined_variables (Collection<LocalVariable> collection) {
148 if (return_expression != null) {
149 return_expression.get_defined_variables (collection);
153 public override void get_used_variables (Collection<LocalVariable> collection) {
154 if (return_expression != null) {
155 return_expression.get_used_variables (collection);