Fix incorrect unsupported error on synthetic extension call on LHS of ::

#KT-13271 Fixed
This commit is contained in:
Alexander Udalov
2016-08-09 19:54:04 +03:00
parent 9dc7e90e12
commit bd88b0941d
8 changed files with 67 additions and 12 deletions
@@ -18,8 +18,7 @@ package org.jetbrains.kotlin.resolve.jvm.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.isCallableReference
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
@@ -27,11 +26,8 @@ import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
class UnsupportedSyntheticCallableReferenceChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
val expression = resolvedCall.call.callElement
if (expression !is KtNameReferenceExpression || expression.parent !is KtCallableReferenceExpression) return
// TODO: support references to synthetic Java extension properties (KT-8575)
if (resolvedCall.resultingDescriptor is SyntheticJavaPropertyDescriptor) {
if (resolvedCall.call.isCallableReference() && resolvedCall.resultingDescriptor is SyntheticJavaPropertyDescriptor) {
context.trace.report(UNSUPPORTED.on(reportOn, "reference to the synthetic extension property for a Java get/set method"))
}
}
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
import org.jetbrains.kotlin.resolve.calls.callUtil.isCallableReference
import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
@@ -175,7 +176,7 @@ class CallCompleter(
val returnType = candidateDescriptor.returnType
val expectedReturnType =
if (isResolvingCallableReference(call)) {
if (call.isCallableReference()) {
// TODO: compute generic type argument for R in the kotlin.Function<R> supertype (KT-12963)
// TODO: also add constraints for parameter types (KT-12964)
if (!TypeUtils.noExpectedType(expectedType) && expectedType.isFunctionType) getReturnTypeFromFunctionType(expectedType)
@@ -241,11 +242,6 @@ class CallCompleter(
setResultingSubstitutor(system.resultingSubstitutor)
}
private fun isResolvingCallableReference(call: Call): Boolean {
val callElement = call.callElement
return (callElement.parent as? KtCallableReferenceExpression)?.callableReference == callElement
}
private fun <D : CallableDescriptor> MutableResolvedCall<D>.updateResolutionStatusFromConstraintSystem(
context: BasicCallResolutionContext,
tracing: TracingStrategy
@@ -229,6 +229,12 @@ fun Call.isSafeCall(): Boolean {
fun Call.isExplicitSafeCall(): Boolean = callOperationNode?.elementType == KtTokens.SAFE_ACCESS
fun Call.isCallableReference(): Boolean {
val callElement = callElement
return callElement is KtNameReferenceExpression &&
(callElement.parent as? KtCallableReferenceExpression)?.callableReference == callElement
}
fun Call.createLookupLocation(): KotlinLookupLocation {
val calleeExpression = calleeExpression
val element =
@@ -0,0 +1,21 @@
// WITH_RUNTIME
// FILE: A.java
public class A {
private final String field;
public A(String field) {
this.field = field;
}
public CharSequence getFoo() { return field; }
}
// FILE: test.kt
fun box(): String {
with (A("OK")) {
val k = foo::toString
return k()
}
}
@@ -0,0 +1,13 @@
// FILE: A.java
class A {
public CharSequence getFoo() { return null; }
}
// FILE: test.kt
fun test() {
with (A()) {
foo::toString
}
}
@@ -0,0 +1,11 @@
package
public fun test(): kotlin.Unit
public/*package*/ open class A {
public/*package*/ constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open fun getFoo(): kotlin.CharSequence!
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1811,6 +1811,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("syntheticExtensionOnLHS.kt")
public void testSyntheticExtensionOnLHS() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/bound/syntheticExtensionOnLHS.kt");
doTest(fileName);
}
@TestMetadata("valueOfTypeParameterType.kt")
public void testValueOfTypeParameterType() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/callableReference/bound/valueOfTypeParameterType.kt");
@@ -1500,6 +1500,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("syntheticExtensionOnLHS.kt")
public void testSyntheticExtensionOnLHS() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/callableReference/bound/syntheticExtensionOnLHS.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/codegen/box/callableReference/bound/inline")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)