Hi, I am trying to update a compiler plugin with K...
# k2-adopters
c
Hi, I am trying to update a compiler plugin with K2-support and are trying to generate companion objects for classes implementing a specific interface. Trying to access
FirClassSymbol.resolvedSuperTypeRefs
to inspect and match a specific
ClassId
in
FirDeclarationGenerationExtension.getNestedClassifiersNames
will throw a
Copy code
class org.jetbrains.kotlin.fir.types.impl.FirUserTypeRefImpl cannot be cast to class org.jetbrains.kotlin.fir.types.FirResolvedTypeRef (org.jetbrains.kotlin.fir.types.impl.FirUserTypeRefImpl and org.jetbrains.kotlin.fir.types.FirResolvedTypeRef are in unnamed module of loader java.net.URLClassLoader @4f4073dc)
The old implementation relies on inspection of the class name through PSI element, as the old
ClassDescriptor.getSuperInterfaces()
could fail with stack overflows for classes using generics. This old approach could somehow be replicated, but is there a way to trigger some more reliable resolving of symbols with fully qualified names or inspect the imports from the FIR-context?
k
@dmitriy.novozhilov
d
This is by design, check the corresponding part of the documentation The reason for that is the circular dependency in computation: • to get resolved types of class in the plugin, compiler should run supertypes resolution • to resolve supertypes of class compiler should ask the plugin for generated classes (because generated class can be used as supertype of some class) So it was decided to break this cycle by allowing plugins to see classes which supertypes are not resolved yet
there a way to trigger some more reliable resolving of symbols with fully qualified names or inspect the imports from the FIR-context?
This resolution may change after you generate new classes So no, there is no such mechanism
c
Thanks for the pointers and clarification
@dmitriy.novozhilov I see that the whole lookup mechanism is solely relying on annotations. In our case we are using an empty marker interface to indicate the target classes and don't rely on any internals of the interface. This could of course be changed into an annotation based approach that added the synthesized base interface. However, we like that the purely interface-based approach has the advantage that the type system is immediately visible to the users and makes it easier to discover the various API entry points for our synthesized classes. In this case it is not required to fully resolve the base classes, but would be sufficient to resolve and match the
ClassId
. Wouldn't it be somehow possible to make that information available at an ealier phase, just as it is already possible to lookup specific annotations by FQN? Further, the referenced docs mentions that there are "plans to design some new syntax from passing information" around. Are there other alternatives in the pipeline?
d
In this case it is not required to fully resolve the base classes, but would be sufficient to resolve and match the ClassId
That it was I've told about. Compiler can not correctly resolve supertypes of classes without knowing which classes will be generated by plugins Consider the following case:
Copy code
// FILE: a.kt
package foo

interface MyMarkerInterface

// FILE: b.kt
package bar

import foo.MyMarkerInterface

abstract class Base {
    interface MyMarkerInterface // generated by plugin
}

class Derived : Base() {
    // If `Base` supertype is not resolved yet then it's resolved to foo.MyMarkerInterface
    // Otherwise it resolved to bar.Base.MyMarkerInterface
    class Nested : MyMarkerInterface
}
I understand that this situation is more-or-less abnormal, but compiler should behave correctly and consistently in all possible cases
However, we like that the purely interface-based approach has the advantage that the type system is immediately visible to the users and makes it easier to discover the various API entry points for our synthesized classes.
Visibility for users can be kept by IDE support. E.g. IDE can render generated supertypes as inlay hints (actually, it's a good feature request for IDE plugin)
Further, the referenced docs mentions that there are "plans to design some new syntax from passing information" around. Are there other alternatives in the pipeline?
For now it's planned that this new syntax will be something similar to annotations or it still will be regular annotations with some restrictions
👍 1