1 33 34 package bsh; 35 36 43 class Types 44 { 45 51 static final int CAST=0, ASSIGNMENT=1; 52 53 static final int 54 JAVA_BASE_ASSIGNABLE = 1, 55 JAVA_BOX_TYPES_ASSIGABLE = 2, 56 JAVA_VARARGS_ASSIGNABLE = 3, 57 BSH_ASSIGNABLE = 4; 58 59 static final int 60 FIRST_ROUND_ASSIGNABLE = JAVA_BASE_ASSIGNABLE, 61 LAST_ROUND_ASSIGNABLE = BSH_ASSIGNABLE; 62 63 69 static Primitive VALID_CAST = new Primitive(1); 70 static Primitive INVALID_CAST = new Primitive(-1); 71 72 75 public static Class [] getTypes( Object [] args ) 76 { 77 if ( args == null ) 78 return new Class [0]; 79 80 Class [] types = new Class [ args.length ]; 81 82 for( int i=0; i<args.length; i++ ) 83 { 84 if ( args[i] == null ) 85 types[i] = null; 86 else 87 if ( args[i] instanceof Primitive ) 88 types[i] = ((Primitive)args[i]).getType(); 89 else 90 types[i] = args[i].getClass(); 91 } 92 93 return types; 94 } 95 96 102 103 static boolean isSignatureAssignable( Class [] from, Class [] to, int round ) 104 { 105 if ( round != JAVA_VARARGS_ASSIGNABLE && from.length != to.length ) 106 return false; 107 108 switch ( round ) 109 { 110 case JAVA_BASE_ASSIGNABLE: 111 for( int i=0; i<from.length; i++ ) 112 if ( !isJavaBaseAssignable( to[i], from[i] ) ) 113 return false; 114 return true; 115 case JAVA_BOX_TYPES_ASSIGABLE: 116 for( int i=0; i<from.length; i++ ) 117 if ( !isJavaBoxTypesAssignable( to[i], from[i] ) ) 118 return false; 119 return true; 120 case JAVA_VARARGS_ASSIGNABLE: 121 return isSignatureVarargsAssignable( from, to ); 122 case BSH_ASSIGNABLE: 123 for( int i=0; i<from.length; i++ ) 124 if ( !isBshAssignable( to[i], from[i] ) ) 125 return false; 126 return true; 127 default: 128 throw new InterpreterError("bad case"); 129 } 130 } 131 132 private static boolean isSignatureVarargsAssignable( 133 Class [] from, Class [] to ) 134 { 135 return false; 136 } 137 138 163 static boolean isJavaAssignable( Class lhsType, Class rhsType ) { 164 return isJavaBaseAssignable( lhsType, rhsType ) 165 || isJavaBoxTypesAssignable( lhsType, rhsType ); 166 } 167 168 173 static boolean isJavaBaseAssignable( Class lhsType, Class rhsType ) 174 { 175 182 if ( lhsType == null ) 183 return false; 184 185 if ( rhsType == null ) 188 return !lhsType.isPrimitive(); 189 190 if ( lhsType.isPrimitive() && rhsType.isPrimitive() ) 191 { 192 if ( lhsType == rhsType ) 193 return true; 194 195 if ( (rhsType == Byte.TYPE) && 197 (lhsType == Short.TYPE || lhsType == Integer.TYPE 198 || lhsType == Long.TYPE || lhsType == Float.TYPE 199 || lhsType == Double.TYPE)) 200 return true; 201 202 if ( (rhsType == Short.TYPE) && 203 (lhsType == Integer.TYPE || lhsType == Long.TYPE || 204 lhsType == Float.TYPE || lhsType == Double.TYPE)) 205 return true; 206 207 if ((rhsType == Character.TYPE) && 208 (lhsType == Integer.TYPE || lhsType == Long.TYPE || 209 lhsType == Float.TYPE || lhsType == Double.TYPE)) 210 return true; 211 212 if ((rhsType == Integer.TYPE) && 213 (lhsType == Long.TYPE || lhsType == Float.TYPE || 214 lhsType == Double.TYPE)) 215 return true; 216 217 if ((rhsType == Long.TYPE) && 218 (lhsType == Float.TYPE || lhsType == Double.TYPE)) 219 return true; 220 221 if ((rhsType == Float.TYPE) && (lhsType == Double.TYPE)) 222 return true; 223 } 224 else 225 if ( lhsType.isAssignableFrom(rhsType) ) 226 return true; 227 228 return false; 229 } 230 231 234 static boolean isJavaBoxTypesAssignable( 235 Class lhsType, Class rhsType ) 236 { 237 if ( lhsType == null ) 239 return false; 240 241 if ( lhsType == Object .class ) 243 return true; 244 245 if ( lhsType == Number .class 247 && rhsType != Character.TYPE 248 && rhsType != Boolean.TYPE 249 ) 250 return true; 251 252 if ( Primitive.wrapperMap.get( lhsType ) == rhsType ) 257 return true; 258 259 return false; 260 } 261 262 266 static boolean isBshAssignable( Class toType, Class fromType ) 267 { 268 try { 269 return castObject( 270 toType, fromType, null, 271 ASSIGNMENT, true 272 ) == VALID_CAST; 273 } catch ( UtilEvalError e ) { 274 throw new InterpreterError("err in cast check: "+e); 276 } 277 } 278 279 298 public static Object castObject( 299 Object fromValue, Class toType, int operation ) 300 throws UtilEvalError 301 { 302 if ( fromValue == null ) 303 throw new InterpreterError("null fromValue"); 304 305 Class fromType = 306 fromValue instanceof Primitive ? 307 ((Primitive)fromValue).getType() 308 : fromValue.getClass(); 309 310 return castObject( 311 toType, fromType, fromValue, operation, false ); 312 } 313 314 371 375 private static Object castObject( 376 Class toType, Class fromType, Object fromValue, 377 int operation, boolean checkOnly ) 378 throws UtilEvalError 379 { 380 385 if ( checkOnly && fromValue != null ) 386 throw new InterpreterError("bad cast params 1"); 387 if ( !checkOnly && fromValue == null ) 388 throw new InterpreterError("bad cast params 2"); 389 if ( fromType == Primitive.class ) 390 throw new InterpreterError("bad from Type, need to unwrap"); 391 if ( fromValue == Primitive.NULL && fromType != null ) 392 throw new InterpreterError("inconsistent args 1"); 393 if ( fromValue == Primitive.VOID && fromType != Void.TYPE ) 394 throw new InterpreterError("inconsistent args 2"); 395 if ( toType == Void.TYPE ) 396 throw new InterpreterError("loose toType should be null"); 397 398 if ( toType == null || toType == fromType ) 400 return checkOnly ? VALID_CAST : 401 fromValue; 402 403 if ( toType.isPrimitive() ) 405 { 406 if ( fromType == Void.TYPE || fromType == null 407 || fromType.isPrimitive() ) 408 { 409 return Primitive.castPrimitive( 411 toType, fromType, (Primitive)fromValue, 412 checkOnly, operation ); 413 } else 414 { 415 if ( Primitive.isWrapperType( fromType ) ) 416 { 417 420 Class unboxedFromType = Primitive.unboxType( fromType ); 422 Primitive primFromValue; 423 if ( checkOnly ) 424 primFromValue = null; else 426 primFromValue = (Primitive)Primitive.wrap( 427 fromValue, unboxedFromType ); 428 429 return Primitive.castPrimitive( 430 toType, unboxedFromType, primFromValue, 431 checkOnly, operation ); 432 } else 433 { 434 if ( checkOnly ) 436 return INVALID_CAST; 437 else 438 throw castError( toType, fromType, operation ); 439 } 440 } 441 } 442 443 445 if ( fromType == Void.TYPE || fromType == null 447 || fromType.isPrimitive() ) 448 { 449 if ( Primitive.isWrapperType( toType ) 451 && fromType != Void.TYPE && fromType != null ) 452 { 453 return checkOnly ? VALID_CAST : 455 Primitive.castWrapper( 456 Primitive.unboxType(toType), 457 ((Primitive)fromValue).getValue() ); 458 } 459 460 if ( toType == Object .class 462 && fromType != Void.TYPE && fromType != null ) 463 { 464 return checkOnly ? VALID_CAST : 466 ((Primitive)fromValue).getValue(); 467 } 468 469 return Primitive.castPrimitive( 473 toType, fromType, (Primitive)fromValue, checkOnly, operation ); 474 } 475 476 if ( toType.isAssignableFrom( fromType ) ) 480 return checkOnly ? VALID_CAST : 481 fromValue; 482 483 if ( toType.isInterface() 486 && bsh.This.class.isAssignableFrom( fromType ) 487 && Capabilities.canGenerateInterfaces() 488 ) 489 return checkOnly ? VALID_CAST : 490 ((bsh.This)fromValue).getInterface( toType ); 491 492 if ( Primitive.isWrapperType( toType ) 495 && Primitive.isWrapperType( fromType ) 496 ) 497 return checkOnly ? VALID_CAST : 498 Primitive.castWrapper( toType, fromValue ); 499 500 if ( checkOnly ) 501 return INVALID_CAST; 502 else 503 throw castError( toType, fromType , operation ); 504 } 505 506 510 static UtilEvalError castError( 511 Class lhsType, Class rhsType, int operation ) 512 { 513 return castError( 514 Reflect.normalizeClassName(lhsType), 515 Reflect.normalizeClassName(rhsType), operation ); 516 } 517 518 static UtilEvalError castError( 519 String lhs, String rhs, int operation ) 520 { 521 if ( operation == ASSIGNMENT ) 522 return new UtilEvalError ( 523 "Can't assign " + rhs + " to "+ lhs ); 524 525 Exception cce = new ClassCastException ( 526 "Cannot cast " + rhs + " to " + lhs ); 527 return new UtilTargetError( cce ); 528 } 529 530 } 531 | Popular Tags |