Search in sources :

Example 6 with ExpressionReceiver

use of org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver in project kotlin by JetBrains.

the class BasicExpressionTypingVisitor method visitEquality.

private KotlinTypeInfo visitEquality(KtBinaryExpression expression, ExpressionTypingContext context, KtSimpleNameExpression operationSign, final KtExpression left, final KtExpression right) {
    if (right == null || left == null) {
        ExpressionTypingUtils.getTypeInfoOrNullType(right, context, facade);
        ExpressionTypingUtils.getTypeInfoOrNullType(left, context, facade);
        return TypeInfoFactoryKt.createTypeInfo(components.builtIns.getBooleanType(), context);
    }
    KotlinTypeInfo leftTypeInfo = getTypeInfoOrNullType(left, context, facade);
    DataFlowInfo dataFlowInfo = leftTypeInfo.getDataFlowInfo();
    ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
    KotlinTypeInfo rightTypeInfo = facade.getTypeInfo(right, contextWithDataFlow);
    TemporaryBindingTrace traceInterpretingRightAsNullableAny = TemporaryBindingTrace.create(context.trace, "trace to resolve 'equals(Any?)' interpreting as of type Any? an expression:", right);
    traceInterpretingRightAsNullableAny.recordType(right, components.builtIns.getNullableAnyType());
    // Nothing? has no members, and `equals()` would be unresolved on it
    KotlinType leftType = leftTypeInfo.getType();
    if (leftType != null && KotlinBuiltIns.isNothingOrNullableNothing(leftType)) {
        traceInterpretingRightAsNullableAny.recordType(left, components.builtIns.getNullableAnyType());
    }
    ExpressionTypingContext newContext = context.replaceBindingTrace(traceInterpretingRightAsNullableAny);
    ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, newContext);
    Call call = CallMaker.makeCallWithExpressions(expression, receiver, // semantically, a call to `==` is a safe call
    new KtPsiFactory(expression.getProject()).createSafeCallNode(), operationSign, Collections.singletonList(right));
    OverloadResolutionResults<FunctionDescriptor> resolutionResults = components.callResolver.resolveCallWithGivenName(newContext, call, operationSign, OperatorNameConventions.EQUALS);
    traceInterpretingRightAsNullableAny.commit(new TraceEntryFilter() {

        @Override
        public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
            // the type of the right (and sometimes left) expression isn't 'Any?' actually
            if ((key == right || key == left) && slice == EXPRESSION_TYPE_INFO)
                return false;
            return true;
        }
    }, true);
    if (resolutionResults.isSuccess()) {
        FunctionDescriptor equals = resolutionResults.getResultingCall().getResultingDescriptor();
        if (ensureBooleanResult(operationSign, OperatorNameConventions.EQUALS, equals.getReturnType(), context)) {
            ensureNonemptyIntersectionOfOperandTypes(expression, context);
        }
    } else {
        if (resolutionResults.isAmbiguity()) {
            context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResultingCalls()));
        } else {
            context.trace.report(EQUALS_MISSING.on(operationSign));
        }
    }
    return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
}
Also used : ResolvedCall(org.jetbrains.kotlin.resolve.calls.model.ResolvedCall) ExpressionReceiver(org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver) DataFlowInfo(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo)

Example 7 with ExpressionReceiver

use of org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver in project kotlin by JetBrains.

the class ControlStructureTypingVisitor method visitForExpression.

public KotlinTypeInfo visitForExpression(KtForExpression expression, ExpressionTypingContext contextWithExpectedType, boolean isStatement) {
    if (!isStatement)
        return components.dataFlowAnalyzer.illegalStatementType(expression, contextWithExpectedType, facade);
    ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
    // Preliminary analysis
    PreliminaryLoopVisitor loopVisitor = PreliminaryLoopVisitor.visitLoop(expression);
    context = context.replaceDataFlowInfo(loopVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo, components.languageVersionSettings));
    KtExpression loopRange = expression.getLoopRange();
    KotlinType expectedParameterType = null;
    KotlinTypeInfo loopRangeInfo;
    if (loopRange != null) {
        ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope));
        loopRangeInfo = facade.getTypeInfo(loopRange, context);
        if (loopRangeReceiver != null) {
            expectedParameterType = components.forLoopConventionsChecker.checkIterableConvention(loopRangeReceiver, context);
        }
    } else {
        loopRangeInfo = TypeInfoFactoryKt.noTypeInfo(context);
    }
    LexicalWritableScope loopScope = newWritableScopeImpl(context, LexicalScopeKind.FOR, components.overloadChecker);
    KtParameter loopParameter = expression.getLoopParameter();
    if (loopParameter != null) {
        VariableDescriptor variableDescriptor = createLoopParameterDescriptor(loopParameter, expectedParameterType, context);
        ModifiersChecker.ModifiersCheckingProcedure modifiersCheckingProcedure = components.modifiersChecker.withTrace(context.trace);
        modifiersCheckingProcedure.checkModifiersForLocalDeclaration(loopParameter, variableDescriptor);
        components.identifierChecker.checkDeclaration(loopParameter, context.trace);
        loopScope.addVariableDescriptor(variableDescriptor);
        KtDestructuringDeclaration multiParameter = loopParameter.getDestructuringDeclaration();
        if (multiParameter != null) {
            KotlinType elementType = expectedParameterType == null ? ErrorUtils.createErrorType("Loop range has no type") : expectedParameterType;
            TransientReceiver iteratorNextAsReceiver = new TransientReceiver(elementType);
            components.annotationResolver.resolveAnnotationsWithArguments(loopScope, loopParameter.getModifierList(), context.trace);
            components.destructuringDeclarationResolver.defineLocalVariablesFromDestructuringDeclaration(loopScope, multiParameter, iteratorNextAsReceiver, loopRange, context);
            modifiersCheckingProcedure.checkModifiersForDestructuringDeclaration(multiParameter);
            components.identifierChecker.checkDeclaration(multiParameter, context.trace);
        }
    }
    KtExpression body = expression.getBody();
    KotlinTypeInfo bodyTypeInfo;
    if (body != null) {
        bodyTypeInfo = components.expressionTypingServices.getBlockReturnedTypeWithWritableScope(loopScope, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context.replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo()));
    } else {
        bodyTypeInfo = loopRangeInfo;
    }
    return components.dataFlowAnalyzer.checkType(bodyTypeInfo.replaceType(components.builtIns.getUnitType()), expression, contextWithExpectedType).replaceDataFlowInfo(loopRangeInfo.getDataFlowInfo());
}
Also used : KotlinType(org.jetbrains.kotlin.types.KotlinType) ExpressionReceiver(org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver) LexicalWritableScope(org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope) ModifiersChecker(org.jetbrains.kotlin.resolve.ModifiersChecker) TransientReceiver(org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver)

Example 8 with ExpressionReceiver

use of org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver in project kotlin by JetBrains.

the class CallResolver method resolveFunctionCall.

@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveFunctionCall(@NotNull BasicCallResolutionContext context) {
    ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
    Call.CallType callType = context.call.getCallType();
    if (callType == Call.CallType.ARRAY_GET_METHOD || callType == Call.CallType.ARRAY_SET_METHOD) {
        Name name = callType == Call.CallType.ARRAY_GET_METHOD ? OperatorNameConventions.GET : OperatorNameConventions.SET;
        KtArrayAccessExpression arrayAccessExpression = (KtArrayAccessExpression) context.call.getCallElement();
        return computeTasksAndResolveCall(context, name, arrayAccessExpression, NewResolutionOldInference.ResolutionKind.Function.INSTANCE);
    }
    KtExpression calleeExpression = context.call.getCalleeExpression();
    if (calleeExpression instanceof KtSimpleNameExpression) {
        KtSimpleNameExpression expression = (KtSimpleNameExpression) calleeExpression;
        return computeTasksAndResolveCall(context, expression.getReferencedNameAsName(), expression, NewResolutionOldInference.ResolutionKind.Function.INSTANCE);
    } else if (calleeExpression instanceof KtConstructorCalleeExpression) {
        return (OverloadResolutionResults) resolveCallForConstructor(context, (KtConstructorCalleeExpression) calleeExpression);
    } else if (calleeExpression instanceof KtConstructorDelegationReferenceExpression) {
        KtConstructorDelegationCall delegationCall = (KtConstructorDelegationCall) context.call.getCallElement();
        DeclarationDescriptor container = context.scope.getOwnerDescriptor();
        assert container instanceof ConstructorDescriptor : "Trying to resolve JetConstructorDelegationCall not in constructor. scope.ownerDescriptor = " + container;
        return (OverloadResolutionResults) resolveConstructorDelegationCall(context, delegationCall, (KtConstructorDelegationReferenceExpression) calleeExpression, (ClassConstructorDescriptor) container);
    } else if (calleeExpression == null) {
        return checkArgumentTypesAndFail(context);
    }
    // Here we handle the case where the callee expression must be something of type function, e.g. (foo.bar())(1, 2)
    KotlinType expectedType = NO_EXPECTED_TYPE;
    if (calleeExpression instanceof KtLambdaExpression) {
        int parameterNumber = ((KtLambdaExpression) calleeExpression).getValueParameters().size();
        List<KotlinType> parameterTypes = new ArrayList<KotlinType>(parameterNumber);
        for (int i = 0; i < parameterNumber; i++) {
            parameterTypes.add(NO_EXPECTED_TYPE);
        }
        expectedType = FunctionTypesKt.createFunctionType(builtIns, Annotations.Companion.getEMPTY(), null, parameterTypes, null, context.expectedType);
    }
    KotlinType calleeType = expressionTypingServices.safeGetType(context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.trace);
    ExpressionReceiver expressionReceiver = ExpressionReceiver.Companion.create(calleeExpression, calleeType, context.trace.getBindingContext());
    Call call = new CallTransformer.CallForImplicitInvoke(context.call.getExplicitReceiver(), expressionReceiver, context.call, false);
    TracingStrategyForInvoke tracingForInvoke = new TracingStrategyForInvoke(calleeExpression, call, calleeType);
    return resolveCallForInvoke(context.replaceCall(call), tracingForInvoke);
}
Also used : OverloadResolutionResults(org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults) KotlinType(org.jetbrains.kotlin.types.KotlinType) Name(org.jetbrains.kotlin.name.Name) ExpressionReceiver(org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver) NotNull(org.jetbrains.annotations.NotNull)

Example 9 with ExpressionReceiver

use of org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver in project kotlin by JetBrains.

the class BasicExpressionTypingVisitor method getTypeInfoForBinaryCall.

@NotNull
public KotlinTypeInfo getTypeInfoForBinaryCall(@NotNull Name name, @NotNull ExpressionTypingContext context, @NotNull KtBinaryExpression binaryExpression) {
    KtExpression left = binaryExpression.getLeft();
    KotlinTypeInfo typeInfo;
    if (left != null) {
        //left here is a receiver, so it doesn't depend on expected type
        typeInfo = facade.getTypeInfo(left, context.replaceContextDependency(INDEPENDENT).replaceExpectedType(NO_EXPECTED_TYPE));
    } else {
        typeInfo = TypeInfoFactoryKt.noTypeInfo(context);
    }
    ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(typeInfo.getDataFlowInfo());
    OverloadResolutionResults<FunctionDescriptor> resolutionResults;
    if (left != null) {
        ExpressionReceiver receiver = safeGetExpressionReceiver(facade, left, context);
        resolutionResults = components.callResolver.resolveBinaryCall(contextWithDataFlow.replaceScope(context.scope), receiver, binaryExpression, name);
    } else {
        resolutionResults = OverloadResolutionResultsImpl.nameNotFound();
    }
    if (resolutionResults.isSingleResult()) {
        typeInfo = typeInfo.replaceDataFlowInfo(resolutionResults.getResultingCall().getDataFlowInfoForArguments().getResultInfo());
    }
    return typeInfo.replaceType(OverloadResolutionResultsUtil.getResultingType(resolutionResults, context.contextDependency));
}
Also used : ExpressionReceiver(org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver) NotNull(org.jetbrains.annotations.NotNull)

Example 10 with ExpressionReceiver

use of org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver in project kotlin by JetBrains.

the class BasicExpressionTypingVisitor method resolveArrayAccessSpecialMethod.

@NotNull
private KotlinTypeInfo resolveArrayAccessSpecialMethod(@NotNull KtArrayAccessExpression arrayAccessExpression, //only for 'set' method
@Nullable KtExpression rightHandSide, @NotNull ExpressionTypingContext oldContext, @NotNull BindingTrace traceForResolveResult, boolean isGet, boolean isImplicit) {
    KtExpression arrayExpression = arrayAccessExpression.getArrayExpression();
    if (arrayExpression == null)
        return TypeInfoFactoryKt.noTypeInfo(oldContext);
    KotlinTypeInfo arrayTypeInfo = facade.safeGetTypeInfo(arrayExpression, oldContext.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT));
    KotlinType arrayType = ExpressionTypingUtils.safeGetType(arrayTypeInfo);
    ExpressionTypingContext context = oldContext.replaceDataFlowInfo(arrayTypeInfo.getDataFlowInfo());
    ExpressionReceiver receiver = ExpressionReceiver.Companion.create(arrayExpression, arrayType, context.trace.getBindingContext());
    if (!isGet)
        assert rightHandSide != null;
    Call call = isGet ? CallMaker.makeArrayGetCall(receiver, arrayAccessExpression, Call.CallType.ARRAY_GET_METHOD) : CallMaker.makeArraySetCall(receiver, arrayAccessExpression, rightHandSide, Call.CallType.ARRAY_SET_METHOD);
    OverloadResolutionResults<FunctionDescriptor> functionResults = components.callResolver.resolveCallWithGivenName(context, call, arrayAccessExpression, isGet ? OperatorNameConventions.GET : OperatorNameConventions.SET);
    List<KtExpression> indices = arrayAccessExpression.getIndexExpressions();
    // The accumulated data flow info of all index expressions is saved on the last index
    KotlinTypeInfo resultTypeInfo = arrayTypeInfo;
    if (!indices.isEmpty()) {
        resultTypeInfo = facade.getTypeInfo(indices.get(indices.size() - 1), context);
    }
    if (!isGet) {
        resultTypeInfo = facade.getTypeInfo(rightHandSide, context);
    }
    if ((isImplicit && !functionResults.isSuccess()) || !functionResults.isSingleResult()) {
        traceForResolveResult.report(isGet ? NO_GET_METHOD.on(arrayAccessExpression) : NO_SET_METHOD.on(arrayAccessExpression));
        return resultTypeInfo.clearType();
    }
    traceForResolveResult.record(isGet ? INDEXED_LVALUE_GET : INDEXED_LVALUE_SET, arrayAccessExpression, functionResults.getResultingCall());
    return resultTypeInfo.replaceType(functionResults.getResultingDescriptor().getReturnType());
}
Also used : ResolvedCall(org.jetbrains.kotlin.resolve.calls.model.ResolvedCall) ExpressionReceiver(org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

ExpressionReceiver (org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver)11 NotNull (org.jetbrains.annotations.NotNull)5 Name (org.jetbrains.kotlin.name.Name)3 ResolvedCall (org.jetbrains.kotlin.resolve.calls.model.ResolvedCall)3 KotlinType (org.jetbrains.kotlin.types.KotlinType)3 IElementType (com.intellij.psi.tree.IElementType)2 DataFlowInfo (org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo)2 Nullable (org.jetbrains.annotations.Nullable)1 FunctionDescriptor (org.jetbrains.kotlin.descriptors.FunctionDescriptor)1 ModifiersChecker (org.jetbrains.kotlin.resolve.ModifiersChecker)1 TemporaryBindingTrace (org.jetbrains.kotlin.resolve.TemporaryBindingTrace)1 CallPosition (org.jetbrains.kotlin.resolve.calls.context.CallPosition)1 TemporaryTraceAndCache (org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache)1 OverloadResolutionResults (org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults)1 DataFlowValue (org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue)1 DataFlowValueFactory.createDataFlowValue (org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory.createDataFlowValue)1 LexicalWritableScope (org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope)1 ReceiverValue (org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue)1 TransientReceiver (org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver)1