Skip to content

Commit 0eb6d1c

Browse files
committed
Kotlin: useFunction might return null
1 parent 3e86c4c commit 0eb6d1c

File tree

2 files changed

+108
-42
lines changed

2 files changed

+108
-42
lines changed

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

Lines changed: 91 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -552,9 +552,13 @@ open class KotlinFileExtractor(
552552
logger.warnElement("Expected annotation property to define a getter", prop)
553553
} else {
554554
val getterId = useFunction<DbMethod>(getter)
555-
val exprId = extractAnnotationValueExpression(v, id, i, "{$getterId}", getter.returnType, extractEnumTypeAccesses)
556-
if (exprId != null) {
557-
tw.writeAnnotValue(id, getterId, exprId)
555+
if (getterId == null) {
556+
logger.errorElement("Couldn't get ID for getter", getter)
557+
} else {
558+
val exprId = extractAnnotationValueExpression(v, id, i, "{$getterId}", getter.returnType, extractEnumTypeAccesses)
559+
if (exprId != null) {
560+
tw.writeAnnotValue(id, getterId, exprId)
561+
}
558562
}
559563
}
560564
}
@@ -979,6 +983,10 @@ open class KotlinFileExtractor(
979983
private fun extractInstanceInitializerBlock(parent: StmtParent, enclosingConstructor: IrConstructor) {
980984
with("object initializer block", enclosingConstructor) {
981985
val constructorId = useFunction<DbConstructor>(enclosingConstructor)
986+
if (constructorId == null) {
987+
logger.errorElement("Cannot get ID for constructor", enclosingConstructor)
988+
return
989+
}
982990
val enclosingClass = enclosingConstructor.parentClassOrNull
983991
if (enclosingClass == null) {
984992
logger.errorElement("Constructor's parent is not a class", enclosingConstructor)
@@ -1410,10 +1418,17 @@ open class KotlinFileExtractor(
14101418

14111419
val sourceDeclaration =
14121420
overriddenAttributes?.sourceDeclarationId ?:
1413-
if (typeSubstitution != null && overriddenAttributes?.id == null)
1414-
useFunction(f)
1415-
else
1421+
if (typeSubstitution != null && overriddenAttributes?.id == null) {
1422+
val sourceFunId = useFunction<DbCallable>(f)
1423+
if (sourceFunId == null) {
1424+
logger.errorElement("Cannot get source ID for function", f)
1425+
id // TODO: This is wrong; we ought to just fail in this case
1426+
} else {
1427+
sourceFunId
1428+
}
1429+
} else {
14161430
id
1431+
}
14171432

14181433
val extReceiver = f.extensionReceiverParameter
14191434
// The following parameter order is correct, because member $default methods (where the order would be [dispatchParam], [extensionParam], normalParams) are not extracted here
@@ -3274,7 +3289,14 @@ open class KotlinFileExtractor(
32743289
idx: Int,
32753290
callable: Label<out DbCallable>,
32763291
enclosingStmt: Label<out DbStmt>
3277-
): Label<DbNewexpr>? = extractNewExpr(useFunction<DbConstructor>(calledConstructor, constructorTypeArgs), constructedType, locId, parent, idx, callable, enclosingStmt)
3292+
): Label<DbNewexpr>? {
3293+
val funId = useFunction<DbConstructor>(calledConstructor, constructorTypeArgs)
3294+
if (funId == null) {
3295+
logger.error("Cannot get ID for newExpr function")
3296+
return null
3297+
}
3298+
return extractNewExpr(funId, constructedType, locId, parent, idx, callable, enclosingStmt)
3299+
}
32783300

32793301
private fun needsObinitFunction(c: IrClass) = c.primaryConstructor == null && c.constructors.count() > 1
32803302

@@ -3707,9 +3729,13 @@ open class KotlinFileExtractor(
37073729

37083730
val locId = tw.getLocation(e)
37093731
val methodId = useFunction<DbConstructor>(e.symbol.owner)
3732+
if (methodId == null) {
3733+
logger.errorElement("Cannot get ID for delegating constructor", e)
3734+
} else {
3735+
tw.writeCallableBinding(id.cast<DbCaller>(), methodId)
3736+
}
37103737

37113738
tw.writeHasLocation(id, locId)
3712-
tw.writeCallableBinding(id.cast<DbCaller>(), methodId)
37133739
extractCallValueArguments(id, e, id, callable, 0)
37143740
val dr = e.dispatchReceiver
37153741
if (dr != null) {
@@ -4645,7 +4671,11 @@ open class KotlinFileExtractor(
46454671
extractExprContext(callId, locId, labels.methodId, retId)
46464672

46474673
val callableId = useFunction<DbCallable>(target.owner.realOverrideTarget, classTypeArgsIncludingOuterClasses)
4648-
tw.writeCallableBinding(callId.cast<DbCaller>(), callableId)
4674+
if (callableId == null) {
4675+
logger.error("Cannot get ID for reflection target")
4676+
} else {
4677+
tw.writeCallableBinding(callId.cast<DbCaller>(), callableId)
4678+
}
46494679

46504680
val useFirstArgAsDispatch: Boolean
46514681
if (dispatchReceiverInfo != null) {
@@ -4827,20 +4857,24 @@ open class KotlinFileExtractor(
48274857
val getterReturnType = parameterTypes.last()
48284858

48294859
if (getter != null) {
4830-
val getLabels = addFunctionManual(tw.getFreshIdLabel(), OperatorNameConventions.GET.asString(), getterParameterTypes, getterReturnType, classId, locId)
48314860
val getterCallableId = useFunction<DbCallable>(getter.owner.realOverrideTarget, classTypeArguments)
4861+
if (getterCallableId == null) {
4862+
logger.errorElement("Cannot get ID for getter", propertyReferenceExpr)
4863+
} else {
4864+
val getLabels = addFunctionManual(tw.getFreshIdLabel(), OperatorNameConventions.GET.asString(), getterParameterTypes, getterReturnType, classId, locId)
4865+
4866+
helper.extractCallToReflectionTarget(
4867+
getLabels,
4868+
getter,
4869+
getterReturnType,
4870+
expressionTypeArguments,
4871+
classTypeArguments
4872+
)
48324873

4833-
helper.extractCallToReflectionTarget(
4834-
getLabels,
4835-
getter,
4836-
getterReturnType,
4837-
expressionTypeArguments,
4838-
classTypeArguments
4839-
)
4840-
4841-
tw.writePropertyRefGetBinding(idPropertyRef, getterCallableId)
4874+
tw.writePropertyRefGetBinding(idPropertyRef, getterCallableId)
48424875

4843-
helper.extractPropertyReferenceInvoke(getLabels.methodId, getterParameterTypes, getterReturnType)
4876+
helper.extractPropertyReferenceInvoke(getLabels.methodId, getterParameterTypes, getterReturnType)
4877+
}
48444878
} else {
48454879
// Property without a getter.
48464880
if (backingField == null) {
@@ -4861,19 +4895,22 @@ open class KotlinFileExtractor(
48614895
}
48624896

48634897
if (setter != null) {
4864-
val setLabels = addFunctionManual(tw.getFreshIdLabel(), OperatorNameConventions.SET.asString(), parameterTypes, pluginContext.irBuiltIns.unitType, classId, locId)
4865-
48664898
val setterCallableId = useFunction<DbCallable>(setter.owner.realOverrideTarget, classTypeArguments)
4899+
if (setterCallableId == null) {
4900+
logger.errorElement("Cannot get ID for setter", propertyReferenceExpr)
4901+
} else {
4902+
val setLabels = addFunctionManual(tw.getFreshIdLabel(), OperatorNameConventions.SET.asString(), parameterTypes, pluginContext.irBuiltIns.unitType, classId, locId)
48674903

4868-
helper.extractCallToReflectionTarget(
4869-
setLabels,
4870-
setter,
4871-
pluginContext.irBuiltIns.unitType,
4872-
expressionTypeArguments,
4873-
classTypeArguments
4874-
)
4904+
helper.extractCallToReflectionTarget(
4905+
setLabels,
4906+
setter,
4907+
pluginContext.irBuiltIns.unitType,
4908+
expressionTypeArguments,
4909+
classTypeArguments
4910+
)
48754911

4876-
tw.writePropertyRefSetBinding(idPropertyRef, setterCallableId)
4912+
tw.writePropertyRefSetBinding(idPropertyRef, setterCallableId)
4913+
}
48774914
} else {
48784915
if (backingField != null && !backingField.owner.isFinal) {
48794916
val setLabels = addFunctionManual(tw.getFreshIdLabel(), OperatorNameConventions.SET.asString(), parameterTypes, pluginContext.irBuiltIns.unitType, classId, locId)
@@ -5008,7 +5045,11 @@ open class KotlinFileExtractor(
50085045
tw.writeCallableBinding(idMemberRef, ids.constructor)
50095046

50105047
val targetCallableId = useFunction<DbCallable>(target.owner.realOverrideTarget, classTypeArguments)
5011-
tw.writeMemberRefBinding(idMemberRef, targetCallableId)
5048+
if (targetCallableId == null) {
5049+
logger.errorElement("Cannot get ID for function reference callable", functionReferenceExpr)
5050+
} else {
5051+
tw.writeMemberRefBinding(idMemberRef, targetCallableId)
5052+
}
50125053

50135054
val helper = CallableReferenceHelper(functionReferenceExpr, locId, ids)
50145055

@@ -5154,7 +5195,11 @@ open class KotlinFileExtractor(
51545195
tw.writeExprsKotlinType(callId, callType.kotlinResult.id)
51555196
extractExprContext(callId, locId, funLabels.methodId, retId)
51565197
val calledMethodId = useFunction<DbMethod>(lambda)
5157-
tw.writeCallableBinding(callId, calledMethodId)
5198+
if (calledMethodId == null) {
5199+
logger.errorElement("Cannot get ID for called lambda", lambda)
5200+
} else {
5201+
tw.writeCallableBinding(callId, calledMethodId)
5202+
}
51585203

51595204
// this access
51605205
extractThisAccess(ids.type, funLabels.methodId, callId, -1, retId, locId)
@@ -5623,7 +5668,11 @@ open class KotlinFileExtractor(
56235668
tw.writeExprsKotlinType(callId, callType.kotlinResult.id)
56245669
extractExprContext(callId, locId, ids.function, returnId)
56255670
val calledMethodId = useFunction<DbMethod>(invokeMethod, functionType.arguments)
5626-
tw.writeCallableBinding(callId, calledMethodId)
5671+
if (calledMethodId == null) {
5672+
logger.errorElement("Cannot get ID for called method", invokeMethod)
5673+
} else {
5674+
tw.writeCallableBinding(callId, calledMethodId)
5675+
}
56275676

56285677
// <fn> access
56295678
val lhsId = tw.getFreshIdLabel<DbVaraccess>()
@@ -5746,14 +5795,17 @@ open class KotlinFileExtractor(
57465795
if (baseConstructor == null) {
57475796
logger.warnElement("Cannot find base constructor", elementToReportOn)
57485797
} else {
5749-
val superCallId = tw.getFreshIdLabel<DbSuperconstructorinvocationstmt>()
5750-
tw.writeStmts_superconstructorinvocationstmt(superCallId, constructorBlockId, 0, ids.constructor)
5751-
57525798
val baseConstructorId = useFunction<DbConstructor>(baseConstructor)
5799+
if (baseConstructorId == null) {
5800+
logger.errorElement("Cannot find base constructor ID", elementToReportOn)
5801+
} else {
5802+
val superCallId = tw.getFreshIdLabel<DbSuperconstructorinvocationstmt>()
5803+
tw.writeStmts_superconstructorinvocationstmt(superCallId, constructorBlockId, 0, ids.constructor)
57535804

5754-
tw.writeHasLocation(superCallId, locId)
5755-
tw.writeCallableBinding(superCallId.cast<DbCaller>(), baseConstructorId)
5756-
extractSuperconstructorArgs(superCallId)
5805+
tw.writeHasLocation(superCallId, locId)
5806+
tw.writeCallableBinding(superCallId.cast<DbCaller>(), baseConstructorId)
5807+
extractSuperconstructorArgs(superCallId)
5808+
}
57575809
}
57585810
}
57595811

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

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,16 +1322,30 @@ open class KotlinUsesExtractor(
13221322
else -> false
13231323
}
13241324

1325-
fun <T: DbCallable> useFunction(f: IrFunction, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>? = null, noReplace: Boolean = false): Label<out T> {
1326-
return useFunction(f, null, classTypeArgsIncludingOuterClasses, noReplace)
1325+
fun <T: DbCallable> useFunction(f: IrFunction, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>? = null, noReplace: Boolean = false): Label<out T>? {
1326+
if (f.isLocalFunction()) {
1327+
val ids = getLocallyVisibleFunctionLabels(f)
1328+
return ids.function.cast<T>()
1329+
}
1330+
val javaFun = kotlinFunctionToJavaEquivalent(f, noReplace)
1331+
val parentId = useDeclarationParent(javaFun.parent, false, classTypeArgsIncludingOuterClasses, true)
1332+
if (parentId == null) {
1333+
logger.error("Couldn't find parent ID for function ${f.name.asString()}")
1334+
return null
1335+
}
1336+
return useFunction(f, javaFun, parentId, classTypeArgsIncludingOuterClasses)
13271337
}
13281338

1329-
fun <T: DbCallable> useFunction(f: IrFunction, parentId: Label<out DbElement>?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, noReplace: Boolean = false): Label<out T> {
1339+
fun <T: DbCallable> useFunction(f: IrFunction, parentId: Label<out DbElement>, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, noReplace: Boolean = false): Label<out T> {
13301340
if (f.isLocalFunction()) {
13311341
val ids = getLocallyVisibleFunctionLabels(f)
13321342
return ids.function.cast<T>()
13331343
}
13341344
val javaFun = kotlinFunctionToJavaEquivalent(f, noReplace)
1345+
return useFunction(f, javaFun, parentId, classTypeArgsIncludingOuterClasses)
1346+
}
1347+
1348+
private fun <T: DbCallable> useFunction(f: IrFunction, javaFun: IrFunction, parentId: Label<out DbElement>, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?): Label<out T> {
13351349
val label = getFunctionLabel(javaFun, parentId, classTypeArgsIncludingOuterClasses)
13361350
val id: Label<T> = tw.getLabelFor(label) {
13371351
extractPrivateSpecialisedDeclaration(f, classTypeArgsIncludingOuterClasses)

0 commit comments

Comments
 (0)