[FIR] Add companion scope before static scope

Static scope is checked first during resolution
(scopes are in reverse order).
This fixes a difference between how K1 and K2 resolve annotations.

#KT-63249 Fixed
This commit is contained in:
Kirill Rakhman
2023-12-12 18:49:45 +01:00
committed by Space Team
parent 2c74a2356a
commit 44b3c66ad7
10 changed files with 603 additions and 5 deletions
@@ -1746,6 +1746,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/annotations/classAnnotationsInLocalClass.kt");
}
@Test
@TestMetadata("companionAnnotations.kt")
public void testCompanionAnnotations() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/companionAnnotations.kt");
}
@Test
@TestMetadata("constantFromOuterScopeAsAnnotaionParameter.kt")
public void testConstantFromOuterScopeAsAnnotaionParameter() throws Exception {
@@ -1746,6 +1746,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/annotations/classAnnotationsInLocalClass.kt");
}
@Test
@TestMetadata("companionAnnotations.kt")
public void testCompanionAnnotations() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/companionAnnotations.kt");
}
@Test
@TestMetadata("constantFromOuterScopeAsAnnotaionParameter.kt")
public void testConstantFromOuterScopeAsAnnotaionParameter() throws Exception {
@@ -1746,6 +1746,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/annotations/classAnnotationsInLocalClass.kt");
}
@Test
@TestMetadata("companionAnnotations.kt")
public void testCompanionAnnotations() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/companionAnnotations.kt");
}
@Test
@TestMetadata("constantFromOuterScopeAsAnnotaionParameter.kt")
public void testConstantFromOuterScopeAsAnnotaionParameter() throws Exception {
@@ -1746,6 +1746,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/annotations/classAnnotationsInLocalClass.kt");
}
@Test
@TestMetadata("companionAnnotations.kt")
public void testCompanionAnnotations() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/companionAnnotations.kt");
}
@Test
@TestMetadata("constantFromOuterScopeAsAnnotaionParameter.kt")
public void testConstantFromOuterScopeAsAnnotaionParameter() throws Exception {
@@ -491,16 +491,21 @@ open class FirTypeResolveTransformer(
}
}
session.nestedClassifierScope(firClass)?.let(scopesToAdd::add)
if (firClass is FirRegularClass) {
val companionObject = firClass.companionObjectSymbol?.fir
if (companionObject != null) {
session.nestedClassifierScope(companionObject)?.let(scopesToAdd::add)
}
// Companion scope is added before static scope,
// i.e., static scope is checked first during resolution (scopes are in reverse order).
// This is because we can qualify companion scope using `Companion.` if we want to explicitly refer to a declaration in the
// companion.
firClass.companionObjectSymbol?.fir
?.let(session::nestedClassifierScope)
?.let(scopesToAdd::add)
session.nestedClassifierScope(firClass)?.let(scopesToAdd::add)
addScopes(scopesToAdd)
addTypeParametersScope(firClass)
} else {
session.nestedClassifierScope(firClass)?.let(scopesToAdd::add)
addScopes(scopesToAdd)
}
@@ -0,0 +1,74 @@
// FIR_DUMP
class CompanionOnly {
@Ann
companion object {
annotation class Ann
@Ann
object Foo
}
}
class Test {
annotation class Ann
@Ann
companion object {
annotation class Ann
@Ann
object Foo
}
}
open class Super {
annotation class Ann
}
class TestWithSuperAndOwn : Super() {
annotation class Ann
@Ann
companion object {
annotation class Ann
@Ann
object Foo
}
}
class TestWithSuperOnly : Super() {
@Ann // Change in resolution from K1 to K2, see KT-64299
companion object {
annotation class Ann
@Ann
object Foo
}
}
open class SuperWithCompanion {
companion object {
annotation class Ann
}
}
class TestWithSuperWithCompanionOnly : SuperWithCompanion() {
@Ann
companion object {
annotation class Ann
@Ann
object Foo
}
}
class TestWithSuperWithCompanionOnly2 : SuperWithCompanion() {
@<!UNRESOLVED_REFERENCE!>Ann<!>
companion object {
@<!UNRESOLVED_REFERENCE!>Ann<!>
object Foo
}
}
@@ -0,0 +1,203 @@
FILE: companionAnnotations.fir.kt
public final class CompanionOnly : R|kotlin/Any| {
public constructor(): R|CompanionOnly| {
super<R|kotlin/Any|>()
}
@R|CompanionOnly.Companion.Ann|() public final companion object Companion : R|kotlin/Any| {
private constructor(): R|CompanionOnly.Companion| {
super<R|kotlin/Any|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|CompanionOnly.Companion.Ann| {
super<R|kotlin/Any|>()
}
}
@R|CompanionOnly.Companion.Ann|() public final object Foo : R|kotlin/Any| {
private constructor(): R|CompanionOnly.Companion.Foo| {
super<R|kotlin/Any|>()
}
}
}
}
public final class Test : R|kotlin/Any| {
public constructor(): R|Test| {
super<R|kotlin/Any|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|Test.Ann| {
super<R|kotlin/Any|>()
}
}
@R|Test.Ann|() public final companion object Companion : R|kotlin/Any| {
private constructor(): R|Test.Companion| {
super<R|kotlin/Any|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|Test.Companion.Ann| {
super<R|kotlin/Any|>()
}
}
@R|Test.Companion.Ann|() public final object Foo : R|kotlin/Any| {
private constructor(): R|Test.Companion.Foo| {
super<R|kotlin/Any|>()
}
}
}
}
public open class Super : R|kotlin/Any| {
public constructor(): R|Super| {
super<R|kotlin/Any|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|Super.Ann| {
super<R|kotlin/Any|>()
}
}
}
public final class TestWithSuperAndOwn : R|Super| {
public constructor(): R|TestWithSuperAndOwn| {
super<R|Super|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|TestWithSuperAndOwn.Ann| {
super<R|kotlin/Any|>()
}
}
@R|TestWithSuperAndOwn.Ann|() public final companion object Companion : R|kotlin/Any| {
private constructor(): R|TestWithSuperAndOwn.Companion| {
super<R|kotlin/Any|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|TestWithSuperAndOwn.Companion.Ann| {
super<R|kotlin/Any|>()
}
}
@R|TestWithSuperAndOwn.Companion.Ann|() public final object Foo : R|kotlin/Any| {
private constructor(): R|TestWithSuperAndOwn.Companion.Foo| {
super<R|kotlin/Any|>()
}
}
}
}
public final class TestWithSuperOnly : R|Super| {
public constructor(): R|TestWithSuperOnly| {
super<R|Super|>()
}
@R|TestWithSuperOnly.Companion.Ann|() public final companion object Companion : R|kotlin/Any| {
private constructor(): R|TestWithSuperOnly.Companion| {
super<R|kotlin/Any|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|TestWithSuperOnly.Companion.Ann| {
super<R|kotlin/Any|>()
}
}
@R|TestWithSuperOnly.Companion.Ann|() public final object Foo : R|kotlin/Any| {
private constructor(): R|TestWithSuperOnly.Companion.Foo| {
super<R|kotlin/Any|>()
}
}
}
}
public open class SuperWithCompanion : R|kotlin/Any| {
public constructor(): R|SuperWithCompanion| {
super<R|kotlin/Any|>()
}
public final companion object Companion : R|kotlin/Any| {
private constructor(): R|SuperWithCompanion.Companion| {
super<R|kotlin/Any|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|SuperWithCompanion.Companion.Ann| {
super<R|kotlin/Any|>()
}
}
}
}
public final class TestWithSuperWithCompanionOnly : R|SuperWithCompanion| {
public constructor(): R|TestWithSuperWithCompanionOnly| {
super<R|SuperWithCompanion|>()
}
@R|TestWithSuperWithCompanionOnly.Companion.Ann|() public final companion object Companion : R|kotlin/Any| {
private constructor(): R|TestWithSuperWithCompanionOnly.Companion| {
super<R|kotlin/Any|>()
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(): R|TestWithSuperWithCompanionOnly.Companion.Ann| {
super<R|kotlin/Any|>()
}
}
@R|TestWithSuperWithCompanionOnly.Companion.Ann|() public final object Foo : R|kotlin/Any| {
private constructor(): R|TestWithSuperWithCompanionOnly.Companion.Foo| {
super<R|kotlin/Any|>()
}
}
}
}
public final class TestWithSuperWithCompanionOnly2 : R|SuperWithCompanion| {
public constructor(): R|TestWithSuperWithCompanionOnly2| {
super<R|SuperWithCompanion|>()
}
@<ERROR TYPE REF: Symbol not found for Ann>() public final companion object Companion : R|kotlin/Any| {
private constructor(): R|TestWithSuperWithCompanionOnly2.Companion| {
super<R|kotlin/Any|>()
}
@<ERROR TYPE REF: Symbol not found for Ann>() public final object Foo : R|kotlin/Any| {
private constructor(): R|TestWithSuperWithCompanionOnly2.Companion.Foo| {
super<R|kotlin/Any|>()
}
}
}
}
@@ -0,0 +1,74 @@
// FIR_DUMP
class CompanionOnly {
@<!UNRESOLVED_REFERENCE!>Ann<!>
companion object {
annotation class Ann
@Ann
object Foo
}
}
class Test {
annotation class Ann
@Ann
companion object {
annotation class Ann
@Ann
object Foo
}
}
open class Super {
annotation class Ann
}
class TestWithSuperAndOwn : Super() {
annotation class Ann
@Ann
companion object {
annotation class Ann
@Ann
object Foo
}
}
class TestWithSuperOnly : Super() {
@Ann // Change in resolution from K1 to K2, see KT-64299
companion object {
annotation class Ann
@Ann
object Foo
}
}
open class SuperWithCompanion {
companion object {
annotation class Ann
}
}
class TestWithSuperWithCompanionOnly : SuperWithCompanion() {
@<!UNRESOLVED_REFERENCE!>Ann<!>
companion object {
annotation class Ann
@Ann
object Foo
}
}
class TestWithSuperWithCompanionOnly2 : SuperWithCompanion() {
@<!UNRESOLVED_REFERENCE!>Ann<!>
companion object {
@<!UNRESOLVED_REFERENCE!>Ann<!>
object Foo
}
}
@@ -0,0 +1,212 @@
package
public final class CompanionOnly {
public constructor CompanionOnly()
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
@[Error type: Unresolved type for Ann] /* annotation class not found */ public companion object Companion {
private constructor Companion()
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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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
}
@CompanionOnly.Companion.Ann public object Foo {
private 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 open class Super {
public constructor Super()
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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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 open class SuperWithCompanion {
public constructor SuperWithCompanion()
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 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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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 final class Test {
public constructor Test()
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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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
}
@Test.Ann public companion object Companion {
private constructor Companion()
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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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
}
@Test.Companion.Ann public object Foo {
private 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 final class TestWithSuperAndOwn : Super {
public constructor TestWithSuperAndOwn()
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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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
}
@TestWithSuperAndOwn.Ann public companion object Companion {
private constructor Companion()
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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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
}
@TestWithSuperAndOwn.Companion.Ann public object Foo {
private 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 final class TestWithSuperOnly : Super {
public constructor TestWithSuperOnly()
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
@Super.Ann public companion object Companion {
private constructor Companion()
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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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
}
@TestWithSuperOnly.Companion.Ann public object Foo {
private 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 final class TestWithSuperWithCompanionOnly : SuperWithCompanion {
public constructor TestWithSuperWithCompanionOnly()
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
@[Error type: Unresolved type for Ann] /* annotation class not found */ public companion object Companion {
private constructor Companion()
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 final annotation class Ann : kotlin.Annotation {
public constructor Ann()
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
}
@TestWithSuperWithCompanionOnly.Companion.Ann public object Foo {
private 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 final class TestWithSuperWithCompanionOnly2 : SuperWithCompanion {
public constructor TestWithSuperWithCompanionOnly2()
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
@[Error type: Unresolved type for Ann] /* annotation class not found */ public companion object Companion {
private constructor Companion()
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
@[Error type: Unresolved type for Ann] /* annotation class not found */ public object Foo {
private 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
}
}
}
@@ -1746,6 +1746,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/annotations/classAnnotationsInLocalClass.kt");
}
@Test
@TestMetadata("companionAnnotations.kt")
public void testCompanionAnnotations() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/companionAnnotations.kt");
}
@Test
@TestMetadata("constantFromOuterScopeAsAnnotaionParameter.kt")
public void testConstantFromOuterScopeAsAnnotaionParameter() throws Exception {