예제 #1
0
 @NotNull
 public KotlinType getArrayElementType(@NotNull KotlinType arrayType) {
   if (isArray(arrayType)) {
     if (arrayType.getArguments().size() != 1) {
       throw new IllegalStateException();
     }
     return arrayType.getArguments().get(0).getType();
   }
   KotlinType primitiveType =
       kotlinArrayTypeToPrimitiveKotlinType.get(TypeUtils.makeNotNullable(arrayType));
   if (primitiveType == null) {
     throw new IllegalStateException("not array: " + arrayType);
   }
   return primitiveType;
 }
예제 #2
0
 @Nullable
 public static KotlinType getReceiverType(@NotNull KotlinType type) {
   assert isFunctionOrExtensionFunctionType(type) : type;
   if (isExtensionFunctionType(type)) {
     // TODO: this is incorrect when a class extends from an extension function and swaps type
     // arguments
     return type.getArguments().get(0).getType();
   }
   return null;
 }
예제 #3
0
 public static boolean dependsOnTypeConstructors(
     @NotNull KotlinType type, @NotNull Collection<TypeConstructor> typeParameterConstructors) {
   if (typeParameterConstructors.contains(type.getConstructor())) return true;
   for (TypeProjection typeProjection : type.getArguments()) {
     if (!typeProjection.isStarProjection()
         && dependsOnTypeConstructors(typeProjection.getType(), typeParameterConstructors)) {
       return true;
     }
   }
   return false;
 }
예제 #4
0
 @NotNull
 public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType(
     @NotNull KotlinType type) {
   assert isFunctionOrExtensionFunctionType(type);
   List<TypeProjection> arguments = type.getArguments();
   int first = isExtensionFunctionType(type) ? 1 : 0;
   int last = arguments.size() - 2;
   // TODO: fix bugs associated with this here and in neighboring methods, see KT-9820
   assert first <= last + 1 : "Not an exact function type: " + type;
   List<TypeProjection> parameterTypes = new ArrayList<TypeProjection>(last - first + 1);
   for (int i = first; i <= last; i++) {
     parameterTypes.add(arguments.get(i));
   }
   return parameterTypes;
 }
예제 #5
0
 public static boolean contains(
     @Nullable KotlinType type, @NotNull Function1<KotlinType, Boolean> isSpecialType) {
   if (type == null) return false;
   if (isSpecialType.invoke(type)) return true;
   Flexibility flexibility = type.getCapability(Flexibility.class);
   if (flexibility != null
       && (contains(flexibility.getLowerBound(), isSpecialType)
           || contains(flexibility.getUpperBound(), isSpecialType))) {
     return true;
   }
   for (TypeProjection projection : type.getArguments()) {
     if (!projection.isStarProjection() && contains(projection.getType(), isSpecialType))
       return true;
   }
   return false;
 }
예제 #6
0
 @NotNull
 public static KotlinType getReturnTypeFromFunctionType(@NotNull KotlinType type) {
   assert isFunctionOrExtensionFunctionType(type);
   List<TypeProjection> arguments = type.getArguments();
   return arguments.get(arguments.size() - 1).getType();
 }
예제 #7
0
 @Override
 @NotNull
 public List<TypeProjection> getArguments() {
   return delegate.getArguments();
 }
예제 #8
0
  public static boolean canHaveSubtypes(KotlinTypeChecker typeChecker, @NotNull KotlinType type) {
    if (type.isMarkedNullable()) {
      return true;
    }
    if (!type.getConstructor().isFinal()) {
      return true;
    }

    List<TypeParameterDescriptor> parameters = type.getConstructor().getParameters();
    List<TypeProjection> arguments = type.getArguments();
    for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
      TypeParameterDescriptor parameterDescriptor = parameters.get(i);
      TypeProjection typeProjection = arguments.get(i);
      if (typeProjection.isStarProjection()) return true;

      Variance projectionKind = typeProjection.getProjectionKind();
      KotlinType argument = typeProjection.getType();

      switch (parameterDescriptor.getVariance()) {
        case INVARIANT:
          switch (projectionKind) {
            case INVARIANT:
              if (lowerThanBound(typeChecker, argument, parameterDescriptor)
                  || canHaveSubtypes(typeChecker, argument)) {
                return true;
              }
              break;
            case IN_VARIANCE:
              if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
                return true;
              }
              break;
            case OUT_VARIANCE:
              if (canHaveSubtypes(typeChecker, argument)) {
                return true;
              }
              break;
          }
          break;
        case IN_VARIANCE:
          if (projectionKind != Variance.OUT_VARIANCE) {
            if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
              return true;
            }
          } else {
            if (canHaveSubtypes(typeChecker, argument)) {
              return true;
            }
          }
          break;
        case OUT_VARIANCE:
          if (projectionKind != Variance.IN_VARIANCE) {
            if (canHaveSubtypes(typeChecker, argument)) {
              return true;
            }
          } else {
            if (lowerThanBound(typeChecker, argument, parameterDescriptor)) {
              return true;
            }
          }
          break;
      }
    }
    return false;
  }