1 /* valapropertyaccessor.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 get or set accessor of a property in the source code.
28 public class Vala
.PropertyAccessor
: Subroutine
{
30 * The corresponding property.
32 public Property prop
{
33 get { return parent_symbol as Property
; }
39 public DataType? value_type
{
40 get { return _value_type
; }
44 _value_type
.parent_node
= this
;
50 * Specifies whether this accessor may be used to get the property.
52 public bool readable
{ get; private set; }
55 * Specifies whether this accessor may be used to set the property.
57 public bool writable
{ get; private set; }
60 * Specifies whether this accessor may be used to construct the
63 public bool construction
{ get; private set; }
66 * True if the body was automatically generated
68 public bool automatic_body
{ get; private set; }
70 public override bool has_result
{
71 get { return readable
; }
75 * Represents the generated value parameter in a set accessor.
77 public Parameter value_parameter
{ get; private set; }
79 private DataType _value_type
;
82 * Creates a new property accessor.
84 * @param readable true if get accessor, false otherwise
85 * @param writable true if set accessor, false otherwise
86 * @param construction true if construct accessor, false otherwise
87 * @param body accessor body
88 * @param source_reference reference to source code
89 * @return newly created property accessor
91 public PropertyAccessor (bool readable
, bool writable
, bool construction
, DataType? value_type
, Block? body
, SourceReference? source_reference
, Comment? comment
= null) {
92 base (null, source_reference
, comment
);
93 this
.readable
= readable
;
94 this
.writable
= writable
;
95 this
.construction
= construction
;
96 this
.value_type
= value_type
;
98 this
.access
= SymbolAccessibility
.PUBLIC
;
101 public override void accept (CodeVisitor visitor
) {
102 visitor
.visit_property_accessor (this
);
105 public override void accept_children (CodeVisitor visitor
) {
106 value_type
.accept (visitor
);
108 if (result_var
!= null) {
109 result_var
.accept (visitor
);
113 body
.accept (visitor
);
118 * Get the method representing this property accessor
119 * @return null if the accessor is neither readable nor writable
121 public Method?
get_method () {
124 m
= new
Method ("get_%s".printf (prop
.name
), value_type
, source_reference
, comment
);
125 } else if (writable
) {
126 m
= new
Method ("set_%s".printf (prop
.name
), new
VoidType(), source_reference
, comment
);
127 m
.add_parameter (value_parameter
.copy ());
131 m
.owner
= prop
.owner
;
133 m
.binding
= prop
.binding
;
134 m
.is_abstract
= prop
.is_abstract
;
135 m
.is_virtual
= prop
.is_virtual
;
141 public override bool check (CodeContext context
) {
148 if (!value_type
.check (context
)) {
153 var old_symbol
= context
.analyzer
.current_symbol
;
155 context
.analyzer
.current_symbol
= this
;
157 if (writable
|| construction
) {
158 value_parameter
= new
Parameter ("value", value_type
, source_reference
);
161 if (prop
.source_type
== SourceFileType
.SOURCE
) {
162 if (body
== null && !prop
.interface_only
&& !prop
.is_abstract
) {
163 /* no accessor body specified, insert default body */
165 automatic_body
= true;
166 body
= new
Block (source_reference
);
167 var ma
= new MemberAccess
.simple ("_%s".printf (prop
.name
), source_reference
);
169 body
.add_statement (new
ReturnStatement (ma
, source_reference
));
171 Expression value
= new MemberAccess
.simple ("value", source_reference
);
172 if (value_type
.value_owned
) {
173 value
= new
ReferenceTransferExpression (value
, source_reference
);
175 var assignment
= new
Assignment (ma
, value
, AssignmentOperator
.SIMPLE
, source_reference
);
176 body
.add_statement (new
ExpressionStatement (assignment
));
181 if ((prop
.is_abstract
|| prop
.is_virtual
|| prop
.overrides
) && access
== SymbolAccessibility
.PRIVATE
) {
183 Report
.error (source_reference
, "Property `%s' with private accessor cannot be marked as abstract, virtual or override".printf (prop
.get_full_name ()));
187 if (body
!= null && prop
.is_abstract
) {
189 Report
.error (source_reference
, "Accessor of abstract property `%s' cannot have body".printf (prop
.get_full_name ()));
194 if (writable
|| construction
) {
195 body
.scope
.add (value_parameter
.name
, value_parameter
);
198 body
.check (context
);
200 foreach (DataType body_error_type
in body
.get_error_types ()) {
201 if (!((ErrorType
) body_error_type
).dynamic_error
) {
202 Report
.warning (body_error_type
.source_reference
, "unhandled error `%s'".printf (body_error_type
.to_string()));
207 context
.analyzer
.current_symbol
= old_symbol
;
212 public override void replace_type (DataType old_type
, DataType new_type
) {
213 if (value_type
== old_type
) {
214 value_type
= new_type
;