Value classes: Add JvmInlineValueClasses language feature
This commit is contained in:
@@ -119,8 +119,7 @@ object ModifierCheckerCore {
|
||||
EXPECT_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
ACTUAL_KEYWORD to listOf(LanguageFeature.MultiPlatformProjects),
|
||||
LATEINIT_KEYWORD to listOf(LanguageFeature.LateinitTopLevelProperties, LanguageFeature.LateinitLocalVariables),
|
||||
FUN_KEYWORD to listOf(LanguageFeature.FunctionalInterfaceConversion),
|
||||
VALUE_KEYWORD to listOf(LanguageFeature.InlineClasses)
|
||||
FUN_KEYWORD to listOf(LanguageFeature.FunctionalInterfaceConversion)
|
||||
)
|
||||
|
||||
private val featureDependenciesTargets = mapOf(
|
||||
@@ -128,6 +127,7 @@ object ModifierCheckerCore {
|
||||
LanguageFeature.LateinitLocalVariables to setOf(LOCAL_VARIABLE),
|
||||
LanguageFeature.LateinitTopLevelProperties to setOf(TOP_LEVEL_PROPERTY),
|
||||
LanguageFeature.InlineClasses to setOf(CLASS_ONLY),
|
||||
LanguageFeature.JvmInlineValueClasses to setOf(CLASS_ONLY),
|
||||
LanguageFeature.FunctionalInterfaceConversion to setOf(INTERFACE)
|
||||
)
|
||||
|
||||
|
||||
+21
-3
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
@@ -32,11 +33,28 @@ object InlineClassDeclarationChecker : DeclarationChecker {
|
||||
if (descriptor !is ClassDescriptor || !descriptor.isInline && !descriptor.isValue) return
|
||||
if (descriptor.kind != ClassKind.CLASS) return
|
||||
|
||||
val inlineOrValueKeyword = declaration.modifierList?.getModifier(KtTokens.INLINE_KEYWORD)
|
||||
?: declaration.modifierList?.getModifier(KtTokens.VALUE_KEYWORD)
|
||||
val trace = context.trace
|
||||
|
||||
val valueKeyword = declaration.modifierList?.getModifier(KtTokens.VALUE_KEYWORD)
|
||||
|
||||
// The check cannot be done in ModifierCheckerCore, since `value` keyword is enabled by one of two features, not by both of
|
||||
// them simultaneously
|
||||
if (valueKeyword != null) {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.JvmInlineValueClasses) &&
|
||||
!context.languageVersionSettings.supportsFeature(LanguageFeature.InlineClasses)
|
||||
) {
|
||||
trace.report(
|
||||
Errors.UNSUPPORTED_FEATURE.on(
|
||||
valueKeyword, LanguageFeature.JvmInlineValueClasses to context.languageVersionSettings
|
||||
)
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val inlineOrValueKeyword = declaration.modifierList?.getModifier(KtTokens.INLINE_KEYWORD) ?: valueKeyword
|
||||
require(inlineOrValueKeyword != null) { "Declaration of inline class must have 'inline' keyword" }
|
||||
|
||||
val trace = context.trace
|
||||
if (descriptor.isInner || DescriptorUtils.isLocal(descriptor)) {
|
||||
trace.report(Errors.INLINE_CLASS_NOT_TOP_LEVEL.on(inlineOrValueKeyword))
|
||||
return
|
||||
|
||||
+2
-1
@@ -21,7 +21,8 @@ class ResultClassInReturnTypeChecker : DeclarationChecker {
|
||||
val languageVersionSettings = context.languageVersionSettings
|
||||
if (
|
||||
languageVersionSettings.getFlag(AnalysisFlags.allowResultReturnType) ||
|
||||
languageVersionSettings.getFeatureSupport(LanguageFeature.InlineClasses) == LanguageFeature.State.ENABLED &&
|
||||
(languageVersionSettings.getFeatureSupport(LanguageFeature.InlineClasses) == LanguageFeature.State.ENABLED ||
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.JvmInlineValueClasses)) &&
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.AllowResultInReturnType)
|
||||
) return
|
||||
|
||||
|
||||
+1
-1
@@ -13,4 +13,4 @@ annotation class JvmInline
|
||||
<!VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION, WRONG_MODIFIER_TARGET!>value<!> enum class InlineEnum
|
||||
|
||||
@JvmInline
|
||||
<!UNSUPPORTED_FEATURE!>value<!> class NotVal(<!INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER!>x: Int<!>)
|
||||
<!UNSUPPORTED_FEATURE!>value<!> class NotVal(x: Int)
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// !LANGUAGE: +JvmInlineValueClasses
|
||||
// WITH_RUNTIME
|
||||
|
||||
package kotlin.jvm
|
||||
|
||||
annotation class JvmInline
|
||||
|
||||
@JvmInline
|
||||
value class VC(val a: Any)
|
||||
@@ -0,0 +1,23 @@
|
||||
package
|
||||
|
||||
package kotlin {
|
||||
|
||||
package kotlin.jvm {
|
||||
|
||||
public final annotation class JvmInline : kotlin.Annotation {
|
||||
public constructor JvmInline()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmInline public final value class VC {
|
||||
public constructor VC(/*0*/ a: kotlin.Any)
|
||||
public final val a: kotlin.Any
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -43,6 +43,12 @@ public class DiagnosticsTestWithJvmIrBackendGenerated extends AbstractDiagnostic
|
||||
runTest("compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented_ir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noWarningInLV1_5.kt")
|
||||
public void testNoWarningInLV1_5() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendInlineCycle_ir.kt")
|
||||
public void testSuspendInlineCycle_ir() throws Exception {
|
||||
|
||||
+6
@@ -43,6 +43,12 @@ public class DiagnosticsTestWithOldJvmBackendGenerated extends AbstractDiagnosti
|
||||
runTest("compiler/testData/diagnostics/testsWithJvmBackend/multipleBigArityFunsImplemented.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("noWarningInLV1_5.kt")
|
||||
public void testNoWarningInLV1_5() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithJvmBackend/noWarningInLV1_5.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suspendInlineCycle.kt")
|
||||
public void testSuspendInlineCycle() throws Exception {
|
||||
|
||||
@@ -194,6 +194,7 @@ enum class LanguageFeature(
|
||||
// Next features can be enabled regardless of new inference
|
||||
|
||||
InlineClasses(sinceVersion = KOTLIN_1_3, defaultState = State.ENABLED_WITH_WARNING, kind = UNSTABLE_FEATURE),
|
||||
JvmInlineValueClasses(sinceVersion = KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER),
|
||||
;
|
||||
|
||||
val presentableName: String
|
||||
|
||||
Reference in New Issue
Block a user