Skip to content

Commit 4a2f244

Browse files
Kotlin: Add 2.4.0 API compatibility layer and plugin registration
- Add version-specific compatibility wrappers (v_2_4_0/IrCompat.kt) for removed APIs: valueParameters, extensionReceiverParameter, extensionReceiver, getValueArgument, putValueArgument, valueArgumentsCount, typeArgumentsCount, getTypeArgument, addAnnotations, setAnnotations, setDispatchReceiverParameter - Add pre-2.4.0 pass-through implementations (v_1_8_0/IrCompat.kt) - Migrate plugin registration from ComponentRegistrar to CompilerPluginRegistrar for 2.4.0 (v_2_4_0/Kotlin2ComponentRegistrar.kt) - Add META-INF service file for CompilerPluginRegistrar - Update all extractor source files to use codeQl* compat functions - All versions (1.8.0 through 2.4.0) build successfully Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent ed9e160 commit 4a2f244

15 files changed

Lines changed: 396 additions & 157 deletions

java/kotlin-extractor/src/main/kotlin/KotlinExtractorComponentRegistrar.kt

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,21 @@
33

44
package com.github.codeql
55

6-
import com.intellij.mock.MockProject
7-
import com.intellij.openapi.extensions.LoadingOrder
8-
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
96
import org.jetbrains.kotlin.config.CompilerConfiguration
107

118
class KotlinExtractorComponentRegistrar : Kotlin2ComponentRegistrar() {
12-
override fun registerProjectComponents(
13-
project: MockProject,
14-
configuration: CompilerConfiguration
15-
) {
9+
override fun doRegisterExtensions(configuration: CompilerConfiguration) {
1610
val invocationTrapFile = configuration[KEY_INVOCATION_TRAP_FILE]
1711
if (invocationTrapFile == null) {
1812
throw Exception("Required argument for TRAP invocation file not given")
1913
}
20-
// Register with LoadingOrder.LAST to ensure the extractor runs after other
21-
// IR generation plugins (like kotlinx.serialization) have generated their code.
22-
val extensionPoint = project.extensionArea.getExtensionPoint(IrGenerationExtension.extensionPointName)
23-
extensionPoint.registerExtension(
14+
registerExtractorExtension(
2415
KotlinExtractorExtension(
2516
invocationTrapFile,
2617
configuration[KEY_CHECK_TRAP_IDENTICAL] ?: false,
2718
configuration[KEY_COMPILATION_STARTTIME],
2819
configuration[KEY_EXIT_AFTER_EXTRACTION] ?: false
29-
),
30-
LoadingOrder.LAST,
31-
project
20+
)
3221
)
3322
}
3423
}

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 108 additions & 108 deletions
Large diffs are not rendered by default.

java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
1212
import org.jetbrains.kotlin.ir.declarations.*
1313
import org.jetbrains.kotlin.ir.expressions.*
1414
import org.jetbrains.kotlin.ir.symbols.*
15-
import org.jetbrains.kotlin.ir.types.addAnnotations
15+
import com.github.codeql.utils.versions.codeQlAddAnnotations
1616
import org.jetbrains.kotlin.ir.types.classFqName
1717
import org.jetbrains.kotlin.ir.types.classifierOrNull
1818
import org.jetbrains.kotlin.ir.types.classOrNull
@@ -355,7 +355,7 @@ open class KotlinUsesExtractor(
355355
}
356356

357357
private fun propertySignature(p: IrProperty) =
358-
((p.getter ?: p.setter)?.extensionReceiverParameter?.let {
358+
((p.getter ?: p.setter)?.codeQlExtensionReceiverParameter?.let {
359359
useType(erase(it.type)).javaResult.signature
360360
} ?: "")
361361

@@ -368,7 +368,7 @@ open class KotlinUsesExtractor(
368368
// useDeclarationParent -> useFunction
369369
// -> extractFunctionLaterIfExternalFileMember, which would result for `fun <T> f(t:
370370
// T) { ... }` for example.
371-
(listOfNotNull(d.extensionReceiverParameter) + d.valueParameters)
371+
(listOfNotNull(d.codeQlExtensionReceiverParameter) + d.codeQlValueParameters)
372372
.map { useType(erase(it.type)).javaResult.signature }
373373
.joinToString(separator = ",", prefix = "(", postfix = ")")
374374
is IrProperty -> propertySignature(d) + externalClassExtractor.propertySignature
@@ -488,8 +488,8 @@ open class KotlinUsesExtractor(
488488
val result =
489489
replacementClass.declarations.findSubType<IrSimpleFunction> { replacementDecl ->
490490
replacementDecl.name == f.name &&
491-
replacementDecl.valueParameters.size == f.valueParameters.size &&
492-
replacementDecl.valueParameters.zip(f.valueParameters).all {
491+
replacementDecl.codeQlValueParameters.size == f.codeQlValueParameters.size &&
492+
replacementDecl.codeQlValueParameters.zip(f.codeQlValueParameters).all {
493493
erase(it.first.type) == erase(it.second.type)
494494
}
495495
}
@@ -1265,7 +1265,7 @@ open class KotlinUsesExtractor(
12651265
private fun getWildcardSuppressionDirective(t: IrAnnotationContainer): Boolean? =
12661266
t.getAnnotation(jvmWildcardSuppressionAnnotation)?.let {
12671267
@Suppress("USELESS_CAST") // `as? Boolean` is not needed for Kotlin < 2.1
1268-
(it.getValueArgument(0) as? CodeQLIrConst<Boolean>)?.value as? Boolean ?: true
1268+
(it.codeQlGetValueArgument(0) as? CodeQLIrConst<Boolean>)?.value as? Boolean ?: true
12691269
}
12701270

12711271
private fun addJavaLoweringArgumentWildcards(
@@ -1376,9 +1376,9 @@ open class KotlinUsesExtractor(
13761376
f.parent,
13771377
parentId,
13781378
getFunctionShortName(f).nameInDB,
1379-
(maybeParameterList ?: f.valueParameters).map { it.type },
1379+
(maybeParameterList ?: f.codeQlValueParameters).map { it.type },
13801380
getAdjustedReturnType(f),
1381-
f.extensionReceiverParameter?.type,
1381+
f.codeQlExtensionReceiverParameter?.type,
13821382
getFunctionTypeParameters(f),
13831383
classTypeArgsIncludingOuterClasses,
13841384
overridesCollectionsMethodWithAlteredParameterTypes(f),
@@ -1401,12 +1401,12 @@ open class KotlinUsesExtractor(
14011401
// The name of the function; normally f.name.asString().
14021402
name: String,
14031403
// The types of the value parameters that the functions takes; normally
1404-
// f.valueParameters.map { it.type }.
1404+
// f.codeQlValueParameters.map { it.type }.
14051405
parameterTypes: List<IrType>,
14061406
// The return type of the function; normally f.returnType.
14071407
returnType: IrType,
14081408
// The extension receiver of the function, if any; normally
1409-
// f.extensionReceiverParameter?.type.
1409+
// f.codeQlExtensionReceiverParameter?.type.
14101410
extensionParamType: IrType?,
14111411
// The type parameters of the function. This does not include type parameters of enclosing
14121412
// classes.
@@ -1579,15 +1579,15 @@ open class KotlinUsesExtractor(
15791579
parentClass.fqNameWhenAvailable?.asString() !=
15801580
"java.util.concurrent.ConcurrentHashMap" ||
15811581
getFunctionShortName(f).nameInDB != "keySet" ||
1582-
f.valueParameters.isNotEmpty() ||
1582+
f.codeQlValueParameters.isNotEmpty() ||
15831583
f.returnType.classFqName?.asString() != "kotlin.collections.MutableSet"
15841584
) {
15851585
return f.returnType
15861586
}
15871587

15881588
val otherKeySet =
15891589
parentClass.declarations.findSubType<IrFunction> {
1590-
it.name.asString() == "keySet" && it.valueParameters.size == 1
1590+
it.name.asString() == "keySet" && it.codeQlValueParameters.size == 1
15911591
} ?: return f.returnType
15921592

15931593
return otherKeySet.returnType.codeQlWithHasQuestionMark(false)
@@ -1695,8 +1695,8 @@ open class KotlinUsesExtractor(
16951695
javaClass.declarations.findSubType<IrFunction> { decl ->
16961696
!decl.isFakeOverride &&
16971697
decl.name.asString() == jvmName &&
1698-
decl.valueParameters.size == f.valueParameters.size &&
1699-
decl.valueParameters.zip(f.valueParameters).all { p ->
1698+
decl.codeQlValueParameters.size == f.codeQlValueParameters.size &&
1699+
decl.codeQlValueParameters.zip(f.codeQlValueParameters).all { p ->
17001700
erase(p.first.type).classifierOrNull ==
17011701
erase(p.second.type).classifierOrNull
17021702
}
@@ -2125,7 +2125,7 @@ open class KotlinUsesExtractor(
21252125
}
21262126

21272127
return if (t.arguments.isNotEmpty())
2128-
t.addAnnotations(listOf(RawTypeAnnotation.annotationConstructor))
2128+
t.codeQlAddAnnotations(listOf(RawTypeAnnotation.annotationConstructor))
21292129
else t
21302130
}
21312131
}
@@ -2153,7 +2153,7 @@ open class KotlinUsesExtractor(
21532153
val idxOffset =
21542154
if (
21552155
declarationParent is IrFunction &&
2156-
declarationParent.extensionReceiverParameter != null
2156+
declarationParent.codeQlExtensionReceiverParameter != null
21572157
)
21582158
// For extension functions increase the index to match what the java extractor sees:
21592159
1
@@ -2187,7 +2187,7 @@ open class KotlinUsesExtractor(
21872187
// Gets a field's corresponding property's extension receiver type, if any
21882188
fun getExtensionReceiverType(f: IrField) =
21892189
f.correspondingPropertySymbol?.owner?.let {
2190-
(it.getter ?: it.setter)?.extensionReceiverParameter?.type
2190+
(it.getter ?: it.setter)?.codeQlExtensionReceiverParameter?.type
21912191
}
21922192

21932193
fun getFieldLabel(f: IrField): String {
@@ -2222,14 +2222,14 @@ open class KotlinUsesExtractor(
22222222
val setter = p.setter
22232223

22242224
val func = getter ?: setter
2225-
val ext = func?.extensionReceiverParameter
2225+
val ext = func?.codeQlExtensionReceiverParameter
22262226

22272227
return if (ext == null) {
22282228
"@\"property;{$parentId};${p.name.asString()}\""
22292229
} else {
22302230
val returnType =
22312231
getter?.returnType
2232-
?: setter?.valueParameters?.singleOrNull()?.type
2232+
?: setter?.codeQlValueParameters?.singleOrNull()?.type
22332233
?: pluginContext.irBuiltIns.unitType
22342234
val typeParams = getFunctionTypeParameters(func)
22352235

java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package com.github.codeql
22

3+
import com.github.codeql.utils.versions.codeQlGetValueArgument
4+
import com.github.codeql.utils.versions.codeQlPutValueArgument
5+
import com.github.codeql.utils.versions.codeQlSetAnnotations
6+
import com.github.codeql.utils.versions.codeQlSetDispatchReceiverParameter
37
import com.github.codeql.utils.versions.createImplicitParameterDeclarationWithWrappedDescriptor
48
import java.lang.annotation.ElementType
59
import java.util.HashSet
@@ -95,7 +99,7 @@ class MetaAnnotationSupport(
9599
JvmAnnotationNames.REPEATABLE_ANNOTATION
96100
}
97101
return if (jvmRepeatable != null) {
98-
((jvmRepeatable.getValueArgument(0) as? IrClassReference)?.symbol as? IrClassSymbol)
102+
((jvmRepeatable.codeQlGetValueArgument(0) as? IrClassReference)?.symbol as? IrClassSymbol)
99103
?.owner
100104
} else {
101105
getOrCreateSyntheticRepeatableAnnotationContainer(annotationClass)
@@ -122,7 +126,7 @@ class MetaAnnotationSupport(
122126
containerConstructor.symbol
123127
)
124128
.apply {
125-
putValueArgument(
129+
codeQlPutValueArgument(
126130
0,
127131
IrVarargImpl(
128132
UNDEFINED_OFFSET,
@@ -144,7 +148,7 @@ class MetaAnnotationSupport(
144148

145149
// Taken from AdditionalClassAnnotationLowering.kt
146150
private fun loadAnnotationTargets(targetEntry: IrConstructorCall): Set<KotlinTarget>? {
147-
val valueArgument = targetEntry.getValueArgument(0) as? IrVararg ?: return null
151+
val valueArgument = targetEntry.codeQlGetValueArgument(0) as? IrVararg ?: return null
148152
return valueArgument.elements
149153
.filterIsInstance<IrGetEnumValue>()
150154
.mapNotNull { KotlinTarget.valueOrNull(it.symbol.owner.name.asString()) }
@@ -237,7 +241,7 @@ class MetaAnnotationSupport(
237241
targetConstructor.symbol,
238242
0
239243
)
240-
.apply { putValueArgument(0, vararg) }
244+
.apply { codeQlPutValueArgument(0, vararg) }
241245
}
242246

243247
private val javaAnnotationRetention by lazy {
@@ -263,7 +267,7 @@ class MetaAnnotationSupport(
263267
// Taken from AnnotationCodegen.kt (not available in Kotlin < 1.6.20)
264268
private fun IrClass.getAnnotationRetention(): KotlinRetention? {
265269
val retentionArgument =
266-
getAnnotation(StandardNames.FqNames.retention)?.getValueArgument(0) as? IrGetEnumValue
270+
getAnnotation(StandardNames.FqNames.retention)?.codeQlGetValueArgument(0) as? IrGetEnumValue
267271
?: return null
268272
val retentionArgumentValue = retentionArgument.symbol.owner
269273
return KotlinRetention.valueOf(retentionArgumentValue.name.asString())
@@ -291,7 +295,7 @@ class MetaAnnotationSupport(
291295
0
292296
)
293297
.apply {
294-
putValueArgument(
298+
codeQlPutValueArgument(
295299
0,
296300
IrGetEnumValueImpl(
297301
UNDEFINED_OFFSET,
@@ -333,7 +337,7 @@ class MetaAnnotationSupport(
333337
return
334338
}
335339
val newParam = thisReceiever.copyTo(this)
336-
dispatchReceiverParameter = newParam
340+
codeQlSetDispatchReceiverParameter(newParam)
337341
body =
338342
factory
339343
.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
@@ -406,7 +410,7 @@ class MetaAnnotationSupport(
406410
val repeatableContainerAnnotation =
407411
kotlinAnnotationRepeatableContainer?.constructors?.single()
408412

409-
containerClass.annotations =
413+
codeQlSetAnnotations(containerClass,
410414
annotationClass.annotations
411415
.filter {
412416
it.isAnnotationWithEqualFqName(StandardNames.FqNames.retention) ||
@@ -424,6 +428,7 @@ class MetaAnnotationSupport(
424428
)
425429
}
426430
)
431+
)
427432

428433
containerClass
429434
}
@@ -469,7 +474,7 @@ class MetaAnnotationSupport(
469474
repeatableConstructor.symbol,
470475
0
471476
)
472-
.apply { putValueArgument(0, containerReference) }
477+
.apply { codeQlPutValueArgument(0, containerReference) }
473478
}
474479

475480
private val javaAnnotationDocumented by lazy {

java/kotlin-extractor/src/main/kotlin/TrapWriter.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.codeql
22

33
import com.github.codeql.KotlinUsesExtractor.LocallyVisibleFunctionLabels
4+
import com.github.codeql.utils.versions.codeQlExtensionReceiver
45
import com.semmle.extractor.java.PopulateFile
56
import com.semmle.util.unicode.UTF8Util
67
import java.io.BufferedWriter
@@ -331,7 +332,7 @@ open class FileTrapWriter(
331332
is IrCall -> {
332333
// Calls have incorrect startOffset, so we adjust them:
333334
val dr = e.dispatchReceiver?.let { getStartOffset(it) }
334-
val er = e.extensionReceiver?.let { getStartOffset(it) }
335+
val er = e.codeQlExtensionReceiver?.let { getStartOffset(it) }
335336
offsetMinOf(e.startOffset, dr, er)
336337
}
337338
else -> e.startOffset

java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.github.codeql.comments
22

33
import com.github.codeql.*
44
import com.github.codeql.utils.isLocalFunction
5+
import com.github.codeql.utils.versions.codeQlExtensionReceiverParameter
56
import com.github.codeql.utils.versions.isDispatchReceiver
67
import org.jetbrains.kotlin.ir.IrElement
78
import org.jetbrains.kotlin.ir.declarations.*
@@ -11,7 +12,7 @@ import org.jetbrains.kotlin.ir.util.parentClassOrNull
1112

1213
private fun IrValueParameter.isExtensionReceiver(): Boolean {
1314
val parentFun = parent as? IrFunction ?: return false
14-
return parentFun.extensionReceiverParameter == this
15+
return parentFun.codeQlExtensionReceiverParameter == this
1516
}
1617

1718
open class CommentExtractor(

java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.github.codeql.utils
22

33
import com.github.codeql.utils.versions.CodeQLIrConst
4+
import com.github.codeql.utils.versions.codeQlGetValueArgument
5+
import com.github.codeql.utils.versions.codeQlValueArgumentsCount
46
import org.jetbrains.kotlin.builtins.StandardNames
57
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
68
import org.jetbrains.kotlin.ir.declarations.IrClass
@@ -76,9 +78,9 @@ private fun getSpecialJvmName(f: IrFunction): String? {
7678
fun getJvmName(container: IrAnnotationContainer): String? {
7779
for (a: IrConstructorCall in container.annotations) {
7880
val t = a.type
79-
if (t is IrSimpleType && a.valueArgumentsCount == 1) {
81+
if (t is IrSimpleType && a.codeQlValueArgumentsCount == 1) {
8082
val owner = t.classifier.owner
81-
val v = a.getValueArgument(0)
83+
val v = a.codeQlGetValueArgument(0)
8284
if (owner is IrClass) {
8385
val aPkg = owner.packageFqName?.asString()
8486
val name = owner.name.asString()

java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
1818
import org.jetbrains.kotlin.ir.expressions.impl.*
1919
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
2020
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
21-
import org.jetbrains.kotlin.ir.types.addAnnotations
21+
import com.github.codeql.utils.versions.codeQlAddAnnotations
2222
import org.jetbrains.kotlin.ir.types.classifierOrNull
2323
import org.jetbrains.kotlin.ir.types.makeNotNull
2424
import org.jetbrains.kotlin.ir.types.makeNullable
@@ -202,7 +202,7 @@ fun IrType.toRawType(): IrType =
202202
when (val owner = this.classifier.owner) {
203203
is IrClass -> {
204204
if (this.arguments.isNotEmpty())
205-
this.addAnnotations(listOf(RawTypeAnnotation.annotationConstructor))
205+
this.codeQlAddAnnotations(listOf(RawTypeAnnotation.annotationConstructor))
206206
else this
207207
}
208208
is IrTypeParameter -> owner.superTypes[0].toRawType()
@@ -215,7 +215,7 @@ fun IrType.toRawType(): IrType =
215215
fun IrClass.toRawType(): IrType {
216216
val result = this.typeWith(listOf())
217217
return if (this.typeParameters.isNotEmpty())
218-
result.addAnnotations(listOf(RawTypeAnnotation.annotationConstructor))
218+
result.codeQlAddAnnotations(listOf(RawTypeAnnotation.annotationConstructor))
219219
else result
220220
}
221221

0 commit comments

Comments
 (0)