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

Skip to content

Commit ea4e919

Browse files
tamasvajkigfoo
authored andcommitted
Extract missing functions directly in kotlin package
1 parent 3a2f7be commit ea4e919

5 files changed

Lines changed: 129 additions & 25 deletions

File tree

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

Lines changed: 81 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ open class KotlinFileExtractor(
620620
}
621621

622622
fun extractCall(c: IrCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
623-
fun isFunction(pkgName: String, className: String, fName: String): Boolean {
623+
fun isFunction(pkgName: String, className: String, fName: String, hasQuestionMark: Boolean = false): Boolean {
624624
val verbose = false
625625
fun verboseln(s: String) { if(verbose) println(s) }
626626
verboseln("Attempting match for $pkgName $className $fName")
@@ -632,7 +632,14 @@ open class KotlinFileExtractor(
632632
val extensionReceiverParameter = target.extensionReceiverParameter
633633
// TODO: Are both branches of this `if` possible?:
634634
val targetClass = if (extensionReceiverParameter == null) target.parent
635-
else (extensionReceiverParameter.type as? IrSimpleType)?.classifier?.owner
635+
else {
636+
val st = extensionReceiverParameter.type as? IrSimpleType
637+
if (st?.hasQuestionMark != hasQuestionMark) {
638+
verboseln("Nullablility of type didn't match")
639+
return false
640+
}
641+
st?.classifier?.owner
642+
}
636643
if (targetClass !is IrClass) {
637644
verboseln("No match as didn't find target class")
638645
return false
@@ -663,6 +670,49 @@ open class KotlinFileExtractor(
663670
isFunction("kotlin", "Double", fName)
664671
}
665672

673+
fun extractMethodAccess(callTarget: IrFunction, extractTypeArguments: Boolean = true){
674+
val id = tw.getFreshIdLabel<DbMethodaccess>()
675+
val type = useType(c.type)
676+
val locId = tw.getLocation(c)
677+
val methodId = useFunction<DbMethod>(callTarget)
678+
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
679+
tw.writeHasLocation(id, locId)
680+
tw.writeCallableEnclosingExpr(id, callable)
681+
tw.writeCallableBinding(id, methodId)
682+
tw.writeStatementEnclosingExpr(id, enclosingStmt)
683+
684+
if (extractTypeArguments) {
685+
// type arguments at index -2, -3, ...
686+
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
687+
}
688+
689+
val dr = c.dispatchReceiver
690+
if(dr != null) {
691+
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
692+
}
693+
for(i in 0 until c.valueArgumentsCount) {
694+
val arg = c.getValueArgument(i)
695+
if(arg != null) {
696+
extractExpressionExpr(arg, callable, id, i, enclosingStmt)
697+
}
698+
}
699+
}
700+
701+
fun extractSpecialEnumFunction(fnName: String){
702+
if (c.typeArgumentsCount != 1) {
703+
logger.warnElement(Severity.ErrorSevere, "Expected to find exactly one type argument", c)
704+
return
705+
}
706+
707+
val func = ((c.getTypeArgument(0) as? IrSimpleType)?.classifier?.owner as? IrClass)?.declarations?.find { it is IrFunction && it.name.asString() == fnName }
708+
if (func == null) {
709+
logger.warnElement(Severity.ErrorSevere, "Couldn't find function $fnName on enum type", c)
710+
return
711+
}
712+
713+
extractMethodAccess(func as IrFunction, false)
714+
}
715+
666716
fun binopDisp(id: Label<out DbExpr>) {
667717
val locId = tw.getLocation(c)
668718
tw.writeHasLocation(id, locId)
@@ -693,12 +743,24 @@ open class KotlinFileExtractor(
693743
val dr = c.dispatchReceiver
694744
when {
695745
c.origin == IrStatementOrigin.PLUS &&
696-
(isNumericFunction("plus") || isFunction("kotlin", "String", "plus")) -> {
746+
(isNumericFunction("plus")
747+
|| isFunction("kotlin", "String", "plus")
748+
|| isFunction("kotlin", "String", "plus", true) // TODO: this is not correct. `a + b` becomes `(a?:"\"null\"") + (b?:"\"null\"")`.
749+
) -> {
697750
val id = tw.getFreshIdLabel<DbAddexpr>()
698751
val type = useType(c.type)
699752
tw.writeExprs_addexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
700753
binopDisp(id)
701754
}
755+
isFunction("kotlin", "String", "plus", true) -> {
756+
// TODO: this is not correct. `a + b` becomes `(a?:"\"null\"") + (b?:"\"null\"")`.
757+
val func = pluginContext.irBuiltIns.stringType.classOrNull?.owner?.declarations?.find { it is IrFunction && it.name.asString() == "plus" }
758+
if (func == null) {
759+
logger.warnElement(Severity.ErrorSevere, "Couldn't find plus function on string type", c)
760+
return
761+
}
762+
extractMethodAccess(func as IrFunction)
763+
}
702764
c.origin == IrStatementOrigin.MINUS && isNumericFunction("minus") -> {
703765
val id = tw.getFreshIdLabel<DbSubexpr>()
704766
val type = useType(c.type)
@@ -840,6 +902,21 @@ open class KotlinFileExtractor(
840902
// TODO
841903
logger.warnElement(Severity.ErrorSevere, "Unhandled builtin", c)
842904
}
905+
isFunction("kotlin", "Any", "toString", true) -> {
906+
// TODO: this is not correct. `a.toString()` becomes `(a?:"\"null\"").toString()`
907+
val func = pluginContext.irBuiltIns.anyType.classOrNull?.owner?.declarations?.find { it is IrFunction && it.name.asString() == "toString" }
908+
if (func == null) {
909+
logger.warnElement(Severity.ErrorSevere, "Couldn't find toString function", c)
910+
return
911+
}
912+
extractMethodAccess(func as IrFunction)
913+
}
914+
isBuiltinCallKotlin(c, "enumValues") -> {
915+
extractSpecialEnumFunction("values")
916+
}
917+
isBuiltinCallKotlin(c, "enumValueOf") -> {
918+
extractSpecialEnumFunction("valueOf")
919+
}
843920
isBuiltinCallKotlin(c, "arrayOfNulls") -> {
844921
val id = tw.getFreshIdLabel<DbArraycreationexpr>()
845922
val type = useType(c.type)
@@ -922,28 +999,7 @@ open class KotlinFileExtractor(
922999
}
9231000
}
9241001
else -> {
925-
val id = tw.getFreshIdLabel<DbMethodaccess>()
926-
val type = useType(c.type)
927-
val locId = tw.getLocation(c)
928-
val methodId = useFunction<DbMethod>(c.symbol.owner)
929-
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
930-
tw.writeHasLocation(id, locId)
931-
tw.writeCallableEnclosingExpr(id, callable)
932-
tw.writeCallableBinding(id, methodId)
933-
tw.writeStatementEnclosingExpr(id, enclosingStmt)
934-
935-
// type arguments at index -2, -3, ...
936-
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
937-
938-
if(dr != null) {
939-
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
940-
}
941-
for(i in 0 until c.valueArgumentsCount) {
942-
val arg = c.getValueArgument(i)
943-
if(arg != null) {
944-
extractExpressionExpr(arg, callable, id, i, enclosingStmt)
945-
}
946-
}
1002+
extractMethodAccess(c.symbol.owner)
9471003
}
9481004
}
9491005
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,5 @@
7575
| exprs.kt:138:12:138:20 | ... + ... | exprs.kt:138:12:138:14 | 123 | exprs.kt:138:18:138:20 | 456 |
7676
| exprs.kt:164:8:164:16 | ... != ... | exprs.kt:164:8:164:8 | r | exprs.kt:164:13:164:16 | null |
7777
| exprs.kt:193:31:193:37 | ... + ... | exprs.kt:193:31:193:32 | <get-a1>(...) | exprs.kt:193:36:193:37 | a2 |
78+
| exprs.kt:207:19:207:23 | ... + ... | file://:0:0:0:0 | <none> | exprs.kt:207:23:207:23 | 5 |
79+
| exprs.kt:209:19:209:25 | ... + ... | exprs.kt:209:20:209:21 | ...!! | exprs.kt:209:25:209:25 | 5 |

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,35 @@
537537
| exprs.kt:199:5:199:20 | y | exprs.kt:198:1:200:1 | notNullAssertion | LocalVariableDeclExpr |
538538
| exprs.kt:199:18:199:18 | x | exprs.kt:198:1:200:1 | notNullAssertion | VarAccess |
539539
| exprs.kt:199:19:199:20 | ...!! | exprs.kt:198:1:200:1 | notNullAssertion | NotNullExpr |
540+
| exprs.kt:202:1:215:1 | <obinit>(...) | exprs.kt:202:1:215:1 | Class2 | MethodAccess |
541+
| exprs.kt:205:9:205:29 | a | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
542+
| exprs.kt:205:20:205:29 | toString(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
543+
| exprs.kt:206:9:206:27 | b0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
544+
| exprs.kt:206:21:206:27 | plus(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
545+
| exprs.kt:206:26:206:26 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
546+
| exprs.kt:207:9:207:23 | b1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
547+
| exprs.kt:207:19:207:23 | ... + ... | exprs.kt:203:5:214:5 | x | AddExpr |
548+
| exprs.kt:207:23:207:23 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
549+
| exprs.kt:208:9:208:29 | b2 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
550+
| exprs.kt:208:19:208:19 | s | exprs.kt:203:5:214:5 | x | VarAccess |
551+
| exprs.kt:208:20:208:21 | ...!! | exprs.kt:203:5:214:5 | x | NotNullExpr |
552+
| exprs.kt:208:23:208:29 | plus(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
553+
| exprs.kt:208:28:208:28 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
554+
| exprs.kt:209:9:209:25 | b3 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
555+
| exprs.kt:209:19:209:19 | s | exprs.kt:203:5:214:5 | x | VarAccess |
556+
| exprs.kt:209:19:209:25 | ... + ... | exprs.kt:203:5:214:5 | x | AddExpr |
557+
| exprs.kt:209:20:209:21 | ...!! | exprs.kt:203:5:214:5 | x | NotNullExpr |
558+
| exprs.kt:209:25:209:25 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
559+
| exprs.kt:210:9:210:36 | c0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
560+
| exprs.kt:210:18:210:36 | values(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
561+
| exprs.kt:211:9:211:31 | c1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
562+
| exprs.kt:211:24:211:31 | values(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
563+
| exprs.kt:212:9:212:44 | d0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
564+
| exprs.kt:212:18:212:44 | valueOf(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
565+
| exprs.kt:212:38:212:42 | GREEN | exprs.kt:203:5:214:5 | x | StringLiteral |
566+
| exprs.kt:213:9:213:39 | d1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
567+
| exprs.kt:213:24:213:39 | valueOf(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
568+
| exprs.kt:213:33:213:37 | GREEN | exprs.kt:203:5:214:5 | x | StringLiteral |
540569
| file://:0:0:0:0 | C | exprs.kt:146:5:146:33 | foo | TypeAccess |
541570
| file://:0:0:0:0 | Color | exprs.kt:175:6:179:1 | Color | TypeAccess |
542571
| file://:0:0:0:0 | Direction | exprs.kt:171:6:173:1 | Direction | TypeAccess |

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,18 @@ class Class1 {
198198
fun notNullAssertion(x: Any?) {
199199
val y: Any = x!!
200200
}
201+
202+
class Class2 {
203+
fun x(aa: Any?, s: String?) {
204+
205+
val a = aa.toString()
206+
val b0 = s.plus(5)
207+
val b1 = s + 5
208+
val b2 = s!!.plus(5)
209+
val b3 = s!! + 5
210+
val c0 = enumValues<Color>()
211+
val c1 = Color.values()
212+
val d0 = enumValueOf<Color>("GREEN")
213+
val d1 = Color.valueOf("GREEN")
214+
}
215+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
| exprs.kt:199:19:199:20 | ...!! | exprs.kt:199:18:199:18 | x |
2+
| exprs.kt:208:20:208:21 | ...!! | exprs.kt:208:19:208:19 | s |
3+
| exprs.kt:209:20:209:21 | ...!! | exprs.kt:209:19:209:19 | s |

0 commit comments

Comments
 (0)