[JVM] Introduce MF Value Classes to frontend
This commit is contained in:
committed by
Space
parent
c15b1ec001
commit
7595f798e1
@@ -400,12 +400,13 @@ public interface Errors {
|
||||
DiagnosticFactory0<PsiElement> NON_PRIVATE_CONSTRUCTOR_IN_SEALED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Inline classes
|
||||
// Inline classes, Value classes
|
||||
|
||||
DiagnosticFactory0<PsiElement> VALUE_CLASS_NOT_TOP_LEVEL = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> VALUE_CLASS_NOT_FINAL = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> ABSENCE_OF_PRIMARY_CONSTRUCTOR_FOR_VALUE_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtElement> INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtElement> VALUE_CLASS_EMPTY_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtParameter> VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtProperty> PROPERTY_WITH_BACKING_FIELD_INSIDE_VALUE_CLASS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<PsiElement> DELEGATED_PROPERTY_INSIDE_VALUE_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
+3
-2
@@ -755,8 +755,9 @@ public class DefaultErrorMessages {
|
||||
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(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(VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER, "Value class primary constructor must only have final read-only (val) property 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 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");
|
||||
MAP.put(VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE, "Value class cannot have value parameter of type ''{0}''", RENDER_TYPE);
|
||||
|
||||
+36
-19
@@ -80,31 +80,47 @@ object InlineClassDeclarationChecker : DeclarationChecker {
|
||||
return
|
||||
}
|
||||
|
||||
val baseParameter = primaryConstructor.valueParameters.singleOrNull()
|
||||
if (baseParameter == null) {
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ValueClasses)) {
|
||||
if (primaryConstructor.valueParameters.isEmpty()) {
|
||||
(primaryConstructor.valueParameterList ?: declaration).let {
|
||||
trace.report(Errors.VALUE_CLASS_EMPTY_CONSTRUCTOR.on(it))
|
||||
return
|
||||
}
|
||||
}
|
||||
} else if (primaryConstructor.valueParameters.size != 1) {
|
||||
(primaryConstructor.valueParameterList ?: declaration).let {
|
||||
trace.report(Errors.INLINE_CLASS_CONSTRUCTOR_WRONG_PARAMETERS_SIZE.on(it))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!isParameterAcceptableForInlineClass(baseParameter)) {
|
||||
trace.report(Errors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER.on(baseParameter))
|
||||
return
|
||||
var baseParametersOk = true
|
||||
for (baseParameter in primaryConstructor.valueParameters) {
|
||||
|
||||
if (!isParameterAcceptableForInlineClass(baseParameter)) {
|
||||
trace.report(Errors.VALUE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER.on(baseParameter))
|
||||
baseParametersOk = false
|
||||
continue
|
||||
}
|
||||
|
||||
val baseParameterType = descriptor.safeAs<ClassDescriptor>()?.defaultType?.substitutedUnderlyingType()
|
||||
val baseParameterTypeReference = baseParameter.typeReference
|
||||
if (baseParameterType != null && baseParameterTypeReference != null) {
|
||||
if (baseParameterType.isInapplicableParameterType()) {
|
||||
trace.report(Errors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE.on(baseParameterTypeReference, baseParameterType))
|
||||
baseParametersOk = false
|
||||
continue
|
||||
}
|
||||
|
||||
if (baseParameterType.isRecursiveInlineClassType()) { // todo check work for MF VC
|
||||
trace.report(Errors.VALUE_CLASS_CANNOT_BE_RECURSIVE.on(baseParameterTypeReference))
|
||||
baseParametersOk = false
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val baseParameterType = descriptor.safeAs<ClassDescriptor>()?.defaultType?.substitutedUnderlyingType()
|
||||
val baseParameterTypeReference = baseParameter.typeReference
|
||||
if (baseParameterType != null && baseParameterTypeReference != null) {
|
||||
if (baseParameterType.isInapplicableParameterType()) {
|
||||
trace.report(Errors.VALUE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE.on(baseParameterTypeReference, baseParameterType))
|
||||
return
|
||||
}
|
||||
|
||||
if (baseParameterType.isRecursiveInlineClassType()) {
|
||||
trace.report(Errors.VALUE_CLASS_CANNOT_BE_RECURSIVE.on(baseParameterTypeReference))
|
||||
return
|
||||
}
|
||||
if (!baseParametersOk) {
|
||||
return
|
||||
}
|
||||
|
||||
for (supertypeEntry in declaration.superTypeListEntries) {
|
||||
@@ -129,7 +145,8 @@ object InlineClassDeclarationChecker : DeclarationChecker {
|
||||
}
|
||||
|
||||
if (descriptor.getAllSuperClassifiers().any {
|
||||
it.fqNameUnsafe == StandardNames.FqNames.cloneable || it.fqNameUnsafe == javaLangCloneable }
|
||||
it.fqNameUnsafe == StandardNames.FqNames.cloneable || it.fqNameUnsafe == javaLangCloneable
|
||||
}
|
||||
) {
|
||||
trace.report(Errors.VALUE_CLASS_CANNOT_BE_CLONEABLE.on(inlineOrValueKeyword))
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user