Fix unreported deprecation on variables called as functions

#KT-16272 Fixed
This commit is contained in:
Alexander Udalov
2017-02-10 18:06:40 +03:00
parent 6793861fd4
commit 57f2feb6fb
5 changed files with 36 additions and 31 deletions
@@ -53,7 +53,6 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
import org.jetbrains.kotlin.types.expressions.FakeCallResolver
import java.util.*
class CallCompleter(
@@ -62,7 +61,6 @@ class CallCompleter(
private val dataFlowAnalyzer: DataFlowAnalyzer,
private val callCheckers: Iterable<CallChecker>,
private val builtIns: KotlinBuiltIns,
private val fakeCallResolver: FakeCallResolver,
private val languageVersionSettings: LanguageVersionSettings,
private val compilerConfiguration: CompilerConfiguration
) {
@@ -86,7 +84,7 @@ class CallCompleter(
temporaryTrace.commit()
}
if (resolvedCall != null) {
if (resolvedCall != null && context.trace.wantsDiagnostics()) {
val calleeExpression = if (resolvedCall is VariableAsFunctionResolvedCall)
resolvedCall.variableCall.call.calleeExpression
else
@@ -95,10 +93,12 @@ class CallCompleter(
if (calleeExpression != null && !calleeExpression.isFakeElement) calleeExpression
else resolvedCall.call.callElement
if (context.trace.wantsDiagnostics()) {
val callCheckerContext = CallCheckerContext(context, languageVersionSettings, compilerConfiguration)
for (callChecker in callCheckers) {
callChecker.check(resolvedCall, reportOn, callCheckerContext)
val callCheckerContext = CallCheckerContext(context, languageVersionSettings, compilerConfiguration)
for (callChecker in callCheckers) {
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
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.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
import org.jetbrains.kotlin.resolve.calls.context.CallResolutionContext
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.getReceiverValueWithSmartCast
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
@@ -74,29 +76,16 @@ fun ResolvedCall<*>.getExplicitReceiverValue(): ReceiverValue? {
}
}
fun ResolvedCall<*>.getImplicitReceiverValue(): ImplicitReceiver? {
return when (explicitReceiverKind) {
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> extensionReceiver ?: dispatchReceiver
ExplicitReceiverKind.DISPATCH_RECEIVER -> extensionReceiver
ExplicitReceiverKind.EXTENSION_RECEIVER -> dispatchReceiver
else -> null
} as? ImplicitReceiver
}
fun ResolvedCall<*>.getImplicitReceiverValue(): ImplicitReceiver? =
getImplicitReceivers().firstOrNull() as? ImplicitReceiver
fun ResolvedCall<*>.getImplicitReceivers(): Collection<ReceiverValue> {
if (this is VariableAsFunctionResolvedCall) {
val receivers = variableCall.getImplicitReceivers() + functionCall.getImplicitReceivers()
assert(receivers.size <= 3) { "There are ${receivers.size} for $this call" }
return receivers
}
return when (explicitReceiverKind) {
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> listOfNotNull(dispatchReceiver, extensionReceiver)
ExplicitReceiverKind.DISPATCH_RECEIVER -> listOfNotNull(extensionReceiver)
ExplicitReceiverKind.EXTENSION_RECEIVER -> listOfNotNull(dispatchReceiver)
ExplicitReceiverKind.BOTH_RECEIVERS -> emptyList()
}
}
fun ResolvedCall<*>.getImplicitReceivers(): Collection<ReceiverValue> =
when (explicitReceiverKind) {
ExplicitReceiverKind.NO_EXPLICIT_RECEIVER -> listOfNotNull(extensionReceiver, dispatchReceiver)
ExplicitReceiverKind.DISPATCH_RECEIVER -> listOfNotNull(extensionReceiver)
ExplicitReceiverKind.EXTENSION_RECEIVER -> listOfNotNull(dispatchReceiver)
ExplicitReceiverKind.BOTH_RECEIVERS -> emptyList()
}
private fun ResolvedCall<*>.hasSafeNullableReceiver(context: CallResolutionContext<*>): Boolean {
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);
}
@TestMetadata("propertyWithInvoke.kt")
public void testPropertyWithInvoke() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/propertyWithInvoke.kt");
doTest(fileName);
}
@TestMetadata("typeUsage.kt")
public void testTypeUsage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/typeUsage.kt");