@NotNull
  private VarargCheckResult checkVarargInSuperFunctions(
      @NotNull ValueParameterDescriptor originalParam) {
    boolean someSupersVararg = false;
    boolean someSupersNotVararg = false;
    for (FunctionDescriptor superFunction : superFunctions) {
      if (superFunction.getValueParameters().get(originalParam.getIndex()).getVarargElementType()
          != null) {
        someSupersVararg = true;
      } else {
        someSupersNotVararg = true;
      }
    }

    JetType originalVarargElementType = originalParam.getVarargElementType();
    JetType originalType = originalParam.getType();

    if (someSupersVararg && someSupersNotVararg) {
      reportError("Incompatible super methods: some have vararg parameter, some have not");
      return new VarargCheckResult(originalType, originalVarargElementType != null);
    }

    KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
    if (someSupersVararg && originalVarargElementType == null) {
      // convert to vararg

      assert isArrayType(originalType);

      if (builtIns.isPrimitiveArray(originalType)) {
        // replace IntArray? with IntArray
        return new VarargCheckResult(TypeUtils.makeNotNullable(originalType), true);
      }

      // replace Array<out Foo>? with Array<Foo>
      JetType varargElementType = builtIns.getArrayElementType(originalType);
      return new VarargCheckResult(builtIns.getArrayType(INVARIANT, varargElementType), true);
    } else if (someSupersNotVararg && originalVarargElementType != null) {
      // convert to non-vararg

      assert isArrayType(originalType);

      if (builtIns.isPrimitiveArray(originalType)) {
        // replace IntArray with IntArray?
        return new VarargCheckResult(TypeUtils.makeNullable(originalType), false);
      }

      // replace Array<Foo> with Array<out Foo>?
      return new VarargCheckResult(
          TypeUtils.makeNullable(
              builtIns.getArrayType(Variance.OUT_VARIANCE, originalVarargElementType)),
          false);
    }

    return new VarargCheckResult(originalType, originalVarargElementType != null);
  }
  private void checkParameterAndReturnTypesForOverridingMethods(
      @NotNull List<ValueParameterDescriptor> valueParameters,
      @NotNull List<TypeParameterDescriptor> methodTypeParameters,
      @Nullable JetType returnType) {
    TypeSubstitutor substitutor =
        DescriptorResolverUtils.createSubstitutorForTypeParameters(originalToAltTypeParameters);

    for (ValueParameterDescriptor parameter : valueParameters) {
      int index = parameter.getIndex();
      ValueParameterDescriptor altParameter = altValueParameters.get(index);

      JetType substituted = substitutor.substitute(parameter.getType(), Variance.INVARIANT);
      assert substituted != null;

      if (!TypeUtils.equalTypes(substituted, altParameter.getType())) {
        throw new AlternativeSignatureMismatchException(
            "Parameter type changed for method which overrides another: "
                + altParameter.getType()
                + ", was: "
                + parameter.getType());
      }
    }

    // don't check receiver

    for (TypeParameterDescriptor parameter : methodTypeParameters) {
      int index = parameter.getIndex();

      JetType substituted =
          substitutor.substitute(parameter.getUpperBoundsAsType(), Variance.INVARIANT);
      assert substituted != null;

      if (!TypeUtils.equalTypes(substituted, altTypeParameters.get(index).getUpperBoundsAsType())) {
        throw new AlternativeSignatureMismatchException(
            "Type parameter's upper bound changed for method which overrides another: "
                + altTypeParameters.get(index).getUpperBoundsAsType()
                + ", was: "
                + parameter.getUpperBoundsAsType());
      }
    }

    if (returnType != null) {
      JetType substitutedReturnType = substitutor.substitute(returnType, Variance.INVARIANT);
      assert substitutedReturnType != null;

      if (!JetTypeChecker.INSTANCE.isSubtypeOf(altReturnType, substitutedReturnType)) {
        throw new AlternativeSignatureMismatchException(
            "Return type is changed to not subtype for method which overrides another: "
                + altReturnType
                + ", was: "
                + returnType);
      }
    }
  }
Example #3
0
  @NotNull
  public TypeReconstructionResult reconstruct(@NotNull JetType subjectType) {
    if (!isBare()) return new TypeReconstructionResult(getActualType(), true);

    TypeReconstructionResult reconstructionResult =
        CastDiagnosticsUtil.findStaticallyKnownSubtype(
            TypeUtils.makeNotNullable(subjectType), getBareTypeConstructor());
    JetType type = reconstructionResult.getResultingType();
    // No need to make an absent type nullable
    if (type == null) return reconstructionResult;

    JetType resultingType = TypeUtils.makeNullableAsSpecified(type, isBareTypeNullable());
    return new TypeReconstructionResult(
        resultingType, reconstructionResult.isAllArgumentsInferred());
  }
  @NotNull
  private static Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>>
      getSuperclassToFunctionsMultimap(
          @NotNull PsiMethodWrapper method,
          @NotNull BindingContext bindingContext,
          @NotNull ClassDescriptor containingClass) {
    Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>> result = HashMultimap.create();

    Name functionName = Name.identifier(method.getName());
    int parameterCount = method.getParameters().size();

    for (JetType supertype : TypeUtils.getAllSupertypes(containingClass.getDefaultType())) {
      ClassifierDescriptor klass = supertype.getConstructor().getDeclarationDescriptor();
      assert klass != null;
      FqName fqName = DescriptorUtils.getFQName(klass).toSafe();

      for (FunctionDescriptor fun :
          klass.getDefaultType().getMemberScope().getFunctions(functionName)) {
        if (fun.getKind().isReal() && fun.getValueParameters().size() == parameterCount) {
          PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, fun);
          if (declaration instanceof PsiMethod) {
            result.put(fqName, Pair.create(fun, (PsiMethod) declaration));
          } // else declaration is null or JetNamedFunction: both cases are processed later
        }
      }
    }
    return result;
  }
 public void addSupertype(@NotNull JetType supertype) {
   assert !supertype.isError() : "Error types must be filtered out in DescriptorResolver";
   if (TypeUtils.getClassDescriptor(supertype) != null) {
     // See the Errors.SUPERTYPE_NOT_A_CLASS_OR_TRAIT
     supertypes.add(supertype);
   }
 }
Example #6
0
  // allowedFinalSupertypes typically contains a enum type of which supertypeOwner is an entry
  private void checkSupertypeList(
      @NotNull MutableClassDescriptor supertypeOwner,
      @NotNull Map<JetTypeReference, JetType> supertypes,
      Set<TypeConstructor> allowedFinalSupertypes) {
    Set<TypeConstructor> typeConstructors = Sets.newHashSet();
    boolean classAppeared = false;
    for (Map.Entry<JetTypeReference, JetType> entry : supertypes.entrySet()) {
      JetTypeReference typeReference = entry.getKey();
      JetType supertype = entry.getValue();

      ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
      if (classDescriptor != null) {
        if (classDescriptor.getKind() != ClassKind.TRAIT) {
          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 (!typeConstructors.add(constructor)) {
        trace.report(SUPERTYPE_APPEARS_TWICE.on(typeReference));
      }

      if (constructor.isSealed() && !allowedFinalSupertypes.contains(constructor)) {
        trace.report(FINAL_SUPERTYPE.on(typeReference));
      }
    }
  }
 @Override
 public void visitTypeVariable(String name, boolean nullable) {
   JetType r =
       TypeUtils.makeNullableAsSpecified(
           typeVariableResolver.getTypeVariable(name).getDefaultType(), nullable);
   done(r);
 }
  // Returns list with type arguments info from supertypes
  // Example:
  //     - Foo<A, B> is a subtype of Bar<A, List<B>>, Baz<Boolean, A>
  //     - input: klass = Foo, typesFromSuper = [Bar<String, List<Int>>, Baz<Boolean, CharSequence>]
  //     - output[0] = [String, CharSequence], output[1] = []
  private static List<List<TypeProjectionAndVariance>> calculateTypeArgumentsFromSuper(
      @NotNull ClassDescriptor klass, @NotNull Collection<TypeAndVariance> typesFromSuper) {
    // For each superclass of klass and its parameters, hold their mapping to klass' parameters
    // #0 of Bar ->  A
    // #1 of Bar ->  List<B>
    // #0 of Baz ->  Boolean
    // #1 of Baz ->  A
    // #0 of Foo ->  A (mapped to itself)
    // #1 of Foo ->  B (mapped to itself)
    Multimap<TypeConstructor, TypeProjection> substitution =
        SubstitutionUtils.buildDeepSubstitutionMultimap(
            TypeUtils.makeUnsubstitutedType(klass, JetScope.EMPTY));

    // for each parameter of klass, hold arguments in corresponding supertypes
    List<List<TypeProjectionAndVariance>> parameterToArgumentsFromSuper = Lists.newArrayList();
    for (TypeParameterDescriptor ignored : klass.getTypeConstructor().getParameters()) {
      parameterToArgumentsFromSuper.add(new ArrayList<TypeProjectionAndVariance>());
    }

    // Enumerate all types from super and all its parameters
    for (TypeAndVariance typeFromSuper : typesFromSuper) {
      for (TypeParameterDescriptor parameter :
          typeFromSuper.type.getConstructor().getParameters()) {
        TypeProjection argument = typeFromSuper.type.getArguments().get(parameter.getIndex());

        // for given example, this block is executed four times:
        // 1. typeFromSuper = Bar<String, List<Int>>,      parameter = "#0 of Bar",  argument =
        // String
        // 2. typeFromSuper = Bar<String, List<Int>>,      parameter = "#1 of Bar",  argument =
        // List<Int>
        // 3. typeFromSuper = Baz<Boolean, CharSequence>,  parameter = "#0 of Baz",  argument =
        // Boolean
        // 4. typeFromSuper = Baz<Boolean, CharSequence>,  parameter = "#1 of Baz",  argument =
        // CharSequence

        // if it is mapped to klass' parameter, then store it into map
        for (TypeProjection projection : substitution.get(parameter.getTypeConstructor())) {
          // 1. projection = A
          // 2. projection = List<B>
          // 3. projection = Boolean
          // 4. projection = A
          ClassifierDescriptor classifier =
              projection.getType().getConstructor().getDeclarationDescriptor();

          // this condition is true for 1 and 4, false for 2 and 3
          if (classifier instanceof TypeParameterDescriptor
              && classifier.getContainingDeclaration() == klass) {
            int parameterIndex = ((TypeParameterDescriptor) classifier).getIndex();
            Variance effectiveVariance =
                parameter.getVariance().superpose(typeFromSuper.varianceOfPosition);
            parameterToArgumentsFromSuper
                .get(parameterIndex)
                .add(new TypeProjectionAndVariance(argument, effectiveVariance));
          }
        }
      }
    }
    return parameterToArgumentsFromSuper;
  }
  @NotNull
  public TypeInfoForCall getQualifiedExpressionExtendedTypeInfo(
      @NotNull JetQualifiedExpression expression,
      @NotNull ResolutionContext context,
      @NotNull ResolveMode resolveMode) {
    // TODO : functions as values
    JetExpression selectorExpression = expression.getSelectorExpression();
    JetExpression receiverExpression = expression.getReceiverExpression();
    JetTypeInfo receiverTypeInfo =
        expressionTypingServices.getTypeInfoWithNamespaces(
            receiverExpression,
            context.scope,
            NO_EXPECTED_TYPE,
            context.dataFlowInfo,
            context.trace);
    JetType receiverType = receiverTypeInfo.getType();
    if (selectorExpression == null) return TypeInfoForCall.create(null, context.dataFlowInfo);
    if (receiverType == null)
      receiverType = ErrorUtils.createErrorType("Type for " + expression.getText());

    context = context.replaceDataFlowInfo(receiverTypeInfo.getDataFlowInfo());

    if (selectorExpression instanceof JetSimpleNameExpression) {
      ConstantUtils.propagateConstantValues(
          expression, context.trace, (JetSimpleNameExpression) selectorExpression);
    }

    TypeInfoForCall selectorReturnTypeInfo =
        getSelectorReturnTypeInfo(
            new ExpressionReceiver(receiverExpression, receiverType),
            expression.getOperationTokenNode(),
            selectorExpression,
            context,
            resolveMode);
    JetType selectorReturnType = selectorReturnTypeInfo.getType();

    // TODO move further
    if (!(receiverType instanceof NamespaceType)
        && expression.getOperationSign() == JetTokens.SAFE_ACCESS) {
      if (selectorReturnType != null
          && !selectorReturnType.isNullable()
          && !KotlinBuiltIns.getInstance().isUnit(selectorReturnType)) {
        if (receiverType.isNullable()) {
          selectorReturnType = TypeUtils.makeNullable(selectorReturnType);
        }
      }
    }

    // TODO : this is suspicious: remove this code?
    if (selectorReturnType != null) {
      context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, selectorReturnType);
    }
    JetTypeInfo typeInfo =
        JetTypeInfo.create(selectorReturnType, selectorReturnTypeInfo.getDataFlowInfo());
    if (resolveMode == ResolveMode.TOP_LEVEL_CALL) {
      DataFlowUtils.checkType(typeInfo.getType(), expression, context, typeInfo.getDataFlowInfo());
    }
    return TypeInfoForCall.create(typeInfo, selectorReturnTypeInfo);
  }
Example #10
0
 private static void addForClassType(
     ArrayList<String> result, JetType jetType, JetNameValidator validator) {
   ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(jetType);
   if (classDescriptor != null) {
     Name className = classDescriptor.getName();
     addCamelNames(result, className.getName(), validator);
   }
 }
 @NotNull
 private JetType computeUpperBoundsAsType() {
   Set<JetType> upperBounds = getUpperBounds();
   assert !upperBounds.isEmpty() : "Upper bound list is empty in " + getName();
   JetType upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.DEFAULT, upperBounds);
   return upperBoundsAsType != null
       ? upperBoundsAsType
       : KotlinBuiltIns.getInstance().getNothingType();
 }
Example #12
0
 private void assertSupertypes(String typeStr, String... supertypeStrs) {
   Set<JetType> allSupertypes = TypeUtils.getAllSupertypes(makeType(scopeWithImports, typeStr));
   Set<JetType> expected = Sets.newHashSet();
   for (String supertypeStr : supertypeStrs) {
     JetType supertype = makeType(scopeWithImports, supertypeStr);
     expected.add(supertype);
   }
   assertEquals(expected, allSupertypes);
 }
Example #13
0
 private void assertIntersection(String expected, String... types) {
   Set<JetType> typesToIntersect = new LinkedHashSet<JetType>();
   for (String type : types) {
     typesToIntersect.add(makeType(type));
   }
   JetType result = TypeUtils.intersect(JetTypeChecker.INSTANCE, typesToIntersect);
   //        assertNotNull("Intersection is null for " + typesToIntersect, result);
   assertEquals(makeType(expected), result);
 }
 private static Map<ClassDescriptor, JetType> getSuperclassToSupertypeMap(
     ClassDescriptor containingClass) {
   Map<ClassDescriptor, JetType> superclassToSupertype = Maps.newHashMap();
   for (JetType supertype : TypeUtils.getAllSupertypes(containingClass.getDefaultType())) {
     ClassifierDescriptor superclass = supertype.getConstructor().getDeclarationDescriptor();
     assert superclass instanceof ClassDescriptor;
     superclassToSupertype.put((ClassDescriptor) superclass, supertype);
   }
   return superclassToSupertype;
 }
 /*
  * Checks if receiver declaration could be resolved to call expected receiver.
  */
 public static boolean checkIsExtensionCallable(
     @NotNull ReceiverDescriptor expectedReceiver, @NotNull CallableDescriptor receiverArgument) {
   JetType type = expectedReceiver.getType();
   if (checkReceiverResolution(expectedReceiver, type, receiverArgument)) return true;
   if (type.isNullable()) {
     JetType notNullableType = TypeUtils.makeNotNullable(type);
     if (checkReceiverResolution(expectedReceiver, notNullableType, receiverArgument)) return true;
   }
   return false;
 }
  @Override
  public void invoke(@NotNull Project project, Editor editor, PsiFile file)
      throws IncorrectOperationException {
    assert element.getTypeArguments().isEmpty();

    String typeString =
        TypeUtils.getTypeNameAndStarProjectionsString(element.getText(), argumentCount);
    JetTypeElement replacement = JetPsiFactory.createType(project, typeString).getTypeElement();
    assert replacement != null : "No type element after parsing " + typeString;

    element.replace(replacement);
  }
  @Override
  public JetType getClassObjectType() {
    checkInitialized();
    if (classObjectUpperBounds.isEmpty()) return null;

    if (classObjectBoundsAsType == null) {
      classObjectBoundsAsType =
          TypeUtils.intersect(JetTypeChecker.INSTANCE, classObjectUpperBounds);
      if (classObjectBoundsAsType == null) {
        classObjectBoundsAsType = KotlinBuiltIns.getInstance().getNothingType();
      }
    }
    return classObjectBoundsAsType;
  }
 @Override
 @NotNull
 public JetType getUpperBoundsAsType() {
   checkInitialized();
   if (upperBoundsAsType == null) {
     assert upperBounds != null : "Upper bound list is null in " + getName();
     assert upperBounds.size() > 0 : "Upper bound list is empty in " + getName();
     upperBoundsAsType = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds);
     if (upperBoundsAsType == null) {
       upperBoundsAsType = KotlinBuiltIns.getInstance().getNothingType();
     }
   }
   return upperBoundsAsType;
 }
 @Nullable
 private JetType checkAssignmentType(
     @Nullable JetType assignmentType,
     @NotNull JetBinaryExpression expression,
     @NotNull ExpressionTypingContext context) {
   if (assignmentType != null
       && !KotlinBuiltIns.getInstance().isUnit(assignmentType)
       && context.expectedType != TypeUtils.NO_EXPECTED_TYPE
       && TypeUtils.equalTypes(context.expectedType, assignmentType)) {
     context.trace.report(Errors.ASSIGNMENT_TYPE_MISMATCH.on(expression, context.expectedType));
     return null;
   }
   return DataFlowUtils.checkStatementType(expression, context);
 }
 @NotNull
 private static JetType getFunctionTypeForSamType(@NotNull JetType samType) {
   FunctionDescriptor function = getAbstractMethodOfSamType(samType);
   JetType returnType = function.getReturnType();
   assert returnType != null : "function is not initialized: " + function;
   List<JetType> parameterTypes = Lists.newArrayList();
   for (ValueParameterDescriptor parameter : function.getValueParameters()) {
     parameterTypes.add(parameter.getType());
   }
   JetType functionType =
       KotlinBuiltIns.getInstance()
           .getFunctionType(
               Collections.<AnnotationDescriptor>emptyList(), null, parameterTypes, returnType);
   return TypeUtils.makeNullableAsSpecified(functionType, samType.isNullable());
 }
Example #21
0
 /**
  * Add import directive corresponding to a type to file when it is needed.
  *
  * @param type type to import
  * @param file file where import directive should be added
  */
 public static void addImportDirectivesIfNeeded(@NotNull JetType type, @NotNull JetFile file) {
   if (JetPluginUtil.checkTypeIsStandard(type, file.getProject())
       || ErrorUtils.isErrorType(type)) {
     return;
   }
   BindingContext bindingContext = getContextForSingleFile(file);
   PsiElement element =
       BindingContextUtils.descriptorToDeclaration(
           bindingContext, type.getMemberScope().getContainingDeclaration());
   if (element != null
       && element.getContainingFile()
           == file) { // declaration is in the same file, so no import is needed
     return;
   }
   for (ClassDescriptor clazz : TypeUtils.getAllClassDescriptors(type)) {
     addImportDirective(DescriptorUtils.getFQName(getTopLevelClass(clazz)).toSafe(), file);
   }
 }
 @Nullable
 private static String getMessageFromAnnotationDescriptor(
     @NotNull AnnotationDescriptor descriptor) {
   ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(descriptor.getType());
   if (classDescriptor != null) {
     ValueParameterDescriptor parameter =
         DescriptorResolverUtils.getAnnotationParameterByName(
             DEFAULT_ANNOTATION_MEMBER_NAME, classDescriptor);
     if (parameter != null) {
       CompileTimeConstant<?> valueArgument = descriptor.getValueArgument(parameter);
       if (valueArgument != null) {
         Object value = valueArgument.getValue();
         if (value instanceof String) {
           return String.valueOf(value);
         }
       }
     }
   }
   return null;
 }
 @NotNull
 @Override
 public JetType getDefaultType() {
   // checkInitialized();
   if (defaultType == null) {
     defaultType =
         new JetTypeImpl(
             Collections.<AnnotationDescriptor>emptyList(),
             getTypeConstructor(),
             TypeUtils.hasNullableLowerBound(this),
             Collections.<TypeProjection>emptyList(),
             new LazyScopeAdapter(
                 new RecursionIntolerantLazyValue<JetScope>() {
                   @Override
                   protected JetScope compute() {
                     return getUpperBoundsAsType().getMemberScope();
                   }
                 }));
   }
   return defaultType;
 }
  private void transformSupertypeList(
      List<JetType> result,
      PsiClassType[] extendsListTypes,
      TypeVariableResolver typeVariableResolver) {
    for (PsiClassType type : extendsListTypes) {
      PsiClass resolved = type.resolve();
      if (resolved != null) {
        String qualifiedName = resolved.getQualifiedName();
        assert qualifiedName != null;
        if (JvmStdlibNames.JET_OBJECT.getFqName().equalsTo(qualifiedName)) {
          continue;
        }
      }

      JetType transform =
          typeTransformer.transformToType(type, TypeUsage.SUPERTYPE, typeVariableResolver);
      if (ErrorUtils.isErrorType(transform)) {
        continue;
      }

      result.add(TypeUtils.makeNotNullable(transform));
    }
  }
Example #25
0
  private void addConstraint(
      @NotNull ConstraintKind constraintKind,
      @NotNull JetType subjectType,
      @Nullable JetType constrainingType,
      @NotNull ConstraintPosition constraintPosition) {

    if (constrainingType == TypeUtils.NO_EXPECTED_TYPE
        || constrainingType == DONT_CARE
        || constrainingType == CANT_INFER) {
      return;
    }

    if (constrainingType == null
        || (ErrorUtils.isErrorType(constrainingType)
            && constrainingType != PLACEHOLDER_FUNCTION_TYPE)) {
      hasErrorInConstrainingTypes = true;
      return;
    }

    assert subjectType != TypeUtils.NO_EXPECTED_TYPE
        : "Subject type shouldn't be NO_EXPECTED_TYPE (in position " + constraintPosition + " )";
    if (ErrorUtils.isErrorType(subjectType)) return;

    DeclarationDescriptor subjectTypeDescriptor =
        subjectType.getConstructor().getDeclarationDescriptor();

    KotlinBuiltIns kotlinBuiltIns = KotlinBuiltIns.getInstance();
    if (constrainingType == PLACEHOLDER_FUNCTION_TYPE) {
      if (!kotlinBuiltIns.isFunctionOrExtensionFunctionType(subjectType)) {
        if (subjectTypeDescriptor instanceof TypeParameterDescriptor
            && typeParameterConstraints.get(subjectTypeDescriptor) != null) {
          // a constraint binds type parameter and any function type, so there is no new info and no
          // error
          return;
        }
        errorConstraintPositions.add(constraintPosition);
      }
      return;
    }

    // todo temporary hack
    // function literal without declaring receiver type { x -> ... }
    // can be considered as extension function if one is expected
    // (special type constructor for function/ extension function should be introduced like
    // PLACEHOLDER_FUNCTION_TYPE)
    if (constraintKind == SUB_TYPE
        && kotlinBuiltIns.isFunctionType(constrainingType)
        && kotlinBuiltIns.isExtensionFunctionType(subjectType)) {
      constrainingType = createCorrespondingExtensionFunctionType(constrainingType, DONT_CARE);
    }

    DeclarationDescriptor constrainingTypeDescriptor =
        constrainingType.getConstructor().getDeclarationDescriptor();

    if (subjectTypeDescriptor instanceof TypeParameterDescriptor) {
      TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) subjectTypeDescriptor;
      TypeConstraintsImpl typeConstraints = typeParameterConstraints.get(typeParameter);
      if (typeConstraints != null) {
        if (TypeUtils.dependsOnTypeParameterConstructors(
            constrainingType, Collections.singleton(DONT_CARE.getConstructor()))) {
          return;
        }
        if (subjectType.isNullable() && constrainingType.isNullable()) {
          constrainingType = TypeUtils.makeNotNullable(constrainingType);
        }
        typeConstraints.addBound(constraintKind, constrainingType);
        return;
      }
    }
    if (constrainingTypeDescriptor instanceof TypeParameterDescriptor) {
      assert typeParameterConstraints.get(constrainingTypeDescriptor) == null
          : "Constraining type contains type variable " + constrainingTypeDescriptor.getName();
    }
    if (constraintKind == SUB_TYPE && kotlinBuiltIns.isNothingOrNullableNothing(constrainingType)) {
      // following constraints are always true:
      // 'Nothing' is a subtype of any type
      if (!constrainingType.isNullable()) return;
      // 'Nothing?' is a subtype of nullable type
      if (subjectType.isNullable()) return;
    }
    if (!(constrainingTypeDescriptor instanceof ClassDescriptor)
        || !(subjectTypeDescriptor instanceof ClassDescriptor)) {
      errorConstraintPositions.add(constraintPosition);
      return;
    }
    switch (constraintKind) {
      case SUB_TYPE:
        {
          if (kotlinBuiltIns.isNothingOrNullableNothing(constrainingType)) break;
          JetType correspondingSupertype =
              TypeCheckingProcedure.findCorrespondingSupertype(constrainingType, subjectType);
          if (correspondingSupertype != null) {
            constrainingType = correspondingSupertype;
          }
          break;
        }
      case SUPER_TYPE:
        {
          if (kotlinBuiltIns.isNothingOrNullableNothing(subjectType)) break;
          JetType correspondingSupertype =
              TypeCheckingProcedure.findCorrespondingSupertype(subjectType, constrainingType);
          if (correspondingSupertype != null) {
            subjectType = correspondingSupertype;
          }
        }
      case EQUAL: // nothing
    }
    if (constrainingType.getConstructor() != subjectType.getConstructor()) {
      errorConstraintPositions.add(constraintPosition);
      return;
    }
    TypeConstructor typeConstructor = subjectType.getConstructor();
    List<TypeProjection> subjectArguments = subjectType.getArguments();
    List<TypeProjection> constrainingArguments = constrainingType.getArguments();
    List<TypeParameterDescriptor> parameters = typeConstructor.getParameters();
    for (int i = 0; i < subjectArguments.size(); i++) {
      Variance typeParameterVariance = parameters.get(i).getVariance();
      TypeProjection subjectArgument = subjectArguments.get(i);
      TypeProjection constrainingArgument = constrainingArguments.get(i);

      ConstraintKind typeParameterConstraintKind =
          getTypeParameterConstraintKind(
              typeParameterVariance, subjectArgument, constrainingArgument, constraintKind);

      addConstraint(
          typeParameterConstraintKind,
          subjectArgument.getType(),
          constrainingArgument.getType(),
          constraintPosition);
    }
  }
Example #26
0
 public PossiblyBareType makeNullable() {
   if (isBare()) {
     return isBareTypeNullable() ? this : bare(getBareTypeConstructor(), true);
   }
   return type(TypeUtils.makeNullable(getActualType()));
 }
 @NotNull
 @Override
 public String getText() {
   return JetBundle.message(
       "add.star.projections", TypeUtils.getTypeNameAndStarProjectionsString("", argumentCount));
 }
Example #28
0
 private static void addNamesForType(
     ArrayList<String> result, JetType jetType, JetNameValidator validator) {
   JetStandardLibrary standardLibrary = JetStandardLibrary.getInstance();
   JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
   if (ErrorUtils.containsErrorType(jetType)) return;
   if (typeChecker.equalTypes(standardLibrary.getBooleanType(), jetType)) {
     addName(result, "b", validator);
   } else if (typeChecker.equalTypes(standardLibrary.getIntType(), jetType)) {
     addName(result, "i", validator);
   } else if (typeChecker.equalTypes(standardLibrary.getByteType(), jetType)) {
     addName(result, "byte", validator);
   } else if (typeChecker.equalTypes(standardLibrary.getLongType(), jetType)) {
     addName(result, "l", validator);
   } else if (typeChecker.equalTypes(standardLibrary.getFloatType(), jetType)) {
     addName(result, "fl", validator);
   } else if (typeChecker.equalTypes(standardLibrary.getDoubleType(), jetType)) {
     addName(result, "d", validator);
   } else if (typeChecker.equalTypes(standardLibrary.getShortType(), jetType)) {
     addName(result, "sh", validator);
   } else if (typeChecker.equalTypes(standardLibrary.getCharType(), jetType)) {
     addName(result, "c", validator);
   } else if (typeChecker.equalTypes(standardLibrary.getStringType(), jetType)) {
     addName(result, "s", validator);
   } else {
     if (jetType.getArguments().size() == 1) {
       JetType argument = jetType.getArguments().get(0).getType();
       if (typeChecker.equalTypes(standardLibrary.getArrayType(argument), jetType)) {
         if (typeChecker.equalTypes(standardLibrary.getBooleanType(), argument)) {
           addName(result, "booleans", validator);
         } else if (typeChecker.equalTypes(standardLibrary.getIntType(), argument)) {
           addName(result, "ints", validator);
         } else if (typeChecker.equalTypes(standardLibrary.getByteType(), argument)) {
           addName(result, "bytes", validator);
         } else if (typeChecker.equalTypes(standardLibrary.getLongType(), argument)) {
           addName(result, "longs", validator);
         } else if (typeChecker.equalTypes(standardLibrary.getFloatType(), argument)) {
           addName(result, "floats", validator);
         } else if (typeChecker.equalTypes(standardLibrary.getDoubleType(), argument)) {
           addName(result, "doubles", validator);
         } else if (typeChecker.equalTypes(standardLibrary.getShortType(), argument)) {
           addName(result, "shorts", validator);
         } else if (typeChecker.equalTypes(standardLibrary.getCharType(), argument)) {
           addName(result, "chars", validator);
         } else if (typeChecker.equalTypes(standardLibrary.getStringType(), argument)) {
           addName(result, "strings", validator);
         } else {
           ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(argument);
           if (classDescriptor != null) {
             Name className = classDescriptor.getName();
             addName(
                 result, "arrayOf" + StringUtil.capitalize(className.getName()) + "s", validator);
           }
         }
       } else {
         addForClassType(result, jetType, validator);
       }
     } else {
       addForClassType(result, jetType, validator);
     }
   }
 }
Example #29
0
 @Override
 public boolean apply(JetType type) {
   assert !type.isError() : "Error types must be filtered out in DescriptorResolver";
   return TypeUtils.getClassDescriptor(type) != null;
 }
Example #30
0
 @Override
 public boolean apply(JetType type) {
   return !ErrorUtils.isErrorType(type) && (TypeUtils.getClassDescriptor(type) != null);
 }