Skip to content

Support package-private classes and constructors in AssembleModelGenerator #356

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
Jun 30, 2022
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 @@ -3,6 +3,7 @@ package org.utbot.engine
import org.utbot.common.findField
import org.utbot.common.findFieldOrNull
import org.utbot.common.invokeCatching
import org.utbot.common.withAccessibility
import org.utbot.framework.plugin.api.ClassId
import org.utbot.framework.plugin.api.ConstructorId
import org.utbot.framework.plugin.api.EnvironmentModels
Expand Down Expand Up @@ -390,12 +391,19 @@ class ValueConstructor {
*/
private fun value(model: UtModel) = construct(model, null).value


private fun MethodId.call(args: List<Any?>, instance: Any?): Any? =
method.invokeCatching(obj = instance, args = args).getOrThrow()
method.run {
withAccessibility {
invokeCatching(obj = instance, args = args).getOrThrow()
}
}

private fun ConstructorId.call(args: List<Any?>): Any? =
constructor.newInstance(*args.toTypedArray())
constructor.run {
withAccessibility {
newInstance(*args.toTypedArray())
}
}

/**
* Fetches primitive value from NutsModel to create array of primitives.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import org.utbot.framework.plugin.api.util.defaultValueModel
import org.utbot.framework.plugin.api.util.executableId
import org.utbot.framework.plugin.api.util.jClass
import org.utbot.framework.util.nextModelName
import java.lang.reflect.Constructor
import java.util.IdentityHashMap

/**
Expand Down Expand Up @@ -256,7 +257,7 @@ class AssembleModelGenerator(private val methodUnderTest: UtMethod<*>) {
}
//fill field value if it hasn't been filled by constructor, and it is not default
if (fieldId in constructorInfo.affectedFields ||
(fieldId !in constructorInfo.setFields && !fieldModel.hasDefaultValue())
(fieldId !in constructorInfo.setFields && !fieldModel.hasDefaultValue())
) {
val modifierCall = modifierCall(this, fieldId, assembleModel(fieldModel))
callChain.add(modifierCall)
Expand Down Expand Up @@ -357,15 +358,21 @@ class AssembleModelGenerator(private val methodUnderTest: UtMethod<*>) {
*/
private fun findBestConstructorOrNull(compositeModel: UtCompositeModel): ConstructorId? {
val classId = compositeModel.classId
if (!classId.isPublic || classId.isInner) return null
if (!classId.isVisible || classId.isInner) return null

return classId.jClass.declaredConstructors
.filter { it.isPublic || !it.isPrivate && it.declaringClass.packageName.startsWith(methodPackageName) }
.filter { it.isVisible }
.sortedByDescending { it.parameterCount }
.map { it.executableId }
.firstOrNull { constructorAnalyzer.isAppropriate(it) }
}

private val ClassId.isVisible : Boolean
get() = this.isPublic || !this.isPrivate && this.packageName.startsWith(methodPackageName)

private val Constructor<*>.isVisible : Boolean
get() = this.isPublic || !this.isPrivate && this.declaringClass.packageName.startsWith(methodPackageName)

/**
* Creates setter or direct setter call to set a field.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import kotlin.reflect.KClass
import org.mockito.Mockito
import org.mockito.stubbing.Answer
import org.objectweb.asm.Type
import org.utbot.common.withAccessibility

/**
* Constructs values (including mocks) from models.
Expand Down Expand Up @@ -433,10 +434,18 @@ class MockValueConstructor(
}

private fun MethodId.call(args: List<Any?>, instance: Any?): Any? =
method.invokeCatching(obj = instance, args = args).getOrThrow()
method.run {
withAccessibility {
invokeCatching(obj = instance, args = args).getOrThrow()
}
}

private fun ConstructorId.call(args: List<Any?>): Any? =
constructor.newInstance(*args.toTypedArray())
constructor.run {
withAccessibility {
newInstance(*args.toTypedArray())
}
}

/**
* Fetches primitive value from NutsModel to create array of primitives.
Expand Down