3 * Copyright (C) 2006-2007 Jürg Billeter, Raffaele Sandrini
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 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>
21 * Raffaele Sandrini <rasa@gmx.ch>
27 * Represents a type or namespace method.
29 public class Vala
.Method
: Member
, Invokable
{
31 * The symbol name of this method.
33 public string name
{ get; set; }
36 * The return type of this method.
38 public TypeReference return_type
{ get; set; }
40 public Block body
{ get; set; }
43 * Specifies the accessibility of this method. Public accessibility
44 * doesn't limit access. Default accessibility limits access to this
45 * program or library. Private accessibility limits access to instances
46 * of the contained type.
48 public MemberAccessibility access
;
51 * Specifies whether this method may only be called with an instance of
54 public bool instance
{
64 * Specifies whether this method is abstract. Abstract methods have no
65 * body, may only be specified within abstract classes, and must be
66 * overriden by derived non-abstract classes.
68 public bool is_abstract
{ get; set; }
71 * Specifies whether this method is virtual. Virtual methods may be
72 * overridden by derived classes.
74 public bool is_virtual
{ get; set; }
77 * Specifies whether this method overrides a virtual or abstract method
80 public bool overrides
{ get; set; }
83 * Specifies whether the C method returns a new instance pointer which
84 * may be different from the previous instance pointer. Only valid for
87 public bool returns_modified_pointer
{ get; set; }
90 * Specifies whether the instance pointer should be passed as the first
91 * or as the last argument in C code. Defaults to first.
93 public bool instance_last
{ get; set; }
96 * Specifies whether the instance of a value type should be passed by
97 * reference. Only valid for instance methods of value types.
99 public bool instance_by_reference
{ get; set; }
102 * Specifies the virtual or abstract method this method overrides.
103 * Reference must be weak as virtual methods set base_method to
106 public weak Method base_method
{ get; set; }
109 * Specifies the abstract interface method this method implements.
111 public Method base_interface_method
{ get; set; }
114 * Specifies the generated `this' parameter for instance methods.
116 public FormalParameter this_parameter
{ get; set; }
119 * Specifies whether the array length should implicitly be passed
120 * if the parameter type is an array.
122 public bool no_array_length
{
124 return _no_array_length
;
127 _no_array_length
= value
;
128 foreach (FormalParameter param
in parameters
) {
129 param
.no_array_length
= value
;
135 * Specifies whether this method expects printf-style format arguments.
137 public bool printf_format
{ get; set; }
139 private bool _instance
= true;
140 private List
<FormalParameter
> parameters
;
141 private string cname
;
142 private bool _no_array_length
;
145 * Creates a new method.
147 * @param name method name
148 * @param return_type method return type
149 * @param source reference to source code
150 * @return newly created method
152 public Method (string _name
, TypeReference _return_type
, SourceReference source
= null) {
154 return_type
= _return_type
;
155 source_reference
= source
;
159 * Appends parameter to this method.
161 * @param param a formal parameter
163 public void add_parameter (FormalParameter
! param
) {
164 if (no_array_length
) {
165 param
.no_array_length
= true;
168 parameters
.append (param
);
171 public List
<weak FormalParameter
> get_parameters () {
172 return parameters
.copy ();
175 public TypeReference
get_return_type () {
179 public bool is_invokable () {
183 public override void accept (CodeVisitor
! visitor
) {
184 visitor
.visit_method (this
);
187 public override void accept_children (CodeVisitor
! visitor
) {
188 if (return_type
!= null) {
189 return_type
.accept (visitor
);
192 foreach (FormalParameter param
in parameters
) {
193 param
.accept (visitor
);
197 body
.accept (visitor
);
202 * Returns the interface name of this method as it is used in C code.
204 * @return the name to be used in C code
206 public string! get_cname () {
208 cname
= get_default_cname ();
214 * Returns the default interface name of this method as it is used in C
217 * @return the name to be used in C code by default
219 public virtual string! get_default_cname () {
220 var parent
= symbol
.parent_symbol
.node
;
221 if (parent is DataType
) {
222 if (name
.has_prefix ("_")) {
223 return "_%s%s".printf (((DataType
) parent
).get_lower_case_cprefix (), name
.offset (1));
225 return "%s%s".printf (((DataType
) parent
).get_lower_case_cprefix (), name
);
227 } else if (parent is Namespace
) {
228 return "%s%s".printf (((Namespace
) parent
).get_lower_case_cprefix (), name
);
235 * Returns the implementation name of this data type as it is used in C
238 * @return the name to be used in C code
240 public string! get_real_cname () {
241 if (base_method
!= null || base_interface_method
!= null) {
242 var parent
= (Class
) symbol
.parent_symbol
.node
;
243 return "%s_real_%s".printf (parent
.get_lower_case_cname (null), name
);
250 * Sets the name of this method as it is used in C code.
252 * @param cname the name to be used in C code
254 public void set_cname (string cname
) {
258 private void process_ccode_attribute (Attribute a
) {
259 if (a
.has_argument ("cname")) {
260 set_cname (a
.get_string ("cname"));
265 * Process all associated attributes.
267 public void process_attributes () {
268 foreach (Attribute a
in attributes
) {
269 if (a
.name
== "CCode") {
270 process_ccode_attribute (a
);
271 } else if (a
.name
== "ReturnsModifiedPointer") {
272 returns_modified_pointer
= true;
273 } else if (a
.name
== "InstanceLast") {
274 instance_last
= true;
275 } else if (a
.name
== "InstanceByReference") {
276 instance_by_reference
= true;
277 } else if (a
.name
== "FloatingReference") {
278 return_type
.floating_reference
= true;
279 } else if (a
.name
== "NoArrayLength") {
280 no_array_length
= true;
281 } else if (a
.name
== "PrintfFormat") {
282 printf_format
= true;
288 * Checks whether the arguments and return type of the specified method
289 * matches this method.
292 * @return true if the specified method is compatible to this method
294 public bool equals (Method
! m2
) {
295 if (!m2
.return_type
.equals (return_type
)) {
299 var method_params
= m2
.get_parameters ();
300 weak List
<weak FormalParameter
> method_params_it
= method_params
;
301 foreach (FormalParameter param
in parameters
) {
302 /* method may not expect less arguments */
303 if (method_params_it
== null) {
307 var method_param
= (FormalParameter
) method_params_it
.data
;
308 if (!method_param
.type_reference
.equals (param
.type_reference
)) {
312 method_params_it
= method_params_it
.next
;
315 /* method may not expect more arguments */
316 if (method_params_it
!= null) {