1 11 package org.eclipse.jdt.internal.compiler.lookup; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.ast.*; 15 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 16 import org.eclipse.jdt.internal.compiler.codegen.CodeStream; 17 import org.eclipse.jdt.internal.compiler.impl.Constant; 18 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 19 20 public class BlockScope extends Scope { 21 22 public LocalVariableBinding[] locals; 24 public int localIndex; public int startIndex; public int offset; public int maxOffset; 29 public BlockScope[] shiftScopes; 32 33 public Scope[] subscopes = new Scope[1]; public int subscopeCount = 0; public CaseStatement enclosingCase; 38 public final static VariableBinding[] EmulationPathToImplicitThis = {}; 39 public final static VariableBinding[] NoEnclosingInstanceInConstructorCall = {}; 40 41 public final static VariableBinding[] NoEnclosingInstanceInStaticContext = {}; 42 43 public BlockScope(BlockScope parent) { 44 this(parent, true); 45 } 46 47 public BlockScope(BlockScope parent, boolean addToParentScope) { 48 this(Scope.BLOCK_SCOPE, parent); 49 this.locals = new LocalVariableBinding[5]; 50 if (addToParentScope) parent.addSubscope(this); 51 this.startIndex = parent.localIndex; 52 } 53 54 public BlockScope(BlockScope parent, int variableCount) { 55 this(Scope.BLOCK_SCOPE, parent); 56 this.locals = new LocalVariableBinding[variableCount]; 57 parent.addSubscope(this); 58 this.startIndex = parent.localIndex; 59 } 60 61 protected BlockScope(int kind, Scope parent) { 62 super(kind, parent); 63 } 64 65 67 public final void addAnonymousType(TypeDeclaration anonymousType, ReferenceBinding superBinding) { 68 ClassScope anonymousClassScope = new ClassScope(this, anonymousType); 69 anonymousClassScope.buildAnonymousTypeBinding( 70 enclosingSourceType(), 71 superBinding); 72 } 73 74 76 public final void addLocalType(TypeDeclaration localType) { 77 ClassScope localTypeScope = new ClassScope(this, localType); 78 addSubscope(localTypeScope); 79 localTypeScope.buildLocalTypeBinding(enclosingSourceType()); 80 } 81 82 85 public final void addLocalVariable(LocalVariableBinding binding) { 86 checkAndSetModifiersForVariable(binding); 87 if (this.localIndex == this.locals.length) 89 System.arraycopy( 90 this.locals, 91 0, 92 (this.locals = new LocalVariableBinding[this.localIndex * 2]), 93 0, 94 this.localIndex); 95 this.locals[this.localIndex++] = binding; 96 97 binding.declaringScope = this; 99 binding.id = this.outerMostMethodScope().analysisIndex++; 100 } 102 103 public void addSubscope(Scope childScope) { 104 if (this.subscopeCount == this.subscopes.length) 105 System.arraycopy( 106 this.subscopes, 107 0, 108 (this.subscopes = new Scope[this.subscopeCount * 2]), 109 0, 110 this.subscopeCount); 111 this.subscopes[this.subscopeCount++] = childScope; 112 } 113 114 118 public final boolean allowBlankFinalFieldAssignment(FieldBinding binding) { 119 if (enclosingReceiverType() != binding.declaringClass) 120 return false; 121 122 MethodScope methodScope = methodScope(); 123 if (methodScope.isStatic != binding.isStatic()) 124 return false; 125 return methodScope.isInsideInitializer() || ((AbstractMethodDeclaration) methodScope.referenceContext).isInitializationMethod(); } 128 String basicToString(int tab) { 129 String newLine = "\n"; for (int i = tab; --i >= 0;) 131 newLine += "\t"; 133 String s = newLine + "--- Block Scope ---"; newLine += "\t"; s += newLine + "locals:"; for (int i = 0; i < this.localIndex; i++) 137 s += newLine + "\t" + this.locals[i].toString(); s += newLine + "startIndex = " + this.startIndex; return s; 140 } 141 142 private void checkAndSetModifiersForVariable(LocalVariableBinding varBinding) { 143 int modifiers = varBinding.modifiers; 144 if ((modifiers & ExtraCompilerModifiers.AccAlternateModifierProblem) != 0 && varBinding.declaration != null){ 145 problemReporter().duplicateModifierForVariable(varBinding.declaration, this instanceof MethodScope); 146 } 147 int realModifiers = modifiers & ExtraCompilerModifiers.AccJustFlag; 148 149 int unexpectedModifiers = ~ClassFileConstants.AccFinal; 150 if ((realModifiers & unexpectedModifiers) != 0 && varBinding.declaration != null){ 151 problemReporter().illegalModifierForVariable(varBinding.declaration, this instanceof MethodScope); 152 } 153 varBinding.modifiers = modifiers; 154 } 155 156 162 void computeLocalVariablePositions(int ilocal, int initOffset, CodeStream codeStream) { 163 this.offset = initOffset; 164 this.maxOffset = initOffset; 165 166 int maxLocals = this.localIndex; 168 boolean hasMoreVariables = ilocal < maxLocals; 169 170 int iscope = 0, maxScopes = this.subscopeCount; 172 boolean hasMoreScopes = maxScopes > 0; 173 174 while (hasMoreVariables || hasMoreScopes) { 176 if (hasMoreScopes 177 && (!hasMoreVariables || (this.subscopes[iscope].startIndex() <= ilocal))) { 178 if (this.subscopes[iscope] instanceof BlockScope) { 180 BlockScope subscope = (BlockScope) this.subscopes[iscope]; 181 int subOffset = subscope.shiftScopes == null ? this.offset : subscope.maxShiftedOffset(); 182 subscope.computeLocalVariablePositions(0, subOffset, codeStream); 183 if (subscope.maxOffset > this.maxOffset) 184 this.maxOffset = subscope.maxOffset; 185 } 186 hasMoreScopes = ++iscope < maxScopes; 187 } else { 188 189 LocalVariableBinding local = this.locals[ilocal]; 192 boolean generateCurrentLocalVar = (local.useFlag == LocalVariableBinding.USED && local.constant() == Constant.NotAConstant); 194 195 if (local.useFlag == LocalVariableBinding.UNUSED 197 && (local.declaration != null) && ((local.declaration.bits & ASTNode.IsLocalDeclarationReachable) != 0)) { 200 if (!(local.declaration instanceof Argument)) this.problemReporter().unusedLocalVariable(local.declaration); 202 } 203 204 if (!generateCurrentLocalVar) { 206 if (local.declaration != null && compilerOptions().preserveAllLocalVariables) { 207 generateCurrentLocalVar = true; local.useFlag = LocalVariableBinding.USED; 209 } 210 } 211 212 if (generateCurrentLocalVar) { 214 215 if (local.declaration != null) { 216 codeStream.record(local); } 218 local.resolvedPosition = this.offset; 220 221 if ((local.type == TypeBinding.LONG) || (local.type == TypeBinding.DOUBLE)) { 222 this.offset += 2; 223 } else { 224 this.offset++; 225 } 226 if (this.offset > 0xFFFF) { this.problemReporter().noMoreAvailableSpaceForLocal( 228 local, 229 local.declaration == null ? (ASTNode)this.methodScope().referenceContext : local.declaration); 230 } 231 } else { 232 local.resolvedPosition = -1; } 234 hasMoreVariables = ++ilocal < maxLocals; 235 } 236 } 237 if (this.offset > this.maxOffset) 238 this.maxOffset = this.offset; 239 } 240 241 248 public void emulateOuterAccess(LocalVariableBinding outerLocalVariable) { 249 BlockScope outerVariableScope = outerLocalVariable.declaringScope; 250 if (outerVariableScope == null) 251 return; MethodScope currentMethodScope = this.methodScope(); 253 if (outerVariableScope.methodScope() != currentMethodScope) { 254 NestedTypeBinding currentType = (NestedTypeBinding) this.enclosingSourceType(); 255 256 if (!currentType.isLocalType()) { 258 return; 259 } 260 if (!currentMethodScope.isInsideInitializerOrConstructor()) { 262 currentType.addSyntheticArgumentAndField(outerLocalVariable); 263 } else { 264 currentType.addSyntheticArgument(outerLocalVariable); 265 } 266 } 267 } 268 269 288 public final ReferenceBinding findLocalType(char[] name) { 289 long compliance = compilerOptions().complianceLevel; 290 for (int i = this.subscopeCount-1; i >= 0; i--) { 291 if (this.subscopes[i] instanceof ClassScope) { 292 LocalTypeBinding sourceType = (LocalTypeBinding)((ClassScope) this.subscopes[i]).referenceContext.binding; 293 if (compliance >= ClassFileConstants.JDK1_4 && sourceType.enclosingCase != null) { 295 if (!this.isInsideCase(sourceType.enclosingCase)) { 296 continue; 297 } 298 } 299 if (CharOperation.equals(sourceType.sourceName(), name)) 300 return sourceType; 301 } 302 } 303 return null; 304 } 305 306 311 public LocalDeclaration[] findLocalVariableDeclarations(int position) { 312 int ilocal = 0, maxLocals = this.localIndex; 314 boolean hasMoreVariables = maxLocals > 0; 315 LocalDeclaration[] localDeclarations = null; 316 int declPtr = 0; 317 318 int iscope = 0, maxScopes = this.subscopeCount; 320 boolean hasMoreScopes = maxScopes > 0; 321 322 while (hasMoreVariables || hasMoreScopes) { 324 if (hasMoreScopes 325 && (!hasMoreVariables || (this.subscopes[iscope].startIndex() <= ilocal))) { 326 Scope subscope = this.subscopes[iscope]; 328 if (subscope.kind == Scope.BLOCK_SCOPE) { localDeclarations = ((BlockScope)subscope).findLocalVariableDeclarations(position); 330 if (localDeclarations != null) { 331 return localDeclarations; 332 } 333 } 334 hasMoreScopes = ++iscope < maxScopes; 335 } else { 336 LocalVariableBinding local = this.locals[ilocal]; if (local != null) { 339 LocalDeclaration localDecl = local.declaration; 340 if (localDecl != null) { 341 if (localDecl.declarationSourceStart <= position) { 342 if (position <= localDecl.declarationSourceEnd) { 343 if (localDeclarations == null) { 344 localDeclarations = new LocalDeclaration[maxLocals]; 345 } 346 localDeclarations[declPtr++] = localDecl; 347 } 348 } else { 349 return localDeclarations; 350 } 351 } 352 } 353 hasMoreVariables = ++ilocal < maxLocals; 354 if (!hasMoreVariables && localDeclarations != null) { 355 return localDeclarations; 356 } 357 } 358 } 359 return null; 360 } 361 362 public LocalVariableBinding findVariable(char[] variableName) { 363 int varLength = variableName.length; 364 for (int i = this.localIndex-1; i >= 0; i--) { LocalVariableBinding local; 366 char[] localName; 367 if ((localName = (local = this.locals[i]).name).length == varLength && CharOperation.equals(localName, variableName)) 368 return local; 369 } 370 return null; 371 } 372 373 404 public Binding getBinding(char[][] compoundName, int mask, InvocationSite invocationSite, boolean needResolve) { 405 Binding binding = getBinding(compoundName[0], mask | Binding.TYPE | Binding.PACKAGE, invocationSite, needResolve); 406 invocationSite.setFieldIndex(1); 407 if (binding instanceof VariableBinding) return binding; 408 CompilationUnitScope unitScope = compilationUnitScope(); 409 unitScope.recordQualifiedReference(compoundName); 412 if (!binding.isValidBinding()) return binding; 413 414 int length = compoundName.length; 415 int currentIndex = 1; 416 foundType : if (binding instanceof PackageBinding) { 417 PackageBinding packageBinding = (PackageBinding) binding; 418 while (currentIndex < length) { 419 unitScope.recordReference(packageBinding.compoundName, compoundName[currentIndex]); 420 binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]); 421 invocationSite.setFieldIndex(currentIndex); 422 if (binding == null) { 423 if (currentIndex == length) { 424 return new ProblemReferenceBinding( 426 CharOperation.subarray(compoundName, 0, currentIndex), 427 null, 428 ProblemReasons.NotFound); 429 } 430 return new ProblemBinding( 431 CharOperation.subarray(compoundName, 0, currentIndex), 432 ProblemReasons.NotFound); 433 } 434 if (binding instanceof ReferenceBinding) { 435 if (!binding.isValidBinding()) 436 return new ProblemReferenceBinding( 437 CharOperation.subarray(compoundName, 0, currentIndex), 438 ((ReferenceBinding)binding).closestMatch(), 439 binding.problemId()); 440 if (!((ReferenceBinding) binding).canBeSeenBy(this)) 441 return new ProblemReferenceBinding( 442 CharOperation.subarray(compoundName, 0, currentIndex), 443 (ReferenceBinding) binding, 444 ProblemReasons.NotVisible); 445 break foundType; 446 } 447 packageBinding = (PackageBinding) binding; 448 } 449 450 return new ProblemReferenceBinding( 452 CharOperation.subarray(compoundName, 0, currentIndex), 453 null, 454 ProblemReasons.NotFound); 455 } 456 457 ReferenceBinding referenceBinding = (ReferenceBinding) binding; 459 binding = environment().convertToRawType(referenceBinding); 460 if (invocationSite instanceof ASTNode) { 461 ASTNode invocationNode = (ASTNode) invocationSite; 462 if (invocationNode.isTypeUseDeprecated(referenceBinding, this)) { 463 problemReporter().deprecatedType(referenceBinding, invocationNode); 464 } 465 } 466 while (currentIndex < length) { 467 referenceBinding = (ReferenceBinding) binding; 468 char[] nextName = compoundName[currentIndex++]; 469 invocationSite.setFieldIndex(currentIndex); 470 invocationSite.setActualReceiverType(referenceBinding); 471 if ((mask & Binding.FIELD) != 0 && (binding = findField(referenceBinding, nextName, invocationSite, true )) != null) { 472 if (!binding.isValidBinding()) { 473 return new ProblemFieldBinding( 474 ((ProblemFieldBinding)binding).closestMatch, 475 ((ProblemFieldBinding)binding).declaringClass, 476 CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'), 477 binding.problemId()); 478 } 479 break; } 481 if ((binding = findMemberType(nextName, referenceBinding)) == null) { 482 if ((mask & Binding.FIELD) != 0) { 483 return new ProblemBinding( 484 CharOperation.subarray(compoundName, 0, currentIndex), 485 referenceBinding, 486 ProblemReasons.NotFound); 487 } 488 return new ProblemReferenceBinding( 489 CharOperation.subarray(compoundName, 0, currentIndex), 490 referenceBinding, 491 ProblemReasons.NotFound); 492 } 493 if (!binding.isValidBinding()) 495 return new ProblemReferenceBinding( 496 CharOperation.subarray(compoundName, 0, currentIndex), 497 ((ReferenceBinding)binding).closestMatch(), 498 binding.problemId()); 499 if (invocationSite instanceof ASTNode) { 500 referenceBinding = (ReferenceBinding) binding; 501 ASTNode invocationNode = (ASTNode) invocationSite; 502 if (invocationNode.isTypeUseDeprecated(referenceBinding, this)) { 503 problemReporter().deprecatedType(referenceBinding, invocationNode); 504 } 505 } 506 } 507 if ((mask & Binding.FIELD) != 0 && (binding instanceof FieldBinding)) { 508 FieldBinding field = (FieldBinding) binding; 510 if (!field.isStatic()) 511 return new ProblemFieldBinding( 512 field, 513 field.declaringClass, 514 CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'), 515 ProblemReasons.NonStaticReferenceInStaticContext); 516 return binding; 517 } 518 if ((mask & Binding.TYPE) != 0 && (binding instanceof ReferenceBinding)) { 519 return binding; 521 } 522 523 return new ProblemBinding( 525 CharOperation.subarray(compoundName, 0, currentIndex), 526 ProblemReasons.NotFound); 527 } 528 529 public final Binding getBinding(char[][] compoundName, InvocationSite invocationSite) { 531 int currentIndex = 0; 532 int length = compoundName.length; 533 Binding binding = 534 getBinding( 535 compoundName[currentIndex++], 536 Binding.VARIABLE | Binding.TYPE | Binding.PACKAGE, 537 invocationSite, 538 true ); 539 if (!binding.isValidBinding()) 540 return binding; 541 542 foundType : if (binding instanceof PackageBinding) { 543 while (currentIndex < length) { 544 PackageBinding packageBinding = (PackageBinding) binding; 545 binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]); 546 if (binding == null) { 547 if (currentIndex == length) { 548 return new ProblemReferenceBinding( 550 CharOperation.subarray(compoundName, 0, currentIndex), 551 null, 552 ProblemReasons.NotFound); 553 } 554 return new ProblemBinding( 555 CharOperation.subarray(compoundName, 0, currentIndex), 556 ProblemReasons.NotFound); 557 } 558 if (binding instanceof ReferenceBinding) { 559 if (!binding.isValidBinding()) 560 return new ProblemReferenceBinding( 561 CharOperation.subarray(compoundName, 0, currentIndex), 562 ((ReferenceBinding)binding).closestMatch(), 563 binding.problemId()); 564 if (!((ReferenceBinding) binding).canBeSeenBy(this)) 565 return new ProblemReferenceBinding( 566 CharOperation.subarray(compoundName, 0, currentIndex), 567 (ReferenceBinding) binding, 568 ProblemReasons.NotVisible); 569 break foundType; 570 } 571 } 572 return binding; 573 } 574 575 foundField : if (binding instanceof ReferenceBinding) { 576 while (currentIndex < length) { 577 ReferenceBinding typeBinding = (ReferenceBinding) binding; 578 char[] nextName = compoundName[currentIndex++]; 579 if ((binding = findField(typeBinding, nextName, invocationSite, true )) != null) { 580 if (!binding.isValidBinding()) { 581 return new ProblemFieldBinding( 582 (FieldBinding) binding, 583 ((FieldBinding) binding).declaringClass, 584 CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'), 585 binding.problemId()); 586 } 587 if (!((FieldBinding) binding).isStatic()) 588 return new ProblemFieldBinding( 589 (FieldBinding) binding, 590 ((FieldBinding) binding).declaringClass, 591 CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'), 592 ProblemReasons.NonStaticReferenceInStaticContext); 593 break foundField; } 595 if ((binding = findMemberType(nextName, typeBinding)) == null) { 596 return new ProblemBinding( 597 CharOperation.subarray(compoundName, 0, currentIndex), 598 typeBinding, 599 ProblemReasons.NotFound); 600 } 601 if (!binding.isValidBinding()) { 602 return new ProblemReferenceBinding( 603 CharOperation.subarray(compoundName, 0, currentIndex), 604 ((ReferenceBinding)binding).closestMatch(), 605 binding.problemId()); 606 } 607 } 608 return binding; 609 } 610 611 VariableBinding variableBinding = (VariableBinding) binding; 612 while (currentIndex < length) { 613 TypeBinding typeBinding = variableBinding.type; 614 if (typeBinding == null) { 615 return new ProblemFieldBinding( 616 null, 617 null, 618 CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'), 619 ProblemReasons.NotFound); 620 } 621 variableBinding = findField(typeBinding, compoundName[currentIndex++], invocationSite, true ); 622 if (variableBinding == null) { 623 return new ProblemFieldBinding( 624 null, 625 null, 626 CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'), 627 ProblemReasons.NotFound); 628 } 629 if (!variableBinding.isValidBinding()) 630 return variableBinding; 631 } 632 return variableBinding; 633 } 634 635 652 public VariableBinding[] getEmulationPath(LocalVariableBinding outerLocalVariable) { 653 MethodScope currentMethodScope = this.methodScope(); 654 SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType(); 655 656 BlockScope variableScope = outerLocalVariable.declaringScope; 658 if (variableScope == null || currentMethodScope == variableScope.methodScope()) { 659 return new VariableBinding[] { outerLocalVariable }; 660 } 662 if (currentMethodScope.isInsideInitializerOrConstructor() 664 && (sourceType.isNestedType())) { 665 SyntheticArgumentBinding syntheticArg; 666 if ((syntheticArg = ((NestedTypeBinding) sourceType).getSyntheticArgument(outerLocalVariable)) != null) { 667 return new VariableBinding[] { syntheticArg }; 668 } 669 } 670 if (!currentMethodScope.isStatic) { 672 FieldBinding syntheticField; 673 if ((syntheticField = sourceType.getSyntheticField(outerLocalVariable)) != null) { 674 return new VariableBinding[] { syntheticField }; 675 } 676 } 677 return null; 678 } 679 680 691 public Object [] getEmulationPath(ReferenceBinding targetEnclosingType, boolean onlyExactMatch, boolean denyEnclosingArgInConstructorCall) { 692 MethodScope currentMethodScope = this.methodScope(); 693 SourceTypeBinding sourceType = currentMethodScope.enclosingSourceType(); 694 695 if (!currentMethodScope.isStatic && !currentMethodScope.isConstructorCall) { 697 if (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeWithSameErasure(targetEnclosingType) != null)) { 698 return BlockScope.EmulationPathToImplicitThis; } 700 } 701 if (!sourceType.isNestedType() || sourceType.isStatic()) { if (currentMethodScope.isConstructorCall) { 703 return BlockScope.NoEnclosingInstanceInConstructorCall; 704 } else if (currentMethodScope.isStatic){ 705 return BlockScope.NoEnclosingInstanceInStaticContext; 706 } 707 return null; 708 } 709 boolean insideConstructor = currentMethodScope.isInsideInitializerOrConstructor(); 710 if (insideConstructor) { 712 SyntheticArgumentBinding syntheticArg; 713 if ((syntheticArg = ((NestedTypeBinding) sourceType).getSyntheticArgument(targetEnclosingType, onlyExactMatch)) != null) { 714 if (denyEnclosingArgInConstructorCall 716 && currentMethodScope.isConstructorCall 717 && (sourceType == targetEnclosingType || (!onlyExactMatch && sourceType.findSuperTypeWithSameErasure(targetEnclosingType) != null))) { 718 return BlockScope.NoEnclosingInstanceInConstructorCall; 719 } 720 return new Object [] { syntheticArg }; 721 } 722 } 723 724 if (currentMethodScope.isStatic) { 726 return BlockScope.NoEnclosingInstanceInStaticContext; 727 } 728 if (sourceType.isAnonymousType()) { 729 ReferenceBinding enclosingType = sourceType.enclosingType(); 730 if (enclosingType.isNestedType()) { 731 NestedTypeBinding nestedEnclosingType = (NestedTypeBinding) enclosingType; 732 SyntheticArgumentBinding enclosingArgument = nestedEnclosingType.getSyntheticArgument(nestedEnclosingType.enclosingType(), onlyExactMatch); 733 if (enclosingArgument != null) { 734 FieldBinding syntheticField = sourceType.getSyntheticField(enclosingArgument); 735 if (syntheticField != null) { 736 if (syntheticField.type == targetEnclosingType || (!onlyExactMatch && ((ReferenceBinding)syntheticField.type).findSuperTypeWithSameErasure(targetEnclosingType) != null)) 737 return new Object [] { syntheticField }; 738 } 739 } 740 } 741 } 742 FieldBinding syntheticField = sourceType.getSyntheticField(targetEnclosingType, onlyExactMatch); 743 if (syntheticField != null) { 744 if (currentMethodScope.isConstructorCall){ 745 return BlockScope.NoEnclosingInstanceInConstructorCall; 746 } 747 return new Object [] { syntheticField }; 748 } 749 750 Object [] path = new Object [2]; ReferenceBinding currentType = sourceType.enclosingType(); 753 if (insideConstructor) { 754 path[0] = ((NestedTypeBinding) sourceType).getSyntheticArgument(currentType, onlyExactMatch); 755 } else { 756 if (currentMethodScope.isConstructorCall){ 757 return BlockScope.NoEnclosingInstanceInConstructorCall; 758 } 759 path[0] = sourceType.getSyntheticField(currentType, onlyExactMatch); 760 } 761 if (path[0] != null) { 763 int count = 1; 764 ReferenceBinding currentEnclosingType; 765 while ((currentEnclosingType = currentType.enclosingType()) != null) { 766 767 if (currentType == targetEnclosingType 769 || (!onlyExactMatch && currentType.findSuperTypeWithSameErasure(targetEnclosingType) != null)) break; 770 771 if (currentMethodScope != null) { 772 currentMethodScope = currentMethodScope.enclosingMethodScope(); 773 if (currentMethodScope != null && currentMethodScope.isConstructorCall){ 774 return BlockScope.NoEnclosingInstanceInConstructorCall; 775 } 776 if (currentMethodScope != null && currentMethodScope.isStatic){ 777 return BlockScope.NoEnclosingInstanceInStaticContext; 778 } 779 } 780 781 syntheticField = ((NestedTypeBinding) currentType).getSyntheticField(currentEnclosingType, onlyExactMatch); 782 if (syntheticField == null) break; 783 784 if (count == path.length) { 786 System.arraycopy(path, 0, (path = new Object [count + 1]), 0, count); 787 } 788 path[count++] = ((SourceTypeBinding) syntheticField.declaringClass).addSyntheticMethod(syntheticField, true); 790 currentType = currentEnclosingType; 791 } 792 if (currentType == targetEnclosingType 793 || (!onlyExactMatch && currentType.findSuperTypeWithSameErasure(targetEnclosingType) != null)) { 794 return path; 795 } 796 } 797 return null; 798 } 799 800 802 public final boolean isDuplicateLocalVariable(char[] name) { 803 BlockScope current = this; 804 while (true) { 805 for (int i = 0; i < this.localIndex; i++) { 806 if (CharOperation.equals(name, current.locals[i].name)) 807 return true; 808 } 809 if (current.kind != Scope.BLOCK_SCOPE) return false; 810 current = (BlockScope)current.parent; 811 } 812 } 813 814 public int maxShiftedOffset() { 815 int max = -1; 816 if (this.shiftScopes != null){ 817 for (int i = 0, length = this.shiftScopes.length; i < length; i++){ 818 int subMaxOffset = this.shiftScopes[i].maxOffset; 819 if (subMaxOffset > max) max = subMaxOffset; 820 } 821 } 822 return max; 823 } 824 825 831 public ProblemReporter problemReporter() { 832 return outerMostMethodScope().problemReporter(); 833 } 834 835 839 public void propagateInnerEmulation(ReferenceBinding targetType, boolean isEnclosingInstanceSupplied) { 840 842 SyntheticArgumentBinding[] syntheticArguments; 843 if ((syntheticArguments = targetType.syntheticOuterLocalVariables()) != null) { 844 for (int i = 0, max = syntheticArguments.length; i < max; i++) { 845 SyntheticArgumentBinding syntheticArg = syntheticArguments[i]; 846 if (!(isEnclosingInstanceSupplied 848 && (syntheticArg.type == targetType.enclosingType()))) { 849 this.emulateOuterAccess(syntheticArg.actualOuterLocalVariable); 850 } 851 } 852 } 853 } 854 855 859 public TypeDeclaration referenceType() { 860 return methodScope().referenceType(); 861 } 862 863 867 public int scopeIndex() { 868 if (this instanceof MethodScope) return -1; 869 BlockScope parentScope = (BlockScope)this.parent; 870 Scope[] parentSubscopes = parentScope.subscopes; 871 for (int i = 0, max = parentScope.subscopeCount; i < max; i++) { 872 if (parentSubscopes[i] == this) return i; 873 } 874 return -1; 875 } 876 877 int startIndex() { 879 return this.startIndex; 880 } 881 882 public String toString() { 883 return toString(0); 884 } 885 886 public String toString(int tab) { 887 String s = basicToString(tab); 888 for (int i = 0; i < this.subscopeCount; i++) 889 if (this.subscopes[i] instanceof BlockScope) 890 s += ((BlockScope) this.subscopes[i]).toString(tab + 1) + "\n"; return s; 892 } 893 } 894 | Popular Tags |