Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cd07cc4

Browse files
smowtonigfoo
authored andcommitted
Class trap labels: include outer type parameters
1 parent 94efb42 commit cd07cc4

2 files changed

Lines changed: 29 additions & 8 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ open class KotlinFileExtractor(
151151
logger.warn(Severity.ErrorSevere, "Instance without type arguments: " + c.name.asString())
152152
}
153153

154-
val classLabelResults = getClassLabel(c, typeArgs)
154+
val classLabelResults = getClassLabel(c, argsIncludingOuterClasses)
155155
val id = tw.getLabelFor<DbClassorinterface>(classLabelResults.classLabel)
156156
val pkg = c.packageFqName?.asString() ?: ""
157157
val cls = classLabelResults.shortName

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

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.github.codeql
33
import com.github.codeql.utils.substituteTypeArguments
44
import com.semmle.extractor.java.OdasaOutput
55
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
6+
import org.jetbrains.kotlin.backend.common.lower.parents
7+
import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
68
import org.jetbrains.kotlin.backend.jvm.codegen.isRawType
79
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
810
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
@@ -140,6 +142,24 @@ open class KotlinUsesExtractor(
140142
} ?: argsIncludingOuterClasses
141143
}
142144

145+
// The Kotlin compiler internal representation of Outer<A, B>.Inner<C, D>.InnerInner<E, F> is InnerInner<E, F, C, D, A, B>. This function returns [A, B, C, D, E, F].
146+
fun orderTypeArgsLeftToRight(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?): List<IrTypeArgument>? {
147+
if(argsIncludingOuterClasses.isNullOrEmpty())
148+
return argsIncludingOuterClasses
149+
val ret = ArrayList<IrTypeArgument>()
150+
// Iterate over nested inner classes starting at `c`'s surrounding top-level or static nested class and ending at `c`, from the outermost inwards:
151+
val parentsList = c.parentsWithSelf.toList()
152+
val firstOuterClassIdx = parentsList.indexOfFirst { it is IrClass && !it.isInner }
153+
val truncatedParents = if (firstOuterClassIdx == -1) parentsList else parentsList.subList(0, firstOuterClassIdx + 1)
154+
for(parent in truncatedParents.reversed()) {
155+
if(parent is IrClass) {
156+
val firstArgIdx = argsIncludingOuterClasses.size - (ret.size + parent.typeParameters.size)
157+
ret.addAll(argsIncludingOuterClasses.subList(firstArgIdx, firstArgIdx + parent.typeParameters.size))
158+
}
159+
}
160+
return ret
161+
}
162+
143163
// `typeArgs` can be null to describe a raw generic type.
144164
// For non-generic types it will be zero-length list.
145165
fun useClassInstance(c: IrClass, typeArgs: List<IrTypeArgument>?, inReceiverContext: Boolean = false): UseClassInstanceResult {
@@ -199,7 +219,7 @@ open class KotlinUsesExtractor(
199219
// For all purposes ignore type arguments relating to outer classes.
200220
val typeArgs = removeOuterClassTypeArgs(c, argsIncludingOuterClasses)
201221

202-
val classLabelResult = getClassLabel(c, typeArgs)
222+
val classLabelResult = getClassLabel(c, argsIncludingOuterClasses)
203223

204224
var instanceSeenBefore = true
205225

@@ -733,10 +753,10 @@ class X {
733753
/**
734754
* This returns the `X` in c's label `@"class;X"`.
735755
*
736-
* `typeArgs` can be null to describe a raw generic type.
756+
* `argsIncludingOuterClasses` can be null to describe a raw generic type.
737757
* For non-generic types it will be zero-length list.
738758
*/
739-
private fun getUnquotedClassLabel(c: IrClass, typeArgs: List<IrTypeArgument>?): ClassLabelResults {
759+
private fun getUnquotedClassLabel(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?): ClassLabelResults {
740760
val pkg = c.packageFqName?.asString() ?: ""
741761
val cls = c.name.asString()
742762
val label = when (val parent = c.parent) {
@@ -753,14 +773,15 @@ class X {
753773
}
754774
}
755775

756-
val typeArgLabels = typeArgs?.map { getTypeArgumentLabel(it) }
776+
val reorderedArgs = orderTypeArgsLeftToRight(c, argsIncludingOuterClasses)
777+
val typeArgLabels = reorderedArgs?.map { getTypeArgumentLabel(it) }
757778
val typeArgsShortName =
758779
if (typeArgLabels == null)
759780
"<>"
760781
else if(typeArgLabels.isEmpty())
761782
""
762783
else
763-
typeArgLabels.joinToString(prefix = "<", postfix = ">", separator = ",") { it.shortName }
784+
typeArgLabels.takeLast(c.typeParameters.size).joinToString(prefix = "<", postfix = ">", separator = ",") { it.shortName }
764785

765786
return ClassLabelResults(
766787
label + (typeArgLabels?.joinToString(separator = "") { ";{${it.id}}" } ?: "<>"),
@@ -770,12 +791,12 @@ class X {
770791

771792
// `args` can be null to describe a raw generic type.
772793
// For non-generic types it will be zero-length list.
773-
fun getClassLabel(c: IrClass, typeArgs: List<IrTypeArgument>?): ClassLabelResults {
794+
fun getClassLabel(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?): ClassLabelResults {
774795
if (c.isAnonymousObject) {
775796
logger.warn(Severity.ErrorSevere, "Label generation should not be requested for an anonymous class")
776797
}
777798

778-
val unquotedLabel = getUnquotedClassLabel(c, typeArgs)
799+
val unquotedLabel = getUnquotedClassLabel(c, argsIncludingOuterClasses)
779800
return ClassLabelResults(
780801
"@\"class;${unquotedLabel.classLabel}\"",
781802
unquotedLabel.shortName)

0 commit comments

Comments
 (0)