MultifileClassCodegen
- initial implementation - new Kotlin file kinds + stub builder
This commit is contained in:
@@ -22,30 +22,23 @@ import org.jetbrains.kotlin.psi.JetFile
|
||||
public interface JvmFileClassInfo {
|
||||
public val fileClassFqName: FqName
|
||||
public val facadeClassFqName: FqName
|
||||
public val kind: Kind
|
||||
|
||||
public enum class Kind {
|
||||
FILE_CLASS,
|
||||
MULTIFILE_CLASS_PART
|
||||
;
|
||||
}
|
||||
public val isWithJvmName: Boolean
|
||||
public val isMultifileClass: Boolean
|
||||
}
|
||||
|
||||
public class JvmFileFacadeInfo(
|
||||
override val fileClassFqName: FqName
|
||||
public class JvmSimpleFileClassInfo(
|
||||
override val fileClassFqName: FqName,
|
||||
override val isWithJvmName: Boolean
|
||||
) : JvmFileClassInfo {
|
||||
override val facadeClassFqName: FqName
|
||||
get() = fileClassFqName
|
||||
override val kind: JvmFileClassInfo.Kind
|
||||
get() = JvmFileClassInfo.Kind.FILE_CLASS
|
||||
override val facadeClassFqName: FqName get() = fileClassFqName
|
||||
override val isMultifileClass: Boolean get() = false
|
||||
}
|
||||
|
||||
public class JvmMultifileFacadePartInfo(
|
||||
public class JvmMultifileClassPartInfo(
|
||||
override val fileClassFqName: FqName,
|
||||
override val facadeClassFqName: FqName
|
||||
) : JvmFileClassInfo {
|
||||
override val kind: JvmFileClassInfo.Kind
|
||||
get() = JvmFileClassInfo.Kind.MULTIFILE_CLASS_PART
|
||||
|
||||
override val isWithJvmName: Boolean get() = true
|
||||
override val isMultifileClass: Boolean get() = true
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ public object JvmFileClassUtil {
|
||||
public val JVM_NAME: FqName = FqName("kotlin.jvm.JvmName")
|
||||
public val JVM_NAME_SHORT: String = JVM_NAME.shortName().asString()
|
||||
|
||||
// TODO @JvmMultifileClass
|
||||
public val JVM_MULTIFILE_CLASS: FqName = FqName("kotlin.jvm.JvmMultifileClass")
|
||||
public val JVM_MULTIFILE_CLASS_SHORT = JVM_MULTIFILE_CLASS.shortName().asString()
|
||||
|
||||
public @jvmStatic fun getFileClassInfo(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations?): JvmFileClassInfo =
|
||||
if (jvmFileClassAnnotations != null)
|
||||
@@ -40,13 +41,13 @@ public object JvmFileClassUtil {
|
||||
|
||||
public @jvmStatic fun getFileClassInfoForAnnotation(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations): JvmFileClassInfo =
|
||||
if (jvmFileClassAnnotations.multipleFiles)
|
||||
JvmMultifileFacadePartInfo(getHiddenPartFqName(file, jvmFileClassAnnotations),
|
||||
getFacadeFqName(file, jvmFileClassAnnotations))
|
||||
JvmMultifileClassPartInfo(getHiddenPartFqName(file, jvmFileClassAnnotations),
|
||||
getFacadeFqName(file, jvmFileClassAnnotations))
|
||||
else
|
||||
JvmFileFacadeInfo(getFacadeFqName(file, jvmFileClassAnnotations))
|
||||
JvmSimpleFileClassInfo(getFacadeFqName(file, jvmFileClassAnnotations), true)
|
||||
|
||||
public @jvmStatic fun getDefaultFileClassInfo(file: JetFile): JvmFileClassInfo =
|
||||
JvmFileFacadeInfo(PackagePartClassUtils.getPackagePartFqName(file.packageFqName, file.name))
|
||||
JvmSimpleFileClassInfo(PackagePartClassUtils.getPackagePartFqName(file.packageFqName, file.name), false)
|
||||
|
||||
public @jvmStatic fun getFacadeFqName(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations): FqName =
|
||||
file.packageFqName.child(Name.identifier(jvmFileClassAnnotations.name))
|
||||
@@ -59,31 +60,35 @@ public object JvmFileClassUtil {
|
||||
|
||||
public @jvmStatic fun parseJvmFileClass(annotations: Annotations): ParsedJmvFileClassAnnotations? {
|
||||
val jvmName = annotations.findAnnotation(JVM_NAME)
|
||||
// TODO @JvmMultifileClass
|
||||
return if (jvmName != null) parseJvmFileClass(jvmName) else null
|
||||
val jvmMultifileClass = annotations.findAnnotation(JVM_MULTIFILE_CLASS)
|
||||
return jvmName?.let {
|
||||
parseJvmFileClass(it, jvmMultifileClass)
|
||||
}
|
||||
}
|
||||
|
||||
public @jvmStatic fun parseJvmFileClass(jvmName: AnnotationDescriptor): ParsedJmvFileClassAnnotations {
|
||||
public @jvmStatic fun parseJvmFileClass(jvmName: AnnotationDescriptor, jvmMultifileClass: AnnotationDescriptor?): ParsedJmvFileClassAnnotations {
|
||||
val name = jvmName.allValueArguments.values().firstOrNull()?.let { (it as? StringValue)?.value }
|
||||
return ParsedJmvFileClassAnnotations(name!!, false)
|
||||
val isMultifileClassPart = jvmMultifileClass != null
|
||||
return ParsedJmvFileClassAnnotations(name!!, isMultifileClassPart)
|
||||
}
|
||||
|
||||
public @jvmStatic fun getFileClassInfoNoResolve(file: JetFile): JvmFileClassInfo =
|
||||
getFileClassInfo(file, parseJvmNameOnFileNoResolve(file))
|
||||
|
||||
public @jvmStatic fun parseJvmNameOnFileNoResolve(file: JetFile): ParsedJmvFileClassAnnotations? =
|
||||
findJvmNameOnFileNoResolve(file)?.let { parseJvmNameOnFileNoResolve(it) }
|
||||
|
||||
public @jvmStatic fun findJvmNameOnFileNoResolve(file: JetFile): JetAnnotationEntry? =
|
||||
file.fileAnnotationList?.annotationEntries?.firstOrNull {
|
||||
it.calleeExpression?.constructorReferenceExpression?.getReferencedName() == JVM_NAME_SHORT
|
||||
findAnnotationEntryOnFileNoResolve(file, JVM_NAME_SHORT)?.let { annotationEntry ->
|
||||
val nameExpr = annotationEntry.valueArguments.firstOrNull()?.getArgumentExpression() ?: return null
|
||||
val name = getLiteralStringFromRestrictedConstExpression(nameExpr)
|
||||
val isMultifileClassPart = findAnnotationEntryOnFileNoResolve(file, JVM_MULTIFILE_CLASS_SHORT) != null
|
||||
name?.let {
|
||||
ParsedJmvFileClassAnnotations(it, isMultifileClassPart)
|
||||
}
|
||||
}
|
||||
|
||||
public @jvmStatic fun parseJvmNameOnFileNoResolve(annotationEntry: JetAnnotationEntry): ParsedJmvFileClassAnnotations? {
|
||||
val nameExpr = annotationEntry.valueArguments.firstOrNull()?.getArgumentExpression() ?: return null
|
||||
val name = getLiteralStringFromRestrictedConstExpression(nameExpr)
|
||||
return name?.let { ParsedJmvFileClassAnnotations(it, false) }
|
||||
}
|
||||
public @jvmStatic fun findAnnotationEntryOnFileNoResolve(file: JetFile, shortName: String): JetAnnotationEntry? =
|
||||
file.fileAnnotationList?.annotationEntries?.firstOrNull {
|
||||
it.calleeExpression?.constructorReferenceExpression?.getReferencedName() == shortName
|
||||
}
|
||||
|
||||
private @jvmStatic fun getLiteralStringFromRestrictedConstExpression(argumentExpression: JetExpression?): String? {
|
||||
val stringTemplate = argumentExpression as? JetStringTemplateExpression ?: return null
|
||||
|
||||
+10
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.psi.JetClassOrObject
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
|
||||
public enum class MemberKind { FIELD, METHOD }
|
||||
@@ -39,13 +40,16 @@ public enum class JvmDeclarationOriginKind {
|
||||
DELEGATION_TO_TRAIT_IMPL,
|
||||
DELEGATION,
|
||||
BRIDGE,
|
||||
MULTIFILE_CLASS,
|
||||
MULTIFILE_CLASS_PART,
|
||||
SYNTHETIC // this means that there's no proper descriptor for this jvm declaration
|
||||
}
|
||||
|
||||
public class JvmDeclarationOrigin(
|
||||
public val originKind: JvmDeclarationOriginKind,
|
||||
public val element: PsiElement?,
|
||||
public val descriptor: DeclarationDescriptor?
|
||||
public val descriptor: DeclarationDescriptor?,
|
||||
public val multifileClassFqName: FqName? = null
|
||||
) {
|
||||
companion object {
|
||||
public val NO_ORIGIN: JvmDeclarationOrigin = JvmDeclarationOrigin(OTHER, null, null)
|
||||
@@ -67,6 +71,11 @@ public fun Bridge(descriptor: DeclarationDescriptor, element: PsiElement? = Desc
|
||||
public fun PackageFacade(descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(PACKAGE_FACADE, null, descriptor)
|
||||
public fun PackagePart(file: JetFile, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(PACKAGE_PART, file, descriptor)
|
||||
|
||||
public fun MultifileClass(descriptor: PackageFragmentDescriptor, multifileClassFqName: FqName): JvmDeclarationOrigin =
|
||||
JvmDeclarationOrigin(MULTIFILE_CLASS, null, descriptor, multifileClassFqName)
|
||||
public fun MultifileClassPart(file: JetFile, descriptor: PackageFragmentDescriptor, multifileClassFqName: FqName): JvmDeclarationOrigin =
|
||||
JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor, multifileClassFqName)
|
||||
|
||||
public fun TraitImpl(element: JetClassOrObject, descriptor: ClassDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(TRAIT_IMPL, element, descriptor)
|
||||
public fun DelegationToTraitImpl(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin =
|
||||
JvmDeclarationOrigin(DELEGATION_TO_TRAIT_IMPL, element, descriptor)
|
||||
|
||||
Reference in New Issue
Block a user