Skip to content

Commit d286136

Browse files
committed
Kotlin: extract implInterface
1 parent d50be83 commit d286136

File tree

4 files changed

+41
-34
lines changed

4 files changed

+41
-34
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,9 @@ open class KotlinFileExtractor(
264264
val pkg = c.packageFqName?.asString() ?: ""
265265
val cls = classLabelResults.shortName
266266
val pkgId = extractPackage(pkg)
267-
val kind = c.kind
268267
// TODO: There's lots of duplication between this and extractClassSource.
269268
// Can we share it?
270-
if(kind == ClassKind.INTERFACE || kind == ClassKind.ANNOTATION_CLASS) {
269+
if (c.isInterfaceLike) {
271270
val interfaceId = id.cast<DbInterface>()
272271
val sourceInterfaceId = useClassSource(c).cast<DbInterface>()
273272
tw.writeInterfaces(interfaceId, cls, pkgId, sourceInterfaceId)
@@ -276,6 +275,7 @@ open class KotlinFileExtractor(
276275
val sourceClassId = useClassSource(c).cast<DbClass>()
277276
tw.writeClasses(classId, cls, pkgId, sourceClassId)
278277

278+
val kind = c.kind
279279
if (kind == ClassKind.ENUM_CLASS) {
280280
tw.writeIsEnumType(classId)
281281
} else if (kind != ClassKind.CLASS && kind != ClassKind.OBJECT) {
@@ -403,14 +403,14 @@ open class KotlinFileExtractor(
403403
val pkg = c.packageFqName?.asString() ?: ""
404404
val cls = if (c.isAnonymousObject) "" else c.name.asString()
405405
val pkgId = extractPackage(pkg)
406-
val kind = c.kind
407-
if (kind == ClassKind.INTERFACE || kind == ClassKind.ANNOTATION_CLASS) {
406+
if (c.isInterfaceLike) {
408407
val interfaceId = id.cast<DbInterface>()
409408
tw.writeInterfaces(interfaceId, cls, pkgId, interfaceId)
410409
} else {
411410
val classId = id.cast<DbClass>()
412411
tw.writeClasses(classId, cls, pkgId, classId)
413412

413+
val kind = c.kind
414414
if (kind == ClassKind.ENUM_CLASS) {
415415
tw.writeIsEnumType(classId)
416416
} else if (kind != ClassKind.CLASS && kind != ClassKind.OBJECT) {
@@ -4775,7 +4775,7 @@ open class KotlinFileExtractor(
47754775

47764776
addModifiers(id, "final")
47774777
addVisibilityModifierToLocalOrAnonymousClass(id)
4778-
extractClassSupertypes(superTypes, listOf(), id, inReceiverContext = true)
4778+
extractClassSupertypes(superTypes, listOf(), id, isInterface = false, inReceiverContext = true)
47794779

47804780
extractEnclosingClass(declarationParent, id, null, locId, listOf())
47814781

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,10 +1489,10 @@ open class KotlinUsesExtractor(
14891489
* Argument `inReceiverContext` will be passed onto the `useClassInstance` invocation for each supertype.
14901490
*/
14911491
fun extractClassSupertypes(c: IrClass, id: Label<out DbReftype>, mode: ExtractSupertypesMode = ExtractSupertypesMode.Unbound, inReceiverContext: Boolean = false) {
1492-
extractClassSupertypes(c.superTypes, c.typeParameters, id, mode, inReceiverContext)
1492+
extractClassSupertypes(c.superTypes, c.typeParameters, id, c.isInterfaceLike, mode, inReceiverContext)
14931493
}
14941494

1495-
fun extractClassSupertypes(superTypes: List<IrType>, typeParameters: List<IrTypeParameter>, id: Label<out DbReftype>, mode: ExtractSupertypesMode = ExtractSupertypesMode.Unbound, inReceiverContext: Boolean = false) {
1495+
fun extractClassSupertypes(superTypes: List<IrType>, typeParameters: List<IrTypeParameter>, id: Label<out DbReftype>, isInterface: Boolean, mode: ExtractSupertypesMode = ExtractSupertypesMode.Unbound, inReceiverContext: Boolean = false) {
14961496
// Note we only need to substitute type args here because it is illegal to directly extend a type variable.
14971497
// (For example, we can't have `class A<E> : E`, but can have `class A<E> : Comparable<E>`)
14981498
val subbedSupertypes = when(mode) {
@@ -1507,12 +1507,15 @@ open class KotlinUsesExtractor(
15071507
for(t in subbedSupertypes) {
15081508
when(t) {
15091509
is IrSimpleType -> {
1510-
val owner = t.classifier.owner
1511-
when (owner) {
1510+
when (val owner = t.classifier.owner) {
15121511
is IrClass -> {
15131512
val typeArgs = if (t.arguments.isNotEmpty() && mode is ExtractSupertypesMode.Raw) null else t.arguments
15141513
val l = useClassInstance(owner, typeArgs, inReceiverContext).typeResult.id
1515-
tw.writeExtendsReftype(id, l)
1514+
if (isInterface || !owner.isInterfaceLike) {
1515+
tw.writeExtendsReftype(id, l)
1516+
} else {
1517+
tw.writeImplInterface(id.cast(), l.cast())
1518+
}
15161519
}
15171520
else -> {
15181521
logger.error("Unexpected simple type supertype: " + t.javaClass + ": " + t.render())
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.github.codeql.utils
22

3+
import org.jetbrains.kotlin.descriptors.ClassKind
34
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
5+
import org.jetbrains.kotlin.ir.declarations.IrClass
46
import org.jetbrains.kotlin.ir.declarations.IrFunction
57

68
fun IrFunction.isLocalFunction(): Boolean {
79
return this.visibility == DescriptorVisibilities.LOCAL
8-
}
10+
}
11+
12+
val IrClass.isInterfaceLike get() = kind == ClassKind.INTERFACE || kind == ClassKind.ANNOTATION_CLASS

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

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,26 @@ extendsOrImplements
77
| classes.kt:20:1:22:1 | IF1 | file://<external>/Object.class:0:0:0:0 | Object | extends |
88
| classes.kt:24:1:26:1 | IF2 | file://<external>/Object.class:0:0:0:0 | Object | extends |
99
| classes.kt:28:1:30:1 | ClassSix | classes.kt:12:1:15:1 | ClassFour | extends |
10-
| classes.kt:28:1:30:1 | ClassSix | classes.kt:20:1:22:1 | IF1 | extends |
11-
| classes.kt:28:1:30:1 | ClassSix | classes.kt:24:1:26:1 | IF2 | extends |
10+
| classes.kt:28:1:30:1 | ClassSix | classes.kt:20:1:22:1 | IF1 | implements |
11+
| classes.kt:28:1:30:1 | ClassSix | classes.kt:24:1:26:1 | IF2 | implements |
1212
| classes.kt:34:1:47:1 | ClassSeven | file://<external>/Object.class:0:0:0:0 | Object | extends |
1313
| classes.kt:49:1:51:1 | Direction | file://<external>/Enum.class:0:0:0:0 | Enum<Direction> | extends |
1414
| classes.kt:53:1:57:1 | Color | file://<external>/Enum.class:0:0:0:0 | Enum<Color> | extends |
1515
| classes.kt:59:1:59:23 | Interface1 | file://<external>/Object.class:0:0:0:0 | Object | extends |
1616
| classes.kt:60:1:60:23 | Interface2 | file://<external>/Object.class:0:0:0:0 | Object | extends |
1717
| classes.kt:61:1:61:26 | Interface3 | file://<external>/Object.class:0:0:0:0 | Object | extends |
1818
| classes.kt:63:1:91:1 | Class1 | file://<external>/Object.class:0:0:0:0 | Object | extends |
19-
| classes.kt:66:20:66:54 | new Object(...) { ... } | classes.kt:59:1:59:23 | Interface1 | extends |
20-
| classes.kt:66:20:66:54 | new Object(...) { ... } | classes.kt:60:1:60:23 | Interface2 | extends |
21-
| classes.kt:68:20:68:74 | new Object(...) { ... } | classes.kt:59:1:59:23 | Interface1 | extends |
22-
| classes.kt:68:20:68:74 | new Object(...) { ... } | classes.kt:60:1:60:23 | Interface2 | extends |
23-
| classes.kt:68:20:68:74 | new Object(...) { ... } | file://<external>/Interface3.class:0:0:0:0 | Interface3<String> | extends |
24-
| classes.kt:72:16:77:10 | new Object(...) { ... } | classes.kt:59:1:59:23 | Interface1 | extends |
25-
| classes.kt:72:16:77:10 | new Object(...) { ... } | classes.kt:60:1:60:23 | Interface2 | extends |
19+
| classes.kt:66:20:66:54 | new Object(...) { ... } | classes.kt:59:1:59:23 | Interface1 | implements |
20+
| classes.kt:66:20:66:54 | new Object(...) { ... } | classes.kt:60:1:60:23 | Interface2 | implements |
21+
| classes.kt:68:20:68:74 | new Object(...) { ... } | classes.kt:59:1:59:23 | Interface1 | implements |
22+
| classes.kt:68:20:68:74 | new Object(...) { ... } | classes.kt:60:1:60:23 | Interface2 | implements |
23+
| classes.kt:68:20:68:74 | new Object(...) { ... } | file://<external>/Interface3.class:0:0:0:0 | Interface3<String> | implements |
24+
| classes.kt:72:16:77:10 | new Object(...) { ... } | classes.kt:59:1:59:23 | Interface1 | implements |
25+
| classes.kt:72:16:77:10 | new Object(...) { ... } | classes.kt:60:1:60:23 | Interface2 | implements |
2626
| classes.kt:75:24:75:33 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object | extends |
27-
| classes.kt:81:16:81:38 | new Interface1(...) { ... } | classes.kt:59:1:59:23 | Interface1 | extends |
27+
| classes.kt:81:16:81:38 | new Interface1(...) { ... } | classes.kt:59:1:59:23 | Interface1 | implements |
2828
| classes.kt:85:16:85:25 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object | extends |
29-
| classes.kt:89:16:89:44 | new Interface3<Integer>(...) { ... } | file://<external>/Interface3.class:0:0:0:0 | Interface3<Integer> | extends |
29+
| classes.kt:89:16:89:44 | new Interface3<Integer>(...) { ... } | file://<external>/Interface3.class:0:0:0:0 | Interface3<Integer> | implements |
3030
| classes.kt:93:1:93:26 | pulicClass | file://<external>/Object.class:0:0:0:0 | Object | extends |
3131
| classes.kt:94:1:94:29 | privateClass | file://<external>/Object.class:0:0:0:0 | Object | extends |
3232
| classes.kt:95:1:95:31 | internalClass | file://<external>/Object.class:0:0:0:0 | Object | extends |
@@ -73,31 +73,31 @@ extendsOrImplements
7373
| generic_anonymous.kt:16:5:18:5 | C0 | file://<external>/Object.class:0:0:0:0 | Object | extends |
7474
| generic_anonymous.kt:20:5:22:5 | C1 | file://<external>/Object.class:0:0:0:0 | Object | extends |
7575
| generic_anonymous.kt:25:9:31:9 | | file://<external>/Object.class:0:0:0:0 | Object | extends |
76-
| generic_anonymous.kt:26:13:26:37 | new Object(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<U2> | extends |
77-
| generic_anonymous.kt:26:13:26:37 | new Object(...) { ... } | file://<external>/Outer$C1.class:0:0:0:0 | C1<U3> | extends |
78-
| generic_anonymous.kt:27:13:27:37 | new Object(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<U2> | extends |
79-
| generic_anonymous.kt:27:13:27:37 | new Object(...) { ... } | file://<external>/Outer$C1.class:0:0:0:0 | C1<U2> | extends |
80-
| generic_anonymous.kt:28:13:28:41 | new Object(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<U2> | extends |
81-
| generic_anonymous.kt:28:13:28:41 | new Object(...) { ... } | file://<external>/Outer$C1.class:0:0:0:0 | C1<String> | extends |
82-
| generic_anonymous.kt:29:13:29:29 | new C0<U2>(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<U2> | extends |
83-
| generic_anonymous.kt:30:13:30:33 | new C0<String>(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<String> | extends |
76+
| generic_anonymous.kt:26:13:26:37 | new Object(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<U2> | implements |
77+
| generic_anonymous.kt:26:13:26:37 | new Object(...) { ... } | file://<external>/Outer$C1.class:0:0:0:0 | C1<U3> | implements |
78+
| generic_anonymous.kt:27:13:27:37 | new Object(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<U2> | implements |
79+
| generic_anonymous.kt:27:13:27:37 | new Object(...) { ... } | file://<external>/Outer$C1.class:0:0:0:0 | C1<U2> | implements |
80+
| generic_anonymous.kt:28:13:28:41 | new Object(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<U2> | implements |
81+
| generic_anonymous.kt:28:13:28:41 | new Object(...) { ... } | file://<external>/Outer$C1.class:0:0:0:0 | C1<String> | implements |
82+
| generic_anonymous.kt:29:13:29:29 | new C0<U2>(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<U2> | implements |
83+
| generic_anonymous.kt:30:13:30:33 | new C0<String>(...) { ... } | file://<external>/Outer$C0.class:0:0:0:0 | C0<String> | implements |
8484
| localClassField.kt:1:1:11:1 | A | file://<external>/Object.class:0:0:0:0 | Object | extends |
8585
| localClassField.kt:3:9:3:19 | L | file://<external>/Object.class:0:0:0:0 | Object | extends |
8686
| localClassField.kt:8:9:8:19 | L | file://<external>/Object.class:0:0:0:0 | Object | extends |
8787
| local_anonymous.kt:3:1:36:1 | Class1 | file://<external>/Object.class:0:0:0:0 | Object | extends |
8888
| local_anonymous.kt:5:16:7:9 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object | extends |
8989
| local_anonymous.kt:11:9:11:24 | | file://<external>/Object.class:0:0:0:0 | Object | extends |
90-
| local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<Integer,Integer,Integer> | extends |
90+
| local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<Integer,Integer,Integer> | implements |
9191
| local_anonymous.kt:16:23:16:49 | new Function2<Integer,Integer,Integer>(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object | extends |
92-
| local_anonymous.kt:17:23:17:49 | new Function2<Integer,Integer,Integer>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<Integer,Integer,Integer> | extends |
92+
| local_anonymous.kt:17:23:17:49 | new Function2<Integer,Integer,Integer>(...) { ... } | file://<external>/Function2.class:0:0:0:0 | Function2<Integer,Integer,Integer> | implements |
9393
| local_anonymous.kt:17:23:17:49 | new Function2<Integer,Integer,Integer>(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object | extends |
94-
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | file://<external>/Function1.class:0:0:0:0 | Function1<Class1,Unit> | extends |
94+
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | file://<external>/Function1.class:0:0:0:0 | Function1<Class1,Unit> | implements |
9595
| local_anonymous.kt:21:21:21:31 | new Function1<Class1,Unit>(...) { ... } | file://<external>/FunctionReference.class:0:0:0:0 | FunctionReference | extends |
9696
| local_anonymous.kt:25:9:25:27 | LocalClass | file://<external>/Object.class:0:0:0:0 | Object | extends |
9797
| local_anonymous.kt:29:31:35:5 | new Object(...) { ... } | file://<external>/Object.class:0:0:0:0 | Object | extends |
9898
| local_anonymous.kt:38:1:38:23 | Interface2 | file://<external>/Object.class:0:0:0:0 | Object | extends |
9999
| local_anonymous.kt:39:1:45:1 | Class2 | file://<external>/Object.class:0:0:0:0 | Object | extends |
100-
| local_anonymous.kt:40:14:44:5 | new Interface2(...) { ... } | local_anonymous.kt:38:1:38:23 | Interface2 | extends |
100+
| local_anonymous.kt:40:14:44:5 | new Interface2(...) { ... } | local_anonymous.kt:38:1:38:23 | Interface2 | implements |
101101
| superChain.kt:1:1:1:33 | SuperChain1 | file://<external>/Object.class:0:0:0:0 | Object | extends |
102102
| superChain.kt:2:1:2:60 | SuperChain2 | file://<external>/SuperChain1.class:0:0:0:0 | SuperChain1<T3,String> | extends |
103103
| superChain.kt:3:1:3:60 | SuperChain3 | file://<external>/SuperChain2.class:0:0:0:0 | SuperChain2<T5,String> | extends |

0 commit comments

Comments
 (0)