K1: Deprecate incorrect callable references resolution behavior
^KT-54316 Related ^KT-54832 Fixed
This commit is contained in:
committed by
Space Team
parent
a3fd63fb1d
commit
2953e600ff
+12
@@ -2706,6 +2706,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceWithMostSpecificGenericTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceWithMostSpecificGenericTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("callableReferencesToCompanionMembers.kt")
|
||||||
|
public void testCallableReferencesToCompanionMembers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("classVsPackage.kt")
|
@TestMetadata("classVsPackage.kt")
|
||||||
public void testClassVsPackage() throws Exception {
|
public void testClassVsPackage() throws Exception {
|
||||||
@@ -2742,6 +2748,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/correctInfoAfterArrayLikeCall.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/correctInfoAfterArrayLikeCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("deprecateTopLevelReferenceWithCompanionLHS.kt")
|
||||||
|
public void testDeprecateTopLevelReferenceWithCompanionLHS() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("deprecatedCompanionReceiverInParentheses.kt")
|
@TestMetadata("deprecatedCompanionReceiverInParentheses.kt")
|
||||||
public void testDeprecatedCompanionReceiverInParentheses() throws Exception {
|
public void testDeprecatedCompanionReceiverInParentheses() throws Exception {
|
||||||
|
|||||||
+12
@@ -2706,6 +2706,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceWithMostSpecificGenericTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceWithMostSpecificGenericTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("callableReferencesToCompanionMembers.kt")
|
||||||
|
public void testCallableReferencesToCompanionMembers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("classVsPackage.kt")
|
@TestMetadata("classVsPackage.kt")
|
||||||
public void testClassVsPackage() throws Exception {
|
public void testClassVsPackage() throws Exception {
|
||||||
@@ -2742,6 +2748,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/correctInfoAfterArrayLikeCall.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/correctInfoAfterArrayLikeCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("deprecateTopLevelReferenceWithCompanionLHS.kt")
|
||||||
|
public void testDeprecateTopLevelReferenceWithCompanionLHS() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("deprecatedCompanionReceiverInParentheses.kt")
|
@TestMetadata("deprecatedCompanionReceiverInParentheses.kt")
|
||||||
public void testDeprecatedCompanionReceiverInParentheses() throws Exception {
|
public void testDeprecatedCompanionReceiverInParentheses() throws Exception {
|
||||||
|
|||||||
+12
@@ -2706,6 +2706,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceWithMostSpecificGenericTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceWithMostSpecificGenericTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("callableReferencesToCompanionMembers.kt")
|
||||||
|
public void testCallableReferencesToCompanionMembers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("classVsPackage.kt")
|
@TestMetadata("classVsPackage.kt")
|
||||||
public void testClassVsPackage() throws Exception {
|
public void testClassVsPackage() throws Exception {
|
||||||
@@ -2742,6 +2748,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/correctInfoAfterArrayLikeCall.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/correctInfoAfterArrayLikeCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("deprecateTopLevelReferenceWithCompanionLHS.kt")
|
||||||
|
public void testDeprecateTopLevelReferenceWithCompanionLHS() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("deprecatedCompanionReceiverInParentheses.kt")
|
@TestMetadata("deprecatedCompanionReceiverInParentheses.kt")
|
||||||
public void testDeprecatedCompanionReceiverInParentheses() throws Exception {
|
public void testDeprecatedCompanionReceiverInParentheses() throws Exception {
|
||||||
|
|||||||
@@ -889,6 +889,7 @@ public interface Errors {
|
|||||||
DiagnosticFactory0<KtExpression> RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<KtExpression> RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory0<KtParenthesizedExpression> PARENTHESIZED_COMPANION_LHS_DEPRECATION = DiagnosticFactory0.create(WARNING);
|
DiagnosticFactory0<KtParenthesizedExpression> PARENTHESIZED_COMPANION_LHS_DEPRECATION = DiagnosticFactory0.create(WARNING);
|
||||||
|
DiagnosticFactory0<PsiElement> INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS = DiagnosticFactory0.create(WARNING);
|
||||||
|
|
||||||
DiagnosticFactory0<PsiElement> RESOLUTION_TO_PRIVATE_CONSTRUCTOR_OF_SEALED_CLASS = DiagnosticFactory0.create(WARNING);
|
DiagnosticFactory0<PsiElement> RESOLUTION_TO_PRIVATE_CONSTRUCTOR_OF_SEALED_CLASS = DiagnosticFactory0.create(WARNING);
|
||||||
|
|
||||||
|
|||||||
+5
@@ -460,6 +460,11 @@ public class DefaultErrorMessages {
|
|||||||
|
|
||||||
MAP.put(PARENTHESIZED_COMPANION_LHS_DEPRECATION, "Access to companion object through parenthesized class name is deprecated. Please, add explicit Companion qualifier.");
|
MAP.put(PARENTHESIZED_COMPANION_LHS_DEPRECATION, "Access to companion object through parenthesized class name is deprecated. Please, add explicit Companion qualifier.");
|
||||||
|
|
||||||
|
MAP.put(
|
||||||
|
INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS,
|
||||||
|
"Callable reference to the companion's member is incorrectly resolved as unbound. Please, add explicit Companion qualifier to the left-hand-side. See https://youtrack.jetbrains.com/issue/KT-54316 for details"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
MAP.put(RESOLUTION_TO_PRIVATE_CONSTRUCTOR_OF_SEALED_CLASS, "The private constructor of a sealed class will become inaccessible here in future. See https://youtrack.jetbrains.com/issue/KT-44866 for details");
|
MAP.put(RESOLUTION_TO_PRIVATE_CONSTRUCTOR_OF_SEALED_CLASS, "The private constructor of a sealed class will become inaccessible here in future. See https://youtrack.jetbrains.com/issue/KT-44866 for details");
|
||||||
MAP.put(
|
MAP.put(
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ private val DEFAULT_CALL_CHECKERS = listOf(
|
|||||||
ReferencingToUnderscoreNamedParameterOfCatchBlockChecker, VarargWrongExecutionOrderChecker, SelfCallInNestedObjectConstructorChecker,
|
ReferencingToUnderscoreNamedParameterOfCatchBlockChecker, VarargWrongExecutionOrderChecker, SelfCallInNestedObjectConstructorChecker,
|
||||||
NewSchemeOfIntegerOperatorResolutionChecker, EnumEntryVsCompanionPriorityCallChecker, CompanionInParenthesesLHSCallChecker,
|
NewSchemeOfIntegerOperatorResolutionChecker, EnumEntryVsCompanionPriorityCallChecker, CompanionInParenthesesLHSCallChecker,
|
||||||
ResolutionToPrivateConstructorOfSealedClassChecker, EqualityCallChecker, UnsupportedUntilOperatorChecker,
|
ResolutionToPrivateConstructorOfSealedClassChecker, EqualityCallChecker, UnsupportedUntilOperatorChecker,
|
||||||
BuilderInferenceAssignmentChecker, IncorrectCapturedApproximationCallChecker,
|
BuilderInferenceAssignmentChecker, IncorrectCapturedApproximationCallChecker, CompanionIncorrectlyUnboundedWhenUsedAsLHSCallChecker,
|
||||||
)
|
)
|
||||||
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
|
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
|
||||||
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
|
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
|
||||||
|
|||||||
+45
-9
@@ -13,8 +13,11 @@ import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
|||||||
import org.jetbrains.kotlin.psi.KtParenthesizedExpression
|
import org.jetbrains.kotlin.psi.KtParenthesizedExpression
|
||||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.context.CallPosition
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecate callable references in a form of (SomeClass)::name when SomeClass has a companion
|
* Deprecate callable references in a form of (SomeClass)::name when SomeClass has a companion
|
||||||
@@ -27,16 +30,49 @@ object CompanionInParenthesesLHSCallChecker : CallChecker {
|
|||||||
val unwrappedLhs = parenthesizedExpression.expression ?: return
|
val unwrappedLhs = parenthesizedExpression.expression ?: return
|
||||||
val expressionReceiver = resolvedCall.call.explicitReceiver as? ExpressionReceiver ?: return
|
val expressionReceiver = resolvedCall.call.explicitReceiver as? ExpressionReceiver ?: return
|
||||||
|
|
||||||
val referencedClass = expressionReceiver.type.constructor.declarationDescriptor as? ClassDescriptor ?: return
|
if (!isReferenceToShortFormCompanion(expressionReceiver, unwrappedLhs, context)) return
|
||||||
if (!referencedClass.isCompanionObject) return
|
|
||||||
|
|
||||||
// We should also consider cases like (package.MyClassWithCompanion)::foo
|
|
||||||
val simpleReference =
|
|
||||||
((unwrappedLhs as? KtDotQualifiedExpression)?.selectorExpression ?: unwrappedLhs) as? KtReferenceExpression
|
|
||||||
?: return
|
|
||||||
|
|
||||||
if (context.trace.bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, simpleReference] == null) return
|
|
||||||
|
|
||||||
context.trace.report(Errors.PARENTHESIZED_COMPANION_LHS_DEPRECATION.on(parenthesizedExpression))
|
context.trace.report(Errors.PARENTHESIZED_COMPANION_LHS_DEPRECATION.on(parenthesizedExpression))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report warnings on top-level callable references (one that are not nested in any call) that have short-formed LHS resolved to companion
|
||||||
|
* Because they have wrong function type shape at K1
|
||||||
|
* (see relevant testData)
|
||||||
|
*/
|
||||||
|
object CompanionIncorrectlyUnboundedWhenUsedAsLHSCallChecker : CallChecker {
|
||||||
|
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||||
|
val callableReference = resolvedCall.call.callElement.parent as? KtCallableReferenceExpression ?: return
|
||||||
|
val classQualifier = resolvedCall.call.explicitReceiver as? ClassQualifier ?: return
|
||||||
|
val dispatchReceiver = resolvedCall.dispatchReceiver ?: return
|
||||||
|
|
||||||
|
if (dispatchReceiver != classQualifier.classValueReceiver) return
|
||||||
|
|
||||||
|
// Only top-level callable references may have callPosition like this
|
||||||
|
// References nested in calls have CallPosition.Unknown
|
||||||
|
if (context.resolutionContext.callPosition !is CallPosition.CallableReferenceRhs) return
|
||||||
|
|
||||||
|
val referencedClass = dispatchReceiver.type.constructor.declarationDescriptor as? ClassDescriptor ?: return
|
||||||
|
if (!referencedClass.isCompanionObject) return
|
||||||
|
|
||||||
|
context.trace.report(Errors.INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS.on(callableReference))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isReferenceToShortFormCompanion(
|
||||||
|
receiver: ReceiverValue,
|
||||||
|
lhs: PsiElement?,
|
||||||
|
context: CallCheckerContext
|
||||||
|
): Boolean {
|
||||||
|
val referencedClass = receiver.type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
|
||||||
|
if (!referencedClass.isCompanionObject) return false
|
||||||
|
|
||||||
|
// We should also consider cases like (package.MyClassWithCompanion)::foo
|
||||||
|
val simpleReference =
|
||||||
|
((lhs as? KtDotQualifiedExpression)?.selectorExpression ?: lhs) as? KtReferenceExpression
|
||||||
|
?: return false
|
||||||
|
|
||||||
|
return context.trace.bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, simpleReference] != null
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -37,5 +37,5 @@ fun test() {
|
|||||||
val r7 = c::foo
|
val r7 = c::foo
|
||||||
checkSubtype<() -> String>(r7)
|
checkSubtype<() -> String>(r7)
|
||||||
|
|
||||||
C::bar
|
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>C::bar<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// FIR_DUMP
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
companion object {
|
||||||
|
fun bar() {}
|
||||||
|
val baz = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val x1 = Foo::bar
|
||||||
|
val x2 = Foo.Companion::bar
|
||||||
|
val x3 = Foo::baz
|
||||||
|
val x4 = Foo.Companion::baz
|
||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
FILE: callableReferencesToCompanionMembers.fir.kt
|
||||||
|
public final class Foo : R|kotlin/Any| {
|
||||||
|
public constructor(): R|Foo| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final companion object Companion : R|kotlin/Any| {
|
||||||
|
private constructor(): R|Foo.Companion| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final fun bar(): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val baz: R|kotlin/Int| = Int(42)
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final val x1: R|kotlin/reflect/KFunction0<kotlin/Unit>| = Q|Foo|::R|/Foo.Companion.bar|
|
||||||
|
public get(): R|kotlin/reflect/KFunction0<kotlin/Unit>|
|
||||||
|
public final val x2: R|kotlin/reflect/KFunction0<kotlin/Unit>| = Q|Foo.Companion|::R|/Foo.Companion.bar|
|
||||||
|
public get(): R|kotlin/reflect/KFunction0<kotlin/Unit>|
|
||||||
|
public final val x3: R|kotlin/reflect/KProperty0<kotlin/Int>| = Q|Foo|::R|/Foo.Companion.baz|
|
||||||
|
public get(): R|kotlin/reflect/KProperty0<kotlin/Int>|
|
||||||
|
public final val x4: R|kotlin/reflect/KProperty0<kotlin/Int>| = Q|Foo.Companion|::R|/Foo.Companion.baz|
|
||||||
|
public get(): R|kotlin/reflect/KProperty0<kotlin/Int>|
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// FIR_DUMP
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
companion object {
|
||||||
|
fun bar() {}
|
||||||
|
val baz = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val x1 = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>Foo::bar<!>
|
||||||
|
val x2 = Foo.Companion::bar
|
||||||
|
val x3 = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>Foo::baz<!>
|
||||||
|
val x4 = Foo.Companion::baz
|
||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val x1: kotlin.reflect.KFunction1<Foo, kotlin.Unit>
|
||||||
|
public val x2: kotlin.reflect.KFunction0<kotlin.Unit>
|
||||||
|
public val x3: kotlin.reflect.KProperty1<Foo, kotlin.Int>
|
||||||
|
public val x4: kotlin.reflect.KProperty0<kotlin.Int>
|
||||||
|
|
||||||
|
public final class Foo {
|
||||||
|
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
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public final val baz: kotlin.Int = 42
|
||||||
|
public final fun bar(): kotlin.Unit
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
// SKIP_TXT
|
||||||
|
|
||||||
|
class A {
|
||||||
|
companion object {
|
||||||
|
fun foo(): Int = 43
|
||||||
|
val companionProp: Int = 44
|
||||||
|
}
|
||||||
|
|
||||||
|
fun baz(): Int = 1
|
||||||
|
val memberProp: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
object Obj {
|
||||||
|
fun foo(): Int = 43
|
||||||
|
val objProp: Int = 44
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
A::foo.invoke(<!TOO_MANY_ARGUMENTS!>A()<!>)
|
||||||
|
A::foo.invoke()
|
||||||
|
val x = A::foo
|
||||||
|
x.invoke(<!TOO_MANY_ARGUMENTS!>A()<!>)
|
||||||
|
x.invoke()
|
||||||
|
|
||||||
|
A.Companion::foo.invoke()
|
||||||
|
val x0 = A.Companion::foo
|
||||||
|
x0.invoke()
|
||||||
|
|
||||||
|
bar(A::foo)
|
||||||
|
|
||||||
|
val y = id(A::foo)
|
||||||
|
y.invoke()
|
||||||
|
|
||||||
|
A::baz.invoke(A())
|
||||||
|
|
||||||
|
val z = A::baz
|
||||||
|
z.invoke(A())
|
||||||
|
bam(A::baz)
|
||||||
|
|
||||||
|
Obj::foo.invoke()
|
||||||
|
|
||||||
|
val zObj = Obj::foo
|
||||||
|
zObj.invoke()
|
||||||
|
bar(Obj::foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mainProp() {
|
||||||
|
A::companionProp.invoke(<!TOO_MANY_ARGUMENTS!>A()<!>)
|
||||||
|
A::companionProp.invoke()
|
||||||
|
val x = A::companionProp
|
||||||
|
x.invoke(<!TOO_MANY_ARGUMENTS!>A()<!>)
|
||||||
|
x.invoke()
|
||||||
|
|
||||||
|
A.Companion::companionProp.invoke()
|
||||||
|
val x0 = A.Companion::companionProp
|
||||||
|
x0.invoke()
|
||||||
|
|
||||||
|
bar(A::companionProp)
|
||||||
|
|
||||||
|
val y = id(A::companionProp)
|
||||||
|
y.invoke()
|
||||||
|
|
||||||
|
A::memberProp.invoke(A())
|
||||||
|
|
||||||
|
val z = A::memberProp
|
||||||
|
z.invoke(A())
|
||||||
|
bam(A::memberProp)
|
||||||
|
|
||||||
|
Obj::objProp.invoke()
|
||||||
|
|
||||||
|
val zObj = Obj::objProp
|
||||||
|
zObj.invoke()
|
||||||
|
bar(Obj::objProp)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <E> id(e: E): E = e
|
||||||
|
|
||||||
|
fun bar(x: () -> Int) {}
|
||||||
|
fun bam(x: A.() -> Int) {}
|
||||||
Vendored
+79
@@ -0,0 +1,79 @@
|
|||||||
|
// SKIP_TXT
|
||||||
|
|
||||||
|
class A {
|
||||||
|
companion object {
|
||||||
|
fun foo(): Int = 43
|
||||||
|
val companionProp: Int = 44
|
||||||
|
}
|
||||||
|
|
||||||
|
fun baz(): Int = 1
|
||||||
|
val memberProp: Int = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
object Obj {
|
||||||
|
fun foo(): Int = 43
|
||||||
|
val objProp: Int = 44
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::foo<!>.invoke(A())
|
||||||
|
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::foo<!>.invoke<!NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
|
val x = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::foo<!>
|
||||||
|
x.invoke(A())
|
||||||
|
x.invoke<!NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
|
|
||||||
|
A.Companion::foo.invoke()
|
||||||
|
val x0 = A.Companion::foo
|
||||||
|
x0.invoke()
|
||||||
|
|
||||||
|
bar(A::foo)
|
||||||
|
|
||||||
|
val y = id(A::foo)
|
||||||
|
y.invoke()
|
||||||
|
|
||||||
|
A::baz.invoke(A())
|
||||||
|
|
||||||
|
val z = A::baz
|
||||||
|
z.invoke(A())
|
||||||
|
bam(A::baz)
|
||||||
|
|
||||||
|
Obj::foo.invoke()
|
||||||
|
|
||||||
|
val zObj = Obj::foo
|
||||||
|
zObj.invoke()
|
||||||
|
bar(Obj::foo)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mainProp() {
|
||||||
|
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::companionProp<!>.invoke(A())
|
||||||
|
<!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::companionProp<!>.invoke<!NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
|
val x = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>A::companionProp<!>
|
||||||
|
x.invoke(A())
|
||||||
|
x.invoke<!NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
|
|
||||||
|
A.Companion::companionProp.invoke()
|
||||||
|
val x0 = A.Companion::companionProp
|
||||||
|
x0.invoke()
|
||||||
|
|
||||||
|
bar(A::companionProp)
|
||||||
|
|
||||||
|
val y = id(A::companionProp)
|
||||||
|
y.invoke()
|
||||||
|
|
||||||
|
A::memberProp.invoke(A())
|
||||||
|
|
||||||
|
val z = A::memberProp
|
||||||
|
z.invoke(A())
|
||||||
|
bam(A::memberProp)
|
||||||
|
|
||||||
|
Obj::objProp.invoke()
|
||||||
|
|
||||||
|
val zObj = Obj::objProp
|
||||||
|
zObj.invoke()
|
||||||
|
bar(Obj::objProp)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <E> id(e: E): E = e
|
||||||
|
|
||||||
|
fun bar(x: () -> Int) {}
|
||||||
|
fun bam(x: A.() -> Int) {}
|
||||||
@@ -26,6 +26,6 @@ fun main() {
|
|||||||
// It must be OK
|
// It must be OK
|
||||||
val x18 = String?::hashCode <!USELESS_ELVIS!>?: ::foo<!>
|
val x18 = String?::hashCode <!USELESS_ELVIS!>?: ::foo<!>
|
||||||
val x19 = String::hashCode <!USELESS_ELVIS!>?: ::foo<!>
|
val x19 = String::hashCode <!USELESS_ELVIS!>?: ::foo<!>
|
||||||
val x20 = String?::hashCode::hashCode
|
val x20 = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>String?::hashCode<!>::hashCode
|
||||||
val x21 = kotlin.String?::hashCode::hashCode
|
val x21 = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>kotlin.String?::hashCode<!>::hashCode
|
||||||
}
|
}
|
||||||
|
|||||||
+74
@@ -0,0 +1,74 @@
|
|||||||
|
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
||||||
|
|
||||||
|
import A.Base.Companion.FromABaseCompanion
|
||||||
|
import B.Base.Companion.FromBBaseCompanion
|
||||||
|
import C.Base.Companion.FromCBaseCompanion
|
||||||
|
import D.Base.Companion.FromDBaseCompanion
|
||||||
|
|
||||||
|
// ===== Case 1: LHS is a class
|
||||||
|
//
|
||||||
|
object A {
|
||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
class FromABaseCompanion {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base() {
|
||||||
|
val a = FromABaseCompanion::foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Case 2: LHS is a class with companion object, function comes from class
|
||||||
|
|
||||||
|
object B {
|
||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
class FromBBaseCompanion {
|
||||||
|
fun foo() = 42
|
||||||
|
|
||||||
|
companion object {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base() {
|
||||||
|
val a = FromBBaseCompanion::foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Case 3: LHS is a class with companion object, function comes from companion
|
||||||
|
|
||||||
|
object C {
|
||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
class FromCBaseCompanion {
|
||||||
|
companion object {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base() {
|
||||||
|
val a = FromCBaseCompanion::foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Case 4: LHS is an object
|
||||||
|
|
||||||
|
object D {
|
||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
object FromDBaseCompanion {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base() {
|
||||||
|
val a = FromDBaseCompanion::foo
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
||||||
|
|
||||||
import A.Base.Companion.FromABaseCompanion
|
import A.Base.Companion.FromABaseCompanion
|
||||||
@@ -54,7 +53,7 @@ object C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Derived : Base() {
|
class Derived : Base() {
|
||||||
val a = FromCBaseCompanion::foo
|
val a = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>FromCBaseCompanion::foo<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
||||||
|
|
||||||
|
// ===== Case 1: LHS is a class
|
||||||
|
//
|
||||||
|
object A {
|
||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
class FromBaseCompanion {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base() {
|
||||||
|
val a = A.Base.Companion.FromBaseCompanion::foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== Case 2: LHS is a class with companion object, function comes from class
|
||||||
|
|
||||||
|
object B {
|
||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
class FromBaseCompanion {
|
||||||
|
fun foo() = 42
|
||||||
|
|
||||||
|
companion object {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base() {
|
||||||
|
val a = B.Base.Companion.FromBaseCompanion::foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Case 3: LHS is a class with companion object, function comes from companion
|
||||||
|
|
||||||
|
object C {
|
||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
class FromBaseCompanion {
|
||||||
|
companion object {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base() {
|
||||||
|
val a = C.Base.Companion.FromBaseCompanion::foo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Case 4: LHS is an object
|
||||||
|
|
||||||
|
object D {
|
||||||
|
open class Base {
|
||||||
|
companion object {
|
||||||
|
object FromBaseCompanion {
|
||||||
|
fun foo() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived : Base() {
|
||||||
|
val a = D.Base.Companion.FromBaseCompanion::foo
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// FIR_IDENTICAL
|
|
||||||
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
// !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion
|
||||||
|
|
||||||
// ===== Case 1: LHS is a class
|
// ===== Case 1: LHS is a class
|
||||||
@@ -49,7 +48,7 @@ object C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Derived : Base() {
|
class Derived : Base() {
|
||||||
val a = C.Base.Companion.FromBaseCompanion::foo
|
val a = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!>C.Base.Companion.FromBaseCompanion::foo<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ object C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Derived : Base() {
|
class Derived : Base() {
|
||||||
val a = <!DEPRECATED_ACCESS_BY_SHORT_NAME!>FromBaseCompanion<!>::foo
|
val a = <!INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS!><!DEPRECATED_ACCESS_BY_SHORT_NAME!>FromBaseCompanion<!>::foo<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+12
@@ -2712,6 +2712,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceWithMostSpecificGenericTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferenceWithMostSpecificGenericTypeParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("callableReferencesToCompanionMembers.kt")
|
||||||
|
public void testCallableReferencesToCompanionMembers() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("classVsPackage.kt")
|
@TestMetadata("classVsPackage.kt")
|
||||||
public void testClassVsPackage() throws Exception {
|
public void testClassVsPackage() throws Exception {
|
||||||
@@ -2748,6 +2754,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/callableReference/correctInfoAfterArrayLikeCall.kt");
|
runTest("compiler/testData/diagnostics/tests/callableReference/correctInfoAfterArrayLikeCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("deprecateTopLevelReferenceWithCompanionLHS.kt")
|
||||||
|
public void testDeprecateTopLevelReferenceWithCompanionLHS() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("deprecatedCompanionReceiverInParentheses.kt")
|
@TestMetadata("deprecatedCompanionReceiverInParentheses.kt")
|
||||||
public void testDeprecatedCompanionReceiverInParentheses() throws Exception {
|
public void testDeprecatedCompanionReceiverInParentheses() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user