1 /* valacreationmethod.vala
3 * Copyright (C) 2007-2008 Raffaele Sandrini, 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 * Raffaele Sandrini <raffaele@sandrini.ch>
21 * Jürg Billeter <j@bitron.ch>
27 * Represents a type creation method.
29 public class Vala
.CreationMethod
: Method
{
31 * Specifies the name of the type this creation method belongs to.
33 public string type_name
{ get; set; }
36 * Specifies the number of parameters this creation method sets.
38 public int n_construction_params
{ get; set; }
41 * Specifies a custom C return type for that creation method.
42 * Only the idl parser and the interface writer should use this.
43 * FIXME: remove this as soon the compiler has a decent attribute
46 public string? custom_return_type_cname
{ get; set; }
49 * Specifies whether this constructor chains up to a base
50 * constructor or a different constructor of the same class.
52 public bool chain_up
{ get; set; }
55 * Creates a new method.
57 * @param name method name
58 * @param source_reference reference to source code
59 * @return newly created method
61 public CreationMethod (string? type_name
, string? name
, SourceReference? source_reference
= null) {
62 base (name
, new
VoidType (), source_reference
);
63 this
.type_name
= type_name
;
65 carray_length_parameter_position
= -3;
66 cdelegate_target_parameter_position
= -3;
69 public override void accept (CodeVisitor visitor
) {
70 visitor
.visit_creation_method (this
);
73 public override void accept_children (CodeVisitor visitor
) {
74 foreach (FormalParameter param
in get_parameters()) {
75 param
.accept (visitor
);
78 foreach (DataType error_type
in get_error_types ()) {
79 error_type
.accept (visitor
);
83 body
.accept (visitor
);
87 public override string get_default_cname () {
88 var parent
= parent_symbol as TypeSymbol
;
91 if (parent is Struct
) {
96 return "%s%s".printf (parent
.get_lower_case_cprefix (), infix
);
98 return "%s%s_%s".printf (parent
.get_lower_case_cprefix (), infix
, name
);
102 public override string get_real_cname () {
103 var parent
= parent_symbol as Class
;
105 if (parent
== null || parent
.is_compact
) {
109 string infix
= "construct";
112 return "%s%s".printf (parent
.get_lower_case_cprefix (), infix
);
114 return "%s%s_%s".printf (parent
.get_lower_case_cprefix (), infix
, name
);
118 public override bool check (SemanticAnalyzer analyzer
) {
125 process_attributes ();
127 if (type_name
!= null && type_name
!= analyzer
.current_symbol
.name
) {
128 // type_name is null for constructors generated by GIdlParser
129 Report
.error (source_reference
, "missing return type in method `%s.%s´".printf (analyzer
.current_symbol
.get_full_name (), type_name
));
134 var old_source_file
= analyzer
.current_source_file
;
135 var old_symbol
= analyzer
.current_symbol
;
136 var old_class
= analyzer
.current_class
;
137 var old_struct
= analyzer
.current_struct
;
138 var old_return_type
= analyzer
.current_return_type
;
140 if (source_reference
!= null) {
141 analyzer
.current_source_file
= source_reference
.file
;
143 analyzer
.current_symbol
= this
;
144 if (parent_symbol is Class
) {
145 analyzer
.current_class
= (Class
) parent_symbol
;
146 } else if (parent_symbol is Struct
) {
147 analyzer
.current_struct
= (Struct
) parent_symbol
;
149 analyzer
.current_return_type
= return_type
;
151 foreach (FormalParameter param
in get_parameters()) {
152 param
.check (analyzer
);
155 foreach (DataType error_type
in get_error_types ()) {
156 error_type
.check (analyzer
);
160 body
.check (analyzer
);
163 analyzer
.current_source_file
= old_source_file
;
164 analyzer
.current_symbol
= old_symbol
;
165 analyzer
.current_class
= old_class
;
166 analyzer
.current_struct
= old_struct
;
167 analyzer
.current_return_type
= old_return_type
;
169 if (analyzer
.current_symbol
.parent_symbol is Method
) {
170 /* lambda expressions produce nested methods */
171 var up_method
= (Method
) analyzer
.current_symbol
.parent_symbol
;
172 analyzer
.current_return_type
= up_method
.return_type
;
175 if (is_abstract
|| is_virtual
|| overrides
) {
176 Report
.error (source_reference
, "The creation method `%s' cannot be marked as override, virtual, or abstract".printf (get_full_name ()));