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;
}
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;
}
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();
}
}
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);
}
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));
}
Aggregations