Search in sources :

Example 1 with KotlinType

use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.

the class OverridingUtil method isOverridableByWithoutExternalConditions.

@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 (superDescriptor instanceof FunctionDescriptor && subDescriptor instanceof FunctionDescriptor && ((FunctionDescriptor) superDescriptor).isSuspend() != ((FunctionDescriptor) subDescriptor).isSuspend()) {
        return OverrideCompatibilityInfo.conflict("Incompatible suspendability");
    }
    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();
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) KotlinTypeChecker(org.jetbrains.kotlin.types.checker.KotlinTypeChecker) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with KotlinType

use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.

the class AsmUtil method genClosureFields.

public static void genClosureFields(@NotNull CalculatedClosure closure, ClassBuilder v, KotlinTypeMapper typeMapper) {
    List<Pair<String, Type>> allFields = new ArrayList<Pair<String, Type>>();
    ClassifierDescriptor captureThis = closure.getCaptureThis();
    if (captureThis != null) {
        allFields.add(Pair.create(CAPTURED_THIS_FIELD, typeMapper.mapType(captureThis)));
    }
    KotlinType captureReceiverType = closure.getCaptureReceiverType();
    if (captureReceiverType != null && !CallableReferenceUtilKt.isForCallableReference(closure)) {
        allFields.add(Pair.create(CAPTURED_RECEIVER_FIELD, typeMapper.mapType(captureReceiverType)));
    }
    allFields.addAll(closure.getRecordedFields());
    genClosureFields(allFields, v);
}
Also used : IElementType(com.intellij.psi.tree.IElementType) JvmPrimitiveType(org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType) PrimitiveType(org.jetbrains.kotlin.builtins.PrimitiveType) KotlinType(org.jetbrains.kotlin.types.KotlinType) TypeUtils.isNullableType(org.jetbrains.kotlin.types.TypeUtils.isNullableType) KotlinType(org.jetbrains.kotlin.types.KotlinType) ArrayList(java.util.ArrayList) Pair(com.intellij.openapi.util.Pair)

Example 3 with KotlinType

use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.

the class SignaturesPropagationData method modifyValueParametersAccordingToSuperMethods.

private ValueParameters modifyValueParametersAccordingToSuperMethods(@NotNull List<ValueParameterDescriptor> parameters) {
    KotlinType resultReceiverType = null;
    List<ValueParameterDescriptor> resultParameters = new ArrayList<ValueParameterDescriptor>(parameters.size());
    boolean shouldBeExtension = checkIfShouldBeExtension();
    for (final ValueParameterDescriptor originalParam : parameters) {
        final int originalIndex = originalParam.getIndex();
        List<TypeAndName> typesFromSuperMethods = ContainerUtil.map(superFunctions, new Function<FunctionDescriptor, TypeAndName>() {

            @Override
            public TypeAndName fun(FunctionDescriptor superFunction) {
                ReceiverParameterDescriptor receiver = superFunction.getExtensionReceiverParameter();
                int index = receiver != null ? originalIndex - 1 : originalIndex;
                if (index == -1) {
                    assert receiver != null : "can't happen: index is -1, while function is not extension";
                    return new TypeAndName(receiver.getType(), originalParam.getName());
                }
                ValueParameterDescriptor parameter = superFunction.getValueParameters().get(index);
                return new TypeAndName(parameter.getType(), parameter.getName());
            }
        });
        VarargCheckResult varargCheckResult = checkVarargInSuperFunctions(originalParam);
        KotlinType altType = varargCheckResult.parameterType;
        if (shouldBeExtension && originalIndex == 0) {
            resultReceiverType = altType;
        } else {
            Name stableName = null;
            for (int i = 0; i < superFunctions.size(); i++) {
                if (superFunctions.get(i).hasStableParameterNames()) {
                    // When there's more than one stable name in super functions, we pick the first one. This behaviour is similar to
                    // the compiler front-end, except that it reports a warning in such cases
                    // TODO: report a warning somewhere if there's more than one stable name in super functions
                    stableName = typesFromSuperMethods.get(i).name;
                    break;
                }
            }
            resultParameters.add(new ValueParameterDescriptorImpl(originalParam.getContainingDeclaration(), null, shouldBeExtension ? originalIndex - 1 : originalIndex, originalParam.getAnnotations(), stableName != null ? stableName : originalParam.getName(), altType, originalParam.declaresDefaultValue(), originalParam.isCrossinline(), originalParam.isNoinline(), varargCheckResult.isVararg ? DescriptorUtilsKt.getBuiltIns(originalParam).getArrayElementType(altType) : null, SourceElement.NO_SOURCE));
        }
    }
    boolean hasStableParameterNames = CollectionsKt.any(superFunctions, new Function1<FunctionDescriptor, Boolean>() {

        @Override
        public Boolean invoke(FunctionDescriptor descriptor) {
            return descriptor.hasStableParameterNames();
        }
    });
    return new ValueParameters(resultReceiverType, resultParameters, hasStableParameterNames);
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) DescriptorUtils.getFqName(org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName) Name(org.jetbrains.kotlin.name.Name) ValueParameterDescriptorImpl(org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl)

Example 4 with KotlinType

use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.

the class SignaturesPropagationData method getSuperFunctionsForMethod.

private static List<FunctionDescriptor> getSuperFunctionsForMethod(@NotNull JavaMethod method, @NotNull JavaMethodDescriptor autoMethodDescriptor, @NotNull ClassDescriptor containingClass) {
    List<FunctionDescriptor> superFunctions = Lists.newArrayList();
    // TODO: Add propagation for other kotlin descriptors (KT-3621)
    Name name = method.getName();
    Method autoSignature = null;
    boolean autoMethodContainsVararg = SignaturePropagationUtilKt.containsVarargs(autoMethodDescriptor);
    for (KotlinType supertype : containingClass.getTypeConstructor().getSupertypes()) {
        Collection<SimpleFunctionDescriptor> superFunctionCandidates = supertype.getMemberScope().getContributedFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS);
        if (!autoMethodContainsVararg && !SignaturePropagationUtilKt.containsAnyNotTrivialSignature(superFunctionCandidates))
            continue;
        if (autoSignature == null) {
            autoSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(autoMethodDescriptor);
        }
        for (FunctionDescriptor candidate : superFunctionCandidates) {
            // TODO: remove this continue when KT-15747 is fixed
            if (candidate.isSuspend())
                continue;
            Method candidateSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(candidate);
            if (KotlinToJvmSignatureMapperKt.erasedSignaturesEqualIgnoringReturnTypes(autoSignature, candidateSignature)) {
                superFunctions.add(candidate);
            }
        }
    }
    // sorting for diagnostic stability
    Collections.sort(superFunctions, new Comparator<FunctionDescriptor>() {

        @Override
        public int compare(@NotNull FunctionDescriptor fun1, @NotNull FunctionDescriptor fun2) {
            FqNameUnsafe fqName1 = getFqName(fun1.getContainingDeclaration());
            FqNameUnsafe fqName2 = getFqName(fun2.getContainingDeclaration());
            return fqName1.asString().compareTo(fqName2.asString());
        }
    });
    return superFunctions;
}
Also used : FqNameUnsafe(org.jetbrains.kotlin.name.FqNameUnsafe) KotlinType(org.jetbrains.kotlin.types.KotlinType) JavaMethod(org.jetbrains.kotlin.load.java.structure.JavaMethod) Method(org.jetbrains.org.objectweb.asm.commons.Method) DescriptorUtils.getFqName(org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName) Name(org.jetbrains.kotlin.name.Name)

Example 5 with KotlinType

use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.

the class SignaturesPropagationData method checkVarargInSuperFunctions.

@NotNull
private VarargCheckResult checkVarargInSuperFunctions(@NotNull ValueParameterDescriptor originalParam) {
    boolean someSupersVararg = false;
    boolean someSupersNotVararg = false;
    for (FunctionDescriptor superFunction : superFunctions) {
        int originalIndex = originalParam.getIndex();
        int index = superFunction.getExtensionReceiverParameter() != null ? originalIndex - 1 : originalIndex;
        if (index != -1 && superFunction.getValueParameters().get(index).getVarargElementType() != null) {
            someSupersVararg = true;
        } else {
            someSupersNotVararg = true;
        }
    }
    KotlinType originalVarargElementType = originalParam.getVarargElementType();
    KotlinType originalType = originalParam.getType();
    if (someSupersVararg && someSupersNotVararg) {
        reportError("Incompatible super methods: some have vararg parameter, some have not");
        return new VarargCheckResult(originalType, originalVarargElementType != null);
    }
    if (someSupersVararg && originalVarargElementType == null) {
        assert isArrayType(originalType);
        return new VarargCheckResult(TypeUtils.makeNotNullable(originalType), true);
    } else if (someSupersNotVararg && originalVarargElementType != null) {
        assert isArrayType(originalType);
        return new VarargCheckResult(TypeUtils.makeNullable(originalType), false);
    }
    return new VarargCheckResult(originalType, originalVarargElementType != null);
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

KotlinType (org.jetbrains.kotlin.types.KotlinType)110 NotNull (org.jetbrains.annotations.NotNull)34 IElementType (com.intellij.psi.tree.IElementType)16 Type (org.jetbrains.org.objectweb.asm.Type)16 Nullable (org.jetbrains.annotations.Nullable)10 JsExpression (org.jetbrains.kotlin.js.backend.ast.JsExpression)7 PsiElement (com.intellij.psi.PsiElement)6 Name (org.jetbrains.kotlin.name.Name)6 ArrayList (java.util.ArrayList)4 KtExpression (org.jetbrains.kotlin.psi.KtExpression)4 Map (java.util.Map)3 BothSignatureWriter (org.jetbrains.kotlin.codegen.signature.BothSignatureWriter)3 JvmSignatureWriter (org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter)3 VariableDescriptor (org.jetbrains.kotlin.descriptors.VariableDescriptor)3 LocalVariableDescriptor (org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor)3 DataFlowInfo (org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo)3 ExpressionReceiver (org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver)3 PrimitiveType (org.jetbrains.kotlin.builtins.PrimitiveType)2 CallableDescriptor (org.jetbrains.kotlin.descriptors.CallableDescriptor)2 DeclarationDescriptor (org.jetbrains.kotlin.descriptors.DeclarationDescriptor)2