public TypeBinding checkResolvedType(
     TypeBinding type, Scope scope, int location, boolean hasError) {
   // SH}
   if (type.isArrayType() && ((ArrayBinding) type).leafComponentType == TypeBinding.VOID) {
     scope.problemReporter().cannotAllocateVoidArray(this);
     return null;
   }
   if (!(this
           instanceof
           QualifiedTypeReference) // QualifiedTypeReference#getTypeBinding called above will have
                                   // already checked deprecation
       && isTypeUseDeprecated(type, scope)) {
     reportDeprecatedType(type, scope);
   }
   type =
       scope
           .environment()
           .convertToRawType(type, false /*do not force conversion of enclosing types*/);
   if (type.leafComponentType().isRawType()
       && (this.bits & ASTNode.IgnoreRawTypeCheck) == 0
       && scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference)
           != ProblemSeverities.Ignore) {
     scope.problemReporter().rawTypeReference(this, type);
   }
   if (hasError) {
     resolveAnnotations(scope, 0); // don't apply null defaults to buggy type
     return type;
   } else {
     // store the computed type only if no error, otherwise keep the problem type instead
     this.resolvedType = type;
     resolveAnnotations(scope, location);
     return this
         .resolvedType; // pick up value that may have been changed in resolveAnnotations(..)
   }
 }
  /**
   * After a method has substituted type parameters, check if this resulted in any contradictory
   * null annotations. Problems are either reported directly (if scope != null) or by returning a
   * ProblemMethodBinding.
   */
  public static MethodBinding checkForContraditions(
      final MethodBinding method, final InvocationSite invocationSite, final Scope scope) {

    class SearchContradictions extends TypeBindingVisitor {
      ReferenceBinding typeWithContradiction;

      @Override
      public boolean visit(ReferenceBinding referenceBinding) {
        if ((referenceBinding.tagBits & TagBits.AnnotationNullMASK) == TagBits.AnnotationNullMASK) {
          this.typeWithContradiction = referenceBinding;
          return false;
        }
        return true;
      }

      @Override
      public boolean visit(TypeVariableBinding typeVariable) {
        return visit((ReferenceBinding) typeVariable);
      }

      @Override
      public boolean visit(RawTypeBinding rawType) {
        return visit((ReferenceBinding) rawType);
      }
    }

    SearchContradictions searchContradiction = new SearchContradictions();
    TypeBindingVisitor.visit(searchContradiction, method.returnType);
    if (searchContradiction.typeWithContradiction != null) {
      if (scope == null)
        return new ProblemMethodBinding(
            method,
            method.selector,
            method.parameters,
            ProblemReasons.ContradictoryNullAnnotations);
      scope.problemReporter().contradictoryNullAnnotationsInferred(method, invocationSite);
      // note: if needed, we might want to update the method by removing the contradictory
      // annotations??
      return method;
    }

    Expression[] arguments = null;
    if (invocationSite instanceof Invocation) arguments = ((Invocation) invocationSite).arguments();
    for (int i = 0; i < method.parameters.length; i++) {
      TypeBindingVisitor.visit(searchContradiction, method.parameters[i]);
      if (searchContradiction.typeWithContradiction != null) {
        if (scope == null)
          return new ProblemMethodBinding(
              method,
              method.selector,
              method.parameters,
              ProblemReasons.ContradictoryNullAnnotations);
        if (arguments != null && i < arguments.length)
          scope.problemReporter().contradictoryNullAnnotationsInferred(method, arguments[i]);
        else scope.problemReporter().contradictoryNullAnnotationsInferred(method, invocationSite);
        return method;
      }
    }
    return method;
  }
 protected void reportDeprecatedType(TypeBinding type, Scope scope) {
   // {ObjectTeams:
   if (this.deprecationProblemId == 0) return;
   if (this.deprecationProblemId == IProblem.DeprecatedBaseclass)
     scope.problemReporter().deprecatedBaseclass(this, type);
   else
     // SH}
     scope.problemReporter().deprecatedType(type, this, Integer.MAX_VALUE);
 }
 protected void resolveAnnotations(Scope scope, int location) {
   Annotation[][] annotationsOnDimensions = getAnnotationsOnDimensions();
   if (this.annotations != null || annotationsOnDimensions != null) {
     BlockScope resolutionScope = Scope.typeAnnotationsResolutionScope(scope);
     if (resolutionScope != null) {
       int dimensions = this.dimensions();
       if (this.annotations != null) {
         TypeBinding leafComponentType = this.resolvedType.leafComponentType();
         leafComponentType =
             resolveAnnotations(resolutionScope, this.annotations, leafComponentType);
         this.resolvedType =
             dimensions > 0
                 ? scope.environment().createArrayType(leafComponentType, dimensions)
                 : leafComponentType;
         // contradictory null annotations on the type are already detected in
         // Annotation.resolveType() (SE7 treatment)
       }
       if (annotationsOnDimensions != null) {
         this.resolvedType =
             resolveAnnotations(resolutionScope, annotationsOnDimensions, this.resolvedType);
         if (this.resolvedType instanceof ArrayBinding) {
           long[] nullTagBitsPerDimension =
               ((ArrayBinding) this.resolvedType).nullTagBitsPerDimension;
           if (nullTagBitsPerDimension != null) {
             for (int i = 0;
                 i < dimensions;
                 i++) { // skip last annotations at [dimensions] (concerns the leaf type)
               if ((nullTagBitsPerDimension[i] & TagBits.AnnotationNullMASK)
                   == TagBits.AnnotationNullMASK) {
                 scope.problemReporter().contradictoryNullAnnotations(annotationsOnDimensions[i]);
                 nullTagBitsPerDimension[i] = 0;
               }
             }
           }
         }
       }
     }
   }
   if (scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled
       && this.resolvedType != null
       && (this.resolvedType.tagBits & TagBits.AnnotationNullMASK) == 0
       && !this.resolvedType.isTypeVariable()
       && !this.resolvedType.isWildcard()
       && location != 0
       && scope.hasDefaultNullnessFor(location)) {
     if (location == Binding.DefaultLocationTypeBound
         && this.resolvedType.id == TypeIds.T_JavaLangObject) {
       scope.problemReporter().implicitObjectBoundNoNullDefault(this);
     } else {
       LookupEnvironment environment = scope.environment();
       AnnotationBinding[] annots = new AnnotationBinding[] {environment.getNonNullAnnotation()};
       this.resolvedType = environment.createAnnotatedType(this.resolvedType, annots);
     }
   }
 }
 private TypeBinding createArrayType(Scope scope, TypeBinding type) {
   if (this.dimensions > 0) {
     if (this.dimensions > 255) scope.problemReporter().tooManyDimensions(this);
     return scope.createArrayType(type, this.dimensions);
   }
   return type;
 }
 /**
  * @see
  *     org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope,
  *     org.eclipse.jdt.internal.compiler.lookup.TypeBinding,
  *     org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
  */
 public void computeConversion(
     Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
   if (runtimeTimeType == null || compileTimeType == null) return;
   // set the generic cast after the fact, once the type expectation is fully known (no need for
   // strict cast)
   if (this.binding != null && this.binding.isValidBinding()) {
     FieldBinding originalBinding = this.binding.original();
     TypeBinding originalType = originalBinding.type;
     // extra cast needed if field type is type variable
     if (originalType.leafComponentType().isTypeVariable()) {
       TypeBinding targetType =
           (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
               ? compileTimeType // unboxing: checkcast before conversion
               : runtimeTimeType;
       this.genericCast = originalBinding.type.genericCast(targetType);
       if (this.genericCast instanceof ReferenceBinding) {
         ReferenceBinding referenceCast = (ReferenceBinding) this.genericCast;
         if (!referenceCast.canBeSeenBy(scope)) {
           scope
               .problemReporter()
               .invalidType(
                   this,
                   new ProblemReferenceBinding(
                       CharOperation.splitOn('.', referenceCast.shortReadableName()),
                       referenceCast,
                       ProblemReasons.NotVisible));
         }
       }
     }
   }
   super.computeConversion(scope, runtimeTimeType, compileTimeType);
 }
 /** During deferred checking re-visit a previously recording unboxing situation. */
 protected void checkUnboxing(Scope scope, Expression expression, FlowInfo flowInfo) {
   int status = expression.nullStatus(flowInfo, this);
   if ((status & FlowInfo.NULL) != 0) {
     scope.problemReporter().nullUnboxing(expression, expression.resolvedType);
     return;
   } else if ((status & FlowInfo.POTENTIALLY_NULL) != 0) {
     scope.problemReporter().potentialNullUnboxing(expression, expression.resolvedType);
     return;
   } else if ((status & FlowInfo.NON_NULL) != 0) {
     return;
   }
   // not handled, perhaps our parent will eventually have something to say?
   if (this.parent != null) {
     this.parent.recordUnboxing(scope, expression, FlowInfo.UNKNOWN, flowInfo);
   }
 }
 protected void checkIllegalNullAnnotation(Scope scope) {
   if (this.resolvedType.leafComponentType().isBaseType()
       && hasNullTypeAnnotation(AnnotationPosition.LEAF_TYPE))
     scope
         .problemReporter()
         .illegalAnnotationForBaseType(
             this, this.annotations[0], this.resolvedType.tagBits & TagBits.AnnotationNullMASK);
 }
 /**
  * Check whether this type reference conforms to the null constraints defined for the
  * corresponding type variable.
  */
 protected void checkNullConstraints(
     Scope scope, Substitution substitution, TypeBinding[] variables, int rank) {
   if (variables != null && variables.length > rank) {
     TypeBinding variable = variables[rank];
     if (variable.hasNullTypeAnnotations()) {
       if (NullAnnotationMatching.analyse(
               variable, this.resolvedType, null, substitution, -1, null, CheckMode.BOUND_CHECK)
           .isAnyMismatch())
         scope.problemReporter().nullityMismatchTypeArgument(variable, this.resolvedType, this);
     }
   }
   checkIllegalNullAnnotation(scope);
 }
Exemple #10
0
 void checkDecapsulation(ReferenceBinding baseClass, Scope scope) {
   if (!this.resolvedMethod.canBeSeenBy(baseClass, this, scope)) {
     WeavingScheme weavingScheme = scope.compilerOptions().weavingScheme;
     this.implementationStrategy =
         weavingScheme == WeavingScheme.OTDRE
             ? ImplementationStrategy.DYN_ACCESS
             : ImplementationStrategy.DECAPS_WRAPPER;
     this.accessId = createAccessAttribute(scope.enclosingSourceType().roleModel);
     scope.problemReporter().decapsulation(this, baseClass, scope);
   } else {
     this.implementationStrategy = ImplementationStrategy.DIRECT;
   }
 }
 /* check for use of protected role (for parameterized/qualified type references). */
 protected boolean isIllegalQualifiedUseOfProtectedRole(Scope scope) {
   // implies ReferenceBinding
   if (((ReferenceBinding) this.resolvedType).isProtected() // here we only check protected roles
       && !this.getBaseclassDecapsulation().isAllowed()) {
     scope.problemReporter().qualifiedProtectedRole(this, (ReferenceBinding) this.resolvedType);
     // keep a problem binding,  clients may be interested in this information, see
     // CodeSelectionTests.testRoleCreation3
     this.resolvedType =
         new ProblemReferenceBinding(
             ((ReferenceBinding) this.resolvedType).compoundName,
             (ReferenceBinding) this.resolvedType,
             ProblemReasons.NotVisible);
     return true;
   }
   return false;
 }
Exemple #12
0
  /* Answer true if the method use is considered deprecated.
   * An access in the same compilation unit is allowed.
   */
  public final boolean isMethodUseDeprecated(
      MethodBinding method, Scope scope, boolean isExplicitUse) {
    // ignore references insing Javadoc comments
    if ((this.bits & ASTNode.InsideJavadoc) == 0
        && method.isOrEnclosedByPrivateType()
        && !scope.isDefinedInMethod(method)) {
      // ignore cases where method is used from inside itself (e.g. direct recursions)
      method.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
    }

    // TODO (maxime) consider separating concerns between deprecation and access restriction.
    // 				 Caveat: this was not the case when access restriction funtion was added.
    if (isExplicitUse && (method.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
      // note: explicit constructors calls warnings are kept despite the 'new C1()' case (two
      //       warnings, one on type, the other on constructor), because of the 'super()' case.
      AccessRestriction restriction =
          scope.environment().getAccessRestriction(method.declaringClass.erasure());
      if (restriction != null) {
        scope
            .problemReporter()
            .forbiddenReference(
                method,
                this,
                restriction.classpathEntryType,
                restriction.classpathEntryName,
                restriction.getProblemId());
      }
    }

    if (!method.isViewedAsDeprecated()) return false;

    // inside same unit - no report
    if (scope.isDefinedInSameUnit(method.declaringClass)) return false;

    // non explicit use and non explicitly deprecated - no report
    if (!isExplicitUse && (method.modifiers & ClassFileConstants.AccDeprecated) == 0) {
      return false;
    }

    // if context is deprecated, may avoid reporting
    if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode
        && scope.isInsideDeprecatedCode()) return false;
    return true;
  }
Exemple #13
0
  /* Answer true if the type use is considered deprecated.
   * An access in the same compilation unit is allowed.
   */
  public final boolean isTypeUseDeprecated(TypeBinding type, Scope scope) {

    if (type.isArrayType()) {
      type = ((ArrayBinding) type).leafComponentType;
    }
    if (type.isBaseType()) return false;

    ReferenceBinding refType = (ReferenceBinding) type;
    // ignore references insing Javadoc comments
    if ((this.bits & ASTNode.InsideJavadoc) == 0
        && refType.isOrEnclosedByPrivateType()
        && !scope.isDefinedInType(refType)) {
      // ignore cases where type is used from inside itself
      ((ReferenceBinding) refType.erasure()).modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
    }

    if (refType.hasRestrictedAccess()) {
      AccessRestriction restriction = scope.environment().getAccessRestriction(type.erasure());
      if (restriction != null) {
        scope
            .problemReporter()
            .forbiddenReference(
                type,
                this,
                restriction.classpathEntryType,
                restriction.classpathEntryName,
                restriction.getProblemId());
      }
    }

    // force annotations resolution before deciding whether the type may be deprecated
    refType.initializeDeprecatedAnnotationTagBits();

    if (!refType.isViewedAsDeprecated()) return false;

    // inside same unit - no report
    if (scope.isDefinedInSameUnit(refType)) return false;

    // if context is deprecated, may avoid reporting
    if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode
        && scope.isInsideDeprecatedCode()) return false;
    return true;
  }
 protected void reportInvalidType(Scope scope) {
   // {ObjectTeams: suppress this in role feature bridge (the same will be reported against the
   // original, too):
   if (scope.isFakeMethod(FakeKind.ROLE_FEATURE_BRIDGE)) {
     scope.referenceContext().tagAsHavingErrors();
     return;
   }
   // did we misread an OT keyword as a type reference (during syntax recovery)?
   if (!scope.environment().globalOptions.isPureJava) {
     char[] token = getLastToken();
     for (int j = 0; j < IOTConstants.OT_KEYWORDS.length; j++) {
       if (CharOperation.equals(token, IOTConstants.OT_KEYWORDS[j])) {
         if (scope.referenceContext().compilationResult().hasErrors())
           return; // assume this is a secondary error
       }
     }
   }
   // SH}
   scope.problemReporter().invalidType(this, this.resolvedType);
 }
 /**
  * @see
  *     org.eclipse.jdt.internal.compiler.ast.Expression#computeConversion(org.eclipse.jdt.internal.compiler.lookup.Scope,
  *     org.eclipse.jdt.internal.compiler.lookup.TypeBinding,
  *     org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
  */
 public void computeConversion(
     Scope scope, TypeBinding runtimeTimeType, TypeBinding compileTimeType) {
   if (runtimeTimeType == null || compileTimeType == null) return;
   // set the generic cast after the fact, once the type expectation is fully known (no need for
   // strict cast)
   if (this.binding != null && this.binding.isValidBinding()) {
     MethodBinding originalBinding = this.binding.original();
     TypeBinding originalType = originalBinding.returnType;
     // extra cast needed if method return type is type variable
     if (originalType.leafComponentType().isTypeVariable()) {
       TypeBinding targetType =
           (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType())
               ? compileTimeType // unboxing: checkcast before conversion
               : runtimeTimeType;
       this.valueCast = originalType.genericCast(targetType);
     } else if (this.binding == scope.environment().arrayClone
         && runtimeTimeType.id != TypeIds.T_JavaLangObject
         && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
       // from 1.5 source level on, array#clone() resolves to array type, but codegen to
       // #clone()Object - thus require extra inserted cast
       this.valueCast = runtimeTimeType;
     }
     if (this.valueCast instanceof ReferenceBinding) {
       ReferenceBinding referenceCast = (ReferenceBinding) this.valueCast;
       if (!referenceCast.canBeSeenBy(scope)) {
         scope
             .problemReporter()
             .invalidType(
                 this,
                 new ProblemReferenceBinding(
                     CharOperation.splitOn('.', referenceCast.shortReadableName()),
                     referenceCast,
                     ProblemReasons.NotVisible));
       }
     }
   }
   super.computeConversion(scope, runtimeTimeType, compileTimeType);
 }
Exemple #16
0
  public final boolean isFieldUseDeprecated(
      FieldBinding field, Scope scope, boolean isStrictlyAssigned) {
    // ignore references insing Javadoc comments
    if ((this.bits & ASTNode.InsideJavadoc) == 0
        && !isStrictlyAssigned
        && field.isOrEnclosedByPrivateType()
        && !scope.isDefinedInField(field)) {
      // ignore cases where field is used from inside itself
      field.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
    }

    if ((field.modifiers & ExtraCompilerModifiers.AccRestrictedAccess) != 0) {
      AccessRestriction restriction =
          scope.environment().getAccessRestriction(field.declaringClass.erasure());
      if (restriction != null) {
        scope
            .problemReporter()
            .forbiddenReference(
                field,
                this,
                restriction.classpathEntryType,
                restriction.classpathEntryName,
                restriction.getProblemId());
      }
    }

    if (!field.isViewedAsDeprecated()) return false;

    // inside same unit - no report
    if (scope.isDefinedInSameUnit(field.declaringClass)) return false;

    // if context is deprecated, may avoid reporting
    if (!scope.compilerOptions().reportDeprecationInsideDeprecatedCode
        && scope.isInsideDeprecatedCode()) return false;
    return true;
  }
 /**
  * @see org.eclipse.jdt.internal.compiler.ast.Expression#tagAsUnnecessaryCast(Scope,TypeBinding)
  */
 public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) {
   // null is not instanceof Type, recognize direct scenario
   if (this.expression.resolvedType != TypeBinding.NULL)
     scope.problemReporter().unnecessaryInstanceof(this, castType);
 }
 /**
  * Record a null reference for use by deferred checks. Only looping or finally contexts really
  * record that information. The context may emit an error immediately depending on the status of
  * local against flowInfo and its nature (only looping of finally contexts defer part of the
  * checks; nonetheless, contexts that are nested into a looping or a finally context get affected
  * and delegate some checks to their enclosing context).
  *
  * @param scope the scope into which the check is performed
  * @param local the local variable involved in the check
  * @param location the location triggering the analysis, for normal null dereference this is an
  *     expression resolving to 'local', for resource leaks it is an early exit statement.
  * @param checkType the status against which the check must be performed; one of {@link
  *     #CAN_ONLY_NULL CAN_ONLY_NULL}, {@link #CAN_ONLY_NULL_NON_NULL CAN_ONLY_NULL_NON_NULL},
  *     {@link #MAY_NULL MAY_NULL}, potentially combined with a context indicator (one of {@link
  *     #IN_COMPARISON_NULL}, {@link #IN_COMPARISON_NON_NULL}, {@link #IN_ASSIGNMENT} or {@link
  *     #IN_INSTANCEOF}) and a bit to indicate whether the reference is being recorded inside an
  *     assert, {@link #HIDE_NULL_COMPARISON_WARNING}
  * @param flowInfo the flow info at the check point; deferring contexts will perform supplementary
  *     checks against flow info instances that cannot be known at the time of calling this method
  *     (they are influenced by code that follows the current point)
  */
 public void recordUsingNullReference(
     Scope scope, LocalVariableBinding local, ASTNode location, int checkType, FlowInfo flowInfo) {
   if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0 || flowInfo.isDefinitelyUnknown(local)) {
     return;
   }
   // if reference is being recorded inside an assert, we will not raise redundant null check
   // warnings
   checkType |= (this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING);
   int checkTypeWithoutHideNullWarning =
       checkType & ~FlowContext.HIDE_NULL_COMPARISON_WARNING_MASK;
   switch (checkTypeWithoutHideNullWarning) {
     case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
     case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
       if (flowInfo.isDefinitelyNonNull(local)) {
         if (checkTypeWithoutHideNullWarning
             == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
           if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
             scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
           }
           flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
         } else {
           scope.problemReporter().localVariableNonNullComparedToNull(local, location);
           flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
         }
         return;
       } else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
         return;
       }
       // $FALL-THROUGH$
     case CAN_ONLY_NULL | IN_COMPARISON_NULL:
     case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
     case CAN_ONLY_NULL | IN_ASSIGNMENT:
     case CAN_ONLY_NULL | IN_INSTANCEOF:
       Expression reference = (Expression) location;
       if (flowInfo.isDefinitelyNull(local)) {
         switch (checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
           case FlowContext.IN_COMPARISON_NULL:
             if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL)
                 && (reference.implicitConversion & TypeIds.UNBOXING)
                     != 0) { // check for auto-unboxing first and report appropriate warning
               scope.problemReporter().localVariableNullReference(local, reference);
               return;
             }
             if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
               scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
             }
             flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
             return;
           case FlowContext.IN_COMPARISON_NON_NULL:
             if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL)
                 && (reference.implicitConversion & TypeIds.UNBOXING)
                     != 0) { // check for auto-unboxing first and report appropriate warning
               scope.problemReporter().localVariableNullReference(local, reference);
               return;
             }
             scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
             flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
             return;
           case FlowContext.IN_ASSIGNMENT:
             scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
             return;
           case FlowContext.IN_INSTANCEOF:
             scope.problemReporter().localVariableNullInstanceof(local, reference);
             return;
         }
       } else if (flowInfo.isPotentiallyNull(local)) {
         switch (checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
           case FlowContext.IN_COMPARISON_NULL:
             if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL)
                 && (reference.implicitConversion & TypeIds.UNBOXING)
                     != 0) { // check for auto-unboxing first and report appropriate warning
               scope.problemReporter().localVariablePotentialNullReference(local, reference);
               return;
             }
             break;
           case FlowContext.IN_COMPARISON_NON_NULL:
             if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL)
                 && (reference.implicitConversion & TypeIds.UNBOXING)
                     != 0) { // check for auto-unboxing first and report appropriate warning
               scope.problemReporter().localVariablePotentialNullReference(local, reference);
               return;
             }
             break;
         }
       } else if (flowInfo.cannotBeDefinitelyNullOrNonNull(local)) {
         return;
       }
       break;
     case MAY_NULL:
       if (flowInfo.isDefinitelyNull(local)) {
         scope.problemReporter().localVariableNullReference(local, location);
         return;
       }
       if (flowInfo.isPotentiallyNull(local)) {
         scope.problemReporter().localVariablePotentialNullReference(local, location);
         return;
       }
       break;
     default:
       // never happens
   }
   if (this.parent != null) {
     this.parent.recordUsingNullReference(scope, local, location, checkType, flowInfo);
   }
 }
 protected TypeBinding internalResolveType(Scope scope, int location) {
   // handle the error here
   this.constant = Constant.NotAConstant;
   if (this.resolvedType != null) { // is a shared type reference which was already resolved
     if (this.resolvedType.isValidBinding()) {
       return this.resolvedType;
     } else {
       switch (this.resolvedType.problemId()) {
         case ProblemReasons.NotFound:
         case ProblemReasons.NotVisible:
         case ProblemReasons.InheritedNameHidesEnclosingName:
           TypeBinding type = this.resolvedType.closestMatch();
           if (type == null) return null;
           return scope
               .environment()
               .convertToRawType(type, false /*do not force conversion of enclosing types*/);
         default:
           return null;
       }
     }
   }
   boolean hasError;
   // {ObjectTeams: don't let SelectionNodeFound(null) prevent alternate searching strategies:
   SelectionNodeFound caughtException = null;
   TypeBinding type = null;
   try {
     // base import scope first:
     CompilationResult compilationResult = scope.referenceCompilationUnit().compilationResult();
     CompilationResult.CheckPoint cp = compilationResult.getCheckPoint(scope.referenceContext());
     try {
       type =
           checkResolveUsingBaseImportScope(
               scope, location, false); // apply TOLERATE strategy only as a last resort below
       // copied from below:
       if (type != null && type.isValidBinding()) {
         type =
             scope
                 .environment()
                 .convertToRawType(type, false /*do not force conversion of enclosing types*/);
         if (type.leafComponentType().isRawType()
             && (this.bits & ASTNode.IgnoreRawTypeCheck) == 0
             && scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference)
                 != ProblemSeverities.Ignore) {
           scope.problemReporter().rawTypeReference(this, type);
         }
         return type;
       }
     } catch (SelectionNodeFound snf) {
       if (snf.binding != null) throw snf; // found a valid node.
       caughtException = snf;
     } finally {
       if (caughtException != null || (type == null) || !type.isValidBinding())
         compilationResult.rollBack(cp);
     }
     // ~orig~:
     type = this.resolvedType = getTypeBinding(scope);
     if (type == null) {
       return null; // detected cycle while resolving hierarchy
     }
     // :~giro~
   } catch (SelectionNodeFound snf) {
     if (snf.binding != null) throw snf; // found a valid node.
     caughtException = snf;
   }
   // a third chance trying an anchored type:
   try {
     if ((caughtException != null) || (this.resolvedType.problemId() == ProblemReasons.NotFound)) {
       // anchored type
       TypeBinding result = resolveAnchoredType(scope);
       if (result != null) // did we do any better than before?
       type = this.resolvedType = result; // if non-null but ProblemBinding report below.
     }
   } catch (SelectionNodeFound snf2) {
     caughtException = snf2; // throw the newer exception instead.
   }
   // a forth chance trying a TOLERATED base imported type:
   try {
     if ((caughtException != null) || (this.resolvedType.problemId() == ProblemReasons.NotFound)) {
       if (this.baseclassDecapsulation == DecapsulationState.TOLERATED) {
         TypeBinding result = checkResolveUsingBaseImportScope(scope, -1, true);
         if (result != null) // did we do any better than before?
         type = this.resolvedType = result; // if non-null but ProblemBinding report below.
       }
     }
   } catch (SelectionNodeFound snf2) {
     caughtException = snf2; // throw the newer exception instead.
   } finally {
     // the attempt to prevent an exception failed:
     if (caughtException != null) throw caughtException;
   }
   // SH}
   if ((hasError = !type.isValidBinding()) == true) {
     reportInvalidType(scope);
     switch (type.problemId()) {
       case ProblemReasons.NotFound:
       case ProblemReasons.NotVisible:
       case ProblemReasons.InheritedNameHidesEnclosingName:
         type = type.closestMatch();
         if (type == null) return null;
         break;
       default:
         return null;
     }
   }
   // {ObjectTeams: Split method to make tail accessible:
   return checkResolvedType(type, scope, location, hasError);
 }
 protected void reportDeprecatedType(TypeBinding type, Scope scope, int index) {
   scope.problemReporter().deprecatedType(type, this, index);
 }
  private TypeBinding internalResolveLeafType(
      Scope scope, ReferenceBinding enclosingType, boolean checkBounds) {
    ReferenceBinding currentType;
    if (enclosingType == null) {
      this.resolvedType = scope.getType(this.token);
      if (this.resolvedType.isValidBinding()) {
        currentType = (ReferenceBinding) this.resolvedType;
      } else {
        reportInvalidType(scope);
        switch (this.resolvedType.problemId()) {
          case ProblemReasons.NotFound:
          case ProblemReasons.NotVisible:
          case ProblemReasons.InheritedNameHidesEnclosingName:
            TypeBinding type = this.resolvedType.closestMatch();
            if (type instanceof ReferenceBinding) {
              currentType = (ReferenceBinding) type;
              break;
            }
            // $FALL-THROUGH$ - unable to complete type binding, but still resolve type arguments
          default:
            boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
            int argLength = this.typeArguments.length;
            for (int i = 0; i < argLength; i++) {
              TypeReference typeArgument = this.typeArguments[i];
              if (isClassScope) {
                typeArgument.resolveType((ClassScope) scope);
              } else {
                typeArgument.resolveType((BlockScope) scope, checkBounds);
              }
            }
            return null;
        }
        // be resilient, still attempt resolving arguments
      }
      enclosingType = currentType.enclosingType(); // if member type
      if (enclosingType != null) {
        enclosingType =
            currentType.isStatic()
                ? (ReferenceBinding)
                    scope
                        .environment()
                        .convertToRawType(
                            enclosingType, false /*do not force conversion of enclosing types*/)
                : scope.environment().convertToParameterizedType(enclosingType);
        currentType =
            scope
                .environment()
                .createParameterizedType(
                    (ReferenceBinding) currentType.erasure(), null /* no arg */, enclosingType);
      }
    } else { // resolving member type (relatively to enclosingType)
      this.resolvedType = currentType = scope.getMemberType(this.token, enclosingType);
      if (!this.resolvedType.isValidBinding()) {
        scope.problemReporter().invalidEnclosingType(this, currentType, enclosingType);
        return null;
      }
      if (isTypeUseDeprecated(currentType, scope))
        scope.problemReporter().deprecatedType(currentType, this);
      ReferenceBinding currentEnclosing = currentType.enclosingType();
      if (currentEnclosing != null && currentEnclosing.erasure() != enclosingType.erasure()) {
        enclosingType =
            currentEnclosing; // inherited member type, leave it associated with its enclosing
                              // rather than subtype
      }
    }

    // check generic and arity
    boolean isClassScope = scope.kind == Scope.CLASS_SCOPE;
    TypeReference keep = null;
    if (isClassScope) {
      keep = ((ClassScope) scope).superTypeReference;
      ((ClassScope) scope).superTypeReference = null;
    }
    int argLength = this.typeArguments.length;
    TypeBinding[] argTypes = new TypeBinding[argLength];
    boolean argHasError = false;
    ReferenceBinding currentOriginal = (ReferenceBinding) currentType.original();
    for (int i = 0; i < argLength; i++) {
      TypeReference typeArgument = this.typeArguments[i];
      TypeBinding argType =
          isClassScope
              ? typeArgument.resolveTypeArgument((ClassScope) scope, currentOriginal, i)
              : typeArgument.resolveTypeArgument((BlockScope) scope, currentOriginal, i);
      this.bits |= (typeArgument.bits & ASTNode.HasTypeAnnotations);
      if (argType == null) {
        argHasError = true;
      } else {
        if (typeArgument.annotations != null)
          argTypes[i] =
              captureTypeAnnotations(scope, enclosingType, argType, typeArgument.annotations[0]);
        else argTypes[i] = argType;
      }
    }
    if (argHasError) {
      return null;
    }
    if (isClassScope) {
      ((ClassScope) scope).superTypeReference = keep;
      if (((ClassScope) scope).detectHierarchyCycle(currentOriginal, this)) return null;
    }

    final boolean isDiamond = (this.bits & ASTNode.IsDiamond) != 0;
    TypeVariableBinding[] typeVariables = currentOriginal.typeVariables();
    if (typeVariables == Binding.NO_TYPE_VARIABLES) { // non generic invoked with arguments
      boolean isCompliant15 =
          scope.compilerOptions().originalSourceLevel >= ClassFileConstants.JDK1_5;
      if ((currentOriginal.tagBits & TagBits.HasMissingType) == 0) {
        if (isCompliant15) { // below 1.5, already reported as syntax error
          this.resolvedType = currentType;
          scope
              .problemReporter()
              .nonGenericTypeCannotBeParameterized(0, this, currentType, argTypes);
          return null;
        }
      }
      // resilience do not rebuild a parameterized type unless compliance is allowing it
      if (!isCompliant15) {
        if (!this.resolvedType.isValidBinding()) return currentType;
        return this.resolvedType = currentType;
      }
      // if missing generic type, and compliance >= 1.5, then will rebuild a parameterized binding
    } else if (argLength != typeVariables.length) {
      if (!isDiamond) { // check arity, IsDiamond never set for 1.6-
        scope.problemReporter().incorrectArityForParameterizedType(this, currentType, argTypes);
        return null;
      }
    } else if (!currentType.isStatic()) {
      ReferenceBinding actualEnclosing = currentType.enclosingType();
      if (actualEnclosing != null && actualEnclosing.isRawType()) {
        scope
            .problemReporter()
            .rawMemberTypeCannotBeParameterized(
                this,
                scope.environment().createRawType(currentOriginal, actualEnclosing),
                argTypes);
        return null;
      }
    }

    ParameterizedTypeBinding parameterizedType =
        scope.environment().createParameterizedType(currentOriginal, argTypes, enclosingType);
    // check argument type compatibility for non <> cases - <> case needs no bounds check, we will
    // scream foul if needed during inference.
    if (!isDiamond) {
      if (checkBounds) // otherwise will do it in Scope.connectTypeVariables() or generic method
                       // resolution
      parameterizedType.boundCheck(scope, this.typeArguments);
      else scope.deferBoundCheck(this);
    }
    if (isTypeUseDeprecated(parameterizedType, scope))
      reportDeprecatedType(parameterizedType, scope);

    if (!this.resolvedType.isValidBinding()) {
      return parameterizedType;
    }
    return this.resolvedType = parameterizedType;
  }