Trying to determine if an instance `Protobuf.Funct...
# kontributors
r
Trying to determine if an instance
Protobuf.Function
has an
override
modifier but don't see anything in the flags for that. Any ideas or has anybody else attempted this before?. I'm in the context of processing annotations. Let me know if #kapt is better suited for this. thanks!
e
the only "override" reference in the proto is exposed in
kotlin-metadata
as the
ProtoBuf.Function.memberKind: MemberKind?
extension, where
MemberKind
is an enum of
DECLARATION, FAKE_OVERRIDE, DELEGATION, SYNTHESIZED
I'm afraid in this case you'll have to use the classic apt APIs
r
Thanks Eugenio, do you have a link to those API's or any pointers on how to go from
Protobuf.Function
to those?
e
so the function must come from an
Element
, no?
r
Comes from
target.classOrPackageProto.functionList
e
ah, damn, you'll need the next version of the lib LOL
r
I do have a
TypeElement
e
ok, so, first of all copy/paste these (new) functions:
Copy code
/**
 * If possible, returns the [ProtoBuf.Function] inside [functionList] represented by [methodElement].
 */
fun getFunctionOrNull(
    methodElement: ExecutableElement,
    nameResolver: NameResolver,
    functionList: List<ProtoBuf.Function>,
    typeUtils: Types
): ProtoBuf.Function? =
    methodElement.getJvmMethodSignature(typeUtils).let { methodSignature ->
        functionList.firstOrNull { methodSignature == it.getJvmMethodSignature(nameResolver) }
    }

/** @see [getFunctionOrNull] */
fun ClassData.getFunctionOrNull(
    methodElement: ExecutableElement,
    typeUtils: Types
) =
    getFunctionOrNull(methodElement, nameResolver, proto.functionList, typeUtils)

/** @see [getFunctionOrNull] */
fun PackageData.getFunctionOrNull(
    methodElement: ExecutableElement,
    typeUtils: Types
) =
    getFunctionOrNull(methodElement, nameResolver, proto.functionList, typeUtils)
with these you can match the Kotlin version of the function with the JVM implementation (they might have different names etc)
r
Right on, will try that and report, thanks!
e
once you have the right
ExecutableElement
, then it's about understanding the class hierarchy and see where that was declarated originally
everything else, by definition, is an override
it's a bit convoluted but annotation processing often is 😐
r
Turns out Java does not have any metadata associated to
override
so I'm assuming the Kotlin compiler just inserts
@Override
annotating the method as such. Can't figure out how to extract the function annotations to see if that is present
e
No no it's not about having an override, that's just a visual indicator: you need to traverse the class/interface hierarchy and check where the method was originally defined
@raulraja if you can't figure out how to do it ping me 🙂
r
But doesn't Kotlin already inserts that annotation in the Metadata? Doing a traversal I have to keep track of parameter variance and compare in a context of subtypes which is not going to be trivial since you can override by subtyping.
e
unfortunately the
@Override
annotation is completely optional on the JVM
r
Cool I'll take a look
Thanks!
actually @raulraja given your use case this is probably what you need ^
r
Is non contemplating the 'override' keyword an overlook in Proto.Function? This feels out too hard for such a simple cal which is to determine if it had an override mod. I'll use that in the meantime but this feels like it was forgot to get included unless I'm missing a major limitation.
e
oh no, keep in mind that the proto only contains the additional information needed to rebuild the Kotlin types from the underlying JVM types
so if it CAN be done through the apt APIs, that's the only way to do it
and it it's in the proto, it means it' can't be done only with the apt APIs
the reason why the proto has so much information is because Kotlin entities can differ quite a lot from the imlementing JVM ones