From b89b6e432a471f962969194bbc8dbcde53995a81 Mon Sep 17 00:00:00 2001 From: Anders Fugmann Date: Thu, 4 Jun 2026 18:12:45 +0200 Subject: [PATCH] Kotlin 2.4.0: Use IrAnnotationImpl for annotation creation In 2.4.0, annotation lists are typed as List and IrConstructorCallImpl does not extend IrAnnotation. Replace all IrConstructorCallImpl.fromSymbolOwner() calls that create annotations with a compat wrapper codeQlAnnotationFromSymbolOwner() that uses IrAnnotationImpl.fromSymbolOwner() in 2.4.0 (returning proper IrAnnotation instances) and IrConstructorCallImpl.fromSymbolOwner() in pre-2.4.0 versions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../src/main/kotlin/KotlinFileExtractor.kt | 4 ++-- .../src/main/kotlin/MetaAnnotationSupport.kt | 13 +++++++------ .../src/main/kotlin/utils/TypeSubstitution.kt | 2 +- .../main/kotlin/utils/versions/v_1_8_0/IrCompat.kt | 11 +++++++++++ .../main/kotlin/utils/versions/v_2_4_0/IrCompat.kt | 13 +++++++++++++ 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index efafbeab3bf..9ec97ed24cc 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -721,7 +721,7 @@ open class KotlinFileExtractor( (it.type as? IrSimpleType)?.classFqName?.asString() != "kotlin.Deprecated" } + // Note we lose any arguments to @java.lang.Deprecated that were written in source. - IrConstructorCallImpl.fromSymbolOwner( + codeQlAnnotationFromSymbolOwner( UNDEFINED_OFFSET, UNDEFINED_OFFSET, jldConstructor.returnType, @@ -2327,7 +2327,7 @@ open class KotlinFileExtractor( getClassByFqName(pluginContext, it)?.let { annotationClass -> annotationClass.owner.declarations.firstIsInstanceOrNull()?.let { annotationConstructor -> - IrConstructorCallImpl.fromSymbolOwner( + codeQlAnnotationFromSymbolOwner( UNDEFINED_OFFSET, UNDEFINED_OFFSET, annotationConstructor.returnType, diff --git a/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt b/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt index ccebbafc7ce..e215b5ca31d 100644 --- a/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt +++ b/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt @@ -1,5 +1,6 @@ package com.github.codeql +import com.github.codeql.utils.versions.codeQlAnnotationFromSymbolOwner import com.github.codeql.utils.versions.codeQlGetValueArgument import com.github.codeql.utils.versions.codeQlPutValueArgument import com.github.codeql.utils.versions.codeQlSetAnnotations @@ -121,7 +122,7 @@ class MetaAnnotationSupport( ) return null } else { - return IrConstructorCallImpl.fromSymbolOwner( + return codeQlAnnotationFromSymbolOwner( containerClass.defaultType, containerConstructor.symbol ) @@ -234,7 +235,7 @@ class MetaAnnotationSupport( ) } - return IrConstructorCallImpl.fromSymbolOwner( + return codeQlAnnotationFromSymbolOwner( UNDEFINED_OFFSET, UNDEFINED_OFFSET, targetConstructor.returnType, @@ -287,7 +288,7 @@ class MetaAnnotationSupport( val targetConstructor = retentionType.declarations.firstIsInstanceOrNull() ?: return null - return IrConstructorCallImpl.fromSymbolOwner( + return codeQlAnnotationFromSymbolOwner( UNDEFINED_OFFSET, UNDEFINED_OFFSET, targetConstructor.returnType, @@ -419,7 +420,7 @@ class MetaAnnotationSupport( .map { it.deepCopyWithSymbols(containerClass) } + listOfNotNull( repeatableContainerAnnotation?.let { - IrConstructorCallImpl.fromSymbolOwner( + codeQlAnnotationFromSymbolOwner( UNDEFINED_OFFSET, UNDEFINED_OFFSET, it.returnType, @@ -467,7 +468,7 @@ class MetaAnnotationSupport( containerClass.symbol, containerClass.defaultType ) - return IrConstructorCallImpl.fromSymbolOwner( + return codeQlAnnotationFromSymbolOwner( UNDEFINED_OFFSET, UNDEFINED_OFFSET, repeatableConstructor.returnType, @@ -493,7 +494,7 @@ class MetaAnnotationSupport( javaAnnotationDocumented?.declarations?.firstIsInstanceOrNull() ?: return null - return IrConstructorCallImpl.fromSymbolOwner( + return codeQlAnnotationFromSymbolOwner( UNDEFINED_OFFSET, UNDEFINED_OFFSET, documentedConstructor.returnType, diff --git a/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt b/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt index b9f0b6e301a..c990edc213f 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt @@ -192,7 +192,7 @@ object RawTypeAnnotation { addConstructor { isPrimary = true } } val constructor = annoClass.constructors.single() - IrConstructorCallImpl.fromSymbolOwner(constructor.constructedClassType, constructor.symbol) + codeQlAnnotationFromSymbolOwner(constructor.constructedClassType, constructor.symbol) } } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/IrCompat.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/IrCompat.kt index 837b7dfdae4..3ba3db2696f 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/IrCompat.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_8_0/IrCompat.kt @@ -5,6 +5,8 @@ import org.jetbrains.kotlin.ir.declarations.IrValueParameter import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression +import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.addAnnotations @@ -58,3 +60,12 @@ fun codeQlSetAnnotations(container: org.jetbrains.kotlin.ir.declarations.IrMutab fun IrFunction.codeQlSetDispatchReceiverParameter(param: IrValueParameter?) { dispatchReceiverParameter = param } + +// In pre-2.4.0, annotations are List so IrConstructorCallImpl works directly. +fun codeQlAnnotationFromSymbolOwner( + startOffset: Int, endOffset: Int, type: IrType, symbol: IrConstructorSymbol, typeArgumentsCount: Int +): IrConstructorCall = + IrConstructorCallImpl.fromSymbolOwner(startOffset, endOffset, type, symbol, typeArgumentsCount) + +fun codeQlAnnotationFromSymbolOwner(type: IrType, symbol: IrConstructorSymbol): IrConstructorCall = + IrConstructorCallImpl.fromSymbolOwner(type, symbol) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt index 1d010b0996c..e388a09c37a 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_2_4_0/IrCompat.kt @@ -8,6 +8,9 @@ import org.jetbrains.kotlin.ir.expressions.IrAnnotation import org.jetbrains.kotlin.ir.expressions.IrConstructorCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression +import org.jetbrains.kotlin.ir.expressions.impl.IrAnnotationImpl +import org.jetbrains.kotlin.ir.expressions.impl.fromSymbolOwner +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.addAnnotations @@ -93,3 +96,13 @@ fun IrFunction.codeQlSetDispatchReceiverParameter(param: IrValueParameter?) { parameters = mutableParams } +// In 2.4.0, annotation lists require IrAnnotation instances. +// Use IrAnnotationImpl.fromSymbolOwner instead of IrConstructorCallImpl.fromSymbolOwner. +fun codeQlAnnotationFromSymbolOwner( + startOffset: Int, endOffset: Int, type: IrType, symbol: IrConstructorSymbol, typeArgumentsCount: Int +): IrConstructorCall = + IrAnnotationImpl.fromSymbolOwner(startOffset, endOffset, type, symbol, typeArgumentsCount) + +fun codeQlAnnotationFromSymbolOwner(type: IrType, symbol: IrConstructorSymbol): IrConstructorCall = + IrAnnotationImpl.fromSymbolOwner(type, symbol) +