All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.appmetrica.gradle.aarcheck.api.parser.javassist.JavassistMethodParams.kt Maven / Gradle / Ivy

The newest version!
package io.appmetrica.gradle.aarcheck.api.parser.javassist

import io.appmetrica.gradle.aarcheck.api.MethodParam
import javassist.CtBehavior
import javassist.Modifier
import javassist.bytecode.ParameterAnnotationsAttribute
import javassist.bytecode.SignatureAttribute

object JavassistMethodParams {
    // constructors in java inner class has signature with parent class as first parameter
    // but annotation info contains info for only real parameters
    // sample from javap:
    // public com.yandex.aarcheck.library.java.PublicClass$InnerPublicClass(com.yandex.aarcheck.library.java.PublicClass, java.lang.String, int);
    //    descriptor: (Lcom/yandex/aarcheck/library/java/PublicClass;Ljava/lang/String;I)V
    //    ...
    //    RuntimeInvisibleParameterAnnotations:
    //      parameter 0:
    //        0: #26()
    //          androidx.annotation.Nullable
    //      parameter 1:
    //
    //  P.S. in kotlin constructors signature has only real parameters, but descriptor has parent class
    fun from(ctBehavior: CtBehavior): List {
        val signature = SignatureAttribute.toMethodSignature(ctBehavior.genericSignature ?: ctBehavior.signature)
        val params = signature.parameterTypes
        val paramAnnotations = ctBehavior.methodInfo2
            .getAttribute(ParameterAnnotationsAttribute.invisibleTag) as ParameterAnnotationsAttribute?

        val firstParamIsParentClass = ctBehavior.methodInfo.isConstructor && params.isNotEmpty() &&
            ctBehavior.declaringClass?.declaringClass?.name == params[0].jvmTypeName()
        val realParams = if (firstParamIsParentClass) params.drop(1) else params.toList()

        return realParams.mapIndexed { index, param ->
            val annotations = paramAnnotations?.annotations?.getOrNull(index)
            val isVarArgs = Modifier.isVarArgs(ctBehavior.modifiers) && index == realParams.lastIndex
            MethodParam(
                type = JavassistType.from(param).let {
                    if (isVarArgs) it.copy(arrayDim = it.arrayDim - 1) else it
                },
                annotations = annotations?.map(JavassistAnnotation::from) ?: emptyList(),

                isVarArgs = isVarArgs
            )
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy