Search in sources :

Example 11 with TypeParameterDescriptor

use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.

the class ReifiedTypeParameterSubstitutionChecker method check.

@Override
public void check(@NotNull ResolvedCall<?> resolvedCall, @NotNull PsiElement reportOn, @NotNull CallCheckerContext context) {
    Map<TypeParameterDescriptor, KotlinType> typeArguments = resolvedCall.getTypeArguments();
    for (Map.Entry<TypeParameterDescriptor, KotlinType> entry : typeArguments.entrySet()) {
        TypeParameterDescriptor parameter = entry.getKey();
        KotlinType argument = entry.getValue();
        ClassifierDescriptor argumentDeclarationDescriptor = argument.getConstructor().getDeclarationDescriptor();
        if (!parameter.isReified() && !isTypeParameterOfKotlinArray(parameter)) {
            continue;
        }
        KtTypeProjection typeProjection = CollectionsKt.getOrNull(resolvedCall.getCall().getTypeArguments(), parameter.getIndex());
        PsiElement reportErrorOn = typeProjection != null ? typeProjection : reportOn;
        if (argumentDeclarationDescriptor instanceof TypeParameterDescriptor && !((TypeParameterDescriptor) argumentDeclarationDescriptor).isReified()) {
            context.getTrace().report(Errors.TYPE_PARAMETER_AS_REIFIED.on(reportErrorOn, (TypeParameterDescriptor) argumentDeclarationDescriptor));
        } else if (TypeUtilsKt.cannotBeReified(argument)) {
            context.getTrace().report(Errors.REIFIED_TYPE_FORBIDDEN_SUBSTITUTION.on(reportErrorOn, argument));
        }
    // REIFIED_TYPE_UNSAFE_SUBSTITUTION is temporary disabled because it seems too strict now (see KT-10847)
    //else if (TypeUtilsKt.unsafeAsReifiedArgument(argument) && !hasPureReifiableAnnotation(parameter)) {
    //    context.getTrace().report(Errors.REIFIED_TYPE_UNSAFE_SUBSTITUTION.on(reportErrorOn, argument));
    //}
    }
}
Also used : TypeParameterDescriptor(org.jetbrains.kotlin.descriptors.TypeParameterDescriptor) KotlinType(org.jetbrains.kotlin.types.KotlinType) ClassifierDescriptor(org.jetbrains.kotlin.descriptors.ClassifierDescriptor) KtTypeProjection(org.jetbrains.kotlin.psi.KtTypeProjection) Map(java.util.Map) PsiElement(com.intellij.psi.PsiElement)

Example 12 with TypeParameterDescriptor

use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.

the class MemberMatching method typeParametersMatch.

static boolean typeParametersMatch(@NotNull KtTypeParameterListOwner typeParameterListOwner, @NotNull List<TypeParameterDescriptor> typeParameterDescriptors) {
    List<KtTypeParameter> decompiledParameters = typeParameterListOwner.getTypeParameters();
    if (decompiledParameters.size() != typeParameterDescriptors.size()) {
        return false;
    }
    Multimap<Name, String> decompiledParameterToBounds = HashMultimap.create();
    for (KtTypeParameter parameter : decompiledParameters) {
        KtTypeReference extendsBound = parameter.getExtendsBound();
        if (extendsBound != null) {
            decompiledParameterToBounds.put(parameter.getNameAsName(), extendsBound.getText());
        }
    }
    for (KtTypeConstraint typeConstraint : typeParameterListOwner.getTypeConstraints()) {
        KtSimpleNameExpression typeParameterName = typeConstraint.getSubjectTypeParameterName();
        assert typeParameterName != null;
        KtTypeReference bound = typeConstraint.getBoundTypeReference();
        assert bound != null;
        decompiledParameterToBounds.put(typeParameterName.getReferencedNameAsName(), bound.getText());
    }
    for (int i = 0; i < decompiledParameters.size(); i++) {
        KtTypeParameter decompiledParameter = decompiledParameters.get(i);
        TypeParameterDescriptor descriptor = typeParameterDescriptors.get(i);
        Name name = decompiledParameter.getNameAsName();
        assert name != null;
        if (!name.equals(descriptor.getName())) {
            return false;
        }
        Set<String> descriptorUpperBounds = Sets.newHashSet(ContainerUtil.map(descriptor.getUpperBounds(), new Function<KotlinType, String>() {

            @Override
            public String fun(KotlinType type) {
                return DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(type);
            }
        }));
        KotlinBuiltIns builtIns = DescriptorUtilsKt.getBuiltIns(descriptor);
        Set<String> decompiledUpperBounds = decompiledParameterToBounds.get(descriptor.getName()).isEmpty() ? Sets.newHashSet(DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(builtIns.getDefaultBound())) : Sets.newHashSet(decompiledParameterToBounds.get(descriptor.getName()));
        if (!descriptorUpperBounds.equals(decompiledUpperBounds)) {
            return false;
        }
    }
    return true;
}
Also used : TypeParameterDescriptor(org.jetbrains.kotlin.descriptors.TypeParameterDescriptor) KotlinType(org.jetbrains.kotlin.types.KotlinType) Name(org.jetbrains.kotlin.name.Name) Function(com.intellij.util.Function) KotlinBuiltIns(org.jetbrains.kotlin.builtins.KotlinBuiltIns)

Example 13 with TypeParameterDescriptor

use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.

the class DescriptorSubstitutor method substituteTypeParameters.

@NotNull
public static TypeSubstitutor substituteTypeParameters(@ReadOnly @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull TypeSubstitution originalSubstitution, @NotNull DeclarationDescriptor newContainingDeclaration, @NotNull @Mutable List<TypeParameterDescriptor> result) {
    Map<TypeConstructor, TypeProjection> mutableSubstitution = new HashMap<TypeConstructor, TypeProjection>();
    Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> substitutedMap = new HashMap<TypeParameterDescriptor, TypeParameterDescriptorImpl>();
    int index = 0;
    for (TypeParameterDescriptor descriptor : typeParameters) {
        TypeParameterDescriptorImpl substituted = TypeParameterDescriptorImpl.createForFurtherModification(newContainingDeclaration, descriptor.getAnnotations(), descriptor.isReified(), descriptor.getVariance(), descriptor.getName(), index++, SourceElement.NO_SOURCE);
        mutableSubstitution.put(descriptor.getTypeConstructor(), new TypeProjectionImpl(substituted.getDefaultType()));
        substitutedMap.put(descriptor, substituted);
        result.add(substituted);
    }
    TypeSubstitutor substitutor = TypeSubstitutor.createChainedSubstitutor(originalSubstitution, TypeConstructorSubstitution.createByConstructorsMap(mutableSubstitution));
    for (TypeParameterDescriptor descriptor : typeParameters) {
        TypeParameterDescriptorImpl substituted = substitutedMap.get(descriptor);
        for (KotlinType upperBound : descriptor.getUpperBounds()) {
            KotlinType substitutedBound = substitutor.substitute(upperBound, Variance.IN_VARIANCE);
            assert substitutedBound != null : "Upper bound failed to substitute: " + descriptor;
            substituted.addUpperBound(substitutedBound);
        }
        substituted.setInitialized();
    }
    return substitutor;
}
Also used : TypeParameterDescriptor(org.jetbrains.kotlin.descriptors.TypeParameterDescriptor) HashMap(java.util.HashMap) TypeParameterDescriptorImpl(org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl) NotNull(org.jetbrains.annotations.NotNull)

Example 14 with TypeParameterDescriptor

use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.

the class TypeSubstitutor method substituteTypeArguments.

private List<TypeProjection> substituteTypeArguments(List<TypeParameterDescriptor> typeParameters, List<TypeProjection> typeArguments, int recursionDepth) throws SubstitutionException {
    List<TypeProjection> substitutedArguments = new ArrayList<TypeProjection>(typeParameters.size());
    for (int i = 0; i < typeParameters.size(); i++) {
        TypeParameterDescriptor typeParameter = typeParameters.get(i);
        TypeProjection typeArgument = typeArguments.get(i);
        TypeProjection substitutedTypeArgument = unsafeSubstitute(typeArgument, recursionDepth + 1);
        switch(conflictType(typeParameter.getVariance(), substitutedTypeArgument.getProjectionKind())) {
            case NO_CONFLICT:
                // if the corresponding type parameter is already co/contra-variant, there's not need for an explicit projection
                if (typeParameter.getVariance() != Variance.INVARIANT && !substitutedTypeArgument.isStarProjection()) {
                    substitutedTypeArgument = new TypeProjectionImpl(Variance.INVARIANT, substitutedTypeArgument.getType());
                }
                break;
            case OUT_IN_IN_POSITION:
            case IN_IN_OUT_POSITION:
                substitutedTypeArgument = TypeUtils.makeStarProjection(typeParameter);
                break;
        }
        substitutedArguments.add(substitutedTypeArgument);
    }
    return substitutedArguments;
}
Also used : TypeParameterDescriptor(org.jetbrains.kotlin.descriptors.TypeParameterDescriptor) ArrayList(java.util.ArrayList)

Example 15 with TypeParameterDescriptor

use of org.jetbrains.kotlin.descriptors.TypeParameterDescriptor in project kotlin by JetBrains.

the class TypeUtils method canHaveSubtypes.

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;
}
Also used : TypeParameterDescriptor(org.jetbrains.kotlin.descriptors.TypeParameterDescriptor)

Aggregations

TypeParameterDescriptor (org.jetbrains.kotlin.descriptors.TypeParameterDescriptor)15 NotNull (org.jetbrains.annotations.NotNull)5 ClassifierDescriptor (org.jetbrains.kotlin.descriptors.ClassifierDescriptor)4 HashMap (java.util.HashMap)2 ClassDescriptor (org.jetbrains.kotlin.descriptors.ClassDescriptor)2 KotlinType (org.jetbrains.kotlin.types.KotlinType)2 PsiElement (com.intellij.psi.PsiElement)1 Function (com.intellij.util.Function)1 SmartList (com.intellij.util.SmartList)1 File (java.io.File)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 Unit (kotlin.Unit)1 AnalysisResult (org.jetbrains.kotlin.analyzer.AnalysisResult)1 KotlinBuiltIns (org.jetbrains.kotlin.builtins.KotlinBuiltIns)1 ModuleDescriptor (org.jetbrains.kotlin.descriptors.ModuleDescriptor)1 ValueParameterDescriptor (org.jetbrains.kotlin.descriptors.ValueParameterDescriptor)1 TypeParameterDescriptorImpl (org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl)1 Name (org.jetbrains.kotlin.name.Name)1 KtFile (org.jetbrains.kotlin.psi.KtFile)1