KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > idl > Case


1 package org.jacorb.idl;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import java.util.Enumeration JavaDoc;
24
25 /**
26  * @author Gerald Brose
27  * @version $Id: Case.java,v 1.16 2004/05/06 12:39:58 nicolas Exp $
28  */

29
30 class Case
31     extends IdlSymbol
32 {
33
34     /** the labels for this case */
35     public SymbolList case_label_list = null;
36
37     /** only set after parsing */
38     private IdlSymbol[] labels;
39
40     /** this case's element's type's spec */
41     public ElementSpec element_spec = null;
42
43     /** the switch type's spec */
44     TypeSpec type_spec = null;
45
46     public Case( int num )
47     {
48         super( num );
49     }
50
51     public void setPackage( String JavaDoc s )
52     {
53         s = parser.pack_replace( s );
54         if( pack_name.length() > 0 )
55             pack_name = s + "." + pack_name;
56         else
57             pack_name = s;
58
59         element_spec.setPackage( s );
60         Enumeration JavaDoc e = case_label_list.v.elements();
61
62         for( ; e.hasMoreElements(); )
63         {
64             IdlSymbol sym = (IdlSymbol)e.nextElement();
65             if( sym != null )
66                 sym.setPackage( s );
67         }
68
69         if( type_spec != null )
70             type_spec.setPackage( s );
71     }
72
73     /**
74      * pass a reference to the containing union through
75      * to the case elements, which pass it on
76      */

77
78     public void setUnion( UnionType ut )
79     {
80         element_spec.setUnion( ut );
81     }
82
83     public void setEnclosingSymbol( IdlSymbol s )
84     {
85         if( enclosing_symbol != null && enclosing_symbol != s )
86             throw new RuntimeException JavaDoc( "Compiler Error: trying to reassign container for " + name );
87
88         enclosing_symbol = s;
89         element_spec.setEnclosingSymbol( s );
90     }
91
92
93     public void setTypeSpec( TypeSpec s )
94     {
95         // and enum type name if necessary
96
type_spec = s;
97         type_spec.setPackage( pack_name );
98     }
99
100     private String JavaDoc enumTypeName()
101     {
102         // and enum type name if necessary
103
if( type_spec.type_spec instanceof ConstrTypeSpec )
104         {
105             return ( (ConstrTypeSpec)type_spec.type_spec ).full_name();
106         }
107         else if( type_spec.type_spec instanceof ScopedName )
108         {
109             TypeSpec ts = ( (ScopedName)type_spec.type_spec ).resolvedTypeSpec();
110
111             while( ts instanceof ScopedName || ts instanceof AliasTypeSpec )
112             {
113                 if( ts instanceof ScopedName )
114                     ts = ( (ScopedName)ts ).resolvedTypeSpec();
115                 if( ts instanceof AliasTypeSpec )
116                     ts = ( (AliasTypeSpec)ts ).originalType();
117             }
118
119             if( ts instanceof ConstrTypeSpec )
120                 return ( (ConstrTypeSpec)ts ).c_type_spec.full_name();
121         }
122         // all else
123
return null;
124     }
125
126
127     public void parse()
128     {
129         element_spec.parse();
130
131         labels = new IdlSymbol[ case_label_list.v.size() ];
132         int label_idx = 0;
133
134         for( Enumeration JavaDoc e = case_label_list.v.elements();
135              e.hasMoreElements(); )
136         {
137             IdlSymbol sym = (IdlSymbol)e.nextElement();
138             // remember label names
139
labels[ label_idx++ ] = sym;
140
141             // check that no literals are used in case labels when
142
// the switch type spec doesn't allow it (i.e. bool, int, char)
143

144             TypeSpec ts = type_spec.typeSpec();
145
146             if( sym != null )
147             {
148                 // null means "default" label in union
149
if( ( (ConstExpr)sym ).or_expr.xor_expr.and_expr.shift_expr.add_expr.
150                         mult_expr.unary_expr.primary_expr.symbol instanceof Literal )
151                 {
152                     Literal literal =
153                             (Literal)( (ConstExpr)sym ).or_expr.xor_expr.and_expr.shift_expr.add_expr.mult_expr.unary_expr.primary_expr.symbol;
154
155                     if( ts instanceof ScopedName )
156                     {
157                         while( ts instanceof ScopedName )
158                         {
159                             ts = ( (ScopedName)type_spec.typeSpec() ).resolvedTypeSpec();
160                             if( ts instanceof AliasTypeSpec )
161                                 ts = ( (AliasTypeSpec)ts ).originalType();
162                         }
163                     }
164
165                     /* make sure that case label and discriminator
166                        value are compatible */

167
168                     if(
169                             ( !( ts instanceof BooleanType ||
170                             ts instanceof IntType ||
171                             ts instanceof CharType ||
172                             ( ts instanceof BaseType && ( (BaseType)ts ).isSwitchType() )
173                             )
174                             )
175                             ||
176                             ( ts instanceof BooleanType &&
177                             !( literal.string.equals( "true" ) || literal.string.equals( "false" ) ) )
178                             ||
179                             ( ts instanceof CharType &&
180                             !literal.string.startsWith( "'" ) )
181                     )
182                     {
183                         parser.error( "Illegal case label <" + literal.string +
184                                 "> for switch type " + type_spec.typeName(), token );
185                         return; // abort parsing the case here (we'd get other errors)
186
}
187
188                     if( ts instanceof IntType )
189                     {
190                         try
191                         {
192                             int testme = Integer.parseInt( literal.string );
193                         }
194                         catch( NumberFormatException JavaDoc ne )
195                         {
196                             parser.error( "Illegal case label <" + literal.string +
197                                     "> for integral switch type " + type_spec.typeName(), token );
198                             return;
199                         }
200                     }
201                 }
202             }
203
204             // if the switch type for the union we're part of
205
// is an enumeration type, the enum type name has
206
// been set.
207

208             if( enumTypeName() == null )
209             {
210                 // no enum
211
if( sym != null )
212                 {
213                     // null means "default" label in union
214
sym.parse();
215                 }
216             }
217             else
218             {
219                 // case label const expressions refer to enum values
220
if( sym != null )
221                 {
222                     // now, if this is not the default case label...
223
// get the case label (a const expr) as a scoped name
224
ScopedName sn =
225                             (ScopedName)( (ConstExpr)sym ).or_expr.xor_expr.and_expr.
226                             shift_expr.add_expr.mult_expr.unary_expr.primary_expr.symbol;
227
228                     // replace the original case label by a new, fully
229
// scoped name for the enum type value
230

231                     int idx = case_label_list.v.indexOf( sym );
232                     sym = new ScopedName( new_num() );
233                     ( (ScopedName)sym ).setId( sn.typeName );
234                     sym.setPackage( pack_name );
235                     sym.parse();
236                     case_label_list.v.setElementAt( sym, idx );
237                 }
238             }
239         } // for
240

241     }
242
243     IdlSymbol[] getLabels()
244     {
245         if (labels == null)
246         {
247             throw new RuntimeException JavaDoc ("Case labels not initialized!" );
248         }
249         return labels;
250     }
251
252
253     public void print( java.io.PrintWriter JavaDoc ps )
254     {
255         element_spec.print( ps );
256     }
257
258
259 }
260
Popular Tags