Rename KaptAnonymousTypeTransformer and move to frontend.java

This is needed in order to run light analysis mode tests for JVM IR
backend. In the subsequent commit, this extension is added to light
analysis mode tests.

Kapt stub generation uses this extension to transform local types to
non-local:

    private val x = object {}

With this extension, x's type will be `Any`. Without it, it will be an
anonymous type. This anonymous type was not a problem for the old JVM
backend, but it's difficult to translate it in the IR infrastructure in
the light analysis mode where bodies are not resolved.

When kapt stub generation works with JVM IR enabled,
KaptAnonymousTypeTransformer ensured that backend would not crash and
stubs would contain something useful.

However, this is not happening in light analysis mode tests, which are
supposed to check how compiler behaves in the light analysis mode which
is used in kapt.
This commit is contained in:
Alexander Udalov
2023-06-09 00:44:13 +02:00
parent c95a9ff55e
commit c5f44486a9
4 changed files with 24 additions and 35 deletions
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.jvm
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.resolve.DeclarationSignatureAnonymousTypeTransformer
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.replace
import org.jetbrains.kotlin.types.typeUtil.builtIns
open class ReplaceWithSupertypeAnonymousTypeTransformer : DeclarationSignatureAnonymousTypeTransformer {
override fun transformAnonymousType(descriptor: DeclarationDescriptorWithVisibility, type: KotlinType): KotlinType? =
if (!DescriptorUtils.isLocal(descriptor))
replaceAnonymousTypeWithSuperType(type)
else type
}
fun replaceAnonymousTypeWithSuperType(type: KotlinType): KotlinType {
val declaration = type.constructor.declarationDescriptor as? ClassDescriptor ?: return type
if (KotlinBuiltIns.isArray(type)) {
val elementTypeProjection = type.arguments.singleOrNull()
if (elementTypeProjection != null && !elementTypeProjection.isStarProjection) {
return type.builtIns.getArrayType(
elementTypeProjection.projectionKind,
replaceAnonymousTypeWithSuperType(elementTypeProjection.type)
)
}
}
val actualType = when {
DescriptorUtils.isAnonymousObject(declaration) || DescriptorUtils.isLocal(declaration) -> {
if (type.constructor.supertypes.size == 1) {
replaceAnonymousTypeWithSuperType(type.constructor.supertypes.iterator().next())
} else {
/*
Frontend reports an error on public properties in this case,
but we ignore errors when making stubs, so there should be a reasonable fallback.
*/
type.builtIns.anyType
}
}
else -> type
}
if (actualType.arguments.isEmpty()) return actualType
val arguments = actualType.arguments.map { typeArg ->
if (typeArg.isStarProjection)
return@map typeArg
TypeProjectionImpl(typeArg.projectionKind, replaceAnonymousTypeWithSuperType(typeArg.type))
}
return actualType.replace(newArguments = arguments)
}