Extract JvmNames, JvmFieldApplicabilityProblem to compiler.common

This commit is contained in:
Ivan Kochurkin
2021-09-08 16:04:57 +03:00
committed by TeamCityServer
parent d4746903c8
commit e3805c9b98
7 changed files with 59 additions and 34 deletions
@@ -25,6 +25,10 @@ import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialize
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.JvmNames.JVM_MULTIFILE_CLASS_SHORT
import org.jetbrains.kotlin.name.JvmNames.JVM_NAME_SHORT
import org.jetbrains.kotlin.name.JvmNames.JVM_PACKAGE_NAME_SHORT
import org.jetbrains.kotlin.name.JvmNames.MULTIFILE_PART_NAME_DELIMITER
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -36,14 +40,6 @@ object JvmFileClassUtil {
val JVM_NAME: FqName = FqName("kotlin.jvm.JvmName")
val JVM_NAME_SHORT: String = JVM_NAME.shortName().asString()
val JVM_MULTIFILE_CLASS: FqName = FqName("kotlin.jvm.JvmMultifileClass")
val JVM_MULTIFILE_CLASS_SHORT = JVM_MULTIFILE_CLASS.shortName().asString()
val JVM_PACKAGE_NAME: FqName = FqName("kotlin.jvm.JvmPackageName")
private val JVM_PACKAGE_NAME_SHORT = JVM_PACKAGE_NAME.shortName().asString()
private const val MULTIFILE_PART_NAME_DELIMITER = "__"
fun getPartFqNameForDeserialized(descriptor: DeserializedMemberDescriptor): FqName =
descriptor.getImplClassNameForDeserialized()?.fqNameForTopLevelClassMaybeWithDollars
?: error("No implClassName for $descriptor")
@@ -138,7 +134,7 @@ val KtFile.javaFileFacadeFqName: FqName
private val LOG = Logger.getInstance("JvmFileClassUtil")
fun KtDeclaration.isInsideJvmMultifileClassFile() =
JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(containingKtFile, JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT) != null
JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(containingKtFile, JVM_MULTIFILE_CLASS_SHORT) != null
fun DeclarationDescriptor.isTopLevelInJvmMultifileClass(): Boolean {
if (containingDeclaration !is PackageFragmentDescriptor) return false
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.name.JvmNames.JVM_MULTIFILE_CLASS
import org.jetbrains.kotlin.name.JvmNames.JVM_NAME
import org.jetbrains.kotlin.name.JvmNames.JVM_PACKAGE_NAME
import org.jetbrains.kotlin.name.isValidJavaFqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
@@ -35,7 +37,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
object FileClassAnnotationsChecker : AdditionalAnnotationChecker {
// JvmName & JvmMultifileClass annotations are applicable to multi-file class parts regardless of their retention.
private val alwaysApplicable = hashSetOf(JvmFileClassUtil.JVM_NAME, JvmFileClassUtil.JVM_MULTIFILE_CLASS)
private val alwaysApplicable = hashSetOf(JVM_NAME, JVM_MULTIFILE_CLASS)
override fun checkEntries(
entries: List<KtAnnotationEntry>,
@@ -55,7 +57,7 @@ object FileClassAnnotationsChecker : AdditionalAnnotationChecker {
fileAnnotationsToCheck.add(Pair(entry, classDescriptor))
}
val isMultifileClass = fileAnnotationsToCheck.any { it.second.fqNameSafe == JvmFileClassUtil.JVM_MULTIFILE_CLASS }
val isMultifileClass = fileAnnotationsToCheck.any { it.second.fqNameSafe == JVM_MULTIFILE_CLASS }
if (isMultifileClass) {
for ((entry, classDescriptor) in fileAnnotationsToCheck) {
@@ -67,7 +69,7 @@ object FileClassAnnotationsChecker : AdditionalAnnotationChecker {
}
} else {
for ((entry, classDescriptor) in fileAnnotationsToCheck) {
if (classDescriptor.fqNameSafe != JvmFileClassUtil.JVM_PACKAGE_NAME) continue
if (classDescriptor.fqNameSafe != JVM_PACKAGE_NAME) continue
val argumentExpression = entry.valueArguments.firstOrNull()?.getArgumentExpression() ?: continue
val stringTemplateEntries = (argumentExpression as? KtStringTemplateExpression)?.entries ?: continue
@@ -32,28 +32,13 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmFieldAnnotation
import org.jetbrains.kotlin.resolve.jvm.checkers.JvmFieldApplicabilityChecker.Problem.*
import org.jetbrains.kotlin.jvm.JvmFieldApplicabilityProblem.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.resolve.jvm.isInlineClassThatRequiresMangling
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope
class JvmFieldApplicabilityChecker : DeclarationChecker {
internal enum class Problem(val errorMessage: String) {
NOT_FINAL("JvmField can only be applied to final property"),
PRIVATE("JvmField has no effect on a private property"),
CUSTOM_ACCESSOR("JvmField cannot be applied to a property with a custom accessor"),
OVERRIDES("JvmField cannot be applied to a property that overrides some other property"),
LATEINIT("JvmField cannot be applied to lateinit property"),
CONST("JvmField cannot be applied to const property"),
INSIDE_COMPANION_OF_INTERFACE("JvmField cannot be applied to a property defined in companion object of interface"),
NOT_PUBLIC_VAL_WITH_JVMFIELD("JvmField could be applied only if all interface companion properties are 'public final val' with '@JvmField' annotation"),
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE("JvmField cannot be applied to top level property of a file annotated with ${JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT}"),
DELEGATE("JvmField cannot be applied to delegated property"),
RETURN_TYPE_IS_INLINE_CLASS("JvmField cannot be applied to a property of an inline class type")
}
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
if (descriptor !is PropertyDescriptor || (declaration !is KtProperty && declaration !is KtParameter)) return