Skip to content

Commit 44e70af

Browse files
committed
Kotlin: Extract missing arguments of enum constructor calls
1 parent b8e1aa6 commit 44e70af

File tree

7 files changed

+67
-16
lines changed

7 files changed

+67
-16
lines changed

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

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,12 +1868,13 @@ open class KotlinFileExtractor(
18681868
extractStaticTypeAccessQualifierUnchecked(overriddenCallTarget.parent, id, locId, enclosingCallable, enclosingStmt)
18691869
}
18701870

1871-
extractDefaultsCallArguments(id, overriddenCallTarget, enclosingCallable, enclosingStmt, valueArguments, dispatchReceiver, extensionReceiver)
1871+
extractDefaultsCallArguments(id, overriddenCallTarget, locId, enclosingCallable, enclosingStmt, valueArguments, dispatchReceiver, extensionReceiver)
18721872
}
18731873

18741874
private fun extractDefaultsCallArguments(
18751875
id: Label<out DbExprparent>,
18761876
callTarget: IrFunction,
1877+
locId: Label<DbLocation>,
18771878
enclosingCallable: Label<out DbCallable>,
18781879
enclosingStmt: Label<out DbStmt>,
18791880
valueArguments: List<IrExpression?>,
@@ -1900,7 +1901,7 @@ open class KotlinFileExtractor(
19001901
IrConstImpl.defaultValueForType(0, 0, getDefaultsMethodLastArgType(callTarget))
19011902
)
19021903

1903-
extractCallValueArguments(id, valueArgsWithDummies + extraArgs, enclosingStmt, enclosingCallable, nextIdx, extractVarargAsArray = true)
1904+
extractCallValueArguments(id, valueArgsWithDummies + extraArgs, callTarget, locId, enclosingStmt, enclosingCallable, nextIdx, extractVarargAsArray = true)
19041905
}
19051906

19061907
private fun getFunctionInvokeMethod(typeArgs: List<IrTypeArgument>): IrFunction? {
@@ -2022,7 +2023,7 @@ open class KotlinFileExtractor(
20222023
childIdx,
20232024
enclosingStmt,
20242025
valueArguments.size,
2025-
{ argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) },
2026+
{ argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, syntacticCallTarget, locId, enclosingStmt, enclosingCallable, idxOffset) },
20262027
dispatchReceiver?.type,
20272028
dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } },
20282029
extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } },
@@ -2116,19 +2117,38 @@ open class KotlinFileExtractor(
21162117
this is IrEnumEntry
21172118

21182119

2119-
private fun extractCallValueArguments(callId: Label<out DbExprparent>, call: IrFunctionAccessExpression, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int) =
2120-
extractCallValueArguments(callId, (0 until call.valueArgumentsCount).map { call.getValueArgument(it) }, enclosingStmt, enclosingCallable, idxOffset)
2120+
private fun extractCallValueArguments(callId: Label<out DbExprparent>, call: IrFunctionAccessExpression, callTarget: IrFunction, fallbackLocation: Label<DbLocation>, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int) =
2121+
extractCallValueArguments(callId, (0 until call.valueArgumentsCount).map { call.getValueArgument(it) }, callTarget, fallbackLocation, enclosingStmt, enclosingCallable, idxOffset)
21212122

2122-
private fun extractCallValueArguments(callId: Label<out DbExprparent>, valueArguments: List<IrExpression?>, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int, extractVarargAsArray: Boolean = false) {
2123+
private fun extractCallValueArguments(callId: Label<out DbExprparent>, valueArguments: List<IrExpression?>, callTarget: IrFunction, fallbackLocation: Label<DbLocation>, enclosingStmt: Label<out DbStmt>, enclosingCallable: Label<out DbCallable>, idxOffset: Int, extractVarargAsArray: Boolean = false) {
21232124
var i = 0
21242125
valueArguments.forEach { arg ->
2125-
if(arg != null) {
2126+
if (arg != null) {
21262127
if (arg is IrVararg && !extractVarargAsArray) {
21272128
arg.elements.forEachIndexed { varargNo, vararg -> extractVarargElement(vararg, enclosingCallable, callId, i + idxOffset + varargNo, enclosingStmt) }
21282129
i += arg.elements.size
21292130
} else {
21302131
extractExpressionExpr(arg, enclosingCallable, callId, (i++) + idxOffset, enclosingStmt)
21312132
}
2133+
} else {
2134+
val realCallTarget = callTarget.target.realOverrideTarget
2135+
2136+
// Generated constructor calls to kotlin.Enum have no arguments in IR, but the constructor takes two parameters.
2137+
if (realCallTarget is IrConstructor &&
2138+
realCallTarget.parentClassOrNull?.symbol == pluginContext.irBuiltIns.enumClass &&
2139+
realCallTarget.valueParameters.size == 2 &&
2140+
i < realCallTarget.valueParameters.size) {
2141+
2142+
if (i == 0 && realCallTarget.valueParameters[i].type == pluginContext.irBuiltIns.stringType) {
2143+
2144+
val id = extractNull(pluginContext.irBuiltIns.stringType, fallbackLocation, callId, (i++) + idxOffset, enclosingCallable, enclosingStmt)
2145+
tw.writeCompiler_generated(id, CompilerGeneratedKinds.ENUM_CONSTRUCTOR_ARGUMENT.kind)
2146+
} else if (i == 1 && realCallTarget.valueParameters[i].type == pluginContext.irBuiltIns.intType) {
2147+
2148+
val id = extractConstantInteger(0, fallbackLocation, callId, (i++) + idxOffset, enclosingCallable, enclosingStmt)
2149+
tw.writeCompiler_generated(id, CompilerGeneratedKinds.ENUM_CONSTRUCTOR_ARGUMENT.kind)
2150+
}
2151+
}
21322152
}
21332153
}
21342154
}
@@ -3067,11 +3087,11 @@ open class KotlinFileExtractor(
30673087
// which have null arguments even though the parameters don't give default values.
30683088
val id = if (e !is IrEnumConstructorCall && callUsesDefaultArguments(e.symbol.owner, valueArgs)) {
30693089
extractNewExpr(getDefaultsMethodLabel(e.symbol.owner).cast(), type, locId, parent, idx, callable, enclosingStmt).also {
3070-
extractDefaultsCallArguments(it, e.symbol.owner, callable, enclosingStmt, valueArgs, null, null)
3090+
extractDefaultsCallArguments(it, e.symbol.owner, locId, callable, enclosingStmt, valueArgs, null, null)
30713091
}
30723092
} else {
30733093
extractNewExpr(e.symbol.owner, eType.arguments, type, locId, parent, idx, callable, enclosingStmt).also {
3074-
extractCallValueArguments(it, e, enclosingStmt, callable, 0)
3094+
extractCallValueArguments(it, e, e.symbol.owner, locId, enclosingStmt, callable, 0)
30753095
}
30763096
}
30773097

@@ -3396,6 +3416,14 @@ open class KotlinFileExtractor(
33963416
extractExprContext(it, locId, callable, enclosingStmt)
33973417
}
33983418

3419+
private fun extractNull(t: IrType, locId: Label<DbLocation>, parent: Label<out DbExprparent>, idx: Int, callable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) =
3420+
tw.getFreshIdLabel<DbNullliteral>().also {
3421+
val type = useType(t)
3422+
tw.writeExprs_nullliteral(it, type.javaResult.id, parent, idx)
3423+
tw.writeExprsKotlinType(it, type.kotlinResult.id)
3424+
extractExprContext(it, locId, callable, enclosingStmt)
3425+
}
3426+
33993427
private fun extractAssignExpr(type: IrType, locId: Label<DbLocation>, parent: Label<out DbExprparent>, idx: Int, callable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) =
34003428
tw.getFreshIdLabel<DbAssignexpr>().also {
34013429
val typeResults = useType(type)
@@ -3436,7 +3464,7 @@ open class KotlinFileExtractor(
34363464

34373465
tw.writeHasLocation(id, locId)
34383466
tw.writeCallableBinding(id.cast<DbCaller>(), methodId)
3439-
extractCallValueArguments(id, e, id, callable, 0)
3467+
extractCallValueArguments(id, e, e.symbol.owner, locId, id, callable, 0)
34403468
val dr = e.dispatchReceiver
34413469
if (dr != null) {
34423470
extractExpressionExpr(dr, callable, id, -1, id)
@@ -3614,12 +3642,7 @@ open class KotlinFileExtractor(
36143642
tw.writeNamestrings(v.toString(), v.toString(), id)
36153643
}
36163644
v == null -> {
3617-
val id = tw.getFreshIdLabel<DbNullliteral>()
3618-
val type = useType(e.type) // class;kotlin.Nothing
3619-
val locId = tw.getLocation(e)
3620-
tw.writeExprs_nullliteral(id, type.javaResult.id, exprParent.parent, exprParent.idx)
3621-
tw.writeExprsKotlinType(id, type.kotlinResult.id)
3622-
extractExprContext(id, locId, callable, exprParent.enclosingStmt)
3645+
extractNull(e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
36233646
}
36243647
else -> {
36253648
logger.errorElement("Unrecognised IrConst: " + v.javaClass, e)
@@ -5516,5 +5539,6 @@ open class KotlinFileExtractor(
55165539
JVMOVERLOADS_METHOD(9),
55175540
DEFAULT_ARGUMENTS_METHOD(10),
55185541
INTERFACE_FORWARDER(11),
5542+
ENUM_CONSTRUCTOR_ARGUMENT(12),
55195543
}
55205544
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import java
2+
3+
from Call call, Callable c
4+
where
5+
count(call.getAnArgument()) != c.getNumberOfParameters() and
6+
call.getCallee() = c and
7+
not exists(Parameter p | c.getAParameter() = p and p.isVarargs()) and
8+
call.getFile().isKotlinSourceFile()
9+
select call, c, count(call.getAnArgument()), c.getNumberOfParameters()

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ classes.kt:
174174
# 49| 0: [ClassInstanceExpr] new Enum(...)
175175
# 49| -3: [TypeAccess] Enum<Direction>
176176
# 49| 0: [TypeAccess] Direction
177+
# 49| 0: [NullLiteral] null
178+
# 49| 1: [IntegerLiteral] 0
177179
# 49| 1: [BlockStmt] { ... }
178180
# 50| 5: [FieldDeclaration] Direction NORTH;
179181
# 50| -1: [TypeAccess] Direction
@@ -209,6 +211,8 @@ classes.kt:
209211
# 53| 0: [ClassInstanceExpr] new Enum(...)
210212
# 53| -3: [TypeAccess] Enum<Color>
211213
# 53| 0: [TypeAccess] Color
214+
# 53| 0: [NullLiteral] null
215+
# 53| 1: [IntegerLiteral] 0
212216
# 53| 1: [BlockStmt] { ... }
213217
# 53| 0: [ExprStmt] <Expr>;
214218
# 53| 0: [KtInitializerAssignExpr] ...=...

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3358,6 +3358,8 @@ exprs.kt:
33583358
# 174| 0: [ClassInstanceExpr] new Enum(...)
33593359
# 174| -3: [TypeAccess] Enum<Direction>
33603360
# 174| 0: [TypeAccess] Direction
3361+
# 174| 0: [NullLiteral] null
3362+
# 174| 1: [IntegerLiteral] 0
33613363
# 174| 1: [BlockStmt] { ... }
33623364
# 175| 5: [FieldDeclaration] Direction NORTH;
33633365
# 175| -1: [TypeAccess] Direction
@@ -3393,6 +3395,8 @@ exprs.kt:
33933395
# 178| 0: [ClassInstanceExpr] new Enum(...)
33943396
# 178| -3: [TypeAccess] Enum<Color>
33953397
# 178| 0: [TypeAccess] Color
3398+
# 178| 0: [NullLiteral] null
3399+
# 178| 1: [IntegerLiteral] 0
33963400
# 178| 1: [BlockStmt] { ... }
33973401
# 178| 0: [ExprStmt] <Expr>;
33983402
# 178| 0: [KtInitializerAssignExpr] ...=...

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,9 +1470,11 @@
14701470
| exprs.kt:170:9:170:17 | r2.height | exprs.kt:165:1:172:1 | foo | VarAccess |
14711471
| exprs.kt:170:9:170:21 | ...=... | exprs.kt:165:1:172:1 | foo | AssignExpr |
14721472
| exprs.kt:170:21:170:21 | 3 | exprs.kt:165:1:172:1 | foo | IntegerLiteral |
1473+
| exprs.kt:174:1:176:1 | 0 | exprs.kt:174:6:176:1 | Direction | IntegerLiteral |
14731474
| exprs.kt:174:1:176:1 | Direction | exprs.kt:174:6:176:1 | Direction | TypeAccess |
14741475
| exprs.kt:174:1:176:1 | Enum<Direction> | exprs.kt:174:6:176:1 | Direction | TypeAccess |
14751476
| exprs.kt:174:1:176:1 | new Enum(...) | exprs.kt:174:6:176:1 | Direction | ClassInstanceExpr |
1477+
| exprs.kt:174:1:176:1 | null | exprs.kt:174:6:176:1 | Direction | NullLiteral |
14761478
| exprs.kt:175:5:175:10 | ...=... | exprs.kt:0:0:0:0 | <clinit> | KtInitializerAssignExpr |
14771479
| exprs.kt:175:5:175:10 | Direction | exprs.kt:0:0:0:0 | <clinit> | TypeAccess |
14781480
| exprs.kt:175:5:175:10 | Direction | exprs.kt:0:0:0:0 | <clinit> | TypeAccess |
@@ -1497,9 +1499,11 @@
14971499
| exprs.kt:175:25:175:28 | Direction | file://:0:0:0:0 | <none> | TypeAccess |
14981500
| exprs.kt:175:25:175:28 | Direction.EAST | exprs.kt:0:0:0:0 | <clinit> | VarAccess |
14991501
| exprs.kt:175:25:175:28 | new Direction(...) | exprs.kt:0:0:0:0 | <clinit> | ClassInstanceExpr |
1502+
| exprs.kt:178:1:182:1 | 0 | exprs.kt:178:6:182:1 | Color | IntegerLiteral |
15001503
| exprs.kt:178:1:182:1 | Color | exprs.kt:178:6:182:1 | Color | TypeAccess |
15011504
| exprs.kt:178:1:182:1 | Enum<Color> | exprs.kt:178:6:182:1 | Color | TypeAccess |
15021505
| exprs.kt:178:1:182:1 | new Enum(...) | exprs.kt:178:6:182:1 | Color | ClassInstanceExpr |
1506+
| exprs.kt:178:1:182:1 | null | exprs.kt:178:6:182:1 | Color | NullLiteral |
15031507
| exprs.kt:178:18:178:29 | ...=... | exprs.kt:178:6:182:1 | Color | KtInitializerAssignExpr |
15041508
| exprs.kt:178:18:178:29 | int | file://:0:0:0:0 | <none> | TypeAccess |
15051509
| exprs.kt:178:18:178:29 | int | file://:0:0:0:0 | <none> | TypeAccess |

java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ A.kt:
8888
# 23| 0: [ClassInstanceExpr] new Enum(...)
8989
# 23| -3: [TypeAccess] Enum<Enu>
9090
# 23| 0: [TypeAccess] Enu
91+
# 23| 0: [NullLiteral] null
92+
# 23| 1: [IntegerLiteral] 0
9193
# 23| 1: [BlockStmt] { ... }
9294
# 24| 5: [FieldDeclaration] Enu A;
9395
# 24| -1: [TypeAccess] Enu

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,11 @@
231231
| enumClass.kt:0:0:0:0 | EnumWithFunctions[] | TypeAccess |
232232
| enumClass.kt:0:0:0:0 | String | TypeAccess |
233233
| enumClass.kt:0:0:0:0 | String | TypeAccess |
234+
| enumClass.kt:1:1:4:1 | 0 | IntegerLiteral |
234235
| enumClass.kt:1:1:4:1 | Enum<EnumClass> | TypeAccess |
235236
| enumClass.kt:1:1:4:1 | EnumClass | TypeAccess |
236237
| enumClass.kt:1:1:4:1 | new Enum(...) | ClassInstanceExpr |
238+
| enumClass.kt:1:1:4:1 | null | NullLiteral |
237239
| enumClass.kt:1:22:1:31 | ...=... | KtInitializerAssignExpr |
238240
| enumClass.kt:1:22:1:31 | int | TypeAccess |
239241
| enumClass.kt:1:22:1:31 | int | TypeAccess |
@@ -256,9 +258,11 @@
256258
| enumClass.kt:3:5:3:12 | EnumClass.enum2 | VarAccess |
257259
| enumClass.kt:3:5:3:12 | new EnumClass(...) | ClassInstanceExpr |
258260
| enumClass.kt:3:11:3:11 | 1 | IntegerLiteral |
261+
| enumClass.kt:6:1:16:1 | 0 | IntegerLiteral |
259262
| enumClass.kt:6:1:16:1 | Enum<EnumWithFunctions> | TypeAccess |
260263
| enumClass.kt:6:1:16:1 | EnumWithFunctions | TypeAccess |
261264
| enumClass.kt:6:1:16:1 | new Enum(...) | ClassInstanceExpr |
265+
| enumClass.kt:6:1:16:1 | null | NullLiteral |
262266
| enumClass.kt:8:3:11:4 | ...=... | KtInitializerAssignExpr |
263267
| enumClass.kt:8:3:11:4 | <implicit coercion to unit> | ImplicitCoercionToUnitExpr |
264268
| enumClass.kt:8:3:11:4 | EnumWithFunctions | TypeAccess |

0 commit comments

Comments
 (0)