Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
beff080
Kotlin: Update kotlin_rules to 2.2.0 and remove support for Kotlin 1.…
andersfugmann Dec 4, 2025
772503b
Kotlin: Remove resource_strip_prefix for kotlin extraction
andersfugmann Dec 4, 2025
bc419fd
Kotlin: Silence compilation warnings
andersfugmann Dec 4, 2025
07e5479
Kotlin: Add support for Kotlin 2.3.0
andersfugmann Dec 4, 2025
cc25d30
Kotlin: Update compiler plugin for Kotlin 2.3.0
andersfugmann Dec 4, 2025
b8d01ed
Kotlin: Fix bazel format and address copilot review comments
andersfugmann Dec 5, 2025
164cae8
Kotlin: Strip prefix when building plugin
andersfugmann Dec 20, 2025
eb37255
Kotlin: Create IrSimpleType factory function to support constructor c…
andersfugmann Jan 5, 2026
4d7c841
Kotlin: Fix spelling
andersfugmann Jan 5, 2026
5552527
Kotlin: Remove obsolete file
andersfugmann Jan 5, 2026
8ee3523
Kotlin: Remove support for Kotlin versions 1.6 and 1.7
andersfugmann Jan 5, 2026
5cdfb77
Kotlin: Add additional warning suppresion to v1_9_0 and remove copy i…
andersfugmann Jan 5, 2026
e1f3d5b
Kotlin: Do not skip writing of getter and setters if the local deliga…
andersfugmann Jan 6, 2026
6d60595
Kotlin: Add changenotes for Kotlin 2.3 support and removal of support…
andersfugmann Jan 8, 2026
9f5de6b
Kotlin: Bump versions in documentation
andersfugmann Jan 7, 2026
d69fe20
Kotlin: Bump upper bound for supported kotlin version in integration …
andersfugmann Jan 7, 2026
939f3e8
Kotlin: Update kotlin compiler version in integration tests
andersfugmann Jan 8, 2026
2757240
Kotlin: Update kotlin serialization integration test to use Kotlin co…
andersfugmann Jan 8, 2026
f6f5b7e
Kotlin: Accept test changes after rebasing to include changes from ht…
andersfugmann Jan 28, 2026
a6f8af0
Kotlin: Accept column location changes in tests
andersfugmann Jan 14, 2026
59fa01e
Kotlin: Add bitwise 'and' operation expected by Kotlin 2.3 compiler t…
andersfugmann Jan 15, 2026
86d9c34
Kotlin: Accept test changes
andersfugmann Jan 15, 2026
31867a5
Kotlin: Accept test changes
andersfugmann Jan 15, 2026
2320d50
Kotlin: Address detections from kotin internal queries
andersfugmann Jan 23, 2026
ab495fa
Kotlin: Inline cast
andersfugmann Jan 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ bazel_dep(name = "bazel_skylib", version = "1.8.1")
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl")
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
bazel_dep(name = "fmt", version = "12.1.0-codeql.1")
bazel_dep(name = "rules_kotlin", version = "2.1.3-codeql.1")
bazel_dep(name = "rules_kotlin", version = "2.2.0-codeql.1")
bazel_dep(name = "gazelle", version = "0.40.0")
bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.1")
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
Expand Down Expand Up @@ -221,10 +221,6 @@ use_repo(
kotlin_extractor_deps,
"codeql_kotlin_defaults",
"codeql_kotlin_embeddable",
"kotlin-compiler-1.6.0",
"kotlin-compiler-1.6.20",
"kotlin-compiler-1.7.0",
"kotlin-compiler-1.7.20",
"kotlin-compiler-1.8.0",
"kotlin-compiler-1.9.0-Beta",
"kotlin-compiler-1.9.20-Beta",
Expand All @@ -234,10 +230,7 @@ use_repo(
"kotlin-compiler-2.1.20-Beta1",
"kotlin-compiler-2.2.0-Beta1",
"kotlin-compiler-2.2.20-Beta2",
"kotlin-compiler-embeddable-1.6.0",
"kotlin-compiler-embeddable-1.6.20",
"kotlin-compiler-embeddable-1.7.0",
"kotlin-compiler-embeddable-1.7.20",
"kotlin-compiler-2.3.0",
"kotlin-compiler-embeddable-1.8.0",
"kotlin-compiler-embeddable-1.9.0-Beta",
"kotlin-compiler-embeddable-1.9.20-Beta",
Expand All @@ -247,10 +240,7 @@ use_repo(
"kotlin-compiler-embeddable-2.1.20-Beta1",
"kotlin-compiler-embeddable-2.2.0-Beta1",
"kotlin-compiler-embeddable-2.2.20-Beta2",
"kotlin-stdlib-1.6.0",
"kotlin-stdlib-1.6.20",
"kotlin-stdlib-1.7.0",
"kotlin-stdlib-1.7.20",
"kotlin-compiler-embeddable-2.3.0",
"kotlin-stdlib-1.8.0",
"kotlin-stdlib-1.9.0-Beta",
"kotlin-stdlib-1.9.20-Beta",
Expand All @@ -260,6 +250,7 @@ use_repo(
"kotlin-stdlib-2.1.20-Beta1",
"kotlin-stdlib-2.2.0-Beta1",
"kotlin-stdlib-2.2.20-Beta2",
"kotlin-stdlib-2.3.0",
)

go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
Expand Down
3 changes: 1 addition & 2 deletions docs/codeql/reusables/supported-versions-compilers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
Java,"Java 7 to 25 [6]_","javac (OpenJDK and Oracle JDK),

Eclipse compiler for Java (ECJ) [7]_",``.java``
Kotlin,"Kotlin 1.6.0 [15]_ to 2.2.2\ *x*","kotlinc",``.kt``
Kotlin,"Kotlin 1.8.0 to 2.3.0\ *x*","kotlinc",``.kt``
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [8]_"
Python [9]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13",Not applicable,``.py``
Ruby [10]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"
Expand All @@ -45,4 +45,3 @@
.. [12] Support for the analysis of Swift requires macOS.
.. [13] Embedded Swift is not supported.
.. [14] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default.
.. [15] Support for Kotlin versions 1.6 and 1.7 is deprecated and will be removed in release 2.24.1.
8 changes: 1 addition & 7 deletions java/kotlin-extractor/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,7 @@ kt_javac_options(
javac_opts = ":javac-options",
kotlinc_opts = ":kotlinc-options-%s" % v,
module_name = "codeql-kotlin-extractor",
# resource_strip_prefix is very nit-picky: the following makes it work from
# `codeql`, `@codeql_kotlin_embeddable` and `semmle-code`
resource_strip_prefix = (
("../%s/" % repo_name() if repo_name() else "") +
("%s/" % package_name() if package_name() else "") +
v
),
resource_strip_prefix = v,
resources = [
":resources-%s" % v,
],
Expand Down
3 changes: 0 additions & 3 deletions java/kotlin-extractor/deps/kotlin-compiler-1.6.0.jar

This file was deleted.

3 changes: 0 additions & 3 deletions java/kotlin-extractor/deps/kotlin-compiler-1.6.20.jar

This file was deleted.

3 changes: 0 additions & 3 deletions java/kotlin-extractor/deps/kotlin-compiler-1.7.0.jar

This file was deleted.

3 changes: 0 additions & 3 deletions java/kotlin-extractor/deps/kotlin-compiler-1.7.20.jar

This file was deleted.

3 changes: 3 additions & 0 deletions java/kotlin-extractor/deps/kotlin-compiler-2.3.0.jar
Git LFS file not shown

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Git LFS file not shown
3 changes: 0 additions & 3 deletions java/kotlin-extractor/deps/kotlin-stdlib-1.6.0.jar

This file was deleted.

3 changes: 0 additions & 3 deletions java/kotlin-extractor/deps/kotlin-stdlib-1.6.20.jar

This file was deleted.

3 changes: 0 additions & 3 deletions java/kotlin-extractor/deps/kotlin-stdlib-1.7.0.jar

This file was deleted.

3 changes: 0 additions & 3 deletions java/kotlin-extractor/deps/kotlin-stdlib-1.7.20.jar

This file was deleted.

3 changes: 3 additions & 0 deletions java/kotlin-extractor/deps/kotlin-stdlib-2.3.0.jar
Git LFS file not shown
2 changes: 1 addition & 1 deletion java/kotlin-extractor/dev/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import io
import os

DEFAULT_VERSION = "2.2.0"
DEFAULT_VERSION = "2.3.0"


def options():
Expand Down
29 changes: 20 additions & 9 deletions java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ open class KotlinFileExtractor(

private fun extractClassModifiers(c: IrClass, id: Label<out DbClassorinterface>) {
with("class modifiers", c) {
@Suppress("REDUNDANT_ELSE_IN_WHEN")
when (c.modality) {
Modality.FINAL -> addModifiers(id, "final")
Modality.SEALED -> addModifiers(id, "sealed")
Expand Down Expand Up @@ -1342,7 +1343,7 @@ open class KotlinFileExtractor(
extractTypeAccessRecursive(substitutedType, location, id, -1)
}
val syntheticParameterNames =
isUnderscoreParameter(vp) ||
vp.origin == IrDeclarationOrigin.UNDERSCORE_PARAMETER ||
((vp.parent as? IrFunction)?.let { hasSynthesizedParameterNames(it) } ?: true)
val javaParameter =
when (val callable = (vp.parent as? IrFunction)?.let { getJavaCallable(it) }) {
Expand Down Expand Up @@ -1644,7 +1645,7 @@ open class KotlinFileExtractor(
extractMethodAndParameterTypeAccesses: Boolean,
typeSubstitution: TypeSubstitution?,
classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?
) =
) : Label<out DbCallable> =
forceExtractFunction(
f,
parentId,
Expand Down Expand Up @@ -2801,6 +2802,7 @@ open class KotlinFileExtractor(

private fun extractBody(b: IrBody, callable: Label<out DbCallable>) {
with("body", b) {
@Suppress("REDUNDANT_ELSE_IN_WHEN")
when (b) {
is IrBlockBody -> extractBlockBody(b, callable)
is IrSyntheticBody -> extractSyntheticBody(b, callable)
Expand Down Expand Up @@ -2834,7 +2836,7 @@ open class KotlinFileExtractor(
when {
kind == IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1)
kind == IrSyntheticBodyKind.ENUM_VALUEOF -> tw.writeKtSyntheticBody(callable, 2)
kind == kind_ENUM_ENTRIES -> tw.writeKtSyntheticBody(callable, 3)
kind == IrSyntheticBodyKind.ENUM_ENTRIES -> tw.writeKtSyntheticBody(callable, 3)
else -> {
logger.errorElement("Unhandled synthetic body kind " + kind, b)
}
Expand Down Expand Up @@ -2973,13 +2975,22 @@ open class KotlinFileExtractor(
val locId = tw.getLocation(s)
tw.writeStmts_block(blockId, parent, idx, callable)
tw.writeHasLocation(blockId, locId)
extractVariable(s.delegate, callable, blockId, 0)

// For Kotlin < 2.3, s.delegate is not-nullable, but for Kotlin >= 2.3
// it is nullable. Cast to nullable to handle both cases uniformly.
// For Kotlin >= 2.3, the cast is redundant, hence the suppress.
@Suppress("USELESS_CAST")
val delegate: IrVariable? = s.delegate as IrVariable?
val propId = tw.getFreshIdLabel<DbKt_property>()
tw.writeKtProperties(propId, s.name.asString())
tw.writeHasLocation(propId, locId)
tw.writeKtPropertyDelegates(propId, useVariable(s.delegate))

if (delegate == null) {
// This is not expected to happen, as the plugin hooks into the pipeline before IR lowering.
logger.errorElement("Local delegated property is missing delegate", s)
} else {
extractVariable(delegate, callable, blockId, 0)
tw.writeKtProperties(propId, s.name.asString())
tw.writeHasLocation(propId, locId)
tw.writeKtPropertyDelegates(propId, useVariable(delegate))
}
// Getter:
extractStatement(s.getter, callable, blockId, 1)
val getterLabel = getLocallyVisibleFunctionLabels(s.getter).function
Expand Down Expand Up @@ -3332,7 +3343,7 @@ open class KotlinFileExtractor(
// that specified the default values, which will in turn dynamically dispatch back to the
// relevant override.
val overriddenCallTarget =
(callTarget as? IrSimpleFunction)?.allOverriddenIncludingSelf()?.firstOrNull {
(callTarget as? IrSimpleFunction)?.allOverridden(includeSelf = true)?.firstOrNull {
it.overriddenSymbols.isEmpty() &&
it.valueParameters.any { p -> p.defaultValue != null }
} ?: callTarget
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -849,9 +849,6 @@ open class KotlinUsesExtractor(
}

private fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults {
if (s.abbreviation != null) {
// TODO: Extract this information
}
// We use this when we don't actually have an IrClass for a class
// we want to refer to
// TODO: Eliminate the need for this if possible
Expand Down Expand Up @@ -939,7 +936,7 @@ open class KotlinUsesExtractor(
return arrayInfo.componentTypeResults
}
owner is IrClass -> {
val args = if (s.codeQlIsRawType()) null else s.arguments
val args = if (s.isRawType()) null else s.arguments

return useSimpleTypeClass(owner, args, s.isNullableCodeQL())
}
Expand Down Expand Up @@ -1836,6 +1833,7 @@ open class KotlinUsesExtractor(

// Note this function doesn't return a signature because type arguments are never
// incorporated into function signatures.
@Suppress("REDUNDANT_ELSE_IN_WHEN")
return when (arg) {
is IrStarProjection -> {
val anyTypeLabel =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.github.codeql

import com.github.codeql.utils.versions.copyParameterToFunction
import com.github.codeql.utils.versions.createImplicitParameterDeclarationWithWrappedDescriptor
import java.lang.annotation.ElementType
import java.util.HashSet
Expand All @@ -21,7 +20,9 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrClassReference
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue
Expand All @@ -31,6 +32,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.constructedClass
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.copyTo
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
Expand Down Expand Up @@ -330,7 +332,7 @@ class MetaAnnotationSupport(
)
return
}
val newParam = copyParameterToFunction(thisReceiever, this)
val newParam = thisReceiever.copyTo(this)
dispatchReceiverParameter = newParam
body =
factory
Expand Down
36 changes: 36 additions & 0 deletions java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.parentClassOrNull
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass
import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
import org.jetbrains.kotlin.name.FqName

// Adapted from Kotlin's interpreter/Utils.kt function 'internalName'
// Translates class names into their JLS section 13.1 binary name,
Expand All @@ -31,6 +33,40 @@ fun getFileClassName(f: IrFile) =
.replaceFirst(Regex("""\.kt$"""), "")
.replaceFirstChar { it.uppercase() }) + "Kt")

fun getFileClassFqName(d: IrDeclaration): FqName? {
// d is in a file class.
// Get the name in a similar way to the compiler's ExternalPackageParentPatcherLowering
// visitMemberAccess/generateOrGetFacadeClass.

// But first, fields aren't IrMemberWithContainerSource, so we need
// to get back to the property (if there is one)
if (d is IrField) {
val propSym = d.correspondingPropertySymbol
if (propSym != null) {
return getFileClassFqName(propSym.owner)
}
}

// Now the main code
if (d is IrMemberWithContainerSource) {
val containerSource = d.containerSource
if (containerSource is FacadeClassSource) {
val facadeClassName = containerSource.facadeClassName
if (facadeClassName != null) {
// TODO: This is really a multifile-class rather than a file-class,
// but for now we treat them the same.
return facadeClassName.fqNameForTopLevelClassMaybeWithDollars
} else {
return containerSource.className.fqNameForTopLevelClassMaybeWithDollars
}
} else {
return null
}
} else {
return null
}
}

fun getIrElementBinaryName(that: IrElement): String {
if (that is IrFile) {
val shortName = getFileClassName(that)
Expand Down
17 changes: 15 additions & 2 deletions java/kotlin-extractor/src/main/kotlin/utils/GetByFqName.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,38 @@ package com.github.codeql.utils

import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name

fun getClassByFqName(pluginContext: IrPluginContext, fqName: FqName): IrClassSymbol? {
val id = ClassId.topLevel(fqName)
return getClassByClassId(pluginContext, id)
}

fun getClassByFqName(pluginContext: IrPluginContext, fqName: String): IrClassSymbol? {
return getClassByFqName(pluginContext, FqName(fqName))
}

fun getClassByClassId(pluginContext: IrPluginContext, id: ClassId): IrClassSymbol? {
return pluginContext.referenceClass(id)
}

fun getFunctionsByFqName(
pluginContext: IrPluginContext,
pkgName: String,
name: String
): Collection<IrSimpleFunctionSymbol> {
return getFunctionsByFqName(pluginContext, FqName(pkgName), Name.identifier(name))
val id = CallableId(FqName(pkgName), Name.identifier(name))
return pluginContext.referenceFunctions(id)
}

fun getPropertiesByFqName(
pluginContext: IrPluginContext,
pkgName: String,
name: String
): Collection<IrPropertySymbol> {
return getPropertiesByFqName(pluginContext, FqName(pkgName), Name.identifier(name))
val id = CallableId(FqName(pkgName), Name.identifier(name))
return pluginContext.referenceProperties(id)
}
Loading
Loading