Hey folks I'm trying to write kotlin compiler plug...
# compiler
r
Hey folks I'm trying to write kotlin compiler plugin. I published my plugin to gradle portal, and I try to use it in 2 different repos In the first repo it works fine, in the second - no. In the second repository I receive the error when my plugin tries to get a resolved type from method return type The code in those two repos is the same, except in the second one I also use kotlin serialization plugin. I checked - if I disable it, my plugin works fine Does someone know why it may happen and how to fix it?
v
I guess whoever might be able to help at least needs to know which error you get, otherwise it's hard to guess what you problem might be.
r
Here's the stacktrace:
Copy code
Caused by: org.jetbrains.kotlin.utils.exceptions.KotlinIllegalArgumentExceptionWithAttachments: Expected FirResolvedTypeRef with ConeKotlinType but was FirImplicitTypeRefImplWithoutSource
        at org.jetbrains.kotlin.fir.types.FirTypeUtilsKt.getConeType(FirTypeUtils.kt:201)
        at io.github.rastiehaiev.fir.SuspendifyFirSupertypeGenerator.computeAdditionalSupertypes(SuspendifyFirSupertypeGenerator.kt:56)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.addSupertypesFromExtensions(FirSupertypesResolution.kt:495)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.resolveSpecificClassLikeSupertypes$lambda$15(FirSupertypesResolution.kt:472)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.resolveSpecificClassLikeSupertypes(FirSupertypesResolution.kt:402)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.resolveSpecificClassLikeSupertypes(FirSupertypesResolution.kt:445)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.visitRegularClass(FirSupertypesResolution.kt:425)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.visitRegularClass(FirSupertypesResolution.kt:226)
        at org.jetbrains.kotlin.fir.declarations.FirRegularClass.accept(FirRegularClass.kt:48)
        at org.jetbrains.kotlin.fir.declarations.impl.FirFileImpl.acceptChildren(FirFileImpl.kt:57)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.visitDeclarationContent(FirSupertypesResolution.kt:413)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.visitFile(FirSupertypesResolution.kt:593)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverVisitor.visitFile(FirSupertypesResolution.kt:226)
        at org.jetbrains.kotlin.fir.declarations.FirFile.accept(FirFile.kt:42)
        at org.jetbrains.kotlin.fir.resolve.transformers.FirSupertypeResolverTransformer.transformFile(FirSupertypesResolution.kt:71)
        ... 43 more
This happens when I try to do
FirSimpleFunction.returnTypeRef.coneType
Here's my code: https://github.com/rastiehaiev/suspendify/blob/main/plugin-kotlin/src/main/kotlin/io/github/rastiehaiev/fir/SuspendifyFirExtensionRegistrar.kt#L236 (I replaced
coneType
with
coneTypeOrNull
so it doesn't fail compilation, but plugin doesn't generate any methods/classes because of this)
j
Try to apply the plugins in a different order
r
I tried, it didn't help 🙂
b
It is unsafe to use the return type of a declaration during classifier generation. The presence of a
FirSupertypeGenerationExtension
causes all nested classifier declaration generation to happen during the
SUPER_TYPES
phase, when function return types haven't been resolved yet. The serialization plugin has one of these extensions, which is why adding the plugin causes yours to fail. From the stacktrace, I also see a
SuspendifyFirSupertypeGenerator.computeAdditionalSupertypes
call which is not present in your repository, so it would seem you also now have one of these extensions?
r
Hey @bnorm thanks, that explains why it fails in my case.. I had
SuspendifyFirSupertypeGenerator
, but then I removed it (as didn't know how to implement and use it honestly) if I cannot use function/value parameters' return types in
FirSupertypeGenerationExtension
, do you know how can I generate my classes/methods? I implemented IR part, and with current FIR implementation it works, but it fails if I use other plugins, like serialization
So as far as I understand, serialization plugin drags my plugin execution into the SUPER_TYPES phase, so I cannot use return types as at this phase they are not resolved. What I need to achieve is this:
Copy code
@Suspendify
class Repository {
   fun save(id: String): Entity { /*…*/ }
}

fun main() = runBlocking {
    val repo = Repository()
    
    // 'suspendify' is generated by plugin:
    val suspendifiedRepository = repo.suspendify(with = <http://Dispatchers.IO|Dispatchers.IO>)
    
    // 'save' is also generated by plugin, and it's suspend:
    suspendifiedRepository.save("123")
}
To generate the
save
function in FIR, I need to know function's return type and value parameter return type If I don't generate this method in FIR, the IDE will not "see" it. What is the best practice to achieve my idea?
d
But why do you generate this function with
FirSupertypeGenerationExtension
? For generation of new members there is a
FirDeclarationGenerationExtension.generateFunctions
method, which is called at
STATUS
phase or later. At this phase all explicitly written types on functions are resolved and you can access them. Note that it won't work for implicit types and there is no way to workaround it:
Copy code
class Repository {
   fun save(id: String) = createEntity(...)
}
In this case the return type of
save
function will be computed at
IMPLICIT_TYPES_BODY_RESOLVE
, which is too late
r
I don't generate function in
FirSupertypeGenerationExtension
, I do it in `FirDeclarationGenerationExtension`: https://github.com/rastiehaiev/suspendify/blob/main/plugin-kotlin/src/main/kotlin/io/github/rastiehaiev/fir/SuspendifyFirExtensionRegistrar.kt#L127 I don't use
FirSupertypeGenerationExtension
at all. As far as I understood, kotlin serialization plugin forces my plugin to execute in earlier stage (SUPER_TYPES), where the resolving isn't done yet. That's why my plugin doesn't work
d
The problem here that you collect information about functions during class generation, not members for class generation. You should move the computation of
toFunction
from line 97 somewhere to
generateFunctions
1
r
okay, I'll try, thanks!
it worked!
👍 1
thank you!
👌 1