Temporary use special container mapping logic for IR backend

This commit is contained in:
Mikhael Bogdanov
2018-08-08 15:55:57 +03:00
parent 813e1ffa39
commit 6b5b9fbde4
9 changed files with 74 additions and 26 deletions
@@ -17,7 +17,8 @@ class KotlinToJvmSignatureMapperImpl : KotlinToJvmSignatureMapper {
// We use empty BindingContext, because it is only used by KotlinTypeMapper for purposes irrelevant to the needs of this class // We use empty BindingContext, because it is only used by KotlinTypeMapper for purposes irrelevant to the needs of this class
private val typeMapper = KotlinTypeMapper( private val typeMapper = KotlinTypeMapper(
BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES,
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT,
false
) )
override fun mapToJvmMethodSignature(function: FunctionDescriptor) = typeMapper.mapAsmMethod(function) override fun mapToJvmMethodSignature(function: FunctionDescriptor) = typeMapper.mapAsmMethod(function)
@@ -48,12 +48,14 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
private val diagnostics: DiagnosticSink, private val diagnostics: DiagnosticSink,
moduleName: String, moduleName: String,
isReleaseCoroutines: Boolean, isReleaseCoroutines: Boolean,
shouldGenerate: (JvmDeclarationOrigin) -> Boolean shouldGenerate: (JvmDeclarationOrigin) -> Boolean,
isIrBackend: Boolean
) : SignatureCollectingClassBuilderFactory(builderFactory, shouldGenerate) { ) : SignatureCollectingClassBuilderFactory(builderFactory, shouldGenerate) {
// Avoid errors when some classes are not loaded for some reason // Avoid errors when some classes are not loaded for some reason
private val typeMapper = KotlinTypeMapper( private val typeMapper = KotlinTypeMapper(
bindingContext, ClassBuilderMode.LIGHT_CLASSES, IncompatibleClassTracker.DoNothing, moduleName, false, isReleaseCoroutines bindingContext, ClassBuilderMode.LIGHT_CLASSES, IncompatibleClassTracker.DoNothing, moduleName, false, isReleaseCoroutines,
isIrBackend
) )
private val reportDiagnosticsTasks = ArrayList<() -> Unit>() private val reportDiagnosticsTasks = ArrayList<() -> Unit>()
@@ -181,13 +181,15 @@ class GenerationState private constructor(
filter = if (wantsDiagnostics) BindingTraceFilter.ACCEPT_ALL else BindingTraceFilter.NO_DIAGNOSTICS filter = if (wantsDiagnostics) BindingTraceFilter.ACCEPT_ALL else BindingTraceFilter.NO_DIAGNOSTICS
) )
val bindingContext: BindingContext = bindingTrace.bindingContext val bindingContext: BindingContext = bindingTrace.bindingContext
private val isIrBackend = configuration.get(JVMConfigurationKeys.IR) ?: false
val typeMapper: KotlinTypeMapper = KotlinTypeMapper( val typeMapper: KotlinTypeMapper = KotlinTypeMapper(
this.bindingContext, this.bindingContext,
classBuilderMode, classBuilderMode,
IncompatibleClassTrackerImpl(extraJvmDiagnosticsTrace), IncompatibleClassTrackerImpl(extraJvmDiagnosticsTrace),
this.moduleName, this.moduleName,
isJvm8Target, isJvm8Target,
configuration.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines) configuration.languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines),
isIrBackend
) )
val intrinsics: IntrinsicMethods = run { val intrinsics: IntrinsicMethods = run {
val shouldUseConsistentEquals = languageVersionSettings.supportsFeature(LanguageFeature.ThrowNpeOnExplicitEqualsForBoxedNull) && val shouldUseConsistentEquals = languageVersionSettings.supportsFeature(LanguageFeature.ThrowNpeOnExplicitEqualsForBoxedNull) &&
@@ -251,7 +253,8 @@ class GenerationState private constructor(
BuilderFactoryForDuplicateSignatureDiagnostics( BuilderFactoryForDuplicateSignatureDiagnostics(
it, this.bindingContext, diagnostics, this.moduleName, it, this.bindingContext, diagnostics, this.moduleName,
isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines), isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines),
shouldGenerate = { !shouldOnlyCollectSignatures(it) } shouldGenerate = { !shouldOnlyCollectSignatures(it) },
isIrBackend = isIrBackend
).apply { duplicateSignatureFactory = this } ).apply { duplicateSignatureFactory = this }
}, },
{ BuilderFactoryForDuplicateClassNameDiagnostics(it, diagnostics) }, { BuilderFactoryForDuplicateClassNameDiagnostics(it, diagnostics) },
@@ -10,7 +10,6 @@ import com.intellij.psi.PsiElement;
import kotlin.Pair; import kotlin.Pair;
import kotlin.Unit; import kotlin.Unit;
import kotlin.collections.CollectionsKt; import kotlin.collections.CollectionsKt;
import kotlin.reflect.KType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment; import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment;
@@ -87,6 +86,7 @@ public class KotlinTypeMapper {
private final String moduleName; private final String moduleName;
private final boolean isJvm8Target; private final boolean isJvm8Target;
private final boolean isReleaseCoroutines; private final boolean isReleaseCoroutines;
private boolean isIrBackend;
private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() { private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() {
@NotNull @NotNull
@@ -158,7 +158,7 @@ public class KotlinTypeMapper {
@NotNull String moduleName, @NotNull String moduleName,
boolean isJvm8Target boolean isJvm8Target
) { ) {
this(bindingContext, classBuilderMode, incompatibleClassTracker, moduleName, isJvm8Target, false); this(bindingContext, classBuilderMode, incompatibleClassTracker, moduleName, isJvm8Target, false, false);
} }
public KotlinTypeMapper( public KotlinTypeMapper(
@@ -167,7 +167,8 @@ public class KotlinTypeMapper {
@NotNull IncompatibleClassTracker incompatibleClassTracker, @NotNull IncompatibleClassTracker incompatibleClassTracker,
@NotNull String moduleName, @NotNull String moduleName,
boolean isJvm8Target, boolean isJvm8Target,
boolean isReleaseCoroutines boolean isReleaseCoroutines,
boolean isIrBackend
) { ) {
this.bindingContext = bindingContext; this.bindingContext = bindingContext;
this.classBuilderMode = classBuilderMode; this.classBuilderMode = classBuilderMode;
@@ -175,6 +176,7 @@ public class KotlinTypeMapper {
this.moduleName = moduleName; this.moduleName = moduleName;
this.isJvm8Target = isJvm8Target; this.isJvm8Target = isJvm8Target;
this.isReleaseCoroutines = isReleaseCoroutines; this.isReleaseCoroutines = isReleaseCoroutines;
this.isIrBackend = isIrBackend;
} }
public static final boolean RELEASE_COROUTINES_DEFAULT = false; public static final boolean RELEASE_COROUTINES_DEFAULT = false;
@@ -505,7 +507,8 @@ public class KotlinTypeMapper {
(ktType, asmType, typeMappingMode) -> { (ktType, asmType, typeMappingMode) -> {
writeGenericType(ktType, asmType, signatureVisitor, typeMappingMode); writeGenericType(ktType, asmType, signatureVisitor, typeMappingMode);
return Unit.INSTANCE; return Unit.INSTANCE;
} },
isIrBackend
); );
} }
@@ -541,7 +544,8 @@ public class KotlinTypeMapper {
) { ) {
return TypeSignatureMappingKt.mapType( return TypeSignatureMappingKt.mapType(
kotlinType, AsmTypeFactory.INSTANCE, mode, staticTypeMappingConfiguration, null, kotlinType, AsmTypeFactory.INSTANCE, mode, staticTypeMappingConfiguration, null,
(ktType, asmType, typeMappingMode) -> Unit.INSTANCE (ktType, asmType, typeMappingMode) -> Unit.INSTANCE,
false
); );
} }
@@ -1677,7 +1681,7 @@ public class KotlinTypeMapper {
if (recordedType != null) { if (recordedType != null) {
return recordedType.getInternalName(); return recordedType.getInternalName();
} }
return TypeSignatureMappingKt.computeInternalName(classDescriptor, typeMappingConfiguration); return TypeSignatureMappingKt.computeInternalName(classDescriptor, typeMappingConfiguration, isIrBackend);
} }
public static class InternalNameMapper { public static class InternalNameMapper {
@@ -76,7 +76,7 @@ internal val ClassDescriptor.internalName: String
return JvmClassName.byClassId(it).internalName return JvmClassName.byClassId(it).internalName
} }
return computeInternalName(this) return computeInternalName(this, isIrBackend = false)
} }
internal val ClassId.internalName: String internal val ClassId.internalName: String
@@ -89,7 +89,14 @@ private fun StringBuilder.appendErasedType(type: KotlinType) {
} }
internal fun KotlinType.mapToJvmType() = internal fun KotlinType.mapToJvmType() =
mapType(this, JvmTypeFactoryImpl, TypeMappingMode.DEFAULT, TypeMappingConfigurationImpl, descriptorTypeWriter = null) mapType(
this,
JvmTypeFactoryImpl,
TypeMappingMode.DEFAULT,
TypeMappingConfigurationImpl,
descriptorTypeWriter = null,
isIrBackend = false
)
sealed class JvmType { sealed class JvmType {
// null means 'void' // null means 'void'
@@ -51,13 +51,15 @@ fun <T : Any> mapType(
mode: TypeMappingMode, mode: TypeMappingMode,
typeMappingConfiguration: TypeMappingConfiguration<T>, typeMappingConfiguration: TypeMappingConfiguration<T>,
descriptorTypeWriter: JvmDescriptorTypeWriter<T>?, descriptorTypeWriter: JvmDescriptorTypeWriter<T>?,
writeGenericType: (KotlinType, T, TypeMappingMode) -> Unit = DO_NOTHING_3 writeGenericType: (KotlinType, T, TypeMappingMode) -> Unit = DO_NOTHING_3,
isIrBackend: Boolean
): T { ): T {
if (kotlinType.isSuspendFunctionType) { if (kotlinType.isSuspendFunctionType) {
return mapType( return mapType(
transformSuspendFunctionToRuntimeFunctionType(kotlinType, typeMappingConfiguration.releaseCoroutines()), transformSuspendFunctionToRuntimeFunctionType(kotlinType, typeMappingConfiguration.releaseCoroutines()),
factory, mode, typeMappingConfiguration, descriptorTypeWriter, factory, mode, typeMappingConfiguration, descriptorTypeWriter,
writeGenericType writeGenericType,
isIrBackend
) )
} }
@@ -78,7 +80,7 @@ fun <T : Any> mapType(
// It's not very important because such types anyway are prohibited in declarations // It's not very important because such types anyway are prohibited in declarations
return mapType( return mapType(
commonSupertype.replaceArgumentsWithStarProjections(), commonSupertype.replaceArgumentsWithStarProjections(),
factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType factory, mode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType, isIrBackend
) )
} }
@@ -116,7 +118,8 @@ fun <T : Any> mapType(
mapType( mapType(
memberType, factory, memberType, factory,
mode.toGenericArgumentMode(memberProjection.projectionKind), mode.toGenericArgumentMode(memberProjection.projectionKind),
typeMappingConfiguration, descriptorTypeWriter, writeGenericType typeMappingConfiguration, descriptorTypeWriter, writeGenericType,
isIrBackend
) )
descriptorTypeWriter?.writeArrayEnd() descriptorTypeWriter?.writeArrayEnd()
@@ -130,7 +133,15 @@ fun <T : Any> mapType(
val typeForMapping = computeUnderlyingType(kotlinType) val typeForMapping = computeUnderlyingType(kotlinType)
if (typeForMapping != null) { if (typeForMapping != null) {
val newMode = if (typeForMapping.isInlineClassType()) mode else mode.wrapInlineClassesMode() val newMode = if (typeForMapping.isInlineClassType()) mode else mode.wrapInlineClassesMode()
return mapType(typeForMapping, factory, newMode, typeMappingConfiguration, descriptorTypeWriter, writeGenericType) return mapType(
typeForMapping,
factory,
newMode,
typeMappingConfiguration,
descriptorTypeWriter,
writeGenericType,
isIrBackend
)
} }
} }
@@ -144,7 +155,13 @@ fun <T : Any> mapType(
val enumClassIfEnumEntry = if (descriptor.kind == ClassKind.ENUM_ENTRY) val enumClassIfEnumEntry = if (descriptor.kind == ClassKind.ENUM_ENTRY)
descriptor.containingDeclaration as ClassDescriptor descriptor.containingDeclaration as ClassDescriptor
else descriptor else descriptor
factory.createObjectType(computeInternalName(enumClassIfEnumEntry.original, typeMappingConfiguration)) factory.createObjectType(
computeInternalName(
enumClassIfEnumEntry.original,
typeMappingConfiguration,
isIrBackend
)
)
} }
} }
@@ -156,7 +173,12 @@ fun <T : Any> mapType(
descriptor is TypeParameterDescriptor -> { descriptor is TypeParameterDescriptor -> {
val type = mapType( val type = mapType(
getRepresentativeUpperBound(descriptor), getRepresentativeUpperBound(descriptor),
factory, mode, typeMappingConfiguration, writeGenericType = DO_NOTHING_3, descriptorTypeWriter = null factory,
mode,
typeMappingConfiguration,
writeGenericType = DO_NOTHING_3,
descriptorTypeWriter = null,
isIrBackend = isIrBackend
) )
descriptorTypeWriter?.writeTypeVariable(descriptor.getName(), type) descriptorTypeWriter?.writeTypeVariable(descriptor.getName(), type)
return type return type
@@ -237,9 +259,10 @@ private fun shouldUseUnderlyingType(inlineClassType: KotlinType): Boolean {
fun computeInternalName( fun computeInternalName(
klass: ClassDescriptor, klass: ClassDescriptor,
typeMappingConfiguration: TypeMappingConfiguration<*> = TypeMappingConfigurationImpl typeMappingConfiguration: TypeMappingConfiguration<*> = TypeMappingConfigurationImpl,
isIrBackend: Boolean
): String { ): String {
val container = klass.containingDeclaration val container = if (isIrBackend) getContainer(klass.containingDeclaration) else klass.containingDeclaration
val name = SpecialNames.safeIdentifier(klass.name).identifier val name = SpecialNames.safeIdentifier(klass.name).identifier
if (container is PackageFragmentDescriptor) { if (container is PackageFragmentDescriptor) {
@@ -253,11 +276,16 @@ fun computeInternalName(
val containerInternalName = val containerInternalName =
typeMappingConfiguration.getPredefinedInternalNameForClass(containerClass) ?: computeInternalName( typeMappingConfiguration.getPredefinedInternalNameForClass(containerClass) ?: computeInternalName(
containerClass, containerClass,
typeMappingConfiguration typeMappingConfiguration,
isIrBackend
) )
return containerInternalName + "$" + name return containerInternalName + "$" + name
} }
private fun getContainer(container: DeclarationDescriptor?): DeclarationDescriptor? =
container as? ClassDescriptor ?: container as? PackageFragmentDescriptor ?:
container?.let { getContainer(it.containingDeclaration) }
private fun getRepresentativeUpperBound(descriptor: TypeParameterDescriptor): KotlinType { private fun getRepresentativeUpperBound(descriptor: TypeParameterDescriptor): KotlinType {
val upperBounds = descriptor.upperBounds val upperBounds = descriptor.upperBounds
assert(!upperBounds.isEmpty()) { "Upper bounds should not be empty: " + descriptor } assert(!upperBounds.isEmpty()) { "Upper bounds should not be empty: " + descriptor }
@@ -185,7 +185,8 @@ class ParcelableDeclarationChecker : DeclarationChecker {
IncompatibleClassTracker.DoNothing, IncompatibleClassTracker.DoNothing,
descriptor.module.name.asString(), descriptor.module.name.asString(),
/* isJvm8Target */ false, /* isJvm8Target */ false,
/* isReleaseCoroutines */ KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT /* isReleaseCoroutines */ KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT,
/* isIrBackend*/false
) )
for (parameter in primaryConstructor?.valueParameters.orEmpty()) { for (parameter in primaryConstructor?.valueParameters.orEmpty()) {
@@ -37,7 +37,8 @@ class IdeaKotlinUastResolveProviderService : KotlinUastResolveProviderService {
override fun getTypeMapper(element: KtElement): KotlinTypeMapper? { override fun getTypeMapper(element: KtElement): KotlinTypeMapper? {
return KotlinTypeMapper( return KotlinTypeMapper(
getBindingContext(element), ClassBuilderMode.LIGHT_CLASSES, getBindingContext(element), ClassBuilderMode.LIGHT_CLASSES,
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT,
false
) )
} }
@@ -56,7 +56,8 @@ class UastAnalysisHandlerExtension : AnalysisHandlerExtension {
val typeMapper = KotlinTypeMapper( val typeMapper = KotlinTypeMapper(
bindingContext, ClassBuilderMode.LIGHT_CLASSES, bindingContext, ClassBuilderMode.LIGHT_CLASSES,
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME, false, KotlinTypeMapper.RELEASE_COROUTINES_DEFAULT,
false
) )
this.typeMapper = typeMapper this.typeMapper = typeMapper
return typeMapper return typeMapper