vala: Add consts/methods to retrieve and check library version
[vala-gnome.git] / vala / valanamespace.vala
blobaf062f85c0108c004a7062081c7e6b0728eae6cb
1 /* valanamespace.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
19 * Author:
20 * Jürg Billeter <j@bitron.ch>
23 using GLib;
25 /**
26 * Represents a namespace declaration in the source code.
28 public class Vala.Namespace : Symbol {
29 private List<Class> classes = new ArrayList<Class> ();
30 private List<Interface> interfaces = new ArrayList<Interface> ();
31 private List<Struct> structs = new ArrayList<Struct> ();
32 private List<Enum> enums = new ArrayList<Enum> ();
33 private List<ErrorDomain> error_domains = new ArrayList<ErrorDomain> ();
34 private List<Delegate> delegates = new ArrayList<Delegate> ();
35 private List<Constant> constants = new ArrayList<Constant> ();
36 private List<Field> fields = new ArrayList<Field> ();
37 private List<Method> methods = new ArrayList<Method> ();
39 private List<Comment> comments = new ArrayList<Comment> ();
41 private List<Namespace> namespaces = new ArrayList<Namespace> ();
43 private List<UsingDirective> using_directives = new ArrayList<UsingDirective> ();
45 /**
46 * Creates a new namespace.
48 * @param name namespace name
49 * @param source_reference reference to source code
50 * @return newly created namespace
52 public Namespace (string? name, SourceReference? source_reference = null) {
53 base (name, source_reference);
54 access = SymbolAccessibility.PUBLIC;
57 /**
58 * Adds a new using directive with the specified namespace.
60 * @param ns reference to namespace
62 public void add_using_directive (UsingDirective ns) {
63 using_directives.add (ns);
66 public void add_comment (Comment comment) {
67 comments.add (comment);
70 /**
71 * Returns a copy of the list of namespaces.
73 * @return comment list
75 public List<Comment> get_comments () {
76 return comments;
79 /**
80 * Adds the specified namespace to this source file.
82 * @param ns a namespace
84 public override void add_namespace (Namespace ns) {
85 if (ns.owner == null) {
86 ns.source_reference.file.add_node (ns);
89 if (scope.lookup (ns.name) is Namespace) {
90 // merge if namespace already exists
91 var old_ns = (Namespace) scope.lookup (ns.name);
92 if (old_ns.external_package && !ns.external_package) {
93 old_ns.source_reference = ns.source_reference;
96 foreach (var using_directive in ns.using_directives) {
97 old_ns.add_using_directive (using_directive);
99 foreach (Namespace sub_ns in ns.get_namespaces ()) {
100 old_ns.add_namespace (sub_ns);
102 foreach (Class cl in ns.get_classes ()) {
103 old_ns.add_class (cl);
105 foreach (Struct st in ns.get_structs ()) {
106 old_ns.add_struct (st);
108 foreach (Interface iface in ns.get_interfaces ()) {
109 old_ns.add_interface (iface);
111 foreach (Delegate d in ns.get_delegates ()) {
112 old_ns.add_delegate (d);
114 foreach (Enum en in ns.get_enums ()) {
115 old_ns.add_enum (en);
117 foreach (ErrorDomain ed in ns.get_error_domains ()) {
118 old_ns.add_error_domain (ed);
120 foreach (Constant c in ns.get_constants ()) {
121 old_ns.add_constant (c);
123 foreach (Field f in ns.get_fields ()) {
124 old_ns.add_field (f);
126 foreach (Method m in ns.get_methods ()) {
127 old_ns.add_method (m);
129 foreach (Comment c in ns.get_comments ()) {
130 old_ns.add_comment (c);
132 foreach (Attribute a in ns.attributes) {
133 if (old_ns.get_attribute (a.name) == null) {
134 old_ns.attributes.append(a);
137 } else {
138 namespaces.add (ns);
139 scope.add (ns.name, ns);
144 * Returns a copy of the list of namespaces.
146 * @return namespace list
148 public List<Namespace> get_namespaces () {
149 return namespaces;
153 * Adds the specified class to this namespace.
155 * @param cl a class
157 public override void add_class (Class cl) {
158 // namespaces do not support private memebers
159 if (cl.access == SymbolAccessibility.PRIVATE) {
160 cl.access = SymbolAccessibility.INTERNAL;
163 if (cl.owner == null) {
164 cl.source_reference.file.add_node (cl);
167 classes.add (cl);
168 scope.add (cl.name, cl);
172 * Adds the specified interface to this namespace.
174 * @param iface an interface
176 public override void add_interface (Interface iface) {
177 // namespaces do not support private memebers
178 if (iface.access == SymbolAccessibility.PRIVATE) {
179 iface.access = SymbolAccessibility.INTERNAL;
182 if (iface.owner == null) {
183 iface.source_reference.file.add_node (iface);
186 interfaces.add (iface);
187 scope.add (iface.name, iface);
192 * Adds the specified struct to this namespace.
194 * @param st a struct
196 public override void add_struct (Struct st) {
197 // namespaces do not support private memebers
198 if (st.access == SymbolAccessibility.PRIVATE) {
199 st.access = SymbolAccessibility.INTERNAL;
202 if (st.owner == null) {
203 st.source_reference.file.add_node (st);
206 structs.add (st);
207 scope.add (st.name, st);
211 * Removes the specified struct from this namespace.
213 * @param st a struct
215 public void remove_struct (Struct st) {
216 structs.remove (st);
217 scope.remove (st.name);
221 * Adds the specified enum to this namespace.
223 * @param en an enum
225 public override void add_enum (Enum en) {
226 // namespaces do not support private memebers
227 if (en.access == SymbolAccessibility.PRIVATE) {
228 en.access = SymbolAccessibility.INTERNAL;
231 if (en.owner == null) {
232 en.source_reference.file.add_node (en);
235 enums.add (en);
236 scope.add (en.name, en);
240 * Adds the specified error domain to this namespace.
242 * @param edomain an error domain
244 public override void add_error_domain (ErrorDomain edomain) {
245 // namespaces do not support private memebers
246 if (edomain.access == SymbolAccessibility.PRIVATE) {
247 edomain.access = SymbolAccessibility.INTERNAL;
250 if (edomain.owner == null) {
251 edomain.source_reference.file.add_node (edomain);
254 error_domains.add (edomain);
255 scope.add (edomain.name, edomain);
259 * Adds the specified delegate to this namespace.
261 * @param d a delegate
263 public override void add_delegate (Delegate d) {
264 // namespaces do not support private memebers
265 if (d.access == SymbolAccessibility.PRIVATE) {
266 d.access = SymbolAccessibility.INTERNAL;
269 if (d.owner == null) {
270 d.source_reference.file.add_node (d);
273 delegates.add (d);
274 scope.add (d.name, d);
278 * Returns a copy of the list of structs.
280 * @return struct list
282 public List<Struct> get_structs () {
283 return structs;
287 * Returns a copy of the list of classes.
289 * @return class list
291 public List<Class> get_classes () {
292 return classes;
296 * Returns a copy of the list of interfaces.
298 * @return interface list
300 public List<Interface> get_interfaces () {
301 return interfaces;
305 * Returns a copy of the list of enums.
307 * @return enum list
309 public List<Enum> get_enums () {
310 return enums;
314 * Returns a copy of the list of error domains.
316 * @return error domain list
318 public List<ErrorDomain> get_error_domains () {
319 return error_domains;
323 * Returns a copy of the list of fields.
325 * @return field list
327 public List<Field> get_fields () {
328 return fields;
332 * Returns a copy of the list of constants.
334 * @return constant list
336 public List<Constant> get_constants () {
337 return constants;
341 * Returns a copy of the list of delegates.
343 * @return delegate list
345 public List<Delegate> get_delegates () {
346 return delegates;
350 * Returns a copy of the list of methods.
352 * @return method list
354 public List<Method> get_methods () {
355 return methods;
359 * Adds the specified constant to this namespace.
361 * @param constant a constant
363 public override void add_constant (Constant constant) {
364 // namespaces do not support private memebers
365 if (constant.access == SymbolAccessibility.PRIVATE) {
366 constant.access = SymbolAccessibility.INTERNAL;
369 if (constant.owner == null) {
370 constant.source_reference.file.add_node (constant);
373 constants.add (constant);
374 scope.add (constant.name, constant);
378 * Adds the specified field to this namespace.
380 * @param f a field
382 public override void add_field (Field f) {
383 if (f.binding == MemberBinding.INSTANCE) {
384 // default to static member binding
385 f.binding = MemberBinding.STATIC;
388 // namespaces do not support private memebers
389 if (f.access == SymbolAccessibility.PRIVATE) {
390 f.access = SymbolAccessibility.INTERNAL;
393 if (f.binding == MemberBinding.INSTANCE) {
394 Report.error (f.source_reference, "instance members are not allowed outside of data types");
395 f.error = true;
396 return;
397 } else if (f.binding == MemberBinding.CLASS) {
398 Report.error (f.source_reference, "class members are not allowed outside of classes");
399 f.error = true;
400 return;
403 if (f.owner == null) {
404 f.source_reference.file.add_node (f);
407 fields.add (f);
408 scope.add (f.name, f);
412 * Adds the specified method to this namespace.
414 * @param m a method
416 public override void add_method (Method m) {
417 if (m.binding == MemberBinding.INSTANCE) {
418 // default to static member binding
419 m.binding = MemberBinding.STATIC;
422 // namespaces do not support private memebers
423 if (m.access == SymbolAccessibility.PRIVATE) {
424 m.access = SymbolAccessibility.INTERNAL;
427 if (m is CreationMethod) {
428 Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
429 m.error = true;
430 return;
432 if (m.binding == MemberBinding.INSTANCE) {
433 Report.error (m.source_reference, "instance members are not allowed outside of data types");
434 m.error = true;
435 return;
436 } else if (m.binding == MemberBinding.CLASS) {
437 Report.error (m.source_reference, "class members are not allowed outside of classes");
438 m.error = true;
439 return;
441 if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
442 m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
443 m.result_var.is_result = true;
446 if (m.owner == null) {
447 m.source_reference.file.add_node (m);
450 methods.add (m);
451 scope.add (m.name, m);
454 public override void accept (CodeVisitor visitor) {
455 visitor.visit_namespace (this);
458 public override void accept_children (CodeVisitor visitor) {
459 foreach (UsingDirective ns_ref in using_directives) {
460 ns_ref.accept (visitor);
463 foreach (Namespace ns in namespaces) {
464 ns.accept (visitor);
467 /* process enums first to avoid order problems in C code */
468 foreach (Enum en in enums) {
469 en.accept (visitor);
472 foreach (ErrorDomain edomain in error_domains) {
473 edomain.accept (visitor);
476 foreach (Class cl in classes) {
477 cl.accept (visitor);
480 foreach (Interface iface in interfaces) {
481 iface.accept (visitor);
484 foreach (Struct st in structs) {
485 st.accept (visitor);
488 foreach (Delegate d in delegates) {
489 d.accept (visitor);
492 foreach (Constant c in constants) {
493 c.accept (visitor);
496 foreach (Field f in fields) {
497 f.accept (visitor);
500 foreach (Method m in methods) {
501 m.accept (visitor);
505 public override bool check (CodeContext context) {
506 if (checked) {
507 return !error;
510 checked = true;
512 var a = get_attribute ("CCode");
513 if (a != null && a.has_argument ("gir_namespace")) {
514 source_reference.file.gir_namespace = a.get_string ("gir_namespace");
516 if (a != null && a.has_argument ("gir_version")) {
517 source_reference.file.gir_version = a.get_string ("gir_version");
520 foreach (Namespace ns in namespaces) {
521 ns.check (context);
524 return !error;