From 16c5fb6f6b61e5adddc3ef3d8c08dd4587f408fc Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 5 Sep 2017 14:36:39 +0300 Subject: [PATCH] Refactor and simplify JvmFileClassUtil --- .../codegen/state/KotlinTypeMapper.java | 3 +- .../kotlin/fileClasses/JvmFileClassUtil.kt | 79 +++++++------------ .../NoResolveFileClassesProvider.kt | 5 +- .../kotlin/resolve/jvm/JvmOverloadFilter.kt | 7 +- 4 files changed, 35 insertions(+), 59 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java index 8b3b4fe6c86..2753ae52c05 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.java @@ -49,6 +49,7 @@ import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion; import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; +import org.jetbrains.kotlin.load.java.descriptors.UtilKt; import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment; import org.jetbrains.kotlin.load.kotlin.*; import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider.IncrementalMultifileClassPackageFragment; @@ -330,7 +331,7 @@ public class KotlinTypeMapper { return new ContainingClassesInfo(FAKE_CLASS_ID_FOR_BUILTINS, FAKE_CLASS_ID_FOR_BUILTINS); } - Name implClassName = JvmFileClassUtil.getImplClassName(descriptor); + Name implClassName = UtilKt.getImplClassNameForDeserialized(descriptor); assert implClassName != null : "No implClassName for " + descriptor; String implSimpleName = implClassName.asString(); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/JvmFileClassUtil.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/JvmFileClassUtil.kt index f293fecaf4e..c9b3276c942 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/JvmFileClassUtil.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/JvmFileClassUtil.kt @@ -18,14 +18,12 @@ package org.jetbrains.kotlin.fileClasses import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor object JvmFileClassUtil { @@ -35,46 +33,36 @@ object JvmFileClassUtil { val JVM_MULTIFILE_CLASS: FqName = FqName("kotlin.jvm.JvmMultifileClass") val JVM_MULTIFILE_CLASS_SHORT = JVM_MULTIFILE_CLASS.shortName().asString() - const val MULTIFILE_PART_NAME_DELIMITER = "__" + private const val MULTIFILE_PART_NAME_DELIMITER = "__" - internal fun getFileClassInfo(file: KtFile, jvmFileClassAnnotations: ParsedJvmFileClassAnnotations?): JvmFileClassInfo = - if (jvmFileClassAnnotations != null) - getFileClassInfoForAnnotation(file, jvmFileClassAnnotations) - else - getDefaultFileClassInfo(file) - - private fun getFileClassInfoForAnnotation(file: KtFile, jvmFileClassAnnotations: ParsedJvmFileClassAnnotations): JvmFileClassInfo = - if (jvmFileClassAnnotations.multipleFiles) - JvmMultifileClassPartInfo(getHiddenPartFqName(file, jvmFileClassAnnotations), - getFacadeFqName(file, jvmFileClassAnnotations)) - else - JvmSimpleFileClassInfo(getFacadeFqName(file, jvmFileClassAnnotations), true) - - @JvmStatic fun getDefaultFileClassInfo(file: KtFile): JvmFileClassInfo = - JvmSimpleFileClassInfo(PackagePartClassUtils.getPackagePartFqName(file.packageFqName, file.name), false) - - private fun getFacadeFqName(file: KtFile, jvmFileClassAnnotations: ParsedJvmFileClassAnnotations): FqName = - file.packageFqName.child(Name.identifier(jvmFileClassAnnotations.name)) - - @JvmStatic fun getPartFqNameForDeserialized(deserializedMemberDescriptor: DeserializedMemberDescriptor): FqName { - val implClassName = getImplClassName(deserializedMemberDescriptor) ?: error("No implClassName for $deserializedMemberDescriptor") - val packageFqName = (deserializedMemberDescriptor.containingDeclaration as PackageFragmentDescriptor).fqName - return packageFqName.child(implClassName) + fun getPartFqNameForDeserialized(descriptor: DeserializedMemberDescriptor): FqName { + val implClassName = descriptor.getImplClassNameForDeserialized() ?: error("No implClassName for $descriptor") + return (descriptor.containingDeclaration as PackageFragmentDescriptor).fqName.child(implClassName) } - @JvmStatic fun getImplClassName(deserializedMemberDescriptor: DeserializedMemberDescriptor): Name? = - deserializedMemberDescriptor.getImplClassNameForDeserialized() - - private fun getHiddenPartFqName(file: KtFile, jvmFileClassAnnotations: ParsedJvmFileClassAnnotations): FqName = - file.packageFqName.child(Name.identifier(manglePartName(jvmFileClassAnnotations.name, file.name))) - - @JvmStatic fun manglePartName(facadeName: String, fileName: String): String = + private fun manglePartName(facadeName: String, fileName: String): String = "$facadeName$MULTIFILE_PART_NAME_DELIMITER${PackagePartClassUtils.getFilePartShortName(fileName)}" - @JvmStatic fun getFileClassInfoNoResolve(file: KtFile): JvmFileClassInfo = - getFileClassInfo(file, parseJvmNameOnFileNoResolve(file)) + @JvmStatic + fun getFileClassInfoNoResolve(file: KtFile): JvmFileClassInfo { + val parsedAnnotations = parseJvmNameOnFileNoResolve(file) + val packageFqName = file.packageFqName + return when { + parsedAnnotations != null -> { + val facadeClassFqName = packageFqName.child(Name.identifier(parsedAnnotations.jvmName)) + when { + parsedAnnotations.isMultifileClass -> JvmMultifileClassPartInfo( + fileClassFqName = packageFqName.child(Name.identifier(manglePartName(parsedAnnotations.jvmName, file.name))), + facadeClassFqName = facadeClassFqName + ) + else -> JvmSimpleFileClassInfo(facadeClassFqName, true) + } + } + else -> JvmSimpleFileClassInfo(PackagePartClassUtils.getPackagePartFqName(packageFqName, file.name), false) + } + } - internal fun parseJvmNameOnFileNoResolve(file: KtFile): ParsedJvmFileClassAnnotations? { + private fun parseJvmNameOnFileNoResolve(file: KtFile): ParsedJvmFileClassAnnotations? { val jvmName = findAnnotationEntryOnFileNoResolve(file, JVM_NAME_SHORT) ?: return null val nameExpr = jvmName.valueArguments.firstOrNull()?.getArgumentExpression() ?: return null val name = getLiteralStringFromRestrictedConstExpression(nameExpr) ?: return null @@ -83,29 +71,20 @@ object JvmFileClassUtil { return ParsedJvmFileClassAnnotations(name, isMultifileClassPart) } - @JvmStatic fun findAnnotationEntryOnFileNoResolve(file: KtFile, shortName: String): KtAnnotationEntry? = + @JvmStatic + fun findAnnotationEntryOnFileNoResolve(file: KtFile, shortName: String): KtAnnotationEntry? = file.fileAnnotationList?.annotationEntries?.firstOrNull { it.calleeExpression?.constructorReferenceExpression?.getReferencedName() == shortName } - @JvmStatic private fun getLiteralStringFromRestrictedConstExpression(argumentExpression: KtExpression?): String? { + private fun getLiteralStringFromRestrictedConstExpression(argumentExpression: KtExpression?): String? { val stringTemplate = argumentExpression as? KtStringTemplateExpression ?: return null - val stringTemplateEntries = stringTemplate.entries - if (stringTemplateEntries.size != 1) return null - val singleEntry = stringTemplateEntries[0] as? KtLiteralStringTemplateEntry ?: return null + val singleEntry = stringTemplate.entries.singleOrNull() as? KtLiteralStringTemplateEntry ?: return null return singleEntry.text } - - @JvmStatic fun isFromMultifileClass(declarationElement: KtElement, descriptor: DeclarationDescriptor): Boolean { - if (DescriptorUtils.isTopLevelDeclaration(descriptor)) { - val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(declarationElement.containingKtFile) - return fileClassInfo.withJvmMultifileClass - } - return false - } } -internal class ParsedJvmFileClassAnnotations(val name: String, val multipleFiles: Boolean) +internal class ParsedJvmFileClassAnnotations(val jvmName: String, val isMultifileClass: Boolean) val KtFile.javaFileFacadeFqName: FqName get() { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/NoResolveFileClassesProvider.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/NoResolveFileClassesProvider.kt index b9e5238169c..c7dff5897cd 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/NoResolveFileClassesProvider.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/fileClasses/NoResolveFileClassesProvider.kt @@ -18,8 +18,7 @@ package org.jetbrains.kotlin.fileClasses import org.jetbrains.kotlin.psi.KtFile - object NoResolveFileClassesProvider : JvmFileClassesProvider { override fun getFileClassInfo(file: KtFile): JvmFileClassInfo = - JvmFileClassUtil.getFileClassInfo(file, JvmFileClassUtil.parseJvmNameOnFileNoResolve(file)) -} \ No newline at end of file + JvmFileClassUtil.getFileClassInfoNoResolve(file) +} diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmOverloadFilter.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmOverloadFilter.kt index 1b2ab874dbe..48d687c0e44 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmOverloadFilter.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmOverloadFilter.kt @@ -16,20 +16,18 @@ package org.jetbrains.kotlin.resolve.jvm -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorNonRoot import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor -import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider import org.jetbrains.kotlin.fileClasses.getFileClassFqName +import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.OverloadFilter import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor import java.util.* - object JvmOverloadFilter : OverloadFilter { override fun filterPackageMemberOverloads(overloads: Collection): Collection { val result = ArrayList() @@ -50,8 +48,7 @@ object JvmOverloadFilter : OverloadFilter { throw AssertionError("Package member expected; got $overload with containing declaration $containingDeclaration") } - val implClassName = JvmFileClassUtil.getImplClassName(overload) ?: - throw AssertionError("No implClassName: $overload") + val implClassName = overload.getImplClassNameForDeserialized() ?: throw AssertionError("No implClassName: $overload") val implClassFQN = containingDeclaration.fqName.child(implClassName) if (!sourceClassesFQNs.contains(implClassFQN)) { result.add(overload)