[FIR] Add type resolution service into SerializationFirSupertypesExtension

This service allows resolve custom user types from plugins, which allows
  to support specifying type arguments of generated supertypes basing
  on arguments passed to annotations
This commit is contained in:
Dmitriy Novozhilov
2022-09-23 12:14:17 +03:00
committed by Space
parent 5461ef6172
commit 7ce3934cf7
11 changed files with 247 additions and 6 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.extensions
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import kotlin.reflect.KClass
abstract class FirSupertypeGenerationExtension(session: FirSession) : FirExtension(session) {
@@ -22,12 +23,21 @@ abstract class FirSupertypeGenerationExtension(session: FirSession) : FirExtensi
abstract fun needTransformSupertypes(declaration: FirClassLikeDeclaration): Boolean
context(TypeResolveServiceContainer)
@Suppress("IncorrectFormatting") // KTIJ-22227
abstract fun computeAdditionalSupertypes(
classLikeDeclaration: FirClassLikeDeclaration,
resolvedSupertypes: List<FirResolvedTypeRef>
): List<FirResolvedTypeRef>
fun interface Factory : FirExtension.Factory<FirSupertypeGenerationExtension>
class TypeResolveServiceContainer(val typeResolver: TypeResolveService)
abstract class TypeResolveService {
abstract fun resolveUserType(type: FirUserTypeRef): FirResolvedTypeRef
}
}
val FirExtensionService.supertypeGenerators: List<FirSupertypeGenerationExtension> by FirExtensionService.registeredExtensions()
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension
import org.jetbrains.kotlin.fir.extensions.extensionService
import org.jetbrains.kotlin.fir.extensions.supertypeGenerators
import org.jetbrains.kotlin.fir.resolve.*
@@ -421,22 +422,39 @@ open class FirSupertypeResolverVisitor(
superTypeRef
}
}.also {
addSupertypesFromExtensions(classLikeDeclaration, it)
addSupertypesFromExtensions(classLikeDeclaration, it, transformer, scopeDeclaration)
}
}
}
private fun <T> List<T>.createCopy(): List<T> = ArrayList(this)
private fun addSupertypesFromExtensions(klass: FirClassLikeDeclaration, supertypeRefs: MutableList<FirResolvedTypeRef>) {
private fun addSupertypesFromExtensions(
klass: FirClassLikeDeclaration,
supertypeRefs: MutableList<FirResolvedTypeRef>,
typeResolveTransformer: FirTransformer<ScopeClassDeclaration>,
scopeDeclaration: ScopeClassDeclaration
) {
if (supertypeGenerationExtensions.isEmpty()) return
for (extension in supertypeGenerationExtensions) {
if (extension.needTransformSupertypes(klass)) {
supertypeRefs += extension.computeAdditionalSupertypes(klass, supertypeRefs)
val typeResolveService = TypeResolveServiceForPlugins(typeResolveTransformer, scopeDeclaration)
with(FirSupertypeGenerationExtension.TypeResolveServiceContainer(typeResolveService)) {
for (extension in supertypeGenerationExtensions) {
if (extension.needTransformSupertypes(klass)) {
supertypeRefs += extension.computeAdditionalSupertypes(klass, supertypeRefs)
}
}
}
}
private class TypeResolveServiceForPlugins(
val typeResolveTransformer: FirTransformer<ScopeClassDeclaration>,
val scopeDeclaration: ScopeClassDeclaration
) : FirSupertypeGenerationExtension.TypeResolveService() {
override fun resolveUserType(type: FirUserTypeRef): FirResolvedTypeRef {
return type.transform(typeResolveTransformer, scopeDeclaration)
}
}
override fun visitTypeAlias(typeAlias: FirTypeAlias, data: Any?) {
// TODO: this if is a temporary hack for built-in types (because we can't load file for them)
if (typeAlias.expandedTypeRef is FirResolvedTypeRef) {