@@ -2,18 +2,15 @@ package com.github.codeql
2
2
3
3
import com.github.codeql.comments.CommentExtractor
4
4
import 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.*
8
6
import com.semmle.extractor.java.OdasaOutput
9
7
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
10
- import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
11
8
import org.jetbrains.kotlin.backend.common.lower.parents
12
9
import org.jetbrains.kotlin.backend.common.pop
13
- import org.jetbrains.kotlin.backend.jvm.ir.getAnnotationRetention
14
10
import org.jetbrains.kotlin.builtins.StandardNames
15
11
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
16
12
import org.jetbrains.kotlin.config.JvmAnalysisFlags
13
+ import org.jetbrains.kotlin.config.JvmTarget
17
14
import org.jetbrains.kotlin.descriptors.*
18
15
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
19
16
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
@@ -31,8 +28,32 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
31
28
import org.jetbrains.kotlin.ir.symbols.*
32
29
import org.jetbrains.kotlin.ir.types.*
33
30
import 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
36
57
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
37
58
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
38
59
import org.jetbrains.kotlin.load.java.structure.JavaClass
@@ -471,16 +492,24 @@ open class KotlinFileExtractor(
471
492
extractDeclInitializers(c.declarations, false ) { Pair (blockId, obinitId) }
472
493
}
473
494
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
+
474
503
// Adapted from RepeatedAnnotationLowering.kt
475
504
private fun groupRepeatableAnnotations (annotations : List <IrConstructorCall >): List <IrConstructorCall > {
476
505
if (annotations.size < 2 ) return annotations
477
506
478
- val annotationsByClass = annotations.groupByTo(mutableMapOf ()) { it.symbol.owner.constructedClass }
507
+ val annotationsByClass = annotations.groupByTo(mutableMapOf ()) { it.annotationClass }
479
508
if (annotationsByClass.values.none { it.size > 1 }) return annotations
480
509
481
510
val result = mutableListOf<IrConstructorCall >()
482
511
for (annotation in annotations) {
483
- val annotationClass = annotation.symbol.owner.constructedClass
512
+ val annotationClass = annotation.annotationClass
484
513
val grouped = annotationsByClass.remove(annotationClass) ? : continue
485
514
if (grouped.size < 2 ) {
486
515
result.add(grouped.single())
@@ -501,7 +530,7 @@ open class KotlinFileExtractor(
501
530
// Adapted from RepeatedAnnotationLowering.kt
502
531
private fun getOrCreateContainerClass (annotationClass : IrClass ): IrClass ? {
503
532
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 }
505
534
return if (jvmRepeatable != null ) {
506
535
((jvmRepeatable.getValueArgument(0 ) as ? IrClassReference )?.symbol as ? IrClassSymbol )?.owner
507
536
} else {
@@ -701,8 +730,11 @@ open class KotlinFileExtractor(
701
730
}
702
731
}
703
732
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
706
738
707
739
// Adapted from AdditionalClassAnnotationLowering.kt
708
740
private fun generateTargetAnnotation (c : IrClass ): IrConstructorCall ? {
@@ -751,6 +783,15 @@ open class KotlinFileExtractor(
751
783
}
752
784
}
753
785
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
+
754
795
// Taken from AdditionalClassAnnotationLowering.kt
755
796
private fun generateRetentionAnnotation (irClass : IrClass ): IrConstructorCall ? {
756
797
if (irClass.hasAnnotation(JvmAnnotationNames .RETENTION_ANNOTATION ))
@@ -777,16 +818,46 @@ open class KotlinFileExtractor(
777
818
private val javaAnnotationRepeatable by lazy { referenceExternalClass(" java.lang.annotation.Repeatable" ) }
778
819
private val kotlinAnnotationRepeatableContainer by lazy { referenceExternalClass(" kotlin.jvm.internal.RepeatableContainer" ) }
779
820
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
+
780
851
// Taken from JvmCachedDeclarations.kt
781
852
private fun getOrCreateSyntheticRepeatableAnnotationContainer (annotationClass : IrClass ) =
782
853
globalExtensionState.syntheticRepeatableAnnotationContainers.getOrPut(annotationClass) {
783
854
val containerClass = pluginContext.irFactory.buildClass {
784
855
kind = ClassKind .ANNOTATION_CLASS
785
- name = Name .identifier(JvmAbi . REPEATABLE_ANNOTATION_CONTAINER_NAME )
856
+ name = Name .identifier(" Container " )
786
857
}.apply {
787
858
createImplicitParameterDeclarationWithWrappedDescriptor()
788
859
parent = annotationClass
789
- superTypes = listOf (pluginContext.irBuiltIns.annotationType )
860
+ superTypes = listOf (getAnnotationType( pluginContext) )
790
861
}
791
862
792
863
val propertyName = Name .identifier(" value" )
@@ -795,7 +866,7 @@ open class KotlinFileExtractor(
795
866
containerClass.addConstructor {
796
867
isPrimary = true
797
868
}.apply {
798
- addValueParameter(propertyName, propertyType)
869
+ addValueParameter(propertyName.identifier , propertyType)
799
870
}
800
871
801
872
containerClass.addProperty {
@@ -808,7 +879,7 @@ open class KotlinFileExtractor(
808
879
parent = containerClass
809
880
correspondingPropertySymbol = this @property.symbol
810
881
}
811
- addDefaultGetter(containerClass, pluginContext.irBuiltIns )
882
+ addDefaultGetter(this , containerClass )
812
883
}
813
884
814
885
val repeatableContainerAnnotation = kotlinAnnotationRepeatableContainer?.let { it.constructors.single() }
0 commit comments