001: package org.jacorb.idl;
002:
003: /*
004: * JacORB - a free Java ORB
005: *
006: * Copyright (C) 1997-2004 Gerald Brose.
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Library General Public License for more details.
017: *
018: * You should have received a copy of the GNU Library General Public
019: * License along with this library; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: */
022:
023: import java.util.Enumeration;
024:
025: /**
026: * @author Gerald Brose
027: * @version $Id: Case.java,v 1.17 2006/06/19 10:34:57 alphonse.bendt Exp $
028: */
029:
030: public class Case extends IdlSymbol {
031: /** the labels for this case */
032: public SymbolList case_label_list = null;
033:
034: /** only set after parsing */
035: private IdlSymbol[] labels;
036:
037: /** this case's element's type's spec */
038: public ElementSpec element_spec = null;
039:
040: /** the switch type's spec */
041: TypeSpec type_spec = null;
042:
043: public Case(int num) {
044: super (num);
045: }
046:
047: public void setPackage(String s) {
048: s = parser.pack_replace(s);
049: if (pack_name.length() > 0)
050: pack_name = s + "." + pack_name;
051: else
052: pack_name = s;
053:
054: element_spec.setPackage(s);
055: Enumeration e = case_label_list.v.elements();
056:
057: for (; e.hasMoreElements();) {
058: IdlSymbol sym = (IdlSymbol) e.nextElement();
059: if (sym != null)
060: sym.setPackage(s);
061: }
062:
063: if (type_spec != null)
064: type_spec.setPackage(s);
065: }
066:
067: /**
068: * pass a reference to the containing union through
069: * to the case elements, which pass it on
070: */
071:
072: public void setUnion(UnionType ut) {
073: element_spec.setUnion(ut);
074: }
075:
076: public void setEnclosingSymbol(IdlSymbol s) {
077: if (enclosing_symbol != null && enclosing_symbol != s)
078: throw new RuntimeException(
079: "Compiler Error: trying to reassign container for "
080: + name);
081:
082: enclosing_symbol = s;
083: element_spec.setEnclosingSymbol(s);
084: }
085:
086: public void setTypeSpec(TypeSpec s) {
087: // and enum type name if necessary
088: type_spec = s;
089: type_spec.setPackage(pack_name);
090: }
091:
092: private String enumTypeName() {
093: // and enum type name if necessary
094: if (type_spec.type_spec instanceof ConstrTypeSpec) {
095: return ((ConstrTypeSpec) type_spec.type_spec).full_name();
096: } else if (type_spec.type_spec instanceof ScopedName) {
097: TypeSpec ts = ((ScopedName) type_spec.type_spec)
098: .resolvedTypeSpec();
099:
100: while (ts instanceof ScopedName
101: || ts instanceof AliasTypeSpec) {
102: if (ts instanceof ScopedName)
103: ts = ((ScopedName) ts).resolvedTypeSpec();
104: if (ts instanceof AliasTypeSpec)
105: ts = ((AliasTypeSpec) ts).originalType();
106: }
107:
108: if (ts instanceof ConstrTypeSpec)
109: return ((ConstrTypeSpec) ts).c_type_spec.full_name();
110: }
111: // all else
112: return null;
113: }
114:
115: public void parse() {
116: element_spec.parse();
117:
118: labels = new IdlSymbol[case_label_list.v.size()];
119: int label_idx = 0;
120:
121: for (Enumeration e = case_label_list.v.elements(); e
122: .hasMoreElements();) {
123: IdlSymbol sym = (IdlSymbol) e.nextElement();
124: // remember label names
125: labels[label_idx++] = sym;
126:
127: // check that no literals are used in case labels when
128: // the switch type spec doesn't allow it (i.e. bool, int, char)
129:
130: TypeSpec ts = type_spec.typeSpec();
131:
132: if (sym != null) {
133: // null means "default" label in union
134: if (((ConstExpr) sym).or_expr.xor_expr.and_expr.shift_expr.add_expr.mult_expr.unary_expr.primary_expr.symbol instanceof Literal) {
135: Literal literal = (Literal) ((ConstExpr) sym).or_expr.xor_expr.and_expr.shift_expr.add_expr.mult_expr.unary_expr.primary_expr.symbol;
136:
137: if (ts instanceof ScopedName) {
138: while (ts instanceof ScopedName) {
139: ts = ((ScopedName) type_spec.typeSpec())
140: .resolvedTypeSpec();
141: if (ts instanceof AliasTypeSpec)
142: ts = ((AliasTypeSpec) ts)
143: .originalType();
144: }
145: }
146:
147: /* make sure that case label and discriminator
148: value are compatible */
149:
150: if ((!(ts instanceof BooleanType
151: || ts instanceof IntType
152: || ts instanceof CharType || (ts instanceof BaseType && ((BaseType) ts)
153: .isSwitchType())))
154: || (ts instanceof BooleanType && !(literal.string
155: .equals("true") || literal.string
156: .equals("false")))
157: || (ts instanceof CharType && !literal.string
158: .startsWith("'"))) {
159: parser.error("Illegal case label <"
160: + literal.string + "> for switch type "
161: + type_spec.typeName(), token);
162: return; // abort parsing the case here (we'd get other errors)
163: }
164:
165: if (ts instanceof IntType) {
166: try {
167: Integer.parseInt(literal.string);
168: } catch (NumberFormatException ne) {
169: parser.error("Illegal case label <"
170: + literal.string
171: + "> for integral switch type "
172: + type_spec.typeName(), token);
173: return;
174: }
175: }
176: }
177: }
178:
179: // if the switch type for the union we're part of
180: // is an enumeration type, the enum type name has
181: // been set.
182:
183: if (enumTypeName() == null) {
184: // no enum
185: if (sym != null) {
186: // null means "default" label in union
187: sym.parse();
188: }
189: } else {
190: // case label const expressions refer to enum values
191: if (sym != null) {
192: // now, if this is not the default case label...
193: // get the case label (a const expr) as a scoped name
194: ScopedName sn = (ScopedName) ((ConstExpr) sym).or_expr.xor_expr.and_expr.shift_expr.add_expr.mult_expr.unary_expr.primary_expr.symbol;
195:
196: // replace the original case label by a new, fully
197: // scoped name for the enum type value
198:
199: int idx = case_label_list.v.indexOf(sym);
200: sym = new ScopedName(new_num());
201: ((ScopedName) sym).setId(sn.typeName);
202: sym.setPackage(pack_name);
203: sym.parse();
204: case_label_list.v.setElementAt(sym, idx);
205: }
206: }
207: } // for
208:
209: }
210:
211: IdlSymbol[] getLabels() {
212: if (labels == null) {
213: throw new RuntimeException("Case labels not initialized!");
214: }
215: return labels;
216: }
217:
218: public void print(java.io.PrintWriter ps) {
219: element_spec.print(ps);
220: }
221: }
|