Skip to content

Commit 31ada23

Browse files
committed
Divided synthetic methods to "true-synthetic methods" and "implicitly declared methods"
1 parent 1a47496 commit 31ada23

File tree

7 files changed

+61
-45
lines changed

7 files changed

+61
-45
lines changed

utbot-cli/src/main/kotlin/org/utbot/cli/GenerateTestsCommand.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import org.utbot.framework.plugin.api.CodegenLanguage
1717
import org.utbot.framework.plugin.api.UtMethodTestSet
1818
import org.utbot.framework.plugin.api.util.UtContext
1919
import org.utbot.framework.plugin.api.util.isAbstract
20+
import org.utbot.framework.plugin.api.util.isSynthetic
2021
import org.utbot.framework.plugin.api.util.withUtContext
21-
import org.utbot.framework.util.isKnownSyntheticMethod
22+
import org.utbot.framework.util.isKnownImplicitlyDeclaredMethod
2223
import org.utbot.sarif.SarifReport
2324
import org.utbot.sarif.SourceFindingStrategyDefault
2425
import java.nio.file.Files
@@ -97,7 +98,9 @@ class GenerateTestsCommand :
9798
withUtContext(UtContext(classLoader)) {
9899
val classIdUnderTest = ClassId(targetClassFqn)
99100
val targetMethods = classIdUnderTest.targetMethods()
100-
.filterWhen(UtSettings.skipTestGenerationForSyntheticMethods) { !isKnownSyntheticMethod(it) }
101+
.filterWhen(UtSettings.skipTestGenerationForSyntheticAndImplicitlyDeclaredMethods) {
102+
!it.isSynthetic && !it.isKnownImplicitlyDeclaredMethod
103+
}
101104
.filterNot { it.isAbstract }
102105
val testCaseGenerator = initializeGenerator(workingDirectory)
103106

utbot-framework-api/src/main/kotlin/org/utbot/framework/UtSettings.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.utbot.framework
33
import com.jetbrains.rd.util.LogLevel
44
import mu.KotlinLogging
55
import org.utbot.common.AbstractSettings
6+
import java.lang.reflect.Executable
67
private val logger = KotlinLogging.logger {}
78

89
/**
@@ -361,9 +362,9 @@ object UtSettings : AbstractSettings(
361362
var singleSelector by getBooleanProperty(true)
362363

363364
/**
364-
* Flag that indicates whether tests for synthetic methods (values, valueOf in enums) should be generated, or not
365+
* Flag that indicates whether tests for synthetic (see [Executable.isSynthetic]) and implicitly declared methods (like values, valueOf in enums) should be generated, or not
365366
*/
366-
var skipTestGenerationForSyntheticMethods by getBooleanProperty(true)
367+
var skipTestGenerationForSyntheticAndImplicitlyDeclaredMethods by getBooleanProperty(true)
367368

368369
/**
369370
* Flag that indicates whether should we branch on and set static fields from trusted libraries or not.

utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/util/IdUtil.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,9 @@ val ExecutableId.isPackagePrivate: Boolean
518518
val ExecutableId.isAbstract: Boolean
519519
get() = Modifier.isAbstract(modifiers)
520520

521+
val ExecutableId.isSynthetic: Boolean
522+
get() = (this is MethodId) && method.isSynthetic
523+
521524

522525
/**
523526
* Construct MethodId
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.utbot.framework.util
2+
3+
import org.utbot.framework.plugin.api.ExecutableId
4+
import org.utbot.framework.plugin.api.util.isData
5+
import org.utbot.framework.plugin.api.util.isEnum
6+
7+
/**
8+
* Returns whether this method could be implicitly generated by compiler, or not.
9+
*
10+
* Note that here we can only judge this by method name and kind of class (data class, enum, etc).
11+
* There seems to be no (at least, easy) way to check from bytecode if this method was actually overridden by user,
12+
* so this function will return true even if the matching method is not autogenerated but written explicitly by user.
13+
*/
14+
val ExecutableId.isKnownImplicitlyDeclaredMethod: Boolean
15+
get() {
16+
if (classId.isEnum)
17+
return name in KnownImplicitlyDeclaredMethods.enumImplicitlyDeclaredMethodNames
18+
19+
if (classId.isData)
20+
return KnownImplicitlyDeclaredMethods.dataClassImplicitlyDeclaredMethodNameRegexps.any { it.matches(name) }
21+
return false
22+
}
23+
24+
/**
25+
* Contains names of methods that are always autogenerated by compiler and thus it is unlikely that
26+
* one would want to generate tests for them.
27+
*/
28+
private object KnownImplicitlyDeclaredMethods {
29+
/** List with names of enum methods that are generated by compiler */
30+
val enumImplicitlyDeclaredMethodNames = listOf("values", "valueOf")
31+
32+
/** List with regexps that match names of methods that are generated by Kotlin compiler for data classes */
33+
val dataClassImplicitlyDeclaredMethodNameRegexps = listOf(
34+
"equals",
35+
"hashCode",
36+
"toString",
37+
"copy",
38+
"component[1-9][0-9]*"
39+
).map { it.toRegex() }
40+
}

utbot-framework/src/main/kotlin/org/utbot/framework/util/SyntheticMethods.kt

Lines changed: 0 additions & 34 deletions
This file was deleted.

utbot-intellij/src/main/kotlin/org/utbot/intellij/plugin/util/PsiClassHelper.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ private val PsiMember.isKotlinGetterOrSetter: Boolean
2323
return isGetter || isSetter
2424
}
2525

26-
// By now, we think that method in Kotlin is synthetic iff navigation to its declaration leads to its declaring class
27-
// rather than the method itself (because synthetic methods don't have bodies that we can navigate to)
28-
private val PsiMember.isSyntheticKotlinMethod: Boolean
26+
// By now, we think that method in Kotlin is autogenerated iff navigation to its declaration leads to its declaring class
27+
// rather than the method itself (because such methods don't have bodies that we can navigate to)
28+
private val PsiMember.isKotlinAutogeneratedMethod: Boolean
2929
get() = this is KtLightMethod && navigationElement is KtClass
3030

3131
fun Iterable<MemberInfo>.filterTestableMethods(): List<MemberInfo> = this
32-
.filterWhen(UtSettings.skipTestGenerationForSyntheticMethods) {
33-
it.member !is SyntheticElement && !it.member.isSyntheticKotlinMethod
32+
.filterWhen(UtSettings.skipTestGenerationForSyntheticAndImplicitlyDeclaredMethods) {
33+
it.member !is SyntheticElement && !it.member.isKotlinAutogeneratedMethod
3434
}
3535
.filterNot { it.member.isAbstract }
3636
.filterNot { it.member.isKotlinGetterOrSetter }

utbot-junit-contest/src/main/kotlin/org/utbot/contest/Contest.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import org.utbot.framework.plugin.api.util.jClass
2929
import org.utbot.framework.plugin.api.util.utContext
3030
import org.utbot.framework.plugin.api.util.withUtContext
3131
import org.utbot.framework.plugin.services.JdkInfoService
32-
import org.utbot.framework.util.isKnownSyntheticMethod
32+
import org.utbot.framework.util.isKnownImplicitlyDeclaredMethod
3333
import org.utbot.fuzzer.UtFuzzedExecution
3434
import org.utbot.instrumentation.ConcreteExecutor
3535
import org.utbot.instrumentation.ConcreteExecutorPool
@@ -60,6 +60,7 @@ import kotlinx.coroutines.newSingleThreadContext
6060
import kotlinx.coroutines.runBlocking
6161
import kotlinx.coroutines.withTimeoutOrNull
6262
import kotlinx.coroutines.yield
63+
import org.utbot.framework.plugin.api.util.isSynthetic
6364

6465
internal const val junitVersion = 4
6566
private val logger = KotlinLogging.logger {}
@@ -402,7 +403,9 @@ private fun prepareClass(javaClazz: Class<*>, methodNameFilter: String?): List<E
402403
val classFilteredMethods = methodsToGenerate
403404
.map { it.executableId }
404405
.filter { methodNameFilter?.equals(it.name) ?: true }
405-
.filterWhen(UtSettings.skipTestGenerationForSyntheticMethods) { !isKnownSyntheticMethod(it) }
406+
.filterWhen(UtSettings.skipTestGenerationForSyntheticAndImplicitlyDeclaredMethods) {
407+
!it.isSynthetic && !it.isKnownImplicitlyDeclaredMethod
408+
}
406409
.toList()
407410

408411

0 commit comments

Comments
 (0)