Skip to content
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

(#21) Add support for overriding default values #32

Merged
merged 3 commits into from
May 5, 2024
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ Apart from that if you want to control range / length / size of the values being
- `Pair`
- Nullable types
- Properties with **unsupported** types which are nullable are allowed, and the generated value would always be null
- Properties with default values can have *any type*, as they are not considered while generating code
- Properties with default values can have *any type*, as they are not considered while generating code, (unless the `overrideDefaultValues` property of the `Dowel` annotation is toggled to `true` for that class)
- Types in the above mentioned list having generic type parameters (like `List` and `Map`) can only have `@Dowel` supported types as their type parameters. Like `List<String>`, `Map<String, @Dowel class>`
- As far as a type is in above mentioned supported list, there are no practical limitations on how many times they may be nested.
Like `List<Map<Set<String>, List<@Dowel class>>>`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ package com.jayasuryat.dowel.sample.ui.home.model.location

import com.jayasuryat.dowel.annotation.Dowel

@Dowel
@Dowel(overrideDefaultValues = true)
data class Location(
val lat: Long?,
val lat: Long? = 0L,
val lon: Long?,
)
2 changes: 2 additions & 0 deletions dowel-annotation/api/dowel-annotation.api
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ public abstract interface annotation class com/jayasuryat/dowel/annotation/Consi
public abstract interface annotation class com/jayasuryat/dowel/annotation/Dowel : java/lang/annotation/Annotation {
public static final field COUNT_PROPERTY_NAME Ljava/lang/String;
public static final field Companion Lcom/jayasuryat/dowel/annotation/Dowel$Companion;
public static final field OVERRIDE_DEFAULT_VALUES_NAME Ljava/lang/String;
public abstract fun count ()I
public abstract fun overrideDefaultValues ()Z
}

public final class com/jayasuryat/dowel/annotation/Dowel$Companion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import com.jayasuryat.dowel.annotation.internal.DowelInternal
* * [androidx.annotation.Size]
*
* @param [count] Number of items in the generated sequence of items
* @param [overrideDefaultValues] Flag indicating whether to override properties with default values
* @see [DowelList]
* @see [ConsiderForDowel]
*/
Expand All @@ -78,6 +79,7 @@ import com.jayasuryat.dowel.annotation.internal.DowelInternal
@Target(AnnotationTarget.CLASS)
public annotation class Dowel(
val count: Int = DEFAULT_COUNT,
val overrideDefaultValues: Boolean = false,
) {

public companion object {
Expand All @@ -86,5 +88,8 @@ public annotation class Dowel(

@DowelInternal
public const val COUNT_PROPERTY_NAME: String = "count"

@DowelInternal
public const val OVERRIDE_DEFAULT_VALUES_NAME: String = "overrideDefaultValues"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ internal class ClassRepresentationMapper(
val constructor: KSFunctionDeclaration = classDeclaration.primaryConstructor!!
val parameters: List<KSValueParameter> = constructor.parameters

// Flag to enable / disable code gen for properties with default values
val shouldOverrideDefaultValues: Boolean = classDeclaration.shouldOverrideDefaultValues()

val mappedParameters: List<ClassRepresentation.Parameter> = parameters
.filter { !it.hasDefault } // Ignoring all properties with default values
.filter { shouldOverrideDefaultValues || it.hasDefault.not() }
.mapNotNull { parameter -> // Filtering out UnsupportedType parameters

val resolvedType = parameter.type.resolve()
Expand Down Expand Up @@ -690,3 +693,16 @@ internal class ClassRepresentationMapper(
.replaceFirstChar { char -> char.lowercaseChar() } + "List"
}
}

/**
* Checks if the given KSClassDeclaration should override default values.
* @return Boolean value indicating whether default values should be overridden.
*/
private fun KSClassDeclaration.shouldOverrideDefaultValues(): Boolean {
val classDeclaration = this
return classDeclaration.annotations
.first { it.shortName.asString() == Dowel::class.java.simpleName }
.arguments
.first { it.name!!.asString() == Dowel.Companion.OVERRIDE_DEFAULT_VALUES_NAME }
.value as Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,40 @@ internal class DowelProcessingTest {
Assert.assertTrue(result.messages.contains(expectedMessage))
}

@Test
fun `should compile success for dowel with overrideDefaultValues`() {

val source = """
package dowel

import com.jayasuryat.dowel.annotation.Dowel

@Dowel(overrideDefaultValues = true)
internal class Person(
val name: String = "",
val age: String,
)

@Dowel(overrideDefaultValues = false)
internal class Address(
val name: String = "",
val place: String,
)

@Dowel
internal class SomeData(
val name: String = "",
val data: String,
)

""".trimIndent()

val kotlinSource: SourceFile = SourceFile.kotlin(name = "Person.kt", contents = source)
val result: KotlinCompilation.Result = compile(kotlinSource, PreviewParameterProviderStub)

Assert.assertEquals(KotlinCompilation.ExitCode.OK, result.exitCode)
Assert.assertEquals("", result.messages)
}
//spotless:on

private fun compile(
Expand Down
Loading