Skip to content

Commit

Permalink
Merge pull request #239 from ProjectMapK/develop
Browse files Browse the repository at this point in the history
Release 2024-11-10 13:53:05 +0000
  • Loading branch information
k163377 authored Nov 10, 2024
2 parents d91cee1 + 623edaa commit 2015dfa
Show file tree
Hide file tree
Showing 27 changed files with 216 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/lint-and-test-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v2
uses: gradle/actions/wrapper-validation@v3
- name: Set up java
uses: actions/setup-java@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
name: git-pr-release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: git-pr-release
Expand Down
24 changes: 14 additions & 10 deletions .github/workflows/test-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,27 @@ jobs:
fail-fast: false
matrix:
# LTS versions, latest version (if exists)
java-version: [ '8', '11', '17', '21', '22' ]
java-version: [ '8', '11', '17', '21', '23' ]
# Minimum version, latest release version, latest pre-release version (if exists)
kotlin:
- name: '1.8.22'
version: '1.8.22'
k2: false
- name: '1.9.23'
version: '1.9.23'
- name: '1.9.25'
version: '1.9.25'
k2: false
- name: '1.9.23 K2'
version: '1.9.23'
- name: '1.9.25 K2'
version: '1.9.25'
k2: true
- name: '2.0.0-Beta5'
version: '2.0.0-Beta5'
- name: '2.0.21'
version: '2.0.21'
k2: false
- name: '2.0.0-Beta5 K2'
version: '2.0.0-Beta5'
- name: '2.0.21 K2'
version: '2.0.21'
k2: true
- name: '2.1.0-RC'
k2: false
- name: '2.1.0-RC K2'
k2: true
env:
KOTLIN_VERSION: ${{ matrix.kotlin.version }}
Expand All @@ -63,7 +67,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v2
uses: gradle/actions/wrapper-validation@v3
- name: 'Set up java ${{ matrix.java-version }}'
uses: actions/setup-java@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ This project makes several disruptive changes to achieve more `Kotlin-like` beha
Details are summarized in [KogeraSpecificImplementations](./docs/KogeraSpecificImplementations.md).

# Compatibility
- `jackson 2.16.x`
- `jackson 2.17.x`
- `Java 8+`
- `Kotlin 1.8.22+`

Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ val jacksonVersion = libs.versions.jackson.get()
val generatedSrcPath = "${layout.buildDirectory.get()}/generated/kotlin"

group = groupStr
version = "${jacksonVersion}-beta13"
version = "${jacksonVersion}-beta14"

repositories {
mavenCentral()
Expand Down
6 changes: 3 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[versions]
kotlin = "1.8.22" # Mainly for CI, it can be rewritten by environment variable.
jackson = "2.17.1"
jackson = "2.17.3"

# test libs
junit = "5.10.2"
junit = "5.11.3"

[libraries]
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib" }
Expand All @@ -16,7 +16,7 @@ kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect" }
junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
junit-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
mockk = "io.mockk:mockk:1.13.10"
mockk = "io.mockk:mockk:1.13.13"
jackson-xml = { module = "com.fasterxml.jackson.dataformat:jackson-dataformat-xml", version.ref = "jackson" }
jackson-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", version.ref = "jackson" }

Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
21 changes: 12 additions & 9 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#

##############################################################################
#
Expand Down Expand Up @@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
Expand Down Expand Up @@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down Expand Up @@ -145,15 +148,15 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
Expand Down Expand Up @@ -202,11 +205,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
Expand Down
22 changes: 12 additions & 10 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem

@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
Expand Down Expand Up @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

Expand All @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import io.github.projectmapk.jackson.module.kogera.annotation.JsonKUnbox
import kotlinx.metadata.KmClass
import kotlinx.metadata.KmClassifier
import kotlinx.metadata.KmType
import kotlinx.metadata.isNullable
import kotlinx.metadata.jvm.JvmMethodSignature
import kotlinx.metadata.jvm.KotlinClassMetadata
import java.lang.reflect.AnnotatedElement
Expand All @@ -22,9 +21,6 @@ internal fun Class<*>.toKmClass(): KmClass? = getAnnotation(METADATA_CLASS)?.let

internal fun Class<*>.isUnboxableValueClass() = this.isAnnotationPresent(JVM_INLINE_CLASS)

// JmClass must be value class.
internal fun JmClass.wrapsNullValueClass() = inlineClassUnderlyingType!!.isNullable

private val primitiveClassToDesc = mapOf(
Byte::class.java to 'B',
Char::class.java to 'C',
Expand Down Expand Up @@ -87,8 +83,9 @@ internal fun String.reconstructClass(): Class<*> {
return Class.forName(String(replaced))
}

internal fun KmType.reconstructClassOrNull(): Class<*>? = (classifier as? KmClassifier.Class)
?.let { kotlin.runCatching { it.name.reconstructClass() }.getOrNull() }
internal fun KmType.reconstructClassOrNull(): Class<*>? = (classifier as? KmClassifier.Class)?.reconstructClassOrNull()
internal fun KmClassifier.Class.reconstructClassOrNull(): Class<*>? =
runCatching { name.reconstructClass() }.getOrNull()

internal fun AnnotatedElement.hasCreatorAnnotation(): Boolean = getAnnotation(JSON_CREATOR_CLASS)
?.let { it.mode != JsonCreator.Mode.DISABLED }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.projectmapk.jackson.module.kogera

import com.fasterxml.jackson.databind.util.LRUMap
import io.github.projectmapk.jackson.module.kogera.jmClass.JmClass
import java.io.Serializable
import java.lang.reflect.Method
import java.util.Optional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@ import io.github.projectmapk.jackson.module.kogera.JSON_K_UNBOX_CLASS
import io.github.projectmapk.jackson.module.kogera.KOTLIN_DURATION_CLASS
import io.github.projectmapk.jackson.module.kogera.ReflectionCache
import io.github.projectmapk.jackson.module.kogera.isUnboxableValueClass
import io.github.projectmapk.jackson.module.kogera.reconstructClassOrNull
import io.github.projectmapk.jackson.module.kogera.jmClass.JmValueParameter
import io.github.projectmapk.jackson.module.kogera.ser.KotlinDurationValueToJavaDurationConverter
import io.github.projectmapk.jackson.module.kogera.ser.KotlinToJavaDurationConverter
import io.github.projectmapk.jackson.module.kogera.ser.SequenceToIteratorConverter
import io.github.projectmapk.jackson.module.kogera.wrapsNullValueClass
import kotlinx.metadata.KmTypeProjection
import kotlinx.metadata.KmValueParameter
import kotlinx.metadata.isNullable
import java.lang.reflect.Constructor
import java.lang.reflect.Method
Expand All @@ -36,9 +34,9 @@ internal class KotlinFallbackAnnotationIntrospector(
private val useJavaDurationConversion: Boolean,
private val cache: ReflectionCache
) : NopAnnotationIntrospector() {
private fun findKotlinParameter(param: AnnotatedParameter): KmValueParameter? =
private fun findKotlinParameter(param: AnnotatedParameter): JmValueParameter? =
when (val owner = param.owner.member) {
is Constructor<*> -> cache.getJmClass(param.declaringClass)?.findKmConstructor(owner)?.valueParameters
is Constructor<*> -> cache.getJmClass(param.declaringClass)?.findJmConstructor(owner)?.valueParameters
is Method -> if (Modifier.isStatic(owner.modifiers)) {
cache.getJmClass(param.declaringClass)
?.companion
Expand All @@ -49,7 +47,7 @@ internal class KotlinFallbackAnnotationIntrospector(
else -> null
}?.let { it[param.index] }

private fun findKotlinParameter(param: Annotated): KmValueParameter? =
private fun findKotlinParameter(param: Annotated): JmValueParameter? =
(param as? AnnotatedParameter)?.let { findKotlinParameter(it) }

// since 2.4
Expand All @@ -66,7 +64,7 @@ internal class KotlinFallbackAnnotationIntrospector(
override fun refineDeserializationType(config: MapperConfig<*>, a: Annotated, baseType: JavaType): JavaType =
findKotlinParameter(a)?.let { param ->
val rawType = a.rawType
param.type.reconstructClassOrNull()
param.reconstructedClassOrNull
?.takeIf { it.isUnboxableValueClass() && it != rawType }
?.let { config.constructType(it) }
} ?: baseType
Expand Down Expand Up @@ -101,7 +99,7 @@ internal class KotlinFallbackAnnotationIntrospector(

// Determine if the unbox result of value class is nullable
// @see findNullSerializer
private fun Class<*>.requireRebox(): Boolean = cache.getJmClass(this)!!.wrapsNullValueClass()
private fun Class<*>.requireRebox(): Boolean = cache.getJmClass(this)!!.wrapsNullableIfValue

// Perform proper serialization even if the value wrapped by the value class is null.
// If value is a non-null object type, it must not be reboxing.
Expand All @@ -124,11 +122,11 @@ internal class KotlinFallbackAnnotationIntrospector(
?: super.findSetterInfo(ann)
}

private fun KmValueParameter.isNullishTypeAt(index: Int): Boolean = type.arguments.getOrNull(index)?.let {
private fun JmValueParameter.isNullishTypeAt(index: Int): Boolean = arguments.getOrNull(index)?.let {
// If it is not a StarProjection, type is not null
it === KmTypeProjection.STAR || it.type!!.isNullable
} ?: true // If a type argument cannot be taken, treat it as nullable to avoid unexpected failure.

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

0 comments on commit 2015dfa

Please sign in to comment.