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

Skip to content

Commit b542769

Browse files
tamasvajkigfoo
authored andcommitted
Fix constructor extraction and extract type arguments of constructor calls
1 parent 936c29b commit b542769

9 files changed

Lines changed: 103 additions & 58 deletions

File tree

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

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import org.jetbrains.kotlin.ir.expressions.*
1111
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin.*
1212
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
1313
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
14+
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
1415
import org.jetbrains.kotlin.ir.types.*
16+
import org.jetbrains.kotlin.ir.util.dumpKotlinLike
1517
import org.jetbrains.kotlin.ir.util.packageFqName
1618
import org.jetbrains.kotlin.ir.util.render
1719
import java.io.File
@@ -499,9 +501,9 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
499501
return label
500502
}
501503

502-
fun useFunction(f: IrFunction): Label<out DbMethod> {
504+
fun <T: DbCallable> useFunction(f: IrFunction): Label<out T> {
503505
val label = getFunctionLabel(f)
504-
val id: Label<DbMethod> = tw.getLabelFor(label)
506+
val id: Label<T> = tw.getLabelFor(label)
505507
return id
506508
}
507509

@@ -543,7 +545,7 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
543545
return id
544546
}
545547

546-
fun extractValueParameter(vp: IrValueParameter, parent: Label<out DbMethod>, idx: Int) {
548+
fun extractValueParameter(vp: IrValueParameter, parent: Label<out DbCallable>, idx: Int) {
547549
val id = useValueParameter(vp)
548550
val typeId = useType(vp.type)
549551
val locId = tw.getLocation(vp.startOffset, vp.endOffset)
@@ -616,11 +618,26 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
616618

617619
fun extractFunction(f: IrFunction, parentid: Label<out DbReftype>) {
618620
currentFunction = f
619-
val id = useFunction(f)
621+
620622
val locId = tw.getLocation(f)
621623
val signature = "TODO"
622624
val returnTypeId = useType(f.returnType)
623-
tw.writeMethods(id, f.name.asString(), signature, returnTypeId, parentid, id)
625+
626+
val id: Label<out DbCallable>
627+
if (f.symbol is IrConstructorSymbol) {
628+
id = useFunction<DbConstructor>(f)
629+
tw.writeConstrs(id, f.returnType.classFqName?.shortName()?.asString() ?: f.name.asString(), signature, returnTypeId, parentid, id)
630+
} else {
631+
id = useFunction<DbMethod>(f)
632+
tw.writeMethods(id, f.name.asString(), signature, returnTypeId, parentid, id)
633+
634+
val extReceiver = f.extensionReceiverParameter
635+
if (extReceiver != null) {
636+
val extendedType = useType(extReceiver.type)
637+
tw.writeKtExtensionFunctions(id, extendedType)
638+
}
639+
}
640+
624641
tw.writeHasLocation(id, locId)
625642
val body = f.body
626643
if(body != null) {
@@ -630,12 +647,6 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
630647
extractValueParameter(vp, id, i)
631648
}
632649

633-
val extReceiver = f.extensionReceiverParameter
634-
if (extReceiver != null) {
635-
val extendedType = useType(extReceiver.type)
636-
tw.writeKtExtensionFunctions(id, extendedType)
637-
}
638-
639650
f.typeParameters.map { extractTypeParameter(it, Optional.of(id)) }
640651

641652
currentFunction = null
@@ -807,18 +818,13 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
807818
val id = tw.getFreshIdLabel<DbMethodaccess>()
808819
val typeId = useType(c.type)
809820
val locId = tw.getLocation(c)
810-
val methodId = useFunction(c.symbol.owner)
821+
val methodId = useFunction<DbMethod>(c.symbol.owner)
811822
tw.writeExprs_methodaccess(id, typeId, parent, idx)
812823
tw.writeHasLocation(id, locId)
813824
tw.writeCallableBinding(id, methodId)
814825

815826
// type arguments at index -2, -3, ...
816-
for (argIdx in 0 until c.typeArgumentsCount) {
817-
val arg = c.getTypeArgument(argIdx)!!
818-
val argTypeId = useType(arg)
819-
val argId = tw.getFreshIdLabel<DbUnannotatedtypeaccess>()
820-
tw.writeExprs_unannotatedtypeaccess(argId, argTypeId, id,argIdx * -1 - 2)
821-
}
827+
extractTypeArguments(c, id, -2, true)
822828
id
823829
}
824830
}
@@ -834,6 +840,21 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
834840
}
835841
}
836842

843+
private fun extractTypeArguments(
844+
c: IrFunctionAccessExpression,
845+
id: Label<out DbExprparent>,
846+
startIndex: Int = 0,
847+
reverse: Boolean = false
848+
) {
849+
for (argIdx in 0 until c.typeArgumentsCount) {
850+
val arg = c.getTypeArgument(argIdx)!!
851+
val argTypeId = useType(arg)
852+
val argId = tw.getFreshIdLabel<DbUnannotatedtypeaccess>()
853+
val mul = if (reverse) -1 else 1
854+
tw.writeExprs_unannotatedtypeaccess(argId, argTypeId, id, argIdx * mul + startIndex)
855+
}
856+
}
857+
837858
private fun extractConstructorCall(
838859
e: IrFunctionAccessExpression,
839860
parent: Label<out DbExprparent>,
@@ -843,7 +864,7 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
843864
val id = tw.getFreshIdLabel<DbNewexpr>()
844865
val typeId = useType(e.type)
845866
val locId = tw.getLocation(e)
846-
val methodId = useFunction(e.symbol.owner)
867+
val methodId = useFunction<DbConstructor>(e.symbol.owner)
847868
tw.writeExprs_newexpr(id, typeId, parent, idx)
848869
tw.writeHasLocation(id, locId)
849870
tw.writeCallableBinding(id, methodId)
@@ -855,10 +876,14 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
855876
}
856877
val dr = e.dispatchReceiver
857878
if (dr != null) {
858-
extractExpression(dr, callable, id, -3)
879+
extractExpression(dr, callable, id, -2)
859880
}
860881

861-
// todo: type arguments at index -4, -5, ...
882+
if (e.typeArgumentsCount > 0) {
883+
val typeAccessId = tw.getFreshIdLabel<DbUnannotatedtypeaccess>()
884+
tw.writeExprs_unannotatedtypeaccess(typeAccessId, typeId, id, -3)
885+
extractTypeArguments(e, typeAccessId)
886+
}
862887
}
863888

864889
private val loopIdMap: MutableMap<IrLoop, Label<out DbKtloopstmt>> = mutableMapOf()
@@ -908,7 +933,7 @@ class KotlinFileExtractor(val logger: FileLogger, val tw: FileTrapWriter, val fi
908933
}
909934

910935
val locId = tw.getLocation(e)
911-
val methodId = useFunction(e.symbol.owner)
936+
val methodId = useFunction<DbConstructor>(e.symbol.owner)
912937

913938
tw.writeHasLocation(id, locId)
914939
@Suppress("UNCHECKED_CAST")

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ comments
55
| comments.kt:18:9:18:25 | // A line comment | // A line comment |
66
| comments.kt:22:5:24:6 | /*\n A block comment\n */ | /*\n A block comment\n */ |
77
commentOwners
8-
| comments.kt:4:1:11:3 | /**\n * A group of *members*.\n *\n * This class has no useful logic; it's just a documentation example.\n *\n * @property name the name of this group.\n * @constructor Creates an empty group.\n */ | comments.kt:12:1:25:1 | <init> |
8+
| comments.kt:4:1:11:3 | /**\n * A group of *members*.\n *\n * This class has no useful logic; it's just a documentation example.\n *\n * @property name the name of this group.\n * @constructor Creates an empty group.\n */ | comments.kt:12:1:25:1 | Group |
99
| comments.kt:4:1:11:3 | /**\n * A group of *members*.\n *\n * This class has no useful logic; it's just a documentation example.\n *\n * @property name the name of this group.\n * @constructor Creates an empty group.\n */ | comments.kt:12:1:25:1 | Group |
1010
| comments.kt:4:1:11:3 | /**\n * A group of *members*.\n *\n * This class has no useful logic; it's just a documentation example.\n *\n * @property name the name of this group.\n * @constructor Creates an empty group.\n */ | comments.kt:12:1:25:1 | equals |
1111
| comments.kt:4:1:11:3 | /**\n * A group of *members*.\n *\n * This class has no useful logic; it's just a documentation example.\n *\n * @property name the name of this group.\n * @constructor Creates an empty group.\n */ | comments.kt:12:1:25:1 | hashCode |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 55 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (55,0,189)
2+
Relevant element: argumentid=55
3+
Full ID for 55: @"type;boolean"
4+
Relevant element: parentid=189
5+
Full ID for 189: @"class;kotlin.reflect.KClass;(55)". The ID may expand to @"class;kotlin.reflect.KClass;{@"type;boolean"}"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
| exprs.kt:53:9:53:18 | ...=... | AssignExpr |
4848
| exprs.kt:53:9:53:18 | n | VarAccess |
4949
| exprs.kt:53:9:53:18 | n | VarAccess |
50-
| exprs.kt:54:27:54:31 | (no string representation) | ClassInstanceExpr |
50+
| exprs.kt:54:27:54:31 | new C(...) | ClassInstanceExpr |
5151
| exprs.kt:54:29:54:30 | 42 | IntegerLiteral |
5252
| file://:0:0:0:0 | b1 | LocalVariableDeclExpr |
5353
| file://:0:0:0:0 | b2 | LocalVariableDeclExpr |
Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 11 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (11,0,132)
2-
Relevant element: argumentid=11
3-
Full ID for 11: @"type;int"
4-
Relevant element: parentid=132
5-
Full ID for 132: @"class;foo.bar.C1;(11);(11)". The ID may expand to @"class;foo.bar.C1;{@"type;int"};{@"type;int"}"
6-
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 11 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (11,0,197)
7-
Relevant element: argumentid=11
8-
Full ID for 11: @"type;int"
9-
Relevant element: parentid=197
10-
Full ID for 197: @"class;foo.bar.C0;(11)". The ID may expand to @"class;foo.bar.C0;{@"type;int"}"
11-
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 11 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (11,1,132)
12-
Relevant element: argumentid=11
13-
Full ID for 11: @"type;int"
14-
Relevant element: parentid=132
15-
Full ID for 132: @"class;foo.bar.C1;(11);(11)". The ID may expand to @"class;foo.bar.C1;{@"type;int"};{@"type;int"}"
16-
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 11 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (11,1,157)
17-
Relevant element: argumentid=11
18-
Full ID for 11: @"type;int"
19-
Relevant element: parentid=157
20-
Full ID for 157: @"class;foo.bar.C1;(13);(11)". The ID may expand to @"class;foo.bar.C1;{@"type;string"};{@"type;int"}"
21-
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 13 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (13,0,146)
22-
Relevant element: argumentid=13
23-
Full ID for 13: @"type;string"
24-
Relevant element: parentid=146
25-
Full ID for 146: @"class;foo.bar.C1;(13);(13)". The ID may expand to @"class;foo.bar.C1;{@"type;string"};{@"type;string"}"
26-
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 13 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (13,0,157)
27-
Relevant element: argumentid=13
28-
Full ID for 13: @"type;string"
29-
Relevant element: parentid=157
30-
Full ID for 157: @"class;foo.bar.C1;(13);(11)". The ID may expand to @"class;foo.bar.C1;{@"type;string"};{@"type;int"}"
1+
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 12 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (12,0,135)
2+
Relevant element: argumentid=12
3+
Full ID for 12: @"type;int"
4+
Relevant element: parentid=135
5+
Full ID for 135: @"class;foo.bar.C1;(12);(12)". The ID may expand to @"class;foo.bar.C1;{@"type;int"};{@"type;int"}"
6+
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 12 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (12,0,206)
7+
Relevant element: argumentid=12
8+
Full ID for 12: @"type;int"
9+
Relevant element: parentid=206
10+
Full ID for 206: @"class;foo.bar.C0;(12)". The ID may expand to @"class;foo.bar.C0;{@"type;int"}"
11+
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 12 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (12,1,135)
12+
Relevant element: argumentid=12
13+
Full ID for 12: @"type;int"
14+
Relevant element: parentid=135
15+
Full ID for 135: @"class;foo.bar.C1;(12);(12)". The ID may expand to @"class;foo.bar.C1;{@"type;int"};{@"type;int"}"
16+
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 12 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (12,1,163)
17+
Relevant element: argumentid=12
18+
Full ID for 12: @"type;int"
19+
Relevant element: parentid=163
20+
Full ID for 163: @"class;foo.bar.C1;(14);(12)". The ID may expand to @"class;foo.bar.C1;{@"type;string"};{@"type;int"}"
21+
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 14 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (14,0,152)
22+
Relevant element: argumentid=14
23+
Full ID for 14: @"type;string"
24+
Relevant element: parentid=152
25+
Full ID for 152: @"class;foo.bar.C1;(14);(14)". The ID may expand to @"class;foo.bar.C1;{@"type;string"};{@"type;string"}"
26+
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): Value 14 of field argumentid is not in type @reftype. The value is however in the following types: @primitive. Appears in tuple (14,0,163)
27+
Relevant element: argumentid=14
28+
Full ID for 14: @"type;string"
29+
Relevant element: parentid=163
30+
Full ID for 163: @"class;foo.bar.C1;(14);(12)". The ID may expand to @"class;foo.bar.C1;{@"type;string"};{@"type;int"}"
3131
[VALUE_NOT_IN_TYPE] predicate typeArgs(@reftype argumentid, int pos, @typeorcallable parentid): More errors, not displayed. There are 7 values of field argumentid that are not in type @reftype for a relation of size 12

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ genericCall
2727
| generics.kt:27:17:27:22 | f2(...) | generics.kt:15:10:15:10 | U | file://:0:0:0:0 | string |
2828
| generics.kt:30:17:30:21 | f2(...) | generics.kt:15:10:15:10 | U | file://:0:0:0:0 | int |
2929
| generics.kt:32:8:32:12 | f4(...) | generics.kt:21:10:21:10 | P | file://:0:0:0:0 | int |
30+
genericCtor
31+
| generics.kt:16:16:16:26 | new C1(...) | 0 | generics.kt:15:10:15:10 | U |
32+
| generics.kt:16:16:16:26 | new C1(...) | 1 | generics.kt:15:10:15:10 | U |
33+
| generics.kt:25:14:25:28 | new C1(...) | 0 | file://:0:0:0:0 | int |
34+
| generics.kt:25:14:25:28 | new C1(...) | 1 | file://:0:0:0:0 | int |
35+
| generics.kt:28:14:28:32 | new C1(...) | 0 | file://:0:0:0:0 | string |
36+
| generics.kt:28:14:28:32 | new C1(...) | 1 | file://:0:0:0:0 | int |
37+
| generics.kt:33:21:33:29 | new C0(...) | 0 | file://:0:0:0:0 | int |

java/ql/test/kotlin/library-tests/generics/generics.ql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ query predicate genericFunction(GenericCallable c, TypeVariable tv, int i) {
1212
}
1313

1414
query predicate genericCall(GenericCall c, TypeVariable tv, Type t) { c.getATypeArgument(tv) = t }
15+
16+
query predicate genericCtor(ClassInstanceExpr c, int i, Type ta) {
17+
c.getTypeArgument(i).getType() = ta
18+
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
11
methods
2-
| file://:0:0:0:0 | <init> |
32
| file://:0:0:0:0 | equals |
43
| file://:0:0:0:0 | equals |
54
| file://:0:0:0:0 | hashCode |
65
| file://:0:0:0:0 | hashCode |
76
| file://:0:0:0:0 | toString |
87
| file://:0:0:0:0 | toString |
98
| methods2.kt:4:1:5:1 | fooBarTopLevelMethod |
10-
| methods2.kt:7:1:10:1 | <init> |
119
| methods2.kt:7:1:10:1 | <obinit> |
1210
| methods2.kt:7:1:10:1 | equals |
1311
| methods2.kt:7:1:10:1 | hashCode |
1412
| methods2.kt:7:1:10:1 | toString |
1513
| methods2.kt:8:5:9:5 | fooBarClassMethod |
1614
| methods3.kt:3:1:3:39 | fooBarTopLevelMethod |
17-
| methods3.kt:5:1:7:1 | <init> |
1815
| methods3.kt:5:1:7:1 | <obinit> |
1916
| methods3.kt:5:1:7:1 | equals |
2017
| methods3.kt:5:1:7:1 | hashCode |
2118
| methods3.kt:5:1:7:1 | toString |
2219
| methods3.kt:6:5:6:43 | fooBarTopLevelMethod |
2320
| methods.kt:2:1:3:1 | topLevelMethod |
24-
| methods.kt:5:1:13:1 | <init> |
2521
| methods.kt:5:1:13:1 | <obinit> |
2622
| methods.kt:5:1:13:1 | equals |
2723
| methods.kt:5:1:13:1 | hashCode |
2824
| methods.kt:5:1:13:1 | toString |
2925
| methods.kt:6:5:7:5 | classMethod |
3026
| methods.kt:9:5:12:5 | anotherClassMethod |
27+
constructors
28+
| file://:0:0:0:0 | Any |
29+
| methods2.kt:7:1:10:1 | Class2 |
30+
| methods3.kt:5:1:7:1 | Class3 |
31+
| methods.kt:5:1:13:1 | Class |
3132
extensions
3233
| methods3.kt:3:1:3:39 | fooBarTopLevelMethod | file://:0:0:0:0 | int |
3334
| methods3.kt:6:5:6:43 | fooBarTopLevelMethod | file://:0:0:0:0 | int |

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ import java
22

33
query predicate methods(Method m) { any() }
44

5+
query predicate constructors(Constructor c) { any() }
6+
57
query predicate extensions(ExtensionMethod m, Type t) { m.getExtendedType() = t }

0 commit comments

Comments
 (0)