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 b2b66a3ecc5..5bc0c11ab54 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 @@ -2394,6 +2394,34 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract } } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InlineClasses extends AbstractLazyBodyIsNotTouchedTilContractsPhaseTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInInlineClasses() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/inlineClasses"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("inlineClassConstructor.kt") + public void testInlineClassConstructor() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.kt"); + } + + @TestMetadata("inlineClassDeclaration.kt") + public void testInlineClassDeclaration() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.kt"); + } + + @TestMetadata("inlineClassMembers.kt") + public void testInlineClassMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt"); + } + } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/innerClasses") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/fir/analysis-tests/testData/resolve/fromBuilder/simpleClass.kt b/compiler/fir/analysis-tests/testData/resolve/fromBuilder/simpleClass.kt index bdadf0db4d7..a16fc196212 100644 --- a/compiler/fir/analysis-tests/testData/resolve/fromBuilder/simpleClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/fromBuilder/simpleClass.kt @@ -18,4 +18,4 @@ class SomeClass : SomeInterface { lateinit var fau: Double } -inline class InlineClass +inline class InlineClass diff --git a/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.fir.txt b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.fir.txt new file mode 100644 index 00000000000..df9e3e0d32a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.fir.txt @@ -0,0 +1,146 @@ +FILE: inlineClassConstructor.kt + public final class WithoutConstructor : R|kotlin/Any| { + public constructor(): R|WithoutConstructor| { + super() + } + + } + public final inline class WithoutParameter : R|kotlin/Any| { + public constructor(): R|WithoutParameter| { + super() + } + + } + public final inline class WithTwoParameters : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|, y: R|kotlin/String|): R|WithTwoParameters| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + public final val y: R|kotlin/String| = R|/y| + public get(): R|kotlin/String| + + } + public final inline class Ok : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|Ok| { + super() + } + + private final val x: R|kotlin/Int| = R|/x| + private get(): R|kotlin/Int| + + } + public final inline class OpenParameter : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|OpenParameter| { + super() + } + + public open val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + public final inline class VarargParameter : R|kotlin/Any| { + public constructor(vararg x: R|kotlin/IntArray|): R|VarargParameter| { + super() + } + + } + public final inline class VarParameter : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|VarParameter| { + super() + } + + public final var x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + public set(value: R|kotlin/Int|): R|kotlin/Unit| + + } + public final inline class SimpleParameter : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|SimpleParameter| { + super() + } + + } + public final inline class UnitParameter : R|kotlin/Any| { + public constructor(x: R|kotlin/Unit|): R|UnitParameter| { + super() + } + + public final val x: R|kotlin/Unit| = R|/x| + public get(): R|kotlin/Unit| + + } + public final inline class NothingParameter : R|kotlin/Any| { + public constructor(x: R|kotlin/Nothing|): R|NothingParameter| { + super() + } + + public final val x: R|kotlin/Nothing| = R|/x| + public get(): R|kotlin/Nothing| + + } + public final inline class TypeParameterType : R|kotlin/Any| { + public constructor(x: R|T|): R|TypeParameterType| { + super() + } + + public final val x: R|T| = R|/x| + public get(): R|T| + + } + public final inline class ArrayOfTypeParameters : R|kotlin/Any| { + public constructor(x: R|kotlin/Array|): R|ArrayOfTypeParameters| { + super() + } + + public final val x: R|kotlin/Array| = R|/x| + public get(): R|kotlin/Array| + + } + public final inline class ListOfTypeParameters : R|kotlin/Any| { + public constructor(x: R|kotlin/collections/List|): R|ListOfTypeParameters| { + super() + } + + public final val x: R|kotlin/collections/List| = R|/x| + public get(): R|kotlin/collections/List| + + } + public final inline class StarProjection : R|kotlin/Any| { + public constructor(x: R|kotlin/Array<*>|): R|StarProjection| { + super() + } + + public final val x: R|kotlin/Array<*>| = R|/x| + public get(): R|kotlin/Array<*>| + + } + public final inline class SimpleRecursive : R|kotlin/Any| { + public constructor(x: R|SimpleRecursive|): R|SimpleRecursive| { + super() + } + + public final val x: R|SimpleRecursive| = R|/x| + public get(): R|SimpleRecursive| + + } + public final inline class DoubleRecursive1 : R|kotlin/Any| { + public constructor(x: R|DoubleRecursive2|): R|DoubleRecursive1| { + super() + } + + public final val x: R|DoubleRecursive2| = R|/x| + public get(): R|DoubleRecursive2| + + } + public final inline class DoubleRecursive2 : R|kotlin/Any| { + public constructor(x: R|DoubleRecursive1|): R|DoubleRecursive2| { + super() + } + + public final val x: R|DoubleRecursive1| = R|/x| + public get(): R|DoubleRecursive1| + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.kt b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.kt new file mode 100644 index 00000000000..b7cb51e89f2 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.kt @@ -0,0 +1,21 @@ +value class WithoutConstructor {} + +inline class WithoutParameter() {} +inline class WithTwoParameters(val x: Int, val y: String) {} + +inline class Ok(private val x: Int) {} +inline class OpenParameter(open val x: Int) {} +inline class VarargParameter(vararg x: Int) {} +inline class VarParameter(var x: Int) {} +inline class SimpleParameter(x: Int) {} + +inline class UnitParameter(val x: Unit) +inline class NothingParameter(val x: Nothing) +inline class TypeParameterType(val x: T) +inline class ArrayOfTypeParameters(val x: Array) +inline class ListOfTypeParameters(val x: List) +inline class StarProjection(val x: Array<*>) + +inline class SimpleRecursive(val x: SimpleRecursive) +inline class DoubleRecursive1(val x: DoubleRecursive2) +inline class DoubleRecursive2(val x: DoubleRecursive1) diff --git a/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.fir.txt b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.fir.txt new file mode 100644 index 00000000000..4e10c559708 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.fir.txt @@ -0,0 +1,111 @@ +FILE: inlineClassDeclaration.kt + public final class A : R|kotlin/Any| { + public constructor(): R|A| { + super() + } + + public final inline class B : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|A.B| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + + public final fun foo(): R|kotlin/Unit| { + local final inline class C : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|A.C| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + + } + + public final inner class D : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|A.D| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + + } + public open inline class NotFinalClass1 : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|NotFinalClass1| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + public abstract inline class NotFinalClass2 : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|NotFinalClass2| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + public sealed inline class NotFinalClass3 : R|kotlin/Any| { + protected constructor(x: R|kotlin/Int|): R|NotFinalClass3| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + public final class CloneableClass1 : R|kotlin/Cloneable| { + public constructor(x: R|kotlin/Int|): R|CloneableClass1| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + public final inline class CloneableClass2 : R|java/lang/Cloneable| { + public constructor(x: R|kotlin/Int|): R|CloneableClass2| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + public open class Test : R|kotlin/Any| { + public constructor(): R|Test| { + super() + } + + } + public final inline class ExtendTest : R|Test| { + public constructor(x: R|kotlin/Int|): R|ExtendTest| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } + public final inline class ImplementByDelegation : R|kotlin/Comparable| { + public constructor(x: R|kotlin/Int|): R|ImplementByDelegation| { + super() + } + + local final field <$$delegate_0>: R|kotlin/Comparable| = R|/x| + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.kt b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.kt new file mode 100644 index 00000000000..29fb1c6778c --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.kt @@ -0,0 +1,19 @@ +class A { + inline class B(val x: Int) + fun foo() { + inline class C(val x: Int) + } + inner value class D(val x: Int) +} + +open inline class NotFinalClass1(val x: Int) +abstract inline class NotFinalClass2(val x: Int) +sealed inline class NotFinalClass3(val x: Int) + +value class CloneableClass1(val x: Int): Cloneable +inline class CloneableClass2(val x: Int): java.lang.Cloneable + +open class Test +inline class ExtendTest(val x: Int): Test + +inline class ImplementByDelegation(val x: Int) : Comparable by x diff --git a/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.fir.txt b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.fir.txt new file mode 100644 index 00000000000..bc7b550b6d1 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.fir.txt @@ -0,0 +1,100 @@ +FILE: inlineClassMembers.kt + public final class BackingFields : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|BackingFields| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + public final val y: R|kotlin/Int| = Int(0) + public get(): R|kotlin/Int| + + public final var z: R|kotlin/String| + public get(): R|kotlin/String| { + ^ String() + } + public set(value: R|kotlin/String|): R|kotlin/Unit| { + } + + } + public final class Val : R|kotlin/Any| { + public constructor(): R|Val| { + super() + } + + public final operator fun getValue(thisRef: R|kotlin/Any?|, kProp: R|kotlin/Any?|): R|kotlin/Int| { + ^getValue Int(1) + } + + } + public final inline class DelegatedProp : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|DelegatedProp| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + public final val testVal: R|kotlin/Int|by R|/Val.Val|() + public get(): R|kotlin/Int| { + ^ this@R|/DelegatedProp|.D|/DelegatedProp.testVal|.R|/Val.getValue|(this@R|/DelegatedProp|, ::R|/DelegatedProp.testVal|) + } + + } + public final inline class ReversedMembers : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|ReversedMembers| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + public final fun box(): R|kotlin/Unit| { + } + + public final fun unbox(): R|kotlin/Unit| { + } + + public final override operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean| { + ^equals Boolean(true) + } + + public final override fun hashCode(): R|kotlin/Int| { + ^hashCode Int(1) + } + + } + public final inline class SecondaryConstructors : R|kotlin/Any| { + public constructor(x: R|kotlin/Int|): R|SecondaryConstructors| { + super() + } + + public final val x: R|kotlin/Int| = R|/x| + public get(): R|kotlin/Int| + + public constructor(y: R|kotlin/String|): R|SecondaryConstructors| { + this(Int(5)) + } + + public constructor(x: R|kotlin/Int|, y: R|kotlin/String|): R|SecondaryConstructors| { + this(R|/x|) + } + + } + public final class WithInner : R|kotlin/Any| { + public constructor(x: R|kotlin/String|): R|WithInner| { + super() + } + + public final val x: R|kotlin/String| = R|/x| + public get(): R|kotlin/String| + + public final inner class Inner : R|kotlin/Any| { + public constructor(): R|WithInner.Inner| { + super() + } + + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt new file mode 100644 index 00000000000..6fee05fdbea --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt @@ -0,0 +1,32 @@ +value class BackingFields(val x: Int) { + val y = 0 + var z: String + get() = "" + set(value) {} +} + +class Val { + operator fun getValue(thisRef: Any?, kProp: Any?) = 1 +} +inline class DelegatedProp(val x: Int) { + val testVal by Val() +} + +inline class ReversedMembers(val x: Int) { + fun box() {} + fun unbox() {} + + override fun equals(other: Any?) = true + override fun hashCode() = 1 +} + +inline class SecondaryConstructors(val x: Int) { + constructor(y: String) : this(5) + constructor(x: Int, y: String) : this(x) { + + } +} + +value class WithInner(val x: String) { + inner class Inner +} 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 4492e91c070..6ae8fcb5344 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 @@ -2724,6 +2724,34 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { } } + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + public class InlineClasses { + @Test + public void testAllFilesPresentInInlineClasses() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/inlineClasses"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("inlineClassConstructor.kt") + public void testInlineClassConstructor() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.kt"); + } + + @Test + @TestMetadata("inlineClassDeclaration.kt") + public void testInlineClassDeclaration() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.kt"); + } + + @Test + @TestMetadata("inlineClassMembers.kt") + public void testInlineClassMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt"); + } + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/innerClasses") @TestDataPath("$PROJECT_ROOT") 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 ead574e1fb4..6dd609c2037 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 @@ -2752,6 +2752,35 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos } } + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/inlineClasses") + @TestDataPath("$PROJECT_ROOT") + @Execution(ExecutionMode.SAME_THREAD) + public class InlineClasses { + @Test + public void testAllFilesPresentInInlineClasses() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/inlineClasses"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("inlineClassConstructor.kt") + public void testInlineClassConstructor() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassConstructor.kt"); + } + + @Test + @TestMetadata("inlineClassDeclaration.kt") + public void testInlineClassDeclaration() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassDeclaration.kt"); + } + + @Test + @TestMetadata("inlineClassMembers.kt") + public void testInlineClassMembers() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/inlineClasses/inlineClassMembers.kt"); + } + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/innerClasses") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt index cb14bdb3d39..c1a05326a4a 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt @@ -42,6 +42,8 @@ enum class PositioningStrategy(private val strategy: String? = null) { IF_EXPRESSION, VARIANCE_MODIFIER, LATEINIT_MODIFIER, + INLINE_OR_VALUE_MODIFIER, + INNER_MODIFIER, SELECTOR_BY_QUALIFIED, REFERENCE_BY_QUALIFIED, PRIVATE_MODIFIER, 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 fe0341ca87f..1f6846947a9 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 @@ -154,6 +154,28 @@ object DIAGNOSTICS_LIST : DiagnosticList() { val REDUNDANT_OPEN_IN_INTERFACE by warning(PositioningStrategy.OPEN_MODIFIER) } + val INLINE_CLASSES by object : DiagnosticGroup("Inline classes") { + val INLINE_CLASS_NOT_TOP_LEVEL by error(PositioningStrategy.INLINE_OR_VALUE_MODIFIER) + val INLINE_CLASS_NOT_FINAL by error(PositioningStrategy.MODALITY_MODIFIER) + val ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS by error(PositioningStrategy.INLINE_OR_VALUE_MODIFIER) + val INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE by error() + val INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER by error() + val PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS by error(PositioningStrategy.DECLARATION_SIGNATURE) + val DELEGATED_PROPERTY_INSIDE_INLINE_CLASS by error() + val INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE by error { + parameter("type") + } + val INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION by error() + val INLINE_CLASS_CANNOT_EXTEND_CLASSES by error() + val INLINE_CLASS_CANNOT_BE_RECURSIVE by error() + val RESERVED_MEMBER_INSIDE_INLINE_CLASS by error(PositioningStrategy.DECLARATION_NAME) { + parameter("fun name") + } + val SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS by error() + val INNER_CLASS_INSIDE_INLINE_CLASS by error(PositioningStrategy.INNER_MODIFIER) + val VALUE_CLASS_CANNOT_BE_CLONEABLE by error(PositioningStrategy.INLINE_OR_VALUE_MODIFIER) + } + val APPLICABILITY by object : DiagnosticGroup("Applicability") { val NONE_APPLICABLE by error(PositioningStrategy.REFERENCE_BY_QUALIFIED) { parameter>>("candidates") 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 1b0d5d8c296..c4d53fc4497 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 @@ -141,6 +141,23 @@ object FirErrors { val INCOMPATIBLE_MODIFIERS by error2() val REDUNDANT_OPEN_IN_INTERFACE by warning0(SourceElementPositioningStrategies.OPEN_MODIFIER) + // Inline classes + val INLINE_CLASS_NOT_TOP_LEVEL by error0(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER) + val INLINE_CLASS_NOT_FINAL by error0(SourceElementPositioningStrategies.MODALITY_MODIFIER) + val ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS by error0(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER) + val INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE by error0() + val INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER by error0() + val PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + val DELEGATED_PROPERTY_INSIDE_INLINE_CLASS by error0() + val INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE by error1() + val INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION by error0() + val INLINE_CLASS_CANNOT_EXTEND_CLASSES by error0() + val INLINE_CLASS_CANNOT_BE_RECURSIVE by error0() + val RESERVED_MEMBER_INSIDE_INLINE_CLASS by error1(SourceElementPositioningStrategies.DECLARATION_NAME) + val SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS by error0() + val INNER_CLASS_INSIDE_INLINE_CLASS by error0(SourceElementPositioningStrategies.INNER_MODIFIER) + val VALUE_CLASS_CANNOT_BE_CLONEABLE by error0(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER) + // Applicability val NONE_APPLICABLE by error1>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) val INAPPLICABLE_CANDIDATE by error1>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt index f0d7843fbe3..6b0bd54d208 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.modality @@ -171,3 +172,10 @@ private val FirProperty.hasAccessorImplementation: Boolean (setter !is FirDefaultPropertyAccessor && setter?.hasBody == true) internal val FirClass<*>.canHaveOpenMembers: Boolean get() = modality() != Modality.FINAL || classKind == ClassKind.ENUM_CLASS + +internal fun FirRegularClass.isInlineOrValueClass(): Boolean { + if (this.classKind != ClassKind.CLASS) return false + + val modifierList = with(FirModifierList) { source.getModifierList() } + return isInline || modifierList?.modifiers?.any { it.token == KtTokens.VALUE_KEYWORD } == true +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt new file mode 100644 index 00000000000..90e57a1cc6f --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineClassDeclarationChecker.kt @@ -0,0 +1,198 @@ +/* + * Copyright 2010-2021 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.descriptors.Modality +import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext +import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClass +import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.resolve.calls.isPotentiallyArray +import org.jetbrains.kotlin.fir.resolve.defaultType +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.types.AbstractTypeChecker + +object FirInlineClassDeclarationChecker : FirRegularClassChecker() { + + private val reservedFunctionNames = setOf("box", "unbox", "equals", "hashCode") + private val kotlinCloneableType = ClassId.fromString("kotlin/Cloneable").constructClassLikeType(emptyArray(), false) + private val javaCloneableType = ClassId.fromString("java/lang/Cloneable").constructClassLikeType(emptyArray(), false) + + override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) { + if (!declaration.isInlineOrValueClass()) { + return + } + + if (context.containingDeclarations.size > 1) { + reporter.reportOn(declaration.source, FirErrors.INLINE_CLASS_NOT_TOP_LEVEL, context) + } + + if (declaration.modality != Modality.FINAL) { + reporter.reportOn(declaration.source, FirErrors.INLINE_CLASS_NOT_FINAL, context) + } + + for (supertypeEntry in declaration.superTypeRefs) { + if (supertypeEntry.toRegularClass(context.session)?.isInterface != true) { + reporter.reportOn(supertypeEntry.source, FirErrors.INLINE_CLASS_CANNOT_EXTEND_CLASSES, context) + } + } + + if (declaration.isSubtypeOfCloneable(context)) { + reporter.reportOn(declaration.source, FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE, context) + } + + var primaryConstructor: FirConstructor? = null + var primaryConstructorParameter: FirValueParameter? = null + var primaryConstructorProperty: FirProperty? = null + + for (innerDeclaration in declaration.declarations) { + when (innerDeclaration) { + is FirConstructor -> { + when { + innerDeclaration.isPrimary -> { + primaryConstructor = innerDeclaration + primaryConstructorParameter = innerDeclaration.valueParameters.singleOrNull() + } + + innerDeclaration.body != null -> { + val bodySource = innerDeclaration.body!!.source + reporter.reportOn(bodySource, FirErrors.SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS, context) + } + } + } + is FirRegularClass -> { + if (innerDeclaration.isInner) { + reporter.reportOn(innerDeclaration.source, FirErrors.INNER_CLASS_INSIDE_INLINE_CLASS, context) + } + } + is FirSimpleFunction -> { + val functionName = innerDeclaration.name.asString() + + if (functionName in reservedFunctionNames) { + reporter.reportOn(innerDeclaration.source, FirErrors.RESERVED_MEMBER_INSIDE_INLINE_CLASS, functionName, context) + } + } + is FirField -> { + if (innerDeclaration.isSynthetic) { + val delegatedTypeRefSource = (innerDeclaration.returnTypeRef as FirResolvedTypeRef).delegatedTypeRef?.source + reporter.reportOn(delegatedTypeRefSource, FirErrors.INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION, context) + } + } + is FirProperty -> { + if (innerDeclaration.isRelatedToParameter(primaryConstructorParameter)) { + primaryConstructorProperty = innerDeclaration + } else { + when { + innerDeclaration.delegate != null -> + reporter.reportOn( + innerDeclaration.delegate!!.source, + FirErrors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS, + context + ) + + innerDeclaration.hasBackingField && + innerDeclaration.source?.kind !is FirFakeSourceElementKind -> + reporter.reportOn( + innerDeclaration.source, + FirErrors.PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS, + context + ) + } + } + } + } + } + + if (primaryConstructor?.source?.kind !is FirRealSourceElementKind) { + reporter.reportOn(declaration.source, FirErrors.ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS, context) + return + } + + if (primaryConstructorParameter == null) { + reporter.reportOn(primaryConstructor.source, FirErrors.INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, context) + return + } + + when { + primaryConstructorParameter.isNotFinalReadOnly(primaryConstructorProperty) -> + reporter.reportOn( + primaryConstructorParameter.source, + FirErrors.INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER, + context + ) + + primaryConstructorParameter.returnTypeRef.isInapplicableParameterType() -> + reporter.reportOn( + primaryConstructorParameter.returnTypeRef.source, + FirErrors.INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE, + primaryConstructorParameter.returnTypeRef.coneType, + context + ) + + primaryConstructorParameter.returnTypeRef.coneType.isRecursiveInlineClassType(context.session) -> + reporter.reportOn( + primaryConstructorParameter.returnTypeRef.source, + FirErrors.INLINE_CLASS_CANNOT_BE_RECURSIVE, + context + ) + } + } + + private fun FirProperty.isRelatedToParameter(parameter: FirValueParameter?) = + name == parameter?.name && source?.kind is FirFakeSourceElementKind + + private fun FirValueParameter.isNotFinalReadOnly(primaryConstructorProperty: FirProperty?): Boolean { + if (primaryConstructorProperty == null) return true + + val modifierList = with(FirModifierList) { source.getModifierList() } + val isOpen = modifierList?.modifiers?.any { it.token == KtTokens.OPEN_KEYWORD } == true + + return isVararg || !primaryConstructorProperty.isVal || isOpen + } + + private fun FirTypeRef.isInapplicableParameterType() = + isUnit || isNothing || coneType is ConeTypeParameterType || coneType.isGenericArrayOfTypeParameter() + + private fun ConeKotlinType.isGenericArrayOfTypeParameter(): Boolean { + if (this.typeArguments.firstOrNull() is ConeStarProjection || !isPotentiallyArray()) + return false + + val arrayElementType = arrayElementType()?.type ?: return false + return arrayElementType is ConeTypeParameterType || + arrayElementType.isGenericArrayOfTypeParameter() + } + + private fun ConeKotlinType.isRecursiveInlineClassType(session: FirSession) = + isRecursiveInlineClassType(hashSetOf(), session) + + private fun ConeKotlinType.isRecursiveInlineClassType(visited: HashSet, session: FirSession): Boolean { + if (!visited.add(this)) return true + + val asRegularClass = this.toRegularClass(session) ?: return false + + return asRegularClass.isInlineOrValueClass() && + asRegularClass.primaryConstructor + ?.takeIf { it.source?.kind is FirRealSourceElementKind } + ?.valueParameters + ?.firstOrNull() + ?.returnTypeRef + ?.coneType + ?.isRecursiveInlineClassType(visited, session) == true + } + + private fun FirRegularClass.isSubtypeOfCloneable(context: CheckerContext): Boolean { + val coneType = this.defaultType() + val typeContext = context.session.typeContext + + return AbstractTypeChecker.isSubtypeOf(typeContext, coneType, kotlinCloneableType) || + AbstractTypeChecker.isSubtypeOf(typeContext, coneType, javaCloneableType) + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index b7d84be8c77..800cfb3d266 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMB import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_STRING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.VISIBILITY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.WHEN_MISSING_CASES +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_DELEGATED_PROPERTY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_FUNCTION_WITH_BODY @@ -53,6 +54,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_OBJECT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR @@ -89,6 +91,15 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_LATE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INCOMPATIBLE_MODIFIERS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INFERENCE_ERROR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CANNOT_BE_RECURSIVE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CANNOT_EXTEND_CLASSES +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_NOT_FINAL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_NOT_TOP_LEVEL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_INSIDE_INLINE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS @@ -132,6 +143,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROJECTION_ON_NON import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_WITH_NO_TYPE_NO_INITIALIZER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RECURSION_IN_IMPLICIT_TYPES @@ -148,11 +160,13 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_VISIBILITY_MODIFIER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_MODIFIER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RESERVED_MEMBER_INSIDE_INLINE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_NOT_ALLOWED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_TYPE_MISMATCH_ON_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_CLASS_CONSTRUCTOR_CALL 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_INLINE_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR @@ -178,6 +192,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLA import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_WITH_SETTER +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARARG_OUTSIDE_PARENTHESES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_EXPECTED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_INITIALIZER_IS_REDUNDANT @@ -369,6 +384,23 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left hand side of a class literal") map.put(NULLABLE_TYPE_IN_CLASS_LITERAL_LHS, "Type in a class literal must not be nullable") + // Inline and value classes + map.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes cannot be local or inner") + map.put(INLINE_CLASS_NOT_FINAL, "Inline classes can be only final") + map.put(ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_INLINE_CLASS, "Primary constructor is required for inline class") + map.put(INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, "Inline class must have exactly one primary constructor parameter") + map.put(INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER, "Value class primary constructor must have only final read-only (val) property parameter") + map.put(PROPERTY_WITH_BACKING_FIELD_INSIDE_INLINE_CLASS, "Inline class cannot have properties with backing fields") + map.put(DELEGATED_PROPERTY_INSIDE_INLINE_CLASS, "Inline class cannot have delegated properties") + map.put(INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE, "Inline class cannot have value parameter of type ''{0}''", TO_STRING) + map.put(INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION, "Inline class cannot implement an interface by delegation") + map.put(INLINE_CLASS_CANNOT_EXTEND_CLASSES, "Inline class cannot extend classes") + map.put(INLINE_CLASS_CANNOT_BE_RECURSIVE, "Inline class cannot be recursive") + map.put(RESERVED_MEMBER_INSIDE_INLINE_CLASS, "Member with the name ''{0}'' is reserved for future releases", TO_STRING) + map.put(SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS, "Secondary constructors with bodies are reserved for for future releases") + map.put(INNER_CLASS_INSIDE_INLINE_CLASS, "Inline class cannot have inner classes") + map.put(VALUE_CLASS_CANNOT_BE_CLONEABLE, "Value class cannot be Cloneable") + // Overrides map.put(NOTHING_TO_OVERRIDE, "''{0}'' overrides nothing", DECLARATION_NAME) map.put(OVERRIDING_FINAL_MEMBER, "''{0}'' in ''{1}'' is final and cannot be overridden", NAME, TO_STRING) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt index de3653ba25f..0d67237b93c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt @@ -295,6 +295,12 @@ object LightTreePositioningStrategies { val CONST_MODIFIER: LightTreePositioningStrategy = ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.CONST_KEYWORD)) + val INLINE_OR_VALUE_MODIFIER: LightTreePositioningStrategy = + ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.INLINE_KEYWORD, KtTokens.VALUE_KEYWORD)) + + val INNER_MODIFIER: LightTreePositioningStrategy = + ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.INNER_KEYWORD)) + val OPERATOR: LightTreePositioningStrategy = object : LightTreePositioningStrategy() { override fun mark( node: LighterASTNode, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt index 56c498f5c42..69b214cb13e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt @@ -93,6 +93,16 @@ object SourceElementPositioningStrategies { PositioningStrategies.CONST_MODIFIER ) + val INLINE_OR_VALUE_MODIFIER = SourceElementPositioningStrategy( + LightTreePositioningStrategies.INLINE_OR_VALUE_MODIFIER, + PositioningStrategies.INLINE_OR_VALUE_MODIFIER + ) + + val INNER_MODIFIER = SourceElementPositioningStrategy( + LightTreePositioningStrategies.INNER_MODIFIER, + PositioningStrategies.INNER_MODIFIER + ) + val OPERATOR = SourceElementPositioningStrategy( LightTreePositioningStrategies.OPERATOR, PositioningStrategies.OPERATOR diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt index 9ff80df6f41..c9c59177e8a 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonDeclarationCheckers.kt @@ -62,6 +62,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { FirMemberFunctionsChecker, FirMemberPropertiesChecker, FirNestedClassChecker, + FirInlineClassDeclarationChecker, ) override val constructorCheckers: Set = setOf( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index bf6074a3c3a..ccbc750f532 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.cfg.UnreachableCode import org.jetbrains.kotlin.diagnostics.Errors.ACTUAL_WITHOUT_EXPECT import org.jetbrains.kotlin.diagnostics.Errors.NO_ACTUAL_FOR_EXPECT +import org.jetbrains.kotlin.diagnostics.PositioningStrategies.INNER_MODIFIER import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens.MODALITY_MODIFIERS @@ -440,6 +441,14 @@ object PositioningStrategies { @JvmField val MODALITY_MODIFIER: PositioningStrategy = ModifierSetBasedPositioningStrategy(MODALITY_MODIFIERS) + @JvmField + val INLINE_OR_VALUE_MODIFIER: PositioningStrategy = + ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.INLINE_KEYWORD, KtTokens.VALUE_KEYWORD)) + + @JvmField + val INNER_MODIFIER: PositioningStrategy = + ModifierSetBasedPositioningStrategy(TokenSet.create(KtTokens.INNER_KEYWORD)) + @JvmField val VARIANCE_IN_PROJECTION: PositioningStrategy = object : PositioningStrategy() { override fun mark(element: KtTypeProjection): List { diff --git a/compiler/testData/diagnostics/tests/inlineClasses/basicInlineClassDeclarationDisabled.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/basicInlineClassDeclarationDisabled.fir.kt index 7c2d3936a68..d8476bd6691 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/basicInlineClassDeclarationDisabled.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/basicInlineClassDeclarationDisabled.fir.kt @@ -7,4 +7,4 @@ inline annotation class InlineAnn inline object InlineObject inline enum class InlineEnum -inline class NotVal(x: Int) \ No newline at end of file +inline class NotVal(x: Int) diff --git a/compiler/testData/diagnostics/tests/inlineClasses/delegatedPropertyInInlineClass.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/delegatedPropertyInInlineClass.fir.kt index d80a0c75060..6078d277be2 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/delegatedPropertyInInlineClass.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/delegatedPropertyInInlineClass.fir.kt @@ -20,9 +20,9 @@ object VarObject { } inline class Z(val data: Int) { - val testVal by Val() - var testVar by Var() + val testVal by Val() + var testVar by Var() - val testValBySingleton by ValObject - var testVarBySingleton by VarObject -} \ No newline at end of file + val testValBySingleton by ValObject + var testVarBySingleton by VarObject +} diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.fir.kt deleted file mode 100644 index ca52ee3b324..00000000000 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.fir.kt +++ /dev/null @@ -1,13 +0,0 @@ -// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses - -abstract class AbstractBaseClass - -open class OpenBaseClass - -interface BaseInterface - -inline class TestExtendsAbstractClass(val x: Int) : AbstractBaseClass() - -inline class TestExtendsOpenClass(val x: Int) : OpenBaseClass() - -inline class TestImplementsInterface(val x: Int) : BaseInterface \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt index 4adf5bef811..e8fb24cbfce 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCanOnlyImplementInterfaces.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +InlineClasses, -JvmInlineValueClasses abstract class AbstractBaseClass diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCannotImplementInterfaceByDelegation.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCannotImplementInterfaceByDelegation.fir.kt index feb113b6cb5..81570804f55 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCannotImplementInterfaceByDelegation.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassCannotImplementInterfaceByDelegation.fir.kt @@ -4,6 +4,6 @@ interface IFoo object FooImpl : IFoo -inline class Test1(val x: Any) : IFoo by FooImpl +inline class Test1(val x: Any) : IFoo by FooImpl -inline class Test2(val x: IFoo) : IFoo by x \ No newline at end of file +inline class Test2(val x: IFoo) : IFoo by x diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.fir.kt index c46481682db..99cd1c2f489 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassDeclarationCheck.fir.kt @@ -3,38 +3,38 @@ inline class A0(val x: Int) -inline class A1 -inline class A2() -inline class A3(x: Int) -inline class A4(var x: Int) -inline class A5(val x: Int, val y: Int) -inline class A6(x: Int, val y: Int) -inline class A7(vararg val x: Int) -inline class A8(open val x: Int) +inline class A1 +inline class A2() +inline class A3(x: Int) +inline class A4(var x: Int) +inline class A5(val x: Int, val y: Int) +inline class A6(x: Int, val y: Int) +inline class A7(vararg val x: Int) +inline class A8(open val x: Int) inline class A9(final val x: Int) class B1 { companion object { - inline class C1(val x: Int) - inner inline class C11(val x: Int) + inline class C1(val x: Int) + inner inline class C11(val x: Int) } - inline class C2(val x: Int) - inner inline class C21(val x: Int) + inline class C2(val x: Int) + inner inline class C21(val x: Int) } object B2 { - inline class C3(val x: Int) - inner inline class C31(val x: Int) + inline class C3(val x: Int) + inner inline class C31(val x: Int) } fun foo() { - inline class C4(val x: Int) + inline class C4(val x: Int) } final inline class D0(val x: Int) -open inline class D1(val x: Int) -abstract inline class D2(val x: Int) -sealed inline class D3(val x: Int) +open inline class D1(val x: Int) +abstract inline class D2(val x: Int) +sealed inline class D3(val x: Int) inline data class D4(val x: String) diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassWithForbiddenUnderlyingType.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassWithForbiddenUnderlyingType.fir.kt deleted file mode 100644 index 034af53a9c1..00000000000 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassWithForbiddenUnderlyingType.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses - -inline class Foo(val x: T) -inline class FooNullable(val x: T?) - -inline class FooGenericArray(val x: Array) -inline class FooGenericArray2(val x: Array>) - -inline class FooStarProjectedArray(val x: Array<*>) -inline class FooStarProjectedArray2(val x: Array>) - -inline class Bar(val u: Unit) -inline class BarNullable(val u: Unit?) - -inline class Baz(val u: Nothing) -inline class BazNullable(val u: Nothing?) diff --git a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassWithForbiddenUnderlyingType.kt b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassWithForbiddenUnderlyingType.kt index 0b12d0b97dd..7970009df22 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/inlineClassWithForbiddenUnderlyingType.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/inlineClassWithForbiddenUnderlyingType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +InlineClasses, -JvmInlineValueClasses inline class Foo(val x: T) diff --git a/compiler/testData/diagnostics/tests/inlineClasses/innerClassInsideInlineClass.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/innerClassInsideInlineClass.fir.kt index fd5fcaaa768..55136d17975 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/innerClassInsideInlineClass.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/innerClassInsideInlineClass.fir.kt @@ -2,7 +2,7 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE inline class Foo(val x: Int) { - inner class InnerC - inner object InnerO - inner interface InnerI + inner class InnerC + inner object InnerO + inner interface InnerI } diff --git a/compiler/testData/diagnostics/tests/inlineClasses/propertiesWithBackingFieldsInsideInlineClass.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/propertiesWithBackingFieldsInsideInlineClass.fir.kt index a9d54c4d55f..9e65ca6ffad 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/propertiesWithBackingFieldsInsideInlineClass.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/propertiesWithBackingFieldsInsideInlineClass.fir.kt @@ -13,13 +13,13 @@ inline class Foo(val x: Int) : A, B { val a0 get() = 0 - val a1 = 0 + val a1 = 0 var a2: Int get() = 1 set(value) {} - var a3: Int = 0 + var a3: Int = 0 get() = 1 set(value) { field = value @@ -28,7 +28,7 @@ inline class Foo(val x: Int) : A, B { override val goodSize: Int get() = 0 - override val badSize: Int = 0 + override val badSize: Int = 0 - lateinit var lateinitProperty: String + lateinit var lateinitProperty: String } diff --git a/compiler/testData/diagnostics/tests/inlineClasses/recursiveInlineClasses.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/recursiveInlineClasses.fir.kt deleted file mode 100644 index fded4d68da3..00000000000 --- a/compiler/testData/diagnostics/tests/inlineClasses/recursiveInlineClasses.fir.kt +++ /dev/null @@ -1,21 +0,0 @@ -// !LANGUAGE: +InlineClasses, -JvmInlineValueClasses - -inline class Test1(val x: Test1) - -inline class Test2A(val x: Test2B) -inline class Test2B(val x: Test2A) - -inline class Test3A(val x: Test3B) -inline class Test3B(val x: Test3C) -inline class Test3C(val x: Test3A) - -inline class TestNullable(val x: TestNullable?) - -inline class TestRecursionInTypeArguments(val x: List) - -inline class TestRecursionInArray(val x: Array) - -inline class TestRecursionInUpperBounds>(val x: T) - -inline class Id(val x: T) -inline class TestRecursionThroughId(val x: Id) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inlineClasses/recursiveInlineClasses.kt b/compiler/testData/diagnostics/tests/inlineClasses/recursiveInlineClasses.kt index e92d11d1ed2..9c5ff061e47 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/recursiveInlineClasses.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/recursiveInlineClasses.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +InlineClasses, -JvmInlineValueClasses inline class Test1(val x: Test1) diff --git a/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.fir.kt b/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.fir.kt index 03b8559c84a..5a44a079fee 100644 --- a/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.fir.kt +++ b/compiler/testData/diagnostics/tests/inlineClasses/reservedMembersAndConstructsInsideInlineClass.fir.kt @@ -2,32 +2,32 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER inline class IC1(val x: Any) { - fun box() {} - fun box(x: Any) {} + fun box() {} + fun box(x: Any) {} - fun unbox() {} - fun unbox(x: Any) {} + fun unbox() {} + fun unbox(x: Any) {} - override fun equals(other: Any?): Boolean = true - override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = true + override fun hashCode(): Int = 0 } inline class IC2(val x: Any) { - fun box(x: Any) {} - fun box(): Any = TODO() + fun box(x: Any) {} + fun box(): Any = TODO() - fun unbox(x: Any) {} - fun unbox(): Any = TODO() + fun unbox(x: Any) {} + fun unbox(): Any = TODO() - fun equals(my: Any, other: Any): Boolean = true - fun hashCode(a: Any): Int = 0 + fun equals(my: Any, other: Any): Boolean = true + fun hashCode(a: Any): Int = 0 } inline class IC3(val x: Any) { - fun box(x: Any): Any = TODO() - fun unbox(x: Any): Any = TODO() + fun box(x: Any): Any = TODO() + fun unbox(x: Any): Any = TODO() - fun equals(): Boolean = true + fun equals(): Boolean = true } interface WithBox { @@ -35,11 +35,11 @@ interface WithBox { } inline class IC4(val s: String) : WithBox { - override fun box(): String = "" + override fun box(): String = "" } inline class IC5(val a: String) { - constructor(i: Int) : this(i.toString()) { + constructor(i: Int) : this(i.toString()) { TODO("something") - } -} \ No newline at end of file + } +} diff --git a/compiler/testData/diagnostics/tests/multiplatform/inlineClasses/expectActualInlineClass.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/inlineClasses/expectActualInlineClass.fir.kt index 87931f0c35f..7372c763a97 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/inlineClasses/expectActualInlineClass.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/inlineClasses/expectActualInlineClass.fir.kt @@ -8,7 +8,7 @@ expect inline class Foo1(val x: Int) { expect inline class Foo2(val x: Int) -expect inline class Foo3 +expect inline class Foo3 expect class NonInlineExpect @@ -21,7 +21,7 @@ actual inline class Foo1(val x: Int) { actual fun bar(): String = "Hello" } actual inline class Foo2(val x: String) -actual inline class Foo3 +actual inline class Foo3 actual inline class NonInlineExpect(val x: Int) diff --git a/compiler/testData/diagnostics/tests/valueClasses/basicValueClassDeclarationDisabled.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/basicValueClassDeclarationDisabled.fir.kt index dd47c0f0768..017e6d96fc0 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/basicValueClassDeclarationDisabled.fir.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/basicValueClassDeclarationDisabled.fir.kt @@ -14,4 +14,4 @@ value object InlineObject value enum class InlineEnum @JvmInline -value class NotVal(x: Int) +value class NotVal(x: Int) diff --git a/compiler/testData/diagnostics/tests/valueClasses/delegatedPropertyInValueClass.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/delegatedPropertyInValueClass.fir.kt index 141fd02fafb..84431819bd0 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/delegatedPropertyInValueClass.fir.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/delegatedPropertyInValueClass.fir.kt @@ -26,9 +26,9 @@ object VarObject { @JvmInline value class Z(val data: Int) { - val testVal by Val() - var testVar by Var() + val testVal by Val() + var testVar by Var() - val testValBySingleton by ValObject - var testVarBySingleton by VarObject + val testValBySingleton by ValObject + var testVarBySingleton by VarObject } diff --git a/compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.fir.kt index d4a0c75eb19..42d863b1a69 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.fir.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.fir.kt @@ -19,13 +19,13 @@ value class Foo(val x: Int) : A, B { val a0 get() = 0 - val a1 = 0 + val a1 = 0 var a2: Int get() = 1 set(value) {} - var a3: Int = 0 + var a3: Int = 0 get() = 1 set(value) { field = value @@ -34,7 +34,7 @@ value class Foo(val x: Int) : A, B { override val goodSize: Int get() = 0 - override val badSize: Int = 0 + override val badSize: Int = 0 - lateinit var lateinitProperty: String + lateinit var lateinitProperty: String } diff --git a/compiler/testData/diagnostics/tests/valueClasses/recursiveValueClasses.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/recursiveValueClasses.fir.kt deleted file mode 100644 index 50de3665385..00000000000 --- a/compiler/testData/diagnostics/tests/valueClasses/recursiveValueClasses.fir.kt +++ /dev/null @@ -1,38 +0,0 @@ -// !SKIP_JAVAC -// !LANGUAGE: +InlineClasses - -package kotlin.jvm - -annotation class JvmInline - -@JvmInline -value class Test1(val x: Test1) - -@JvmInline -value class Test2A(val x: Test2B) -@JvmInline -value class Test2B(val x: Test2A) - -@JvmInline -value class Test3A(val x: Test3B) -@JvmInline -value class Test3B(val x: Test3C) -@JvmInline -value class Test3C(val x: Test3A) - -@JvmInline -value class TestNullable(val x: TestNullable?) - -@JvmInline -value class TestRecursionInTypeArguments(val x: List) - -@JvmInline -value class TestRecursionInArray(val x: Array) - -@JvmInline -value class TestRecursionInUpperBounds>(val x: T) - -@JvmInline -value class Id(val x: T) -@JvmInline -value class TestRecursionThroughId(val x: Id) diff --git a/compiler/testData/diagnostics/tests/valueClasses/recursiveValueClasses.kt b/compiler/testData/diagnostics/tests/valueClasses/recursiveValueClasses.kt index 57d949c9208..0b4ab1e319f 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/recursiveValueClasses.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/recursiveValueClasses.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !SKIP_JAVAC // !LANGUAGE: +InlineClasses diff --git a/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.fir.kt index 32edbbe3dd5..ec08f5bd6e8 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.fir.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/reservedMembersAndConstructsInsideValueClass.fir.kt @@ -8,34 +8,34 @@ annotation class JvmInline @JvmInline value class IC1(val x: Any) { - fun box() {} - fun box(x: Any) {} + fun box() {} + fun box(x: Any) {} - fun unbox() {} - fun unbox(x: Any) {} + fun unbox() {} + fun unbox(x: Any) {} - override fun equals(other: Any?): Boolean = true - override fun hashCode(): Int = 0 + override fun equals(other: Any?): Boolean = true + override fun hashCode(): Int = 0 } @JvmInline value class IC2(val x: Any) { - fun box(x: Any) {} - fun box(): Any = TODO() + fun box(x: Any) {} + fun box(): Any = TODO() - fun unbox(x: Any) {} - fun unbox(): Any = TODO() + fun unbox(x: Any) {} + fun unbox(): Any = TODO() - fun equals(my: Any, other: Any): Boolean = true - fun hashCode(a: Any): Int = 0 + fun equals(my: Any, other: Any): Boolean = true + fun hashCode(a: Any): Int = 0 } @JvmInline value class IC3(val x: Any) { - fun box(x: Any): Any = TODO() - fun unbox(x: Any): Any = TODO() + fun box(x: Any): Any = TODO() + fun unbox(x: Any): Any = TODO() - fun equals(): Boolean = true + fun equals(): Boolean = true } interface WithBox { @@ -44,12 +44,12 @@ interface WithBox { @JvmInline value class IC4(val s: String) : WithBox { - override fun box(): String = "" + override fun box(): String = "" } @JvmInline value class IC5(val a: String) { - constructor(i: Int) : this(i.toString()) { + constructor(i: Int) : this(i.toString()) { TODO("something") - } + } } diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassCanOnlyImplementInterfaces.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassCanOnlyImplementInterfaces.fir.kt deleted file mode 100644 index 35a93cd7982..00000000000 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassCanOnlyImplementInterfaces.fir.kt +++ /dev/null @@ -1,21 +0,0 @@ -// !SKIP_JAVAC -// !LANGUAGE: +InlineClasses - -package kotlin.jvm - -annotation class JvmInline - -abstract class AbstractBaseClass - -open class OpenBaseClass - -interface BaseInterface - -@JvmInline -value class TestExtendsAbstractClass(val x: Int) : AbstractBaseClass() - -@JvmInline -value class TestExtendsOpenClass(val x: Int) : OpenBaseClass() - -@JvmInline -value class TestImplementsInterface(val x: Int) : BaseInterface diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassCanOnlyImplementInterfaces.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassCanOnlyImplementInterfaces.kt index 4550ffa6a89..438088b3c57 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassCanOnlyImplementInterfaces.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/valueClassCanOnlyImplementInterfaces.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !SKIP_JAVAC // !LANGUAGE: +InlineClasses diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassCannotImplementInterfaceByDelegation.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassCannotImplementInterfaceByDelegation.fir.kt index 40d22cb608a..dba6b02e2bf 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassCannotImplementInterfaceByDelegation.fir.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/valueClassCannotImplementInterfaceByDelegation.fir.kt @@ -10,7 +10,7 @@ interface IFoo object FooImpl : IFoo @JvmInline -value class Test1(val x: Any) : IFoo by FooImpl +value class Test1(val x: Any) : IFoo by FooImpl @JvmInline -value class Test2(val x: IFoo) : IFoo by x +value class Test2(val x: IFoo) : IFoo by x diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassDeclarationCheck.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassDeclarationCheck.fir.kt index a7683e9acda..e1a337da762 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassDeclarationCheck.fir.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/valueClassDeclarationCheck.fir.kt @@ -10,43 +10,43 @@ annotation class JvmInline value class A0(val x: Int) @JvmInline -value class A1 +value class A1 @JvmInline -value class A2() +value class A2() @JvmInline -value class A3(x: Int) +value class A3(x: Int) @JvmInline -value class A4(var x: Int) +value class A4(var x: Int) @JvmInline -value class A5(val x: Int, val y: Int) +value class A5(val x: Int, val y: Int) @JvmInline -value class A6(x: Int, val y: Int) +value class A6(x: Int, val y: Int) @JvmInline -value class A7(vararg val x: Int) +value class A7(vararg val x: Int) @JvmInline -value class A8(open val x: Int) +value class A8(open val x: Int) @JvmInline value class A9(final val x: Int) class B1 { companion object { @JvmInline - value class C1(val x: Int) + value class C1(val x: Int) } @JvmInline - value class C2(val x: Int) + value class C2(val x: Int) } object B2 { @JvmInline - value class C3(val x: Int) + value class C3(val x: Int) } @JvmInline final value class D0(val x: Int) -open value class D1(val x: Int) -abstract value class D2(val x: Int) -sealed value class D3(val x: Int) +open value class D1(val x: Int) +abstract value class D2(val x: Int) +sealed value class D3(val x: Int) value data class D4(val x: String) diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.fir.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.fir.kt deleted file mode 100644 index 55506c247b5..00000000000 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.fir.kt +++ /dev/null @@ -1,31 +0,0 @@ -// !SKIP_JAVAC -// !LANGUAGE: +InlineClasses - -package kotlin.jvm - -annotation class JvmInline - -@JvmInline -value class Foo(val x: T) -@JvmInline -value class FooNullable(val x: T?) - -@JvmInline -value class FooGenericArray(val x: Array) -@JvmInline -value class FooGenericArray2(val x: Array>) - -@JvmInline -value class FooStarProjectedArray(val x: Array<*>) -@JvmInline -value class FooStarProjectedArray2(val x: Array>) - -@JvmInline -value class Bar(val u: Unit) -@JvmInline -value class BarNullable(val u: Unit?) - -@JvmInline -value class Baz(val u: Nothing) -@JvmInline -value class BazNullable(val u: Nothing?) diff --git a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt b/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt index 532ed9867e1..0875ff51735 100644 --- a/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt +++ b/compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !SKIP_JAVAC // !LANGUAGE: +InlineClasses