Support properties from primary constructor in JvmFieldApplicabilityChecker

#KT-32753 In progress
This commit is contained in:
Him188
2021-03-31 19:37:49 +08:00
committed by TeamCityServer
parent e4ebeec275
commit f90cbb0ce7
12 changed files with 502 additions and 12 deletions
@@ -23,7 +23,9 @@ import org.jetbrains.kotlin.fileClasses.isInsideJvmMultifileClassFile
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtValueArgument
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -53,18 +55,18 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
}
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
if (descriptor !is PropertyDescriptor || declaration !is KtProperty) return
if (descriptor !is PropertyDescriptor || (declaration !is KtProperty && declaration !is KtParameter)) return
val annotation = descriptor.findJvmFieldAnnotation()
?: descriptor.delegateField?.annotations?.findAnnotation(JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME)
?: return
val problem = when {
declaration.hasDelegate() -> DELEGATE
declaration is KtProperty && declaration.hasDelegate() -> DELEGATE
!descriptor.hasBackingField(context.trace.bindingContext) -> return
descriptor.isOverridable -> NOT_FINAL
DescriptorVisibilities.isPrivate(descriptor.visibility) -> PRIVATE
declaration.hasCustomAccessor() -> CUSTOM_ACCESSOR
declaration is KtProperty && declaration.hasCustomAccessor() -> CUSTOM_ACCESSOR
descriptor.overriddenDescriptors.isNotEmpty() -> OVERRIDES
descriptor.isLateInit -> LATEINIT
descriptor.isConst -> CONST
@@ -83,7 +85,14 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
}
val annotationEntry = DescriptorToSourceUtils.getSourceFromAnnotation(annotation) ?: return
context.trace.report(ErrorsJvm.INAPPLICABLE_JVM_FIELD.on(annotationEntry, problem.errorMessage))
val factory =
if (declaration is KtParameter && !context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitJvmFieldOnOverrideFromInterfaceInPrimaryConstructor)) {
ErrorsJvm.INAPPLICABLE_JVM_FIELD_WARNING
} else {
ErrorsJvm.INAPPLICABLE_JVM_FIELD
}
context.trace.report(factory.on(annotationEntry, problem.errorMessage))
}
private fun isInterfaceCompanionWithPublicJvmFieldProperties(companionObject: ClassDescriptor): Boolean {
@@ -120,6 +120,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
MAP.put(UPPER_BOUND_CANNOT_BE_ARRAY, "Upper bound of a type parameter cannot be an array");
MAP.put(INAPPLICABLE_JVM_FIELD, "{0}", STRING);
MAP.put(INAPPLICABLE_JVM_FIELD_WARNING, "{0}. This warning will become an error in further releases", STRING);
MAP.put(JVM_SYNTHETIC_ON_DELEGATE, "'@JvmSynthetic' annotation cannot be used on delegated properties");
@@ -38,6 +38,7 @@ public interface ErrorsJvm {
DiagnosticFactory0<KtAnnotationEntry> ILLEGAL_JVM_NAME = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<KtAnnotationEntry, String> INAPPLICABLE_JVM_FIELD = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtAnnotationEntry, String> INAPPLICABLE_JVM_FIELD_WARNING = DiagnosticFactory1.create(WARNING);
DiagnosticFactory0<KtAnnotationEntry> JVM_SYNTHETIC_ON_DELEGATE = DiagnosticFactory0.create(ERROR);