/** Coerce parameter values to parameter type and unwrap primitives. * @param param the parameter value * @param type the parameter type * @return unwrapped coerced value * @throws Throwable on cast errors */ protected Object coerceToType(Object param, Class<?> type) throws Throwable { if (type != Object.class) param = Types.castObject(param, type, Types.CAST); return Primitive.unwrap(param); }
/** Test if a type can be converted to another type via BeanShell extended syntax rules (a superset of Java conversion rules). */ public static boolean isBshAssignable( Class toType, Class fromType ) { try { return castObject( toType, fromType, null/*fromValue*/, ASSIGNMENT, true/*checkOnly*/ ) == VALID_CAST; } catch ( UtilEvalError e ) { // This should not happen with checkOnly true throw new InterpreterError("err in cast check: "+e); } }
/** Test if a type can be converted to another type via BeanShell extended syntax rules (a superset of Java conversion rules). */ static boolean isBshAssignable( Class toType, Class fromType ) { try { return castObject( toType, fromType, null/*fromValue*/, ASSIGNMENT, true/*checkOnly*/ ) == VALID_CAST; } catch ( UtilEvalError e ) { // This should not happen with checkOnly true throw new InterpreterError("err in cast check: "+e, e); } }
/** Attempt to cast an object instance to a new type if possible via BeanShell extended syntax rules. These rules are always a superset of Java conversion rules. If you wish to impose context sensitive conversion rules then you must test before calling this method. <p/> This method can handle fromValue Primitive types (representing primitive casts) as well as fromValue object casts requiring interface generation, etc. @param toType the class type of the cast result, which may include primitive types, e.g. Byte.TYPE @param fromValue an Object or bsh.Primitive primitive value (including Primitive.NULL or Primitive.VOID ) @see #isBshAssignable( Class, Class ) */ public static Object castObject( Object fromValue, Class toType, int operation ) throws UtilEvalError { if ( fromValue == null ) throw new InterpreterError("null fromValue"); Class fromType = fromValue instanceof Primitive ? ((Primitive)fromValue).getType() : fromValue.getClass(); return castObject( toType, fromType, fromValue, operation, false/*checkonly*/ ); }
tmpArgs[i] = Types.castObject(args[i]/*rhs*/, types[i]/*lhsType*/, Types.ASSIGNMENT); Object varArgs = Array.newInstance(varType, args.length - fixedArgLen); for (int i = fixedArgLen, j = 0; i < args.length; i++, j++) { Array.set(varArgs, j, Primitive.unwrap(Types.castObject(args[i]/*rhs*/, varType/*lhsType*/, Types.ASSIGNMENT)));
Types.castObject(fromValue, Object.class, Types.CAST))); else if ( Types.isJavaAssignable(toType, LinkedList.class) ) Types.castObject(fromValue, Object.class, Types.CAST))); } else if ( Types.isJavaAssignable(toType, ArrayDeque.class) ) Types.castObject(fromValue, Object.class, Types.CAST))); else if ( Types.isJavaAssignable(toType, LinkedHashSet.class) ) Types.castObject(fromValue, Object.class, Types.CAST)));
try { value = Primitive.unwrap( Types.castObject(value, toType, Types.CAST)); } catch (UtilEvalError e) { /* ignore cast errors */ } if ( Byte.TYPE == toType )
@Override public Object visit(BSHCastExpression node) { NameSpace namespace = callstack.top(); Class toType = getType(((BSHType)node.jjtGetChild(0))); SimpleNode expression = (SimpleNode)node.jjtGetChild(1); // evaluate the expression Object fromValue = expression.accept(this); Class fromType = fromValue.getClass(); // TODO: need to add isJavaCastable() test for strictJava // (as opposed to isJavaAssignable()) try { return Types.castObject( fromValue, toType, Types.CAST ); } catch ( UtilEvalError e ) { throw e.toEvalError( node, callstack ); } }
rhs = Types.castObject(rhs, List.class, Types.CAST); if ( lhs instanceof List && rhs instanceof List ) return BshArray.concat(
return castObject( toType, fromType, fromValue, operation, false/*checkonly*/ );
/** Set the value of the typed variable. @param value should be an object or wrapped bsh Primitive type. if value is null the appropriate default value will be set for the type: e.g. false for boolean, zero for integer types. */ public void setValue( Object value, int context ) throws UtilEvalError { // check this.value if ( hasModifier("final") && this.value != null ) throw new UtilEvalError ("Final variable, can't re-assign."); if ( value == null ) value = Primitive.getDefaultValue( type ); if ( lhs != null ) { lhs.assign( value, false/*strictjava*/ ); return; } // TODO: should add isJavaCastable() test for strictJava // (as opposed to isJavaAssignable()) if ( type != null ) value = Types.castObject( value, type, context == DECLARATION ? Types.CAST : Types.ASSIGNMENT ); this.value= value; }
/** */ static int getIndexAux(Object obj, int idx, CallStack callstack, Interpreter interpreter, SimpleNode callerInfo ) throws EvalError { int index; try { Object indexVal = ((SimpleNode) callerInfo.jjtGetChild(idx)).eval( callstack, interpreter ); if ( !(indexVal instanceof Primitive) ) indexVal = Types.castObject( indexVal, Integer.TYPE, Types.ASSIGNMENT ); index = ((Primitive) indexVal).intValue(); } catch( UtilEvalError e ) { Interpreter.debug("doIndex: "+e); throw e.toEvalError( "Arrays may only be indexed by integer types.", callerInfo, callstack ); } return index; }
/** Set the value of the typed variable. @param value should be an object or wrapped bsh Primitive type. if value is null the appropriate default value will be set for the type: e.g. false for boolean, zero for integer types. */ public void setValue( Object value, int context ) throws UtilEvalError { // prevent final variable re-assign if (hasModifier("final")) { if (this.value != null) throw new UtilEvalError("Cannot re-assign final variable "+name+"."); if (value == null) return; } // TODO: should add isJavaCastable() test for strictJava // (as opposed to isJavaAssignable()) if ( type != null && type != Object.class && value != null ) { this.value = Types.castObject( value, type, context == DECLARATION ? Types.CAST : Types.ASSIGNMENT ); value = this.value; } this.value = value; if ( this.value == null && context != DECLARATION ) this.value = Primitive.getDefaultValue( type ); if ( lhs != null ) this.value = lhs.assign( this.value, false/*strictjava*/ ); }
/** @return the result of the cast. */ public Object eval( CallStack callstack, Interpreter interpreter ) throws EvalError { Class toType = ((BSHType)jjtGetChild(0)).getType( callstack, interpreter ); SimpleNode expression = (SimpleNode)jjtGetChild(1); // evaluate the expression Object fromValue = expression.eval(callstack, interpreter); // TODO: need to add isJavaCastable() test for strictJava // (as opposed to isJavaAssignable()) try { return Types.castObject( fromValue, toType, Types.CAST ); } catch ( UtilEvalError e ) { throw e.toEvalError( this, callstack ); } }
/** */ public static int getIndexAux( Object obj, BshEvaluatingVisitor visitor, SimpleNode callerInfo ) throws EvalError { if ( !obj.getClass().isArray() ) throw new EvalError("Not an array", callerInfo, visitor.getCallstack() ); int index; try { Object indexVal = ((SimpleNode)callerInfo.jjtGetChild(0)).accept(visitor); if ( !(indexVal instanceof Primitive) ) indexVal = Types.castObject( indexVal, Integer.TYPE, Types.ASSIGNMENT); index = ((Primitive)indexVal).intValue(); } catch( UtilEvalError e ) { Interpreter.debug("doIndex: "+e); throw e.toEvalError( "Arrays may only be indexed by integer types.", callerInfo, visitor.getCallstack() ); } return index; }
val = Types.castObject( val, Types.arrayElementType(object.getClass()), Types.ASSIGNMENT);
value = Types.castObject( currentInitializer, baseType, Types.CAST ); } catch ( UtilEvalError e ) {
thrown = (Throwable)Types.castObject( thrown/*rsh*/, fp.type/*lhsType*/, Types.ASSIGNMENT ); } catch( UtilEvalError e ) {
value = Types.castObject( currentInitializer, baseType, Types.CAST ); } catch ( UtilEvalError e ) { || Types.isJavaAssignable(Map.class, originalBaseType) || Types.isJavaAssignable(Entry.class, originalBaseType) ) try { initializers = Types.castObject(initializers, originalBaseType, Types.CAST); } catch (UtilEvalError e) { throw new EvalError(e.getMessage(), this, callstack, e);
argValues[i] = Types.castObject( argValues[i], paramTypes[i], Types.ASSIGNMENT ); ret = Types.castObject( ret, returnType, Types.ASSIGNMENT ); } catch( UtilEvalError e )