PageRenderTime 252ms CodeModel.GetById 229ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 1ms

/jEdit/tags/jedit-4-3-pre5/bsh/BSHArrayInitializer.java

#
Java | 161 lines | 82 code | 18 blank | 61 comment | 8 complexity | 95e1e5a59940c20e939d172b88b6020b MD5 | raw file
  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 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 = 
 69			Array.newInstance( baseType, dima );
 70
 71		// Evaluate the initializers
 72        for (int i = 0; i < numInitializers; i++)
 73        {
 74			SimpleNode node = (SimpleNode)jjtGetChild(i);
 75            Object currentInitializer;
 76			if ( node instanceof BSHArrayInitializer ) {
 77				if ( dimensions < 2 )
 78					throw new EvalError(
 79						"Invalid Location for Intializer, position: "+i, 
 80						this, callstack );
 81            	currentInitializer = 
 82					((BSHArrayInitializer)node).eval( 
 83						baseType, dimensions-1, callstack, interpreter);
 84			} else
 85            	currentInitializer = node.eval( callstack, interpreter);
 86
 87			if ( currentInitializer == Primitive.VOID )
 88				throw new EvalError(
 89					"Void in array initializer, position"+i, this, callstack );
 90
 91			// unwrap primitive to the wrapper type
 92			Object value;
 93			if ( currentInitializer instanceof Primitive )
 94			{
 95				Primitive primValue = (Primitive)currentInitializer;
 96				/*
 97				TODO:
 98					to get cast and boxing working e.g.
 99					e.g. Byte [] ia = { 1, 2 }
100
101					If the baseType is a wrapper type then we need to get the 
102					primitive TYPE class for the base type here in order for 
103					the cast to allow it... Then boxing will happen naturally in
104					the Array.set().
105					e.g. Integer [] ia = { 1, 2 }
106				*/
107				/*
108				if ( Primitive.isWrapperType( baseType ) )
109					baseType = Primitive.getPrimitiveTypeForType( baseType );
110				*/
111
112				// don't deal with object types here... unless above
113				if ( baseType.isPrimitive() )
114					try {
115						primValue = primValue.castToType( 
116							baseType, Types.CAST );
117					} catch ( UtilEvalError e ) {
118					e.printStackTrace();
119						Interpreter.debug("error:"+e);
120						throwTypeError( baseType, primValue, i, callstack );
121					}
122
123				value = primValue.getValue();
124			}
125			else
126				value = currentInitializer;
127
128			// store the value in the array
129            try {
130				Array.set(initializers, i, value);
131
132            } catch( IllegalArgumentException e ) {
133				Interpreter.debug("illegal arg"+e);
134				throwTypeError( baseType, currentInitializer, i, callstack );
135            } catch( ArrayStoreException e ) { // I think this can happen
136				Interpreter.debug("arraystore"+e);
137				throwTypeError( baseType, currentInitializer, i, callstack );
138            }
139        }
140
141        return initializers;
142    }
143
144	private void throwTypeError( 
145		Class baseType, Object initializer, int argNum, CallStack callstack ) 
146		throws EvalError
147	{
148		String rhsType;
149		if (initializer instanceof Primitive)
150			rhsType = 
151				((Primitive)initializer).getType().getName();
152		else
153			rhsType = Reflect.normalizeClassName(
154				initializer.getClass());
155
156		throw new EvalError ( "Incompatible type: " + rhsType 
157			+" in initializer of array type: "+ baseType
158			+" at position: "+argNum, this, callstack );
159	}
160
161}