Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
68cc46d
Update kogera version
k163377 May 4, 2025
501fdc3
Merge pull request #338 from ProjectMapK/k163377-patch-1
k163377 May 4, 2025
a586e8b
Fixed to not generate fields
k163377 May 5, 2025
f33e391
Merge pull request #339 from ProjectMapK/ref-name
k163377 May 5, 2025
972a47e
Removal of redundant branch
k163377 May 5, 2025
b0df934
Merge pull request #340 from ProjectMapK/refactors
k163377 May 5, 2025
f89d6a6
Optimize imports
k163377 May 10, 2025
be70eea
Merge pull request #341 from ProjectMapK/opt-imports
k163377 May 10, 2025
f65122b
Fixed to verify by comparison
k163377 May 10, 2025
742d0da
Merge pull request #342 from ProjectMapK/fix-test
k163377 May 10, 2025
a30d857
Add deser tests for primitive that consume two argument slots
k163377 May 10, 2025
9658240
Add ser tests for primitive that consume two argument slots
k163377 May 10, 2025
22fff45
Replaced the test subject with long
k163377 May 11, 2025
9d085b8
Fix order
k163377 May 11, 2025
6ebe24d
Merge pull request #343 from ProjectMapK/value-class-tests
k163377 May 11, 2025
369db98
Fix test definition
k163377 May 11, 2025
660e8e3
Fix test definition
k163377 May 11, 2025
c9a2ad0
Fix typo
k163377 May 11, 2025
0aec1da
Refactor test
k163377 May 11, 2025
cbacfa2
Refactor test
k163377 May 11, 2025
70f4bf7
Fix test definition
k163377 May 11, 2025
bc663f8
Merge pull request #344 from ProjectMapK/fix-tests
k163377 May 11, 2025
988a79e
Replace the non-custom mapper with defaultMapper
k163377 May 11, 2025
a21c704
Replace the non-custom mapper with defaultMapper
k163377 May 11, 2025
5872ecc
fix
k163377 May 11, 2025
c1faf25
Merge pull request #345 from ProjectMapK/default-mapper
k163377 May 11, 2025
b3d5206
Add NullablePrimitive ser tests
k163377 May 17, 2025
b378c4d
Add NullablePrimitive deser tests
k163377 May 17, 2025
a0662c7
Addition of cases that were not generated
k163377 May 17, 2025
0e336a9
Merge pull request #346 from ProjectMapK/nullable-primitive
k163377 May 17, 2025
7a2da09
Enable trailing_comma in formatter
k163377 May 17, 2025
8a6d737
Merge pull request #347 from ProjectMapK/format
k163377 May 17, 2025
758fa68
Update CI Kotlin 2.2 version
k163377 May 25, 2025
068ba92
Merge pull request #348 from ProjectMapK/k163377-patch-1
k163377 May 25, 2025
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: 0 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ root = true

[*.{kt,kts}]
ktlint_code_style = intellij_idea
ij_kotlin_allow_trailing_comma = false
ij_kotlin_allow_trailing_comma_on_call_site = false
2 changes: 1 addition & 1 deletion .github/workflows/test-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
# LTS versions, latest version (if exists)
java-version: [ '17', '21', '24' ]
# Minimum version, latest release version, latest pre-release version (if exists)
kotlin: ['2.0.21', '2.1.20', '2.2.0-Beta2']
kotlin: ['2.0.21', '2.1.20', '2.2.0-RC']
env:
KOTLIN_VERSION: ${{ matrix.kotlin }}
name: "Kotlin ${{ matrix.kotlin }} - Java ${{ matrix.java-version }}"
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ val jacksonVersion = libs.versions.jackson.get()
val generatedSrcPath = "${layout.buildDirectory.get()}/generated/kotlin"

group = groupStr
version = "${jacksonVersion}-beta23"
version = "${jacksonVersion}-beta24"

repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.fasterxml.jackson.databind.module.SimpleAbstractTypeResolver

internal abstract class ClosedRangeMixin<T> @JsonCreator constructor(
public val start: T,
@get:JsonProperty("end") public val endInclusive: T
@get:JsonProperty("end") public val endInclusive: T,
) {
@JsonIgnore
public abstract fun getEnd(): T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.fasterxml.jackson.databind.util.StdConverter
*/
internal class ValueClassBoxConverter<S : Any?, D : Any>(
unboxedClass: Class<S>,
val boxedClass: Class<D>
val boxedClass: Class<D>,
) : StdConverter<S, D>() {
private val boxMethod = boxedClass.getDeclaredMethod("box-impl", unboxedClass).apply {
ClassUtil.checkAndFixAccess(this, false)
Expand All @@ -35,7 +35,7 @@ internal class ValueClassUnboxConverter<T : Any>(val valueClass: Class<T>) : Std

override fun getInputType(typeFactory: TypeFactory): JavaType = typeFactory.constructType(valueClass)
override fun getOutputType(
typeFactory: TypeFactory
typeFactory: TypeFactory,
): JavaType = typeFactory.constructType(unboxMethod.genericReturnType)

val delegatingSerializer: StdDelegatingSerializer by lazy { StdDelegatingSerializer(this) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public fun jacksonMapperBuilder(initializer: KotlinModule.Builder.() -> Unit = {

@JvmOverloads
public fun ObjectMapper.registerKotlinModule(
initializer: KotlinModule.Builder.() -> Unit = {}
initializer: KotlinModule.Builder.() -> Unit = {},
): ObjectMapper = this.registerModule(kotlinModule(initializer))
// endregion

Expand All @@ -67,7 +67,7 @@ internal inline fun <reified T> Any?.checkTypeMismatch(): T {
// JsonMappingException was not used to unify the behavior.
throw RuntimeJsonMappingException(
"Deserialized value did not match the specified type; " +
"specified ${T::class.qualifiedName}$nullability but was ${this?.let { it::class.qualifiedName }}"
"specified ${T::class.qualifiedName}$nullability but was ${this?.let { it::class.qualifiedName }}",
)
}
return this
Expand Down Expand Up @@ -157,7 +157,7 @@ public inline fun <reified T> ObjectMapper.readValue(src: ByteArray): T = readVa
* due to an incorrect customization to [ObjectMapper].
*/
public inline fun <reified T> ObjectMapper.treeToValue(
n: TreeNode
n: TreeNode,
): T = readValue(this.treeAsTokens(n), jacksonTypeRef<T>()).checkTypeMismatch()

/**
Expand Down Expand Up @@ -192,13 +192,13 @@ public inline fun <reified T> ObjectReader.readValuesTyped(jp: JsonParser): Iter
}
}
public inline fun <reified T> ObjectReader.treeToValue(
n: TreeNode
n: TreeNode,
): T? = readValue(this.treeAsTokens(n), jacksonTypeRef<T>())

public inline fun <reified T, reified U> ObjectMapper.addMixIn(): ObjectMapper = addMixIn(T::class.java, U::class.java)
public inline fun <reified T, reified U> JsonMapper.Builder.addMixIn(): JsonMapper.Builder = addMixIn(
T::class.java,
U::class.java
U::class.java,
)

public operator fun ArrayNode.plus(element: Boolean) {
Expand Down Expand Up @@ -298,15 +298,15 @@ public operator fun JsonNode.contains(index: Int): Boolean = has(index)

public fun <T : Any> SimpleModule.addSerializer(
kClass: KClass<T>,
serializer: JsonSerializer<T>
serializer: JsonSerializer<T>,
): SimpleModule = this.apply {
kClass.javaPrimitiveType?.let { addSerializer(it, serializer) }
addSerializer(kClass.javaObjectType, serializer)
}

public fun <T : Any> SimpleModule.addDeserializer(
kClass: KClass<T>,
deserializer: JsonDeserializer<T>
deserializer: JsonDeserializer<T>,
): SimpleModule = this.apply {
kClass.javaPrimitiveType?.let { addDeserializer(it, deserializer) }
addDeserializer(kClass.javaObjectType, deserializer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ private val primitiveClassToDesc = mapOf(
Long::class.java to 'J',
Short::class.java to 'S',
Boolean::class.java to 'Z',
Void.TYPE to 'V'
Void.TYPE to 'V',
)

// -> this.name.replace(".", "/")
Expand All @@ -56,12 +56,12 @@ internal fun Array<Class<*>>.toDescBuilder(): StringBuilder = this

internal fun Constructor<*>.toSignature(): JvmMethodSignature = JvmMethodSignature(
"<init>",
parameterTypes.toDescBuilder().append('V').toString()
parameterTypes.toDescBuilder().append('V').toString(),
)

internal fun Method.toSignature(): JvmMethodSignature = JvmMethodSignature(
this.name,
parameterTypes.toDescBuilder().appendDescriptor(this.returnType).toString()
parameterTypes.toDescBuilder().appendDescriptor(this.returnType).toString(),
)

internal val defaultConstructorMarker: Class<*> by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ internal object KotlinClassIntrospector : BasicClassIntrospector() {
override fun forSerialization(
config: SerializationConfig,
type: JavaType,
r: MixInResolver
r: MixInResolver,
): BasicBeanDescription {
// minor optimization: for some JDK types do minimal introspection
return _findStdTypeDesc(config, type)
Expand All @@ -61,7 +61,7 @@ internal object KotlinClassIntrospector : BasicClassIntrospector() {
override fun forDeserialization(
config: DeserializationConfig,
type: JavaType,
r: MixInResolver
r: MixInResolver,
): BasicBeanDescription {
// minor optimization: for some JDK types do minimal introspection
return _findStdTypeDesc(config, type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ public enum class KotlinFeature(internal val enabledByDefault: Boolean) {
* `@JsonFormat` annotations need to be declared either on getter using `@get:JsonFormat` or field using `@field:JsonFormat`.
* See [jackson-module-kotlin#651] for details.
*/
UseJavaDurationConversion(enabledByDefault = false);
UseJavaDurationConversion(enabledByDefault = false),
;

internal val bitSet: BitSet = (1 shl ordinal).toBitSet()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class KotlinModule private constructor(
public val strictNullChecks: Boolean = StrictNullChecks.enabledByDefault,
public val copySyntheticConstructorParameterAnnotations: Boolean =
CopySyntheticConstructorParameterAnnotations.enabledByDefault,
public val useJavaDurationConversion: Boolean = UseJavaDurationConversion.enabledByDefault
public val useJavaDurationConversion: Boolean = UseJavaDurationConversion.enabledByDefault,
) : SimpleModule(KotlinModule::class.java.name, kogeraVersion) { // kogeraVersion is generated by building.
private constructor(builder: Builder) : this(
builder.cacheSize,
Expand All @@ -59,12 +59,12 @@ public class KotlinModule private constructor(
builder.isEnabled(SingletonSupport),
builder.isEnabled(StrictNullChecks),
builder.isEnabled(CopySyntheticConstructorParameterAnnotations),
builder.isEnabled(UseJavaDurationConversion)
builder.isEnabled(UseJavaDurationConversion),
)

@Deprecated(
message = "This is an API for compatibility; use Builder.",
level = DeprecationLevel.HIDDEN
level = DeprecationLevel.HIDDEN,
)
public constructor() : this(Builder())

Expand Down Expand Up @@ -101,7 +101,7 @@ public class KotlinModule private constructor(

if (!context.isEnabled(MapperFeature.USE_ANNOTATIONS)) {
throw IllegalStateException(
"The Jackson Kotlin module requires USE_ANNOTATIONS to be true or it cannot function"
"The Jackson Kotlin module requires USE_ANNOTATIONS to be true or it cannot function",
)
}

Expand All @@ -123,7 +123,7 @@ public class KotlinModule private constructor(
*/
public data class CacheSize(
val initialCacheSize: Int = Builder.DEFAULT_CACHE_SIZE,
val maxCacheSize: Int = Builder.DEFAULT_CACHE_SIZE
val maxCacheSize: Int = Builder.DEFAULT_CACHE_SIZE,
) : Serializable {
/**
* Set the same size for [initialCacheSize] and [maxCacheSize].
Expand All @@ -133,12 +133,12 @@ public class KotlinModule private constructor(
init {
if (maxCacheSize < 16) {
throw IllegalArgumentException(
"The maxCacheSize must be at least 16. The recommended value is 100 or more."
"The maxCacheSize must be at least 16. The recommended value is 100 or more.",
)
}
if (maxCacheSize < initialCacheSize) {
throw IllegalArgumentException(
"maxCacheSize($maxCacheSize) was less than initialCacheSize($initialCacheSize)."
"maxCacheSize($maxCacheSize) was less than initialCacheSize($initialCacheSize).",
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ internal class ReflectionCache(initialCacheSize: Int, maxCacheSize: Int) : Seria
final override fun toString(): String = key.toString()

class ValueClassBoxConverter(
override val key: Class<*>
override val key: Class<*>,
) : OtherCacheKey<Class<*>, io.github.projectmapk.jackson.module.kogera.ValueClassBoxConverter<*, *>>()
class ValueClassUnboxConverter(
override val key: Class<*>
override val key: Class<*>,
) : OtherCacheKey<Class<*>, io.github.projectmapk.jackson.module.kogera.ValueClassUnboxConverter<*>>()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ import kotlin.metadata.isNullable
internal class KotlinFallbackAnnotationIntrospector(
private val strictNullChecks: Boolean,
private val useJavaDurationConversion: Boolean,
private val cache: ReflectionCache
private val cache: ReflectionCache,
) : NopAnnotationIntrospector() {
private fun findKotlinParameter(
param: AnnotatedParameter
param: AnnotatedParameter,
): JmValueParameter? = when (val owner = param.owner.member) {
is Constructor<*> -> cache.getJmClass(param.declaringClass)?.findJmConstructor(owner)?.valueParameters
is Method -> if (Modifier.isStatic(owner.modifiers)) {
Expand Down Expand Up @@ -69,7 +69,7 @@ internal class KotlinFallbackAnnotationIntrospector(
override fun refineDeserializationType(
config: MapperConfig<*>,
a: Annotated,
baseType: JavaType
baseType: JavaType,
): JavaType = findKotlinParameter(a)?.let { param ->
val rawType = a.rawType
param.reconstructedClassOrNull
Expand Down Expand Up @@ -138,7 +138,7 @@ internal class KotlinFallbackAnnotationIntrospector(
config: MapperConfig<*>,
valueClass: AnnotatedClass,
declaredConstructors: List<PotentialCreator>,
declaredFactories: List<PotentialCreator>
declaredFactories: List<PotentialCreator>,
): PotentialCreator? {
val jmClass = valueClass.creatableKotlinClass() ?: return null
val primarilyConstructor = jmClass.primarilyConstructor()
Expand Down Expand Up @@ -168,18 +168,18 @@ private fun JmValueParameter.isNullishTypeAt(index: Int): Boolean = arguments.ge
} != false // If a type argument cannot be taken, treat it as nullable to avoid unexpected failure.

private fun JmValueParameter.requireStrictNullCheck(
type: JavaType
type: JavaType,
): Boolean = ((type.isArrayType || type.isCollectionLikeType) && !this.isNullishTypeAt(0)) ||
(type.isMapLikeType && !this.isNullishTypeAt(1))

private fun JmClass.primarilyConstructor() = constructors.find { !it.isSecondary } ?: constructors.singleOrNull()

private fun isPossiblySingleString(
jmConstructor: JmConstructor,
jmClass: JmClass
jmClass: JmClass,
) = jmConstructor.valueParameters.singleOrNull()?.let { it.isString && it.name !in jmClass.propertyNameSet } == true

private fun isPossibleSingleString(
isPossiblySingleString: Boolean,
javaConstructor: Constructor<*>
javaConstructor: Constructor<*>,
): Boolean = isPossiblySingleString && javaConstructor.parameters[0].annotations.none { it is JsonProperty }
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import kotlin.metadata.isNullable
internal class KotlinPrimaryAnnotationIntrospector(
private val nullToEmptyCollection: Boolean,
private val nullToEmptyMap: Boolean,
private val cache: ReflectionCache
private val cache: ReflectionCache,
) : NopAnnotationIntrospector() {
// If a new isRequired is explicitly specified or the old required is true, those values take precedence.
// In other cases, override is done by KotlinModule.
Expand Down Expand Up @@ -74,7 +74,7 @@ internal class KotlinPrimaryAnnotationIntrospector(
private fun JmProperty.isRequiredByNullability(): Boolean = !this.returnType.isNullable

private fun AnnotatedMethod.getRequiredMarkerFromCorrespondingAccessor(
jmClass: JmClass
jmClass: JmClass,
): Boolean? = when (parameterCount) {
0 -> jmClass.findPropertyByGetter(member)?.isRequiredByNullability()
1 -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import io.github.projectmapk.jackson.module.kogera.jmClass.JmClass
import io.github.projectmapk.jackson.module.kogera.toSignature
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import kotlin.metadata.isSecondary
import kotlin.metadata.jvm.signature

internal object SequenceDeserializer : StdDeserializer<Sequence<*>>(Sequence::class.java) {
private fun readResolve(): Any = SequenceDeserializer
Expand All @@ -46,7 +44,7 @@ internal object RegexDeserializer : StdDeserializer<Regex>(Regex::class.java) {
val optionsNode = node.get("options")
if (!optionsNode.isArray) {
throw IllegalStateException(
"Expected an array of strings for RegexOptions, but type was ${node.nodeType}"
"Expected an array of strings for RegexOptions, but type was ${node.nodeType}",
)
}
optionsNode.elements().asSequence().map { RegexOption.valueOf(it.asText()) }.toSet()
Expand All @@ -56,7 +54,7 @@ internal object RegexDeserializer : StdDeserializer<Regex>(Regex::class.java) {
return Regex(pattern, options)
} else {
throw IllegalStateException(
"Expected a string or an object to deserialize a Regex, but type was ${node.nodeType}"
"Expected a string or an object to deserialize a Regex, but type was ${node.nodeType}",
)
}
}
Expand Down Expand Up @@ -92,7 +90,7 @@ internal object ULongDeserializer : StdDeserializer<ULong>(ULong::class.java) {

internal class WrapsNullableValueClassBoxDeserializer<S, D : Any>(
private val creator: Method,
private val converter: ValueClassBoxConverter<S, D>
private val converter: ValueClassBoxConverter<S, D>,
) : WrapsNullableValueClassDeserializer<D>(converter.boxedClass) {
private val inputType: Class<*> = creator.parameterTypes[0]

Expand Down Expand Up @@ -150,12 +148,12 @@ private fun findValueCreator(type: JavaType, clazz: Class<*>, jmClass: JmClass):

internal class KotlinDeserializers(
private val cache: ReflectionCache,
private val useJavaDurationConversion: Boolean
private val useJavaDurationConversion: Boolean,
) : SimpleDeserializers() {
override fun findBeanDeserializer(
type: JavaType,
config: DeserializationConfig?,
beanDesc: BeanDescription
beanDesc: BeanDescription,
): JsonDeserializer<*>? {
val rawClass = type.rawClass

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ internal object ULongKeyDeserializer : StdKeyDeserializer(-1, ULong::class.java)
// The implementation is designed to be compatible with various creators, just in case.
internal class ValueClassKeyDeserializer<S, D : Any>(
private val creator: Method,
private val converter: ValueClassBoxConverter<S, D>
private val converter: ValueClassBoxConverter<S, D>,
) : KeyDeserializer() {
private val unboxedClass: Class<*> = creator.parameterTypes[0]

Expand Down Expand Up @@ -82,7 +82,7 @@ internal class ValueClassKeyDeserializer<S, D : Any>(
companion object {
fun createOrNull(
valueClass: Class<*>,
cache: ReflectionCache
cache: ReflectionCache,
): ValueClassKeyDeserializer<*, *>? {
val jmClass = cache.getJmClass(valueClass) ?: return null
val primaryKmConstructorSignature =
Expand All @@ -107,7 +107,7 @@ internal class KotlinKeyDeserializers(private val cache: ReflectionCache) : Simp
override fun findKeyDeserializer(
type: JavaType,
config: DeserializationConfig?,
beanDesc: BeanDescription?
beanDesc: BeanDescription?,
): KeyDeserializer? {
val rawClass = type.rawClass

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal sealed class UnsignedIntegerChecker<T : Comparable<T>, U : Comparable<U
p,
"Numeric value ($value) out of range of ${clazz.simpleName} ($min - $max).",
JsonToken.VALUE_NUMBER_INT,
clazz
clazz,
)
}

Expand Down
Loading