From 9eea6d41932fab474be974c3fb7edded5d289331 Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Tue, 4 Oct 2022 14:23:57 +0200 Subject: [PATCH] Kotlin: Extract type parameter modifiers (`reified`, `in`, `out`) --- .../src/main/kotlin/KotlinFileExtractor.kt | 10 +++++ java/ql/lib/config/semmlecode.dbscheme | 2 +- java/ql/lib/semmle/code/java/Generics.qll | 2 +- java/ql/lib/semmle/code/java/Modifier.qll | 9 +++++ .../modifiers/modifiers.expected | 37 +++++++++++++------ .../library-tests/modifiers/modifiers.kt | 5 +++ 6 files changed, 51 insertions(+), 14 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index b19342edb94..364e9f86d39 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -203,6 +203,16 @@ open class KotlinFileExtractor( } } + if (tp.isReified) { + addModifiers(id, "reified") + } + + if (tp.variance == Variance.IN_VARIANCE) { + addModifiers(id, "in") + } else if (tp.variance == Variance.OUT_VARIANCE) { + addModifiers(id, "out") + } + return id } } diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index ecb42310286..709f1d1fd04 100644 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -1033,7 +1033,7 @@ javadocText( @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | @kt_property; -@modifiable = @member_modifiable| @param | @localvar ; +@modifiable = @member_modifiable| @param | @localvar | @typevariable; @member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; diff --git a/java/ql/lib/semmle/code/java/Generics.qll b/java/ql/lib/semmle/code/java/Generics.qll index 95471437988..54cab14fe40 100644 --- a/java/ql/lib/semmle/code/java/Generics.qll +++ b/java/ql/lib/semmle/code/java/Generics.qll @@ -137,7 +137,7 @@ abstract class BoundedType extends RefType, @boundedtype { * For example, `T` is a type parameter in * `class X { }` and in ` void m() { }`. */ -class TypeVariable extends BoundedType, @typevariable { +class TypeVariable extends BoundedType, Modifiable, @typevariable { /** Gets the generic type that is parameterized by this type parameter, if any. */ GenericType getGenericType() { typeVars(this, _, _, _, result) } diff --git a/java/ql/lib/semmle/code/java/Modifier.qll b/java/ql/lib/semmle/code/java/Modifier.qll index 7dbd4d90726..150b65be671 100644 --- a/java/ql/lib/semmle/code/java/Modifier.qll +++ b/java/ql/lib/semmle/code/java/Modifier.qll @@ -96,4 +96,13 @@ abstract class Modifiable extends Element { /** Holds if this element has a `lateinit` modifier. */ predicate isLateinit() { this.hasModifier("lateinit") } + + /** Holds if this element has a `reified` modifier. */ + predicate isReified() { this.hasModifier("reified") } + + /** Holds if this element has an `in` modifier. */ + predicate isIn() { this.hasModifier("in") } + + /** Holds if this element has an `out` modifier. */ + predicate isOut() { this.hasModifier("out") } } diff --git a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected index 572423554e9..cdde306d74f 100644 --- a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected +++ b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected @@ -1,5 +1,5 @@ -| modifiers.kt:1:1:28:1 | X | Class | public | -| modifiers.kt:1:6:28:1 | X | Constructor | public | +| modifiers.kt:1:1:29:1 | X | Class | public | +| modifiers.kt:1:6:29:1 | X | Constructor | public | | modifiers.kt:2:5:2:21 | a | Field | final | | modifiers.kt:2:5:2:21 | a | Field | private | | modifiers.kt:2:5:2:21 | a | Property | private | @@ -45,13 +45,26 @@ | modifiers.kt:27:12:27:49 | fn5 | Method | inline | | modifiers.kt:27:12:27:49 | fn5 | Method | public | | modifiers.kt:27:20:27:44 | f | Parameter | crossinline | -| modifiers.kt:30:1:36:1 | LateInit | Class | final | -| modifiers.kt:30:1:36:1 | LateInit | Class | public | -| modifiers.kt:30:8:36:1 | LateInit | Constructor | public | -| modifiers.kt:31:5:31:40 | test0 | Field | private | -| modifiers.kt:31:5:31:40 | test0 | Property | lateinit | -| modifiers.kt:31:5:31:40 | test0 | Property | private | -| modifiers.kt:31:22:31:40 | getTest0$private | Method | private | -| modifiers.kt:31:22:31:40 | setTest0$private | Method | private | -| modifiers.kt:33:5:35:5 | fn | Method | public | -| modifiers.kt:34:9:34:36 | LateInit test1 | LocalVariableDecl | lateinit | +| modifiers.kt:28:12:28:39 | fn6 | Method | inline | +| modifiers.kt:28:12:28:39 | fn6 | Method | public | +| modifiers.kt:28:17:28:25 | T | TypeVariable | reified | +| modifiers.kt:31:1:33:1 | Y | Class | final | +| modifiers.kt:31:1:33:1 | Y | Class | public | +| modifiers.kt:31:1:33:1 | Y | Constructor | public | +| modifiers.kt:31:1:33:1 | Y | GenericType | final | +| modifiers.kt:31:1:33:1 | Y | GenericType | public | +| modifiers.kt:31:1:33:1 | Y | ParameterizedType | final | +| modifiers.kt:31:1:33:1 | Y | ParameterizedType | public | +| modifiers.kt:31:9:31:13 | T1 | TypeVariable | in | +| modifiers.kt:31:16:31:21 | T2 | TypeVariable | out | +| modifiers.kt:32:5:32:32 | foo | Method | public | +| modifiers.kt:35:1:41:1 | LateInit | Class | final | +| modifiers.kt:35:1:41:1 | LateInit | Class | public | +| modifiers.kt:35:8:41:1 | LateInit | Constructor | public | +| modifiers.kt:36:5:36:40 | test0 | Field | private | +| modifiers.kt:36:5:36:40 | test0 | Property | lateinit | +| modifiers.kt:36:5:36:40 | test0 | Property | private | +| modifiers.kt:36:22:36:40 | getTest0$private | Method | private | +| modifiers.kt:36:22:36:40 | setTest0$private | Method | private | +| modifiers.kt:38:5:40:5 | fn | Method | public | +| modifiers.kt:39:9:39:36 | LateInit test1 | LocalVariableDecl | lateinit | diff --git a/java/ql/test/kotlin/library-tests/modifiers/modifiers.kt b/java/ql/test/kotlin/library-tests/modifiers/modifiers.kt index 14f66021047..62de34aadb2 100644 --- a/java/ql/test/kotlin/library-tests/modifiers/modifiers.kt +++ b/java/ql/test/kotlin/library-tests/modifiers/modifiers.kt @@ -25,6 +25,11 @@ open class X { inline fun fn4(noinline f: () -> Unit) { } inline fun fn5(crossinline f: () -> Unit) { } + inline fun fn6(x: T) {} +} + +class Y { + fun foo(t: T1) : T2 = null!! } public class LateInit {