Skip to content

Do necessary down casts when generating method calls #2576

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import org.utbot.framework.codegen.domain.models.CgVariable
import org.utbot.framework.codegen.services.access.CgCallableAccessManagerImpl.FieldAccessorSuitability.*
import org.utbot.framework.codegen.tree.CgComponents.getStatementConstructorBy
import org.utbot.framework.codegen.tree.CgComponents.getVariableConstructorBy
import org.utbot.framework.codegen.tree.downcastIfNeeded
import org.utbot.framework.codegen.tree.getAmbiguousOverloadsOf
import org.utbot.framework.codegen.tree.importIfNeeded
import org.utbot.framework.codegen.tree.isUtil
Expand Down Expand Up @@ -114,7 +115,11 @@ internal class CgCallableAccessManagerImpl(val context: CgContext) : CgCallableA
override operator fun CgIncompleteMethodCall.invoke(vararg args: Any?): CgMethodCall {
val resolvedArgs = args.resolve()
val methodCall = if (method.canBeCalledWith(caller, resolvedArgs)) {
CgMethodCall(caller, method, resolvedArgs.guardedForDirectCallOf(method)).takeCallerFromArgumentsIfNeeded()
CgMethodCall(
caller = caller?.let { downcastIfNeeded(method.classId, caller) },
executableId = method,
arguments = resolvedArgs.guardedForDirectCallOf(method)
).takeCallerFromArgumentsIfNeeded()
} else {
method.callWithReflection(caller, resolvedArgs)
}
Expand Down Expand Up @@ -200,7 +205,8 @@ internal class CgCallableAccessManagerImpl(val context: CgContext) : CgCallableA
// this executable can be called on builtin type
this.type is BuiltinClassId && this.type in builtinCallersWithoutReflection -> true

else -> false
// receiver can be downcasted before call
else -> executable.isAccessibleFrom(testClassPackageName)
}

// For some builtin types we need to clarify
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1159,7 +1159,7 @@ open class CgMethodConstructor(val context: CgContext) : CgContextOwner by conte
} else if (context.codegenLanguage == CodegenLanguage.JAVA &&
!jField.isStatic && canBeReadViaGetterFrom(context)
) {
CgMethodCall(variable, getter, emptyList())
variable[getter]()
} else {
utilsClassId[getFieldValue](variable, this.declaringClass.name, this.name)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ open class CgVariableConstructor(val context: CgContext) :
} else if (context.codegenLanguage == CodegenLanguage.JAVA &&
!field.isStatic && fieldId.canBeSetViaSetterFrom(context)
) {
+CgMethodCall(obj, fieldId.setter, listOf(valueForField))
+obj[fieldId.setter](valueForField)
} else {
// composite models must not have info about static fields, hence only non-static fields are set here
+utilsClassId[setField](obj, fieldId.declaringClass.name, fieldId.name, valueForField)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,20 @@ internal fun CgContextOwner.typeCast(
return CgTypeCast(denotableTargetType, expression, isSafetyCast)
}

/**
* Casts [expression] to [targetType] only if downcast is needed,
* e.g. this method will cast `Collection` to `Set`, but not vice-versa.
*
* @see typeCast
*/
internal fun CgContextOwner.downcastIfNeeded(
targetType: ClassId,
expression: CgExpression,
isSafetyCast: Boolean = false
): CgExpression =
if (expression.type isSubtypeOf targetType) expression
else typeCast(targetType, expression, isSafetyCast)

/**
* Sets an element of arguments array in parameterized test,
* if test framework represents arguments as array.
Expand Down