@@ -6,6 +6,7 @@ import com.semmle.extractor.java.OdasaOutput
66import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
77import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
88import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
9+ import org.jetbrains.kotlin.descriptors.ClassKind
910import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
1011import org.jetbrains.kotlin.ir.declarations.*
1112import org.jetbrains.kotlin.ir.expressions.IrConst
@@ -48,29 +49,33 @@ open class KotlinUsesExtractor(
4849 TypeResult (fakeKotlinType(), " " , " " )
4950 )
5051
51- @OptIn(kotlin.ExperimentalStdlibApi ::class ) // Annotation required by kotlin versions < 1.5
52- fun extractFileClass (f : IrFile ): Label <out DbClass > {
53- val fileName = f.fileEntry.name
54- val pkg = f.fqName.asString()
55- val defaultName = fileName.replaceFirst(Regex (""" .*[/\\]""" ), " " ).replaceFirst(Regex (""" \.kt$""" ), " " ).replaceFirstChar({ it.uppercase() }) + " Kt"
56- var jvmName = defaultName
57- for (a: IrConstructorCall in f.annotations) {
52+ fun getJvmName (container : IrAnnotationContainer ): String? {
53+ for (a: IrConstructorCall in container.annotations) {
5854 val t = a.type
59- if (t is IrSimpleType && a.valueArgumentsCount == 1 ) {
55+ if (t is IrSimpleType && a.valueArgumentsCount == 1 ) {
6056 val owner = t.classifier.owner
6157 val v = a.getValueArgument(0 )
62- if (owner is IrClass ) {
58+ if (owner is IrClass ) {
6359 val aPkg = owner.packageFqName?.asString()
6460 val name = owner.name.asString()
6561 if (aPkg == " kotlin.jvm" && name == " JvmName" && v is IrConst <* >) {
6662 val value = v.value
67- if (value is String ) {
68- jvmName = value
63+ if (value is String ) {
64+ return value
6965 }
7066 }
7167 }
7268 }
7369 }
70+ return null
71+ }
72+
73+ @OptIn(kotlin.ExperimentalStdlibApi ::class ) // Annotation required by kotlin versions < 1.5
74+ fun extractFileClass (f : IrFile ): Label <out DbClass > {
75+ val fileName = f.fileEntry.name
76+ val pkg = f.fqName.asString()
77+ val defaultName = fileName.replaceFirst(Regex (""" .*[/\\]""" ), " " ).replaceFirst(Regex (""" \.kt$""" ), " " ).replaceFirstChar({ it.uppercase() }) + " Kt"
78+ var jvmName = getJvmName(f) ? : defaultName
7479 val qualClassName = if (pkg.isEmpty()) jvmName else " $pkg .$jvmName "
7580 val label = " @\" class;$qualClassName \" "
7681 val id: Label <DbClass > = tw.getLabelFor(label, {
@@ -668,22 +673,39 @@ open class KotlinUsesExtractor(
668673
669674 private val IrDeclaration .isAnonymousFunction get() = this is IrSimpleFunction && name == SpecialNames .NO_NAME_PROVIDED
670675
671- fun getFunctionShortName (f : IrFunction ) : String {
676+ data class FunctionNames (val nameInDB : String , val kotlinName : String )
677+
678+ fun getFunctionShortName (f : IrFunction ) : FunctionNames {
672679 if (f.origin == IrDeclarationOrigin .LOCAL_FUNCTION_FOR_LAMBDA || f.isAnonymousFunction)
673- return OperatorNameConventions .INVOKE .asString()
680+ return FunctionNames (
681+ OperatorNameConventions .INVOKE .asString(),
682+ OperatorNameConventions .INVOKE .asString())
674683 (f as ? IrSimpleFunction )?.correspondingPropertySymbol?.let {
675684 val propName = it.owner.name.asString()
676- when (f) {
677- it.owner.getter -> return JvmAbi .getterName(propName)
678- it.owner.setter -> return JvmAbi .setterName(propName)
685+ val getter = it.owner.getter
686+ val setter = it.owner.setter
687+
688+ if (it.owner.parentClassOrNull?.kind == ClassKind .ANNOTATION_CLASS ) {
689+ if (getter == null ) {
690+ logger.error(" Expected to find a getter for a property inside an annotation class" )
691+ return FunctionNames (propName, propName)
692+ } else {
693+ val jvmName = getJvmName(getter)
694+ return FunctionNames (jvmName ? : propName, propName)
695+ }
696+ }
697+
698+ when (f) {
699+ getter -> return FunctionNames (getJvmName(getter) ? : JvmAbi .getterName(propName), JvmAbi .getterName(propName))
700+ setter -> return FunctionNames (getJvmName(setter) ? : JvmAbi .setterName(propName), JvmAbi .setterName(propName))
679701 else -> {
680702 logger.error(
681703 " Function has a corresponding property, but is neither the getter nor the setter"
682704 )
683705 }
684706 }
685707 }
686- return f .name.asString()
708+ return FunctionNames (getJvmName(f) ? : f .name.asString(), f.name.asString() )
687709 }
688710
689711 // This excludes class type parameters that show up in (at least) constructors' typeParameters list.
@@ -727,7 +749,7 @@ open class KotlinUsesExtractor(
727749 * allow it to be passed in.
728750 */
729751 fun getFunctionLabel (f : IrFunction , maybeParentId : Label <out DbElement >? , classTypeArgsIncludingOuterClasses : List <IrTypeArgument >? ) =
730- getFunctionLabel(f.parent, maybeParentId, getFunctionShortName(f), f.valueParameters, f.returnType, f.extensionReceiverParameter, getFunctionTypeParameters(f), classTypeArgsIncludingOuterClasses)
752+ getFunctionLabel(f.parent, maybeParentId, getFunctionShortName(f).nameInDB , f.valueParameters, f.returnType, f.extensionReceiverParameter, getFunctionTypeParameters(f), classTypeArgsIncludingOuterClasses)
731753
732754 /*
733755 * This function actually generates the label for a function.
0 commit comments