Search in sources :

Example 1 with DataFlowInfo

use of org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo in project kotlin by JetBrains.

the class BasicExpressionTypingVisitor method visitBinaryWithTypeRHSExpression.

@Override
public KotlinTypeInfo visitBinaryWithTypeRHSExpression(@NotNull KtBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context) {
    ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE).replaceContextDependency(INDEPENDENT);
    KtExpression left = expression.getLeft();
    KtTypeReference right = expression.getRight();
    if (right == null) {
        return facade.getTypeInfo(left, contextWithNoExpectedType).clearType();
    }
    IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
    boolean allowBareTypes = BARE_TYPES_ALLOWED.contains(operationType);
    TypeResolutionContext typeResolutionContext = new TypeResolutionContext(context.scope, context.trace, true, allowBareTypes, context.isDebuggerContext);
    PossiblyBareType possiblyBareTarget = components.typeResolver.resolvePossiblyBareType(typeResolutionContext, right);
    KotlinTypeInfo typeInfo = facade.getTypeInfo(left, contextWithNoExpectedType);
    KotlinType subjectType = typeInfo.getType();
    KotlinType targetType = reconstructBareType(right, possiblyBareTarget, subjectType, context.trace, components.builtIns);
    if (subjectType != null) {
        checkBinaryWithTypeRHS(expression, contextWithNoExpectedType, targetType, subjectType);
        DataFlowInfo dataFlowInfo = typeInfo.getDataFlowInfo();
        if (operationType == AS_KEYWORD) {
            DataFlowValue value = createDataFlowValue(left, subjectType, context);
            typeInfo = typeInfo.replaceDataFlowInfo(dataFlowInfo.establishSubtyping(value, targetType, components.languageVersionSettings));
        }
    }
    KotlinType result = operationType == AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType;
    KotlinTypeInfo resultTypeInfo = components.dataFlowAnalyzer.checkType(typeInfo.replaceType(result), expression, context);
    RttiExpressionInformation rttiInformation = new RttiExpressionInformation(expression.getLeft(), subjectType, result, operationType == AS_SAFE ? RttiOperation.SAFE_AS : RttiOperation.AS);
    for (RttiExpressionChecker checker : components.rttiExpressionCheckers) {
        checker.check(rttiInformation, expression, context.trace);
    }
    return resultTypeInfo;
}
Also used : DataFlowValue(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue) DataFlowValueFactory.createDataFlowValue(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory.createDataFlowValue) IElementType(com.intellij.psi.tree.IElementType) DataFlowInfo(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo)

Example 2 with DataFlowInfo

use of org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo in project kotlin by JetBrains.

the class BasicExpressionTypingVisitor method visitObjectLiteralExpression.

@Override
public KotlinTypeInfo visitObjectLiteralExpression(@NotNull final KtObjectLiteralExpression expression, final ExpressionTypingContext context) {
    final KotlinType[] result = new KotlinType[1];
    TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve object literal expression", expression);
    ObservableBindingTrace.RecordHandler<PsiElement, ClassDescriptor> handler = new ObservableBindingTrace.RecordHandler<PsiElement, ClassDescriptor>() {

        @Override
        public void handleRecord(WritableSlice<PsiElement, ClassDescriptor> slice, PsiElement declaration, final ClassDescriptor descriptor) {
            if (slice == CLASS && declaration == expression.getObjectDeclaration()) {
                KotlinType defaultType = components.wrappedTypeFactory.createRecursionIntolerantDeferredType(context.trace, new Function0<KotlinType>() {

                    @Override
                    public KotlinType invoke() {
                        return descriptor.getDefaultType();
                    }
                });
                result[0] = defaultType;
            }
        }
    };
    ObservableBindingTrace traceAdapter = new ObservableBindingTrace(temporaryTrace);
    traceAdapter.addHandler(CLASS, handler);
    // don't need to add classifier of object literal to any scope
    components.localClassifierAnalyzer.processClassOrObject(// don't need to add classifier of object literal to any scope
    null, context.replaceBindingTrace(traceAdapter).replaceContextDependency(INDEPENDENT), context.scope.getOwnerDescriptor(), expression.getObjectDeclaration());
    temporaryTrace.commit();
    DataFlowInfo resultFlowInfo = context.dataFlowInfo;
    for (KtSuperTypeListEntry specifier : expression.getObjectDeclaration().getSuperTypeListEntries()) {
        if (specifier instanceof KtSuperTypeCallEntry) {
            KtSuperTypeCallEntry delegator = (KtSuperTypeCallEntry) specifier;
            KotlinTypeInfo delegatorTypeInfo = context.trace.get(EXPRESSION_TYPE_INFO, delegator.getCalleeExpression());
            if (delegatorTypeInfo != null) {
                resultFlowInfo = resultFlowInfo.and(delegatorTypeInfo.getDataFlowInfo());
            }
        }
    }
    // Breaks are not possible inside constructor arguments, so jumpPossible or jumpFlowInfo are not necessary here
    KotlinTypeInfo resultTypeInfo = components.dataFlowAnalyzer.checkType(TypeInfoFactoryKt.createTypeInfo(result[0], resultFlowInfo), expression, context);
    // We have to record it here,
    // otherwise ExpressionTypingVisitorDispatcher records wrong information
    context.trace.record(EXPRESSION_TYPE_INFO, expression, resultTypeInfo);
    context.trace.record(PROCESSED, expression);
    return resultTypeInfo;
}
Also used : WritableSlice(org.jetbrains.kotlin.util.slicedMap.WritableSlice) PsiElement(com.intellij.psi.PsiElement) DataFlowInfo(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo)

Example 3 with DataFlowInfo

use of org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo in project kotlin by JetBrains.

the class BasicExpressionTypingVisitor method checkInExpression.

@NotNull
public KotlinTypeInfo checkInExpression(@NotNull KtElement callElement, @NotNull KtSimpleNameExpression operationSign, @NotNull ValueArgument leftArgument, @Nullable KtExpression right, @NotNull ExpressionTypingContext context) {
    KtExpression left = leftArgument.getArgumentExpression();
    ExpressionTypingContext contextWithNoExpectedType = context.replaceExpectedType(NO_EXPECTED_TYPE);
    if (right == null) {
        if (left != null)
            facade.getTypeInfo(left, contextWithNoExpectedType);
        return TypeInfoFactoryKt.noTypeInfo(context);
    }
    KotlinTypeInfo rightTypeInfo = facade.getTypeInfo(right, contextWithNoExpectedType);
    DataFlowInfo dataFlowInfo = rightTypeInfo.getDataFlowInfo();
    ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, contextWithNoExpectedType);
    ExpressionTypingContext contextWithDataFlow = context.replaceDataFlowInfo(dataFlowInfo);
    OverloadResolutionResults<FunctionDescriptor> resolutionResult = components.callResolver.resolveCallWithGivenName(contextWithDataFlow, CallMaker.makeCall(callElement, receiver, null, operationSign, Collections.singletonList(leftArgument)), operationSign, OperatorNameConventions.CONTAINS);
    KotlinType containsType = OverloadResolutionResultsUtil.getResultingType(resolutionResult, context.contextDependency);
    ensureBooleanResult(operationSign, OperatorNameConventions.CONTAINS, containsType, context);
    if (left != null) {
        dataFlowInfo = facade.getTypeInfo(left, contextWithDataFlow).getDataFlowInfo().and(dataFlowInfo);
        rightTypeInfo = rightTypeInfo.replaceDataFlowInfo(dataFlowInfo);
    }
    if (resolutionResult.isSuccess()) {
        return rightTypeInfo.replaceType(components.builtIns.getBooleanType());
    } else {
        return rightTypeInfo.clearType();
    }
}
Also used : ExpressionReceiver(org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver) DataFlowInfo(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo) NotNull(org.jetbrains.annotations.NotNull)

Example 4 with DataFlowInfo

use of org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo in project kotlin by JetBrains.

the class ControlStructureTypingUtils method createDataFlowInfoForArgumentsOfWhenCall.

public static MutableDataFlowInfoForArguments createDataFlowInfoForArgumentsOfWhenCall(@NotNull Call callForWhen, @NotNull DataFlowInfo subjectDataFlowInfo, @NotNull List<DataFlowInfo> entryDataFlowInfos) {
    Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap = Maps.newHashMap();
    int i = 0;
    for (ValueArgument argument : callForWhen.getValueArguments()) {
        DataFlowInfo entryDataFlowInfo = entryDataFlowInfos.get(i++);
        dataFlowInfoForArgumentsMap.put(argument, entryDataFlowInfo);
    }
    return createIndependentDataFlowInfoForArgumentsForCall(subjectDataFlowInfo, dataFlowInfoForArgumentsMap);
}
Also used : DataFlowInfo(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo)

Example 5 with DataFlowInfo

use of org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo in project kotlin by JetBrains.

the class BasicExpressionTypingVisitor method visitExclExclExpression.

private KotlinTypeInfo visitExclExclExpression(@NotNull KtUnaryExpression expression, @NotNull ExpressionTypingContext context) {
    KtExpression baseExpression = expression.getBaseExpression();
    assert baseExpression != null;
    KtSimpleNameExpression operationSign = expression.getOperationReference();
    assert operationSign.getReferencedNameElementType() == KtTokens.EXCLEXCL;
    // TODO: something must be done for not to lose safe call chain information here
    // See also CallExpressionResolver.getSimpleNameExpressionTypeInfo, .getQualifiedExpressionTypeInfo
    Call call = createCallForSpecialConstruction(expression, expression.getOperationReference(), Collections.singletonList(baseExpression));
    components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(call, ResolveConstruct.EXCL_EXCL, Collections.singletonList("baseExpr"), Collections.singletonList(true), context, null);
    KotlinTypeInfo baseTypeInfo = BindingContextUtils.getRecordedTypeInfo(baseExpression, context.trace.getBindingContext());
    if (ArgumentTypeResolver.isFunctionLiteralArgument(baseExpression, context)) {
        context.trace.report(NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION.on(operationSign));
        if (baseTypeInfo == null) {
            return TypeInfoFactoryKt.createTypeInfo(ErrorUtils.createErrorType("Unresolved lambda expression"), context);
        }
        return baseTypeInfo;
    }
    assert baseTypeInfo != null : "Base expression was not processed: " + expression;
    KotlinType baseType = baseTypeInfo.getType();
    if (baseType == null) {
        return baseTypeInfo;
    }
    DataFlowInfo dataFlowInfo = baseTypeInfo.getDataFlowInfo();
    if (isKnownToBeNotNull(baseExpression, context) && !baseType.isError()) {
        context.trace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, TypeUtils.makeNotNullable(baseType)));
    } else {
        DataFlowValue value = createDataFlowValue(baseExpression, baseType, context);
        baseTypeInfo = baseTypeInfo.replaceDataFlowInfo(dataFlowInfo.disequate(value, DataFlowValue.nullValue(components.builtIns), components.languageVersionSettings));
    }
    KotlinType resultingType = TypeUtils.makeNotNullable(baseType);
    if (context.contextDependency == DEPENDENT) {
        return baseTypeInfo.replaceType(resultingType);
    }
    // The call to checkType() is only needed here to execute additionalTypeCheckers, hence the NO_EXPECTED_TYPE
    return components.dataFlowAnalyzer.checkType(baseTypeInfo.replaceType(resultingType), expression, context.replaceExpectedType(NO_EXPECTED_TYPE));
}
Also used : ResolvedCall(org.jetbrains.kotlin.resolve.calls.model.ResolvedCall) DataFlowValue(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue) DataFlowValueFactory.createDataFlowValue(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory.createDataFlowValue) DataFlowInfo(org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo)

Aggregations

DataFlowInfo (org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo)16 DataFlowValue (org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue)6 NotNull (org.jetbrains.annotations.NotNull)5 ResolvedCall (org.jetbrains.kotlin.resolve.calls.model.ResolvedCall)4 LexicalWritableScope (org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope)4 DataFlowValueFactory.createDataFlowValue (org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory.createDataFlowValue)3 KotlinType (org.jetbrains.kotlin.types.KotlinType)3 ExpressionReceiver (org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver)2 PsiElement (com.intellij.psi.PsiElement)1 IElementType (com.intellij.psi.tree.IElementType)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Function1 (kotlin.jvm.functions.Function1)1 SyntheticFieldDescriptor (org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor)1 ValueArgument (org.jetbrains.kotlin.psi.ValueArgument)1 BindingContext (org.jetbrains.kotlin.resolve.BindingContext)1 CallPosition (org.jetbrains.kotlin.resolve.calls.context.CallPosition)1 MutableDataFlowInfoForArguments (org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments)1 LexicalScope (org.jetbrains.kotlin.resolve.scopes.LexicalScope)1 ControlStructureTypingUtils.createDataFlowInfoForArgumentsForIfCall (org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createDataFlowInfoForArgumentsForIfCall)1