use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class SwitchCodegen method generateNullCheckIfNeeded.
protected void generateNullCheckIfNeeded() {
assert expression.getSubjectExpression() != null : "subject expression can't be null";
KotlinType subjectJetType = bindingContext.getType(expression.getSubjectExpression());
assert subjectJetType != null : "subject type can't be null (i.e. void)";
if (TypeUtils.isNullableType(subjectJetType)) {
int nullEntryIndex = findNullEntryIndex(expression);
Label nullLabel = nullEntryIndex == -1 ? defaultLabel : entryLabels.get(nullEntryIndex);
Label notNullLabel = new Label();
v.dup();
v.ifnonnull(notNullLabel);
v.pop();
v.goTo(nullLabel);
v.visitLabel(notNullLabel);
}
}
use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class MoveDeclarationsOutHelper method createVariableDeclaration.
@NotNull
private static KtProperty createVariableDeclaration(@NotNull KtProperty property, boolean generateDefaultInitializers) {
KotlinType propertyType = getPropertyType(property);
String defaultInitializer = null;
if (generateDefaultInitializers && property.isVar()) {
defaultInitializer = CodeInsightUtils.defaultInitializer(propertyType);
}
return createProperty(property, propertyType, defaultInitializer);
}
use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class KotlinExpressionSurrounder method isApplicable.
@Override
public boolean isApplicable(@NotNull PsiElement[] elements) {
if (elements.length != 1 || !(elements[0] instanceof KtExpression)) {
return false;
}
KtExpression expression = (KtExpression) elements[0];
if (expression instanceof KtCallExpression && expression.getParent() instanceof KtQualifiedExpression) {
return false;
}
KotlinType type = ResolutionUtils.analyze(expression, BodyResolveMode.PARTIAL).getType(expression);
if (type == null || isUnit(type)) {
return false;
}
return isApplicable(expression);
}
use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class ExpressionTypingVisitorDispatcher method recordTypeInfo.
private void recordTypeInfo(@NotNull KtExpression expression, @NotNull KotlinTypeInfo typeInfo) {
LookupTracker lookupTracker = getComponents().lookupTracker;
KotlinType resultType = typeInfo.getType();
if (resultType != null) {
LookupTrackerUtilKt.record(lookupTracker, expression, resultType);
}
}
use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class ExpressionTypingVisitorForStatements method visitAssignmentOperation.
@NotNull
protected KotlinTypeInfo visitAssignmentOperation(KtBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) {
//There is a temporary binding trace for an opportunity to resolve set method for array if needed (the initial trace should be used there)
TemporaryTraceAndCache temporary = TemporaryTraceAndCache.create(contextWithExpectedType, "trace to resolve array set method for binary expression", expression);
ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE).replaceTraceAndCache(temporary).replaceContextDependency(INDEPENDENT);
KtSimpleNameExpression operationSign = expression.getOperationReference();
IElementType operationType = operationSign.getReferencedNameElementType();
KtExpression leftOperand = expression.getLeft();
KotlinTypeInfo leftInfo = ExpressionTypingUtils.getTypeInfoOrNullType(leftOperand, context, facade);
KotlinType leftType = leftInfo.getType();
KtExpression right = expression.getRight();
KtExpression left = leftOperand == null ? null : deparenthesize(leftOperand);
if (right == null || left == null) {
temporary.commit();
return leftInfo.clearType();
}
if (leftType == null) {
KotlinTypeInfo rightInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(leftInfo.getDataFlowInfo()));
context.trace.report(UNRESOLVED_REFERENCE.on(operationSign, operationSign));
temporary.commit();
return rightInfo.clearType();
}
ExpressionReceiver receiver = ExpressionReceiver.Companion.create(left, leftType, context.trace.getBindingContext());
// We check that defined only one of '+=' and '+' operations, and call it (in the case '+' we then also assign)
// Check for '+='
Name name = OperatorConventions.ASSIGNMENT_OPERATIONS.get(operationType);
TemporaryTraceAndCache temporaryForAssignmentOperation = TemporaryTraceAndCache.create(context, "trace to check assignment operation like '+=' for", expression);
OverloadResolutionResults<FunctionDescriptor> assignmentOperationDescriptors = components.callResolver.resolveBinaryCall(context.replaceTraceAndCache(temporaryForAssignmentOperation).replaceScope(scope), receiver, expression, name);
KotlinType assignmentOperationType = OverloadResolutionResultsUtil.getResultingType(assignmentOperationDescriptors, context.contextDependency);
OverloadResolutionResults<FunctionDescriptor> binaryOperationDescriptors;
KotlinType binaryOperationType;
TemporaryTraceAndCache temporaryForBinaryOperation = TemporaryTraceAndCache.create(context, "trace to check binary operation like '+' for", expression);
TemporaryBindingTrace ignoreReportsTrace = TemporaryBindingTrace.create(context.trace, "Trace for checking assignability");
boolean lhsAssignable = basic.checkLValue(ignoreReportsTrace, context, left, right, expression);
if (assignmentOperationType == null || lhsAssignable) {
// Check for '+'
Name counterpartName = OperatorConventions.BINARY_OPERATION_NAMES.get(OperatorConventions.ASSIGNMENT_OPERATION_COUNTERPARTS.get(operationType));
binaryOperationDescriptors = components.callResolver.resolveBinaryCall(context.replaceTraceAndCache(temporaryForBinaryOperation).replaceScope(scope), receiver, expression, counterpartName);
binaryOperationType = OverloadResolutionResultsUtil.getResultingType(binaryOperationDescriptors, context.contextDependency);
} else {
binaryOperationDescriptors = OverloadResolutionResultsImpl.nameNotFound();
binaryOperationType = null;
}
KotlinType type = assignmentOperationType != null ? assignmentOperationType : binaryOperationType;
KotlinTypeInfo rightInfo = leftInfo;
boolean hasRemAssignOperation = atLeastOneOperation(assignmentOperationDescriptors.getResultingCalls(), OperatorNameConventions.REM_ASSIGN);
boolean hasRemBinaryOperation = atLeastOneOperation(binaryOperationDescriptors.getResultingCalls(), OperatorNameConventions.REM);
boolean oneTypeOfModRemOperations = hasRemAssignOperation == hasRemBinaryOperation;
if (assignmentOperationDescriptors.isSuccess() && binaryOperationDescriptors.isSuccess() && oneTypeOfModRemOperations) {
// Both 'plus()' and 'plusAssign()' available => ambiguity
OverloadResolutionResults<FunctionDescriptor> ambiguityResolutionResults = OverloadResolutionResultsUtil.ambiguity(assignmentOperationDescriptors, binaryOperationDescriptors);
context.trace.report(ASSIGN_OPERATOR_AMBIGUITY.on(operationSign, ambiguityResolutionResults.getResultingCalls()));
Collection<DeclarationDescriptor> descriptors = Sets.newHashSet();
for (ResolvedCall<?> resolvedCall : ambiguityResolutionResults.getResultingCalls()) {
descriptors.add(resolvedCall.getResultingDescriptor());
}
rightInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(leftInfo.getDataFlowInfo()));
context.trace.record(AMBIGUOUS_REFERENCE_TARGET, operationSign, descriptors);
} else if (assignmentOperationType != null && (assignmentOperationDescriptors.isSuccess() || !binaryOperationDescriptors.isSuccess()) && (!hasRemBinaryOperation || !binaryOperationDescriptors.isSuccess())) {
// There's 'plusAssign()', so we do a.plusAssign(b)
temporaryForAssignmentOperation.commit();
if (!KotlinTypeChecker.DEFAULT.equalTypes(components.builtIns.getUnitType(), assignmentOperationType)) {
context.trace.report(ASSIGNMENT_OPERATOR_SHOULD_RETURN_UNIT.on(operationSign, assignmentOperationDescriptors.getResultingDescriptor(), operationSign));
}
} else {
// There's only 'plus()', so we try 'a = a + b'
temporaryForBinaryOperation.commit();
context.trace.record(VARIABLE_REASSIGNMENT, expression);
if (left instanceof KtArrayAccessExpression) {
ExpressionTypingContext contextForResolve = context.replaceScope(scope).replaceBindingTrace(TemporaryBindingTrace.create(context.trace, "trace to resolve array set method for assignment", expression));
basic.resolveImplicitArrayAccessSetMethod((KtArrayAccessExpression) left, right, contextForResolve, context.trace);
}
rightInfo = facade.getTypeInfo(right, context.replaceDataFlowInfo(leftInfo.getDataFlowInfo()));
KotlinType expectedType = refineTypeFromPropertySetterIfPossible(context.trace.getBindingContext(), leftOperand, leftType);
components.dataFlowAnalyzer.checkType(binaryOperationType, expression, context.replaceExpectedType(expectedType).replaceDataFlowInfo(rightInfo.getDataFlowInfo()).replaceCallPosition(new CallPosition.PropertyAssignment(left)));
basic.checkLValue(context.trace, context, leftOperand, right, expression);
}
temporary.commit();
return rightInfo.replaceType(checkAssignmentType(type, expression, contextWithExpectedType));
}
Aggregations