예제 #1
0
 @NotNull
 public JetType getArrayElementType(@NotNull JetType arrayType) {
   if (isArray(arrayType)) {
     if (arrayType.getArguments().size() != 1) {
       throw new IllegalStateException();
     }
     return arrayType.getArguments().get(0).getType();
   }
   JetType primitiveType =
       jetArrayTypeToPrimitiveJetType.get(TypeUtils.makeNotNullable(arrayType));
   if (primitiveType == null) {
     throw new IllegalStateException("not array: " + arrayType);
   }
   return primitiveType;
 }
예제 #2
0
 @Nullable
 public static JetType getReceiverType(@NotNull JetType type) {
   assert isFunctionOrExtensionFunctionType(type) : type;
   if (isExtensionFunctionType(type)) {
     return type.getArguments().get(0).getType();
   }
   return null;
 }
예제 #3
0
  private static boolean isTypeConstructorFqNameInSet(
      @NotNull JetType type, @NotNull Set<FqNameUnsafe> classes) {
    ClassifierDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();

    if (declarationDescriptor == null) return false;

    FqNameUnsafe fqName = DescriptorUtils.getFqName(declarationDescriptor);
    return classes.contains(fqName);
  }
예제 #4
0
  public static boolean isExtensionFunctionType(@NotNull JetType type) {
    if (isExactExtensionFunctionType(type)) return true;

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

    return false;
  }
예제 #5
0
 @NotNull
 public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType(
     @NotNull JetType type) {
   assert isFunctionOrExtensionFunctionType(type);
   List<TypeProjection> arguments = type.getArguments();
   int first = isExtensionFunctionType(type) ? 1 : 0;
   int last = arguments.size() - 2;
   List<TypeProjection> parameterTypes = new ArrayList<TypeProjection>(last - first + 1);
   for (int i = first; i <= last; i++) {
     parameterTypes.add(arguments.get(i));
   }
   return parameterTypes;
 }
예제 #6
0
 public static boolean isNullableAny(@NotNull JetType type) {
   return isAnyOrNullableAny(type) && type.isMarkedNullable();
 }
예제 #7
0
 public static boolean isNullableNothing(@NotNull JetType type) {
   return isNothingOrNullableNothing(type) && type.isMarkedNullable();
 }
예제 #8
0
 private static boolean isNotNullConstructedFromGivenClass(
     @NotNull JetType type, @NotNull FqNameUnsafe fqName) {
   return !type.isMarkedNullable() && isConstructedFromGivenClass(type, fqName);
 }
예제 #9
0
 private static boolean isConstructedFromGivenClass(
     @NotNull JetType type, @NotNull FqNameUnsafe fqName) {
   ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
   return descriptor != null && fqName.equals(DescriptorUtils.getFqName(descriptor));
 }
예제 #10
0
 @NotNull
 public static JetType getReturnTypeFromFunctionType(@NotNull JetType type) {
   assert isFunctionOrExtensionFunctionType(type);
   List<TypeProjection> arguments = type.getArguments();
   return arguments.get(arguments.size() - 1).getType();
 }
예제 #11
0
 public static boolean isPrimitiveType(@NotNull JetType type) {
   ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
   return !type.isMarkedNullable()
       && descriptor != null
       && FQ_NAMES.primitiveTypes.contains(DescriptorUtils.getFqName(descriptor));
 }
예제 #12
0
  private void checkSupertypeList(
      @NotNull ClassDescriptor supertypeOwner,
      @NotNull Map<JetTypeReference, JetType> supertypes,
      @NotNull JetClassOrObject jetClass) {
    Set<TypeConstructor> allowedFinalSupertypes =
        getAllowedFinalSupertypes(supertypeOwner, jetClass);
    Set<TypeConstructor> typeConstructors = Sets.newHashSet();
    boolean classAppeared = false;
    for (Map.Entry<JetTypeReference, JetType> entry : supertypes.entrySet()) {
      JetTypeReference typeReference = entry.getKey();
      JetType supertype = entry.getValue();

      boolean addSupertype = true;

      ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
      if (classDescriptor != null) {
        if (ErrorUtils.isError(classDescriptor)) continue;

        if (classDescriptor.getKind() != ClassKind.INTERFACE) {
          if (supertypeOwner.getKind() == ClassKind.ENUM_CLASS) {
            trace.report(CLASS_IN_SUPERTYPE_FOR_ENUM.on(typeReference));
            addSupertype = false;
          } else if (supertypeOwner.getKind() == ClassKind.INTERFACE
              && !classAppeared
              && !TypesPackage.isDynamic(supertype) /* avoid duplicate diagnostics */) {
            trace.report(TRAIT_WITH_SUPERCLASS.on(typeReference));
            addSupertype = false;
          }

          if (classAppeared) {
            trace.report(MANY_CLASSES_IN_SUPERTYPE_LIST.on(typeReference));
          } else {
            classAppeared = true;
          }
        }
      } else {
        trace.report(SUPERTYPE_NOT_A_CLASS_OR_TRAIT.on(typeReference));
      }

      TypeConstructor constructor = supertype.getConstructor();
      if (addSupertype && !typeConstructors.add(constructor)) {
        trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference));
      }

      if (DescriptorUtils.isSingleton(classDescriptor)) {
        trace.report(SINGLETON_IN_SUPERTYPE.on(typeReference));
      } else if (constructor.isFinal() && !allowedFinalSupertypes.contains(constructor)) {
        if (classDescriptor.getModality() == Modality.SEALED) {
          DeclarationDescriptor containingDescriptor = supertypeOwner.getContainingDeclaration();
          while (containingDescriptor != null && containingDescriptor != classDescriptor) {
            containingDescriptor = containingDescriptor.getContainingDeclaration();
          }
          if (containingDescriptor == null) {
            trace.report(SEALED_SUPERTYPE.on(typeReference));
          } else {
            trace.report(SEALED_SUPERTYPE_IN_LOCAL_CLASS.on(typeReference));
          }
        } else {
          trace.report(FINAL_SUPERTYPE.on(typeReference));
        }
      }
    }
  }