/** @see IMethodBinding#overrides(IMethodBinding) */
 public boolean overrides(IMethodBinding otherMethod) {
   LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
   return lookupEnvironment != null
       && lookupEnvironment
           .methodVerifier()
           .doesMethodOverride(this.binding, ((MethodBinding) otherMethod).binding);
 }
Example #2
0
 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);
     }
   }
 }
 public boolean isSubsignature(IMethodBinding otherMethod) {
   try {
     LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
     return lookupEnvironment != null
         && lookupEnvironment
             .methodVerifier()
             .isMethodSubsignature(this.binding, ((MethodBinding) otherMethod).binding);
   } catch (AbortCompilation e) {
     // don't surface internal exception to clients
     // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=143013
     return false;
   }
 }
  public static ReferenceBinding resolveType(LookupEnvironment lookupEnvironment, String typeName) {
    ReferenceBinding type = null;

    int p = typeName.indexOf('$');
    if (p > 0) {
      // resolve an outer type before trying to get the cached inner
      String cupName = typeName.substring(0, p);
      char[][] chars = CharOperation.splitOn('.', cupName.toCharArray());
      ReferenceBinding outerType = lookupEnvironment.getType(chars);
      if (outerType != null) {
        // outer class was found
        resolveRecursive(outerType);
        chars = CharOperation.splitOn('.', typeName.toCharArray());
        type = lookupEnvironment.getCachedType(chars);
        if (type == null) {
          // no inner type; this is a pure failure
          return null;
        }
      }
    } else {
      // just resolve the type straight out
      char[][] chars = CharOperation.splitOn('.', typeName.toCharArray());
      type = lookupEnvironment.getType(chars);
    }

    if (type != null) {
      if (type instanceof UnresolvedReferenceBinding) {
        /*
         * Since type is an instance of UnresolvedReferenceBinding, we know that
         * the return value BinaryTypeBinding.resolveType will be of type
         * ReferenceBinding
         */
        type = (ReferenceBinding) BinaryTypeBinding.resolveType(type, lookupEnvironment, true);
      }
      // found it
      return type;
    }

    // Assume that the last '.' should be '$' and try again.
    //
    p = typeName.lastIndexOf('.');
    if (p >= 0) {
      typeName = typeName.substring(0, p) + "$" + typeName.substring(p + 1);
      return resolveType(lookupEnvironment, typeName);
    }

    return null;
  }
  /**
   * This test checks if {@link INameEnvironment#findType(char[], char[][])} is executed.
   * INameEnvironment has no option to avoid the search for secondary types, therefore the search
   * for secondary types is executed (when available).
   */
  public void test03() {
    NameEnvironmentDummy nameEnv = new NameEnvironmentDummy(false);

    LookupEnvironment lookupEnv = new LookupEnvironment(null, new CompilerOptions(), null, nameEnv);
    PackageBinding packageBinding =
        lookupEnv.createPackage(
            new char[][] {
              "org/eclipse/jdt".toCharArray(), "org/eclipse/jdt/internal".toCharArray()
            });
    assertNotNull(packageBinding);

    assertTrue(
        nameEnv
            .isTypeSearchExecuted); // the method findType(char[], char[][]) should got executed
                                    // (without an option to avoid the search for secondary types)
  }
 /**
  * Feed null information from argument annotations into the analysis and mark arguments as
  * assigned.
  */
 static void analyseArguments(
     LookupEnvironment environment,
     FlowInfo flowInfo,
     Argument[] methodArguments,
     MethodBinding methodBinding) {
   if (methodArguments != null) {
     boolean usesNullTypeAnnotations = environment.usesNullTypeAnnotations();
     int length = Math.min(methodBinding.parameters.length, methodArguments.length);
     for (int i = 0; i < length; i++) {
       if (usesNullTypeAnnotations) {
         // leverage null type annotations:
         long tagBits = methodBinding.parameters[i].tagBits & TagBits.AnnotationNullMASK;
         if (tagBits == TagBits.AnnotationNonNull)
           flowInfo.markAsDefinitelyNonNull(methodArguments[i].binding);
         else if (tagBits == TagBits.AnnotationNullable)
           flowInfo.markPotentiallyNullBit(methodArguments[i].binding);
       } else {
         if (methodBinding.parameterNonNullness != null) {
           // leverage null-info from parameter annotations:
           Boolean nonNullNess = methodBinding.parameterNonNullness[i];
           if (nonNullNess != null) {
             if (nonNullNess.booleanValue())
               flowInfo.markAsDefinitelyNonNull(methodArguments[i].binding);
             else flowInfo.markPotentiallyNullBit(methodArguments[i].binding);
           }
         }
       }
       // tag parameters as being set:
       flowInfo.markAsDefinitelyAssigned(methodArguments[i].binding);
     }
   }
 }
  /**
   * This test checks if types are searched on creating a package, but without the search for
   * secondary types. It isn't necessary to search for secondary types when creating a package,
   * because a package name can not collide with a secondary type. The search for secondary types
   * should not get executed, because the search for secondary types is very expensive regarding
   * performance (all classes of a package have to get loaded, parsed and analyzed).
   */
  public void test04() {
    NameEnvironmentWithProgressDummy nameEnvWithProgress = new NameEnvironmentWithProgressDummy();

    LookupEnvironment lookupEnv =
        new LookupEnvironment(null, new CompilerOptions(), null, nameEnvWithProgress);
    PackageBinding packageBinding =
        lookupEnv.createPackage(
            new char[][] {
              "org/eclipse/jdt".toCharArray(), "org/eclipse/jdt/internal".toCharArray()
            });
    assertNotNull(packageBinding);

    assertTrue(
        nameEnvWithProgress
            .isTypeSearchExecutedWithSearchWithSecondaryTypes); // the method findType(char[],
                                                                // char[][], boolean) should got
                                                                // executed ...
    assertFalse(
        nameEnvWithProgress
            .isTypeSearchWithSearchWithSecondaryTypes); // ... but without the search for secondary
                                                        // types
  }
Example #8
0
  /* (non-Javadoc)
   * @see IMethodBinding#overrides(IMethodBinding)
   */
  public boolean overrides(IMethodBinding overridenMethod) {
    org.eclipse.jdt.internal.compiler.lookup.MethodBinding overridenCompilerBinding =
        ((MethodBinding) overridenMethod).binding;
    if (this.binding == overridenCompilerBinding) return false;
    if (!CharOperation.equals(this.binding.selector, overridenCompilerBinding.selector))
      return false;
    ReferenceBinding match =
        this.binding.declaringClass.findSuperTypeWithSameErasure(
            overridenCompilerBinding.declaringClass);
    if (match == null) return false;

    org.eclipse.jdt.internal.compiler.lookup.MethodBinding[] superMethods = match.methods();
    for (int i = 0, length = superMethods.length; i < length; i++) {
      if (superMethods[i].original() == overridenCompilerBinding) {
        LookupEnvironment lookupEnvironment = this.resolver.lookupEnvironment();
        if (lookupEnvironment == null) return false;
        MethodVerifier methodVerifier = lookupEnvironment.methodVerifier();
        return methodVerifier.doesMethodOverride(this.binding, superMethods[i]);
      }
    }
    return false;
  }
Example #9
0
 public boolean checkUnsafeCast(
     Scope scope,
     TypeBinding castType,
     TypeBinding expressionType,
     TypeBinding match,
     boolean isNarrowing) {
   if (match == castType) {
     if (!isNarrowing
         && match
             == this.resolvedType
                 .leafComponentType()) { // do not tag as unnecessary when recursing through upper
       // bounds
       tagAsUnnecessaryCast(scope, castType);
     }
     return true;
   }
   if (match != null) {
     if (isNarrowing
         ? match.isProvablyDistinct(expressionType)
         : castType.isProvablyDistinct(match)) {
       return false;
     }
   }
   switch (castType.kind()) {
     case Binding.PARAMETERIZED_TYPE:
       if (castType.isBoundParameterizedType()) {
         if (match == null) { // unrelated types
           this.bits |= ASTNode.UnsafeCast;
           return true;
         }
         switch (match.kind()) {
           case Binding.PARAMETERIZED_TYPE:
             if (isNarrowing) {
               // [JLS 5.5] T <: S
               if (expressionType.isRawType() || !expressionType.isEquivalentTo(match)) {
                 this.bits |= ASTNode.UnsafeCast;
                 return true;
               }
               // [JLS 5.5] S has no subtype X != T, such that |X| == |T|
               // if I2<T,U> extends I1<T>, then cast from I1<T> to I2<T,U> is unchecked
               ParameterizedTypeBinding paramCastType = (ParameterizedTypeBinding) castType;
               ParameterizedTypeBinding paramMatch = (ParameterizedTypeBinding) match;
               // easy case if less parameters on match
               TypeBinding[] castArguments = paramCastType.arguments;
               int length = castArguments.length;
               if (paramMatch.arguments == null || length > paramMatch.arguments.length) {
                 this.bits |= ASTNode.UnsafeCast;
               } else if ((paramCastType.tagBits
                       & (TagBits.HasDirectWildcard | TagBits.HasTypeVariable))
                   != 0) {
                 // verify alternate cast type, substituting different type arguments
                 nextAlternateArgument:
                 for (int i = 0; i < length; i++) {
                   switch (castArguments[i].kind()) {
                     case Binding.WILDCARD_TYPE:
                     case Binding.TYPE_PARAMETER:
                       break; // check substituting with other
                     default:
                       continue nextAlternateArgument; // no alternative possible
                   }
                   TypeBinding[] alternateArguments;
                   // need to clone for each iteration to avoid env paramtype cache interference
                   System.arraycopy(
                       paramCastType.arguments,
                       0,
                       alternateArguments = new TypeBinding[length],
                       0,
                       length);
                   alternateArguments[i] = scope.getJavaLangObject();
                   LookupEnvironment environment = scope.environment();
                   ParameterizedTypeBinding alternateCastType =
                       environment.createParameterizedType(
                           (ReferenceBinding) castType.erasure(),
                           alternateArguments,
                           castType.enclosingType());
                   if (alternateCastType.findSuperTypeOriginatingFrom(expressionType) == match) {
                     this.bits |= ASTNode.UnsafeCast;
                     break;
                   }
                 }
               }
               return true;
             } else {
               // [JLS 5.5] T >: S
               if (!match.isEquivalentTo(castType)) {
                 this.bits |= ASTNode.UnsafeCast;
                 return true;
               }
             }
             break;
           case Binding.RAW_TYPE:
             this.bits |=
                 ASTNode.UnsafeCast; // upcast since castType is known to be bound paramType
             return true;
           default:
             if (isNarrowing) {
               // match is not parameterized or raw, then any other subtype of match will erase  to
               // |T|
               this.bits |= ASTNode.UnsafeCast;
               return true;
             }
             break;
         }
       }
       break;
     case Binding.ARRAY_TYPE:
       TypeBinding leafType = castType.leafComponentType();
       if (isNarrowing && (leafType.isBoundParameterizedType() || leafType.isTypeVariable())) {
         this.bits |= ASTNode.UnsafeCast;
         return true;
       }
       break;
     case Binding.TYPE_PARAMETER:
       this.bits |= ASTNode.UnsafeCast;
       return true;
   }
   if (!isNarrowing
       && match
           == this.resolvedType
               .leafComponentType()) { // do not tag as unnecessary when recursing through upper
     // bounds
     tagAsUnnecessaryCast(scope, castType);
   }
   return true;
 }
  public TypeBinding resolveType(BlockScope scope) {

    this.constant = Constant.NotAConstant;
    if ((this.targetType = this.type.resolveType(scope, true /* check bounds*/)) == null)
      return null;

    /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=320463
      https://bugs.eclipse.org/bugs/show_bug.cgi?id=312076
      JLS3 15.8.2 forbids the type named in the class literal expression from being a parameterized type.
      And the grammar in 18.1 disallows (where X and Y are some concrete types) constructs of the form
      Outer<X>.class, Outer<X>.Inner.class, Outer.Inner<X>.class, Outer<X>.Inner<Y>.class etc.
      Corollary wise, we should resolve the type of the class literal expression to be a raw type as
      class literals exist only for the raw underlying type.
    */
    LookupEnvironment environment = scope.environment();
    this.targetType =
        environment.convertToRawType(
            this.targetType, true /* force conversion of enclosing types*/);

    if (this.targetType.isArrayType()) {
      ArrayBinding arrayBinding = (ArrayBinding) this.targetType;
      TypeBinding leafComponentType = arrayBinding.leafComponentType;
      if (leafComponentType == TypeBinding.VOID) {
        scope.problemReporter().cannotAllocateVoidArray(this);
        return null;
      } else if (leafComponentType.isTypeVariable()) {
        scope
            .problemReporter()
            .illegalClassLiteralForTypeVariable((TypeVariableBinding) leafComponentType, this);
      }
    } else if (this.targetType.isTypeVariable()) {
      scope
          .problemReporter()
          .illegalClassLiteralForTypeVariable((TypeVariableBinding) this.targetType, this);
    }
    // {ObjectTeams: do we need a RoleClassLiteralAccess?
    if (this.targetType instanceof ReferenceBinding) {
      ReferenceBinding targetRef = (ReferenceBinding) this.targetType;
      if (targetRef.isRole()) {
        if (this.verbatim) {
          this.targetType =
              RoleTypeCreator.maybeWrapUnqualifiedRoleType(scope, this.targetType, this);
        } else {
          SourceTypeBinding site = scope.enclosingSourceType();
          if (scope.methodScope().isStatic // role class literal needs team instance
              && !site.isRole() // static role method are OK.
              && !RoleTypeBinding.isRoleWithExplicitAnchor(this.targetType)) // t.R.class?
          {
            scope.problemReporter().roleClassLiteralLacksTeamInstance(this, targetRef);
            return null;
          }
          ReferenceBinding teamBinding;
          if (RoleTypeBinding.isRoleWithExplicitAnchor(targetRef))
            teamBinding = targetRef.enclosingType();
          else teamBinding = TeamModel.findEnclosingTeamContainingRole(site, targetRef);
          if (teamBinding == null)
            scope.problemReporter().externalizedRoleClassLiteral(this, targetRef);
          else {
            TypeBinding methodType =
                RoleClassLiteralAccess.ensureGetClassMethod(
                    teamBinding.getTeamModel(),
                    targetRef.roleModel); // not affected by visibility check (for resilience)
            this.roleClassLiteralAccess = new RoleClassLiteralAccess(this, methodType);
            this.resolvedType = this.roleClassLiteralAccess.resolveType(scope);
          }
          return this.resolvedType;
        }
      }
    }
    // SH}
    ReferenceBinding classType = scope.getJavaLangClass();
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=328689
    if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
      // Integer.class --> Class<Integer>, perform boxing of base types (int.class -->
      // Class<Integer>)
      TypeBinding boxedType = null;
      if (this.targetType.id == T_void) {
        boxedType = environment.getResolvedType(JAVA_LANG_VOID, scope);
      } else {
        boxedType = scope.boxing(this.targetType);
      }
      if (environment.usesNullTypeAnnotations())
        boxedType =
            environment.createAnnotatedType(
                boxedType, new AnnotationBinding[] {environment.getNonNullAnnotation()});
      this.resolvedType =
          environment.createParameterizedType(
              classType, new TypeBinding[] {boxedType}, null /*not a member*/);
    } else {
      this.resolvedType = classType;
    }
    return this.resolvedType;
  }