Call Resolver: Fix nullability of parenthesized safe calls used as value arguments
#KT-7903 Fixed
This commit is contained in:
@@ -26,12 +26,12 @@ import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallCandidateResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
@@ -39,13 +39,9 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext
|
||||
import org.jetbrains.kotlin.types.expressions.DataFlowUtils
|
||||
import org.jetbrains.kotlin.psi.JetExpression
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import org.jetbrains.kotlin.psi.JetPsiUtil
|
||||
import org.jetbrains.kotlin.psi.JetSafeQualifiedExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.psi.JetQualifiedExpression
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
@@ -123,9 +119,9 @@ public class CallCompleter(
|
||||
}
|
||||
|
||||
resolvedCall.completeConstraintSystem(context.expectedType, context.trace)
|
||||
|
||||
|
||||
completeArguments(context, results)
|
||||
|
||||
|
||||
resolvedCall.updateResolutionStatusFromConstraintSystem(context, tracing)
|
||||
resolvedCall.markCallAsCompleted()
|
||||
}
|
||||
@@ -304,9 +300,13 @@ public class CallCompleter(
|
||||
expressions.add(expression)
|
||||
expression = deparenthesizeOrGetSelector(expression)
|
||||
}
|
||||
expressions.forEach { expression ->
|
||||
BindingContextUtils.updateRecordedType(
|
||||
updatedType, expression, trace, /* shouldBeMadeNullable = */ hasNecessarySafeCall(expression, trace))
|
||||
|
||||
var shouldBeMadeNullable: Boolean = false
|
||||
expressions.reverse().forEach { expression ->
|
||||
if (!(expression is JetParenthesizedExpression || expression is JetLabeledExpression || expression is JetAnnotatedExpression)) {
|
||||
shouldBeMadeNullable = hasNecessarySafeCall(expression, trace)
|
||||
}
|
||||
BindingContextUtils.updateRecordedType(updatedType, expression, trace, shouldBeMadeNullable)
|
||||
}
|
||||
return trace.getType(argumentExpression)
|
||||
}
|
||||
@@ -321,5 +321,5 @@ public class CallCompleter(
|
||||
//If a receiver type is not null, then this safe expression is useless, and we don't need to make the result type nullable.
|
||||
val expressionType = trace.getType(expression.getReceiverExpression())
|
||||
return expressionType != null && TypeUtils.isNullableType(expressionType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
annotation class foo
|
||||
|
||||
fun f(s : String?) : Boolean {
|
||||
return (@foo s?.equals("a"))!!
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
internal fun f(/*0*/ s: kotlin.String?): kotlin.Boolean
|
||||
|
||||
internal final annotation class foo : kotlin.Annotation {
|
||||
public constructor foo()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun f(s : String?) : Boolean {
|
||||
return foo@(s?.equals("a"))!!
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun f(/*0*/ s: kotlin.String?): kotlin.Boolean
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun f(s : String?) : Boolean {
|
||||
return (((s?.equals("a"))))!!
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun f(/*0*/ s: kotlin.String?): kotlin.Boolean
|
||||
@@ -0,0 +1,3 @@
|
||||
fun f(s : String?) : Boolean {
|
||||
return (s?.equals("a"))!!
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package
|
||||
|
||||
internal fun f(/*0*/ s: kotlin.String?): kotlin.Boolean
|
||||
@@ -4104,6 +4104,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/deparenthesize"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotatedSafeCall.kt")
|
||||
public void testAnnotatedSafeCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deparenthesize/annotatedSafeCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ArrayAccessAssignment.kt")
|
||||
public void testArrayAccessAssignment() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deparenthesize/ArrayAccessAssignment.kt");
|
||||
@@ -4116,6 +4122,24 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("labeledSafeCall.kt")
|
||||
public void testLabeledSafeCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deparenthesize/labeledSafeCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multiParenthesizedSafeCall.kt")
|
||||
public void testMultiParenthesizedSafeCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deparenthesize/multiParenthesizedSafeCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("parenthesizedSafeCall.kt")
|
||||
public void testParenthesizedSafeCall() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deparenthesize/parenthesizedSafeCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ParenthesizedVariable.kt")
|
||||
public void testParenthesizedVariable() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deparenthesize/ParenthesizedVariable.kt");
|
||||
|
||||
Reference in New Issue
Block a user