Use `internal' accessibility for namespace members by default
[vala-lang.git] / vala / valaarraycreationexpression.vala
blob6ed9d0c38212a7b252b70403afceb9c7a0775858
1 /* valaarraycreationexpression.vala
3 * Copyright (C) 2006-2009 Jürg Billeter
4 * Copyright (C) 2006-2008 Raffaele Sandrini
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Author:
21 * Raffaele Sandrini <raffaele@sandrini.ch>
22 * Jürg Billeter <j@bitron.ch>
25 using GLib;
26 using Gee;
28 /**
29 * Represents an array creation expression e.g. "new int[] {1,2,3}".
31 public class Vala.ArrayCreationExpression : Expression {
32 /**
33 * The type of the elements of the array.
35 public DataType element_type {
36 get { return _element_type; }
37 set {
38 _element_type = value;
39 _element_type.parent_node = this;
43 /**
44 * The rank of the array.
46 public int rank { get; set; }
48 /**
49 * The size for each dimension ascending from left to right.
51 private Gee.List<Expression> sizes = new ArrayList<Expression> ();
53 /**
54 * The root array initializer list.
56 public InitializerList? initializer_list {
57 get { return _initializer_list; }
58 set {
59 _initializer_list = value;
60 if (_initializer_list != null) {
61 _initializer_list.parent_node = this;
66 private DataType _element_type;
67 private InitializerList? _initializer_list;
69 /**
70 * Add a size expression.
72 public void append_size (Expression size) {
73 sizes.add (size);
76 /**
77 * Get the sizes for all dimensions ascending from left to right.
79 public Gee.List<Expression> get_sizes () {
80 return new ReadOnlyList<Expression> (sizes);
83 public ArrayCreationExpression (DataType element_type, int rank, InitializerList? initializer_list, SourceReference source_reference) {
84 this.element_type = element_type;
85 this.rank = rank;
86 this.initializer_list = initializer_list;
87 this.source_reference = source_reference;
90 public override void accept_children (CodeVisitor visitor) {
91 if (element_type != null) {
92 element_type.accept (visitor);
95 foreach (Expression e in sizes) {
96 e.accept (visitor);
99 if (initializer_list != null) {
100 initializer_list.accept (visitor);
104 public override void accept (CodeVisitor visitor) {
105 visitor.visit_array_creation_expression (this);
107 visitor.visit_expression (this);
110 public override bool is_pure () {
111 return false;
114 public override void replace_type (DataType old_type, DataType new_type) {
115 if (element_type == old_type) {
116 element_type = new_type;
120 private int create_sizes_from_initializer_list (SemanticAnalyzer analyzer, InitializerList il, int rank, Gee.List<Literal> sl) {
121 if (sl.size == (this.rank - rank)) {
122 // only add size if this is the first initializer list of the current dimension
123 var init = new IntegerLiteral (il.size.to_string (), il.source_reference);
124 init.check (analyzer);
125 sl.add (init);
128 int subsize = -1;
129 foreach (Expression e in il.get_initializers ()) {
130 if (e is InitializerList) {
131 if (rank == 1) {
132 il.error = true;
133 e.error = true;
134 Report.error (e.source_reference, "Expected array element, got array initializer list");
135 return -1;
137 int size = create_sizes_from_initializer_list (analyzer, (InitializerList) e, rank - 1, sl);
138 if (size == -1) {
139 return -1;
141 if (subsize >= 0 && subsize != size) {
142 il.error = true;
143 Report.error (il.source_reference, "Expected initializer list of size %d, got size %d".printf (subsize, size));
144 return -1;
145 } else {
146 subsize = size;
148 } else {
149 if (rank != 1) {
150 il.error = true;
151 e.error = true;
152 Report.error (e.source_reference, "Expected array initializer list, got array element");
153 return -1;
157 return il.size;
160 public override bool check (SemanticAnalyzer analyzer) {
161 if (checked) {
162 return !error;
165 checked = true;
167 Gee.List<Expression> sizes = get_sizes ();
168 var initlist = initializer_list;
170 if (element_type != null) {
171 element_type.check (analyzer);
174 foreach (Expression e in sizes) {
175 e.check (analyzer);
178 var calc_sizes = new ArrayList<Literal> ();
179 if (initlist != null) {
180 initlist.target_type = new ArrayType (element_type, rank, source_reference);
182 initlist.check (analyzer);
184 var ret = create_sizes_from_initializer_list (analyzer, initlist, rank, calc_sizes);
185 if (ret == -1) {
186 error = true;
190 if (sizes.size > 0) {
191 /* check for errors in the size list */
192 foreach (Expression e in sizes) {
193 if (e.value_type == null) {
194 /* return on previous error */
195 return false;
196 } else if (!e.value_type.compatible (analyzer.uint64_type)) {
197 error = true;
198 Report.error (e.source_reference, "Expression of integer type expected");
201 } else {
202 if (initlist == null) {
203 error = true;
204 /* this is an internal error because it is already handeld by the parser */
205 Report.error (source_reference, "internal error: initializer list expected");
206 } else {
207 foreach (Expression size in calc_sizes) {
208 append_size (size);
213 if (error) {
214 return false;
217 /* check for wrong elements inside the initializer */
218 if (initializer_list != null && initializer_list.value_type == null) {
219 return false;
222 /* try to construct the type of the array */
223 if (element_type == null) {
224 error = true;
225 Report.error (source_reference, "Cannot determine the element type of the created array");
226 return false;
229 element_type.value_owned = true;
231 value_type = new ArrayType (element_type, rank, source_reference);
232 value_type.value_owned = true;
234 return !error;