1/* valaswitchlabel.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 23using GLib; 24 25/** 26 * Represents a switch label in the source code. 27 */ 28public class Vala.SwitchLabel : CodeNode { 29 /** 30 * Specifies the label expression. 31 */ 32 public Expression expression { 33 get { return _expression; } 34 set { 35 _expression = value; 36 _expression.parent_node = this; 37 } 38 } 39 40 public weak SwitchSection section { 41 get { return (SwitchSection) parent_node; } 42 } 43 44 private Expression _expression; 45 46 /** 47 * Creates a new switch case label. 48 * 49 * @param expr label expression 50 * @param source reference to source code 51 * @return newly created switch case label 52 */ 53 public SwitchLabel (Expression expr, SourceReference? source = null) { 54 expression = expr; 55 source_reference = source; 56 } 57 58 /** 59 * Creates a new switch default label. 60 * 61 * @param source reference to source code 62 * @return newly created switch default label 63 */ 64 public SwitchLabel.with_default (SourceReference? source = null) { 65 source_reference = source; 66 } 67 68 public override void accept (CodeVisitor visitor) { 69 visitor.visit_switch_label (this); 70 } 71 72 public override void accept_children (CodeVisitor visitor) { 73 if (expression != null) { 74 expression.accept (visitor); 75 76 visitor.visit_end_full_expression (expression); 77 } 78 } 79 80 public override bool check (CodeContext context) { 81 if (checked) { 82 return !error; 83 } 84 85 checked = true; 86 87 if (expression != null) { 88 var switch_statement = (SwitchStatement) section.parent_node; 89 90 // enum-type inference 91 var condition_target_type = switch_statement.expression.target_type; 92 if (expression.symbol_reference == null && condition_target_type != null && condition_target_type.type_symbol is Enum) { 93 var enum_type = (Enum) condition_target_type.type_symbol; 94 foreach (var val in enum_type.get_values ()) { 95 if (expression.to_string () == val.name) { 96 expression.target_type = condition_target_type.copy (); 97 expression.symbol_reference = val; 98 break; 99 } 100 } 101 } 102 103 if (!expression.check (context)) { 104 error = true; 105 return false; 106 } 107 108 if (!expression.is_constant ()) { 109 error = true; 110 Report.error (expression.source_reference, "Expression must be constant"); 111 return false; 112 } 113 if (!expression.value_type.compatible (switch_statement.expression.value_type)) { 114 error = true; 115 Report.error (expression.source_reference, "Cannot convert from `%s' to `%s'".printf (expression.value_type.to_string (), switch_statement.expression.value_type.to_string ())); 116 return false; 117 } 118 } 119 120 return true; 121 } 122 123 public override void emit (CodeGenerator codegen) { 124 codegen.visit_switch_label (this); 125 } 126} 127