diff --git a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt index f7fb77c0c7..43ce904871 100644 --- a/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt +++ b/utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt @@ -189,11 +189,20 @@ val ClassId.isDoubleType: Boolean val ClassId.isClassType: Boolean get() = this == classClassId +/** + * Returns [Metadata] annotation if this is a Kotlin class, null otherwise + */ +val ClassId.kotlinMetadata: Metadata? + get() = jClass.annotations.filterIsInstance().singleOrNull() + +val ClassId.isFromKotlin: Boolean + get() = kotlinMetadata != null + /** * Checks if the class is a Kotlin class with kind File (see [Metadata.kind] for more details) */ val ClassId.isKotlinFile: Boolean - get() = jClass.annotations.filterIsInstance().singleOrNull()?.let { + get() = kotlinMetadata?.let { KotlinClassHeader.Kind.getById(it.kind) == KotlinClassHeader.Kind.FILE_FACADE } ?: false diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/ClassIdUtil.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/ClassIdUtil.kt index aa9c00190c..93eee9c85e 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/ClassIdUtil.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/codegen/model/util/ClassIdUtil.kt @@ -1,8 +1,8 @@ package org.utbot.framework.codegen.model.util import org.utbot.framework.plugin.api.ClassId +import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.FieldId -import org.utbot.framework.plugin.api.MethodId import org.utbot.framework.plugin.api.util.isPackagePrivate import org.utbot.framework.plugin.api.util.isProtected import org.utbot.framework.plugin.api.util.isPublic @@ -40,11 +40,11 @@ infix fun ClassId.isAccessibleFrom(packageName: String): Boolean { /** * Returns field of [this], such that [methodId] is a getter for it (or null if methodId doesn't represent a getter) */ -internal fun ClassId.fieldThatIsGotWith(methodId: MethodId): FieldId? = +internal fun ClassId.fieldThatIsGotWith(methodId: ExecutableId): FieldId? = allDeclaredFieldIds.singleOrNull { !it.isStatic && it.getter.describesSameMethodAs(methodId) } /** * Returns field of [this], such that [methodId] is a setter for it (or null if methodId doesn't represent a setter) */ -internal fun ClassId.fieldThatIsSetWith(methodId: MethodId): FieldId? = +internal fun ClassId.fieldThatIsSetWith(methodId: ExecutableId): FieldId? = allDeclaredFieldIds.singleOrNull { !it.isStatic && it.setter.describesSameMethodAs(methodId) } \ No newline at end of file diff --git a/utbot-framework/src/main/kotlin/org/utbot/framework/util/ImplicitlyDeclaredMethods.kt b/utbot-framework/src/main/kotlin/org/utbot/framework/util/ImplicitlyDeclaredMethods.kt index 727f344abe..655fc16c66 100644 --- a/utbot-framework/src/main/kotlin/org/utbot/framework/util/ImplicitlyDeclaredMethods.kt +++ b/utbot-framework/src/main/kotlin/org/utbot/framework/util/ImplicitlyDeclaredMethods.kt @@ -1,8 +1,12 @@ package org.utbot.framework.util +import org.utbot.framework.codegen.model.util.fieldThatIsGotWith +import org.utbot.framework.codegen.model.util.fieldThatIsSetWith import org.utbot.framework.plugin.api.ExecutableId import org.utbot.framework.plugin.api.util.isData import org.utbot.framework.plugin.api.util.isEnum +import org.utbot.framework.plugin.api.util.isFromKotlin +import org.utbot.framework.plugin.api.util.isKotlinFile /** * Returns whether this method could be implicitly generated by compiler, or not. @@ -14,11 +18,19 @@ import org.utbot.framework.plugin.api.util.isEnum val ExecutableId.isKnownImplicitlyDeclaredMethod: Boolean get() = when { + // this check is needed because reflection is not fully supported for file facades -- see KT-16479, + // by now we assume that such classes can't contain autogenerated methods + classId.isKotlinFile -> false + isKotlinGetterOrSetter -> true classId.isEnum -> name in KnownImplicitlyDeclaredMethods.enumImplicitlyDeclaredMethodNames classId.isData -> KnownImplicitlyDeclaredMethods.dataClassImplicitlyDeclaredMethodNameRegexps.any { it.matches(name) } else -> false } +internal val ExecutableId.isKotlinGetterOrSetter: Boolean + get() = classId.isFromKotlin && + (classId.fieldThatIsGotWith(this) != null || classId.fieldThatIsSetWith(this) != null) + /** * Contains names of methods that are always autogenerated by compiler and thus it is unlikely that * one would want to generate tests for them.