From 82c41316c60dcb4abce971cfec7ef692d3bb7996 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 21 Nov 2024 15:21:11 +0000 Subject: [PATCH] KE2: Populate Kotlin type nullability and alias information --- .../src/main/kotlin/KotlinFileExtractor.kt | 2 +- .../src/main/kotlin/entities/Types.kt | 38 ++++++++++++------- java/ql/lib/config/semmlecode.dbscheme | 8 ++-- java/ql/lib/semmle/code/Location.qll | 6 ++- java/ql/lib/semmle/code/java/KotlinType.qll | 6 ++- 5 files changed, 38 insertions(+), 22 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 5f8a254ba1cc..7f2b0501a62b 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -2776,7 +2776,7 @@ open class KotlinFileExtractor( val locId = tw.getLocation(ta) // TODO: We don't really want to generate any Java types here; we only want the KT type: val type = useType(ta.expandedType) - tw.writeKt_type_alias(id, ta.name.asString(), type.kotlinResult.id) + TODO() // TODO: KotType tw.writeKt_type_alias(id, ta.name.asString(), type.kotlinResult.id) tw.writeHasLocation(id, locId) // TODO: extract annotations diff --git a/java/kotlin-extractor2/src/main/kotlin/entities/Types.kt b/java/kotlin-extractor2/src/main/kotlin/entities/Types.kt index e012405dd384..18b7a00ead43 100644 --- a/java/kotlin-extractor2/src/main/kotlin/entities/Types.kt +++ b/java/kotlin-extractor2/src/main/kotlin/entities/Types.kt @@ -20,25 +20,37 @@ private fun KotlinUsesExtractor.useClassType( } fun KotlinUsesExtractor.useType(t: KaType?, context: TypeContext = TypeContext.OTHER): TypeResults { - when (t) { + val tr = when (t) { null -> { logger.error("Unexpected null type") return extractErrorType() } - is KaClassType -> return useClassType(t) - is KaFlexibleType -> return useType(t.lowerBound) // TODO: take a more reasoned choice here + is KaClassType -> useClassType(t) + is KaFlexibleType -> useType(t.lowerBound) // TODO: take a more reasoned choice here else -> TODO() } - /* - OLD: KE1 - when (t) { - is IrSimpleType -> return useSimpleType(t, context) - else -> { - logger.error("Unrecognised IrType: " + t.javaClass) - return extractErrorType() - } - } - */ + val javaResult = tr.javaResult + val kotlinResultBase = tr.kotlinResult + val abbreviation = t.abbreviatedType + val kotlinResultAlias = if (abbreviation == null) kotlinResultBase else { + // TODO: this cast is unsafe; .symbol is actually a KaClassLikeSymbol + val classId = addClassLabel(abbreviation.symbol as KaClassSymbol) + val kotlinBaseTypeId = kotlinResultBase.id + val kotlinAliasTypeId = + tw.getLabelFor("@\"kt_type_alias;{$classId};{$kotlinBaseTypeId}\"") { + tw.writeKt_type_aliases(it, classId, kotlinBaseTypeId) + } + TypeResult(kotlinAliasTypeId /* , "TODO", "TODO" */) + } + val kotlinResultNullability = if (t.nullability.isNullable) { + val kotlinAliasTypeId = kotlinResultAlias.id + val kotlinNullableTypeId = + tw.getLabelFor("@\"kt_nullable_type;{$kotlinAliasTypeId}\"") { + tw.writeKt_nullable_types(it, kotlinAliasTypeId) + } + TypeResult(kotlinNullableTypeId /* , "TODO", "TODO" */) + } else kotlinResultAlias + return TypeResults(javaResult, kotlinResultNullability) } private fun KotlinUsesExtractor.extractJavaErrorType(): TypeResult { diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index d162a1bc3f65..c34f54a5b28f 100644 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -478,12 +478,12 @@ kt_nullable_types( ) /** - * `id` is the Kotlin type that is the alias called `name` of `kttypeid`. - * That is, it has been defined by `typealias name = kttypeid`. + * `id` is the Kotlin type that is the alias called `classid` of `kttypeid`. + * That is, it has been defined by `typealias classid = kttypeid`. */ -kt_type_alias( +kt_type_aliases( unique int id: @kt_type_alias, - string name: string ref, + int classid: @reftype ref, int kttypeid: @kt_type ref ) diff --git a/java/ql/lib/semmle/code/Location.qll b/java/ql/lib/semmle/code/Location.qll index abc1d19d0f89..a50efda799d7 100644 --- a/java/ql/lib/semmle/code/Location.qll +++ b/java/ql/lib/semmle/code/Location.qll @@ -42,8 +42,10 @@ predicate hasName(Element e, string name) { or modifiers(e, name) or - kt_type_alias(e, name, _) - or + // TODO: An alias declaration might have a name, but the type that + // uses it doesn't + // or + // kt_type_alias(e, name, _) ktProperties(e, name) or e instanceof ErrorType and name = "" diff --git a/java/ql/lib/semmle/code/java/KotlinType.qll b/java/ql/lib/semmle/code/java/KotlinType.qll index 159484bdc5fb..7735b984acd2 100644 --- a/java/ql/lib/semmle/code/java/KotlinType.qll +++ b/java/ql/lib/semmle/code/java/KotlinType.qll @@ -32,7 +32,9 @@ class KotlinTypeAlias extends KotlinType, @kt_type_alias { result = "{" + this.getKotlinType().toString() + "}" + this.getName() } - override string getName() { kt_type_alias(this, result, _) } + override string getName() { result = this.getAliasClass().getName() } - KotlinType getKotlinType() { kt_type_alias(this, _, result) } + Class getAliasClass() { kt_type_aliases(this, result, _) } + + KotlinType getKotlinType() { kt_type_aliases(this, _, result) } }