Imported Upstream version 0.19.0
[platform/upstream/vala.git] / vala / valaswitchsection.vala
1 /* valaswitchsection.vala
2  *
3  * Copyright (C) 2006-2010  Jürg Billeter
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  *      Jürg Billeter <j@bitron.ch>
21  */
22
23 using GLib;
24
25 /**
26  * Represents a switch section in the source code.
27  */
28 public class Vala.SwitchSection : Block {
29         private List<SwitchLabel> labels = new ArrayList<SwitchLabel> ();
30
31         /**
32          * Creates a new switch section.
33          *
34          * @param source_reference reference to source code
35          * @return                 newly created switch section
36          */
37         public SwitchSection (SourceReference? source_reference) {
38                 base (source_reference);
39         }
40         
41         /**
42          * Appends the specified label to the list of switch labels.
43          *
44          * @param label a switch label
45          */
46         public void add_label (SwitchLabel label) {
47                 if (labels.size == 0) {
48                         this.source_reference = label.source_reference;
49                 }
50
51                 labels.add (label);
52                 label.section = this;
53         }
54         
55         /**
56          * Returns a copy of the list of switch labels.
57          *
58          * @return switch label list
59          */
60         public List<SwitchLabel> get_labels () {
61                 return labels;
62         }
63         
64         public bool has_default_label () {
65                 foreach (SwitchLabel label in labels) {
66                         if (label.expression == null) {
67                                 return true;
68                         }
69                 }
70                 
71                 return false;
72         }
73         
74         public override void accept (CodeVisitor visitor) {
75                 visitor.visit_switch_section (this);
76         }
77
78         public override void accept_children (CodeVisitor visitor) {
79                 foreach (SwitchLabel label in labels) {
80                         label.accept (visitor);
81                 }
82
83                 foreach (Statement st in get_statements ()) {
84                         st.accept (visitor);
85                 }
86         }
87
88         public override bool check (CodeContext context) {
89                 if (checked) {
90                         return !error;
91                 }
92
93                 checked = true;
94
95                 foreach (SwitchLabel label in get_labels ()) {
96                         label.check (context);
97                 }
98
99                 owner = context.analyzer.current_symbol.scope;
100
101                 var old_symbol = context.analyzer.current_symbol;
102                 var old_insert_block = context.analyzer.insert_block;
103                 context.analyzer.current_symbol = this;
104                 context.analyzer.insert_block = this;
105
106                 foreach (Statement st in get_statements ()) {
107                         st.check (context);
108                 }
109
110                 foreach (LocalVariable local in get_local_variables ()) {
111                         local.active = false;
112                 }
113
114                 // use get_statements () instead of statement_list to not miss errors within StatementList objects
115                 foreach (Statement stmt in get_statements ()) {
116                         add_error_types (stmt.get_error_types ());
117                 }
118
119                 context.analyzer.current_symbol = old_symbol;
120                 context.analyzer.insert_block = old_insert_block;
121
122                 return !error;
123         }
124
125         public override void emit (CodeGenerator codegen) {
126                 foreach (SwitchLabel label in labels) {
127                         label.emit (codegen);
128                 }
129
130                 base.emit (codegen);
131         }
132 }