1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import java.util.ArrayList ; 14 15 import org.eclipse.jdt.core.compiler.CharOperation; 16 import org.eclipse.jdt.internal.compiler.ASTVisitor; 17 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 18 import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; 19 import org.eclipse.jdt.internal.compiler.codegen.CodeStream; 20 import org.eclipse.jdt.internal.compiler.flow.FlowContext; 21 import org.eclipse.jdt.internal.compiler.flow.FlowInfo; 22 import org.eclipse.jdt.internal.compiler.impl.Constant; 23 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; 24 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; 25 import org.eclipse.jdt.internal.compiler.lookup.Binding; 26 import org.eclipse.jdt.internal.compiler.lookup.BlockScope; 27 import org.eclipse.jdt.internal.compiler.lookup.ClassScope; 28 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; 29 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 30 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 31 import org.eclipse.jdt.internal.compiler.lookup.Scope; 32 import org.eclipse.jdt.internal.compiler.lookup.TagBits; 33 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 34 import org.eclipse.jdt.internal.compiler.lookup.TypeIds; 35 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; 36 import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding; 37 import org.eclipse.jdt.internal.compiler.problem.ShouldNotImplement; 38 import org.eclipse.jdt.internal.compiler.util.Messages; 39 40 public abstract class Expression extends Statement { 41 42 public Constant constant; 43 44 public int statementEnd = -1; 45 46 51 public int implicitConversion; 52 public TypeBinding resolvedType; 53 54 public static final boolean isConstantValueRepresentable(Constant constant, int constantTypeID, int targetTypeID) { 55 if (targetTypeID == constantTypeID) 58 return true; 59 switch (targetTypeID) { 60 case T_char : 61 switch (constantTypeID) { 62 case T_char : 63 return true; 64 case T_double : 65 return constant.doubleValue() == constant.charValue(); 66 case T_float : 67 return constant.floatValue() == constant.charValue(); 68 case T_int : 69 return constant.intValue() == constant.charValue(); 70 case T_short : 71 return constant.shortValue() == constant.charValue(); 72 case T_byte : 73 return constant.byteValue() == constant.charValue(); 74 case T_long : 75 return constant.longValue() == constant.charValue(); 76 default : 77 return false; } 79 80 case T_float : 81 switch (constantTypeID) { 82 case T_char : 83 return constant.charValue() == constant.floatValue(); 84 case T_double : 85 return constant.doubleValue() == constant.floatValue(); 86 case T_float : 87 return true; 88 case T_int : 89 return constant.intValue() == constant.floatValue(); 90 case T_short : 91 return constant.shortValue() == constant.floatValue(); 92 case T_byte : 93 return constant.byteValue() == constant.floatValue(); 94 case T_long : 95 return constant.longValue() == constant.floatValue(); 96 default : 97 return false; } 99 100 case T_double : 101 switch (constantTypeID) { 102 case T_char : 103 return constant.charValue() == constant.doubleValue(); 104 case T_double : 105 return true; 106 case T_float : 107 return constant.floatValue() == constant.doubleValue(); 108 case T_int : 109 return constant.intValue() == constant.doubleValue(); 110 case T_short : 111 return constant.shortValue() == constant.doubleValue(); 112 case T_byte : 113 return constant.byteValue() == constant.doubleValue(); 114 case T_long : 115 return constant.longValue() == constant.doubleValue(); 116 default : 117 return false; } 119 120 case T_byte : 121 switch (constantTypeID) { 122 case T_char : 123 return constant.charValue() == constant.byteValue(); 124 case T_double : 125 return constant.doubleValue() == constant.byteValue(); 126 case T_float : 127 return constant.floatValue() == constant.byteValue(); 128 case T_int : 129 return constant.intValue() == constant.byteValue(); 130 case T_short : 131 return constant.shortValue() == constant.byteValue(); 132 case T_byte : 133 return true; 134 case T_long : 135 return constant.longValue() == constant.byteValue(); 136 default : 137 return false; } 139 140 case T_short : 141 switch (constantTypeID) { 142 case T_char : 143 return constant.charValue() == constant.shortValue(); 144 case T_double : 145 return constant.doubleValue() == constant.shortValue(); 146 case T_float : 147 return constant.floatValue() == constant.shortValue(); 148 case T_int : 149 return constant.intValue() == constant.shortValue(); 150 case T_short : 151 return true; 152 case T_byte : 153 return constant.byteValue() == constant.shortValue(); 154 case T_long : 155 return constant.longValue() == constant.shortValue(); 156 default : 157 return false; } 159 160 case T_int : 161 switch (constantTypeID) { 162 case T_char : 163 return constant.charValue() == constant.intValue(); 164 case T_double : 165 return constant.doubleValue() == constant.intValue(); 166 case T_float : 167 return constant.floatValue() == constant.intValue(); 168 case T_int : 169 return true; 170 case T_short : 171 return constant.shortValue() == constant.intValue(); 172 case T_byte : 173 return constant.byteValue() == constant.intValue(); 174 case T_long : 175 return constant.longValue() == constant.intValue(); 176 default : 177 return false; } 179 180 case T_long : 181 switch (constantTypeID) { 182 case T_char : 183 return constant.charValue() == constant.longValue(); 184 case T_double : 185 return constant.doubleValue() == constant.longValue(); 186 case T_float : 187 return constant.floatValue() == constant.longValue(); 188 case T_int : 189 return constant.intValue() == constant.longValue(); 190 case T_short : 191 return constant.shortValue() == constant.longValue(); 192 case T_byte : 193 return constant.byteValue() == constant.longValue(); 194 case T_long : 195 return true; 196 default : 197 return false; } 199 200 default : 201 return false; } 203 } 204 205 public Expression() { 206 super(); 207 } 208 209 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { 210 return flowInfo; 211 } 212 213 223 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) { 224 225 return analyseCode(currentScope, flowContext, flowInfo); 226 } 227 228 231 public final boolean checkCastTypesCompatibility(Scope scope, TypeBinding castType, TypeBinding expressionType, Expression expression) { 232 233 236 240 if (castType == null || expressionType == null) return true; 241 242 boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; 245 if (castType.isBaseType()) { 246 if (expressionType.isBaseType()) { 247 if (expressionType == castType) { 248 if (expression != null) { 249 this.constant = expression.constant; } 251 tagAsUnnecessaryCast(scope, castType); 252 return true; 253 } 254 boolean necessary = false; 255 if (expressionType.isCompatibleWith(castType) 256 || (necessary = BaseTypeBinding.isNarrowing(castType.id, expressionType.id))) { 257 if (expression != null) { 258 expression.implicitConversion = (castType.id << 4) + expressionType.id; 259 if (expression.constant != Constant.NotAConstant) { 260 this.constant = expression.constant.castTo(expression.implicitConversion); 261 } 262 } 263 if (!necessary) tagAsUnnecessaryCast(scope, castType); 264 return true; 265 266 } 267 } else if (use15specifics 268 && scope.environment().computeBoxingType(expressionType).isCompatibleWith(castType)) { tagAsUnnecessaryCast(scope, castType); 270 return true; 271 } 272 return false; 273 } else if (use15specifics 274 && expressionType.isBaseType() 275 && scope.environment().computeBoxingType(expressionType).isCompatibleWith(castType)) { tagAsUnnecessaryCast(scope, castType); 277 return true; 278 } 279 280 switch(expressionType.kind()) { 281 case Binding.BASE_TYPE : 282 if (expressionType == TypeBinding.NULL) { 284 tagAsUnnecessaryCast(scope, castType); 285 return true; } 287 return false; 288 289 case Binding.ARRAY_TYPE : 290 if (castType == expressionType) { 291 tagAsUnnecessaryCast(scope, castType); 292 return true; } 294 switch (castType.kind()) { 295 case Binding.ARRAY_TYPE : 296 TypeBinding castElementType = ((ArrayBinding) castType).elementsType(); 298 TypeBinding exprElementType = ((ArrayBinding) expressionType).elementsType(); 299 if (exprElementType.isBaseType() || castElementType.isBaseType()) { 300 if (castElementType == exprElementType) { 301 tagAsNeedCheckCast(); 302 return true; 303 } 304 return false; 305 } 306 return checkCastTypesCompatibility(scope, castElementType, exprElementType, expression); 308 309 case Binding.TYPE_PARAMETER : 310 TypeBinding match = expressionType.findSuperTypeWithSameErasure(castType); 312 if (match == null) { 313 checkUnsafeCast(scope, castType, expressionType, null , true); 314 } 315 return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression); 317 318 default: 319 switch (castType.id) { 321 case T_JavaLangCloneable : 322 case T_JavaIoSerializable : 323 tagAsNeedCheckCast(); 324 return true; 325 case T_JavaLangObject : 326 tagAsUnnecessaryCast(scope, castType); 327 return true; 328 default : 329 return false; 330 } 331 } 332 333 case Binding.TYPE_PARAMETER : 334 TypeBinding match = expressionType.findSuperTypeWithSameErasure(castType); 335 if (match != null) { 336 return checkUnsafeCast(scope, castType, expressionType, match, false); 337 } 338 return checkCastTypesCompatibility(scope, castType, ((TypeVariableBinding)expressionType).upperBound(), expression); 340 341 case Binding.WILDCARD_TYPE : match = expressionType.findSuperTypeWithSameErasure(castType); 343 if (match != null) { 344 return checkUnsafeCast(scope, castType, expressionType, match, false); 345 } 346 return checkCastTypesCompatibility(scope, castType, ((WildcardBinding)expressionType).bound, expression); 348 349 default: 350 if (expressionType.isInterface()) { 351 switch (castType.kind()) { 352 case Binding.ARRAY_TYPE : 353 switch (expressionType.id) { 355 case T_JavaLangCloneable : 356 case T_JavaIoSerializable : 357 tagAsNeedCheckCast(); 358 return true; 359 default : 360 return false; 361 } 362 363 case Binding.TYPE_PARAMETER : 364 match = expressionType.findSuperTypeWithSameErasure(castType); 366 if (match == null) { 367 checkUnsafeCast(scope, castType, expressionType, null , true); 368 } 369 return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression); 371 372 default : 373 if (castType.isInterface()) { 374 ReferenceBinding interfaceType = (ReferenceBinding) expressionType; 376 match = interfaceType.findSuperTypeWithSameErasure(castType); 377 if (match != null) { 378 return checkUnsafeCast(scope, castType, interfaceType, match, false); 379 } 380 tagAsNeedCheckCast(); 381 match = castType.findSuperTypeWithSameErasure(interfaceType); 382 if (match != null) { 383 return checkUnsafeCast(scope, castType, interfaceType, match, true); 384 } 385 if (use15specifics) { 386 checkUnsafeCast(scope, castType, expressionType, null , true); 387 if (interfaceType.hasIncompatibleSuperType((ReferenceBinding)castType)) 389 return false; 390 } else { 391 MethodBinding[] castTypeMethods = getAllInheritedMethods((ReferenceBinding) castType); 393 MethodBinding[] expressionTypeMethods = getAllInheritedMethods((ReferenceBinding) expressionType); 394 int exprMethodsLength = expressionTypeMethods.length; 395 for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++) { 396 for (int j = 0; j < exprMethodsLength; j++) { 397 if ((castTypeMethods[i].returnType != expressionTypeMethods[j].returnType) 398 && (CharOperation.equals(castTypeMethods[i].selector, expressionTypeMethods[j].selector)) 399 && castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) { 400 return false; 401 402 } 403 } 404 } 405 } 406 return true; 407 } else { 408 if (castType.id == TypeIds.T_JavaLangObject) { tagAsUnnecessaryCast(scope, castType); 411 return true; 412 } 413 tagAsNeedCheckCast(); 415 match = castType.findSuperTypeWithSameErasure(expressionType); 416 if (match != null) { 417 return checkUnsafeCast(scope, castType, expressionType, match, true); 418 } 419 if (((ReferenceBinding) castType).isFinal()) { 420 return false; 422 } 423 if (use15specifics) { 424 checkUnsafeCast(scope, castType, expressionType, null , true); 425 if (((ReferenceBinding)castType).hasIncompatibleSuperType((ReferenceBinding) expressionType)) { 427 return false; 428 } 429 } 430 return true; 431 } 432 } 433 } else { 434 switch (castType.kind()) { 435 case Binding.ARRAY_TYPE : 436 if (expressionType.id == TypeIds.T_JavaLangObject) { if (use15specifics) checkUnsafeCast(scope, castType, expressionType, expressionType, true); 439 tagAsNeedCheckCast(); 440 return true; 441 } 442 return false; 443 444 case Binding.TYPE_PARAMETER : 445 match = expressionType.findSuperTypeWithSameErasure(castType); 447 if (match == null) { 448 checkUnsafeCast(scope, castType, expressionType, match, true); 449 } 450 return checkCastTypesCompatibility(scope, ((TypeVariableBinding)castType).upperBound(), expressionType, expression); 452 453 default : 454 if (castType.isInterface()) { 455 ReferenceBinding refExprType = (ReferenceBinding) expressionType; 457 match = refExprType.findSuperTypeWithSameErasure(castType); 458 if (match != null) { 459 return checkUnsafeCast(scope, castType, expressionType, match, false); 460 } 461 if (refExprType.isFinal()) { 463 return false; 464 } 465 tagAsNeedCheckCast(); 466 match = castType.findSuperTypeWithSameErasure(expressionType); 467 if (match != null) { 468 return checkUnsafeCast(scope, castType, expressionType, match, true); 469 } 470 if (use15specifics) { 471 checkUnsafeCast(scope, castType, expressionType, null , true); 472 if (refExprType.hasIncompatibleSuperType((ReferenceBinding) castType)) 474 return false; 475 } 476 return true; 477 } else { 478 match = expressionType.findSuperTypeWithSameErasure(castType); 480 if (match != null) { 481 if (expression != null && castType.id == TypeIds.T_JavaLangString) this.constant = expression.constant; return checkUnsafeCast(scope, castType, expressionType, match, false); 483 } 484 match = castType.findSuperTypeWithSameErasure(expressionType); 485 if (match != null) { 486 tagAsNeedCheckCast(); 487 return checkUnsafeCast(scope, castType, expressionType, match, true); 488 } 489 return false; 490 } 491 } 492 } 493 } 494 } 495 496 504 public void checkNPE(BlockScope scope, FlowContext flowContext, 505 FlowInfo flowInfo) { 506 LocalVariableBinding local = this.localVariableBinding(); 507 if (local != null && 508 (local.type.tagBits & TagBits.IsBaseType) == 0) { 509 if ((this.bits & ASTNode.IsNonNull) == 0) { 510 flowContext.recordUsingNullReference(scope, local, this, 511 FlowContext.MAY_NULL, flowInfo); 512 } 513 flowInfo.markAsComparedEqualToNonNull(local); 514 if (flowContext.initsOnFinally != null) { 516 flowContext.initsOnFinally.markAsComparedEqualToNonNull(local); 517 } 518 } 519 } 520 521 public boolean checkUnsafeCast(Scope scope, TypeBinding castType, TypeBinding expressionType, TypeBinding match, boolean isNarrowing) { 522 if (match == castType) { 523 if (!isNarrowing) tagAsUnnecessaryCast(scope, castType); 524 return true; 525 } 526 if (match != null && ( 527 castType.isBoundParameterizedType() 528 || expressionType.isBoundParameterizedType())) { 529 530 if (match.isProvablyDistinctFrom(isNarrowing ? expressionType : castType, 0)) { 531 return false; 532 } 533 } 534 if (!isNarrowing) tagAsUnnecessaryCast(scope, castType); 535 return true; 536 } 537 541 public void computeConversion(Scope scope, TypeBinding runtimeType, TypeBinding compileTimeType) { 542 543 if (runtimeType == null || compileTimeType == null) 544 return; 545 if (this.implicitConversion != 0) return; 547 if (runtimeType != TypeBinding.NULL && runtimeType.isBaseType()) { 551 if (!compileTimeType.isBaseType()) { 552 TypeBinding unboxedType = scope.environment().computeBoxingType(compileTimeType); 553 this.implicitConversion = TypeIds.UNBOXING; 554 scope.problemReporter().autoboxing(this, compileTimeType, runtimeType); 555 compileTimeType = unboxedType; 556 } 557 } else if (compileTimeType != TypeBinding.NULL && compileTimeType.isBaseType()) { 558 TypeBinding boxedType = scope.environment().computeBoxingType(runtimeType); 559 if (boxedType == runtimeType) boxedType = compileTimeType; 561 this.implicitConversion = TypeIds.BOXING | (boxedType.id << 4) + compileTimeType.id; 562 scope.problemReporter().autoboxing(this, compileTimeType, scope.environment().computeBoxingType(boxedType)); 563 return; 564 } else if (this.constant != Constant.NotAConstant && this.constant.typeID() != TypeIds.T_JavaLangString) { 565 this.implicitConversion = TypeIds.BOXING; 566 return; 567 } 568 int compileTimeTypeID, runtimeTypeID; 569 if ((compileTimeTypeID = compileTimeType.id) == TypeIds.NoId) { compileTimeTypeID = compileTimeType.erasure().id == TypeIds.T_JavaLangString ? TypeIds.T_JavaLangString : TypeIds.T_JavaLangObject; 571 } 572 switch (runtimeTypeID = runtimeType.id) { 573 case T_byte : 574 case T_short : 575 case T_char : 576 this.implicitConversion |= (TypeIds.T_int << 4) + compileTimeTypeID; 577 break; 578 case T_JavaLangString : 579 case T_float : 580 case T_boolean : 581 case T_double : 582 case T_int : case T_long : 584 this.implicitConversion |= (runtimeTypeID << 4) + compileTimeTypeID; 585 break; 586 default : } 591 } 592 593 600 public void generateCode(BlockScope currentScope, CodeStream codeStream) { 601 602 if ((this.bits & ASTNode.IsReachable) == 0) { 603 return; 604 } 605 generateCode(currentScope, codeStream, false); 606 } 607 608 615 public void generateCode( 616 BlockScope currentScope, 617 CodeStream codeStream, 618 boolean valueRequired) { 619 620 if (this.constant != Constant.NotAConstant) { 621 int pc = codeStream.position; 623 codeStream.generateConstant(this.constant, this.implicitConversion); 624 codeStream.recordPositionsFrom(pc, this.sourceStart); 625 } else { 626 throw new ShouldNotImplement(Messages.ast_missingCode); 628 } 629 } 630 631 639 public void generateOptimizedBoolean( 640 BlockScope currentScope, 641 CodeStream codeStream, 642 BranchLabel trueLabel, 643 BranchLabel falseLabel, 644 boolean valueRequired) { 645 646 649 Constant cst = this.optimizedBooleanConstant(); 650 generateCode(currentScope, codeStream, valueRequired && cst == Constant.NotAConstant); 651 if ((cst != Constant.NotAConstant) && (cst.typeID() == TypeIds.T_boolean)) { 652 int pc = codeStream.position; 653 if (cst.booleanValue() == true) { 654 if (valueRequired) { 656 if (falseLabel == null) { 657 if (trueLabel != null) { 659 codeStream.goto_(trueLabel); 660 } 661 } 662 } 663 } else { 664 if (valueRequired) { 665 if (falseLabel != null) { 666 if (trueLabel == null) { 668 codeStream.goto_(falseLabel); 669 } 670 } 671 } 672 } 673 codeStream.recordPositionsFrom(pc, this.sourceStart); 674 return; 675 } 676 int position = codeStream.position; 678 if (valueRequired) { 679 if (falseLabel == null) { 680 if (trueLabel != null) { 681 codeStream.ifne(trueLabel); 683 } 684 } else { 685 if (trueLabel == null) { 686 codeStream.ifeq(falseLabel); 688 } else { 689 } 691 } 692 } 693 codeStream.updateLastRecordedEndPC(currentScope, position); 695 } 696 697 702 public void generateOptimizedStringConcatenation( 703 BlockScope blockScope, 704 CodeStream codeStream, 705 int typeID) { 706 707 if (typeID == TypeIds.T_JavaLangString && this.constant != Constant.NotAConstant && this.constant.stringValue().length() == 0) { 708 return; } 710 generateCode(blockScope, codeStream, true); 711 codeStream.invokeStringConcatenationAppendForType(typeID); 712 } 713 714 718 public void generateOptimizedStringConcatenationCreation( 719 BlockScope blockScope, 720 CodeStream codeStream, 721 int typeID) { 722 723 codeStream.newStringContatenation(); 724 codeStream.dup(); 725 switch (typeID) { 726 case T_JavaLangObject : 727 case T_undefined : 728 codeStream.invokeStringConcatenationDefaultConstructor(); 731 generateCode(blockScope, codeStream, true); 732 codeStream.invokeStringConcatenationAppendForType(TypeIds.T_JavaLangObject); 733 return; 734 case T_JavaLangString : 735 case T_null : 736 if (this.constant != Constant.NotAConstant) { 737 String stringValue = this.constant.stringValue(); 738 if (stringValue.length() == 0) { codeStream.invokeStringConcatenationDefaultConstructor(); 740 return; 741 } 742 codeStream.ldc(stringValue); 743 } else { 744 generateCode(blockScope, codeStream, true); 746 codeStream.invokeStringValueOf(TypeIds.T_JavaLangObject); 747 } 748 break; 749 default : 750 generateCode(blockScope, codeStream, true); 751 codeStream.invokeStringValueOf(typeID); 752 } 753 codeStream.invokeStringConcatenationStringConstructor(); 754 } 755 756 private MethodBinding[] getAllInheritedMethods(ReferenceBinding binding) { 757 ArrayList collector = new ArrayList (); 758 getAllInheritedMethods0(binding, collector); 759 return (MethodBinding[]) collector.toArray(new MethodBinding[collector.size()]); 760 } 761 762 private void getAllInheritedMethods0(ReferenceBinding binding, ArrayList collector) { 763 if (!binding.isInterface()) return; 764 MethodBinding[] methodBindings = binding.methods(); 765 for (int i = 0, max = methodBindings.length; i < max; i++) { 766 collector.add(methodBindings[i]); 767 } 768 ReferenceBinding[] superInterfaces = binding.superInterfaces(); 769 for (int i = 0, max = superInterfaces.length; i < max; i++) { 770 getAllInheritedMethods0(superInterfaces[i], collector); 771 } 772 } 773 774 public boolean isCompactableOperation() { 775 776 return false; 777 } 778 779 public boolean isConstantValueOfTypeAssignableToType(TypeBinding constantType, TypeBinding targetType) { 784 785 if (this.constant == Constant.NotAConstant) 786 return false; 787 if (constantType == targetType) 788 return true; 789 if (constantType.isBaseType() && targetType.isBaseType()) { 790 if ((constantType == TypeBinding.INT 792 || BaseTypeBinding.isWidening(TypeIds.T_int, constantType.id)) 793 && (BaseTypeBinding.isNarrowing(targetType.id, TypeIds.T_int))) { 794 return isConstantValueRepresentable(this.constant, constantType.id, targetType.id); 796 } 797 } 798 return false; 799 } 800 801 public boolean isTypeReference() { 802 return false; 803 } 804 805 809 public LocalVariableBinding localVariableBinding() { 810 return null; 811 } 812 813 817 public void markAsNonNull() { 819 this.bits |= ASTNode.IsNonNull; 820 } 821 822 public int nullStatus(FlowInfo flowInfo) { 823 824 if ( 825 this.constant != null && this.constant != Constant.NotAConstant) 826 return FlowInfo.NON_NULL; 828 LocalVariableBinding local = localVariableBinding(); 829 if (local != null) { 830 if (flowInfo.isDefinitelyNull(local)) 831 return FlowInfo.NULL; 832 if (flowInfo.isDefinitelyNonNull(local)) 833 return FlowInfo.NON_NULL; 834 return FlowInfo.UNKNOWN; 835 } 836 return FlowInfo.NON_NULL; 837 } 838 839 846 public Constant optimizedBooleanConstant() { 847 return this.constant; 848 } 849 850 856 public TypeBinding postConversionType(Scope scope) { 857 TypeBinding convertedType = this.resolvedType; 858 int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4; 859 switch (runtimeType) { 860 case T_boolean : 861 convertedType = TypeBinding.BOOLEAN; 862 break; 863 case T_byte : 864 convertedType = TypeBinding.BYTE; 865 break; 866 case T_short : 867 convertedType = TypeBinding.SHORT; 868 break; 869 case T_char : 870 convertedType = TypeBinding.CHAR; 871 break; 872 case T_int : 873 convertedType = TypeBinding.INT; 874 break; 875 case T_float : 876 convertedType = TypeBinding.FLOAT; 877 break; 878 case T_long : 879 convertedType = TypeBinding.LONG; 880 break; 881 case T_double : 882 convertedType = TypeBinding.DOUBLE; 883 break; 884 default : 885 } 886 if ((this.implicitConversion & TypeIds.BOXING) != 0) { 887 convertedType = scope.environment().computeBoxingType(convertedType); 888 } 889 return convertedType; 890 } 891 892 public StringBuffer print(int indent, StringBuffer output) { 893 printIndent(indent, output); 894 return printExpression(indent, output); 895 } 896 897 public abstract StringBuffer printExpression(int indent, StringBuffer output); 898 899 public StringBuffer printStatement(int indent, StringBuffer output) { 900 return print(indent, output).append(";"); } 902 903 public void resolve(BlockScope scope) { 904 906 this.resolveType(scope); 907 return; 908 } 909 910 917 public TypeBinding resolveType(BlockScope scope) { 918 return null; 920 } 921 922 929 public TypeBinding resolveType(ClassScope scope) { 930 return null; 932 } 933 934 public TypeBinding resolveTypeExpecting( 935 BlockScope scope, 936 TypeBinding expectedType) { 937 938 this.setExpectedType(expectedType); TypeBinding expressionType = this.resolveType(scope); 940 if (expressionType == null) return null; 941 if (expressionType == expectedType) return expressionType; 942 943 if (!expressionType.isCompatibleWith(expectedType)) { 944 if (scope.isBoxingCompatibleWith(expressionType, expectedType)) { 945 this.computeConversion(scope, expectedType, expressionType); 946 } else { 947 scope.problemReporter().typeMismatchError(expressionType, expectedType, this); 948 return null; 949 } 950 } 951 return expressionType; 952 } 953 954 959 public Object reusableJSRTarget() { 960 if (this.constant != Constant.NotAConstant) 961 return this.constant; 962 return null; 963 } 964 965 973 public void setExpectedType(TypeBinding expectedType) { 974 } 976 977 public void tagAsNeedCheckCast() { 978 } 980 981 987 public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) { 988 } 990 991 public Expression toTypeReference() { 992 994 999 return this; 1000 } 1001 1002 1007 public void traverse(ASTVisitor visitor, BlockScope scope) { 1008 } 1010 1011 1016 public void traverse(ASTVisitor visitor, ClassScope scope) { 1017 } 1019} 1020 | Popular Tags |