Skip to content

Commit 4865847

Browse files
authored
Merge pull request github#25 from github/kotlin-getclass
Extract ::class expressions
2 parents 67bfd92 + 3e3f36d commit 4865847

File tree

8 files changed

+41
-18
lines changed

8 files changed

+41
-18
lines changed

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -308,17 +308,20 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
308308
}
309309

310310
fun useClass(c: IrClass): Label<out DbClassorinterface> {
311-
if(c.name.asString() == "Any" || c.name.asString() == "Unit") {
311+
// todo: fix this
312+
if (c.origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB ||
313+
c.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB) {
312314
if(tw.getExistingLabelFor<DbClass>(getClassLabel(c)) == null) {
313-
return extractClass(c)
315+
return extractExternalClass(c)
314316
}
315317
}
316318
return addClassLabel(c)
317319
}
318320

319-
fun extractClass(c: IrClass): Label<out DbClassorinterface> {
321+
fun extractExternalClass(c: IrClass): Label<out DbClassorinterface> {
322+
// todo: fix this.
323+
// temporarily only extract the class or interface without any members.
320324
val id = addClassLabel(c)
321-
val locId = tw.getLocation(c)
322325
val pkg = c.packageFqName?.asString() ?: ""
323326
val cls = c.name.asString()
324327
val pkgId = extractPackage(pkg)
@@ -331,6 +334,12 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
331334
val classId = id as Label<out DbClass>
332335
tw.writeClasses(classId, cls, pkgId, classId)
333336
}
337+
return id
338+
}
339+
340+
fun extractClass(c: IrClass): Label<out DbClassorinterface> {
341+
val id = extractExternalClass(c)
342+
val locId = tw.getLocation(c)
334343
tw.writeHasLocation(id, locId)
335344
for(t in c.superTypes) {
336345
when(t) {
@@ -761,7 +770,16 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
761770
tw.writeWhen_branch_else(bId)
762771
}
763772
}
764-
} else -> {
773+
}
774+
is IrGetClass -> {
775+
val id = tw.getFreshIdLabel<DbGetclassexpr>()
776+
val locId = tw.getLocation(e)
777+
val typeId = useType(e.type)
778+
tw.writeExprs_getclassexpr(id, typeId, parent, idx)
779+
tw.writeHasLocation(id, locId)
780+
extractExpression(e.argument, callable, id, 0)
781+
}
782+
else -> {
765783
logger.warnElement(Severity.ErrorSevere, "Unrecognised IrExpression: " + e.javaClass, e)
766784
}
767785
}

java/ql/lib/config/semmlecode.dbscheme

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ case @expr.kind of
652652
| 72 = @intersectiontypeaccess
653653
| 73 = @switchexpr
654654
| 74 = @whenexpr
655+
| 75 = @getclassexpr
655656
;
656657

657658
/** Holds if this `when` expression was written as an `if` expression. */

java/ql/lib/semmle/code/java/Expr.qll

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,9 +2043,7 @@ class WhenExpr extends Expr, @whenexpr {
20432043
override string getAPrimaryQlClass() { result = "WhenExpr" }
20442044

20452045
/** Gets the `i`th branch. */
2046-
WhenBranch getBranch(int i) {
2047-
when_branch(result, this, i)
2048-
}
2046+
WhenBranch getBranch(int i) { when_branch(result, this, i) }
20492047
}
20502048

20512049
/** A Kotlin `when` branch. */
@@ -2063,3 +2061,13 @@ class WhenBranch extends Top, @whenbranch {
20632061

20642062
override string getAPrimaryQlClass() { result = "WhenBranch" }
20652063
}
2064+
2065+
/** A Kotlin `::class` expression. */
2066+
class ClassExpr extends Expr, @getclassexpr {
2067+
/** Gets the expression whose class is being returned. */
2068+
Expr getExpr() { result.isNthChildOf(this, 0) }
2069+
2070+
override string toString() { result = "::class" }
2071+
2072+
override string getAPrimaryQlClass() { result = "ClassExpr" }
2073+
}

java/ql/test/kotlin/library-tests/classes/superTypes.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,3 @@
66
| classes.kt:28:1:29:1 | ClassSix | classes.kt:12:1:15:1 | ClassFour |
77
| classes.kt:28:1:29:1 | ClassSix | classes.kt:20:1:22:1 | IF1 |
88
| classes.kt:28:1:29:1 | ClassSix | classes.kt:24:1:26:1 | IF2 |
9-
| file://:0:0:0:0 | Unit | file://:0:0:0:0 | Any |

java/ql/test/kotlin/library-tests/exprs/exprs.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,15 @@
4141
| exprs.kt:46:12:46:14 | 123 | IntegerLiteral |
4242
| exprs.kt:46:12:46:20 | ... + ... | AddExpr |
4343
| exprs.kt:46:18:46:20 | 456 | IntegerLiteral |
44+
| exprs.kt:50:13:50:16 | true | BooleanLiteral |
45+
| exprs.kt:50:13:50:23 | ::class | ClassExpr |
4446
| file://:0:0:0:0 | b1 | LocalVariableDeclExpr |
4547
| file://:0:0:0:0 | b2 | LocalVariableDeclExpr |
4648
| file://:0:0:0:0 | b6 | LocalVariableDeclExpr |
4749
| file://:0:0:0:0 | b7 | LocalVariableDeclExpr |
4850
| file://:0:0:0:0 | b8 | LocalVariableDeclExpr |
4951
| file://:0:0:0:0 | c | LocalVariableDeclExpr |
52+
| file://:0:0:0:0 | d | LocalVariableDeclExpr |
5053
| file://:0:0:0:0 | i1 | LocalVariableDeclExpr |
5154
| file://:0:0:0:0 | i2 | LocalVariableDeclExpr |
5255
| file://:0:0:0:0 | i3 | LocalVariableDeclExpr |

java/ql/test/kotlin/library-tests/exprs/exprs.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@ TODO
4646
return 123 + 456
4747
}
4848

49+
fun getClass() {
50+
val d = true::class
51+
}

java/ql/test/kotlin/library-tests/methods/methods.expected

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
| file://:0:0:0:0 | <init> |
2-
| file://:0:0:0:0 | equals |
3-
| file://:0:0:0:0 | equals |
4-
| file://:0:0:0:0 | hashCode |
5-
| file://:0:0:0:0 | hashCode |
6-
| file://:0:0:0:0 | toString |
7-
| file://:0:0:0:0 | toString |
81
| methods2.kt:4:1:5:1 | fooBarTopLevelMethod |
92
| methods2.kt:7:1:10:1 | <init> |
103
| methods2.kt:7:1:10:1 | equals |

java/ql/test/kotlin/library-tests/variables/variables.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
| file://:0:0:0:0 | other | file://:0:0:0:0 | Any | file://:0:0:0:0 | <none> |
2-
| file://:0:0:0:0 | other | file://:0:0:0:0 | Any | file://:0:0:0:0 | <none> |
31
| variables.kt:2:1:8:1 | other | file://:0:0:0:0 | Any | file://:0:0:0:0 | <none> |
42
| variables.kt:3:5:3:21 | prop | file://:0:0:0:0 | int | file://:0:0:0:0 | <none> |
53
| variables.kt:5:20:5:29 | param | file://:0:0:0:0 | int | file://:0:0:0:0 | <none> |

0 commit comments

Comments
 (0)