valaenum.vala 4.6 KB
Newer Older
1 2
/* valaenum.vala
 *
3
 * Copyright (C) 2006-2010  Jürg Billeter
4 5 6 7
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * 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 11 12 13 14 15 16 17 18 19 20 21 22 23 24

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	Jürg Billeter <j@bitron.ch>
 */

using GLib;

25 26 27
/**
 * Represents an enum declaration in the source code.
 */
28
public class Vala.Enum : TypeSymbol {
29 30 31
	/**
	 * Specifies whether this is a flags enum.
	 */
32 33 34 35 36 37 38 39
	public bool is_flags {
		get {
			if (_is_flags == null) {
				_is_flags = get_attribute ("Flags") != null;
			}
			return _is_flags;
		}
	}
40

41 42
	private List<EnumValue> values = new ArrayList<EnumValue> ();
	private List<Method> methods = new ArrayList<Method> ();
43
	private List<Constant> constants = new ArrayList<Constant> ();
44 45

	private bool? _is_flags;
46

47 48 49
	/**
	 * Creates a new enum.
	 *
50 51 52
	 * @param name             type name
	 * @param source_reference reference to source code
	 * @return                 newly created enum
53
	 */
54 55
	public Enum (string name, SourceReference? source_reference = null, Comment? comment = null) {
		base (name, source_reference, comment);
56
	}
57

58 59 60 61 62
	/**
	 * Appends the specified enum value to the list of values.
	 *
	 * @param value an enum value
	 */
63
	public void add_value (EnumValue value) {
64 65
		value.access = SymbolAccessibility.PUBLIC;

66
		values.add (value);
67
		scope.add (value.name, value);
68
	}
69

70 71 72 73 74
	/**
	 * Adds the specified method as a member to this enum.
	 *
	 * @param m a method
	 */
75
	public override void add_method (Method m) {
76 77
		if (m is CreationMethod) {
			Report.error (m.source_reference, "construction methods may only be declared within classes and structs");
78

79 80 81
			m.error = true;
			return;
		}
82
		if (m.binding == MemberBinding.INSTANCE) {
83
			m.this_parameter = new Parameter ("this", new EnumValueType (this));
84 85
			m.scope.add (m.this_parameter.name, m.this_parameter);
		}
Jürg Billeter's avatar
Jürg Billeter committed
86
		if (!(m.return_type is VoidType) && m.get_postconditions ().size > 0) {
87 88 89
			m.result_var = new LocalVariable (m.return_type.copy (), "result", null, source_reference);
			m.result_var.is_result = true;
		}
90

91
		methods.add (m);
92
		scope.add (m.name, m);
93 94
	}

95 96 97 98 99
	/**
	 * Adds the specified constant as a member to this enum.
	 *
	 * @param c a constant
	 */
100
	public override void add_constant (Constant c) {
101 102 103 104
		constants.add (c);
		scope.add (c.name, c);
	}

Jürg Billeter's avatar
Jürg Billeter committed
105 106 107 108 109
	/**
	 * Returns a copy of the list of enum values.
	 *
	 * @return list of enum values
	 */
110
	public List<EnumValue> get_values () {
111
		return values;
Jürg Billeter's avatar
Jürg Billeter committed
112 113
	}

114 115 116 117 118
	// used by vapigen
	public void remove_all_values () {
		values.clear ();
	}

119 120 121 122 123
	/**
	 * Returns a copy of the list of methods.
	 *
	 * @return list of methods
	 */
124
	public List<Method> get_methods () {
125
		return methods;
126 127
	}

128 129 130 131 132 133 134 135 136
	/**
	 * Returns a copy of the list of constants.
	 *
	 * @return list of constants
	 */
	public List<Constant> get_constants () {
		return constants;
	}

137
	public override void accept (CodeVisitor visitor) {
138 139 140
		visitor.visit_enum (this);
	}

141
	public override void accept_children (CodeVisitor visitor) {
142 143
		foreach (EnumValue value in values) {
			value.accept (visitor);
144
		}
145 146 147 148

		foreach (Method m in methods) {
			m.accept (visitor);
		}
149 150 151 152

		foreach (Constant c in constants) {
			c.accept (visitor);
		}
153
	}
154

155 156 157
	public override bool is_reference_type () {
		return false;
	}
158

159
	public override bool check (CodeContext context) {
160 161 162 163 164 165
		if (checked) {
			return !error;
		}

		checked = true;

166 167
		var old_source_file = context.analyzer.current_source_file;
		var old_symbol = context.analyzer.current_symbol;
168 169

		if (source_reference != null) {
170
			context.analyzer.current_source_file = source_reference.file;
171
		}
172
		context.analyzer.current_symbol = this;
173

174 175 176 177 178 179
		if (values.size <= 0) {
			Report.error (source_reference, "Enum `%s' requires at least one value".printf (get_full_name ()));
			error = true;
			return false;
		}

180
		foreach (EnumValue value in values) {
181
			value.check (context);
182 183 184
		}

		foreach (Method m in methods) {
185
			m.check (context);
186
		}
187

188
		foreach (Constant c in constants) {
189
			c.check (context);
190 191
		}

192 193
		context.analyzer.current_source_file = old_source_file;
		context.analyzer.current_symbol = old_symbol;
194

195 196
		return !error;
	}
197
}