/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/bsh/BSHArrayInitializer.java
Java | 147 lines | 76 code | 15 blank | 56 comment | 8 complexity | 3830f66068abcb7235d39558de477166 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
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
35package org.gjt.sp.jedit.bsh;
36
37import java.lang.reflect.Array;
38
39class BSHArrayInitializer extends SimpleNode
40{
41 BSHArrayInitializer(int id) { super(id); }
42
43 public Object 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 eval( Class 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 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 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 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 e ) {
119 Interpreter.debug("illegal arg"+e);
120 throwTypeError( baseType, currentInitializer, i, callstack );
121 } catch( ArrayStoreException 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 baseType, Object initializer, int argNum, CallStack callstack )
132 throws EvalError
133 {
134 String 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}