diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt index 4d0117e6945..faaa381b422 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallCompleter.kt @@ -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) - } + } } diff --git a/compiler/testData/diagnostics/tests/deparenthesize/annotatedSafeCall.kt b/compiler/testData/diagnostics/tests/deparenthesize/annotatedSafeCall.kt new file mode 100644 index 00000000000..1d4b00298cf --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/annotatedSafeCall.kt @@ -0,0 +1,5 @@ +annotation class foo + +fun f(s : String?) : Boolean { + return (@foo s?.equals("a"))!! +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/deparenthesize/annotatedSafeCall.txt b/compiler/testData/diagnostics/tests/deparenthesize/annotatedSafeCall.txt new file mode 100644 index 00000000000..a096f8c95ce --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/annotatedSafeCall.txt @@ -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 +} diff --git a/compiler/testData/diagnostics/tests/deparenthesize/labeledSafeCall.kt b/compiler/testData/diagnostics/tests/deparenthesize/labeledSafeCall.kt new file mode 100644 index 00000000000..e270df0ec1d --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/labeledSafeCall.kt @@ -0,0 +1,3 @@ +fun f(s : String?) : Boolean { + return foo@(s?.equals("a"))!! +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/deparenthesize/labeledSafeCall.txt b/compiler/testData/diagnostics/tests/deparenthesize/labeledSafeCall.txt new file mode 100644 index 00000000000..a83af005cf9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/labeledSafeCall.txt @@ -0,0 +1,3 @@ +package + +internal fun f(/*0*/ s: kotlin.String?): kotlin.Boolean diff --git a/compiler/testData/diagnostics/tests/deparenthesize/multiParenthesizedSafeCall.kt b/compiler/testData/diagnostics/tests/deparenthesize/multiParenthesizedSafeCall.kt new file mode 100644 index 00000000000..209ab44d1a1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/multiParenthesizedSafeCall.kt @@ -0,0 +1,3 @@ +fun f(s : String?) : Boolean { + return (((s?.equals("a"))))!! +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/deparenthesize/multiParenthesizedSafeCall.txt b/compiler/testData/diagnostics/tests/deparenthesize/multiParenthesizedSafeCall.txt new file mode 100644 index 00000000000..a83af005cf9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/multiParenthesizedSafeCall.txt @@ -0,0 +1,3 @@ +package + +internal fun f(/*0*/ s: kotlin.String?): kotlin.Boolean diff --git a/compiler/testData/diagnostics/tests/deparenthesize/parenthesizedSafeCall.kt b/compiler/testData/diagnostics/tests/deparenthesize/parenthesizedSafeCall.kt new file mode 100644 index 00000000000..bab8ed3f1be --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/parenthesizedSafeCall.kt @@ -0,0 +1,3 @@ +fun f(s : String?) : Boolean { + return (s?.equals("a"))!! +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/deparenthesize/parenthesizedSafeCall.txt b/compiler/testData/diagnostics/tests/deparenthesize/parenthesizedSafeCall.txt new file mode 100644 index 00000000000..a83af005cf9 --- /dev/null +++ b/compiler/testData/diagnostics/tests/deparenthesize/parenthesizedSafeCall.txt @@ -0,0 +1,3 @@ +package + +internal fun f(/*0*/ s: kotlin.String?): kotlin.Boolean diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index e4082fe9631..f39ed158222 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -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");