Call Resolver: Fix nullability of parenthesized safe calls used as value arguments

#KT-7903 Fixed
This commit is contained in:
Alexey Sedunov
2015-06-03 18:02:01 +03:00
parent d2c33c13a6
commit f08c7d0fd8
10 changed files with 68 additions and 11 deletions
@@ -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
@@ -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
@@ -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");