Пример #1
0
    private void reportCyclicInheritanceHierarchyError(
        @NotNull BindingTrace trace,
        @NotNull ClassDescriptor classDescriptor,
        @NotNull ClassDescriptor superclass) {
      PsiElement psiElement = DescriptorToSourceUtils.getSourceFromDescriptor(classDescriptor);

      PsiElement elementToMark = null;
      if (psiElement instanceof KtClassOrObject) {
        KtClassOrObject classOrObject = (KtClassOrObject) psiElement;
        for (KtSuperTypeListEntry delegationSpecifier : classOrObject.getSuperTypeListEntries()) {
          KtTypeReference typeReference = delegationSpecifier.getTypeReference();
          if (typeReference == null) continue;
          KotlinType supertype = trace.get(TYPE, typeReference);
          if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) {
            elementToMark = typeReference;
          }
        }
      }
      if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) {
        PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement;
        PsiElement nameIdentifier = namedElement.getNameIdentifier();
        if (nameIdentifier != null) {
          elementToMark = nameIdentifier;
        }
      }
      if (elementToMark != null) {
        trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
      }
    }
Пример #2
0
 private static boolean areTypesEquivalent(
     @NotNull KotlinType typeInSuper,
     @NotNull KotlinType typeInSub,
     @NotNull KotlinTypeChecker typeChecker) {
   boolean bothErrors = typeInSuper.isError() && typeInSub.isError();
   return bothErrors || typeChecker.equalTypes(typeInSuper, typeInSub);
 }
Пример #3
0
  @NotNull
  public OverrideCompatibilityInfo isOverridableByWithoutExternalConditions(
      @NotNull CallableDescriptor superDescriptor,
      @NotNull CallableDescriptor subDescriptor,
      boolean checkReturnType) {
    OverrideCompatibilityInfo basicOverridability =
        getBasicOverridabilityProblem(superDescriptor, subDescriptor);
    if (basicOverridability != null) return basicOverridability;

    List<KotlinType> superValueParameters = compiledValueParameters(superDescriptor);
    List<KotlinType> subValueParameters = compiledValueParameters(subDescriptor);

    List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
    List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();

    if (superTypeParameters.size() != subTypeParameters.size()) {
      for (int i = 0; i < superValueParameters.size(); ++i) {
        // TODO: compare erasure
        if (!KotlinTypeChecker.DEFAULT.equalTypes(
            superValueParameters.get(i), subValueParameters.get(i))) {
          return OverrideCompatibilityInfo.incompatible("Type parameter number mismatch");
        }
      }
      return OverrideCompatibilityInfo.conflict("Type parameter number mismatch");
    }

    KotlinTypeChecker typeChecker = createTypeChecker(superTypeParameters, subTypeParameters);

    for (int i = 0; i < superTypeParameters.size(); i++) {
      if (!areTypeParametersEquivalent(
          superTypeParameters.get(i), subTypeParameters.get(i), typeChecker)) {
        return OverrideCompatibilityInfo.incompatible("Type parameter bounds mismatch");
      }
    }

    for (int i = 0; i < superValueParameters.size(); i++) {
      if (!areTypesEquivalent(
          superValueParameters.get(i), subValueParameters.get(i), typeChecker)) {
        return OverrideCompatibilityInfo.incompatible("Value parameter type mismatch");
      }
    }

    if (checkReturnType) {
      KotlinType superReturnType = superDescriptor.getReturnType();
      KotlinType subReturnType = subDescriptor.getReturnType();

      if (superReturnType != null && subReturnType != null) {
        boolean bothErrors = subReturnType.isError() && superReturnType.isError();
        if (!bothErrors && !typeChecker.isSubtypeOf(subReturnType, superReturnType)) {
          return OverrideCompatibilityInfo.conflict("Return type mismatch");
        }
      }
    }

    return OverrideCompatibilityInfo.success();
  }
Пример #4
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;
 }
Пример #5
0
 @Override
 protected void reportSupertypeLoopError(@NotNull KotlinType type) {
   ClassifierDescriptor supertypeDescriptor = type.getConstructor().getDeclarationDescriptor();
   if (supertypeDescriptor instanceof ClassDescriptor) {
     ClassDescriptor superclass = (ClassDescriptor) supertypeDescriptor;
     reportCyclicInheritanceHierarchyError(c.getTrace(), LazyClassDescriptor.this, superclass);
   }
 }
Пример #6
0
  public static boolean isExtensionFunctionType(@NotNull KotlinType type) {
    if (isExactExtensionFunctionType(type)) return true;

    for (KotlinType superType : type.getConstructor().getSupertypes()) {
      if (isExtensionFunctionType(superType)) return true;
    }

    return false;
  }
Пример #7
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;
 }
Пример #8
0
 private static boolean isConstructedFromGivenClass(
     @NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
   ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
   return descriptor != null
       &&
       /* quick check to avoid creation of full FqName instance */ descriptor
           .getName()
           .equals(fqName.shortName())
       && fqName.equals(getFqName(descriptor));
 }
Пример #9
0
 public static boolean isSubtypeOfClass(
     @NotNull KotlinType type, @NotNull DeclarationDescriptor superClass) {
   if (isSameClass(type, superClass)) return true;
   for (KotlinType superType : type.getConstructor().getSupertypes()) {
     if (isSubtypeOfClass(superType, superClass)) {
       return true;
     }
   }
   return false;
 }
Пример #10
0
  public static boolean shouldRecordInitializerForProperty(
      @NotNull VariableDescriptor variable, @NotNull KotlinType type) {
    if (variable.isVar() || type.isError()) return false;

    if (TypeUtils.acceptsNullable(type)) return true;

    KotlinBuiltIns builtIns = getBuiltIns(variable);
    return KotlinBuiltIns.isPrimitiveType(type)
        || KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getStringType(), type)
        || KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getNumber().getDefaultType(), type)
        || KotlinTypeChecker.DEFAULT.equalTypes(builtIns.getAnyType(), type);
  }
Пример #11
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;
 }
Пример #12
0
 private static boolean isSameClass(
     @NotNull KotlinType type, @NotNull DeclarationDescriptor other) {
   DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
   if (descriptor != null) {
     DeclarationDescriptor originalDescriptor = descriptor.getOriginal();
     if (originalDescriptor instanceof ClassifierDescriptor
         && other instanceof ClassifierDescriptor
         && ((ClassifierDescriptor) other)
             .getTypeConstructor()
             .equals(((ClassifierDescriptor) originalDescriptor).getTypeConstructor())) {
       return true;
     }
   }
   return false;
 }
  @NotNull
  private static KtProperty createProperty(
      @NotNull KtProperty property,
      @NotNull KotlinType propertyType,
      @Nullable String initializer) {
    KtTypeReference typeRef = property.getTypeReference();
    String typeString = null;
    if (typeRef != null) {
      typeString = typeRef.getText();
    } else if (!propertyType.isError()) {
      typeString = IdeDescriptorRenderers.SOURCE_CODE.renderType(propertyType);
    }

    return KtPsiFactoryKt.KtPsiFactory(property)
        .createProperty(property.getName(), typeString, property.isVar(), initializer);
  }
Пример #14
0
 @Override
 public boolean apply(KotlinType type) {
   assert !type.isError() : "Error types must be filtered out in DescriptorResolver";
   return TypeUtils.getClassDescriptor(type) != null;
 }
Пример #15
0
 public static boolean isPrimitiveType(@NotNull KotlinType type) {
   ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
   return !type.isMarkedNullable()
       && descriptor instanceof ClassDescriptor
       && isPrimitiveClass((ClassDescriptor) descriptor);
 }
Пример #16
0
 public static boolean isNullableNothing(@NotNull KotlinType type) {
   return isNothingOrNullableNothing(type) && type.isMarkedNullable();
 }
Пример #17
0
 @NotNull
 public static ClassDescriptor getClassDescriptorForType(@NotNull KotlinType type) {
   return getClassDescriptorForTypeConstructor(type.getConstructor());
 }
Пример #18
0
 public static boolean isNullableAny(@NotNull KotlinType type) {
   return isAnyOrNullableAny(type) && type.isMarkedNullable();
 }
Пример #19
0
 private static boolean isNotNullConstructedFromGivenClass(
     @NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
   return !type.isMarkedNullable() && isConstructedFromGivenClass(type, fqName);
 }
Пример #20
0
 private static boolean isTypeAnnotatedWithExtension(@NotNull KotlinType type) {
   return type.getAnnotations().findAnnotation(FQ_NAMES.extensionFunctionType) != null
       || type.getAnnotations().findAnnotation(FQ_NAMES.deprecatedExtensionAnnotation) != null;
 }
Пример #21
0
 @NotNull
 public static KotlinType getReturnTypeFromFunctionType(@NotNull KotlinType type) {
   assert isFunctionOrExtensionFunctionType(type);
   List<TypeProjection> arguments = type.getArguments();
   return arguments.get(arguments.size() - 1).getType();
 }
Пример #22
0
 public static boolean isPrimitiveArray(@NotNull KotlinType type) {
   ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
   return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null;
 }
Пример #23
0
 public static boolean isExactFunctionOrExtensionFunctionType(@NotNull KotlinType type) {
   ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
   return descriptor != null && isNumberedFunctionClassFqName(getFqName(descriptor));
 }
Пример #24
0
  @NotNull
  public OverrideCompatibilityInfo isOverridableByWithoutExternalConditions(
      @NotNull CallableDescriptor superDescriptor,
      @NotNull CallableDescriptor subDescriptor,
      boolean checkReturnType) {
    if (superDescriptor instanceof FunctionDescriptor
            && !(subDescriptor instanceof FunctionDescriptor)
        || superDescriptor instanceof PropertyDescriptor
            && !(subDescriptor instanceof PropertyDescriptor)) {
      return OverrideCompatibilityInfo.incompatible("Member kind mismatch");
    }

    if (!(superDescriptor instanceof FunctionDescriptor)
        && !(superDescriptor instanceof PropertyDescriptor)) {
      throw new IllegalArgumentException(
          "This type of CallableDescriptor cannot be checked for overridability: "
              + superDescriptor);
    }

    // TODO: check outside of this method
    if (!superDescriptor.getName().equals(subDescriptor.getName())) {
      return OverrideCompatibilityInfo.incompatible("Name mismatch");
    }

    OverrideCompatibilityInfo receiverAndParameterResult =
        checkReceiverAndParameterCount(superDescriptor, subDescriptor);
    if (receiverAndParameterResult != null) {
      return receiverAndParameterResult;
    }

    List<KotlinType> superValueParameters = compiledValueParameters(superDescriptor);
    List<KotlinType> subValueParameters = compiledValueParameters(subDescriptor);

    List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
    List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();

    if (superTypeParameters.size() != subTypeParameters.size()) {
      for (int i = 0; i < superValueParameters.size(); ++i) {
        // TODO: compare erasure
        if (!KotlinTypeChecker.DEFAULT.equalTypes(
            superValueParameters.get(i), subValueParameters.get(i))) {
          return OverrideCompatibilityInfo.incompatible("Type parameter number mismatch");
        }
      }
      return OverrideCompatibilityInfo.conflict("Type parameter number mismatch");
    }

    KotlinTypeChecker typeChecker = createTypeChecker(superTypeParameters, subTypeParameters);

    for (int i = 0; i < superTypeParameters.size(); i++) {
      if (!areTypeParametersEquivalent(
          superTypeParameters.get(i), subTypeParameters.get(i), typeChecker)) {
        return OverrideCompatibilityInfo.incompatible("Type parameter bounds mismatch");
      }
    }

    for (int i = 0; i < superValueParameters.size(); i++) {
      if (!areTypesEquivalent(
          superValueParameters.get(i), subValueParameters.get(i), typeChecker)) {
        return OverrideCompatibilityInfo.incompatible("Value parameter type mismatch");
      }
    }

    if (checkReturnType) {
      KotlinType superReturnType = superDescriptor.getReturnType();
      KotlinType subReturnType = subDescriptor.getReturnType();

      if (superReturnType != null && subReturnType != null) {
        boolean bothErrors = subReturnType.isError() && superReturnType.isError();
        if (!bothErrors && !typeChecker.isSubtypeOf(subReturnType, superReturnType)) {
          return OverrideCompatibilityInfo.conflict("Return type mismatch");
        }
      }
    }

    return OverrideCompatibilityInfo.success();
  }