Fix unreported deprecation on variables called as functions
#KT-16272 Fixed
This commit is contained in:
@@ -53,7 +53,6 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
|
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
|
||||||
import org.jetbrains.kotlin.types.expressions.FakeCallResolver
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class CallCompleter(
|
class CallCompleter(
|
||||||
@@ -62,7 +61,6 @@ class CallCompleter(
|
|||||||
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
private val dataFlowAnalyzer: DataFlowAnalyzer,
|
||||||
private val callCheckers: Iterable<CallChecker>,
|
private val callCheckers: Iterable<CallChecker>,
|
||||||
private val builtIns: KotlinBuiltIns,
|
private val builtIns: KotlinBuiltIns,
|
||||||
private val fakeCallResolver: FakeCallResolver,
|
|
||||||
private val languageVersionSettings: LanguageVersionSettings,
|
private val languageVersionSettings: LanguageVersionSettings,
|
||||||
private val compilerConfiguration: CompilerConfiguration
|
private val compilerConfiguration: CompilerConfiguration
|
||||||
) {
|
) {
|
||||||
@@ -86,7 +84,7 @@ class CallCompleter(
|
|||||||
temporaryTrace.commit()
|
temporaryTrace.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolvedCall != null) {
|
if (resolvedCall != null && context.trace.wantsDiagnostics()) {
|
||||||
val calleeExpression = if (resolvedCall is VariableAsFunctionResolvedCall)
|
val calleeExpression = if (resolvedCall is VariableAsFunctionResolvedCall)
|
||||||
resolvedCall.variableCall.call.calleeExpression
|
resolvedCall.variableCall.call.calleeExpression
|
||||||
else
|
else
|
||||||
@@ -95,10 +93,12 @@ class CallCompleter(
|
|||||||
if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression
|
if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression
|
||||||
else resolvedCall.call.callElement
|
else resolvedCall.call.callElement
|
||||||
|
|
||||||
if (context.trace.wantsDiagnostics()) {
|
val callCheckerContext = CallCheckerContext(context, languageVersionSettings, compilerConfiguration)
|
||||||
val callCheckerContext = CallCheckerContext(context, languageVersionSettings, compilerConfiguration)
|
for (callChecker in callCheckers) {
|
||||||
for (callChecker in callCheckers) {
|
callChecker.check(resolvedCall, reportOn, callCheckerContext)
|
||||||
callChecker.check(resolvedCall, reportOn, callCheckerContext)
|
|
||||||
|
if (resolvedCall is VariableAsFunctionResolvedCall) {
|
||||||
|
callChecker.check(resolvedCall.variableCall, reportOn, callCheckerContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,13 +17,15 @@
|
|||||||
package org.jetbrains.kotlin.resolve.calls.resolvedCallUtil
|
package org.jetbrains.kotlin.resolve.calls.resolvedCallUtil
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.KtCallElement
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||||
|
import org.jetbrains.kotlin.psi.KtThisExpression
|
||||||
|
import org.jetbrains.kotlin.psi.ValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
@@ -74,29 +76,16 @@ fun ResolvedCall<*>.getExplicitReceiverValue(): ReceiverValue? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ResolvedCall<*>.getImplicitReceiverValue(): ImplicitReceiver? {
|
fun ResolvedCall<*>.getImplicitReceiverValue(): ImplicitReceiver? =
|
||||||
return when (explicitReceiverKind) {
|
getImplicitReceivers().firstOrNull() as? ImplicitReceiver
|
||||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> extensionReceiver ?: dispatchReceiver
|
|
||||||
ExplicitReceiverKind.DISPATCH_RECEIVER -> extensionReceiver
|
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER -> dispatchReceiver
|
|
||||||
else -> null
|
|
||||||
} as? ImplicitReceiver
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ResolvedCall<*>.getImplicitReceivers(): Collection<ReceiverValue> {
|
fun ResolvedCall<*>.getImplicitReceivers(): Collection<ReceiverValue> =
|
||||||
if (this is VariableAsFunctionResolvedCall) {
|
when (explicitReceiverKind) {
|
||||||
val receivers = variableCall.getImplicitReceivers() + functionCall.getImplicitReceivers()
|
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> listOfNotNull(extensionReceiver, dispatchReceiver)
|
||||||
assert(receivers.size <= 3) { "There are ${receivers.size} for $this call" }
|
ExplicitReceiverKind.DISPATCH_RECEIVER -> listOfNotNull(extensionReceiver)
|
||||||
return receivers
|
ExplicitReceiverKind.EXTENSION_RECEIVER -> listOfNotNull(dispatchReceiver)
|
||||||
}
|
ExplicitReceiverKind.BOTH_RECEIVERS -> emptyList()
|
||||||
|
}
|
||||||
return when (explicitReceiverKind) {
|
|
||||||
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> listOfNotNull(dispatchReceiver, extensionReceiver)
|
|
||||||
ExplicitReceiverKind.DISPATCH_RECEIVER -> listOfNotNull(extensionReceiver)
|
|
||||||
ExplicitReceiverKind.EXTENSION_RECEIVER -> listOfNotNull(dispatchReceiver)
|
|
||||||
ExplicitReceiverKind.BOTH_RECEIVERS -> emptyList()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ResolvedCall<*>.hasSafeNullableReceiver(context: CallResolutionContext<*>): Boolean {
|
private fun ResolvedCall<*>.hasSafeNullableReceiver(context: CallResolutionContext<*>): Boolean {
|
||||||
if (!call.isSafeCall()) return false
|
if (!call.isSafeCall()) return false
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@Deprecated("No")
|
||||||
|
val f: () -> Unit = {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<!DEPRECATION!>f<!>()
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
@kotlin.Deprecated(message = "No") public val f: () -> kotlin.Unit
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
@@ -6340,6 +6340,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("propertyWithInvoke.kt")
|
||||||
|
public void testPropertyWithInvoke() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/propertyWithInvoke.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeUsage.kt")
|
@TestMetadata("typeUsage.kt")
|
||||||
public void testTypeUsage() throws Exception {
|
public void testTypeUsage() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typeUsage.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typeUsage.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user