diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 38d18dcc2164a..7613632a51b8c 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -975,6 +975,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.SELF_TYPE_INAPPLICABLE_TARGET) { firDiagnostic -> + SelfTypeInapplicableTargetImpl( + firDiagnostic.a, + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.OPT_IN_USAGE) { firDiagnostic -> OptInUsageImpl( firDiagnostic.a, @@ -2091,6 +2098,12 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.SELF_TYPE_PARAMETER_FOR_CLASS_WITH_SELF_TYPE) { firDiagnostic -> + SelfTypeParameterForClassWithSelfTypeImpl( + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirErrors.EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED) { firDiagnostic -> ExtensionInClassReferenceNotAllowedImpl( firSymbolBuilder.callableBuilder.buildCallableSymbol(firDiagnostic.a), diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index edfc32d369276..6b7cdf9b38311 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -703,6 +703,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { abstract val typeFromTypesPhase: KtType } + abstract class SelfTypeInapplicableTarget : KtFirDiagnostic() { + override val diagnosticClass get() = SelfTypeInapplicableTarget::class + abstract val actualTarget: String + } + abstract class OptInUsage : KtFirDiagnostic() { override val diagnosticClass get() = OptInUsage::class abstract val optInMarkerFqName: FqName @@ -1487,6 +1492,10 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = NullableOnDefinitelyNotNullable::class } + abstract class SelfTypeParameterForClassWithSelfType : KtFirDiagnostic() { + override val diagnosticClass get() = SelfTypeParameterForClassWithSelfType::class + } + abstract class ExtensionInClassReferenceNotAllowed : KtFirDiagnostic() { override val diagnosticClass get() = ExtensionInClassReferenceNotAllowed::class abstract val referencedDeclaration: KtCallableSymbol diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index ec89a7e5feb99..444aa4062ec14 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -844,6 +844,12 @@ internal class PluginAnnotationAmbiguityImpl( override val token: KtLifetimeToken, ) : KtFirDiagnostic.PluginAnnotationAmbiguity(), KtAbstractFirDiagnostic +internal class SelfTypeInapplicableTargetImpl( + override val actualTarget: String, + override val firDiagnostic: KtPsiDiagnostic, + override val token: KtLifetimeToken, +) : KtFirDiagnostic.SelfTypeInapplicableTarget(), KtAbstractFirDiagnostic + internal class OptInUsageImpl( override val optInMarkerFqName: FqName, override val message: String, @@ -1786,6 +1792,11 @@ internal class NullableOnDefinitelyNotNullableImpl( override val token: KtLifetimeToken, ) : KtFirDiagnostic.NullableOnDefinitelyNotNullable(), KtAbstractFirDiagnostic +internal class SelfTypeParameterForClassWithSelfTypeImpl( + override val firDiagnostic: KtPsiDiagnostic, + override val token: KtLifetimeToken, +) : KtFirDiagnostic.SelfTypeParameterForClassWithSelfType(), KtAbstractFirDiagnostic + internal class ExtensionInClassReferenceNotAllowedImpl( override val referencedDeclaration: KtCallableSymbol, override val firDiagnostic: KtPsiDiagnostic, diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index d3055b055f0ab..e144888b5cb63 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -1300,6 +1300,46 @@ public void testVariableInitializedInTryBlock() throws Exception { public void testWhen() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/cfg/when.kt"); } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("basic.kt") + public void testBasic() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.kt"); + } + + @Test + @TestMetadata("extended.kt") + public void testExtended() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.kt"); + } + + @Test + @TestMetadata("innerAndNested.kt") + public void testInnerAndNested() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.kt"); + } + + @Test + @TestMetadata("typeParameters.kt") + public void testTypeParameters() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.kt"); + } + + @Test + @TestMetadata("typealias.kt") + public void testTypealias() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.kt"); + } + } } @Nested @@ -1525,6 +1565,12 @@ public void testConstructorInInterface() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt"); } + @Test + @TestMetadata("customSelfTypeForClassWithSelfAnnotation.kt") + public void testCustomSelfTypeForClassWithSelfAnnotation() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.kt"); + } + @Test @TestMetadata("cyclicConstructorDelegationCall.kt") public void testCyclicConstructorDelegationCall() throws Exception { @@ -1774,6 +1820,46 @@ public void testParameters() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/functionAsExpression/Parameters.kt"); } } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("forAnnotation.kt") + public void testForAnnotation() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.kt"); + } + + @Test + @TestMetadata("forAnonymousObject.kt") + public void testForAnonymousObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.kt"); + } + + @Test + @TestMetadata("forEnumClass.kt") + public void testForEnumClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.kt"); + } + + @Test + @TestMetadata("forEnumEntry.kt") + public void testForEnumEntry() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.kt"); + } + + @Test + @TestMetadata("forObject.kt") + public void testForObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.kt"); + } + } } @Nested diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index d86da1817f65b..3733ad3286802 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -1123,6 +1123,44 @@ public void testVariableInitializedInTryBlock() throws Exception { public void testWhen() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/cfg/when.kt"); } + + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SelfTypes extends AbstractLazyBodyIsNotTouchedTilContractsPhaseTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("basic.kt") + public void testBasic() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.kt"); + } + + @TestMetadata("extended.kt") + public void testExtended() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.kt"); + } + + @TestMetadata("innerAndNested.kt") + public void testInnerAndNested() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.kt"); + } + + @TestMetadata("typeParameters.kt") + public void testTypeParameters() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.kt"); + } + + @TestMetadata("typealias.kt") + public void testTypealias() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.kt"); + } + } } @TestMetadata("compiler/fir/analysis-tests/testData/resolve/constVal") @@ -1334,6 +1372,11 @@ public void testConstructorInInterface() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt"); } + @TestMetadata("customSelfTypeForClassWithSelfAnnotation.kt") + public void testCustomSelfTypeForClassWithSelfAnnotation() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.kt"); + } + @TestMetadata("cyclicConstructorDelegationCall.kt") public void testCyclicConstructorDelegationCall() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/cyclicConstructorDelegationCall.kt"); @@ -1546,6 +1589,44 @@ public void testParameters() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/functionAsExpression/Parameters.kt"); } } + + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SelfTypes extends AbstractLazyBodyIsNotTouchedTilContractsPhaseTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("forAnnotation.kt") + public void testForAnnotation() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.kt"); + } + + @TestMetadata("forAnonymousObject.kt") + public void testForAnonymousObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.kt"); + } + + @TestMetadata("forEnumClass.kt") + public void testForEnumClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.kt"); + } + + @TestMetadata("forEnumEntry.kt") + public void testForEnumEntry() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.kt"); + } + + @TestMetadata("forObject.kt") + public void testForObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.kt"); + } + } } @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness") diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.fir.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.fir.txt new file mode 100644 index 0000000000000..6c133819c0d2c --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.fir.txt @@ -0,0 +1,63 @@ +FILE: basic.kt + @R|kotlin/Self|() public final class JustSelfAnnotation : R|JustSelfAnnotation<>|> : R|kotlin/Any| { + public constructor : R|JustSelfAnnotation<>|>(): R|JustSelfAnnotation<>| { + super() + } + + public final fun anyFun(): R|kotlin/String| { + ^anyFun String(string) + } + + } + @R|kotlin/Self|() public final class ReturnType : R|ReturnType<>|> : R|kotlin/Any| { + public constructor : R|ReturnType<>|>(): R|ReturnType<>| { + super() + } + + public final fun returnTypeWithVal(): R|| { + lval res: R|| = this@R|/ReturnType| + ^returnTypeWithVal R|/res| + } + + } + @R|kotlin/Self|() public final class SelfWithSelfVariable : R|SelfWithSelfVariable<>|> : R|kotlin/Any| { + public constructor : R|SelfWithSelfVariable<>|>(): R|SelfWithSelfVariable<>| { + super() + } + + public final fun returnType(): R|| { + lval Self: R|| = this@R|/SelfWithSelfVariable| + ^returnType R|/Self| + } + + } + @R|kotlin/Self|() public final class SelfTypeWithSelfFunction : R|SelfTypeWithSelfFunction<>|> : R|kotlin/Any| { + public constructor : R|SelfTypeWithSelfFunction<>|>(): R|SelfTypeWithSelfFunction<>| { + super() + } + + public final fun Self(): R|| { + ^Self this@R|/SelfTypeWithSelfFunction| + } + + } + @R|kotlin/Self|() public final class SelfWithFunctionReturningItself : R|SelfWithFunctionReturningItself<>|> : R|kotlin/Any| { + public constructor : R|SelfWithFunctionReturningItself<>|>(): R|SelfWithFunctionReturningItself<>| { + super() + } + + public final fun ret(): R|SelfWithFunctionReturningItself<*>| { + ^ret this@R|/SelfWithFunctionReturningItself| + } + + } + @R|kotlin/Self|() public final class SelfWithFunctionReturningItselfAndTypeParameter : R|SelfWithFunctionReturningItselfAndTypeParameter>|> : R|kotlin/Any| { + public constructor : R|SelfWithFunctionReturningItselfAndTypeParameter>|>(): R|SelfWithFunctionReturningItselfAndTypeParameter>| { + super() + } + + public final fun ret(): R|SelfWithFunctionReturningItselfAndTypeParameter| { + ^ret this@R|/SelfWithFunctionReturningItselfAndTypeParameter| + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.kt new file mode 100644 index 0000000000000..6e0c8e7583ff8 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.kt @@ -0,0 +1,44 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +import kotlin.Self + +@Self +class JustSelfAnnotation { + fun anyFun(): String = "string" +} + +@Self +class ReturnType { + fun returnTypeWithVal(): Self { + val res: Self = this + return res + } +} + +@Self +class SelfWithSelfVariable { + fun returnType(): Self { + val Self: Self = this + return Self + } +} + +@Self +class SelfTypeWithSelfFunction { + fun Self(): Self { + return this + } +} + +@Self +class SelfWithFunctionReturningItself { + fun ret(): SelfWithFunctionReturningItself { + return this + } +} + +@Self +class SelfWithFunctionReturningItselfAndTypeParameter { + fun ret(): SelfWithFunctionReturningItselfAndTypeParameter { + return this + } +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.fir.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.fir.txt new file mode 100644 index 0000000000000..eda7521872d47 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.fir.txt @@ -0,0 +1,96 @@ +FILE: extended.kt + @R|kotlin/Self|() public abstract interface SelfTypeParameterInterface : R|SelfTypeParameterInterface<>|> : R|kotlin/Any| { + } + @R|kotlin/Self|() public final class SelfTypeAsTypeParameterInExtends : R|SelfTypeAsTypeParameterInExtends<>|> : R|SelfTypeParameterInterface<>| { + public constructor : R|SelfTypeAsTypeParameterInExtends<>|>(): R|SelfTypeAsTypeParameterInExtends<>| { + super() + } + + public final fun returnType(): R|| { + ^returnType this@R|/SelfTypeAsTypeParameterInExtends| + } + + } + @R|kotlin/Self|() public final class SelfTypeWithSelfFunction : R|SelfTypeWithSelfFunction<>|> : R|kotlin/Any| { + public constructor : R|SelfTypeWithSelfFunction<>|>(): R|SelfTypeWithSelfFunction<>| { + super() + } + + public final fun Self(): R|| { + ^Self this@R|/SelfTypeWithSelfFunction| + } + + } + public abstract interface WithTypeParameter : R|kotlin/Any| { + public abstract fun foo(): R|T| + + } + @R|kotlin/Self|() public final class ExtendingInterfaceWithTypeParameter : R|ExtendingInterfaceWithTypeParameter<>|> : R|WithTypeParameter<>| { + public constructor : R|ExtendingInterfaceWithTypeParameter<>|>(): R|ExtendingInterfaceWithTypeParameter<>| { + super() + } + + public open override fun foo(): R|| { + ^foo this@R|/ExtendingInterfaceWithTypeParameter| + } + + } + @R|kotlin/Self|() public abstract class AbstractClassWithSelf : R|AbstractClassWithSelf>|> : R|kotlin/Any| { + public constructor : R|AbstractClassWithSelf>|>(): R|AbstractClassWithSelf>| { + super() + } + + public abstract fun self(): R|| + + } + public final class ExtendingAbstractClassWithSelf : R|AbstractClassWithSelf>| { + public constructor(): R|ExtendingAbstractClassWithSelf| { + super>|>() + } + + public open override fun self(): R|ExtendingAbstractClassWithSelf| { + ^self this@R|/ExtendingAbstractClassWithSelf| + } + + } + @R|kotlin/Self|() public open class SelfClassWithNested : R|SelfClassWithNested<>|> : R|kotlin/Any| { + public constructor : R|SelfClassWithNested<>|>(): R|SelfClassWithNested<>| { + super() + } + + public final class NestedClassExtendingOuterSelf : R|SelfClassWithNested| { + public constructor(): R|SelfClassWithNested.NestedClassExtendingOuterSelf| { + super|>() + } + + public final fun foo(): R|SelfClassWithNested.NestedClassExtendingOuterSelf| { + ^foo this@R|/SelfClassWithNested.NestedClassExtendingOuterSelf| + } + + } + + } + public final class OuterClassWithNested : R|kotlin/Any| { + public constructor(): R|OuterClassWithNested| { + super() + } + + @R|kotlin/Self|() public open class SelfNested : R|OuterClassWithNested.SelfNested<>|> : R|kotlin/Any| { + public constructor : R|OuterClassWithNested.SelfNested<>|>(): R|OuterClassWithNested.SelfNested<>| { + super() + } + + } + + public final class NestedExtendingSelfNested : R|OuterClassWithNested.SelfNested| { + public constructor(): R|OuterClassWithNested.NestedExtendingSelfNested| { + super|>() + } + + public final fun foo(): R|OuterClassWithNested.NestedExtendingSelfNested| { + ^foo this@R|/OuterClassWithNested.NestedExtendingSelfNested| + } + + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.kt new file mode 100644 index 0000000000000..136e83a25dd11 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.kt @@ -0,0 +1,64 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +import kotlin.Self + +@Self +interface SelfTypeParameterInterface + +@Self +class SelfTypeAsTypeParameterInExtends : SelfTypeParameterInterface { + + fun returnType(): Self { + return this + } +} + +@Self +class SelfTypeWithSelfFunction { + fun Self(): Self { + return this + } +} + +interface WithTypeParameter { + fun foo(): T +} + +@Self +class ExtendingInterfaceWithTypeParameter : WithTypeParameter { + override fun foo(): Self { + return this + } +} + +@Self +abstract class AbstractClassWithSelf { + abstract fun self(): Self +} + +class ExtendingAbstractClassWithSelf : AbstractClassWithSelf>() { + override fun self(): ExtendingAbstractClassWithSelf { + return this + } +} + +@Self +open class SelfClassWithNested { + class NestedClassExtendingOuterSelf : SelfClassWithNested() { + fun foo(): NestedClassExtendingOuterSelf { + return this + } + } +} + +class OuterClassWithNested { + @Self + open class SelfNested { + + } + + class NestedExtendingSelfNested : SelfNested() { + fun foo(): NestedExtendingSelfNested { + return this + } + } +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.fir.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.fir.txt new file mode 100644 index 0000000000000..aea88f967fa34 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.fir.txt @@ -0,0 +1,119 @@ +FILE: innerAndNested.kt + public final class InnerClass : R|kotlin/Any| { + public constructor(): R|InnerClass| { + super() + } + + @R|kotlin/Self|() public final inner class Inner : R|InnerClass.Inner<>|> : R|kotlin/Any| { + public InnerClass.constructor : R|InnerClass.Inner<>|>(): R|InnerClass.Inner<>| { + super() + } + + public final fun returnType(): R|| { + ^returnType this@R|/InnerClass.Inner| + } + + } + + } + public final class NestedClass : R|kotlin/Any| { + public constructor(): R|NestedClass| { + super() + } + + @R|kotlin/Self|() public final class Nested : R|NestedClass.Nested<>|> : R|kotlin/Any| { + public constructor : R|NestedClass.Nested<>|>(): R|NestedClass.Nested<>| { + super() + } + + public final fun returnType(): R|| { + ^returnType this@R|/NestedClass.Nested| + } + + } + + } + @R|kotlin/Self|() public final class InnerSelfClass : R|InnerSelfClass<>|> : R|kotlin/Any| { + public constructor : R|InnerSelfClass<>|>(): R|InnerSelfClass<>| { + super() + } + + public final inner class Self : R|kotlin/Any| { + public InnerSelfClass.constructor(): R|InnerSelfClass.Self| { + super() + } + + public final fun returnSelf(): R|InnerSelfClass.Self| { + ^returnSelf this@R|/InnerSelfClass.Self| + } + + } + + public final fun returnType(): R|| { + ^returnType this@R|/InnerSelfClass| + } + + public final fun returnSelfClassType(): R|InnerSelfClass.Self| { + ^returnSelfClassType R|/InnerSelfClass.InnerSelfClass||>().R|/InnerSelfClass.Self.Self|() + } + + } + public final class InnerClassWithSelfAnnotation|> : R|kotlin/Any| { + public constructor|>(): R|InnerClassWithSelfAnnotation| { + super() + } + + @R|kotlin/Self|() public final inner class SelfAnnotated|, out : R|InnerClassWithSelfAnnotation.SelfAnnotated>|> : R|kotlin/Any| { + public InnerClassWithSelfAnnotation.constructor : R|InnerClassWithSelfAnnotation.SelfAnnotated>|>(): R|InnerClassWithSelfAnnotation.SelfAnnotated>| { + super() + } + + public final fun returnType(): R|| { + ^returnType this@R|/InnerClassWithSelfAnnotation.SelfAnnotated| + } + + } + + @R|kotlin/Suppress|(names = vararg(String(UNCHECKED_CAST))) public final fun returnType(): R|S| { + ^returnType (this@R|/InnerClassWithSelfAnnotation| as R|S|) + } + + } + @R|kotlin/Self|() public final class QualifiedThisClass : R|QualifiedThisClass<>|> : R|kotlin/Any| { + public constructor : R|QualifiedThisClass<>|>(): R|QualifiedThisClass<>| { + super() + } + + public final inner class Inner : R|kotlin/Any| { + public QualifiedThisClass.constructor(): R|QualifiedThisClass.Inner| { + super() + } + + public final fun foo(): R|| { + ^foo this@R|/QualifiedThisClass| + } + + } + + } + @R|kotlin/Self|() public final class Outer : R|Outer<>|> : R|kotlin/Any| { + public constructor : R|Outer<>|>(): R|Outer<>| { + super() + } + + @R|kotlin/Self|() public final class Nested : R|Outer.Nested<>|> : R|kotlin/Any| { + public constructor : R|Outer.Nested<>|>(): R|Outer.Nested<>| { + super() + } + + public final fun nested(): R|| { + ^nested this@R|/Outer.Nested| + } + + } + + public final fun outer(): R|| { + ^outer this@R|/Outer| + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.kt new file mode 100644 index 0000000000000..d04a4a3c68f04 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.kt @@ -0,0 +1,78 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +import kotlin.Self + +class InnerClass { + @Self + inner class Inner { + fun returnType(): Self { + return this + } + } +} + +class NestedClass { + @Self + class Nested { + fun returnType(): Self { + return this + } + } +} + +@Self +class InnerSelfClass { + inner class Self { + fun returnSelf(): InnerSelfClass.Self { + return this + } + } + + fun returnType(): Self { + return this + } + + fun returnSelfClassType(): InnerSelfClass.Self { + return InnerSelfClass>().Self() + } +} + + +class InnerClassWithSelfAnnotation> { + + @Self + inner class SelfAnnotated { + fun returnType(): Self { + return this + } + } + + @Suppress("UNCHECKED_CAST") + fun returnType(): S { + return this as S + } + +} + +@Self +class QualifiedThisClass { + inner class Inner { + fun foo(): Self { + return this@QualifiedThisClass + } + } +} + +@Self +class Outer { + + @kotlin.Self + class Nested { + fun nested(): Self { + return this + } + } + + fun outer(): Self { + return this + } +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.fir.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.fir.txt new file mode 100644 index 0000000000000..810b9f19061d7 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.fir.txt @@ -0,0 +1,31 @@ +FILE: typeParameters.kt + @R|kotlin/Self|() public final class ReturnTypeWithTypeParameter : R|ReturnTypeWithTypeParameter>|> : R|kotlin/Any| { + public constructor : R|ReturnTypeWithTypeParameter>|>(): R|ReturnTypeWithTypeParameter>| { + super() + } + + public final fun returnType(): R|| { + ^returnType this@R|/ReturnTypeWithTypeParameter| + } + + public final fun functionWithImplicitConstructor(): R|| { + lval s: R|ReturnTypeWithTypeParameter>| = R|/ReturnTypeWithTypeParameter.ReturnTypeWithTypeParameter||>() + ^functionWithImplicitConstructor this@R|/ReturnTypeWithTypeParameter| + } + + public final fun functionWithManualConstructor(): R|| { + lval s: R|ReturnTypeWithTypeParameter>| = R|/ReturnTypeWithTypeParameter.ReturnTypeWithTypeParameter||>() + ^functionWithManualConstructor this@R|/ReturnTypeWithTypeParameter| + } + + } + @R|kotlin/Self|() public final class ReturnTypeWithMultipleTypeParameters : R|ReturnTypeWithMultipleTypeParameters>|> : R|kotlin/Any| { + public constructor : R|ReturnTypeWithMultipleTypeParameters>|>(): R|ReturnTypeWithMultipleTypeParameters>| { + super() + } + + public final fun returnType(): R|| { + ^returnType this@R|/ReturnTypeWithMultipleTypeParameters| + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.kt new file mode 100644 index 0000000000000..335e90598c5c5 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.kt @@ -0,0 +1,26 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +import kotlin.Self + +@Self +class ReturnTypeWithTypeParameter { + fun returnType(): Self { + return this + } + + fun functionWithImplicitConstructor(): Self { + val s = ReturnTypeWithTypeParameter() + return this + } + + fun functionWithManualConstructor(): Self { + val s = ReturnTypeWithTypeParameter>() + return this + } +} + +@Self +class ReturnTypeWithMultipleTypeParameters { + fun returnType(): Self { + return this + } +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.fir.txt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.fir.txt new file mode 100644 index 0000000000000..bd5ecfecbdd35 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.fir.txt @@ -0,0 +1,17 @@ +FILE: typealias.kt + @R|kotlin/Self|() public final class TypealiasSelf : R|TypealiasSelf<>|> : R|kotlin/Any| { + public constructor : R|TypealiasSelf<>|>(): R|TypealiasSelf<>| { + super() + } + + @R|kotlin/Suppress|(names = vararg(String(TOPLEVEL_TYPEALIASES_ONLY))) public final typealias Self = R|kotlin/String| + + public final fun returnType(): R|| { + ^returnType this@R|/TypealiasSelf| + } + + public final fun returnTypealias(): R|TypealiasSelf.Self| { + ^returnTypealias String(typealias) + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.kt new file mode 100644 index 0000000000000..0fa4c5e845093 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.kt @@ -0,0 +1,16 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +import kotlin.Self + +@Self +class TypealiasSelf { + @Suppress("TOPLEVEL_TYPEALIASES_ONLY") + typealias Self = String + + fun returnType(): Self { + return this + } + + fun returnTypealias(): TypealiasSelf.Self { + return "typealias" + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.fir.txt new file mode 100644 index 0000000000000..f56ba3e55169d --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.fir.txt @@ -0,0 +1,11 @@ +FILE: customSelfTypeForClassWithSelfAnnotation.kt + @R|kotlin/Self|() public final class ClassWithCustomSelfTypeParameter : R|ClassWithCustomSelfTypeParameter>|> : R|kotlin/Any| { + public constructor : R|ClassWithCustomSelfTypeParameter>|>(): R|ClassWithCustomSelfTypeParameter>| { + super() + } + + public final fun returnType(): R|Self| { + ^returnType this@R|/ClassWithCustomSelfTypeParameter| + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.kt new file mode 100644 index 0000000000000..8ea6cd5937395 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.kt @@ -0,0 +1,7 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +@Self +class ClassWithCustomSelfTypeParameter<Self> { + fun returnType(): Self { + return this + } +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.fir.txt new file mode 100644 index 0000000000000..6b7d6e194aa3a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.fir.txt @@ -0,0 +1,7 @@ +FILE: forAnnotation.kt + @R|kotlin/Self|() public final annotation class AnnotationClass : R|AnnotationClass<>|> : R|kotlin/Annotation| { + public constructor : R|AnnotationClass<>|>(): R|AnnotationClass<>| { + super() + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.kt new file mode 100644 index 0000000000000..0b6e26db3cb4c --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.kt @@ -0,0 +1,6 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +import kotlin.Self +@Self +annotation class AnnotationClass { + +} diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.fir.txt new file mode 100644 index 0000000000000..4d7596f8515aa --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.fir.txt @@ -0,0 +1,23 @@ +FILE: forAnonymousObject.kt + public abstract class AbstractClass : R|kotlin/Any| { + public constructor(): R|AbstractClass| { + super() + } + + } + public final val abstractClassObject: R|AbstractClass| = @R|kotlin/Self|() object : R|AbstractClass| { + private constructor(): R|| { + super() + } + + } + + public get(): R|AbstractClass| + public final val obj: R|kotlin/Any| = @R|kotlin/Self|() object : R|kotlin/Any| { + private constructor(): R|| { + super() + } + + } + + public get(): R|kotlin/Any| diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.kt new file mode 100644 index 0000000000000..0300872dfa997 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.kt @@ -0,0 +1,13 @@ +import kotlin.Self + +abstract class AbstractClass { + +} + +val abstractClassObject = @Self object : AbstractClass() { + +} + +val obj = @Self object { + +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.fir.txt new file mode 100644 index 0000000000000..69a811997621b --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.fir.txt @@ -0,0 +1,16 @@ +FILE: forEnumClass.kt + @R|kotlin/Self|() public final enum class EnumClass : R|EnumClass<>|> : R|kotlin/Enum| { + private constructor : R|EnumClass<>|>(): R|EnumClass<>| { + super|>() + } + + public final static fun values(): R|kotlin/Array| { + } + + public final static fun valueOf(value: R|kotlin/String|): R|EnumClass| { + } + + public final static val entries: R|kotlin/enums/EnumEntries| + public get(): R|kotlin/enums/EnumEntries| + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.kt new file mode 100644 index 0000000000000..4ce029d2f1487 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.kt @@ -0,0 +1,6 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +import kotlin.Self +@Self +enum class EnumClass { + +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.fir.txt new file mode 100644 index 0000000000000..504534ce1ef14 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.fir.txt @@ -0,0 +1,23 @@ +FILE: forEnumEntry.kt + public final enum class EnumClass : R|kotlin/Enum| { + private constructor(): R|EnumClass| { + super|>() + } + + @R|kotlin/Self|() public final static enum entry Entry: R|EnumClass| = object : R|EnumClass| { + private constructor(): R|| { + super() + } + + } + + public final static fun values(): R|kotlin/Array| { + } + + public final static fun valueOf(value: R|kotlin/String|): R|EnumClass| { + } + + public final static val entries: R|kotlin/enums/EnumEntries| + public get(): R|kotlin/enums/EnumEntries| + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.kt new file mode 100644 index 0000000000000..a4354219236d3 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.kt @@ -0,0 +1,5 @@ +import kotlin.Self +enum class EnumClass { + @Self + Entry +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.fir.txt new file mode 100644 index 0000000000000..87bcd62de18c5 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.fir.txt @@ -0,0 +1,7 @@ +FILE: forObject.kt + @R|kotlin/Self|() public final object CustomObject : R|CustomObject<>|> : R|kotlin/Any| { + private constructor : R|CustomObject<>|>(): R|CustomObject<>| { + super() + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.kt new file mode 100644 index 0000000000000..d82b17223c70d --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.kt @@ -0,0 +1,6 @@ +// FIR_DISABLE_LAZY_RESOLVE_CHECKS +import kotlin.Self +@Self +object CustomObject { + +} \ No newline at end of file diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index f0d886c8ca9d4..a1e6af3e78d7a 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -1300,6 +1300,46 @@ public void testVariableInitializedInTryBlock() throws Exception { public void testWhen() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/cfg/when.kt"); } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("basic.kt") + public void testBasic() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.kt"); + } + + @Test + @TestMetadata("extended.kt") + public void testExtended() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.kt"); + } + + @Test + @TestMetadata("innerAndNested.kt") + public void testInnerAndNested() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.kt"); + } + + @Test + @TestMetadata("typeParameters.kt") + public void testTypeParameters() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.kt"); + } + + @Test + @TestMetadata("typealias.kt") + public void testTypealias() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.kt"); + } + } } @Nested @@ -1525,6 +1565,12 @@ public void testConstructorInInterface() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt"); } + @Test + @TestMetadata("customSelfTypeForClassWithSelfAnnotation.kt") + public void testCustomSelfTypeForClassWithSelfAnnotation() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.kt"); + } + @Test @TestMetadata("cyclicConstructorDelegationCall.kt") public void testCyclicConstructorDelegationCall() throws Exception { @@ -1774,6 +1820,46 @@ public void testParameters() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/functionAsExpression/Parameters.kt"); } } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("forAnnotation.kt") + public void testForAnnotation() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.kt"); + } + + @Test + @TestMetadata("forAnonymousObject.kt") + public void testForAnonymousObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.kt"); + } + + @Test + @TestMetadata("forEnumClass.kt") + public void testForEnumClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.kt"); + } + + @Test + @TestMetadata("forEnumEntry.kt") + public void testForEnumEntry() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.kt"); + } + + @Test + @TestMetadata("forObject.kt") + public void testForObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.kt"); + } + } } @Nested diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index 269666163f142..22aca05e18327 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -1300,6 +1300,46 @@ public void testVariableInitializedInTryBlock() throws Exception { public void testWhen() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/cfg/when.kt"); } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("basic.kt") + public void testBasic() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/basic.kt"); + } + + @Test + @TestMetadata("extended.kt") + public void testExtended() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/extended.kt"); + } + + @Test + @TestMetadata("innerAndNested.kt") + public void testInnerAndNested() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/innerAndNested.kt"); + } + + @Test + @TestMetadata("typeParameters.kt") + public void testTypeParameters() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typeParameters.kt"); + } + + @Test + @TestMetadata("typealias.kt") + public void testTypealias() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/cfg/selfTypes/typealias.kt"); + } + } } @Nested @@ -1525,6 +1565,12 @@ public void testConstructorInInterface() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/constructorInInterface.kt"); } + @Test + @TestMetadata("customSelfTypeForClassWithSelfAnnotation.kt") + public void testCustomSelfTypeForClassWithSelfAnnotation() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/customSelfTypeForClassWithSelfAnnotation.kt"); + } + @Test @TestMetadata("cyclicConstructorDelegationCall.kt") public void testCyclicConstructorDelegationCall() throws Exception { @@ -1774,6 +1820,46 @@ public void testParameters() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/functionAsExpression/Parameters.kt"); } } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("forAnnotation.kt") + public void testForAnnotation() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnnotation.kt"); + } + + @Test + @TestMetadata("forAnonymousObject.kt") + public void testForAnonymousObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forAnonymousObject.kt"); + } + + @Test + @TestMetadata("forEnumClass.kt") + public void testForEnumClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumClass.kt"); + } + + @Test + @TestMetadata("forEnumEntry.kt") + public void testForEnumEntry() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forEnumEntry.kt"); + } + + @Test + @TestMetadata("forObject.kt") + public void testForObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/diagnostics/selfTypes/forObject.kt"); + } + } } @Nested diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index b90a670ca9763..312706d62e28b 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -298,6 +298,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { parameter("typeFromCompilerPhase") parameter("typeFromTypesPhase") } + + val SELF_TYPE_INAPPLICABLE_TARGET by error() { + parameter("actualTarget") + } } val OPT_IN by object : DiagnosticGroup("OptIn") { @@ -728,6 +732,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { val INCORRECT_LEFT_COMPONENT_OF_INTERSECTION by error() val INCORRECT_RIGHT_COMPONENT_OF_INTERSECTION by error() val NULLABLE_ON_DEFINITELY_NOT_NULLABLE by error() + + val SELF_TYPE_PARAMETER_FOR_CLASS_WITH_SELF_TYPE by error() } val REFLECTION by object : DiagnosticGroup("Reflection") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 0deb1a06694df..c932cf01ecd42 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -259,6 +259,7 @@ object FirErrors { val WRONG_EXTENSION_FUNCTION_TYPE_WARNING by warning0() val ANNOTATION_IN_WHERE_CLAUSE_ERROR by error0() val PLUGIN_ANNOTATION_AMBIGUITY by error2() + val SELF_TYPE_INAPPLICABLE_TARGET by error1() // OptIn val OPT_IN_USAGE by warning2(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) @@ -429,6 +430,7 @@ object FirErrors { val INCORRECT_LEFT_COMPONENT_OF_INTERSECTION by error0() val INCORRECT_RIGHT_COMPONENT_OF_INTERSECTION by error0() val NULLABLE_ON_DEFINITELY_NOT_NULLABLE by error0() + val SELF_TYPE_PARAMETER_FOR_CLASS_WITH_SELF_TYPE by error0() // Reflection val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt index 61c4c51b271ad..aeb732bc3c463 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/CommonDeclarationCheckers.kt @@ -93,6 +93,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirTypeParametersInObjectChecker, FirSupertypesChecker, FirPrimaryConstructorSuperTypeChecker, + FirSelfTypeChecker ) override val regularClassCheckers: Set diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt index b67cbf216d573..b09e777a32db0 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt @@ -19,8 +19,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.utils.fromPrimaryConstructor -import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField +import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.packageFqName @@ -33,6 +32,7 @@ import org.jetbrains.kotlin.name.StandardClassIds object FirAnnotationChecker : FirBasicDeclarationChecker() { private val deprecatedClassId = FqName("kotlin.Deprecated") private val deprecatedSinceKotlinClassId = FqName("kotlin.DeprecatedSinceKotlin") + private val selfClassId = FqName("kotlin.Self") override fun check( declaration: FirDeclaration, @@ -41,13 +41,20 @@ object FirAnnotationChecker : FirBasicDeclarationChecker() { ) { var deprecated: FirAnnotation? = null var deprecatedSinceKotlin: FirAnnotation? = null + var self: FirAnnotation? = null for (annotation in declaration.annotations) { val fqName = annotation.fqName(context.session) ?: continue - if (fqName == deprecatedClassId) { - deprecated = annotation - } else if (fqName == deprecatedSinceKotlinClassId) { - deprecatedSinceKotlin = annotation + when (fqName) { + deprecatedClassId -> { + deprecated = annotation + } + deprecatedSinceKotlinClassId -> { + deprecatedSinceKotlin = annotation + } + selfClassId -> { + self = annotation + } } checkAnnotationTarget(declaration, annotation, context, reporter) @@ -62,6 +69,14 @@ object FirAnnotationChecker : FirBasicDeclarationChecker() { } } + if (self != null) { + if (declaration is FirClass) { + if (declaration.isEnumClass || declaration.isAnnotationClass || declaration.isObject) { + reporter.reportOn(self.source, FirErrors.SELF_TYPE_INAPPLICABLE_TARGET, declaration.classKind.name, context) + } + } + } + if (deprecatedSinceKotlin != null) { checkDeprecatedCalls(deprecatedSinceKotlin, deprecated, context, reporter) } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSelfTypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSelfTypeChecker.kt new file mode 100644 index 0000000000000..6cc001ee6569e --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSelfTypeChecker.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.checkers.declaration + +import org.jetbrains.kotlin.builtins.StandardNames.SELF_TYPE_NAME +import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.reportOn +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.declarations.FirClass +import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId +import org.jetbrains.kotlin.fir.expressions.FirAnnotation +import org.jetbrains.kotlin.name.StandardClassIds + +object FirSelfTypeChecker : FirClassChecker() { + override fun check(declaration: FirClass, context: CheckerContext, reporter: DiagnosticReporter) { + val self: FirAnnotation? = declaration.getAnnotationByClassId(StandardClassIds.Annotations.Self, context.session) + + if (self != null) { + val typeParameter = declaration.typeParameters.find { it.symbol.name.asString() == SELF_TYPE_NAME } + if (typeParameter != null) { + reporter.reportOn(typeParameter.source, FirErrors.SELF_TYPE_PARAMETER_FOR_CLASS_WITH_SELF_TYPE, context) + } + } + } + +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt index 477357c261ffb..b4a029aa887aa 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCastOperatorsChecker.kt @@ -9,9 +9,9 @@ import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.checkers.CastingType +import org.jetbrains.kotlin.fir.analysis.checkers.checkCasting import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.isCastErased -import org.jetbrains.kotlin.fir.analysis.checkers.checkCasting import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.expressions.FirOperation import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt index d9492579a6ab6..c981674d1b069 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrorsDefaultMessages.kt @@ -289,10 +289,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ITERATOR_MISSING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ITERATOR_ON_NULLABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_FIELD_IN_VAL_PROPERTY -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_INTRINSIC_CALL_IN_INLINE_FUNCTION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_INTRINSIC_CALL_ON_NON_ACCESSIBLE_PROPERTY +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_INTRINSIC_CALL_ON_NON_LATEINIT +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_INTRINSIC_CALL_ON_NON_LITERAL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_NULLABLE_BACKING_FIELD import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LATEINIT_PROPERTY_FIELD_DECLARATION_WITH_INITIALIZER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LEAKED_IN_PLACE_LAMBDA @@ -478,6 +478,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_INHERITOR_ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_SUPERTYPE_IN_LOCAL_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_VALUE_CLASS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SELF_TYPE_INAPPLICABLE_TARGET +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SELF_TYPE_PARAMETER_FOR_CLASS_WITH_SELF_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SENSELESS_COMPARISON import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SENSELESS_NULL_IN_WHEN import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SETTER_PROJECTED_OUT @@ -857,7 +859,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { map.put(REPEATED_ANNOTATION, "This annotation is not repeatable") map.put(REPEATED_ANNOTATION_WARNING, "This annotation is not repeatable") map.put(NON_INTERNAL_PUBLISHED_API, "@PublishedApi annotation is only applicable for internal declaration") - + map.put(SELF_TYPE_INAPPLICABLE_TARGET, "Self type annotation is not applicable to target ''{0}''", TO_STRING) // OptIn map.put(OPT_IN_USAGE, "{1}", TO_STRING, STRING) map.put(OPT_IN_USAGE_ERROR, "{1}", TO_STRING, STRING) @@ -1250,6 +1252,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() { ) map.put(DYNAMIC_UPPER_BOUND, "Dynamic type can not be used as an upper bound") + map.put(SELF_TYPE_PARAMETER_FOR_CLASS_WITH_SELF_TYPE, "Custom Self type parameter cannot be declared for classes with @Self.") // Reflection map.put( diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt index 21d49a28e7545..5e0bb2950f4f3 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.SpecialNames.SELF_TYPE import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlin.utils.addToStdlib.runUnless @@ -112,7 +113,7 @@ class Fir2IrClassifierStorage( typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT ) { typeParameters = owner.typeParameters.mapIndexedNotNull { index, typeParameter -> - if (typeParameter !is FirTypeParameter) return@mapIndexedNotNull null + if (typeParameter !is FirTypeParameter || (typeParameter.name == SELF_TYPE && owner is FirConstructor)) return@mapIndexedNotNull null getIrTypeParameter(typeParameter, index, symbol, typeContext).apply { parent = this@setTypeParameters if (superTypes.isEmpty()) { @@ -388,6 +389,7 @@ class Fir2IrClassifierStorage( require(index >= 0) val origin = typeParameter.computeIrOrigin() val irTypeParameter = with(typeParameter) { + val replacedSelfName = if (name == SELF_TYPE) SELF_TYPE_IDENTIFIER else name convertWithOffsets { startOffset, endOffset -> signatureComposer.composeTypeParameterSignature( typeParameter, index, ownerSymbol.signature @@ -399,7 +401,7 @@ class Fir2IrClassifierStorage( ) { symbol -> irFactory.createTypeParameter( startOffset, endOffset, origin, symbol, - name, if (index < 0) 0 else index, + replacedSelfName, if (index < 0) 0 else index, isReified, variance ) @@ -411,7 +413,7 @@ class Fir2IrClassifierStorage( ) { symbol -> irFactory.createTypeParameter( startOffset, endOffset, origin, symbol, - name, if (index < 0) 0 else index, + replacedSelfName, if (index < 0) 0 else index, isReified, variance ) @@ -420,7 +422,7 @@ class Fir2IrClassifierStorage( } } ?: irFactory.createTypeParameter( startOffset, endOffset, origin, IrTypeParameterSymbolImpl(), - name, if (index < 0) 0 else index, + replacedSelfName, if (index < 0) 0 else index, isReified, variance ) @@ -622,4 +624,8 @@ class Fir2IrClassifierStorage( parent = IrExternalPackageFragmentImpl(IrExternalPackageFragmentSymbolImpl(), FqName.ROOT) } } + + companion object Fir2IrClassifierStorage { + private val SELF_TYPE_IDENTIFIER = Name.identifier("\$Self") + } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 384bbfb081adb..5c24a19d94083 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -1440,8 +1440,14 @@ class Fir2IrDeclarationStorage( firPropertySymbol.dispatchReceiverClassLookupTagOrNull() != firPropertySymbol.originalForSubstitutionOverride?.dispatchReceiverClassLookupTagOrNull() Fir2IrLazyProperty( - components, startOffset, endOffset, declarationOrigin, - fir, (lazyParent as? Fir2IrLazyClass)?.fir, symbol, isFakeOverride + components, + startOffset, + endOffset, + declarationOrigin, + fir, + (lazyParent as? Fir2IrLazyClass)?.fir, + symbol, + isFakeOverride ).apply { this.parent = lazyParent } diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 361a1c4c71c50..4a30b9a4a93d9 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -18384,6 +18384,64 @@ public void testSuspendExtension() throws Exception { public void testUnqualifiedEnum() throws Exception { runTest("compiler/testData/codegen/box/fir/unqualifiedEnum.kt"); } + + @Nested + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("classWithSelfType.kt") + public void testClassWithSelfType() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/classWithSelfType.kt"); + } + + @Test + @TestMetadata("ControlFlowInfoSelfTypes.kt") + public void testControlFlowInfoSelfTypes() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/ControlFlowInfoSelfTypes.kt"); + } + + @Test + @TestMetadata("observer.kt") + public void testObserver() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/observer.kt"); + } + + @Test + @TestMetadata("selfClassAsFunctionArgument.kt") + public void testSelfClassAsFunctionArgument() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/selfClassAsFunctionArgument.kt"); + } + + @Test + @TestMetadata("selfClassAsReturnType.kt") + public void testSelfClassAsReturnType() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/selfClassAsReturnType.kt"); + } + + @Test + @TestMetadata("selfTypeBuilder.kt") + public void testSelfTypeBuilder() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/selfTypeBuilder.kt"); + } + + @Test + @TestMetadata("selfTypeInSealedInterface.kt") + public void testSelfTypeInSealedInterface() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/selfTypeInSealedInterface.kt"); + } + + @Test + @TestMetadata("transformationChainLazyContainer.kt") + public void testTransformationChainLazyContainer() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/transformationChainLazyContainer.kt"); + } + } } @Nested diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaClass.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaClass.kt index baa08cad75ebe..712483cffa278 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaClass.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaClass.kt @@ -78,6 +78,11 @@ class FirJavaClass @FirImplementationDetail internal constructor( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) { deprecationsProvider = newDeprecationsProvider } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt index b53568fa1584b..2715c7ee2da5a 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaConstructor.kt @@ -78,6 +78,11 @@ class FirJavaConstructor @FirImplementationDetail constructor( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun acceptChildren(visitor: FirVisitor, data: D) { returnTypeRef.accept(visitor, data) controlFlowGraphReference?.accept(visitor, data) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt index 74b1228c4611f..42b0449363fd6 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt @@ -101,6 +101,11 @@ class FirJavaField @FirImplementationDetail constructor( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun acceptChildren(visitor: FirVisitor, data: D) { returnTypeRef.accept(visitor, data) annotations.forEach { it.accept(visitor, data) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaMethod.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaMethod.kt index f5cc3f5952a94..cfe324ba2beec 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaMethod.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaMethod.kt @@ -152,6 +152,9 @@ class FirJavaMethod @FirImplementationDetail constructor( return this } + override fun replaceTypeParameters(newTypeParameters: List) { + } + override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) { resolvePhase = newResolvePhase } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaValueParameter.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaValueParameter.kt index 3f2fb956b605e..87288d21187b2 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaValueParameter.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaValueParameter.kt @@ -167,6 +167,9 @@ class FirJavaValueParameter @FirImplementationDetail constructor( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + } + override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) { returnTypeRef = newReturnTypeRef } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirSelfTypeScope.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirSelfTypeScope.kt new file mode 100644 index 0000000000000..65360c83b93c6 --- /dev/null +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/scopes/impl/FirSelfTypeScope.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.scopes.impl + +import org.jetbrains.kotlin.builtins.StandardNames.SELF_TYPE_NAME +import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.SpecialNames.SELF_TYPE + +class FirSelfTypeScope(val memberDeclaration: FirMemberDeclaration) : FirScope() { + + override fun processClassifiersByNameWithSubstitution( + name: Name, + processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit + ) { + if (name.asString() == SELF_TYPE_NAME) { + val selfSymbol = memberDeclaration.typeParameters.find { it.symbol.name == SELF_TYPE }?.symbol + if (selfSymbol != null) { + return processor(selfSymbol, ConeSubstitutor.Empty) + } + } + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TypeArgumentMapping.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TypeArgumentMapping.kt index e3771c3a787f3..f7856ac8ef27a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TypeArgumentMapping.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/TypeArgumentMapping.kt @@ -5,16 +5,15 @@ package org.jetbrains.kotlin.fir.resolve.calls -import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration -import org.jetbrains.kotlin.fir.declarations.FirDeclaration -import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin -import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner -import org.jetbrains.kotlin.fir.types.ConeTypeIntersector -import org.jetbrains.kotlin.fir.types.FirTypeProjection +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildPlaceholderProjection import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance -import org.jetbrains.kotlin.fir.types.isRaw -import org.jetbrains.kotlin.fir.types.toFirResolvedTypeRef +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.types.Variance sealed class TypeArgumentMapping { @@ -33,7 +32,7 @@ sealed class TypeArgumentMapping { internal object MapTypeArguments : ResolutionStage() { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { - val typeArguments = callInfo.typeArguments + val typeArguments = enrichedTypeArgumentsWithSelfType(candidate, callInfo, context, callInfo.typeArguments) val owner = candidate.symbol.fir as FirTypeParameterRefsOwner if (typeArguments.isEmpty()) { @@ -60,6 +59,59 @@ internal object MapTypeArguments : ResolutionStage() { } } + private fun enrichedTypeArgumentsWithSelfType( + candidate: Candidate, + callInfo: CallInfo, + context: ResolutionContext, + typeArguments: List + ): List { + if (candidate.symbol is FirConstructorSymbol) { + + val firConstructorSymbol = candidate.symbol + + if (firConstructorSymbol.callableId.classId != null) { + + val classLikeSymbol = context.session.symbolProvider.getClassLikeSymbolByClassId(firConstructorSymbol.callableId.classId!!) + + if (classLikeSymbol != null) { + val firClassSymbol = classLikeSymbol as FirClassSymbol + + val isSelf = firClassSymbol.hasAnnotation(StandardClassIds.Annotations.Self, context.session) + + if (isSelf && callInfo.callKind is CallKind.Function) { + val constructorTypeParametersSize = firConstructorSymbol.typeParameterSymbols.size + val callTypeArgumentsSize = typeArguments.size + + if (constructorTypeParametersSize != callTypeArgumentsSize) { + val coneArgumentsWithStar = + (typeArguments.map { it.toConeTypeProjection() }.toList() + ConeStarProjection).toTypedArray() + val typeRef = firConstructorSymbol.fir.returnTypeRef + val oldConeType = typeRef.coneType as ConeClassLikeType + val coneTypeWithStar = + ConeClassLikeTypeImpl( + oldConeType.lookupTag, + coneArgumentsWithStar, + oldConeType.isNullable, + oldConeType.attributes + ) + + val typeRefWithStar = typeRef.withReplacedConeType(coneTypeWithStar) + val baseClassStarProjection = buildTypeProjectionWithVariance { + source = typeRefWithStar.source + this.typeRef = typeRefWithStar + variance = Variance.INVARIANT + } + + return typeArguments + baseClassStarProjection + } + } + } + + } + } + return typeArguments + } + private fun computeDefaultMappingForRawTypeMember( owner: FirTypeParameterRefsOwner, context: ResolutionContext diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt index de7218e40ca9f..46743416ca7d7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirCallCompleter.kt @@ -67,7 +67,7 @@ class FirCallCompleter( mayBeCoercionToUnitApplied = false, expectedTypeMismatchIsReportedInChecker, isFromCast = false, - shouldEnforceExpectedType = true, + shouldEnforceExpectedType = true ) fun completeCall(call: T, data: ResolutionMode): CompletionResult where T : FirResolvable, T : FirStatement = @@ -95,7 +95,6 @@ class FirCallCompleter( } val reference = call.calleeReference as? FirNamedReferenceWithCandidate ?: return CompletionResult(call, true) - val candidate = reference.candidate val initialType = components.initialTypeOfCandidate(candidate, call) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index c8bc714d77141..d2b3704f2d79c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -277,6 +277,17 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { } if (symbol is FirRegularClassSymbol) { + + val withAddedSelfTypeStar = + (symbol.getAnnotationByClassId( + StandardClassIds.Annotations.Self, + session + ) != null) && allTypeArguments.size != symbol.fir.typeParameters.size + if (withAddedSelfTypeStar) { + allTypeArguments.add(ConeStarProjection) + typeArgumentsCount++ + } + val isPossibleBareType = areBareTypesAllowed && allTypeArguments.isEmpty() if (!isPossibleBareType) { val actualSubstitutor = substitutor ?: ConeSubstitutor.Empty @@ -301,7 +312,8 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { if (typeParameterIndex < typeArgumentsCount) { // Check if type argument matches type parameter in respective qualifier part - val qualifierPartArgumentsCount = qualifier[qualifierPartIndex].typeArgumentList.typeArguments.size + val qualifierPartArgumentsCount = + qualifier[qualifierPartIndex].typeArgumentList.typeArguments.size + (if (withAddedSelfTypeStar) 1 else 0) createDiagnosticsIfExists( parameterClass, qualifierPartIndex, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt index 68cf1780bcb79..e281d0768df21 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSupertypesResolution.kt @@ -8,44 +8,48 @@ package org.jetbrains.kotlin.fir.resolve.transformers import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList -import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.KtFakeSourceElementKind +import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParameterBuilder +import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.declarations.utils.expandedConeType import org.jetbrains.kotlin.fir.declarations.utils.isCompanion -import org.jetbrains.kotlin.fir.declarations.utils.isData import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind -import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.supertypeGenerators -import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeTypeParameterSupertype import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo -import org.jetbrains.kotlin.fir.scopes.* +import org.jetbrains.kotlin.fir.scopes.FirScope +import org.jetbrains.kotlin.fir.scopes.createImportingScopes +import org.jetbrains.kotlin.fir.scopes.getNestedClassifierScope import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope +import org.jetbrains.kotlin.fir.scopes.impl.FirSelfTypeScope import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstitutionForSuperType -import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol -import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase +import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef +import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor import org.jetbrains.kotlin.fir.visitors.FirTransformer -import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.model.TypeArgumentMarker import org.jetbrains.kotlin.utils.addIfNotNull @@ -316,7 +320,7 @@ open class FirSupertypeResolverVisitor( val classId = classLikeDeclaration.symbol.classId val classModuleSession = classLikeDeclaration.moduleData.session - val result = when { + val result: PersistentList = when { classId.isLocal -> { // Local classes should be treated specially and supplied with localClassesNavigationInfo, normally // But it seems to be too strict to add an assertion here @@ -340,7 +344,12 @@ open class FirSupertypeResolverVisitor( else -> getFirClassifierContainerFileIfAny(classLikeDeclaration.symbol)?.let(::prepareFileScopes) ?: persistentListOf() } - return result.pushIfNotNull(classLikeDeclaration.typeParametersScope()) + return result.pushIfNotNull( + if (classLikeDeclaration.typeParameters.any { it.symbol.name == SpecialNames.SELF_TYPE }) + FirSelfTypeScope(classLikeDeclaration) + else + null + ).pushIfNotNull(classLikeDeclaration.typeParametersScope()) } private fun resolveSpecificClassLikeSupertypes( @@ -360,12 +369,13 @@ open class FirSupertypeResolverVisitor( } supertypeComputationSession.startComputingSupertypes(classLikeDeclaration) - val scopes = prepareScopes(classLikeDeclaration) val transformer = FirSpecificTypeResolverTransformer(session, supertypeSupplier = supertypeComputationSession.supertypesSupplier) @OptIn(PrivateForInline::class) val resolvedTypesRefs = transformer.withFile(useSiteFile) { + addSelfToTypeParameters(classLikeDeclaration, session) + val scopes = prepareScopes(classLikeDeclaration) resolveSuperTypeRefs( transformer, ScopeClassDeclaration(scopes, classDeclarationsStack) @@ -438,6 +448,49 @@ open class FirSupertypeResolverVisitor( } } + private fun addSelfToTypeParameters(firClass: FirClassLikeDeclaration, session: FirSession) { + val isSelf = firClass.getAnnotationByClassId(StandardClassIds.Annotations.Self, session) != null + val params = firClass.typeParameters + if (params is MutableList && isSelf && params.find { it.symbol.name == SpecialNames.SELF_TYPE } == null && firClass is FirRegularClass) { + val selfSymbol = FirTypeParameterSymbol() + val firTypeParameterBuilder = FirTypeParameterBuilder() + firTypeParameterBuilder.bounds.add(buildResolvedTypeRef { + source = firClass.source + type = ConeClassLikeLookupTagImpl(firClass.classId).constructClassType( + typeArguments = params.map { + ConeTypeParameterTypeImpl( + lookupTag = ConeTypeParameterLookupTag(it.symbol), + isNullable = false + ) + }.toTypedArray() + arrayOf( + ConeTypeParameterTypeImpl(lookupTag = ConeTypeParameterLookupTag(selfSymbol), isNullable = false) + ), isNullable = false + ) + }) + + val selfTypeParameter = firTypeParameterBuilder.apply { + source = firClass.source?.fakeElement(KtFakeSourceElementKind.ClassSelfTypeRef) + moduleData = session.moduleData + resolvePhase = FirResolvePhase.TYPES + origin = FirDeclarationOrigin.Source + name = SpecialNames.SELF_TYPE + symbol = selfSymbol + containingDeclarationSymbol = firClass.symbol + variance = Variance.OUT_VARIANCE + isReified = false + }.build() + + firClass.replaceTypeParameters(params + selfTypeParameter) + + firClass.declarations.filterIsInstance().forEach { + val constructorTypeParams = it.typeParameters + it.replaceTypeParameters(constructorTypeParams + selfTypeParameter) + val firClassTypeRef = it.returnTypeRef.resolvedTypeFromPrototype(firClass.defaultType()) + it.replaceReturnTypeRef(firClassTypeRef) + } + } + } + private fun List.createCopy(): List = ArrayList(this) private fun addSupertypesFromExtensions( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index c3e582312754c..05314b2b2aa64 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -18,10 +18,14 @@ import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.createImportingScopes import org.jetbrains.kotlin.fir.scopes.getNestedClassifierScope import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope +import org.jetbrains.kotlin.fir.scopes.impl.FirSelfTypeScope import org.jetbrains.kotlin.fir.scopes.impl.nestedClassifierScope import org.jetbrains.kotlin.fir.scopes.impl.wrapNestedClassifierScopeWithSubstitutionForSuperType import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef +import org.jetbrains.kotlin.name.SpecialNames.SELF_TYPE +import org.jetbrains.kotlin.name.StandardClassIds +import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.fir.whileAnalysing import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled @@ -341,6 +345,9 @@ open class FirTypeResolveTransformer( } private fun FirMemberDeclaration.addTypeParametersScope() { + if (typeParameters.any { it.symbol.name == SELF_TYPE }) { + scopes.add(FirSelfTypeScope(this)) + } if (typeParameters.isNotEmpty()) { scopes.add(FirMemberTypeParameterScope(this)) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index 76cfda5275b59..77e1e9aa5fc4f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -29,15 +29,15 @@ import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.withScopeCleanup import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.createImportingScopes -import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope -import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope -import org.jetbrains.kotlin.fir.scopes.impl.FirWhenSubjectImportingScope +import org.jetbrains.kotlin.fir.scopes.impl.* import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames.UNDERSCORE_FOR_UNUSED_VAR +import org.jetbrains.kotlin.name.StandardClassIds class BodyResolveContext( val returnTypeCalculator: ReturnTypeCalculator, @@ -426,7 +426,9 @@ class BodyResolveContext( ?: if (owner.classKind == ClassKind.ENUM_ENTRY) { owner.primaryConstructorIfAny(holder.session)?.callableId?.className?.shortName() } else null - val type = owner.defaultType() + + val selfType = owner.typeParameters.findLast { it.symbol.name == SpecialNames.SELF_TYPE } + val type = selfType?.toConeType() ?: owner.defaultType() val towerElementsForClass = holder.collectTowerDataElementsForClass(owner, type) val base = towerDataContext.addNonLocalTowerDataElements(towerElementsForClass.superClassesStaticsAndCompanionReceivers) @@ -441,15 +443,23 @@ class BodyResolveContext( .addNonLocalScopeIfNotNull(towerElementsForClass.staticScope) val typeParameterScope = (owner as? FirRegularClass)?.typeParameterScope() + val selfTypeScope: FirSelfTypeScope? = + if (owner.hasAnnotation(StandardClassIds.Annotations.Self, holder.session)) { + FirSelfTypeScope(owner) + } else + null val forMembersResolution = staticsAndCompanion .addReceiver(labelName, towerElementsForClass.thisReceiver) .addContextReceiverGroup(towerElementsForClass.contextReceivers) .addNonLocalScopeIfNotNull(typeParameterScope) + .addNonLocalScopeIfNotNull(selfTypeScope) val scopeForConstructorHeader = - staticsAndCompanion.addNonLocalScopeIfNotNull(typeParameterScope) + staticsAndCompanion + .addNonLocalScopeIfNotNull(typeParameterScope) + .addNonLocalScopeIfNotNull(selfTypeScope) /* * Scope for enum entries is equal to initial scope for constructor header diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index 8fc02b0fb83c9..6ba5dca29b9a2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -11,6 +11,10 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.FirProviderInterceptor import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve +import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration +import org.jetbrains.kotlin.fir.scopes.impl.FirSelfTypeScope +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.visitors.FirTransformer open class FirBodyResolveTransformer( session: FirSession, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt index fac56d4b84fc6..45848d0152738 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord import org.jetbrains.kotlin.name.StandardClassIds.Annotations.WasExperimental +import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Self import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled internal abstract class AbstractFirSpecificAnnotationResolveTransformer( @@ -48,7 +49,7 @@ internal abstract class AbstractFirSpecificAnnotationResolveTransformer( protected val computationSession: CompilerRequiredAnnotationsComputationSession ) : FirDefaultTransformer() { companion object { - private val REQUIRED_ANNOTATIONS: Set = setOf(Deprecated, DeprecatedSinceKotlin, WasExperimental, JvmRecord) + private val REQUIRED_ANNOTATIONS: Set = setOf(Deprecated, DeprecatedSinceKotlin, WasExperimental, JvmRecord, Self) private val REQUIRED_ANNOTATION_NAMES: Set = REQUIRED_ANNOTATIONS.mapTo(mutableSetOf()) { it.shortClassName } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt index 5a514de77ed2f..d797e10957b1c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirErrorNamedReference +import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.* diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/inference/ConeTypeVariables.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/inference/ConeTypeVariables.kt index 80cf58f27df6d..5f373d6656656 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/inference/ConeTypeVariables.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/resolve/inference/ConeTypeVariables.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.inference import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.ConeTypeVariable +import org.jetbrains.kotlin.name.SpecialNames class ConeTypeVariableForPostponedAtom(name: String) : ConeTypeVariable(name) class ConeTypeVariableForLambdaParameterType(name: String, val index: Int) : ConeTypeVariable(name) @@ -15,4 +16,11 @@ class ConeTypeVariableForLambdaReturnType(val argument: FirAnonymousFunction, na class ConeTypeParameterBasedTypeVariable( val typeParameterSymbol: FirTypeParameterSymbol -) : ConeTypeVariable(typeParameterSymbol.name.identifier, typeParameterSymbol.toLookupTag()) +) : ConeTypeVariable( + if (typeParameterSymbol.name == SpecialNames.SELF_TYPE) SELF_IDENTIFIER else typeParameterSymbol.name.identifier, + typeParameterSymbol.toLookupTag() +) { + companion object { + const val SELF_IDENTIFIER = "\$Self" + } +} diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousObject.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousObject.kt index 4953aa49af85a..08dc5e9bbd889 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousObject.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousObject.kt @@ -46,6 +46,8 @@ abstract class FirAnonymousObject : FirClass(), FirControlFlowGraphOwner { abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) abstract override fun replaceSuperTypeRefs(newSuperTypeRefs: List) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirCallableDeclaration.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirCallableDeclaration.kt index b8b57b8913f05..50eb172f1aaee 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirCallableDeclaration.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirCallableDeclaration.kt @@ -47,6 +47,8 @@ sealed class FirCallableDeclaration : FirMemberDeclaration() { abstract override fun replaceAnnotations(newAnnotations: List) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) abstract fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirClass.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirClass.kt index 1c073e8d2b4db..ca4ecda9d1b4c 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirClass.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirClass.kt @@ -45,6 +45,8 @@ sealed class FirClass : FirClassLikeDeclaration(), FirStatement, FirTypeParamete abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) abstract fun replaceSuperTypeRefs(newSuperTypeRefs: List) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirClassLikeDeclaration.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirClassLikeDeclaration.kt index 484e9c87d1d56..f44f055ba858a 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirClassLikeDeclaration.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirClassLikeDeclaration.kt @@ -40,6 +40,8 @@ sealed class FirClassLikeDeclaration : FirMemberDeclaration(), FirStatement { abstract override fun replaceAnnotations(newAnnotations: List) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirClassLikeDeclaration diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt index c940fb180f5d4..890a53beeb23f 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirConstructor.kt @@ -53,6 +53,8 @@ abstract class FirConstructor : FirFunction(), FirTypeParameterRefsOwner { abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) abstract override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirEnumEntry.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirEnumEntry.kt index 1ab3cddae6790..22557f556ab84 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirEnumEntry.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirEnumEntry.kt @@ -55,6 +55,8 @@ abstract class FirEnumEntry : FirVariable() { abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) abstract override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirErrorProperty.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirErrorProperty.kt index b115b7cbbdb25..777b7ed019a8c 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirErrorProperty.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirErrorProperty.kt @@ -58,6 +58,8 @@ abstract class FirErrorProperty : FirVariable(), FirDiagnosticHolder { abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) abstract override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirField.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirField.kt index 2ab703b420207..dc939d61438f7 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirField.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirField.kt @@ -57,6 +57,8 @@ abstract class FirField : FirVariable(), FirControlFlowGraphOwner { abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) abstract override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirFunction.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirFunction.kt index 1fa54b2dde230..3bd9e6ec409a1 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirFunction.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirFunction.kt @@ -54,6 +54,8 @@ sealed class FirFunction : FirCallableDeclaration(), FirTargetElement, FirContro abstract override fun replaceAnnotations(newAnnotations: List) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) abstract override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirMemberDeclaration.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirMemberDeclaration.kt index e994c6d5f8181..53a4e2be38310 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirMemberDeclaration.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirMemberDeclaration.kt @@ -38,6 +38,8 @@ sealed class FirMemberDeclaration : FirDeclaration(), FirTypeParameterRefsOwner abstract override fun replaceAnnotations(newAnnotations: List) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirMemberDeclaration abstract override fun transformTypeParameters(transformer: FirTransformer, data: D): FirMemberDeclaration diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirRegularClass.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirRegularClass.kt index 679dcf81a1c55..517471da4a03a 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirRegularClass.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirRegularClass.kt @@ -51,6 +51,8 @@ abstract class FirRegularClass : FirClass(), FirControlFlowGraphOwner { abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) abstract override fun replaceAnnotations(newAnnotations: List) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirTypeParameterRefsOwner.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirTypeParameterRefsOwner.kt index eb8e6058ea6ac..fdfe7811681f5 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirTypeParameterRefsOwner.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirTypeParameterRefsOwner.kt @@ -24,5 +24,7 @@ sealed interface FirTypeParameterRefsOwner : FirElement { override fun transform(transformer: FirTransformer, data: D): E = transformer.transformTypeParameterRefsOwner(this, data) as E + fun replaceTypeParameters(newTypeParameters: List) + fun transformTypeParameters(transformer: FirTransformer, data: D): FirTypeParameterRefsOwner } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt index 432b49fe230b5..bf2cdebd037f3 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirValueParameter.kt @@ -63,6 +63,8 @@ abstract class FirValueParameter : FirVariable(), FirControlFlowGraphOwner { abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) abstract override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirVariable.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirVariable.kt index 6b0efa4101437..bd1308cd5e9d7 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirVariable.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirVariable.kt @@ -56,6 +56,8 @@ sealed class FirVariable : FirCallableDeclaration(), FirStatement { abstract override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) + abstract override fun replaceTypeParameters(newTypeParameters: List) + abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) abstract override fun replaceReceiverParameter(newReceiverParameter: FirReceiverParameter?) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt index 4068ee7edbdea..e968b2b1cf1e4 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.InlineStatus import org.jetbrains.kotlin.fir.declarations.UnresolvedDeprecationProvider diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirBackingFieldBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirBackingFieldBuilder.kt index f39d267925d13..80de42467c6b1 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirBackingFieldBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirBackingFieldBuilder.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.UnresolvedDeprecationProvider import org.jetbrains.kotlin.fir.declarations.impl.FirBackingFieldImpl import org.jetbrains.kotlin.fir.expressions.FirAnnotation diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirErrorFunctionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirErrorFunctionBuilder.kt index 450fed858b3bd..7d0bcf3448b60 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirErrorFunctionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirErrorFunctionBuilder.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.UnresolvedDeprecationProvider import org.jetbrains.kotlin.fir.declarations.impl.FirErrorFunctionImpl diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirPropertyAccessorBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirPropertyAccessorBuilder.kt index 9cc72a2e4dedf..eec7883e4838f 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirPropertyAccessorBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirPropertyAccessorBuilder.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.UnresolvedDeprecationProvider import org.jetbrains.kotlin.fir.declarations.builder.FirFunctionBuilder diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirPropertyBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirPropertyBuilder.kt index 55352375dfee8..ba2756dca2fc1 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirPropertyBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirPropertyBuilder.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.declarations.FirPropertyBodyResolveState import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.UnresolvedDeprecationProvider import org.jetbrains.kotlin.fir.declarations.builder.FirDeclarationBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParametersOwnerBuilder diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirSimpleFunctionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirSimpleFunctionBuilder.kt index 2fef3e38599d7..63c739ce78202 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirSimpleFunctionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirSimpleFunctionBuilder.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.UnresolvedDeprecationProvider import org.jetbrains.kotlin.fir.declarations.builder.FirFunctionBuilder diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirTypeAliasBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirTypeAliasBuilder.kt index c68a14593abf2..dd3fa5bdd78f9 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirTypeAliasBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirTypeAliasBuilder.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeAlias import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.UnresolvedDeprecationProvider import org.jetbrains.kotlin.fir.declarations.builder.FirDeclarationBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirTypeParametersOwnerBuilder diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt index 4ccb54bde7ad1..86b40ac1daf83 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.InlineStatus import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl @@ -180,6 +181,12 @@ internal class FirAnonymousFunctionImpl( inlineStatus = newInlineStatus } + override fun replaceTypeParameters(newTypeParameters: List) { + require(newTypeParameters.all { it is FirTypeParameter }) + typeParameters.clear() + typeParameters.addAll(newTypeParameters.map { it as FirTypeParameter }) + } + override fun replaceTypeRef(newTypeRef: FirTypeRef) { typeRef = newTypeRef } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousObjectImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousObjectImpl.kt index 37bb0702f5c45..64cb3debb03dd 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousObjectImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousObjectImpl.kt @@ -103,6 +103,11 @@ internal class FirAnonymousObjectImpl( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) { deprecationsProvider = newDeprecationsProvider } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirBackingFieldImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirBackingFieldImpl.kt index 130ad5ff8e6cf..3af60be14f9c0 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirBackingFieldImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirBackingFieldImpl.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol @@ -187,4 +188,10 @@ open class FirBackingFieldImpl @FirImplementationDetail constructor( override fun replaceAnnotations(newAnnotations: List) { annotations = newAnnotations.toMutableOrEmpty() } + + override fun replaceTypeParameters(newTypeParameters: List) { + require(newTypeParameters.all { it is FirTypeParameter }) + typeParameters.clear() + typeParameters.addAll(newTypeParameters.map { it as FirTypeParameter }) + } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt index 4bc506c6e51e8..dc3f895751c52 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirConstructorImpl.kt @@ -135,6 +135,11 @@ internal class FirConstructorImpl( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) { returnTypeRef = newReturnTypeRef } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt index 5964d667a5ec5..fa972d92fbea5 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultSetterValueParameter.kt @@ -165,6 +165,8 @@ internal class FirDefaultSetterValueParameter( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) {} + override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) { returnTypeRef = newReturnTypeRef } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirEnumEntryImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirEnumEntryImpl.kt index a854981c96f40..47e46531fe47c 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirEnumEntryImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirEnumEntryImpl.kt @@ -143,6 +143,11 @@ internal class FirEnumEntryImpl( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) { returnTypeRef = newReturnTypeRef } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorFunctionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorFunctionImpl.kt index 8ef6b7b742104..96a907830fb40 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorFunctionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorFunctionImpl.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.declarations.FirErrorFunction import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic @@ -148,4 +149,6 @@ internal class FirErrorFunctionImpl( } override fun replaceBody(newBody: FirBlock?) {} + + override fun replaceTypeParameters(newTypeParameters: List) {} } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorPropertyImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorPropertyImpl.kt index 7484dc52de255..12c308df1798f 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorPropertyImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirErrorPropertyImpl.kt @@ -141,6 +141,8 @@ internal class FirErrorPropertyImpl( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) {} + override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) { returnTypeRef = newReturnTypeRef } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt index 75f0686aa2e7d..fdcd292091b2a 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt @@ -148,6 +148,11 @@ class FirFieldImpl @FirImplementationDetail constructor( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) { returnTypeRef = newReturnTypeRef } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPrimaryConstructor.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPrimaryConstructor.kt index 6d6e9585a7a15..0ec9e6b081aaf 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPrimaryConstructor.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPrimaryConstructor.kt @@ -136,6 +136,11 @@ class FirPrimaryConstructor @FirImplementationDetail constructor( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) { returnTypeRef = newReturnTypeRef } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyAccessorImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyAccessorImpl.kt index fbc29529057e6..3bfaa7fa20002 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyAccessorImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyAccessorImpl.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirBlock @@ -171,4 +172,10 @@ open class FirPropertyAccessorImpl @FirImplementationDetail constructor( override fun replaceAnnotations(newAnnotations: List) { annotations = newAnnotations.toMutableOrEmpty() } + + override fun replaceTypeParameters(newTypeParameters: List) { + require(newTypeParameters.all { it is FirTypeParameter }) + typeParameters.clear() + typeParameters.addAll(newTypeParameters.map { it as FirTypeParameter }) + } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt index 762c4c26f3afe..a027133f880a3 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.FirPropertyBodyResolveState import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference @@ -210,4 +211,10 @@ internal class FirPropertyImpl( override fun replaceBodyResolveState(newBodyResolveState: FirPropertyBodyResolveState) { bodyResolveState = newBodyResolveState } + + override fun replaceTypeParameters(newTypeParameters: List) { + require(newTypeParameters.all { it is FirTypeParameter }) + typeParameters.clear() + typeParameters.addAll(newTypeParameters.map { it as FirTypeParameter }) + } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirRegularClassImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirRegularClassImpl.kt index b1bec06763bcc..8309c2a69f65c 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirRegularClassImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirRegularClassImpl.kt @@ -111,6 +111,11 @@ internal class FirRegularClassImpl( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) { + typeParameters.clear() + typeParameters.addAll(newTypeParameters) + } + override fun replaceDeprecationsProvider(newDeprecationsProvider: DeprecationsProvider) { deprecationsProvider = newDeprecationsProvider } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirSimpleFunctionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirSimpleFunctionImpl.kt index 29d5d8294a9bc..28397b2b0ce5f 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirSimpleFunctionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirSimpleFunctionImpl.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirBlock @@ -172,4 +173,10 @@ internal class FirSimpleFunctionImpl( override fun replaceAnnotations(newAnnotations: List) { annotations = newAnnotations.toMutableOrEmpty() } + + override fun replaceTypeParameters(newTypeParameters: List) { + require(newTypeParameters.all { it is FirTypeParameter }) + typeParameters.clear() + typeParameters.addAll(newTypeParameters.map { it as FirTypeParameter }) + } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirTypeAliasImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirTypeAliasImpl.kt index 2eee6309df020..ee97612ee749b 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirTypeAliasImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirTypeAliasImpl.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeAlias import org.jetbrains.kotlin.fir.declarations.FirTypeParameter +import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.types.FirTypeRef @@ -91,6 +92,12 @@ internal class FirTypeAliasImpl( deprecationsProvider = newDeprecationsProvider } + override fun replaceTypeParameters(newTypeParameters: List) { + require(newTypeParameters.all { it is FirTypeParameter }) + typeParameters.clear() + typeParameters.addAll(newTypeParameters.map { it as FirTypeParameter }) + } + override fun replaceExpandedTypeRef(newExpandedTypeRef: FirTypeRef) { expandedTypeRef = newExpandedTypeRef } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt index d55cf8fa07d66..ad4a34e465287 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirValueParameterImpl.kt @@ -150,6 +150,8 @@ internal class FirValueParameterImpl( resolvePhase = newResolvePhase } + override fun replaceTypeParameters(newTypeParameters: List) {} + override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) { returnTypeRef = newReturnTypeRef } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticProperty.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticProperty.kt index 187080b7d6f89..b3c54bdb47365 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticProperty.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticProperty.kt @@ -189,4 +189,8 @@ class FirSyntheticProperty( private fun notSupported(): Nothing { throw AssertionError("Transformation of synthetic property isn't supported") } + + override fun replaceTypeParameters(newTypeParameters: List) { + throw AssertionError("Mutation of synthetic property isn't supported") + } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticPropertyAccessor.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticPropertyAccessor.kt index 8ad3cba63c764..eb4f630b4f320 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticPropertyAccessor.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticPropertyAccessor.kt @@ -163,6 +163,10 @@ class FirSyntheticPropertyAccessor( throw AssertionError("Mutation of synthetic property accessor isn't supported") } + override fun replaceTypeParameters(newTypeParameters: List) { + throw AssertionError("Mutation of synthetic property isn't supported") + } + override fun replaceAnnotations(newAnnotations: List) { throw AssertionError("Mutation of synthetic property accessor isn't supported") } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirStatusUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirStatusUtils.kt index 55b1d2564262f..8acf93aa884ed 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirStatusUtils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirStatusUtils.kt @@ -55,6 +55,12 @@ inline val FirClass.isInterface: Boolean inline val FirClass.isEnumClass: Boolean get() = classKind.isEnumClass +inline val FirClass.isAnnotationClass: Boolean + get() = classKind.isAnnotationClass + +inline val FirClass.isObject: Boolean + get() = classKind.isObject + inline val FirRegularClass.isSealed: Boolean get() = status.modality == Modality.SEALED inline val FirRegularClass.canHaveAbstractDeclaration: Boolean diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt index 3a85d386ac457..2344b5db94d78 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FieldSets.kt @@ -64,7 +64,7 @@ object FieldSets { val typeParameters by lazy { fieldList("typeParameters", typeParameter) } - val typeParameterRefs by lazy { fieldList("typeParameters", typeParameterRef) } + val typeParameterRefs by lazy { fieldList("typeParameters", typeParameterRef, withReplace = true, overrideTypeRequire = false) } val name by lazy { field(nameType) } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/ElementUtils.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/ElementUtils.kt index 473acabfef371..2c7b44aa6ac5e 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/ElementUtils.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/ElementUtils.kt @@ -11,7 +11,14 @@ import org.jetbrains.kotlin.fir.tree.generator.printer.typeWithArguments // ----------- Simple field ----------- -fun field(name: String, type: String, packageName: String?, customType: Importable? = null, nullable: Boolean = false, withReplace: Boolean = false): Field { +fun field( + name: String, + type: String, + packageName: String?, + customType: Importable? = null, + nullable: Boolean = false, + withReplace: Boolean = false +): Field { return SimpleField(name, type, packageName, customType, nullable, withReplace) } @@ -27,7 +34,14 @@ fun field(name: String, typeWithArgs: Pair>, nullable: Bo } fun field(type: Type, nullable: Boolean = false, withReplace: Boolean = false): Field { - return SimpleField(type.type.replaceFirstChar(Char::lowercaseChar), type.typeWithArguments, type.packageName, null, nullable, withReplace) + return SimpleField( + type.type.replaceFirstChar(Char::lowercaseChar), + type.typeWithArguments, + type.packageName, + null, + nullable, + withReplace + ) } fun booleanField(name: String, withReplace: Boolean = false): Field { @@ -62,12 +76,12 @@ fun field(element: Element, nullable: Boolean = false, withReplace: Boolean = fa // ----------- Field list ----------- -fun fieldList(name: String, type: Importable, withReplace: Boolean = false, useMutableOrEmpty: Boolean = false): Field { - return FieldList(name, type, withReplace, useMutableOrEmpty) +fun fieldList(name: String, type: Importable, withReplace: Boolean = false, overrideTypeRequire: Boolean = false, useMutableOrEmpty: Boolean = false): Field { + return FieldList(name, type, withReplace, overrideTypeRequire, useMutableOrEmpty) } -fun fieldList(element: AbstractElement, withReplace: Boolean = false, useMutableOrEmpty: Boolean = false): Field { - return FieldList(element.name.replaceFirstChar(Char::lowercaseChar) + "s", element, withReplace, useMutableOrEmpty) +fun fieldList(element: AbstractElement, withReplace: Boolean = false, overrideTypeRequire: Boolean = false, useMutableOrEmpty: Boolean = false): Field { + return FieldList(element.name.replaceFirstChar(Char::lowercaseChar) + "s", element, withReplace, overrideTypeRequire, useMutableOrEmpty) } // ----------- Field set ----------- diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Field.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Field.kt index 65e135761995b..b349cb3786705 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Field.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/model/Field.kt @@ -14,6 +14,7 @@ sealed class Field : Importable { abstract var isVolatile: Boolean open var withReplace: Boolean = false abstract val isFirType: Boolean + open val overrideTypeRequire: Boolean = true var fromParent: Boolean = false open var needsSeparateTransform: Boolean = false @@ -205,6 +206,7 @@ class FieldList( override val name: String, val baseType: Importable, override var withReplace: Boolean, + override val overrideTypeRequire: Boolean = true, useMutableOrEmpty: Boolean = false ) : Field() { override var defaultValueInImplementation: String? = null @@ -224,6 +226,7 @@ class FieldList( name, baseType, withReplace, + overrideTypeRequire, isMutableOrEmpty ) } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt index d645d727d0a5c..b37a888676bde 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/element.kt @@ -106,9 +106,16 @@ fun SmartPrinter.printElement(element: Element) { } allFields.filter { it.withReplace }.forEach { - val override = overridenFields[it, it] && !(it.name == "source" && fullQualifiedName.endsWith("FirQualifiedAccess")) - it.replaceDeclaration(override, forceNullable = it.useNullableForReplace) + val overridenTypeRequire = (it.overridenTypes.filterIsInstance() + .any { f -> !f.overrideTypeRequire }) + + if (!overridenTypeRequire) { + val override = (overridenFields[it, it] && !(it.name == "source" && fullQualifiedName.endsWith("FirQualifiedAccess"))) + it.replaceDeclaration(override, forceNullable = it.useNullableForReplace) + } + for (overridenType in it.overridenTypes) { + if (overridenType is Field && !overridenType.overrideTypeRequire) continue it.replaceDeclaration(true, overridenType) } } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/implementation.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/implementation.kt index 314e64e3df7c9..c8b47ad3a554f 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/implementation.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/implementation.kt @@ -339,32 +339,45 @@ fun SmartPrinter.printImplementation(implementation: Implementation) { for (field in allFields.filter { it.withReplace }) { val capitalizedFieldName = field.name.replaceFirstChar(Char::uppercaseChar) val newValue = "new$capitalizedFieldName" - generateReplace(field, forceNullable = field.useNullableForReplace) { - when { - field.withGetter -> {} - field.origin is FieldList && !field.isMutableOrEmpty -> { - println("${field.name}.clear()") - println("${field.name}.addAll($newValue)") - } + val overridenTypeRequire = (field.overridenTypes.filterIsInstance() + .any { !it.overrideTypeRequire }) - else -> { - if (field.useNullableForReplace) { - println("require($newValue != null)") + if (!overridenTypeRequire) { + generateReplace(field, forceNullable = field.useNullableForReplace) { + when { + field.withGetter -> {} + + field.origin is FieldList && !field.isMutableOrEmpty -> { + println("${field.name}.clear()") + println("${field.name}.addAll($newValue)") } - print("${field.name} = $newValue") - if (field.origin is FieldList && field.isMutableOrEmpty) { - print(".toMutableOrEmpty()") + + else -> { + if (field.useNullableForReplace) { + println("require($newValue != null)") + } + print("${field.name} = $newValue") + if (field.origin is FieldList && field.isMutableOrEmpty) { + print(".toMutableOrEmpty()") + } + println() } - println() } } } - for (overridenType in field.overridenTypes) { generateReplace(field, overridenType) { - println("require($newValue is ${field.typeWithArguments})") - println("replace$capitalizedFieldName($newValue)") + if (overridenType is Field && overridenType.overrideTypeRequire) { + println("require($newValue is ${field.typeWithArguments})") + println("replace$capitalizedFieldName($newValue)") + } else if (overridenType is Field && field.origin is FieldList) { + val genericType = + field.type.substring(field.type.indexOfFirst { it == '<' } + 1, field.type.indexOfLast { it == '>' }) + println("require($newValue.all { it is $genericType })") + println("${field.name}.clear()") + println("${field.name}.addAll($newValue.map { it as $genericType })") + } } } } diff --git a/compiler/testData/codegen/box/fir/selfTypes/ControlFlowInfoSelfTypes.kt b/compiler/testData/codegen/box/fir/selfTypes/ControlFlowInfoSelfTypes.kt new file mode 100644 index 0000000000000..30ea66bb8248a --- /dev/null +++ b/compiler/testData/codegen/box/fir/selfTypes/ControlFlowInfoSelfTypes.kt @@ -0,0 +1,208 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlin.Self + +interface ReadOnlyControlFlowInfo { + fun getOrNull(key: K): D? + + // Only used in tests + fun asMap(): Map +} + +@Self +abstract class ControlFlowInfo +internal constructor( + protected val map: Map = mapOf() +) : Map by map, ReadOnlyControlFlowInfo { + protected abstract fun copy(newMap: Map): Self + + fun put(key: K, value: D): Self = + put(key, value, this[key] ?: null as D?) + + /** + * This overload exists just for sake of optimizations: in some cases we've just retrieved the old value, + * so we don't need to scan through the persistent hashmap again + */ + fun put(key: K, value: D, oldValue: D?): Self { + // Avoid a copy instance creation if new value is the same + if (value == oldValue) return this + val newMap = map + (key to value) + return copy(newMap) + } + + override fun getOrNull(key: K): D? = this[key] ?: null as D? + override fun asMap() = this + + fun retainAll(predicate: (K) -> Boolean): Self { + val newMap = map.filter { predicate(it.key) } + return copy(newMap) + } + + override fun equals(other: Any?) = map == (other as? ControlFlowInfo<*, *, *>)?.map + + override fun hashCode() = map.hashCode() + + override fun toString() = map.toString() +} + +// ALIASES BEGIN + +typealias VariableDescriptor = String +typealias VariableUsageControlFlowInfo = ControlFlowInfo +typealias VariableUsageReadOnlyControlInfo = ReadOnlyControlFlowInfo + +// ALIASES END + + +// IMPLEMENTATIONS OF CONTROL FLOW INFOS BEGIN + +class UsageVariableControlFlowInfo(map: Map = mapOf()) : + VariableUsageControlFlowInfo(map), + VariableUsageReadOnlyControlInfo { + override fun copy(newMap: Map): UsageVariableControlFlowInfo = + UsageVariableControlFlowInfo(newMap) +} + +interface VariableInitReadOnlyControlFlowInfo : + ReadOnlyControlFlowInfo { + fun checkDefiniteInitializationInWhen(merge: VariableInitReadOnlyControlFlowInfo): Boolean +} + +class VariableInitControlFlowInfo(map: Map = mapOf()) : + VariableUsageControlFlowInfo(map), + VariableInitReadOnlyControlFlowInfo { + override fun copy(newMap: Map): VariableInitControlFlowInfo = + VariableInitControlFlowInfo(newMap) + + // this = output of EXHAUSTIVE_WHEN_ELSE instruction + // merge = input of MergeInstruction + // returns true if definite initialization in when happens here + override fun checkDefiniteInitializationInWhen(merge: VariableInitReadOnlyControlFlowInfo): Boolean { + for ((key, value) in iterator()) { + if (value.initState == InitState.INITIALIZED_EXHAUSTIVELY && + merge.getOrNull(key)?.initState == InitState.INITIALIZED + ) { + return true + } + } + return false + } +} + +// IMPLEMENTATIONS OF CONTROL FLOW INFOS END + +// STATES BEGIN + +class VariableControlFlowState private constructor(val initState: InitState, val isDeclared: Boolean) { + + fun definitelyInitialized(): Boolean = initState == InitState.INITIALIZED + + fun mayBeInitialized(): Boolean = initState != InitState.NOT_INITIALIZED + + override fun toString(): String { + if (initState == InitState.NOT_INITIALIZED && !isDeclared) return "-" + return "$initState${if (isDeclared) "D" else ""}" + } + + companion object { + + private val VS_IT = VariableControlFlowState(InitState.INITIALIZED, true) + private val VS_IF = VariableControlFlowState(InitState.INITIALIZED, false) + private val VS_ET = VariableControlFlowState(InitState.INITIALIZED_EXHAUSTIVELY, true) + private val VS_EF = VariableControlFlowState(InitState.INITIALIZED_EXHAUSTIVELY, false) + private val VS_UT = VariableControlFlowState(InitState.UNKNOWN, true) + private val VS_UF = VariableControlFlowState(InitState.UNKNOWN, false) + private val VS_NT = VariableControlFlowState(InitState.NOT_INITIALIZED, true) + private val VS_NF = VariableControlFlowState(InitState.NOT_INITIALIZED, false) + + fun create(initState: InitState, isDeclared: Boolean): VariableControlFlowState = + when (initState) { + InitState.INITIALIZED -> if (isDeclared) VS_IT else VS_IF + InitState.INITIALIZED_EXHAUSTIVELY -> if (isDeclared) VS_ET else VS_EF + InitState.UNKNOWN -> if (isDeclared) VS_UT else VS_UF + InitState.NOT_INITIALIZED -> if (isDeclared) VS_NT else VS_NF + } + + fun createInitializedExhaustively(isDeclared: Boolean): VariableControlFlowState = + create(InitState.INITIALIZED_EXHAUSTIVELY, isDeclared) + + fun create(isInitialized: Boolean, isDeclared: Boolean = false): VariableControlFlowState = + create(if (isInitialized) InitState.INITIALIZED else InitState.NOT_INITIALIZED, isDeclared) + + fun create(isDeclaredHere: Boolean, mergedEdgesData: VariableControlFlowState?): VariableControlFlowState = + create(true, isDeclaredHere || mergedEdgesData != null && mergedEdgesData.isDeclared) + } +} + +enum class VariableUseState(private val priority: Int) { + READ(3), + WRITTEN_AFTER_READ(2), + ONLY_WRITTEN_NEVER_READ(1), + UNUSED(0); + + fun merge(variableUseState: VariableUseState?): VariableUseState { + if (variableUseState == null || priority > variableUseState.priority) return this + return variableUseState + } + + companion object { + + @JvmStatic + fun isUsed(variableUseState: VariableUseState?): Boolean = + variableUseState != null && variableUseState != UNUSED + } +} + +enum class InitState(private val s: String) { + // Definitely initialized + INITIALIZED("I"), + // Fake initializer in else branch of "exhaustive when without else", see MagicKind.EXHAUSTIVE_WHEN_ELSE + INITIALIZED_EXHAUSTIVELY("IE"), + // Initialized in some branches, not initialized in other branches + UNKNOWN("I?"), + // Definitely not initialized + NOT_INITIALIZED(""); + + fun merge(other: InitState): InitState { + // X merge X = X + // X merge IE = IE merge X = X + // else X merge Y = I? + if (this == other || other == INITIALIZED_EXHAUSTIVELY) return this + if (this == INITIALIZED_EXHAUSTIVELY) return other + return UNKNOWN + } + + override fun toString() = s +} + +// STATES END + +fun box(): String { + val usageVariableControlFlowInfo: UsageVariableControlFlowInfo = UsageVariableControlFlowInfo( + mapOf( + "unused" to VariableUseState.UNUSED, + "read" to VariableUseState.READ + ) + ) + + val usageVariableControlFlowInfoUpdated: UsageVariableControlFlowInfo = + usageVariableControlFlowInfo.put("second unused", VariableUseState.UNUSED) + + + val variableInitControlFlowInfo: VariableInitControlFlowInfo = VariableInitControlFlowInfo( + mapOf( + "VS_IT" to VariableControlFlowState.create(InitState.INITIALIZED, isDeclared = true), + "VS_IF" to VariableControlFlowState.create(InitState.INITIALIZED, isDeclared = false) + ) + ) + + val updatedVariableInitControlFlowInfo = variableInitControlFlowInfo.put( + "VS_ET", VariableControlFlowState.create(InitState.INITIALIZED_EXHAUSTIVELY, isDeclared = true) + ) + + val predicate = usageVariableControlFlowInfoUpdated.containsKey("second unused") && updatedVariableInitControlFlowInfo.containsKey("VS_ET") + + return if (predicate) "OK" else "ERROR" +} diff --git a/compiler/testData/codegen/box/fir/selfTypes/classWithSelfType.kt b/compiler/testData/codegen/box/fir/selfTypes/classWithSelfType.kt new file mode 100644 index 0000000000000..f39bea57f94c0 --- /dev/null +++ b/compiler/testData/codegen/box/fir/selfTypes/classWithSelfType.kt @@ -0,0 +1,25 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlin.Self + +@Self +open class Foo { + public val bar = 1 + + fun test(): Self = this + + fun box(): String { + val testSelf = test() + if (testSelf.bar == this.bar) + return "OK" + else + return "ERROR" + } +} + +fun box(): String { + val foo = Foo() + return foo.box() +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/fir/selfTypes/observer.kt b/compiler/testData/codegen/box/fir/selfTypes/observer.kt new file mode 100644 index 0000000000000..5128fb544168a --- /dev/null +++ b/compiler/testData/codegen/box/fir/selfTypes/observer.kt @@ -0,0 +1,47 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB +// FULL_JDK + +import java.awt.Color + +@Self +abstract class AbstractObservable { + private val observers: MutableList<(Self) -> Unit> = mutableListOf() + + fun observe(observer: (Self) -> Unit) { + observers += observer + } + + protected fun notification() { + observers.forEach { observer -> + observer(this) + } + } +} + +class Element : AbstractObservable() { + var color: Color = Color.WHITE + set(value) { + field = value + notification() + } +} + +fun box(): String { + val colors: MutableList = mutableListOf() + + val element = Element().apply { + observe { + colors.add(it.color) + } + } + + element.color = Color.BLACK + element.color = Color.DARK_GRAY + + return if (colors.size == 2 && colors.contains(java.awt.Color.BLACK) && colors.contains(java.awt.Color.DARK_GRAY)) + "OK" + else + "ERROR" +} diff --git a/compiler/testData/codegen/box/fir/selfTypes/selfClassAsFunctionArgument.kt b/compiler/testData/codegen/box/fir/selfTypes/selfClassAsFunctionArgument.kt new file mode 100644 index 0000000000000..a72090649a3e0 --- /dev/null +++ b/compiler/testData/codegen/box/fir/selfTypes/selfClassAsFunctionArgument.kt @@ -0,0 +1,30 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlin.Self + +@Self +class Foo { + public val bar = 1 + + fun test(): Self = this + + fun box(): String { + val testSelf = test() + if (testSelf.bar == this.bar) + return "OK" + else + return "ERROR" + } +} + +class Bar { + fun f(foo: Foo): String = foo.box() +} + +fun box(): String { + val foo = Foo() + val bar = Bar() + return bar.f(foo) +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/fir/selfTypes/selfClassAsReturnType.kt b/compiler/testData/codegen/box/fir/selfTypes/selfClassAsReturnType.kt new file mode 100644 index 0000000000000..72f6b986a7289 --- /dev/null +++ b/compiler/testData/codegen/box/fir/selfTypes/selfClassAsReturnType.kt @@ -0,0 +1,29 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlin.Self + +@Self +class Foo { + public val bar = 1 + + fun test(): Self = this + + fun box(): String { + val testSelf = test() + if (testSelf.bar == this.bar) + return "OK" + else + return "ERROR" + } +} + +class Bar { + fun foo(): Foo = Foo() +} + +fun box(): String { + val bar = Bar() + return bar.foo().box() +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/fir/selfTypes/selfTypeBuilder.kt b/compiler/testData/codegen/box/fir/selfTypes/selfTypeBuilder.kt new file mode 100644 index 0000000000000..d815857d1a836 --- /dev/null +++ b/compiler/testData/codegen/box/fir/selfTypes/selfTypeBuilder.kt @@ -0,0 +1,51 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlin.Self + +open class Person(builder: PersonBuilder<*>) { + var name: String + + init { + this.name = builder.name + } +} + +class Employee(builder: EmployeeBuilder) : Person(builder) { + var role: String + + init { + this.role = builder.role + } +} + +@Self +open class PersonBuilder { + lateinit var name: String + + fun setName(name: String): Self { + this.name = name + return this + } + + open fun build(): Person = Person(this) +} + +class EmployeeBuilder : PersonBuilder() { + lateinit var role: String + + fun setRole(role: String): EmployeeBuilder { + this.role = role + return this + } + + override fun build(): Employee = Employee(this) +} + +fun box(): String { + val person: Person = PersonBuilder().setName("Person").build() + val employee: Employee = EmployeeBuilder().setName("Employee").setRole("Role").build() + val predicate = (person.name == "Person" && employee.name == "Employee" && employee.role == "Role") + return if (predicate) "OK" else "ERROR" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/fir/selfTypes/selfTypeInSealedInterface.kt b/compiler/testData/codegen/box/fir/selfTypes/selfTypeInSealedInterface.kt new file mode 100644 index 0000000000000..69e9fa1769df8 --- /dev/null +++ b/compiler/testData/codegen/box/fir/selfTypes/selfTypeInSealedInterface.kt @@ -0,0 +1,22 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlin.Self + +sealed interface Base { + fun foo(): Int { + return when(this) { + is A -> 1 + is B<*> -> 2 + } + } +} + +class A : Base +@Self +class B : Base + +fun box(): String { + return if (B().foo() == 1) "ERROR" else "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/fir/selfTypes/transformationChainLazyContainer.kt b/compiler/testData/codegen/box/fir/selfTypes/transformationChainLazyContainer.kt new file mode 100644 index 0000000000000..0b328b39a27c2 --- /dev/null +++ b/compiler/testData/codegen/box/fir/selfTypes/transformationChainLazyContainer.kt @@ -0,0 +1,43 @@ +// TARGET_BACKEND: JVM_IR + +// WITH_STDLIB + +import kotlin.Self + +@Self +abstract class Lazy(val computation: () -> T) { + protected abstract fun create(computation: () -> T): Self + fun copy(): Self = create(computation) +} + +@Self +abstract class LazyContainer(computation: () -> T) : + Lazy(computation) { + fun applyFunction(f: (T) -> T): Self = create { f(computation()) } +} + +class LazyList(computation: () -> List) : LazyContainer, LazyList>(computation) { + override fun create(computation: () -> List): LazyList = LazyList(computation) + fun add(elem: T): LazyList = create { computation() + elem } +} + +class LazySet(computation: () -> Set) : LazyContainer, LazySet>(computation) { + override fun create(computation: () -> Set): LazySet = LazySet(computation) + fun add(elem: T): LazySet = create { computation() + elem } +} + +fun box(): String { + val list = LazyList { listOf(1, 2, 3) } + .copy() + .applyFunction { l -> l.map { it + 1 } } + .add(15) + .computation() + + val set = LazySet { setOf(1, 2, 3) } + .copy() + .applyFunction { s -> s.map { it + 1 }.toSet() } + .add(3) + .computation() + val predicate = list == listOf(2, 3, 4, 15) && set == setOf(2, 3, 4) + return if (predicate) "OK" else "ERROR" +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index e79df87a1064a..ab9dd7d7bd080 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -17556,6 +17556,16 @@ public void testNotFoundClasses() throws Exception { public void testSuspendExtension() throws Exception { runTest("compiler/testData/codegen/box/fir/SuspendExtension.kt"); } + + @Nested + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + } } @Nested diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 3bd411e0bd6db..d9b7a2dcb38c9 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -18384,6 +18384,64 @@ public void testSuspendExtension() throws Exception { public void testUnqualifiedEnum() throws Exception { runTest("compiler/testData/codegen/box/fir/unqualifiedEnum.kt"); } + + @Nested + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("classWithSelfType.kt") + public void testClassWithSelfType() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/classWithSelfType.kt"); + } + + @Test + @TestMetadata("ControlFlowInfoSelfTypes.kt") + public void testControlFlowInfoSelfTypes() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/ControlFlowInfoSelfTypes.kt"); + } + + @Test + @TestMetadata("observer.kt") + public void testObserver() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/observer.kt"); + } + + @Test + @TestMetadata("selfClassAsFunctionArgument.kt") + public void testSelfClassAsFunctionArgument() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/selfClassAsFunctionArgument.kt"); + } + + @Test + @TestMetadata("selfClassAsReturnType.kt") + public void testSelfClassAsReturnType() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/selfClassAsReturnType.kt"); + } + + @Test + @TestMetadata("selfTypeBuilder.kt") + public void testSelfTypeBuilder() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/selfTypeBuilder.kt"); + } + + @Test + @TestMetadata("selfTypeInSealedInterface.kt") + public void testSelfTypeInSealedInterface() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/selfTypeInSealedInterface.kt"); + } + + @Test + @TestMetadata("transformationChainLazyContainer.kt") + public void testTransformationChainLazyContainer() throws Exception { + runTest("compiler/testData/codegen/box/fir/selfTypes/transformationChainLazyContainer.kt"); + } + } } @Nested diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 666be14d5f3f4..060cfdb4b0c2d 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -14547,6 +14547,19 @@ public void testNameHighlighter() throws Exception { public void testNotFoundClasses() throws Exception { runTest("compiler/testData/codegen/box/fir/notFoundClasses.kt"); } + + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SelfTypes extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + } } @TestMetadata("compiler/testData/codegen/box/fullJdk") diff --git a/core/builtins/src/kotlin/Annotations.kt b/core/builtins/src/kotlin/Annotations.kt index 8a7cac9b567c6..d967f9002dd19 100644 --- a/core/builtins/src/kotlin/Annotations.kt +++ b/core/builtins/src/kotlin/Annotations.kt @@ -174,4 +174,8 @@ public annotation class DslMarker @Retention(AnnotationRetention.BINARY) @MustBeDocumented @SinceKotlin("1.1") -public annotation class PublishedApi \ No newline at end of file +public annotation class PublishedApi + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +public annotation class Self \ No newline at end of file diff --git a/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt b/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt index c489fdd06f246..dfe291bfd4c87 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/builtins/StandardNames.kt @@ -77,6 +77,8 @@ object StandardNames { @JvmField val KOTLIN_INTERNAL_FQ_NAME = BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier("internal")) + const val SELF_TYPE_NAME = "Self" + @JvmField val BUILT_INS_PACKAGE_FQ_NAMES = setOf( BUILT_INS_PACKAGE_FQ_NAME, diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/SpecialNames.kt b/core/compiler.common/src/org/jetbrains/kotlin/name/SpecialNames.kt index 5776b40f13607..546951a06da38 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/name/SpecialNames.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/name/SpecialNames.kt @@ -64,6 +64,9 @@ object SpecialNames { @JvmField val IMPLICIT_SET_PARAMETER = Name.special("") + @JvmField + val SELF_TYPE = Name.special("") + @JvmField val ARRAY = Name.special("") diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt b/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt index 67d0b4df2784e..8d5c9f28bc073 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/name/StandardClassIds.kt @@ -174,6 +174,8 @@ object StandardClassIds { val WasExperimental = "WasExperimental".baseId() + val Self = "Self".baseId() + val AccessibleLateinitPropertyLiteral = "AccessibleLateinitPropertyLiteral".internalId() object Java { @@ -239,7 +241,9 @@ object StandardClassIds { private fun String.baseId() = ClassId(StandardClassIds.BASE_KOTLIN_PACKAGE, Name.identifier(this)) private fun ClassId.unsignedId() = ClassId(StandardClassIds.BASE_KOTLIN_PACKAGE, Name.identifier("U" + shortClassName.identifier)) private fun String.reflectId() = ClassId(StandardClassIds.BASE_REFLECT_PACKAGE, Name.identifier(this)) -private fun Name.primitiveArrayId() = ClassId(StandardClassIds.Array.packageFqName, Name.identifier(identifier + StandardClassIds.Array.shortClassName.identifier)) +private fun Name.primitiveArrayId() = + ClassId(StandardClassIds.Array.packageFqName, Name.identifier(identifier + StandardClassIds.Array.shortClassName.identifier)) + private fun String.collectionsId() = ClassId(StandardClassIds.BASE_COLLECTIONS_PACKAGE, Name.identifier(this)) private fun String.rangesId() = ClassId(StandardClassIds.BASE_RANGES_PACKAGE, Name.identifier(this)) private fun String.annotationId() = ClassId(StandardClassIds.BASE_ANNOTATION_PACKAGE, Name.identifier(this)) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index 74a37e8138843..b17d551fad2f8 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -13514,6 +13514,16 @@ public void testClassCanNotBeCastedToVoid() throws Exception { public void testFalsePositiveBoundSmartcast() throws Exception { runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); } + + @Nested + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + } } @Nested diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java index 63425c5c70f1c..ce0b4c7467515 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java @@ -13610,6 +13610,16 @@ public void testClassCanNotBeCastedToVoid() throws Exception { public void testFalsePositiveBoundSmartcast() throws Exception { runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); } + + @Nested + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + } } @Nested diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index f817699886e19..f79055fa2c8e1 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -13610,6 +13610,16 @@ public void testClassCanNotBeCastedToVoid() throws Exception { public void testFalsePositiveBoundSmartcast() throws Exception { runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); } + + @Nested + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + } } @Nested diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 6d16196e87bd5..b8d052ee57842 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -12087,6 +12087,19 @@ public void testClassCanNotBeCastedToVoid() throws Exception { public void testFalsePositiveBoundSmartcast() throws Exception { runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); } + + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SelfTypes extends AbstractIrCodegenBoxWasmTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath); + } + + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); + } + } } @TestMetadata("compiler/testData/codegen/box/fullJdk") diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java index 5649beb7306e4..17bb8f311d033 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/K2NativeCodegenBoxTestGenerated.java @@ -14822,6 +14822,19 @@ public void testClassCanNotBeCastedToVoid() throws Exception { public void testFalsePositiveBoundSmartcast() throws Exception { runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); } + + @Nested + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + @Tag("codegen") + @UseExtTestCaseGroupProvider() + @K2Pipeline() + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); + } + } } @Nested diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index 21b2f65e3a336..75655883d8209 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -14646,6 +14646,18 @@ public void testClassCanNotBeCastedToVoid() throws Exception { public void testFalsePositiveBoundSmartcast() throws Exception { runTest("compiler/testData/codegen/box/fir/falsePositiveBoundSmartcast.kt"); } + + @Nested + @TestMetadata("compiler/testData/codegen/box/fir/selfTypes") + @TestDataPath("$PROJECT_ROOT") + @Tag("codegen") + @UseExtTestCaseGroupProvider() + public class SelfTypes { + @Test + public void testAllFilesPresentInSelfTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/fir/selfTypes"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true); + } + } } @Nested