Report invisible setter error if it's resolved to synthetic property of base class with public getter and protected setter
^KT-11713 Fixed
This commit is contained in:
@@ -1033,7 +1033,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtTypeParameterList> LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<KtTypeParameterList> LOCAL_VARIABLE_WITH_TYPE_PARAMETERS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory3<KtExpression, DeclarationDescriptor, DescriptorVisibility, DeclarationDescriptor> INVISIBLE_SETTER = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory3<PsiElement, DeclarationDescriptor, DescriptorVisibility, DeclarationDescriptor> INVISIBLE_SETTER = DiagnosticFactory3.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_LOOP_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_FUN_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
@@ -51,25 +51,23 @@ fun ResolutionContext<*>.reportTypeMismatchDueToTypeProjection(
|
||||
): Boolean {
|
||||
if (!TypeUtils.contains(expectedType) { it.isAnyOrNullableAny() || it.isNothing() || it.isNullableNothing() }) return false
|
||||
|
||||
val callPosition = this.callPosition
|
||||
val (resolvedCall, correspondingNotApproximatedTypeByDescriptor: (CallableDescriptor) -> KotlinType?) = when (callPosition) {
|
||||
is CallPosition.ValueArgumentPosition -> Pair(
|
||||
callPosition.resolvedCall, { f: CallableDescriptor ->
|
||||
is CallPosition.ValueArgumentPosition ->
|
||||
callPosition.resolvedCall to { f: CallableDescriptor ->
|
||||
getEffectiveExpectedType(f.valueParameters[callPosition.valueParameter.index], callPosition.valueArgument, this)
|
||||
})
|
||||
is CallPosition.ExtensionReceiverPosition -> Pair<ResolvedCall<*>, (CallableDescriptor) -> KotlinType?>(
|
||||
callPosition.resolvedCall, { f: CallableDescriptor ->
|
||||
f.extensionReceiverParameter?.type
|
||||
})
|
||||
is CallPosition.PropertyAssignment -> Pair<ResolvedCall<out CallableDescriptor>, (CallableDescriptor) -> KotlinType?>(
|
||||
callPosition.leftPart.getResolvedCall(trace.bindingContext) ?: return false, { f: CallableDescriptor ->
|
||||
(f as? PropertyDescriptor)?.setter?.valueParameters?.get(0)?.type
|
||||
})
|
||||
}
|
||||
is CallPosition.ExtensionReceiverPosition ->
|
||||
callPosition.resolvedCall to { f: CallableDescriptor -> f.extensionReceiverParameter?.type }
|
||||
is CallPosition.PropertyAssignment -> {
|
||||
if (callPosition.isLeft) return false
|
||||
val resolvedCall = callPosition.leftPart.getResolvedCall(trace.bindingContext) ?: return false
|
||||
resolvedCall to { f: CallableDescriptor -> (f as? PropertyDescriptor)?.setter?.valueParameters?.get(0)?.type }
|
||||
}
|
||||
is CallPosition.Unknown -> return false
|
||||
}
|
||||
|
||||
val receiverType = resolvedCall.smartCastDispatchReceiverType
|
||||
?: (resolvedCall.dispatchReceiver ?: return false).type
|
||||
?: (resolvedCall.dispatchReceiver ?: return false).type
|
||||
|
||||
val callableDescriptor = resolvedCall.resultingDescriptor.original
|
||||
|
||||
|
||||
@@ -33,5 +33,5 @@ sealed class CallPosition {
|
||||
val valueArgument: ValueArgument
|
||||
) : CallPosition()
|
||||
|
||||
class PropertyAssignment(val leftPart: KtExpression?) : CallPosition()
|
||||
class PropertyAssignment(val leftPart: KtExpression?, val isLeft: Boolean) : CallPosition()
|
||||
}
|
||||
|
||||
+11
-4
@@ -304,7 +304,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
KotlinType expectedType = refineTypeFromPropertySetterIfPossible(context.trace.getBindingContext(), leftOperand, leftType);
|
||||
|
||||
components.dataFlowAnalyzer.checkType(binaryOperationType, expression, context.replaceExpectedType(expectedType)
|
||||
.replaceDataFlowInfo(rightInfo.getDataFlowInfo()).replaceCallPosition(new CallPosition.PropertyAssignment(left)));
|
||||
.replaceDataFlowInfo(rightInfo.getDataFlowInfo()).replaceCallPosition(new CallPosition.PropertyAssignment(left, false)));
|
||||
basic.checkLValue(context.trace, context, leftOperand, right, expression, false);
|
||||
}
|
||||
temporary.commit();
|
||||
@@ -354,14 +354,21 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
|
||||
basic.checkLValue(context.trace, context, arrayAccessExpression, right, expression, true);
|
||||
return typeInfo.replaceType(checkAssignmentType(typeInfo.getType(), expression, contextWithExpectedType));
|
||||
}
|
||||
KotlinTypeInfo leftInfo = ExpressionTypingUtils.getTypeInfoOrNullType(left, context, facade);
|
||||
KotlinTypeInfo leftInfo = ExpressionTypingUtils.getTypeInfoOrNullType(
|
||||
left,
|
||||
context.replaceCallPosition(new CallPosition.PropertyAssignment(left, true)),
|
||||
facade
|
||||
);
|
||||
KotlinType expectedType = refineTypeFromPropertySetterIfPossible(context.trace.getBindingContext(), leftOperand, leftInfo.getType());
|
||||
DataFlowInfo dataFlowInfo = leftInfo.getDataFlowInfo();
|
||||
KotlinTypeInfo resultInfo;
|
||||
if (right != null) {
|
||||
resultInfo = facade.getTypeInfo(
|
||||
right, context.replaceDataFlowInfo(dataFlowInfo).replaceExpectedType(expectedType).replaceCallPosition(
|
||||
new CallPosition.PropertyAssignment(leftOperand)));
|
||||
right,
|
||||
context.replaceDataFlowInfo(dataFlowInfo)
|
||||
.replaceExpectedType(expectedType)
|
||||
.replaceCallPosition(new CallPosition.PropertyAssignment(leftOperand, false))
|
||||
);
|
||||
|
||||
dataFlowInfo = resultInfo.getDataFlowInfo();
|
||||
KotlinType rightType = resultInfo.getType();
|
||||
|
||||
Reference in New Issue
Block a user