From b3c2a4851173fb1534d6b401637855d2992bf9f5 Mon Sep 17 00:00:00 2001 From: Mike Pedersen Date: Fri, 9 Aug 2024 14:02:27 +0200 Subject: [PATCH] Make it optional for parameter names to match named generators. Previously, if parameter names were enabled at compile-time, all parameters were required to match a named generator. This made including parameter names, and using Lincheck with languages always enabling parameter names like Scala, impractical. This instead makes it optional, such that if a named generator matches it is used but if none is found then we apply a default generator. This also enables parameter names at compile time for tests in order to test this behavior. --- build.gradle.kts | 1 + .../kotlinx/lincheck/CTestStructure.java | 17 +++++++++++------ .../generator/ParamGeneratorsTests.kt | 18 ++++++++++++++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index aea6abf24..3588cb7a3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,6 +38,7 @@ kotlin { val test by compilations.getting { kotlinOptions.jvmTarget = "11" + kotlinOptions.options.javaParameters = true } } diff --git a/src/jvm/main/org/jetbrains/kotlinx/lincheck/CTestStructure.java b/src/jvm/main/org/jetbrains/kotlinx/lincheck/CTestStructure.java index cf6c92e5b..becbc31d3 100644 --- a/src/jvm/main/org/jetbrains/kotlinx/lincheck/CTestStructure.java +++ b/src/jvm/main/org/jetbrains/kotlinx/lincheck/CTestStructure.java @@ -243,12 +243,17 @@ private static ParameterGenerator getOrCreateGenerator(Method m, Param paramAnn = p.getAnnotation(Param.class); // If this annotation not presented use named generator based on name presented in @Operation or parameter name. if (paramAnn == null) { - // If name in @Operation is presented, return the generator with this name, - // otherwise return generator with parameter's name - String name = nameInOperation != null ? nameInOperation : - (p.isNamePresent() ? p.getName() : null); - if (name != null) - return checkAndGetNamedGenerator(namedGens, name); + // If name in @Operation is presented, return the generator with this name + if (nameInOperation != null) + return checkAndGetNamedGenerator(namedGens, nameInOperation); + + // Otherwise, if the parameter name matches a named generator, use that one + if (p.isNamePresent()) { + ParameterGenerator generator = namedGens.get(p.getName()); + if (generator != null) + return generator; + } + // Parameter generator is not specified, try to create a default one ParameterGenerator defaultGenerator = defaultGens.get(p.getType()); if (defaultGenerator != null) diff --git a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/generator/ParamGeneratorsTests.kt b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/generator/ParamGeneratorsTests.kt index c3f9ebb23..eae1578eb 100644 --- a/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/generator/ParamGeneratorsTests.kt +++ b/src/jvm/test/org/jetbrains/kotlinx/lincheck_test/generator/ParamGeneratorsTests.kt @@ -88,6 +88,24 @@ class MethodParameterGenerationTestWithSecondParameterAnnotated { } +/** + * Test checks that a named generator matching a parameter name is applied. + * + * This relies on the parameter name being available (i.e. by being compiled with `-java-parameters`). + */ +@Param(name = "key", gen = IntGen::class, conf = "0:10") +class MethodParameterGenerationTestWithParameterNameMatchingGenerator { + @Operation + fun operation(key: Int) { + if (key < 0 || key > 10) { + throw InternalLincheckTestUnexpectedException + } + } + + @Test + fun test() = ModelCheckingOptions().check(this::class) +} + /** * Test checks that method with both parameters of the same type won't receive same values all the time */