[JVM] Introduce MF Value Classes to frontend
This commit is contained in:
committed by
Space
parent
c15b1ec001
commit
7595f798e1
+13
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.test.runners;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -32113,6 +32114,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveMultiFieldValueClasses.kt")
|
||||
public void testRecursiveMultiFieldValueClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/valueClasses/recursiveMultiFieldValueClasses.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveValueClasses.kt")
|
||||
public void testRecursiveValueClasses() throws Exception {
|
||||
@@ -32167,6 +32174,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassWithForbiddenUnderlyingTypeMultiField.kt")
|
||||
public void testValueClassWithForbiddenUnderlyingTypeMultiField() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingTypeMultiField.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassesInsideAnnotations.kt")
|
||||
public void testValueClassesInsideAnnotations() throws Exception {
|
||||
|
||||
+13
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.test.runners;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.utils.TransformersFunctions;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -32113,6 +32114,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/valueClasses/propertiesWithBackingFieldsInsideValueClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveMultiFieldValueClasses.kt")
|
||||
public void testRecursiveMultiFieldValueClasses() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/valueClasses/recursiveMultiFieldValueClasses.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("recursiveValueClasses.kt")
|
||||
public void testRecursiveValueClasses() throws Exception {
|
||||
@@ -32167,6 +32174,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassWithForbiddenUnderlyingTypeMultiField.kt")
|
||||
public void testValueClassWithForbiddenUnderlyingTypeMultiField() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/valueClasses/valueClassWithForbiddenUnderlyingTypeMultiField.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("valueClassesInsideAnnotations.kt")
|
||||
public void testValueClassesInsideAnnotations() throws Exception {
|
||||
|
||||
+1
@@ -405,6 +405,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val VALUE_CLASS_NOT_FINAL by error<KtDeclaration>(PositioningStrategy.MODALITY_MODIFIER)
|
||||
val ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_VALUE_CLASS by error<KtDeclaration>(PositioningStrategy.INLINE_OR_VALUE_MODIFIER)
|
||||
val INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE by error<KtElement>()
|
||||
val VALUE_CLASS_EMPTY_CONSTRUCTOR by error<KtElement>()
|
||||
val VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER by error<KtParameter>()
|
||||
val PROPERTY_WITH_BACKING_FIELD_INSIDE_VALUE_CLASS by error<KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
|
||||
val DELEGATED_PROPERTY_INSIDE_VALUE_CLASS by error<PsiElement>()
|
||||
|
||||
@@ -306,6 +306,7 @@ object FirErrors {
|
||||
val VALUE_CLASS_NOT_FINAL by error0<KtDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
||||
val ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_VALUE_CLASS by error0<KtDeclaration>(SourceElementPositioningStrategies.INLINE_OR_VALUE_MODIFIER)
|
||||
val INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE by error0<KtElement>()
|
||||
val VALUE_CLASS_EMPTY_CONSTRUCTOR by error0<KtElement>()
|
||||
val VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER by error0<KtParameter>()
|
||||
val PROPERTY_WITH_BACKING_FIELD_INSIDE_VALUE_CLASS by error0<KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
|
||||
val DELEGATED_PROPERTY_INSIDE_VALUE_CLASS by error0<PsiElement>()
|
||||
|
||||
+44
-31
@@ -15,18 +15,21 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.hasModifier
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOnWithSuppression
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.withSuppressedDiagnostics
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableReference
|
||||
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
|
||||
object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
|
||||
@@ -60,8 +63,9 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
|
||||
}
|
||||
|
||||
var primaryConstructor: FirConstructor? = null
|
||||
var primaryConstructorParameter: FirValueParameter? = null
|
||||
var primaryConstructorProperty: FirProperty? = null
|
||||
var primaryConstructorParametersByName = mapOf<Name, FirValueParameter>()
|
||||
val primaryConstructorPropertiesByName = mutableMapOf<Name, FirProperty>()
|
||||
var primaryConstructorParametersSymbolsSet = setOf<FirValueParameterSymbol>()
|
||||
|
||||
for (innerDeclaration in declaration.declarations) {
|
||||
when (innerDeclaration) {
|
||||
@@ -69,7 +73,9 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
|
||||
when {
|
||||
innerDeclaration.isPrimary -> {
|
||||
primaryConstructor = innerDeclaration
|
||||
primaryConstructorParameter = innerDeclaration.valueParameters.singleOrNull()
|
||||
primaryConstructorParametersByName = innerDeclaration.valueParameters.associateBy { it.name }
|
||||
primaryConstructorParametersSymbolsSet =
|
||||
primaryConstructorParametersByName.map { (_, parameter) -> parameter.symbol }.toSet()
|
||||
}
|
||||
|
||||
innerDeclaration.body != null -> {
|
||||
@@ -100,7 +106,7 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
|
||||
if (innerDeclaration.isSynthetic) {
|
||||
val symbol = innerDeclaration.initializer?.toResolvedCallableSymbol()
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.InlineClassImplementationByDelegation) &&
|
||||
symbol != null && symbol == primaryConstructorParameter?.symbol
|
||||
symbol != null && symbol in primaryConstructorParametersSymbolsSet
|
||||
) {
|
||||
continue
|
||||
}
|
||||
@@ -115,8 +121,8 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
|
||||
}
|
||||
}
|
||||
is FirProperty -> {
|
||||
if (innerDeclaration.isRelatedToParameter(primaryConstructorParameter)) {
|
||||
primaryConstructorProperty = innerDeclaration
|
||||
if (innerDeclaration.isRelatedToParameter(primaryConstructorParametersByName[innerDeclaration.name])) {
|
||||
primaryConstructorPropertiesByName[innerDeclaration.name] = innerDeclaration
|
||||
} else {
|
||||
when {
|
||||
innerDeclaration.delegate != null ->
|
||||
@@ -147,35 +153,42 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
|
||||
return
|
||||
}
|
||||
|
||||
if (primaryConstructorParameter == null) {
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses)) {
|
||||
if (primaryConstructorParametersByName.isEmpty()) {
|
||||
reporter.reportOnWithSuppression(primaryConstructor, FirErrors.VALUE_CLASS_EMPTY_CONSTRUCTOR, context)
|
||||
return
|
||||
}
|
||||
} else if (primaryConstructorParametersByName.size != 1) {
|
||||
reporter.reportOnWithSuppression(primaryConstructor, FirErrors.INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, context)
|
||||
return
|
||||
}
|
||||
|
||||
withSuppressedDiagnostics(primaryConstructor, context) { context ->
|
||||
withSuppressedDiagnostics(primaryConstructorParameter, context) { context ->
|
||||
when {
|
||||
primaryConstructorParameter.isNotFinalReadOnly(primaryConstructorProperty) ->
|
||||
reporter.reportOn(
|
||||
primaryConstructorParameter.source,
|
||||
FirErrors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER,
|
||||
context
|
||||
)
|
||||
for ((name, primaryConstructorParameter) in primaryConstructorParametersByName) {
|
||||
withSuppressedDiagnostics(primaryConstructor, context) { context ->
|
||||
withSuppressedDiagnostics(primaryConstructorParameter, context) { context ->
|
||||
when {
|
||||
primaryConstructorParameter.isNotFinalReadOnly(primaryConstructorPropertiesByName[name]) ->
|
||||
reporter.reportOn(
|
||||
primaryConstructorParameter.source,
|
||||
FirErrors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER,
|
||||
context
|
||||
)
|
||||
|
||||
primaryConstructorParameter.returnTypeRef.isInapplicableParameterType() ->
|
||||
reporter.reportOn(
|
||||
primaryConstructorParameter.returnTypeRef.source,
|
||||
FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE,
|
||||
primaryConstructorParameter.returnTypeRef.coneType,
|
||||
context
|
||||
)
|
||||
primaryConstructorParameter.returnTypeRef.isInapplicableParameterType() ->
|
||||
reporter.reportOn(
|
||||
primaryConstructorParameter.returnTypeRef.source,
|
||||
FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE,
|
||||
primaryConstructorParameter.returnTypeRef.coneType,
|
||||
context
|
||||
)
|
||||
|
||||
primaryConstructorParameter.returnTypeRef.coneType.isRecursiveInlineClassType(context.session) ->
|
||||
reporter.reportOnWithSuppression(
|
||||
primaryConstructorParameter.returnTypeRef,
|
||||
FirErrors.VALUE_CLASS_CANNOT_BE_RECURSIVE,
|
||||
context
|
||||
)
|
||||
primaryConstructorParameter.returnTypeRef.coneType.isRecursiveInlineClassType(context.session) ->
|
||||
reporter.reportOnWithSuppression(
|
||||
primaryConstructorParameter.returnTypeRef,
|
||||
FirErrors.VALUE_CLASS_CANNOT_BE_RECURSIVE,
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -534,6 +534,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNO
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_EXTEND_CLASSES
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_EMPTY_CONSTRUCTOR
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_NOT_FINAL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_NOT_TOP_LEVEL
|
||||
@@ -1150,13 +1151,14 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
||||
)
|
||||
|
||||
// Value classes
|
||||
map.put(VALUE_CLASS_NOT_TOP_LEVEL, "Value classes cannot be local or inner")
|
||||
map.put(VALUE_CLASS_NOT_FINAL, "Value classes can be only final")
|
||||
map.put(VALUE_CLASS_NOT_TOP_LEVEL, "Value class cannot be local or inner")
|
||||
map.put(VALUE_CLASS_NOT_FINAL, "Value class can be only final")
|
||||
map.put(ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_VALUE_CLASS, "Primary constructor is required for value class")
|
||||
map.put(INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, "Inline class must have exactly one primary constructor parameter") // +
|
||||
map.put(INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE, "Inline class must have exactly one primary constructor parameter")
|
||||
map.put(VALUE_CLASS_EMPTY_CONSTRUCTOR, "Value class must have at least one primary constructor parameter")
|
||||
map.put(
|
||||
VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER,
|
||||
"Value class primary constructor must only have final read-only (val) property parameter"
|
||||
"Value class primary constructor must only have final read-only (val) property parameters"
|
||||
)
|
||||
map.put(PROPERTY_WITH_BACKING_FIELD_INSIDE_VALUE_CLASS, "Value class cannot have properties with backing fields")
|
||||
map.put(DELEGATED_PROPERTY_INSIDE_VALUE_CLASS, "Value class cannot have delegated properties")
|
||||
|
||||
+22
@@ -47482,6 +47482,28 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/valueClasses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class ValueClasses {
|
||||
@Test
|
||||
public void testAllFilesPresentInValueClasses() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/valueClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equality.kt")
|
||||
public void testEquality() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/equality.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("equality.kt")
|
||||
public void testEquality_valueClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/valueClasses/equality.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation());
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/box/vararg")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
Reference in New Issue
Block a user