1/* class.vala 2 * 3 * Copyright (C) 2008-2011 Florian Brosch 4 * 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. 9 * 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. 14 * 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 18 * 19 * Author: 20 * Florian Brosch <flo.brosch@gmail.com> 21 */ 22 23 24using Valadoc.Content; 25 26/** 27 * Represents a class declaration. 28 */ 29public class Valadoc.Api.Class : TypeSymbol { 30 private Vala.ArrayList<TypeReference> interfaces; 31 32 private string? dbus_name; 33 private string? take_value_function_cname; 34 private string? get_value_function_cname; 35 private string? set_value_function_cname; 36 private string? unref_function_name; 37 private string? ref_function_name; 38 private string? free_function_name; 39 private string? finalize_function_name; 40 private string? param_spec_function_name; 41 private string? type_id; 42 private string? is_class_type_macro_name; 43 private string? class_type_macro_name; 44 private string? class_macro_name; 45 private string? private_cname; 46 private string? cname; 47 48 public Class (Node parent, SourceFile file, string name, Vala.SymbolAccessibility accessibility, 49 SourceComment? comment, 50 Vala.Class data) 51 { 52 bool is_basic_type = data.base_class == null && data.name == "string"; 53 54 base (parent, file, name, accessibility, comment, is_basic_type, data); 55 56 this.interfaces = new Vala.ArrayList<TypeReference> (); 57 58 if (!data.is_compact) { 59 this.is_class_type_macro_name = Vala.get_ccode_class_type_check_function (data); 60 this.class_type_macro_name = Vala.get_ccode_class_type_function (data); 61 this.class_macro_name = Vala.get_ccode_type_get_function (data); 62 this.private_cname = _get_private_cname (data); 63 } 64 this.dbus_name = Vala.GDBusModule.get_dbus_name (data); 65 this.type_id = Vala.get_ccode_type_id (data); 66 this.cname = Vala.get_ccode_name (data); 67 68 this.param_spec_function_name = Vala.get_ccode_param_spec_function (data); 69 70 this.unref_function_name = Vala.get_ccode_unref_function (data); 71 this.ref_function_name = Vala.get_ccode_ref_function (data); 72 this.finalize_function_name = (data.is_fundamental () ? "%sfinalize".printf (Vala.get_ccode_lower_case_prefix (data)) : null); 73 this.free_function_name = (data.is_compact ? Vala.get_ccode_free_function (data) : null); 74 75 this.take_value_function_cname = Vala.get_ccode_take_value_function (data); 76 this.get_value_function_cname = Vala.get_ccode_get_value_function (data); 77 this.set_value_function_cname = Vala.get_ccode_set_value_function (data); 78 79 this.is_fundamental = data.is_fundamental (); 80 this.is_abstract = data.is_abstract; 81 this.is_sealed = data.is_sealed; 82 } 83 84 string? _get_private_cname (Vala.Class element) { 85 if (element.is_compact) { 86 return null; 87 } 88 89 string? cname = Vala.get_ccode_name (element); 90 return (cname != null ? cname + "Private" : null); 91 } 92 93 /** 94 * Specifies the base class. 95 */ 96 public TypeReference? base_type { 97 set; 98 get; 99 } 100 101 /** 102 * Returns the name of this class as it is used in C. 103 */ 104 public string? get_cname () { 105 return cname; 106 } 107 108 /** 109 * Returns the name of this class' private data structure as it is used in C. 110 */ 111 public string? get_private_cname () { 112 return private_cname; 113 } 114 115 /** 116 * Returns the C symbol representing the runtime type id for this data type. 117 */ 118 public string? get_type_id () { 119 return type_id; 120 } 121 122 /** 123 * Returns the C function name that increments the reference count of 124 * instances of this data type. 125 * 126 * @return the name of the C function or null if this data type does not 127 * support reference counting 128 */ 129 public string? get_ref_function_cname () { 130 return ref_function_name; 131 } 132 133 /** 134 * Returns the C function name that decrements the reference count of 135 * instances of this data type. 136 * 137 * @return the name of the C function or null if this data type does not 138 * support reference counting 139 */ 140 public string? get_unref_function_cname () { 141 return unref_function_name; 142 } 143 144 /** 145 * Returns the C function name that frees the 146 * instances of this data type. 147 * 148 * @return the name of the C function or null 149 */ 150 public string? get_free_function_name () { 151 return free_function_name; 152 } 153 154 /** 155 * Returns the C function name that finalizes the 156 * instances of this data type. 157 * 158 * @return the name of the C function or null 159 */ 160 public string? get_finalize_function_name () { 161 return finalize_function_name; 162 } 163 164 /** 165 * Returns the cname of the GValue parameter spec function. 166 */ 167 public string? get_param_spec_function_cname () { 168 return param_spec_function_name; 169 } 170 171 /** 172 * Returns the cname of the GValue setter function. 173 */ 174 public string? get_set_value_function_cname () { 175 return set_value_function_cname; 176 } 177 178 /** 179 * Returns the cname of the GValue getter function. 180 */ 181 public string? get_get_value_function_cname () { 182 return get_value_function_cname; 183 } 184 185 /** 186 * Returns the cname of the GValue taker function. 187 */ 188 public string? get_take_value_function_cname () { 189 return take_value_function_cname; 190 } 191 192 /** 193 * Returns the dbus-name. 194 */ 195 public string? get_dbus_name () { 196 return dbus_name; 197 } 198 199 /** 200 * Gets the name of the GType macro which returns the class struct. 201 */ 202 public string get_class_macro_name () { 203 return class_macro_name; 204 } 205 206 /** 207 * Gets the name of the GType macro which returns the type of the class. 208 */ 209 public string get_class_type_macro_name () { 210 return class_type_macro_name; 211 } 212 213 /** 214 * Gets the name of the GType macro which returns whether a class instance is of a given type. 215 */ 216 public string get_is_class_type_macro_name () { 217 return is_class_type_macro_name; 218 } 219 220 /** 221 * Returns a list of all newly implemented interfaces. 222 * 223 * @see get_full_implemented_interface_list 224 */ 225 public Vala.Collection<TypeReference> get_implemented_interface_list () { 226 return this.interfaces; 227 } 228 229 private Vala.Collection<TypeReference> _full_implemented_interfaces = null; 230 231 /** 232 * Returns a list of all implemented interfaces. 233 * 234 * @see get_implemented_interface_list 235 */ 236 public Vala.Collection<TypeReference> get_full_implemented_interface_list () { 237 if (_full_implemented_interfaces == null) { 238 _full_implemented_interfaces = new Vala.ArrayList<TypeReference> (); 239 _full_implemented_interfaces.add_all (this.interfaces); 240 241 if (base_type != null) { 242 _full_implemented_interfaces.add_all (((Class) base_type.data_type).get_full_implemented_interface_list ()); 243 } 244 } 245 246 return _full_implemented_interfaces; 247 } 248 249 public void add_interface (TypeReference iface) { 250 interfaces.add (iface); 251 } 252 253 /** 254 * Specifies whether this class is abstract. 255 */ 256 public bool is_abstract { 257 private set; 258 get; 259 } 260 261 /** 262 * Specifies whether this class is sealed. Sealed classes may not be 263 * sub-classed. 264 */ 265 public bool is_sealed { 266 private set; 267 get; 268 } 269 270 /** 271 * Specifies whether this class is fundamental. 272 */ 273 public bool is_fundamental { 274 private set; 275 get; 276 } 277 278 public bool is_compact { 279 get { 280 return ((Vala.Class) data).is_compact; 281 } 282 } 283 284 /** 285 * {@inheritDoc} 286 */ 287 public override NodeType node_type { get { return NodeType.CLASS; } } 288 289 /** 290 * {@inheritDoc} 291 */ 292 public override void accept (Visitor visitor) { 293 visitor.visit_class (this); 294 } 295 296 private Vala.Set<Interface> _known_derived_interfaces = new Vala.HashSet<Interface> (); 297 private Vala.Set<Class> _known_child_classes = new Vala.HashSet<Class> (); 298 299 /** 300 * Returns a list of all known classes based on this class 301 */ 302 public Vala.Collection<Class> get_known_child_classes () { 303 return _known_child_classes; 304 } 305 306 /** 307 * Returns a list of all known interfaces based on this class 308 */ 309 public Vala.Collection<Interface> get_known_derived_interfaces () { 310 return _known_derived_interfaces; 311 } 312 313 public void register_derived_interface (Interface iface) { 314 _known_derived_interfaces.add (iface); 315 } 316 317 public void register_child_class (Class cl) { 318 if (this.base_type != null) { 319 ((Class) this.base_type.data_type).register_child_class (cl); 320 } 321 322 _known_child_classes.add (cl); 323 } 324 325 /** 326 * {@inheritDoc} 327 */ 328 protected override Inline build_signature () { 329 var signature = new SignatureBuilder (); 330 331 signature.append_keyword (accessibility.to_string ()); 332 if (is_abstract) { 333 signature.append_keyword ("abstract"); 334 } 335 if (is_sealed) { 336 signature.append_keyword ("sealed"); 337 } 338 signature.append_keyword ("class"); 339 signature.append_symbol (this); 340 341 var type_parameters = get_children_by_type (NodeType.TYPE_PARAMETER, false); 342 if (type_parameters.size > 0) { 343 signature.append ("<", false); 344 bool first = true; 345 foreach (Item param in type_parameters) { 346 if (!first) { 347 signature.append (",", false); 348 } 349 signature.append_content (param.signature, false); 350 first = false; 351 } 352 signature.append (">", false); 353 } 354 355 bool first = true; 356 if (base_type != null) { 357 signature.append (":"); 358 359 signature.append_content (base_type.signature); 360 first = false; 361 } 362 363 if (interfaces.size > 0) { 364 if (first) { 365 signature.append (":"); 366 } 367 368 foreach (Item implemented_interface in interfaces) { 369 if (!first) { 370 signature.append (",", false); 371 } 372 signature.append_content (implemented_interface.signature); 373 first = false; 374 } 375 } 376 377 return signature.get (); 378 } 379} 380 381