Kotlin: Fix build for 1.8.0-Beta

The build no longer works for Kotlin < 1.8: We get

    error: class 'org.jetbrains.kotlin.ir.IrElement' was compiled
           with an incompatible version of Kotlin. The binary version
           of its metadata is 1.8.0, expected version is 1.6.0.
This commit is contained in:
Ian Lynagh
2022-11-21 19:56:22 +00:00
parent 6623e5fbf3
commit f7d8d16ed3
11 changed files with 71 additions and 9 deletions

View File

@@ -25,7 +25,7 @@ def version_string_to_tuple(version):
ci_version = '1.7.20'
# Version numbers in the list need to be in semantically increasing order
many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20' ]
many_versions = [ '1.4.32', '1.5.0', '1.5.10', '1.5.20', '1.5.30', '1.6.0', '1.6.20', '1.7.0', '1.7.20', '1.8.0-Beta' ]
many_versions_tuples = [version_string_to_tuple(v) for v in many_versions]

View File

@@ -3,9 +3,11 @@ package com.github.codeql
import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption
import org.jetbrains.kotlin.compiler.plugin.CliOption
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.CompilerConfigurationKey
@OptIn(ExperimentalCompilerApi::class)
class KotlinExtractorCommandLineProcessor : CommandLineProcessor {
override val pluginId = "kotlin-extractor"

View File

@@ -1,10 +1,15 @@
// For ComponentRegistrar
@file:Suppress("DEPRECATION")
package com.github.codeql
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
import com.intellij.mock.MockProject
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.CompilerConfiguration
@OptIn(ExperimentalCompilerApi::class)
class KotlinExtractorComponentRegistrar : ComponentRegistrar {
override fun registerProjectComponents(
project: MockProject,

View File

@@ -1709,6 +1709,10 @@ open class KotlinFileExtractor(
when (b.kind) {
IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1)
IrSyntheticBodyKind.ENUM_VALUEOF -> tw.writeKtSyntheticBody(callable, 2)
else -> {
// TODO: Support IrSyntheticBodyKind.ENUM_ENTRIES
logger.errorElement("Unhandled synthetic body kind " + b.kind.javaClass, b)
}
}
}
}
@@ -2400,7 +2404,7 @@ open class KotlinFileExtractor(
private fun findTopLevelFunctionOrWarn(functionFilter: String, type: String, parameterTypes: Array<String>, warnAgainstElement: IrElement): IrFunction? {
val fn = pluginContext.referenceFunctions(FqName(functionFilter))
val fn = getFunctionsByFqName(pluginContext, functionFilter)
.firstOrNull { fnSymbol ->
fnSymbol.owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type &&
fnSymbol.owner.valueParameters.map { it.type.classFqName?.asString() }.toTypedArray() contentEquals parameterTypes
@@ -2419,7 +2423,7 @@ open class KotlinFileExtractor(
private fun findTopLevelPropertyOrWarn(propertyFilter: String, type: String, warnAgainstElement: IrElement): IrProperty? {
val prop = pluginContext.referenceProperties(FqName(propertyFilter))
val prop = getPropertiesByFqName(pluginContext, propertyFilter)
.firstOrNull { it.owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type }
?.owner

View File

@@ -41,7 +41,7 @@ open class KotlinUsesExtractor(
val globalExtensionState: KotlinExtractorGlobalState
) {
fun referenceExternalClass(name: String) =
pluginContext.referenceClass(FqName(name))?.owner.also {
getClassByFqName(pluginContext, FqName(name))?.owner.also {
if (it == null)
logger.warn("Unable to resolve external class $name")
else
@@ -118,7 +118,7 @@ open class KotlinUsesExtractor(
}
fun getJavaEquivalentClass(c: IrClass) =
getJavaEquivalentClassId(c)?.let { pluginContext.referenceClass(it.asSingleFqName()) }?.owner
getJavaEquivalentClassId(c)?.let { getClassByFqName(pluginContext, it.asSingleFqName()) }?.owner
/**
* Gets a KotlinFileExtractor based on this one, except it attributes locations to the file that declares the given class.
@@ -328,7 +328,7 @@ open class KotlinUsesExtractor(
return@getOrPut null
}
val result = pluginContext.referenceClass(qualifiedName)?.owner
val result = getClassByFqName(pluginContext, qualifiedName)?.owner
if (result != null) {
logger.info("Replaced synthetic class ${c.name} with its real equivalent")
return@getOrPut result
@@ -337,7 +337,7 @@ open class KotlinUsesExtractor(
// The above doesn't work for (some) generated nested classes, such as R$id, which should be R.id
val fqn = qualifiedName.asString()
if (fqn.indexOf('$') >= 0) {
val nested = pluginContext.referenceClass(FqName(fqn.replace('$', '.')))?.owner
val nested = getClassByFqName(pluginContext, fqn.replace('$', '.'))?.owner
if (nested != null) {
logger.info("Replaced synthetic nested class ${c.name} with its real equivalent")
return@getOrPut nested
@@ -454,7 +454,7 @@ open class KotlinUsesExtractor(
}
fun tryGetPair(arity: Int): Pair<IrClass, List<IrTypeArgument>?>? {
val replaced = pluginContext.referenceClass(fqName)?.owner ?: return null
val replaced = getClassByFqName(pluginContext, fqName)?.owner ?: return null
return Pair(replaced, List(arity) { makeTypeProjection(pluginContext.irBuiltIns.anyNType, Variance.INVARIANT) })
}

View File

@@ -7,6 +7,7 @@ import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.name.FqName
import com.github.codeql.utils.*
class PrimitiveTypeMapping(val logger: Logger, val pluginContext: IrPluginContext) {
fun getPrimitiveInfo(s: IrSimpleType) =
@@ -25,7 +26,7 @@ class PrimitiveTypeMapping(val logger: Logger, val pluginContext: IrPluginContex
)
private fun findClass(fqName: String, fallback: IrClass): IrClass {
val symbol = pluginContext.referenceClass(FqName(fqName))
val symbol = getClassByFqName(pluginContext, fqName)
if(symbol == null) {
logger.warn("Can't find $fqName")
// Do the best we can

View File

@@ -0,0 +1,33 @@
package com.github.codeql.utils
import org.jetbrains.kotlin.backend.common.extensions.FirIncompatiblePluginAPI
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.name.FqName
fun getClassByFqName(pluginContext: IrPluginContext, fqName: String): IrClassSymbol? {
return getClassByFqName(pluginContext, FqName(fqName))
}
fun getClassByFqName(pluginContext: IrPluginContext, fqName: FqName): IrClassSymbol? {
@OptIn(FirIncompatiblePluginAPI::class)
return pluginContext.referenceClass(fqName)
}
fun getFunctionsByFqName(pluginContext: IrPluginContext, fqName: String): Collection<IrSimpleFunctionSymbol> {
return getFunctionsByFqName(pluginContext, FqName(fqName))
}
fun getFunctionsByFqName(pluginContext: IrPluginContext, fqName: FqName): Collection<IrSimpleFunctionSymbol> {
@OptIn(FirIncompatiblePluginAPI::class)
return pluginContext.referenceFunctions(fqName)
}
fun getPropertiesByFqName(pluginContext: IrPluginContext, fqName: String): Collection<IrPropertySymbol> {
return getPropertiesByFqName(pluginContext, FqName(fqName))
}
fun getPropertiesByFqName(pluginContext: IrPluginContext, fqName: FqName): Collection<IrPropertySymbol> {
@OptIn(FirIncompatiblePluginAPI::class)
return pluginContext.referenceProperties(fqName)
}

View File

@@ -0,0 +1,4 @@
package org.jetbrains.kotlin.compiler.plugin
@RequiresOptIn("This API is experimental. There are no stability guarantees for it")
annotation class ExperimentalCompilerApi

View File

@@ -0,0 +1,5 @@
package org.jetbrains.kotlin.backend.common.extensions
@RequiresOptIn("This API is not available after FIR")
annotation class FirIncompatiblePluginAPI

View File

@@ -0,0 +1,4 @@
package com.github.codeql
// The compiler provides the annotation class, so we don't need to do
// anything

View File

@@ -0,0 +1,4 @@
package com.github.codeql
// The compiler provides the annotation class, so we don't need to do
// anything