Skip to content

Commit 2a74b8c

Browse files
authored
Do necessary down casts when generating method calls #2598 (#2576)
1 parent f364483 commit 2a74b8c

File tree

4 files changed

+24
-4
lines changed

4 files changed

+24
-4
lines changed

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/services/access/CgCallableAccessManager.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import org.utbot.framework.codegen.domain.models.CgVariable
2727
import org.utbot.framework.codegen.services.access.CgCallableAccessManagerImpl.FieldAccessorSuitability.*
2828
import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy
2929
import org.utbot.framework.codegen.tree.CgComponents.getVariableConstructorBy
30+
import org.utbot.framework.codegen.tree.downcastIfNeeded
3031
import org.utbot.framework.codegen.tree.getAmbiguousOverloadsOf
3132
import org.utbot.framework.codegen.tree.importIfNeeded
3233
import org.utbot.framework.codegen.tree.isUtil
@@ -111,7 +112,11 @@ class CgCallableAccessManagerImpl(val context: CgContext) : CgCallableAccessMana
111112
override operator fun CgIncompleteMethodCall.invoke(vararg args: Any?): CgMethodCall {
112113
val resolvedArgs = args.resolve()
113114
val methodCall = if (method.canBeCalledWith(caller, resolvedArgs)) {
114-
CgMethodCall(caller, method, resolvedArgs.guardedForDirectCallOf(method)).takeCallerFromArgumentsIfNeeded()
115+
CgMethodCall(
116+
caller = caller?.let { downcastIfNeeded(method.classId, caller) },
117+
executableId = method,
118+
arguments = resolvedArgs.guardedForDirectCallOf(method)
119+
).takeCallerFromArgumentsIfNeeded()
115120
} else {
116121
method.callWithReflection(caller, resolvedArgs)
117122
}
@@ -187,7 +192,8 @@ class CgCallableAccessManagerImpl(val context: CgContext) : CgCallableAccessMana
187192
// this executable can be called on builtin type
188193
this.type is BuiltinClassId && this.type in builtinCallersWithoutReflection -> true
189194

190-
else -> false
195+
// receiver can be downcasted before call
196+
else -> executable.isAccessibleFrom(testClassPackageName)
191197
}
192198

193199
// For some builtin types we need to clarify

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgMethodConstructor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ open class CgMethodConstructor(val context: CgContext) : CgContextOwner by conte
11711171
} else if (context.codegenLanguage == CodegenLanguage.JAVA &&
11721172
!jField.isStatic && canBeReadViaGetterFrom(context)
11731173
) {
1174-
CgMethodCall(variable, getter, emptyList())
1174+
variable[getter]()
11751175
} else {
11761176
utilsClassId[getFieldValue](variable, this.declaringClass.name, this.name)
11771177
}

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/CgVariableConstructor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ open class CgVariableConstructor(val context: CgContext) :
215215
} else if (context.codegenLanguage == CodegenLanguage.JAVA &&
216216
!field.isStatic && fieldId.canBeSetViaSetterFrom(context)
217217
) {
218-
+CgMethodCall(obj, fieldId.setter, listOf(valueForField))
218+
+obj[fieldId.setter](valueForField)
219219
} else {
220220
// composite models must not have info about static fields, hence only non-static fields are set here
221221
+utilsClassId[setField](obj, fieldId.declaringClass.name, fieldId.name, valueForField)

utbot-framework/src/main/kotlin/org/utbot/framework/codegen/tree/ConstructorUtils.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,20 @@ internal fun CgContextOwner.typeCast(
291291
return CgTypeCast(denotableTargetType, expression, isSafetyCast)
292292
}
293293

294+
/**
295+
* Casts [expression] to [targetType] only if downcast is needed,
296+
* e.g. this method will cast `Collection` to `Set`, but not vice-versa.
297+
*
298+
* @see typeCast
299+
*/
300+
internal fun CgContextOwner.downcastIfNeeded(
301+
targetType: ClassId,
302+
expression: CgExpression,
303+
isSafetyCast: Boolean = false
304+
): CgExpression =
305+
if (expression.type isSubtypeOf targetType) expression
306+
else typeCast(targetType, expression, isSafetyCast)
307+
294308
/**
295309
* Sets an element of arguments array in parameterized test,
296310
* if test framework represents arguments as array.

0 commit comments

Comments
 (0)