Skip to content

Commit 7b33aeb

Browse files
committed
Kotlin: Refactor TypeResults
We statically know when we expect to have no signature, so now we tell the type system what we know, rather than having signature always be nullable.
1 parent 0e4066b commit 7b33aeb

File tree

4 files changed

+51
-33
lines changed

4 files changed

+51
-33
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ open class KotlinFileExtractor(
848848
paramTypes
849849
}
850850

851-
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature!! }
851+
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature }
852852

853853
val adjustedReturnType = addJavaLoweringWildcards(getAdjustedReturnType(f), false, (javaCallable as? JavaMethod)?.returnType)
854854
val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext.RETURN, pluginContext) } ?: adjustedReturnType
@@ -3866,7 +3866,7 @@ open class KotlinFileExtractor(
38663866
Pair(paramId, paramType)
38673867
}
38683868

3869-
val paramsSignature = parameters.joinToString(separator = ",", prefix = "(", postfix = ")") { it.second.javaResult.signature!! }
3869+
val paramsSignature = parameters.joinToString(separator = ",", prefix = "(", postfix = ")") { it.second.javaResult.signature }
38703870

38713871
val rt = useType(returnType, TypeContext.RETURN)
38723872
tw.writeMethods(methodId, name, "$name$paramsSignature", rt.javaResult.id, parentId, methodId)
@@ -4041,7 +4041,7 @@ open class KotlinFileExtractor(
40414041
/**
40424042
* Extracts a single wildcard type access expression with no enclosing callable and statement.
40434043
*/
4044-
private fun extractWildcardTypeAccess(type: TypeResults, location: Label<out DbLocation>, parent: Label<out DbExprparent>, idx: Int): Label<out DbExpr> {
4044+
private fun extractWildcardTypeAccess(type: TypeResultsWithoutSignatures, location: Label<out DbLocation>, parent: Label<out DbExprparent>, idx: Int): Label<out DbExpr> {
40454045
val id = tw.getFreshIdLabel<DbWildcardtypeaccess>()
40464046
tw.writeExprs_wildcardtypeaccess(id, type.javaResult.id, parent, idx)
40474047
tw.writeExprsKotlinType(id, type.kotlinResult.id)
@@ -4079,7 +4079,7 @@ open class KotlinFileExtractor(
40794079
* No enclosing callable and statement is extracted, this is useful for type access extraction in field declarations.
40804080
*/
40814081
private fun extractWildcardTypeAccessRecursive(t: IrTypeArgument, location: Label<out DbLocation>, parent: Label<out DbExprparent>, idx: Int) {
4082-
val typeLabels by lazy { TypeResults(getTypeArgumentLabel(t), TypeResult(fakeKotlinType(), "TODO", "TODO")) }
4082+
val typeLabels by lazy { TypeResultsWithoutSignatures(getTypeArgumentLabel(t), TypeResultWithoutSignature(fakeKotlinType(), Unit, "TODO")) }
40834083
when (t) {
40844084
is IrStarProjection -> extractWildcardTypeAccess(typeLabels, location, parent, idx)
40854085
is IrTypeProjection -> when(t.variance) {

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

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -91,25 +91,6 @@ open class KotlinUsesExtractor(
9191
}
9292

9393
data class UseClassInstanceResult(val typeResult: TypeResult<DbClassorinterface>, val javaClass: IrClass)
94-
/**
95-
* A triple of a type's database label, its signature for use in callable signatures, and its short name for use
96-
* in all tables that provide a user-facing type name.
97-
*
98-
* `signature` is a Java primitive name (e.g. "int"), a fully-qualified class name ("package.OuterClass.InnerClass"),
99-
* or an array ("componentSignature[]")
100-
* Type variables have the signature of their upper bound.
101-
* Type arguments and anonymous types do not have a signature.
102-
*
103-
* `shortName` is a Java primitive name (e.g. "int"), a class short name with Java-style type arguments ("InnerClass<E>" or
104-
* "OuterClass<ConcreteArgument>" or "OtherClass<? extends Bound>") or an array ("componentShortName[]").
105-
*/
106-
data class TypeResult<out LabelType>(val id: Label<out LabelType>, val signature: String?, val shortName: String) {
107-
fun <U> cast(): TypeResult<U> {
108-
@Suppress("UNCHECKED_CAST")
109-
return this as TypeResult<U>
110-
}
111-
}
112-
data class TypeResults(val javaResult: TypeResult<DbType>, val kotlinResult: TypeResult<DbKt_type>)
11394

11495
fun useType(t: IrType, context: TypeContext = TypeContext.OTHER): TypeResults {
11596
when(t) {
@@ -125,7 +106,7 @@ open class KotlinUsesExtractor(
125106
val typeId = tw.getLabelFor<DbErrortype>("@\"errorType\"") {
126107
tw.writeError_type(it)
127108
}
128-
return TypeResult(typeId, null, "<CodeQL error type>")
109+
return TypeResult(typeId, "<CodeQL error type>", "<CodeQL error type>")
129110
}
130111

131112
private fun extractErrorType(): TypeResults {
@@ -134,7 +115,7 @@ open class KotlinUsesExtractor(
134115
tw.writeKt_nullable_types(it, javaResult.id)
135116
}
136117
return TypeResults(javaResult,
137-
TypeResult(kotlinTypeId, null, "<CodeQL error type>"))
118+
TypeResult(kotlinTypeId, "<CodeQL error type>", "<CodeQL error type>"))
138119
}
139120

140121
fun getJavaEquivalentClass(c: IrClass) =
@@ -431,9 +412,17 @@ open class KotlinUsesExtractor(
431412
}
432413
}
433414

415+
val fqName = replacedClass.fqNameWhenAvailable
416+
val signature = if (fqName == null) {
417+
logger.error("Unable to find signature/fqName for ${replacedClass.name}")
418+
// TODO: Should we return null here instead?
419+
"<no signature available>"
420+
} else {
421+
fqName.asString()
422+
}
434423
return TypeResult(
435424
classLabel,
436-
replacedClass.fqNameWhenAvailable?.asString(),
425+
signature,
437426
classLabelResult.shortName)
438427
}
439428

@@ -1255,7 +1244,7 @@ open class KotlinUsesExtractor(
12551244

12561245
fun getTypeArgumentLabel(
12571246
arg: IrTypeArgument
1258-
): TypeResult<DbReftype> {
1247+
): TypeResultWithoutSignature<DbReftype> {
12591248

12601249
fun extractBoundedWildcard(wildcardKind: Int, wildcardLabelStr: String, wildcardShortName: String, boundLabel: Label<out DbReftype>): Label<DbWildcard> =
12611250
tw.getLabelFor(wildcardLabelStr) { wildcardLabel ->
@@ -1270,27 +1259,27 @@ open class KotlinUsesExtractor(
12701259
return when (arg) {
12711260
is IrStarProjection -> {
12721261
val anyTypeLabel = useType(pluginContext.irBuiltIns.anyType).javaResult.id.cast<DbReftype>()
1273-
TypeResult(extractBoundedWildcard(1, "@\"wildcard;\"", "?", anyTypeLabel), null, "?")
1262+
TypeResultWithoutSignature(extractBoundedWildcard(1, "@\"wildcard;\"", "?", anyTypeLabel), Unit, "?")
12741263
}
12751264
is IrTypeProjection -> {
12761265
val boundResults = useType(arg.type, TypeContext.GENERIC_ARGUMENT)
12771266
val boundLabel = boundResults.javaResult.id.cast<DbReftype>()
12781267

12791268
return if(arg.variance == Variance.INVARIANT)
1280-
boundResults.javaResult.cast<DbReftype>()
1269+
boundResults.javaResult.cast<DbReftype>().forgetSignature()
12811270
else {
12821271
val keyPrefix = if (arg.variance == Variance.IN_VARIANCE) "super" else "extends"
12831272
val wildcardKind = if (arg.variance == Variance.IN_VARIANCE) 2 else 1
12841273
val wildcardShortName = "? $keyPrefix ${boundResults.javaResult.shortName}"
1285-
TypeResult(
1274+
TypeResultWithoutSignature(
12861275
extractBoundedWildcard(wildcardKind, "@\"wildcard;$keyPrefix{$boundLabel}\"", wildcardShortName, boundLabel),
1287-
null,
1276+
Unit,
12881277
wildcardShortName)
12891278
}
12901279
}
12911280
else -> {
12921281
logger.error("Unexpected type argument.")
1293-
return extractJavaErrorType()
1282+
return extractJavaErrorType().forgetSignature()
12941283
}
12951284
}
12961285
}

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

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

33
import com.github.codeql.KotlinUsesExtractor.LocallyVisibleFunctionLabels
4-
import com.github.codeql.KotlinUsesExtractor.TypeResults
54
import com.github.codeql.utils.versions.FileEntry
65
import java.io.BufferedWriter
76
import java.io.File
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.github.codeql
2+
3+
/**
4+
* A triple of a type's database label, its signature for use in callable signatures, and its short name for use
5+
* in all tables that provide a user-facing type name.
6+
*
7+
* `signature` is a Java primitive name (e.g. "int"), a fully-qualified class name ("package.OuterClass.InnerClass"),
8+
* or an array ("componentSignature[]")
9+
* Type variables have the signature of their upper bound.
10+
* Type arguments and anonymous types do not have a signature.
11+
*
12+
* `shortName` is a Java primitive name (e.g. "int"), a class short name with Java-style type arguments ("InnerClass<E>" or
13+
* "OuterClass<ConcreteArgument>" or "OtherClass<? extends Bound>") or an array ("componentShortName[]").
14+
*/
15+
data class TypeResultGeneric<SignatureType,out LabelType>(val id: Label<out LabelType>, val signature: SignatureType, val shortName: String) {
16+
fun <U> cast(): TypeResult<U> {
17+
@Suppress("UNCHECKED_CAST")
18+
return this as TypeResult<U>
19+
}
20+
}
21+
data class TypeResultsGeneric<SignatureType>(val javaResult: TypeResultGeneric<SignatureType,DbType>, val kotlinResult: TypeResultGeneric<SignatureType,DbKt_type>)
22+
23+
typealias TypeResult<T> = TypeResultGeneric<String,T>
24+
typealias TypeResultWithoutSignature<T> = TypeResultGeneric<Unit,T>
25+
typealias TypeResults = TypeResultsGeneric<String>
26+
typealias TypeResultsWithoutSignatures = TypeResultsGeneric<Unit>
27+
28+
fun <T> TypeResult<T>.forgetSignature(): TypeResultWithoutSignature<T> {
29+
return TypeResultWithoutSignature(this.id, Unit, this.shortName)
30+
}

0 commit comments

Comments
 (0)