Ejemplo n.º 1
0
  private static boolean isMoreSpecific(
      @NotNull CallableMemberDescriptor a, @NotNull CallableMemberDescriptor b) {
    if (a instanceof SimpleFunctionDescriptor) {
      assert b instanceof SimpleFunctionDescriptor : "b is " + b.getClass();

      JetType aReturnType = a.getReturnType();
      assert aReturnType != null;
      JetType bReturnType = b.getReturnType();
      assert bReturnType != null;

      return JetTypeChecker.DEFAULT.isSubtypeOf(aReturnType, bReturnType);
    }
    if (a instanceof PropertyDescriptor) {
      assert b instanceof PropertyDescriptor : "b is " + b.getClass();

      if (((PropertyDescriptor) a).isVar() || ((PropertyDescriptor) b).isVar()) {
        return ((PropertyDescriptor) a).isVar();
      }

      // both vals
      return JetTypeChecker.DEFAULT.isSubtypeOf(
          ((PropertyDescriptor) a).getType(), ((PropertyDescriptor) b).getType());
    }
    throw new IllegalArgumentException("Unexpected callable: " + a.getClass());
  }
Ejemplo n.º 2
0
 private void assertSubtypingRelation(String subtype, String supertype, boolean expected) {
   JetType typeNode1 = makeType(subtype);
   JetType typeNode2 = makeType(supertype);
   boolean result = JetTypeChecker.DEFAULT.isSubtypeOf(typeNode1, typeNode2);
   String modifier = expected ? "not " : "";
   assertTrue(typeNode1 + " is " + modifier + "a subtype of " + typeNode2, result == expected);
 }
Ejemplo n.º 3
0
  public boolean isMain(@NotNull JetNamedFunction function) {
    if (!"main".equals(function.getName())) return false;

    FunctionDescriptor functionDescriptor = getFunctionDescriptor.fun(function);
    List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
    if (parameters.size() != 1) return false;

    ValueParameterDescriptor parameter = parameters.get(0);
    JetType parameterType = parameter.getType();
    if (!KotlinBuiltIns.isArray(parameterType)) return false;

    List<TypeProjection> typeArguments = parameterType.getArguments();
    if (typeArguments.size() != 1) return false;

    JetType typeArgument = typeArguments.get(0).getType();
    if (!JetTypeChecker.DEFAULT.equalTypes(
        typeArgument, getBuiltIns(functionDescriptor).getStringType())) return false;

    if (DescriptorUtils.isTopLevelDeclaration(functionDescriptor)) return true;

    DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
    return containingDeclaration instanceof ClassDescriptor
        && ((ClassDescriptor) containingDeclaration).getKind().isSingleton()
        && AnnotationsPackage.hasPlatformStaticAnnotation(functionDescriptor);
  }
  private static boolean isArgumentTypeValid(
      BindingContext bindingContext, JetValueArgument argument, ValueParameterDescriptor param) {
    if (argument.getArgumentExpression() != null) {
      JetType paramType = getActualParameterType(param);
      JetType exprType = bindingContext.getType(argument.getArgumentExpression());
      return exprType == null || JetTypeChecker.DEFAULT.isSubtypeOf(exprType, paramType);
    }

    return false;
  }
Ejemplo n.º 5
0
 private static void removeDuplicateTypes(Set<JetType> conflictingTypes) {
   for (Iterator<JetType> iterator = conflictingTypes.iterator(); iterator.hasNext(); ) {
     JetType type = iterator.next();
     for (JetType otherType : conflictingTypes) {
       boolean subtypeOf = JetTypeChecker.DEFAULT.equalTypes(type, otherType);
       if (type != otherType && subtypeOf) {
         iterator.remove();
         break;
       }
     }
   }
 }
Ejemplo n.º 6
0
 public boolean isBooleanOrSubtype(@NotNull JetType type) {
   return JetTypeChecker.DEFAULT.isSubtypeOf(type, getBooleanType());
 }
Ejemplo n.º 7
0
  @NotNull
  private OverrideCompatibilityInfo isOverridableBy(
      @NotNull CallableDescriptor superDescriptor,
      @NotNull CallableDescriptor subDescriptor,
      boolean checkReturnType) {
    if (superDescriptor instanceof FunctionDescriptor) {
      if (!(subDescriptor instanceof FunctionDescriptor))
        return OverrideCompatibilityInfo.memberKindMismatch();
    } else if (superDescriptor instanceof PropertyDescriptor) {
      if (!(subDescriptor instanceof PropertyDescriptor))
        return OverrideCompatibilityInfo.memberKindMismatch();
    } else {
      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.nameMismatch();
    }

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

    List<JetType> superValueParameters = compiledValueParameters(superDescriptor);
    List<JetType> 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) {
        JetType superValueParameterType = getUpperBound(superValueParameters.get(i));
        JetType subValueParameterType = getUpperBound(subValueParameters.get(i));
        // TODO: compare erasure
        if (!JetTypeChecker.DEFAULT.equalTypes(superValueParameterType, subValueParameterType)) {
          return OverrideCompatibilityInfo.typeParameterNumberMismatch();
        }
      }
      return OverrideCompatibilityInfo.valueParameterTypeMismatch(
          null, null, OverrideCompatibilityInfo.Result.CONFLICT);
    }

    final Map<TypeConstructor, TypeConstructor> matchingTypeConstructors =
        new HashMap<TypeConstructor, TypeConstructor>();
    for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) {
      TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
      TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);
      matchingTypeConstructors.put(
          superTypeParameter.getTypeConstructor(), subTypeParameter.getTypeConstructor());
    }

    JetTypeChecker.TypeConstructorEquality localEqualityAxioms =
        new JetTypeChecker.TypeConstructorEquality() {
          @Override
          public boolean equals(@NotNull TypeConstructor a, @NotNull TypeConstructor b) {
            if (equalityAxioms.equals(a, b)) return true;
            TypeConstructor img1 = matchingTypeConstructors.get(a);
            TypeConstructor img2 = matchingTypeConstructors.get(b);
            if (!(img1 != null && img1.equals(b)) && !(img2 != null && img2.equals(a))) {
              return false;
            }
            return true;
          }
        };

    for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) {
      TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
      TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);

      if (!areTypesEquivalent(
          superTypeParameter.getUpperBoundsAsType(),
          subTypeParameter.getUpperBoundsAsType(),
          localEqualityAxioms)) {
        return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter);
      }
    }

    for (int i = 0, unsubstitutedValueParametersSize = superValueParameters.size();
        i < unsubstitutedValueParametersSize;
        i++) {
      JetType superValueParameter = superValueParameters.get(i);
      JetType subValueParameter = subValueParameters.get(i);

      if (!areTypesEquivalent(superValueParameter, subValueParameter, localEqualityAxioms)) {
        return OverrideCompatibilityInfo.valueParameterTypeMismatch(
            superValueParameter, subValueParameter, INCOMPATIBLE);
      }
    }

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

      if (superReturnType != null && subReturnType != null) {
        boolean bothErrors = subReturnType.isError() && superReturnType.isError();
        if (!bothErrors
            && !JetTypeChecker.withAxioms(localEqualityAxioms)
                .isSubtypeOf(subReturnType, superReturnType)) {
          return OverrideCompatibilityInfo.returnTypeMismatch(superReturnType, subReturnType);
        }
      }
    }

    for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) {
      if (!externalCondition.isOverridable(superDescriptor, subDescriptor)) {
        return OverrideCompatibilityInfo.externalConditionFailed(externalCondition.getClass());
      }
    }

    return OverrideCompatibilityInfo.success();
  }