mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
Extract missing functions directly in kotlin package
This commit is contained in:
@@ -620,7 +620,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
|
||||
fun extractCall(c: IrCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
|
||||
fun isFunction(pkgName: String, className: String, fName: String): Boolean {
|
||||
fun isFunction(pkgName: String, className: String, fName: String, hasQuestionMark: Boolean = false): Boolean {
|
||||
val verbose = false
|
||||
fun verboseln(s: String) { if(verbose) println(s) }
|
||||
verboseln("Attempting match for $pkgName $className $fName")
|
||||
@@ -632,7 +632,14 @@ open class KotlinFileExtractor(
|
||||
val extensionReceiverParameter = target.extensionReceiverParameter
|
||||
// TODO: Are both branches of this `if` possible?:
|
||||
val targetClass = if (extensionReceiverParameter == null) target.parent
|
||||
else (extensionReceiverParameter.type as? IrSimpleType)?.classifier?.owner
|
||||
else {
|
||||
val st = extensionReceiverParameter.type as? IrSimpleType
|
||||
if (st?.hasQuestionMark != hasQuestionMark) {
|
||||
verboseln("Nullablility of type didn't match")
|
||||
return false
|
||||
}
|
||||
st?.classifier?.owner
|
||||
}
|
||||
if (targetClass !is IrClass) {
|
||||
verboseln("No match as didn't find target class")
|
||||
return false
|
||||
@@ -663,6 +670,49 @@ open class KotlinFileExtractor(
|
||||
isFunction("kotlin", "Double", fName)
|
||||
}
|
||||
|
||||
fun extractMethodAccess(callTarget: IrFunction, extractTypeArguments: Boolean = true){
|
||||
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
||||
val type = useType(c.type)
|
||||
val locId = tw.getLocation(c)
|
||||
val methodId = useFunction<DbMethod>(callTarget)
|
||||
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeCallableBinding(id, methodId)
|
||||
tw.writeStatementEnclosingExpr(id, enclosingStmt)
|
||||
|
||||
if (extractTypeArguments) {
|
||||
// type arguments at index -2, -3, ...
|
||||
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
|
||||
}
|
||||
|
||||
val dr = c.dispatchReceiver
|
||||
if(dr != null) {
|
||||
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
|
||||
}
|
||||
for(i in 0 until c.valueArgumentsCount) {
|
||||
val arg = c.getValueArgument(i)
|
||||
if(arg != null) {
|
||||
extractExpressionExpr(arg, callable, id, i, enclosingStmt)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun extractSpecialEnumFunction(fnName: String){
|
||||
if (c.typeArgumentsCount != 1) {
|
||||
logger.warnElement(Severity.ErrorSevere, "Expected to find exactly one type argument", c)
|
||||
return
|
||||
}
|
||||
|
||||
val func = ((c.getTypeArgument(0) as? IrSimpleType)?.classifier?.owner as? IrClass)?.declarations?.find { it is IrFunction && it.name.asString() == fnName }
|
||||
if (func == null) {
|
||||
logger.warnElement(Severity.ErrorSevere, "Couldn't find function $fnName on enum type", c)
|
||||
return
|
||||
}
|
||||
|
||||
extractMethodAccess(func as IrFunction, false)
|
||||
}
|
||||
|
||||
fun binopDisp(id: Label<out DbExpr>) {
|
||||
val locId = tw.getLocation(c)
|
||||
tw.writeHasLocation(id, locId)
|
||||
@@ -693,12 +743,24 @@ open class KotlinFileExtractor(
|
||||
val dr = c.dispatchReceiver
|
||||
when {
|
||||
c.origin == IrStatementOrigin.PLUS &&
|
||||
(isNumericFunction("plus") || isFunction("kotlin", "String", "plus")) -> {
|
||||
(isNumericFunction("plus")
|
||||
|| isFunction("kotlin", "String", "plus")
|
||||
|| isFunction("kotlin", "String", "plus", true) // TODO: this is not correct. `a + b` becomes `(a?:"\"null\"") + (b?:"\"null\"")`.
|
||||
) -> {
|
||||
val id = tw.getFreshIdLabel<DbAddexpr>()
|
||||
val type = useType(c.type)
|
||||
tw.writeExprs_addexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
|
||||
binopDisp(id)
|
||||
}
|
||||
isFunction("kotlin", "String", "plus", true) -> {
|
||||
// TODO: this is not correct. `a + b` becomes `(a?:"\"null\"") + (b?:"\"null\"")`.
|
||||
val func = pluginContext.irBuiltIns.stringType.classOrNull?.owner?.declarations?.find { it is IrFunction && it.name.asString() == "plus" }
|
||||
if (func == null) {
|
||||
logger.warnElement(Severity.ErrorSevere, "Couldn't find plus function on string type", c)
|
||||
return
|
||||
}
|
||||
extractMethodAccess(func as IrFunction)
|
||||
}
|
||||
c.origin == IrStatementOrigin.MINUS && isNumericFunction("minus") -> {
|
||||
val id = tw.getFreshIdLabel<DbSubexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -840,6 +902,21 @@ open class KotlinFileExtractor(
|
||||
// TODO
|
||||
logger.warnElement(Severity.ErrorSevere, "Unhandled builtin", c)
|
||||
}
|
||||
isFunction("kotlin", "Any", "toString", true) -> {
|
||||
// TODO: this is not correct. `a.toString()` becomes `(a?:"\"null\"").toString()`
|
||||
val func = pluginContext.irBuiltIns.anyType.classOrNull?.owner?.declarations?.find { it is IrFunction && it.name.asString() == "toString" }
|
||||
if (func == null) {
|
||||
logger.warnElement(Severity.ErrorSevere, "Couldn't find toString function", c)
|
||||
return
|
||||
}
|
||||
extractMethodAccess(func as IrFunction)
|
||||
}
|
||||
isBuiltinCallKotlin(c, "enumValues") -> {
|
||||
extractSpecialEnumFunction("values")
|
||||
}
|
||||
isBuiltinCallKotlin(c, "enumValueOf") -> {
|
||||
extractSpecialEnumFunction("valueOf")
|
||||
}
|
||||
isBuiltinCallKotlin(c, "arrayOfNulls") -> {
|
||||
val id = tw.getFreshIdLabel<DbArraycreationexpr>()
|
||||
val type = useType(c.type)
|
||||
@@ -922,28 +999,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
||||
val type = useType(c.type)
|
||||
val locId = tw.getLocation(c)
|
||||
val methodId = useFunction<DbMethod>(c.symbol.owner)
|
||||
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeCallableBinding(id, methodId)
|
||||
tw.writeStatementEnclosingExpr(id, enclosingStmt)
|
||||
|
||||
// type arguments at index -2, -3, ...
|
||||
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
|
||||
|
||||
if(dr != null) {
|
||||
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
|
||||
}
|
||||
for(i in 0 until c.valueArgumentsCount) {
|
||||
val arg = c.getValueArgument(i)
|
||||
if(arg != null) {
|
||||
extractExpressionExpr(arg, callable, id, i, enclosingStmt)
|
||||
}
|
||||
}
|
||||
extractMethodAccess(c.symbol.owner)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,3 +75,5 @@
|
||||
| exprs.kt:138:12:138:20 | ... + ... | exprs.kt:138:12:138:14 | 123 | exprs.kt:138:18:138:20 | 456 |
|
||||
| exprs.kt:164:8:164:16 | ... != ... | exprs.kt:164:8:164:8 | r | exprs.kt:164:13:164:16 | null |
|
||||
| exprs.kt:193:31:193:37 | ... + ... | exprs.kt:193:31:193:32 | <get-a1>(...) | exprs.kt:193:36:193:37 | a2 |
|
||||
| exprs.kt:207:19:207:23 | ... + ... | file://:0:0:0:0 | <none> | exprs.kt:207:23:207:23 | 5 |
|
||||
| exprs.kt:209:19:209:25 | ... + ... | exprs.kt:209:20:209:21 | ...!! | exprs.kt:209:25:209:25 | 5 |
|
||||
|
||||
@@ -537,6 +537,35 @@
|
||||
| exprs.kt:199:5:199:20 | y | exprs.kt:198:1:200:1 | notNullAssertion | LocalVariableDeclExpr |
|
||||
| exprs.kt:199:18:199:18 | x | exprs.kt:198:1:200:1 | notNullAssertion | VarAccess |
|
||||
| exprs.kt:199:19:199:20 | ...!! | exprs.kt:198:1:200:1 | notNullAssertion | NotNullExpr |
|
||||
| exprs.kt:202:1:215:1 | <obinit>(...) | exprs.kt:202:1:215:1 | Class2 | MethodAccess |
|
||||
| exprs.kt:205:9:205:29 | a | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:205:20:205:29 | toString(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
|
||||
| exprs.kt:206:9:206:27 | b0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:206:21:206:27 | plus(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
|
||||
| exprs.kt:206:26:206:26 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
|
||||
| exprs.kt:207:9:207:23 | b1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:207:19:207:23 | ... + ... | exprs.kt:203:5:214:5 | x | AddExpr |
|
||||
| exprs.kt:207:23:207:23 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
|
||||
| exprs.kt:208:9:208:29 | b2 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:208:19:208:19 | s | exprs.kt:203:5:214:5 | x | VarAccess |
|
||||
| exprs.kt:208:20:208:21 | ...!! | exprs.kt:203:5:214:5 | x | NotNullExpr |
|
||||
| exprs.kt:208:23:208:29 | plus(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
|
||||
| exprs.kt:208:28:208:28 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
|
||||
| exprs.kt:209:9:209:25 | b3 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:209:19:209:19 | s | exprs.kt:203:5:214:5 | x | VarAccess |
|
||||
| exprs.kt:209:19:209:25 | ... + ... | exprs.kt:203:5:214:5 | x | AddExpr |
|
||||
| exprs.kt:209:20:209:21 | ...!! | exprs.kt:203:5:214:5 | x | NotNullExpr |
|
||||
| exprs.kt:209:25:209:25 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
|
||||
| exprs.kt:210:9:210:36 | c0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:210:18:210:36 | values(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
|
||||
| exprs.kt:211:9:211:31 | c1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:211:24:211:31 | values(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
|
||||
| exprs.kt:212:9:212:44 | d0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:212:18:212:44 | valueOf(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
|
||||
| exprs.kt:212:38:212:42 | GREEN | exprs.kt:203:5:214:5 | x | StringLiteral |
|
||||
| exprs.kt:213:9:213:39 | d1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
|
||||
| exprs.kt:213:24:213:39 | valueOf(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
|
||||
| exprs.kt:213:33:213:37 | GREEN | exprs.kt:203:5:214:5 | x | StringLiteral |
|
||||
| file://:0:0:0:0 | C | exprs.kt:146:5:146:33 | foo | TypeAccess |
|
||||
| file://:0:0:0:0 | Color | exprs.kt:175:6:179:1 | Color | TypeAccess |
|
||||
| file://:0:0:0:0 | Direction | exprs.kt:171:6:173:1 | Direction | TypeAccess |
|
||||
|
||||
@@ -198,3 +198,18 @@ class Class1 {
|
||||
fun notNullAssertion(x: Any?) {
|
||||
val y: Any = x!!
|
||||
}
|
||||
|
||||
class Class2 {
|
||||
fun x(aa: Any?, s: String?) {
|
||||
|
||||
val a = aa.toString()
|
||||
val b0 = s.plus(5)
|
||||
val b1 = s + 5
|
||||
val b2 = s!!.plus(5)
|
||||
val b3 = s!! + 5
|
||||
val c0 = enumValues<Color>()
|
||||
val c1 = Color.values()
|
||||
val d0 = enumValueOf<Color>("GREEN")
|
||||
val d1 = Color.valueOf("GREEN")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
| exprs.kt:199:19:199:20 | ...!! | exprs.kt:199:18:199:18 | x |
|
||||
| exprs.kt:208:20:208:21 | ...!! | exprs.kt:208:19:208:19 | s |
|
||||
| exprs.kt:209:20:209:21 | ...!! | exprs.kt:209:19:209:19 | s |
|
||||
|
||||
Reference in New Issue
Block a user