[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:
committed by
Space
parent
5461ef6172
commit
7ce3934cf7
+10
@@ -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()
|
||||
|
||||
|
||||
+23
-5
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user