PageRenderTime 123ms CodeModel.GetById 116ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre5/bsh/BSHLHSPrimarySuffix.java

#
Java | 156 lines | 94 code | 19 blank | 43 comment | 9 complexity | 0d7a4130b44fbea1425edb25a93e9820 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
 35/*
 36	Warning: this is a hack... should be unified with BSHPrimarySuffix
 37*/
 38package bsh;
 39
 40import java.util.Hashtable;
 41import java.lang.reflect.InvocationTargetException;
 42
 43class BSHLHSPrimarySuffix extends SimpleNode
 44{
 45	public static final int
 46		INDEX = 1,
 47		NAME = 2,
 48		PROPERTY = 3;
 49
 50	public int operation;	// field access or index
 51	Object index;			// the index value if any
 52	/*
 53		If this is a simple field access field is the field
 54		If we're hopscotching a method to a field, method is the
 55		method name and field is the field of the resulting object
 56	*/
 57	public String field;
 58	public String method;
 59
 60	BSHLHSPrimarySuffix(int id) { super(id); }
 61
 62	public LHS doLHSSuffix(
 63		Object obj, CallStack callstack, Interpreter interpreter) 
 64		throws EvalError
 65	{
 66		try
 67		{
 68			switch(operation)
 69			{
 70				case INDEX:
 71					return doIndex(obj, callstack, interpreter);
 72
 73				case NAME:
 74					return doName(obj, callstack, interpreter);
 75
 76				case PROPERTY:
 77					return doProperty(obj, callstack, interpreter);
 78
 79				default:
 80					throw new InterpreterError("LHS suffix");
 81			}
 82		}
 83		catch(ReflectError e)
 84		{
 85			throw new EvalError("reflection error: " + e, this);
 86		}
 87		catch(InvocationTargetException e)
 88		{
 89			throw new TargetError(
 90				"target exception", e.getTargetException(), this, true);
 91		}
 92	}
 93
 94	private LHS doName(
 95		Object obj, CallStack callstack, Interpreter interpreter) 
 96		throws EvalError, ReflectError, InvocationTargetException 
 97	{
 98		if (jjtGetNumChildren() == 0)
 99			// simple field access
100			return Reflect.getLHSObjectField(obj, field);
101		else {
102			// intermediate method invocation, and field access
103			Object[] oa = ((BSHArguments)jjtGetChild(0)).getArguments(
104				callstack, interpreter);
105			try {
106				obj = Reflect.invokeObjectMethod(interpreter, obj, method, oa, this);
107			} catch ( EvalError ee ) {
108				// catch and re-throw to get line number right
109				throw new EvalError( ee.getMessage(), this );
110			}
111			return Reflect.getLHSObjectField(obj, field);
112		}
113	}
114
115	private LHS doIndex(
116		Object obj, CallStack callstack, Interpreter interpreter) 
117		throws EvalError, ReflectError
118	{
119		if(!obj.getClass().isArray())
120			throw new EvalError("Not an array", this);
121
122		int index;
123		try
124		{
125			Primitive val = (Primitive)(((SimpleNode)jjtGetChild(0)).eval(
126				callstack, interpreter));
127			index = val.intValue();
128		}
129		catch(Exception e)
130		{
131			throw new EvalError("You can only index arrays by integer types", this);
132		}
133
134		return new LHS(obj, index);
135	}
136	private LHS doProperty(
137		Object obj, CallStack callstack, Interpreter interpreter) 
138		throws EvalError, ReflectError
139	{
140		if(obj == Primitive.VOID)
141			throw new EvalError("Attempt to access property on a void type", this);
142
143		else if(obj instanceof Primitive)
144			throw new EvalError("Attempt to access property on a primitive", this);
145
146		Object value = ((SimpleNode)jjtGetChild(0)).eval(
147			callstack, interpreter);
148
149		if(!(value instanceof String))
150			throw new EvalError("Property expression must be a String or identifier.", this);
151
152		Interpreter.debug("LHS property access: ");
153		return new LHS(obj, (String)value);
154	}
155}
156