PageRenderTime 33ms CodeModel.GetById 21ms app.highlight 10ms RepoModel.GetById 0ms app.codeStats 0ms

/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}