diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 5a4ec7066a2..8426d47ce9a 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -2706,6 +2706,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag 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 @TestMetadata("classVsPackage.kt") public void testClassVsPackage() throws Exception { @@ -2742,6 +2748,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag 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 @TestMetadata("deprecatedCompanionReceiverInParentheses.kt") public void testDeprecatedCompanionReceiverInParentheses() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index c3ba4b2b9b2..f3444881001 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -2706,6 +2706,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti 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 @TestMetadata("classVsPackage.kt") public void testClassVsPackage() throws Exception { @@ -2742,6 +2748,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti 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 @TestMetadata("deprecatedCompanionReceiverInParentheses.kt") public void testDeprecatedCompanionReceiverInParentheses() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 3845a419df9..7f9d1e2d121 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -2706,6 +2706,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac 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 @TestMetadata("classVsPackage.kt") public void testClassVsPackage() throws Exception { @@ -2742,6 +2748,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac 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 @TestMetadata("deprecatedCompanionReceiverInParentheses.kt") public void testDeprecatedCompanionReceiverInParentheses() throws Exception { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index d885cd7a0a4..2564c8014e3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -889,6 +889,7 @@ public interface Errors { DiagnosticFactory0 RESERVED_SYNTAX_IN_CALLABLE_REFERENCE_LHS = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 PARENTHESIZED_COMPANION_LHS_DEPRECATION = DiagnosticFactory0.create(WARNING); + DiagnosticFactory0 INCORRECT_CALLABLE_REFERENCE_RESOLUTION_FOR_COMPANION_LHS = DiagnosticFactory0.create(WARNING); DiagnosticFactory0 RESOLUTION_TO_PRIVATE_CONSTRUCTOR_OF_SEALED_CLASS = DiagnosticFactory0.create(WARNING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index f90e5458116..3306632b06d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -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( + 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( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt index 919569d4048..52b26d8d9b9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt @@ -70,7 +70,7 @@ private val DEFAULT_CALL_CHECKERS = listOf( ReferencingToUnderscoreNamedParameterOfCatchBlockChecker, VarargWrongExecutionOrderChecker, SelfCallInNestedObjectConstructorChecker, NewSchemeOfIntegerOperatorResolutionChecker, EnumEntryVsCompanionPriorityCallChecker, CompanionInParenthesesLHSCallChecker, ResolutionToPrivateConstructorOfSealedClassChecker, EqualityCallChecker, UnsupportedUntilOperatorChecker, - BuilderInferenceAssignmentChecker, IncorrectCapturedApproximationCallChecker, + BuilderInferenceAssignmentChecker, IncorrectCapturedApproximationCallChecker, CompanionIncorrectlyUnboundedWhenUsedAsLHSCallChecker, ) private val DEFAULT_TYPE_CHECKERS = emptyList() private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CompanionLHSRelatedCheckers.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CompanionLHSRelatedCheckers.kt index 97a53618ff4..fa19b1e5d3a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CompanionLHSRelatedCheckers.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CompanionLHSRelatedCheckers.kt @@ -13,8 +13,11 @@ import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtParenthesizedExpression import org.jetbrains.kotlin.psi.KtReferenceExpression 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.scopes.receivers.ClassQualifier 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 @@ -27,16 +30,49 @@ object CompanionInParenthesesLHSCallChecker : CallChecker { val unwrappedLhs = parenthesizedExpression.expression ?: return val expressionReceiver = resolvedCall.call.explicitReceiver as? ExpressionReceiver ?: return - val referencedClass = expressionReceiver.type.constructor.declarationDescriptor as? ClassDescriptor ?: 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 + if (!isReferenceToShortFormCompanion(expressionReceiver, unwrappedLhs, context)) return 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 +} diff --git a/compiler/testData/diagnostics/tests/callableReference/bound/companionObject.kt b/compiler/testData/diagnostics/tests/callableReference/bound/companionObject.kt index 63c1488e141..00a8a7635f4 100644 --- a/compiler/testData/diagnostics/tests/callableReference/bound/companionObject.kt +++ b/compiler/testData/diagnostics/tests/callableReference/bound/companionObject.kt @@ -37,5 +37,5 @@ fun test() { val r7 = c::foo checkSubtype<() -> String>(r7) - C::bar + C::bar } diff --git a/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.fir.kt b/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.fir.kt new file mode 100644 index 00000000000..20ab56733de --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.fir.kt @@ -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 \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.fir.txt b/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.fir.txt new file mode 100644 index 00000000000..254edb04b88 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.fir.txt @@ -0,0 +1,28 @@ +FILE: callableReferencesToCompanionMembers.fir.kt + public final class Foo : R|kotlin/Any| { + public constructor(): R|Foo| { + super() + } + + public final companion object Companion : R|kotlin/Any| { + private constructor(): R|Foo.Companion| { + super() + } + + 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| = Q|Foo|::R|/Foo.Companion.bar| + public get(): R|kotlin/reflect/KFunction0| + public final val x2: R|kotlin/reflect/KFunction0| = Q|Foo.Companion|::R|/Foo.Companion.bar| + public get(): R|kotlin/reflect/KFunction0| + public final val x3: R|kotlin/reflect/KProperty0| = Q|Foo|::R|/Foo.Companion.baz| + public get(): R|kotlin/reflect/KProperty0| + public final val x4: R|kotlin/reflect/KProperty0| = Q|Foo.Companion|::R|/Foo.Companion.baz| + public get(): R|kotlin/reflect/KProperty0| diff --git a/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.kt b/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.kt new file mode 100644 index 00000000000..d56a5b38257 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.kt @@ -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 diff --git a/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.txt b/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.txt new file mode 100644 index 00000000000..3a83ef1e537 --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/callableReferencesToCompanionMembers.txt @@ -0,0 +1,22 @@ +package + +public val x1: kotlin.reflect.KFunction1 +public val x2: kotlin.reflect.KFunction0 +public val x3: kotlin.reflect.KProperty1 +public val x4: kotlin.reflect.KProperty0 + +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 + } +} diff --git a/compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.fir.kt b/compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.fir.kt new file mode 100644 index 00000000000..eac7d08a94c --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.fir.kt @@ -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(A()) + A::foo.invoke() + val x = A::foo + x.invoke(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(A()) + A::companionProp.invoke() + val x = A::companionProp + x.invoke(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 id(e: E): E = e + +fun bar(x: () -> Int) {} +fun bam(x: A.() -> Int) {} diff --git a/compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.kt b/compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.kt new file mode 100644 index 00000000000..0dee2127f3d --- /dev/null +++ b/compiler/testData/diagnostics/tests/callableReference/deprecateTopLevelReferenceWithCompanionLHS.kt @@ -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(A()) + A::foo.invoke() + val x = A::foo + x.invoke(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(A()) + A::companionProp.invoke() + val x = A::companionProp + x.invoke(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 id(e: E): E = e + +fun bar(x: () -> Int) {} +fun bam(x: A.() -> Int) {} diff --git a/compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt b/compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt index 4954ec2fc36..2c76bedf428 100644 --- a/compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt +++ b/compiler/testData/diagnostics/tests/callableReference/withQuestionMarks.kt @@ -26,6 +26,6 @@ fun main() { // It must be OK val x18 = String?::hashCode ?: ::foo val x19 = String::hashCode ?: ::foo - val x20 = String?::hashCode::hashCode - val x21 = kotlin.String?::hashCode::hashCode + val x20 = String?::hashCode::hashCode + val x21 = kotlin.String?::hashCode::hashCode } diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferenceComplexCasesWithImportsOld.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferenceComplexCasesWithImportsOld.fir.kt new file mode 100644 index 00000000000..50b605870ff --- /dev/null +++ b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferenceComplexCasesWithImportsOld.fir.kt @@ -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 + } +} diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferenceComplexCasesWithImportsOld.kt b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferenceComplexCasesWithImportsOld.kt index d343907a41e..b5411335739 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferenceComplexCasesWithImportsOld.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferenceComplexCasesWithImportsOld.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion import A.Base.Companion.FromABaseCompanion @@ -54,7 +53,7 @@ object C { } class Derived : Base() { - val a = FromCBaseCompanion::foo + val a = FromCBaseCompanion::foo } } @@ -72,4 +71,4 @@ object D { class Derived : Base() { val a = FromDBaseCompanion::foo } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesComplexCasesWithQualificationOld.fir.kt b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesComplexCasesWithQualificationOld.fir.kt new file mode 100644 index 00000000000..d7070895f59 --- /dev/null +++ b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesComplexCasesWithQualificationOld.fir.kt @@ -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 + } +} diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesComplexCasesWithQualificationOld.kt b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesComplexCasesWithQualificationOld.kt index ca89db31d43..d71d9c87799 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesComplexCasesWithQualificationOld.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesComplexCasesWithQualificationOld.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // !LANGUAGE: -ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion // ===== Case 1: LHS is a class @@ -49,7 +48,7 @@ object C { } class Derived : Base() { - val a = C.Base.Companion.FromBaseCompanion::foo + val a = C.Base.Companion.FromBaseCompanion::foo } } @@ -67,4 +66,4 @@ object D { class Derived : Base() { val a = D.Base.Companion.FromBaseCompanion::foo } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesOldComplexCases.kt b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesOldComplexCases.kt index 7392c330dae..805eadd5731 100644 --- a/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesOldComplexCases.kt +++ b/compiler/testData/diagnostics/tests/objects/kt21515/callableReferencesOldComplexCases.kt @@ -48,7 +48,7 @@ object C { } class Derived : Base() { - val a = FromBaseCompanion::foo + val a = FromBaseCompanion::foo } } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 04593209433..19f3f4bea60 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -2712,6 +2712,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { 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 @TestMetadata("classVsPackage.kt") public void testClassVsPackage() throws Exception { @@ -2748,6 +2754,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { 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 @TestMetadata("deprecatedCompanionReceiverInParentheses.kt") public void testDeprecatedCompanionReceiverInParentheses() throws Exception {