Value classes: Allow nested inline classes

This commit is contained in:
Ilmir Usmanov
2020-11-25 17:59:07 +01:00
parent 235813736e
commit 15c325cf10
15 changed files with 113 additions and 8 deletions
@@ -14157,6 +14157,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -704,7 +704,7 @@ public class DefaultErrorMessages {
MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_ENUM, "Constructor must be private in enum class");
MAP.put(NON_PRIVATE_CONSTRUCTOR_IN_SEALED, "Constructor must be private in sealed class");
MAP.put(INLINE_CLASS_NOT_TOP_LEVEL, "Inline classes are only allowed on top level");
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");
@@ -29,7 +29,7 @@ object InlineClassDeclarationChecker : DeclarationChecker {
require(inlineOrValueKeyword != null) { "Declaration of inline class must have 'inline' keyword" }
val trace = context.trace
if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) {
if (descriptor.isInner || DescriptorUtils.isLocal(descriptor)) {
trace.report(Errors.INLINE_CLASS_NOT_TOP_LEVEL.on(inlineOrValueKeyword))
return
}
@@ -0,0 +1,25 @@
// !LANGUAGE: +InlineClasses
class C {
inline class IC1(val s: String)
companion object {
inline class IC2(val s: String)
}
}
object O {
inline class IC3(val s: String)
}
interface I {
inline class IC4(val s: String)
}
fun box(): String {
if (C.IC1("OK").s != "OK") return "FAIL 1"
if (C.Companion.IC2("OK").s != "OK") return "FAIL 2"
if (O.IC3("OK").s != "OK") return "FAIL 3"
if (I.IC4("OK").s != "OK") return "FAIL 4"
return "OK"
}
@@ -16,13 +16,20 @@ 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 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)
}
fun foo() {
inline class C4(val x: Int)
}
final inline class D0(val x: Int)
@@ -15,14 +15,21 @@ inline class A9(final val x: Int)
class B1 {
companion object {
<!INLINE_CLASS_NOT_TOP_LEVEL!>inline<!> class C1(val x: Int)
inline class C1(val x: Int)
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>inner<!> inline class C11(val x: Int)
}
<!INLINE_CLASS_NOT_TOP_LEVEL!>inline<!> class C2(val x: Int)
inline class C2(val x: Int)
inner <!INLINE_CLASS_NOT_TOP_LEVEL!>inline<!> class C21(val x: Int)
}
object B2 {
<!INLINE_CLASS_NOT_TOP_LEVEL!>inline<!> class C3(val x: Int)
inline class C3(val x: Int)
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>inner<!> inline class C31(val x: Int)
}
fun foo() {
<!INLINE_CLASS_NOT_TOP_LEVEL, WRONG_MODIFIER_TARGET!>inline<!> class C4(val x: Int)
}
final inline class D0(val x: Int)
@@ -1,5 +1,7 @@
package
public fun foo(): kotlin.Unit
public final inline class A0 {
public constructor A0(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
@@ -92,6 +94,14 @@ public final class B1 {
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
public final inner inline class C21 {
public constructor C21(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
public companion object Companion {
private constructor Companion()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@@ -105,6 +115,14 @@ public final class B1 {
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
public final inline class C11 {
public constructor C11(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
}
}
@@ -121,6 +139,14 @@ public object B2 {
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
public final inline class C31 {
public constructor C31(/*0*/ x: kotlin.Int)
public final val x: kotlin.Int
public open override /*1*/ /*synthesized*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*synthesized*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*synthesized*/ fun toString(): kotlin.String
}
}
public final inline class D0 {
@@ -30,16 +30,16 @@ value class A9(final val x: Int)
class B1 {
companion object {
@JvmInline
<!INLINE_CLASS_NOT_TOP_LEVEL!>value<!> class C1(val x: Int)
value class C1(val x: Int)
}
@JvmInline
<!INLINE_CLASS_NOT_TOP_LEVEL!>value<!> class C2(val x: Int)
value class C2(val x: Int)
}
object B2 {
@JvmInline
<!INLINE_CLASS_NOT_TOP_LEVEL!>value<!> class C3(val x: Int)
value class C3(val x: Int)
}
@JvmInline
@@ -15557,6 +15557,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -15567,6 +15567,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineClasses/mappingOfBoxedFlexibleInlineClassType.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -14157,6 +14157,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -12152,6 +12152,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -12152,6 +12152,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -12217,6 +12217,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineClasses/multifileClass.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");
@@ -6627,6 +6627,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/inlineClasses/mangledSuperCalls.kt");
}
@TestMetadata("nestedInlineClass.kt")
public void testNestedInlineClass() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/nestedInlineClass.kt");
}
@TestMetadata("noAssertionsOnInlineClassBasedOnNullableType.kt")
public void testNoAssertionsOnInlineClassBasedOnNullableType() throws Exception {
runTest("compiler/testData/codegen/box/inlineClasses/noAssertionsOnInlineClassBasedOnNullableType.kt");