KT-11410: Class hierarchy for parts/facade of multi-file class.

Preserve static initialization semantics for parts by introducing a special "clinit trigger" class.
Insert "static initialization trigger" call to every method of a part class, remove this call on inline.
Always mangle names for private functions in multifile class parts to avoid resolution clashes on inheritance.

NB in codegen tests initializers for all non-const vals are wrapped in 'run { ... }',
so that the initializer is not a constant expression, and some static initialization code should be generated.
This commit is contained in:
Dmitry Petrov
2016-03-16 12:06:18 +03:00
parent 0ccaf43e2c
commit db58ebc4b2
34 changed files with 823 additions and 135 deletions
@@ -18,12 +18,15 @@ 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.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
object JvmFileClassUtil {
@@ -84,14 +87,21 @@ object JvmFileClassUtil {
it.calleeExpression?.constructorReferenceExpression?.getReferencedName() == shortName
}
@JvmStatic
private fun getLiteralStringFromRestrictedConstExpression(argumentExpression: KtExpression?): String? {
@JvmStatic 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
return singleEntry.text
}
@JvmStatic fun isFromMultifileClass(declarationElement: KtElement, descriptor: DeclarationDescriptor): Boolean {
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(declarationElement.getContainingKtFile())
return fileClassInfo.withJvmMultifileClass
}
return false
}
}
internal class ParsedJvmFileClassAnnotations(val name: String, val multipleFiles: Boolean)
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.resolve.jvm.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
@@ -68,9 +67,9 @@ fun PackagePart(file: KtFile, descriptor: PackageFragmentDescriptor): JvmDeclara
/**
* @param representativeFile one of the files representing this multifile class (will be used for diagnostics)
*/
fun MultifileClass(representativeFile: KtFile?, descriptor: PackageFragmentDescriptor, multifileClassFqName: FqName): JvmDeclarationOrigin =
fun MultifileClass(representativeFile: KtFile?, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin =
JvmDeclarationOrigin(MULTIFILE_CLASS, representativeFile, descriptor)
fun MultifileClassPart(file: KtFile, descriptor: PackageFragmentDescriptor, multifileClassFqName: FqName): JvmDeclarationOrigin =
fun MultifileClassPart(file: KtFile, descriptor: PackageFragmentDescriptor): JvmDeclarationOrigin =
JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor)
fun TraitImpl(element: KtClassOrObject, descriptor: ClassDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(INTERFACE_DEFAULT_IMPL, element, descriptor)