@@ -2,18 +2,15 @@ package com.github.codeql
22
33import com.github.codeql.comments.CommentExtractor
44import com.github.codeql.utils.*
5- import com.github.codeql.utils.versions.allOverriddenIncludingSelf
6- import com.github.codeql.utils.versions.functionN
7- import com.github.codeql.utils.versions.isUnderscoreParameter
5+ import com.github.codeql.utils.versions.*
86import com.semmle.extractor.java.OdasaOutput
97import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
10- import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
118import org.jetbrains.kotlin.backend.common.lower.parents
129import org.jetbrains.kotlin.backend.common.pop
13- import org.jetbrains.kotlin.backend.jvm.ir.getAnnotationRetention
1410import org.jetbrains.kotlin.builtins.StandardNames
1511import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
1612import org.jetbrains.kotlin.config.JvmAnalysisFlags
13+ import org.jetbrains.kotlin.config.JvmTarget
1714import org.jetbrains.kotlin.descriptors.*
1815import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
1916import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
@@ -31,8 +28,32 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
3128import org.jetbrains.kotlin.ir.symbols.*
3229import org.jetbrains.kotlin.ir.types.*
3330import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
34- import org.jetbrains.kotlin.ir.util.*
35- import org.jetbrains.kotlin.load.java.JvmAbi
31+ import org.jetbrains.kotlin.ir.util.companionObject
32+ import org.jetbrains.kotlin.ir.util.constructedClass
33+ import org.jetbrains.kotlin.ir.util.constructors
34+ import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
35+ import org.jetbrains.kotlin.ir.util.defaultType
36+ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
37+ import org.jetbrains.kotlin.ir.util.getAnnotation
38+ import org.jetbrains.kotlin.ir.util.hasAnnotation
39+ import org.jetbrains.kotlin.ir.util.hasEqualFqName
40+ import org.jetbrains.kotlin.ir.util.hasInterfaceParent
41+ import org.jetbrains.kotlin.ir.util.isAnonymousObject
42+ import org.jetbrains.kotlin.ir.util.isFakeOverride
43+ import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction
44+ import org.jetbrains.kotlin.ir.util.isInterface
45+ import org.jetbrains.kotlin.ir.util.isLocal
46+ import org.jetbrains.kotlin.ir.util.isNonCompanionObject
47+ import org.jetbrains.kotlin.ir.util.isSuspend
48+ import org.jetbrains.kotlin.ir.util.isSuspendFunctionOrKFunction
49+ import org.jetbrains.kotlin.ir.util.isVararg
50+ import org.jetbrains.kotlin.ir.util.kotlinFqName
51+ import org.jetbrains.kotlin.ir.util.packageFqName
52+ import org.jetbrains.kotlin.ir.util.parentAsClass
53+ import org.jetbrains.kotlin.ir.util.parentClassOrNull
54+ import org.jetbrains.kotlin.ir.util.primaryConstructor
55+ import org.jetbrains.kotlin.ir.util.render
56+ import org.jetbrains.kotlin.ir.util.target
3657import org.jetbrains.kotlin.load.java.JvmAnnotationNames
3758import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
3859import org.jetbrains.kotlin.load.java.structure.JavaClass
@@ -471,16 +492,24 @@ open class KotlinFileExtractor(
471492 extractDeclInitializers(c.declarations, false ) { Pair (blockId, obinitId) }
472493 }
473494
495+ // Taken from AdditionalIrUtils.kt (not available in Kotlin < 1.6)
496+ private val IrConstructorCall .annotationClass
497+ get() = this .symbol.owner.constructedClass
498+
499+ // Taken from AdditionalIrUtils.kt (not available in Kotlin < 1.6)
500+ private fun IrConstructorCall.isAnnotationWithEqualFqName (fqName : FqName ): Boolean =
501+ annotationClass.hasEqualFqName(fqName)
502+
474503 // Adapted from RepeatedAnnotationLowering.kt
475504 private fun groupRepeatableAnnotations (annotations : List <IrConstructorCall >): List <IrConstructorCall > {
476505 if (annotations.size < 2 ) return annotations
477506
478- val annotationsByClass = annotations.groupByTo(mutableMapOf ()) { it.symbol.owner.constructedClass }
507+ val annotationsByClass = annotations.groupByTo(mutableMapOf ()) { it.annotationClass }
479508 if (annotationsByClass.values.none { it.size > 1 }) return annotations
480509
481510 val result = mutableListOf<IrConstructorCall >()
482511 for (annotation in annotations) {
483- val annotationClass = annotation.symbol.owner.constructedClass
512+ val annotationClass = annotation.annotationClass
484513 val grouped = annotationsByClass.remove(annotationClass) ? : continue
485514 if (grouped.size < 2 ) {
486515 result.add(grouped.single())
@@ -501,7 +530,7 @@ open class KotlinFileExtractor(
501530 // Adapted from RepeatedAnnotationLowering.kt
502531 private fun getOrCreateContainerClass (annotationClass : IrClass ): IrClass ? {
503532 val metaAnnotations = annotationClass.annotations
504- val jvmRepeatable = metaAnnotations.find { it.isAnnotation( JvmAnnotationNames .REPEATABLE_ANNOTATION ) }
533+ val jvmRepeatable = metaAnnotations.find { it.symbol.owner.parentAsClass.fqNameWhenAvailable == JvmAnnotationNames .REPEATABLE_ANNOTATION }
505534 return if (jvmRepeatable != null ) {
506535 ((jvmRepeatable.getValueArgument(0 ) as ? IrClassReference )?.symbol as ? IrClassSymbol )?.owner
507536 } else {
@@ -701,8 +730,11 @@ open class KotlinFileExtractor(
701730 }
702731 }
703732
704- // TODO: find out if we can spot when we're building for JVM <= 7 and omit the Java 8-only targets in that case.
705- private fun getAnnotationTargetMap () = jvm8TargetMap
733+ private fun getAnnotationTargetMap () =
734+ if (pluginContext.platform?.any { it.targetPlatformVersion == JvmTarget .JVM_1_6 } == true )
735+ jvm6TargetMap
736+ else
737+ jvm8TargetMap
706738
707739 // Adapted from AdditionalClassAnnotationLowering.kt
708740 private fun generateTargetAnnotation (c : IrClass ): IrConstructorCall ? {
@@ -751,6 +783,15 @@ open class KotlinFileExtractor(
751783 }
752784 }
753785
786+ // Taken from AnnotationCodegen.kt (not available in Kotlin < 1.6.20)
787+ private fun IrClass.getAnnotationRetention (): KotlinRetention ? {
788+ val retentionArgument =
789+ getAnnotation(StandardNames .FqNames .retention)?.getValueArgument(0 )
790+ as ? IrGetEnumValue ? : return null
791+ val retentionArgumentValue = retentionArgument.symbol.owner
792+ return KotlinRetention .valueOf(retentionArgumentValue.name.asString())
793+ }
794+
754795 // Taken from AdditionalClassAnnotationLowering.kt
755796 private fun generateRetentionAnnotation (irClass : IrClass ): IrConstructorCall ? {
756797 if (irClass.hasAnnotation(JvmAnnotationNames .RETENTION_ANNOTATION ))
@@ -777,16 +818,46 @@ open class KotlinFileExtractor(
777818 private val javaAnnotationRepeatable by lazy { referenceExternalClass(" java.lang.annotation.Repeatable" ) }
778819 private val kotlinAnnotationRepeatableContainer by lazy { referenceExternalClass(" kotlin.jvm.internal.RepeatableContainer" ) }
779820
821+ // Taken from declarationBuilders.kt (not available in Kotlin < 1.6):
822+ private fun addDefaultGetter (p : IrProperty , parentClass : IrClass ) {
823+ val field = p.backingField!!
824+ p.addGetter {
825+ origin = IrDeclarationOrigin .DEFAULT_PROPERTY_ACCESSOR
826+ returnType = field.type
827+ }.apply {
828+ dispatchReceiverParameter = copyParameterToFunction(parentClass.thisReceiver!! , this )
829+ body = factory.createBlockBody(
830+ UNDEFINED_OFFSET , UNDEFINED_OFFSET , listOf (
831+ IrReturnImpl (
832+ UNDEFINED_OFFSET , UNDEFINED_OFFSET ,
833+ pluginContext.irBuiltIns.nothingType,
834+ symbol,
835+ IrGetFieldImpl (
836+ UNDEFINED_OFFSET , UNDEFINED_OFFSET ,
837+ field.symbol,
838+ field.type,
839+ IrGetValueImpl (
840+ UNDEFINED_OFFSET , UNDEFINED_OFFSET ,
841+ dispatchReceiverParameter!! .type,
842+ dispatchReceiverParameter!! .symbol
843+ )
844+ )
845+ )
846+ )
847+ )
848+ }
849+ }
850+
780851 // Taken from JvmCachedDeclarations.kt
781852 private fun getOrCreateSyntheticRepeatableAnnotationContainer (annotationClass : IrClass ) =
782853 globalExtensionState.syntheticRepeatableAnnotationContainers.getOrPut(annotationClass) {
783854 val containerClass = pluginContext.irFactory.buildClass {
784855 kind = ClassKind .ANNOTATION_CLASS
785- name = Name .identifier(JvmAbi . REPEATABLE_ANNOTATION_CONTAINER_NAME )
856+ name = Name .identifier(" Container " )
786857 }.apply {
787858 createImplicitParameterDeclarationWithWrappedDescriptor()
788859 parent = annotationClass
789- superTypes = listOf (pluginContext.irBuiltIns.annotationType )
860+ superTypes = listOf (getAnnotationType( pluginContext) )
790861 }
791862
792863 val propertyName = Name .identifier(" value" )
@@ -795,7 +866,7 @@ open class KotlinFileExtractor(
795866 containerClass.addConstructor {
796867 isPrimary = true
797868 }.apply {
798- addValueParameter(propertyName, propertyType)
869+ addValueParameter(propertyName.identifier , propertyType)
799870 }
800871
801872 containerClass.addProperty {
@@ -808,7 +879,7 @@ open class KotlinFileExtractor(
808879 parent = containerClass
809880 correspondingPropertySymbol = this @property.symbol
810881 }
811- addDefaultGetter(containerClass, pluginContext.irBuiltIns )
882+ addDefaultGetter(this , containerClass )
812883 }
813884
814885 val repeatableContainerAnnotation = kotlinAnnotationRepeatableContainer?.let { it.constructors.single() }
0 commit comments