FileClassDescriptor should provide all information required for TypeMapper.

This commit is contained in:
Dmitry Petrov
2016-09-23 11:46:06 +03:00
parent ce8bdef746
commit e8c7c821a7
2 changed files with 36 additions and 55 deletions
@@ -16,18 +16,19 @@
package org.jetbrains.kotlin.backend.jvm.codegen
import com.intellij.util.ArrayUtil
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.lower.FileClassDescriptor
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
import org.jetbrains.kotlin.codegen.MemberCodegen.badDescriptor
import org.jetbrains.kotlin.codegen.SuperClassInfo
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.org.objectweb.asm.Opcodes
@@ -42,53 +43,25 @@ class ClassCodegen private constructor(val irClass: IrClass, val context: JvmBac
val descriptor = irClass.descriptor
val type: Type
val type: Type = typeMapper.mapType(descriptor)
init {
if (descriptor.isFileDescriptor) {
descriptor.name
val fileClassInfo = state.fileClassesProvider.getFileClassInfo((irClass.descriptor.source as KotlinSourceElement).psi.getContainingKtFile())
if (fileClassInfo.withJvmMultifileClass) {
assert(false) { "TODO: support multifile facades" }
}
type = AsmUtil.asmTypeByFqNameWithoutInnerClasses(fileClassInfo.fileClassFqName)
}
else {
type = typeMapper.mapType(descriptor)
}
}
val psiElement = irClass.descriptor.psiElement
val visitor: ClassBuilder
init {
val element = (irClass.descriptor.source as PsiSourceElement).psi!!
visitor = state.factory.newVisitor(irClass.OtherOrigin, type, element.containingFile)
}
val visitor: ClassBuilder = state.factory.newVisitor(OtherOrigin(psiElement, descriptor), type, psiElement.containingFile)
fun generate() {
if (descriptor.isFileDescriptor) {
visitor.defineClass((irClass.descriptor.source as KotlinSourceElement).psi,
state.classFileVersion,
descriptor.calculateClassFlags(),
type.internalName,
null,
"java/lang/Object",
ArrayUtil.EMPTY_STRING_ARRAY
)
}
else {
val superClassInfo = SuperClassInfo.getSuperClassInfo(descriptor, typeMapper)
val signature = ImplementationBodyCodegen.signature(descriptor, type, superClassInfo, typeMapper)
val superClassInfo = SuperClassInfo.getSuperClassInfo(descriptor, typeMapper)
val signature = ImplementationBodyCodegen.signature(descriptor, type, superClassInfo, typeMapper)
visitor.defineClass(irClass.OtherOrigin.element, state.classFileVersion,
descriptor.calculateClassFlags(),
signature.name,
signature.javaGenericSignature,
signature.superclassName,
signature.interfaces.toTypedArray()
)
}
visitor.defineClass(
psiElement,
state.classFileVersion,
descriptor.calculateClassFlags(),
signature.name,
signature.javaGenericSignature,
signature.superclassName,
signature.interfaces.toTypedArray()
)
irClass.declarations.forEach {
generateDeclaration(it)
@@ -190,14 +163,14 @@ fun MemberDescriptor.calculateCommonFlags(): Int {
return flags
}
val IrClass.OtherOrigin: JvmDeclarationOrigin
get() = OtherOrigin((this.descriptor.source as PsiSourceElement).psi!!, this.descriptor)
val DeclarationDescriptorWithSource.psiElement: PsiElement
get() = (source as PsiSourceElement).psi!!
val IrField.OtherOrigin: JvmDeclarationOrigin
get() = OtherOrigin((this.descriptor.source as PsiSourceElement).psi!!, this.descriptor)
get() = OtherOrigin(descriptor.psiElement, this.descriptor)
val IrFunction.OtherOrigin: JvmDeclarationOrigin
get() = OtherOrigin((this.descriptor.source as PsiSourceElement).psi!!, this.descriptor)
get() = OtherOrigin(descriptor.psiElement, this.descriptor)
val ClassDescriptor.isFileDescriptor: Boolean
get() = this is FileClassDescriptor
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.*
@@ -34,9 +35,8 @@ class FileClassDescriptorImpl(
override fun getConstructors(): Collection<ClassConstructorDescriptor> = emptyList()
override fun getContainingDeclaration(): DeclarationDescriptor = containingDeclarationImpl
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> = emptyList()
override fun getDefaultType(): SimpleType = ErrorUtils.createErrorType("File class type for $nameImpl")
override fun getKind(): ClassKind = ClassKind.CLASS
override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope = error("File class has no member scope")
override fun getMemberScope(typeSubstitution: TypeSubstitution): MemberScope = error("File class has no member scope")
override fun getModality(): Modality = Modality.FINAL
override fun getOriginal(): ClassDescriptor = this
@@ -51,9 +51,20 @@ class FileClassDescriptorImpl(
override fun isData(): Boolean = false
override fun substitute(substitutor: TypeSubstitutor): ClassDescriptor = error("File class can't be substituted")
override fun getSource(): SourceElement = sourceElement
override fun getTypeConstructor(): TypeConstructor = error("File class can't be used in types")
override fun isInner(): Boolean = false
override val annotations = Annotations.EMPTY // TODO file annotations
private val typeConstructor = ClassTypeConstructorImpl(this, annotations, true, emptyList(), listOf(builtIns.anyType))
private val defaultType = KotlinTypeFactory.simpleNotNullType(annotations, this, emptyList())
override fun getTypeConstructor(): TypeConstructor = typeConstructor
override fun getDefaultType(): SimpleType = defaultType
override fun getMemberScope(typeArguments: MutableList<out TypeProjection>): MemberScope =
MemberScope.Empty // TODO do we need a more useful MemberScope here?
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
return visitor.visitClassDescriptor(this, data)
}
@@ -62,9 +73,6 @@ class FileClassDescriptorImpl(
visitor.visitClassDescriptor(this, null)
}
override val annotations: Annotations
get() = TODO("not implemented")
override fun toString(): String =
"IrFileClassDescriptor($fqNameUnsafe)"
}