1 /* valalocalvariable.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>
26 * Represents a local variable declaration in the source code.
28 public class Vala
.LocalVariable
: Variable
{
29 public bool is_result
{ get; set; }
32 * Floating variables may only be accessed exactly once.
34 public bool floating
{ get; set; }
36 public bool captured
{ get; set; }
38 public bool no_init
{ get; set; }
41 * Creates a new local variable.
43 * @param name name of the variable
44 * @param init optional initializer expression
45 * @param source reference to source code
46 * @return newly created variable declarator
48 public LocalVariable (DataType? variable_type
, string name
, Expression? initializer
= null, SourceReference? source_reference
= null) {
49 base (variable_type
, name
, initializer
, source_reference
);
52 public override void accept (CodeVisitor visitor
) {
53 visitor
.visit_local_variable (this
);
56 public override void accept_children (CodeVisitor visitor
) {
57 if (initializer
!= null) {
58 initializer
.accept (visitor
);
60 visitor
.visit_end_full_expression (initializer
);
63 if (variable_type
!= null) {
64 variable_type
.accept (visitor
);
68 public override void replace_expression (Expression old_node
, Expression new_node
) {
69 if (initializer
== old_node
) {
70 initializer
= new_node
;
74 public override void replace_type (DataType old_type
, DataType new_type
) {
75 if (variable_type
== old_type
) {
76 variable_type
= new_type
;
80 public override bool check (CodeContext context
) {
87 if (variable_type
!= null) {
88 if (variable_type is VoidType
) {
90 Report
.error (source_reference
, "'void' not supported as variable type");
93 variable_type
.check (context
);
96 if (initializer
!= null) {
97 initializer
.target_type
= variable_type
;
99 initializer
.check (context
);
102 if (variable_type
== null) {
105 if (initializer
== null) {
107 Report
.error (source_reference
, "var declaration not allowed without initializer");
110 if (initializer
.value_type
== null) {
112 Report
.error (source_reference
, "var declaration not allowed with non-typed initializer");
115 if (initializer
.value_type is FieldPrototype
) {
117 Report
.error (initializer
.source_reference
, "Access to instance member `%s' denied".printf (initializer
.symbol_reference
.get_full_name ()));
121 variable_type
= initializer
.value_type
.copy ();
122 variable_type
.value_owned
= true;
123 variable_type
.floating_reference
= false;
125 initializer
.target_type
= variable_type
;
128 if (initializer
!= null && !initializer
.error
) {
129 if (initializer
.value_type
== null) {
130 if (!(initializer is MemberAccess
) && !(initializer is LambdaExpression
)) {
132 Report
.error (source_reference
, "expression type not allowed as initializer");
136 if (initializer
.symbol_reference is Method
&&
137 variable_type is DelegateType
) {
138 var m
= (Method
) initializer
.symbol_reference
;
139 var dt
= (DelegateType
) variable_type
;
140 var cb
= dt
.delegate_symbol
;
142 /* check whether method matches callback type */
143 if (!cb
.matches_method (m
, dt
)) {
145 Report
.error (source_reference
, "declaration of method `%s' doesn't match declaration of callback `%s'".printf (m
.get_full_name (), cb
.get_full_name ()));
149 initializer
.value_type
= variable_type
;
152 Report
.error (source_reference
, "expression type not allowed as initializer");
157 if (!initializer
.value_type
.compatible (variable_type
)) {
159 Report
.error (source_reference
, "Assignment: Cannot convert from `%s' to `%s'".printf (initializer
.value_type
.to_string (), variable_type
.to_string ()));
163 if (initializer
.value_type
.is_disposable ()) {
164 /* rhs transfers ownership of the expression */
165 if (!(variable_type is PointerType
) && !variable_type
.value_owned
) {
166 /* lhs doesn't own the value */
168 Report
.error (source_reference
, "Invalid assignment from owned expression to unowned variable");
174 context
.analyzer
.current_symbol
.scope
.add (name
, this
);
176 // current_symbol is a Method if this is the `result'
177 // variable used for postconditions
178 var block
= context
.analyzer
.current_symbol as Block
;
180 block
.add_local_variable (this
);