1 /* valalistliteral.vala
3 * Copyright (C) 2009-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
20 * Jürg Billeter <j@bitron.ch>
23 public class Vala
.ListLiteral
: Literal
{
24 private List
<Expression
> expression_list
= new ArrayList
<Expression
> ();
26 public DataType element_type
{ get; private set; }
28 public ListLiteral (SourceReference? source_reference
= null) {
29 this
.source_reference
= source_reference
;
32 public override void accept_children (CodeVisitor visitor
) {
33 foreach (Expression expr
in expression_list
) {
34 expr
.accept (visitor
);
38 public override void accept (CodeVisitor visitor
) {
39 visitor
.visit_list_literal (this
);
41 visitor
.visit_expression (this
);
44 public void add_expression (Expression expr
) {
45 expression_list
.add (expr
);
46 expr
.parent_node
= this
;
49 public List
<Expression
> get_expressions () {
50 return expression_list
;
53 public override bool is_pure () {
57 public override void replace_expression (Expression old_node
, Expression new_node
) {
58 for (int i
= 0; i
< expression_list
.size
; i
++) {
59 if (expression_list
[i
] == old_node
) {
60 expression_list
[i
] = new_node
;
65 public override bool check (CodeContext context
) {
72 // list literals are also allowed for constant arrays,
73 // however, they are currently handled by InitializerList
74 // therefore transform this expression if necessary
75 var array_type
= target_type as ArrayType
;
76 if (array_type
!= null && array_type
.inline_allocated
) {
77 var initializer
= new
InitializerList (source_reference
);
78 initializer
.target_type
= target_type
;
79 foreach (var expr
in expression_list
) {
80 initializer
.append (expr
);
83 context
.analyzer
.replaced_nodes
.add (this
);
84 parent_node
.replace_expression (this
, initializer
);
85 return initializer
.check (context
);
88 var list_type
= new
ObjectType ((Class
) context
.root
.scope
.lookup ("Dova").scope
.lookup ("List"));
89 list_type
.value_owned
= true;
91 bool fixed_element_type
= false;
92 if (target_type
!= null && target_type
.data_type
== list_type
.data_type
&& target_type
.get_type_arguments ().size
== 1) {
93 element_type
= target_type
.get_type_arguments ().get (0).copy ();
94 element_type
.value_owned
= false;
95 fixed_element_type
= true;
98 for (int i
= 0; i
< expression_list
.size
; i
++) {
99 var expr
= expression_list
[i
];
101 if (fixed_element_type
) {
102 expr
.target_type
= element_type
;
104 if (!expr
.check (context
)) {
108 // expression might have been replaced in the list
109 expr
= expression_list
[i
];
111 if (element_type
== null) {
112 element_type
= expr
.value_type
.copy ();
113 element_type
.value_owned
= false;
117 if (element_type
== null) {
119 Report
.error (source_reference
, "cannot infer element type for list literal");
123 element_type
= element_type
.copy ();
124 element_type
.value_owned
= true;
125 list_type
.add_type_argument (element_type
);
126 value_type
= list_type
;
131 public override void emit (CodeGenerator codegen
) {
132 foreach (Expression expr
in expression_list
) {
136 codegen
.visit_list_literal (this
);
138 codegen
.visit_expression (this
);