1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.internal.compiler.ASTVisitor; 14 import org.eclipse.jdt.internal.compiler.impl.*; 15 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 16 import org.eclipse.jdt.internal.compiler.codegen.*; 17 import org.eclipse.jdt.internal.compiler.flow.*; 18 import org.eclipse.jdt.internal.compiler.lookup.*; 19 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; 20 21 public class SingleNameReference extends NameReference implements OperatorIds { 22 23 public static final int READ = 0; 24 public static final int WRITE = 1; 25 public char[] token; 26 public MethodBinding[] syntheticAccessors; public TypeBinding genericCast; 28 29 public SingleNameReference(char[] source, long pos) { 30 super(); 31 token = source; 32 sourceStart = (int) (pos >>> 32); 33 sourceEnd = (int) pos; 34 } 35 public FlowInfo analyseAssignment(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) { 36 37 boolean isReachable = (flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0; 38 if (isCompound) { switch (bits & RestrictiveFlagMASK) { 41 case Binding.FIELD : FieldBinding fieldBinding; 43 if ((fieldBinding = (FieldBinding) binding).isBlankFinal() 44 && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) { 45 if (!flowInfo.isDefinitelyAssigned(fieldBinding)) { 46 currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); 47 } 48 } 49 manageSyntheticAccessIfNecessary(currentScope, flowInfo, true ); 50 break; 51 case Binding.LOCAL : LocalVariableBinding localBinding; 54 if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) { 55 currentScope.problemReporter().uninitializedLocalVariable(localBinding, this); 56 } 58 if (isReachable) { 59 localBinding.useFlag = LocalVariableBinding.USED; 60 } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) { 61 localBinding.useFlag = LocalVariableBinding.FAKE_USED; 62 } 63 } 64 } 65 if (assignment.expression != null) { 66 flowInfo = assignment.expression.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); 67 } 68 switch (bits & RestrictiveFlagMASK) { 69 case Binding.FIELD : manageSyntheticAccessIfNecessary(currentScope, flowInfo, false ); 71 72 FieldBinding fieldBinding = (FieldBinding) binding; 73 ReferenceBinding declaringClass = fieldBinding.declaringClass; 74 if (declaringClass.isEnum()) { 76 MethodScope methodScope = currentScope.methodScope(); 77 SourceTypeBinding sourceType = currentScope.enclosingSourceType(); 78 if (fieldBinding.isStatic() 79 && this.constant == Constant.NotAConstant 80 && !methodScope.isStatic 81 && (sourceType == declaringClass || sourceType.superclass == declaringClass) && methodScope.isInsideInitializerOrConstructor()) { 83 currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this); 84 } 85 } 86 if (fieldBinding.isFinal()) { 88 if (!isCompound && fieldBinding.isBlankFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) { 90 if (flowInfo.isPotentiallyAssigned(fieldBinding)) { 91 currentScope.problemReporter().duplicateInitializationOfBlankFinalField(fieldBinding, this); 92 } else { 93 flowContext.recordSettingFinal(fieldBinding, this, flowInfo); 94 } 95 flowInfo.markAsDefinitelyAssigned(fieldBinding); 96 } else { 97 currentScope.problemReporter().cannotAssignToFinalField(fieldBinding, this); 98 } 99 } 100 break; 101 case Binding.LOCAL : LocalVariableBinding localBinding = (LocalVariableBinding) binding; 103 if (!flowInfo.isDefinitelyAssigned(localBinding)){ bits |= FirstAssignmentToLocal; 105 } else { 106 bits &= ~FirstAssignmentToLocal; 107 } 108 if (localBinding.isFinal()) { 109 if ((bits & DepthMASK) == 0) { 110 if ((isReachable && isCompound) || !localBinding.isBlankFinal()){ 112 currentScope.problemReporter().cannotAssignToFinalLocal(localBinding, this); 113 } else if (flowInfo.isPotentiallyAssigned(localBinding)) { 114 currentScope.problemReporter().duplicateInitializationOfFinalLocal(localBinding, this); 115 } else { 116 flowContext.recordSettingFinal(localBinding, this, flowInfo); 117 } 118 } else { 119 currentScope.problemReporter().cannotAssignToFinalOuterLocal(localBinding, this); 120 } 121 } 122 else if ((localBinding.tagBits & TagBits.IsArgument) != 0) { 123 currentScope.problemReporter().parameterAssignment(localBinding, this); 124 } 125 flowInfo.markAsDefinitelyAssigned(localBinding); 126 } 127 manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo); 128 return flowInfo; 129 } 130 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { 131 return analyseCode(currentScope, flowContext, flowInfo, true); 132 } 133 public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) { 134 135 switch (bits & RestrictiveFlagMASK) { 136 case Binding.FIELD : if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) { 138 manageSyntheticAccessIfNecessary(currentScope, flowInfo, true ); 139 } 140 FieldBinding fieldBinding = (FieldBinding) binding; 141 ReferenceBinding declaringClass = fieldBinding.declaringClass; 142 if (declaringClass.isEnum()) { 144 MethodScope methodScope = currentScope.methodScope(); 145 SourceTypeBinding sourceType = currentScope.enclosingSourceType(); 146 if (fieldBinding.isStatic() 147 && this.constant == Constant.NotAConstant 148 && !methodScope.isStatic 149 && (sourceType == declaringClass || sourceType.superclass == declaringClass) && methodScope.isInsideInitializerOrConstructor()) { 151 currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this); 152 } 153 } 154 if (fieldBinding.isBlankFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) { 156 if (!flowInfo.isDefinitelyAssigned(fieldBinding)) { 157 currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this); 158 } 159 } 160 break; 161 case Binding.LOCAL : LocalVariableBinding localBinding; 163 if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) binding)) { 164 currentScope.problemReporter().uninitializedLocalVariable(localBinding, this); 165 } 166 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { 167 localBinding.useFlag = LocalVariableBinding.USED; 168 } else if (localBinding.useFlag == LocalVariableBinding.UNUSED) { 169 localBinding.useFlag = LocalVariableBinding.FAKE_USED; 170 } 171 } 172 if (valueRequired) { 173 manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo); 174 } 175 return flowInfo; 176 } 177 178 public TypeBinding checkFieldAccess(BlockScope scope) { 179 180 FieldBinding fieldBinding = (FieldBinding) binding; 181 182 bits &= ~RestrictiveFlagMASK; bits |= Binding.FIELD; 184 MethodScope methodScope = scope.methodScope(); 185 boolean isStatic = fieldBinding.isStatic(); 186 if (!isStatic) { 187 if (methodScope.isStatic) { 189 scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding); 190 this.constant = Constant.NotAConstant; 191 return fieldBinding.type; 192 } 193 } 194 this.constant = fieldBinding.constant(); 195 196 if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & IsStrictlyAssigned) !=0)) 197 scope.problemReporter().deprecatedField(fieldBinding, this); 198 199 if ((this.bits & IsStrictlyAssigned) == 0 200 && methodScope.enclosingSourceType() == fieldBinding.original().declaringClass 201 && methodScope.lastVisibleFieldID >= 0 202 && fieldBinding.id >= methodScope.lastVisibleFieldID 203 && (!fieldBinding.isStatic() || methodScope.isStatic)) { 204 scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType()); 205 this.bits |= ASTNode.IgnoreNoEffectAssignCheck; 206 } 207 return fieldBinding.type; 208 209 } 210 211 214 public void computeConversion(Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) { 215 if (runtimeTimeType == null || compileTimeType == null) 216 return; 217 if ((bits & Binding.FIELD) != 0 && this.binding != null && this.binding.isValidBinding()) { 218 FieldBinding field = (FieldBinding) this.binding; 220 FieldBinding originalBinding = field.original(); 221 TypeBinding originalType = originalBinding.type; 222 if (originalBinding != field 224 && originalType != field.type 225 && runtimeTimeType.id != T_JavaLangObject 226 && (originalType.tagBits & TagBits.HasTypeVariable) != 0) { 227 TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType()) 228 ? compileTimeType : runtimeTimeType; 230 this.genericCast = originalType.genericCast(scope.boxing(targetType)); 231 } 232 } 233 super.computeConversion(scope, runtimeTimeType, compileTimeType); 234 } 235 236 public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { 237 238 if (assignment.expression.isCompactableOperation()) { 240 BinaryExpression operation = (BinaryExpression) assignment.expression; 241 int operator = (operation.bits & OperatorMASK) >> OperatorSHIFT; 242 SingleNameReference variableReference; 243 if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == binding)) { 244 variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.right, operator, operation.implicitConversion, valueRequired); 246 if (valueRequired) { 247 codeStream.generateImplicitConversion(assignment.implicitConversion); 248 } 249 return; 250 } 251 if ((operation.right instanceof SingleNameReference) 252 && ((operator == PLUS) || (operator == MULTIPLY)) && ((variableReference = (SingleNameReference) operation.right).binding == binding) 254 && (operation.left.constant != Constant.NotAConstant) && (((operation.left.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString) && (((operation.right.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) != T_JavaLangString)) { variableReference.generateCompoundAssignment(currentScope, codeStream, syntheticAccessors == null ? null : syntheticAccessors[WRITE], operation.left, operator, operation.implicitConversion, valueRequired); 259 if (valueRequired) { 260 codeStream.generateImplicitConversion(assignment.implicitConversion); 261 } 262 return; 263 } 264 } 265 switch (bits & RestrictiveFlagMASK) { 266 case Binding.FIELD : FieldBinding fieldBinding; 268 int pc = codeStream.position; 269 if (!(fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { if ((bits & DepthMASK) != 0) { 271 ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); 272 Object [] emulationPath = currentScope.getEmulationPath(targetType, true , false); 273 codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); 274 } else { 275 this.generateReceiver(codeStream); 276 } 277 } 278 codeStream.recordPositionsFrom(pc, this.sourceStart); 279 assignment.expression.generateCode(currentScope, codeStream, true); 280 fieldStore(codeStream, fieldBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], valueRequired); 281 if (valueRequired) { 282 codeStream.generateImplicitConversion(assignment.implicitConversion); 283 } 284 return; 286 case Binding.LOCAL : LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; 288 if (localBinding.resolvedPosition != -1) { 289 assignment.expression.generateCode(currentScope, codeStream, true); 290 } else { 291 if (assignment.expression.constant != Constant.NotAConstant) { 292 if (valueRequired) { 294 codeStream.generateConstant(assignment.expression.constant, assignment.implicitConversion); 295 } 296 } else { 297 assignment.expression.generateCode(currentScope, codeStream, true); 298 300 if (valueRequired) { 301 codeStream.generateImplicitConversion(assignment.implicitConversion); } else { 303 if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) { 304 codeStream.pop2(); 305 } else { 306 codeStream.pop(); 307 } 308 } 309 } 310 return; 311 } 312 if (localBinding.type.isArrayType() 314 && (assignment.expression.resolvedType == TypeBinding.NULL || ((assignment.expression instanceof CastExpression) && (((CastExpression)assignment.expression).innermostCastedExpression().resolvedType == TypeBinding.NULL)))){ 317 codeStream.checkcast(localBinding.type); 318 } 319 320 codeStream.store(localBinding, valueRequired); 322 if ((bits & FirstAssignmentToLocal) != 0) { localBinding.recordInitializationStartPC(codeStream.position); 324 } 325 if (valueRequired) { 327 codeStream.generateImplicitConversion(assignment.implicitConversion); 328 } 329 } 330 } 331 public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { 332 int pc = codeStream.position; 333 if (constant != Constant.NotAConstant) { 334 if (valueRequired) { 335 codeStream.generateConstant(constant, implicitConversion); 336 } 337 codeStream.recordPositionsFrom(pc, this.sourceStart); 338 return; 339 } else { 340 switch (bits & RestrictiveFlagMASK) { 341 case Binding.FIELD : FieldBinding fieldBinding = (FieldBinding) this.codegenBinding; 343 Constant fieldConstant = fieldBinding.constant(); 344 if (fieldConstant != Constant.NotAConstant) { 345 if (valueRequired) { 347 codeStream.generateConstant(fieldConstant, implicitConversion); 348 } 349 codeStream.recordPositionsFrom(pc, this.sourceStart); 350 return; 351 } 352 if (fieldBinding.isStatic()) { 353 if (!valueRequired 354 && ((FieldBinding)binding).original().declaringClass == this.actualReceiverType.erasure() 356 && ((implicitConversion & TypeIds.UNBOXING) == 0) 357 && this.genericCast == null) { 358 codeStream.recordPositionsFrom(pc, this.sourceStart); 360 return; 361 } 362 if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { 364 codeStream.getstatic(fieldBinding); 365 } else { 366 codeStream.invokestatic(syntheticAccessors[READ]); 367 } 368 } else { 369 if (!valueRequired 370 && (implicitConversion & TypeIds.UNBOXING) == 0 371 && this.genericCast == null) { 372 codeStream.recordPositionsFrom(pc, this.sourceStart); 374 return; 375 } 376 if ((bits & DepthMASK) != 0) { 378 ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); 379 Object [] emulationPath = currentScope.getEmulationPath(targetType, true , false); 380 codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); 381 } else { 382 generateReceiver(codeStream); 383 } 384 if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { 386 codeStream.getfield(fieldBinding); 387 } else { 388 codeStream.invokestatic(syntheticAccessors[READ]); 389 } 390 } 391 break; 392 case Binding.LOCAL : LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; 394 if (!valueRequired && (implicitConversion & TypeIds.UNBOXING) == 0) { 395 codeStream.recordPositionsFrom(pc, this.sourceStart); 397 return; 398 } 399 if ((bits & DepthMASK) != 0) { 401 VariableBinding[] path = currentScope.getEmulationPath(localBinding); 403 codeStream.generateOuterAccess(path, this, localBinding, currentScope); 404 } else { 405 codeStream.load(localBinding); 407 } 408 break; 409 default: codeStream.recordPositionsFrom(pc, this.sourceStart); 411 return; 412 } 413 } 414 if (this.genericCast != null) codeStream.checkcast(this.genericCast); 416 if (valueRequired) { 417 codeStream.generateImplicitConversion(implicitConversion); 418 } else { 419 boolean isUnboxing = (implicitConversion & TypeIds.UNBOXING) != 0; 420 if (isUnboxing) codeStream.generateImplicitConversion(implicitConversion); 422 switch (isUnboxing ? postConversionType(currentScope).id : this.resolvedType.id) { 423 case T_long : 424 case T_double : 425 codeStream.pop2(); 426 break; 427 default : 428 codeStream.pop(); 429 } 430 } 431 codeStream.recordPositionsFrom(pc, this.sourceStart); 432 } 433 439 public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { 440 441 this.generateCompoundAssignment( 442 currentScope, 443 codeStream, 444 syntheticAccessors == null ? null : syntheticAccessors[WRITE], 445 expression, 446 operator, 447 assignmentImplicitConversion, 448 valueRequired); 449 } 450 454 public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, MethodBinding writeAccessor, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { 455 switch (bits & RestrictiveFlagMASK) { 456 case Binding.FIELD : FieldBinding fieldBinding; 458 if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { 459 if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { 460 codeStream.getstatic(fieldBinding); 461 } else { 462 codeStream.invokestatic(syntheticAccessors[READ]); 463 } 464 } else { 465 if ((bits & DepthMASK) != 0) { 466 ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); 467 Object [] emulationPath = currentScope.getEmulationPath(targetType, true , false); 468 codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); 469 } else { 470 codeStream.aload_0(); 471 } 472 codeStream.dup(); 473 if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { 474 codeStream.getfield(fieldBinding); 475 } else { 476 codeStream.invokestatic(syntheticAccessors[READ]); 477 } 478 } 479 break; 480 case Binding.LOCAL : LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; 482 Constant assignConstant; 483 int increment; 484 switch (localBinding.type.id) { 486 case T_JavaLangString : 487 codeStream.generateStringConcatenationAppend(currentScope, this, expression); 488 if (valueRequired) { 489 codeStream.dup(); 490 } 491 codeStream.store(localBinding, false); 492 return; 493 case T_int : 494 if (((assignConstant = expression.constant) != Constant.NotAConstant) 495 && (assignConstant.typeID() != T_float) && (assignConstant.typeID() != T_double) 497 && ((increment = assignConstant.intValue()) == (short) increment)) { switch (operator) { 499 case PLUS : 500 codeStream.iinc(localBinding.resolvedPosition, increment); 501 if (valueRequired) { 502 codeStream.load(localBinding); 503 } 504 return; 505 case MINUS : 506 codeStream.iinc(localBinding.resolvedPosition, -increment); 507 if (valueRequired) { 508 codeStream.load(localBinding); 509 } 510 return; 511 } 512 } 513 default : 514 codeStream.load(localBinding); 515 } 516 } 517 int operationTypeID; 519 switch(operationTypeID = (implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) { 520 case T_JavaLangString : 521 case T_JavaLangObject : 522 case T_undefined : 523 codeStream.generateStringConcatenationAppend(currentScope, null, expression); 527 break; 529 default : 530 if (this.genericCast != null) 532 codeStream.checkcast(this.genericCast); 533 codeStream.generateImplicitConversion(this.implicitConversion); 534 if (expression == IntLiteral.One){ codeStream.generateConstant(expression.constant, this.implicitConversion); 537 } else { 538 expression.generateCode(currentScope, codeStream, true); 539 } 540 codeStream.sendOperator(operator, operationTypeID); 542 codeStream.generateImplicitConversion(assignmentImplicitConversion); 544 } 545 switch (bits & RestrictiveFlagMASK) { 547 case Binding.FIELD : fieldStore(codeStream, (FieldBinding) this.codegenBinding, writeAccessor, valueRequired); 549 return; 551 case Binding.LOCAL : LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; 553 if (valueRequired) { 554 if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) { 555 codeStream.dup2(); 556 } else { 557 codeStream.dup(); 558 } 559 } 560 codeStream.store(localBinding, false); 561 } 562 } 563 564 public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { 565 switch (bits & RestrictiveFlagMASK) { 566 case Binding.FIELD : FieldBinding fieldBinding; 568 if ((fieldBinding = (FieldBinding) this.codegenBinding).isStatic()) { 569 if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { 570 codeStream.getstatic(fieldBinding); 571 } else { 572 codeStream.invokestatic(syntheticAccessors[READ]); 573 } 574 } else { 575 if ((bits & DepthMASK) != 0) { 576 ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT); 577 Object [] emulationPath = currentScope.getEmulationPath(targetType, true , false); 578 codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope); 579 } else { 580 codeStream.aload_0(); 581 } 582 codeStream.dup(); 583 if ((syntheticAccessors == null) || (syntheticAccessors[READ] == null)) { 584 codeStream.getfield(fieldBinding); 585 } else { 586 codeStream.invokestatic(syntheticAccessors[READ]); 587 } 588 } 589 if (valueRequired) { 590 if (fieldBinding.isStatic()) { 591 if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { 592 codeStream.dup2(); 593 } else { 594 codeStream.dup(); 595 } 596 } else { if ((fieldBinding.type == TypeBinding.LONG) || (fieldBinding.type == TypeBinding.DOUBLE)) { 598 codeStream.dup2_x1(); 599 } else { 600 codeStream.dup_x1(); 601 } 602 } 603 } 604 if (this.genericCast != null) 605 codeStream.checkcast(this.genericCast); 606 codeStream.generateImplicitConversion(this.implicitConversion); 607 codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion); 608 codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK); 609 codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); 610 fieldStore(codeStream, fieldBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[WRITE], false); 611 return; 613 case Binding.LOCAL : LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding; 615 if (localBinding.type == TypeBinding.INT) { 617 if (valueRequired) { 618 codeStream.load(localBinding); 619 } 620 if (postIncrement.operator == PLUS) { 621 codeStream.iinc(localBinding.resolvedPosition, 1); 622 } else { 623 codeStream.iinc(localBinding.resolvedPosition, -1); 624 } 625 } else { 626 codeStream.load(localBinding); 627 if (valueRequired){ 628 if ((localBinding.type == TypeBinding.LONG) || (localBinding.type == TypeBinding.DOUBLE)) { 629 codeStream.dup2(); 630 } else { 631 codeStream.dup(); 632 } 633 } 634 codeStream.generateImplicitConversion(implicitConversion); 635 codeStream.generateConstant(postIncrement.expression.constant, implicitConversion); 636 codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK); 637 codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion); 638 639 codeStream.store(localBinding, false); 640 } 641 } 642 } 643 644 public void generateReceiver(CodeStream codeStream) { 645 codeStream.aload_0(); 646 } 647 648 651 public TypeBinding[] genericTypeArguments() { 652 return null; 653 } 654 655 659 public LocalVariableBinding localVariableBinding() { 660 switch (bits & RestrictiveFlagMASK) { 661 case Binding.FIELD : break; 663 case Binding.LOCAL : return (LocalVariableBinding) this.binding; 665 } 666 return null; 667 } 668 669 public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) { 670 671 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { 672 if (((bits & DepthMASK) == 0) || (constant != Constant.NotAConstant)) return; 674 675 if ((bits & RestrictiveFlagMASK) == Binding.LOCAL) { 676 currentScope.emulateOuterAccess((LocalVariableBinding) binding); 677 } 678 } 679 } 680 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) { 681 682 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0) return; 683 684 if (constant != Constant.NotAConstant) 686 return; 687 688 if ((bits & Binding.FIELD) != 0) { 689 FieldBinding fieldBinding = (FieldBinding) binding; 690 FieldBinding codegenField = fieldBinding.original(); 691 this.codegenBinding = codegenField; 692 if (((bits & DepthMASK) != 0) 693 && (codegenField.isPrivate() || (codegenField.isProtected() && codegenField.declaringClass.getPackage() != currentScope.enclosingSourceType().getPackage()))) { 696 if (syntheticAccessors == null) 697 syntheticAccessors = new MethodBinding[2]; 698 syntheticAccessors[isReadAccess ? READ : WRITE] = 699 ((SourceTypeBinding)currentScope.enclosingSourceType(). 700 enclosingTypeAt((bits & DepthMASK) >> DepthSHIFT)).addSyntheticMethod(codegenField, isReadAccess); 701 currentScope.problemReporter().needToEmulateFieldAccess(codegenField, this, isReadAccess); 702 return; 703 } 704 if (fieldBinding.declaringClass != this.actualReceiverType 709 && !this.actualReceiverType.isArrayType() 710 && fieldBinding.declaringClass != null && fieldBinding.constant() == Constant.NotAConstant) { 712 CompilerOptions options = currentScope.compilerOptions(); 713 if ((options.targetJDK >= ClassFileConstants.JDK1_2 714 && (options.complianceLevel >= ClassFileConstants.JDK1_4 || !fieldBinding.isStatic()) 715 && fieldBinding.declaringClass.id != T_JavaLangObject) || !fieldBinding.declaringClass.canBeSeenBy(currentScope)) { 717 718 this.codegenBinding = 719 currentScope.enclosingSourceType().getUpdatedFieldBinding( 720 codegenField, 721 (ReferenceBinding)this.actualReceiverType.erasure()); 722 } 723 } 724 } 725 } 726 727 public int nullStatus(FlowInfo flowInfo) { 728 if (this.constant != null && this.constant != Constant.NotAConstant) { 729 return FlowInfo.NON_NULL; } 731 switch (bits & RestrictiveFlagMASK) { 732 case Binding.FIELD : return FlowInfo.UNKNOWN; 734 case Binding.LOCAL : LocalVariableBinding local = (LocalVariableBinding) this.binding; 736 if (local != null) { 737 if (flowInfo.isDefinitelyNull(local)) 738 return FlowInfo.NULL; 739 if (flowInfo.isDefinitelyNonNull(local)) 740 return FlowInfo.NON_NULL; 741 return FlowInfo.UNKNOWN; 742 } 743 } 744 return FlowInfo.NON_NULL; } 746 747 750 public TypeBinding postConversionType(Scope scope) { 751 TypeBinding convertedType = this.resolvedType; 752 if (this.genericCast != null) 753 convertedType = this.genericCast; 754 int runtimeType = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4; 755 switch (runtimeType) { 756 case T_boolean : 757 convertedType = TypeBinding.BOOLEAN; 758 break; 759 case T_byte : 760 convertedType = TypeBinding.BYTE; 761 break; 762 case T_short : 763 convertedType = TypeBinding.SHORT; 764 break; 765 case T_char : 766 convertedType = TypeBinding.CHAR; 767 break; 768 case T_int : 769 convertedType = TypeBinding.INT; 770 break; 771 case T_float : 772 convertedType = TypeBinding.FLOAT; 773 break; 774 case T_long : 775 convertedType = TypeBinding.LONG; 776 break; 777 case T_double : 778 convertedType = TypeBinding.DOUBLE; 779 break; 780 default : 781 } 782 if ((this.implicitConversion & BOXING) != 0) { 783 convertedType = scope.environment().computeBoxingType(convertedType); 784 } 785 return convertedType; 786 } 787 788 public StringBuffer printExpression(int indent, StringBuffer output){ 789 790 return output.append(token); 791 } 792 public TypeBinding reportError(BlockScope scope) { 793 794 constant = Constant.NotAConstant; 796 if (binding instanceof ProblemFieldBinding) { 797 scope.problemReporter().invalidField(this, (FieldBinding) binding); 798 } else if (binding instanceof ProblemReferenceBinding) { 799 scope.problemReporter().invalidType(this, (TypeBinding) binding); 800 } else { 801 scope.problemReporter().unresolvableReference(this, binding); 802 } 803 return null; 804 } 805 806 public TypeBinding resolveType(BlockScope scope) { 807 809 if (this.actualReceiverType != null) { 810 this.binding = scope.getField(this.actualReceiverType, token, this); 811 } else { 812 this.actualReceiverType = scope.enclosingSourceType(); 813 this.binding = scope.getBinding(token, bits & RestrictiveFlagMASK, this, true ); 814 } 815 this.codegenBinding = this.binding; 816 if (this.binding.isValidBinding()) { 817 switch (bits & RestrictiveFlagMASK) { 818 case Binding.VARIABLE : case Binding.VARIABLE | Binding.TYPE : if (binding instanceof VariableBinding) { 821 VariableBinding variable = (VariableBinding) binding; 822 if (binding instanceof LocalVariableBinding) { 823 bits &= ~RestrictiveFlagMASK; bits |= Binding.LOCAL; 825 if (!variable.isFinal() && (bits & DepthMASK) != 0) { 826 scope.problemReporter().cannotReferToNonFinalOuterLocal((LocalVariableBinding)variable, this); 827 } 828 TypeBinding fieldType = variable.type; 829 if ((this.bits & IsStrictlyAssigned) == 0) { 830 constant = variable.constant(); 831 if (fieldType != null) 832 fieldType = fieldType.capture(scope, this.sourceEnd); } else { 834 constant = Constant.NotAConstant; 835 } 836 return this.resolvedType = fieldType; 837 } 838 FieldBinding field = (FieldBinding) this.binding; 840 if (!field.isStatic() && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) { 841 scope.problemReporter().unqualifiedFieldAccess(this, field); 842 } 843 TypeBinding fieldType = checkFieldAccess(scope); 845 return this.resolvedType = 846 (((this.bits & IsStrictlyAssigned) == 0) 847 ? fieldType.capture(scope, this.sourceEnd) 848 : fieldType); 849 } 850 851 bits &= ~RestrictiveFlagMASK; bits |= Binding.TYPE; 854 case Binding.TYPE : constant = Constant.NotAConstant; 856 TypeBinding type = (TypeBinding)binding; 858 if (isTypeUseDeprecated(type, scope)) 859 scope.problemReporter().deprecatedType(type, this); 860 type = scope.environment().convertToRawType(type); 861 return this.resolvedType = type; 862 } 863 } 864 865 return this.resolvedType = this.reportError(scope); 867 } 868 869 public void traverse(ASTVisitor visitor, BlockScope scope) { 870 visitor.visit(this, scope); 871 visitor.endVisit(this, scope); 872 } 873 874 public void traverse(ASTVisitor visitor, ClassScope scope) { 875 visitor.visit(this, scope); 876 visitor.endVisit(this, scope); 877 } 878 879 public String unboundReferenceErrorName(){ 880 881 return new String (token); 882 } 883 } 884 | Popular Tags |