diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index 3ee27e9a01f..7078c3abe0a 100755 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -1224,7 +1224,7 @@ ktPropertyDelegates( ) compiler_generated( - unique int id: @top ref, + unique int id: @element ref, int kind: int ref - // 1: Kotlin declaring classes of adapter functions -); + // 1: Declaring classes of adapter functions in Kotlin +) diff --git a/java/ql/lib/semmle/code/java/Element.qll b/java/ql/lib/semmle/code/java/Element.qll index 7dc5dcb1a52..553e447fa38 100755 --- a/java/ql/lib/semmle/code/java/Element.qll +++ b/java/ql/lib/semmle/code/java/Element.qll @@ -41,6 +41,9 @@ class Element extends @element, Top { /** Cast this element to a `Documentable`. */ Documentable getDoc() { result = this } + + /** Holds if this is an auxiliary program element generated by the compiler. */ + predicate isCompilerGenerated() { compiler_generated(this, _) } } /** diff --git a/java/ql/src/Violations of Best Practice/Dead Code/DeadRefTypes.ql b/java/ql/src/Violations of Best Practice/Dead Code/DeadRefTypes.ql index a7ab73bebf5..e2c62f6d4e1 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/DeadRefTypes.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/DeadRefTypes.ql @@ -52,7 +52,7 @@ predicate dead(RefType dead) { // Insist all source ancestors are dead as well. forall(RefType t | t.fromSource() and t = getASuperTypePlus(dead) | dead(t)) and // Exclude compiler generated classes (e.g. declaring type of adapter functions in Kotlin) - not compiler_generated(dead, _) + not dead.isCompilerGenerated() } from RefType t, string kind diff --git a/java/ql/test/kotlin/library-tests/reflection/reflection.ql b/java/ql/test/kotlin/library-tests/reflection/reflection.ql index 27c4ed9c485..6957e71a188 100644 --- a/java/ql/test/kotlin/library-tests/reflection/reflection.ql +++ b/java/ql/test/kotlin/library-tests/reflection/reflection.ql @@ -87,4 +87,4 @@ query predicate modifiers(ClassInstanceExpr e, Method m, string modifier) { m.hasModifier(modifier) } -query predicate compGenerated(Top t, int i) { compiler_generated(t, i) } +query predicate compGenerated(Element e, int i) { compiler_generated(e, i) } diff --git a/java/ql/test/kotlin/query-tests/DeadRefTypes/DeadRefTypes.expected b/java/ql/test/kotlin/query-tests/DeadRefTypes/DeadRefTypes.expected new file mode 100644 index 00000000000..b900d5172c8 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadRefTypes/DeadRefTypes.expected @@ -0,0 +1 @@ +| test.kt:1:1:1:20 | C1 | Unused class: C1 is not referenced within this codebase. If not used as an external API it should be removed. | diff --git a/java/ql/test/kotlin/query-tests/DeadRefTypes/DeadRefTypes.qlref b/java/ql/test/kotlin/query-tests/DeadRefTypes/DeadRefTypes.qlref new file mode 100644 index 00000000000..2b925a78cbb --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadRefTypes/DeadRefTypes.qlref @@ -0,0 +1 @@ +Violations of Best Practice/Dead Code/DeadRefTypes.ql \ No newline at end of file diff --git a/java/ql/test/kotlin/query-tests/DeadRefTypes/test.kt b/java/ql/test/kotlin/query-tests/DeadRefTypes/test.kt new file mode 100644 index 00000000000..6a38aa0f748 --- /dev/null +++ b/java/ql/test/kotlin/query-tests/DeadRefTypes/test.kt @@ -0,0 +1,15 @@ +private class C1 { } + +private class C2 { } + +fun fn() { + val c = C2() +} + +fun fn1() = 5 + +fun fn2(f: () -> Unit) = f() + +fun adapted() { + fn2(::fn1) +}