public void collectSubstitutes(Scope var1, TypeBinding var2, InferenceContext var3, int var4) {
   if (this.declaringElement == var3.genericMethod) {
     switch (var2.kind()) {
       case 132:
         if (var2 == TypeBinding.field_187) {
           return;
         } else {
           TypeBinding var5 = var1.environment().method_486(var2);
           if (var5 == var2) {
             return;
           } else {
             var2 = var5;
           }
         }
       case 516:
         return;
       default:
         byte var6;
         switch (var4) {
           case 0:
             var6 = 0;
             break;
           case 1:
             var6 = 2;
             break;
           default:
             var6 = 1;
         }
         var3.recordSubstitute(this, var2, var6);
     }
   }
 }
Exemple #2
0
  private static int checkInvocationArgument(
      BlockScope scope,
      Expression argument,
      TypeBinding parameterType,
      TypeBinding argumentType,
      TypeBinding originalParameterType) {
    argument.computeConversion(scope, parameterType, argumentType);

    if (argumentType != TypeBinding.NULL
        && parameterType.kind() == Binding.WILDCARD_TYPE) { // intersection types are tolerated
      WildcardBinding wildcard = (WildcardBinding) parameterType;
      if (wildcard.boundKind != Wildcard.SUPER) {
        return INVOCATION_ARGUMENT_WILDCARD;
      }
    }
    TypeBinding checkedParameterType =
        parameterType; // originalParameterType == null ? parameterType : originalParameterType;
    if (argumentType != checkedParameterType
        && argumentType.needsUncheckedConversion(checkedParameterType)) {
      scope.problemReporter().unsafeTypeConversion(argument, argumentType, checkedParameterType);
      return INVOCATION_ARGUMENT_UNCHECKED;
    }
    return INVOCATION_ARGUMENT_OK;
  }
Exemple #3
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 int boundCheck(Substitution var1, TypeBinding var2) {
   if (var2 != TypeBinding.field_187 && var2 != this) {
     boolean var3 = var1 != null;
     if (!(var2 instanceof ReferenceBinding) && !var2.method_147()) {
       return 2;
     } else if (this.superclass == null) {
       return 0;
     } else {
       TypeBinding var8;
       if (var2.kind() != 516) {
         boolean var14 = false;
         if (this.superclass.id != 1) {
           Object var15 = var3 ? Scope.substitute(var1, this.superclass) : this.superclass;
           if (var15 != var2) {
             if (!var2.isCompatibleWith((TypeBinding) var15)) {
               return 2;
             }
             TypeBinding var18 = var2.method_140((TypeBinding) var15);
             if (var18 != null && var18.method_166() && ((TypeBinding) var15).method_149()) {
               var14 = true;
             }
           }
         }
         int var16 = 0;
         for (int var17 = this.superInterfaces.length; var16 < var17; ++var16) {
           Object var19 =
               var3
                   ? Scope.substitute(var1, this.superInterfaces[var16])
                   : this.superInterfaces[var16];
           if (var19 != var2) {
             if (!var2.isCompatibleWith((TypeBinding) var19)) {
               return 2;
             }
             var8 = var2.method_140((TypeBinding) var19);
             if (var8 != null && var8.method_166() && ((TypeBinding) var19).method_149()) {
               var14 = true;
             }
           }
         }
         return var14 ? 1 : 0;
       } else {
         WildcardBinding var4 = (WildcardBinding) var2;
         switch (var4.field_215) {
           case 1:
             TypeBinding var5 = var4.bound;
             if (var5 == this) {
               return 0;
             } else {
               ReferenceBinding var6 =
                   var3
                       ? (ReferenceBinding) Scope.substitute(var1, this.superclass)
                       : this.superclass;
               boolean var7 = var5.method_147();
               if (!var5.method_157() && var6.id != 1) {
                 if (var7) {
                   if (!var5.isCompatibleWith(var6)) {
                     return 2;
                   }
                 } else {
                   var8 = var5.method_140(var6);
                   if (var8 != null) {
                     if (var6.method_164(var8)) {
                       return 2;
                     }
                   } else {
                     var8 = var6.method_140(var5);
                     if (var8 != null) {
                       if (var8.method_164(var5)) {
                         return 2;
                       }
                     } else if (!var5.method_169() && !var6.method_169()) {
                       return 2;
                     }
                   }
                 }
               }
               ReferenceBinding[] var20 =
                   var3 ? Scope.substitute(var1, this.superInterfaces) : this.superInterfaces;
               int var9 = var20.length;
               boolean var10 = var7 || ((ReferenceBinding) var5).method_221();
               for (int var11 = 0; var11 < var9; ++var11) {
                 ReferenceBinding var12 = var20[var11];
                 if (var7) {
                   if (!var5.isCompatibleWith(var12)) {
                     return 2;
                   }
                 } else {
                   TypeBinding var13 = var5.method_140(var12);
                   if (var13 != null) {
                     if (var12.method_164(var13)) {
                       return 2;
                     }
                   } else if (var10) {
                     return 2;
                   }
                 }
               }
             }
           case 0:
           default:
             return 0;
           case 2:
             return this.boundCheck(var1, var4.bound);
         }
       }
     }
   } else {
     return 0;
   }
 }
  static boolean isEqual(
      org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding,
      org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding2,
      HashSet visitedTypes) {
    if (typeBinding == typeBinding2) return true;
    if (typeBinding == null || typeBinding2 == null) return false;

    switch (typeBinding.kind()) {
      case Binding.BASE_TYPE:
        if (!typeBinding2.isBaseType()) {
          return false;
        }
        return typeBinding.id == typeBinding2.id;

      case Binding.ARRAY_TYPE:
        if (!typeBinding2.isArrayType()) {
          return false;
        }
        return typeBinding.dimensions() == typeBinding2.dimensions()
            && isEqual(
                typeBinding.leafComponentType(), typeBinding2.leafComponentType(), visitedTypes);

      case Binding.PARAMETERIZED_TYPE:
        if (!typeBinding2.isParameterizedType()) {
          return false;
        }
        ParameterizedTypeBinding parameterizedTypeBinding = (ParameterizedTypeBinding) typeBinding;
        ParameterizedTypeBinding parameterizedTypeBinding2 =
            (ParameterizedTypeBinding) typeBinding2;
        return CharOperation.equals(
                parameterizedTypeBinding.compoundName, parameterizedTypeBinding2.compoundName)
            && (parameterizedTypeBinding.modifiers
                    & (ExtraCompilerModifiers.AccJustFlag
                        | ClassFileConstants.AccInterface
                        | ClassFileConstants.AccEnum
                        | ClassFileConstants.AccAnnotation))
                == (parameterizedTypeBinding2.modifiers
                    & (ExtraCompilerModifiers.AccJustFlag
                        | ClassFileConstants.AccInterface
                        | ClassFileConstants.AccEnum
                        | ClassFileConstants.AccAnnotation))
            && isEqual(
                parameterizedTypeBinding.arguments,
                parameterizedTypeBinding2.arguments,
                visitedTypes)
            && isEqual(
                parameterizedTypeBinding.enclosingType(),
                parameterizedTypeBinding2.enclosingType(),
                visitedTypes);

      case Binding.WILDCARD_TYPE:
        if (typeBinding2.kind() != Binding.WILDCARD_TYPE) {
          return false;
        }
        WildcardBinding wildcardBinding = (WildcardBinding) typeBinding;
        WildcardBinding wildcardBinding2 = (WildcardBinding) typeBinding2;
        return isEqual(wildcardBinding.bound, wildcardBinding2.bound, visitedTypes)
            && wildcardBinding.boundKind == wildcardBinding2.boundKind;

      case Binding.INTERSECTION_TYPE:
        if (typeBinding2.kind() != Binding.INTERSECTION_TYPE) {
          return false;
        }
        WildcardBinding intersectionBinding = (WildcardBinding) typeBinding;
        WildcardBinding intersectionBinding2 = (WildcardBinding) typeBinding2;
        return isEqual(intersectionBinding.bound, intersectionBinding2.bound, visitedTypes)
            && isEqual(
                intersectionBinding.otherBounds, intersectionBinding2.otherBounds, visitedTypes);

      case Binding.TYPE_PARAMETER:
        if (!(typeBinding2.isTypeVariable())) {
          return false;
        }
        if (typeBinding.isCapture()) {
          if (!(typeBinding2.isCapture())) {
            return false;
          }
          CaptureBinding captureBinding = (CaptureBinding) typeBinding;
          CaptureBinding captureBinding2 = (CaptureBinding) typeBinding2;
          if (captureBinding.position == captureBinding2.position) {
            if (visitedTypes.contains(typeBinding)) return true;
            visitedTypes.add(typeBinding);

            return isEqual(captureBinding.wildcard, captureBinding2.wildcard, visitedTypes)
                && isEqual(captureBinding.sourceType, captureBinding2.sourceType, visitedTypes);
          }
          return false;
        }
        TypeVariableBinding typeVariableBinding = (TypeVariableBinding) typeBinding;
        TypeVariableBinding typeVariableBinding2 = (TypeVariableBinding) typeBinding2;
        if (CharOperation.equals(typeVariableBinding.sourceName, typeVariableBinding2.sourceName)) {
          if (visitedTypes.contains(typeBinding)) return true;
          visitedTypes.add(typeBinding);

          return isEqual(
                  typeVariableBinding.declaringElement,
                  typeVariableBinding2.declaringElement,
                  visitedTypes)
              && isEqual(
                  typeVariableBinding.superclass(), typeVariableBinding2.superclass(), visitedTypes)
              && isEqual(
                  typeVariableBinding.superInterfaces(),
                  typeVariableBinding2.superInterfaces(),
                  visitedTypes);
        }
        return false;
      case Binding.GENERIC_TYPE:
        if (!typeBinding2.isGenericType()) {
          return false;
        }
        ReferenceBinding referenceBinding = (ReferenceBinding) typeBinding;
        ReferenceBinding referenceBinding2 = (ReferenceBinding) typeBinding2;
        return CharOperation.equals(referenceBinding.compoundName, referenceBinding2.compoundName)
            && (referenceBinding.modifiers
                    & (ExtraCompilerModifiers.AccJustFlag
                        | ClassFileConstants.AccInterface
                        | ClassFileConstants.AccEnum
                        | ClassFileConstants.AccAnnotation))
                == (referenceBinding2.modifiers
                    & (ExtraCompilerModifiers.AccJustFlag
                        | ClassFileConstants.AccInterface
                        | ClassFileConstants.AccEnum
                        | ClassFileConstants.AccAnnotation))
            && isEqual(
                referenceBinding.typeVariables(), referenceBinding2.typeVariables(), visitedTypes)
            && isEqual(
                referenceBinding.enclosingType(), referenceBinding2.enclosingType(), visitedTypes);

      case Binding.RAW_TYPE:
      default:
        if (!(typeBinding2 instanceof ReferenceBinding)) {
          return false;
        }
        referenceBinding = (ReferenceBinding) typeBinding;
        referenceBinding2 = (ReferenceBinding) typeBinding2;
        char[] constantPoolName = referenceBinding.constantPoolName();
        char[] constantPoolName2 = referenceBinding2.constantPoolName();
        // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=116833
        if (constantPoolName == null) {
          if (constantPoolName2 != null) {
            return false;
          }
          if (!CharOperation.equals(
              referenceBinding.computeUniqueKey(), referenceBinding2.computeUniqueKey())) {
            return false;
          }
        } else {
          if (constantPoolName2 == null) {
            return false;
          }
          if (!CharOperation.equals(constantPoolName, constantPoolName2)) {
            return false;
          }
        }
        return CharOperation.equals(referenceBinding.compoundName, referenceBinding2.compoundName)
            && (!referenceBinding2.isGenericType())
            && (referenceBinding.isRawType() == referenceBinding2.isRawType())
            && ((referenceBinding.modifiers & ~ClassFileConstants.AccSuper)
                    & (ExtraCompilerModifiers.AccJustFlag
                        | ClassFileConstants.AccInterface
                        | ClassFileConstants.AccEnum
                        | ClassFileConstants.AccAnnotation))
                == ((referenceBinding2.modifiers & ~ClassFileConstants.AccSuper)
                    & (ExtraCompilerModifiers.AccJustFlag
                        | ClassFileConstants.AccInterface
                        | ClassFileConstants.AccEnum
                        | ClassFileConstants.AccAnnotation))
            && isEqual(
                referenceBinding.enclosingType(), referenceBinding2.enclosingType(), visitedTypes);
    }
  }