Refactor and simplify JvmFileClassUtil
This commit is contained in:
@@ -49,6 +49,7 @@ import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
|
|||||||
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
|
import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
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.java.lazy.descriptors.LazyJavaPackageFragment;
|
||||||
import org.jetbrains.kotlin.load.kotlin.*;
|
import org.jetbrains.kotlin.load.kotlin.*;
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider.IncrementalMultifileClassPackageFragment;
|
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);
|
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;
|
assert implClassName != null : "No implClassName for " + descriptor;
|
||||||
String implSimpleName = implClassName.asString();
|
String implSimpleName = implClassName.asString();
|
||||||
|
|
||||||
|
|||||||
@@ -18,14 +18,12 @@ package org.jetbrains.kotlin.fileClasses
|
|||||||
|
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
import com.intellij.psi.util.CachedValuesManager
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized
|
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
||||||
|
|
||||||
object JvmFileClassUtil {
|
object JvmFileClassUtil {
|
||||||
@@ -35,46 +33,36 @@ object JvmFileClassUtil {
|
|||||||
val JVM_MULTIFILE_CLASS: FqName = FqName("kotlin.jvm.JvmMultifileClass")
|
val JVM_MULTIFILE_CLASS: FqName = FqName("kotlin.jvm.JvmMultifileClass")
|
||||||
val JVM_MULTIFILE_CLASS_SHORT = JVM_MULTIFILE_CLASS.shortName().asString()
|
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 =
|
fun getPartFqNameForDeserialized(descriptor: DeserializedMemberDescriptor): FqName {
|
||||||
if (jvmFileClassAnnotations != null)
|
val implClassName = descriptor.getImplClassNameForDeserialized() ?: error("No implClassName for $descriptor")
|
||||||
getFileClassInfoForAnnotation(file, jvmFileClassAnnotations)
|
return (descriptor.containingDeclaration as PackageFragmentDescriptor).fqName.child(implClassName)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic fun getImplClassName(deserializedMemberDescriptor: DeserializedMemberDescriptor): Name? =
|
private fun manglePartName(facadeName: String, fileName: String): String =
|
||||||
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 =
|
|
||||||
"$facadeName$MULTIFILE_PART_NAME_DELIMITER${PackagePartClassUtils.getFilePartShortName(fileName)}"
|
"$facadeName$MULTIFILE_PART_NAME_DELIMITER${PackagePartClassUtils.getFilePartShortName(fileName)}"
|
||||||
|
|
||||||
@JvmStatic fun getFileClassInfoNoResolve(file: KtFile): JvmFileClassInfo =
|
@JvmStatic
|
||||||
getFileClassInfo(file, parseJvmNameOnFileNoResolve(file))
|
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 jvmName = findAnnotationEntryOnFileNoResolve(file, JVM_NAME_SHORT) ?: return null
|
||||||
val nameExpr = jvmName.valueArguments.firstOrNull()?.getArgumentExpression() ?: return null
|
val nameExpr = jvmName.valueArguments.firstOrNull()?.getArgumentExpression() ?: return null
|
||||||
val name = getLiteralStringFromRestrictedConstExpression(nameExpr) ?: return null
|
val name = getLiteralStringFromRestrictedConstExpression(nameExpr) ?: return null
|
||||||
@@ -83,29 +71,20 @@ object JvmFileClassUtil {
|
|||||||
return ParsedJvmFileClassAnnotations(name, isMultifileClassPart)
|
return ParsedJvmFileClassAnnotations(name, isMultifileClassPart)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic fun findAnnotationEntryOnFileNoResolve(file: KtFile, shortName: String): KtAnnotationEntry? =
|
@JvmStatic
|
||||||
|
fun findAnnotationEntryOnFileNoResolve(file: KtFile, shortName: String): KtAnnotationEntry? =
|
||||||
file.fileAnnotationList?.annotationEntries?.firstOrNull {
|
file.fileAnnotationList?.annotationEntries?.firstOrNull {
|
||||||
it.calleeExpression?.constructorReferenceExpression?.getReferencedName() == shortName
|
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 stringTemplate = argumentExpression as? KtStringTemplateExpression ?: return null
|
||||||
val stringTemplateEntries = stringTemplate.entries
|
val singleEntry = stringTemplate.entries.singleOrNull() as? KtLiteralStringTemplateEntry ?: return null
|
||||||
if (stringTemplateEntries.size != 1) return null
|
|
||||||
val singleEntry = stringTemplateEntries[0] as? KtLiteralStringTemplateEntry ?: return null
|
|
||||||
return singleEntry.text
|
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
|
val KtFile.javaFileFacadeFqName: FqName
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
+2
-3
@@ -18,8 +18,7 @@ package org.jetbrains.kotlin.fileClasses
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
|
|
||||||
object NoResolveFileClassesProvider : JvmFileClassesProvider {
|
object NoResolveFileClassesProvider : JvmFileClassesProvider {
|
||||||
override fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
|
override fun getFileClassInfo(file: KtFile): JvmFileClassInfo =
|
||||||
JvmFileClassUtil.getFileClassInfo(file, JvmFileClassUtil.parseJvmNameOnFileNoResolve(file))
|
JvmFileClassUtil.getFileClassInfoNoResolve(file)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,20 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.jvm
|
package org.jetbrains.kotlin.resolve.jvm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorNonRoot
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorNonRoot
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
|
||||||
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
|
||||||
import org.jetbrains.kotlin.fileClasses.getFileClassFqName
|
import org.jetbrains.kotlin.fileClasses.getFileClassFqName
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.OverloadFilter
|
import org.jetbrains.kotlin.resolve.OverloadFilter
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
object JvmOverloadFilter : OverloadFilter {
|
object JvmOverloadFilter : OverloadFilter {
|
||||||
override fun filterPackageMemberOverloads(overloads: Collection<DeclarationDescriptorNonRoot>): Collection<DeclarationDescriptorNonRoot> {
|
override fun filterPackageMemberOverloads(overloads: Collection<DeclarationDescriptorNonRoot>): Collection<DeclarationDescriptorNonRoot> {
|
||||||
val result = ArrayList<DeclarationDescriptorNonRoot>()
|
val result = ArrayList<DeclarationDescriptorNonRoot>()
|
||||||
@@ -50,8 +48,7 @@ object JvmOverloadFilter : OverloadFilter {
|
|||||||
throw AssertionError("Package member expected; got $overload with containing declaration $containingDeclaration")
|
throw AssertionError("Package member expected; got $overload with containing declaration $containingDeclaration")
|
||||||
}
|
}
|
||||||
|
|
||||||
val implClassName = JvmFileClassUtil.getImplClassName(overload) ?:
|
val implClassName = overload.getImplClassNameForDeserialized() ?: throw AssertionError("No implClassName: $overload")
|
||||||
throw AssertionError("No implClassName: $overload")
|
|
||||||
val implClassFQN = containingDeclaration.fqName.child(implClassName)
|
val implClassFQN = containingDeclaration.fqName.child(implClassName)
|
||||||
if (!sourceClassesFQNs.contains(implClassFQN)) {
|
if (!sourceClassesFQNs.contains(implClassFQN)) {
|
||||||
result.add(overload)
|
result.add(overload)
|
||||||
|
|||||||
Reference in New Issue
Block a user