KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > bsh > BSHArrayInitializer


1 /*****************************************************************************
2  * *
3  * This file is part of the BeanShell Java Scripting distribution. *
4  * Documentation and updates may be found at http://www.beanshell.org/ *
5  * *
6  * Sun Public License Notice: *
7  * *
8  * The contents of this file are subject to the Sun Public License Version *
9  * 1.0 (the "License"); you may not use this file except in compliance with *
10  * the License. A copy of the License is available at http://www.sun.com *
11  * *
12  * The Original Code is BeanShell. The Initial Developer of the Original *
13  * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
14  * (C) 2000. All Rights Reserved. *
15  * *
16  * GNU Public License Notice: *
17  * *
18  * Alternatively, the contents of this file may be used under the terms of *
19  * the GNU Lesser General Public License (the "LGPL"), in which case the *
20  * provisions of LGPL are applicable instead of those above. If you wish to *
21  * allow use of your version of this file only under the terms of the LGPL *
22  * and not to allow others to use your version of this file under the SPL, *
23  * indicate your decision by deleting the provisions above and replace *
24  * them with the notice and other provisions required by the LGPL. If you *
25  * do not delete the provisions above, a recipient may use your version of *
26  * this file under either the SPL or the LGPL. *
27  * *
28  * Patrick Niemeyer (pat@pat.net) *
29  * Author of Learning Java, O'Reilly & Associates *
30  * http://www.pat.net/~pat/ *
31  * *
32  *****************************************************************************/

33
34
35 package bsh;
36
37 import java.lang.reflect.Array JavaDoc;
38
39 class BSHArrayInitializer extends SimpleNode
40 {
41     BSHArrayInitializer(int id) { super(id); }
42
43     public Object JavaDoc eval( CallStack callstack, Interpreter interpreter )
44         throws EvalError
45     {
46         throw new EvalError( "Array initializer has no base type.",
47             this, callstack );
48     }
49
50     /**
51         Construct the array from the initializer syntax.
52
53         @param baseType the base class type of the array (no dimensionality)
54         @param dimensions the top number of dimensions of the array
55             e.g. 2 for a String [][];
56     */

57     public Object JavaDoc eval( Class JavaDoc baseType, int dimensions,
58                         CallStack callstack, Interpreter interpreter )
59         throws EvalError
60     {
61         int numInitializers = jjtGetNumChildren();
62
63         // allocate the array to store the initializers
64
int [] dima = new int [dimensions]; // description of the array
65
// The other dimensions default to zero and are assigned when
66
// the values are set.
67
dima[0] = numInitializers;
68         Object JavaDoc initializers = Array.newInstance( baseType, dima );
69
70         // Evaluate the initializers
71
for (int i = 0; i < numInitializers; i++)
72         {
73             SimpleNode node = (SimpleNode)jjtGetChild(i);
74             Object JavaDoc currentInitializer;
75             if ( node instanceof BSHArrayInitializer ) {
76                 if ( dimensions < 2 )
77                     throw new EvalError(
78                         "Invalid Location for Intializer, position: "+i,
79                         this, callstack );
80                 currentInitializer =
81                     ((BSHArrayInitializer)node).eval(
82                         baseType, dimensions-1, callstack, interpreter);
83             } else
84                 currentInitializer = node.eval( callstack, interpreter);
85
86             if ( currentInitializer == Primitive.VOID )
87                 throw new EvalError(
88                     "Void in array initializer, position"+i, this, callstack );
89
90             // Determine if any conversion is necessary on the initializers.
91
//
92
// Quick test to see if conversions apply:
93
// If the dimensionality of the array is 1 then the elements of
94
// the initializer can be primitives or boxable types. If it is
95
// greater then the values must be array (object) types and there
96
// are currently no conversions that we do on those.
97
// If we have conversions on those in the future then we need to
98
// get the real base type here instead of the dimensionless one.
99
Object JavaDoc value = currentInitializer;
100             if ( dimensions == 1 )
101             {
102                 // We do a bsh cast here. strictJava should be able to affect
103
// the cast there when we tighten control
104
try {
105                     value = Types.castObject(
106                         currentInitializer, baseType, Types.CAST );
107                 } catch ( UtilEvalError e ) {
108                     throw e.toEvalError(
109                         "Error in array initializer", this, callstack );
110                 }
111                 // unwrap any primitive, map voids to null, etc.
112
value = Primitive.unwrap( value );
113             }
114
115                 // store the value in the array
116
try {
117                 Array.set(initializers, i, value);
118             } catch( IllegalArgumentException JavaDoc e ) {
119                 Interpreter.debug("illegal arg"+e);
120                 throwTypeError( baseType, currentInitializer, i, callstack );
121             } catch( ArrayStoreException JavaDoc e ) { // I think this can happen
122
Interpreter.debug("arraystore"+e);
123                 throwTypeError( baseType, currentInitializer, i, callstack );
124             }
125         }
126
127         return initializers;
128     }
129
130     private void throwTypeError(
131         Class JavaDoc baseType, Object JavaDoc initializer, int argNum, CallStack callstack )
132         throws EvalError
133     {
134         String JavaDoc rhsType;
135         if (initializer instanceof Primitive)
136             rhsType =
137                 ((Primitive)initializer).getType().getName();
138         else
139             rhsType = Reflect.normalizeClassName(
140                 initializer.getClass());
141
142         throw new EvalError ( "Incompatible type: " + rhsType
143             +" in initializer of array type: "+ baseType
144             +" at position: "+argNum, this, callstack );
145     }
146
147 }
148
Popular Tags