diff --git a/build.gradle.kts b/build.gradle.kts index b882a9ca4..950359430 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,10 +9,12 @@ import java.net.URI buildscript { dependencies { - val kotlinVersion = System.getenv("MOSHI_KOTLIN_VERSION") - ?: libs.versions.kotlin.get() - val kspVersion = System.getenv("MOSHI_KSP_VERSION") - ?: libs.versions.ksp.get() + val kotlinVersion = + System.getenv("MOSHI_KOTLIN_VERSION") + ?: libs.versions.kotlin.get() + val kspVersion = + System.getenv("MOSHI_KSP_VERSION") + ?: libs.versions.ksp.get() classpath(kotlin("gradle-plugin", version = kotlinVersion)) classpath("com.google.devtools.ksp:symbol-processing-gradle-plugin:$kspVersion") // https://github.com/melix/japicmp-gradle-plugin/issues/36 @@ -44,7 +46,7 @@ spotless { endWithNewline() } val configureCommonJavaFormat: JavaExtension.() -> Unit = { - googleJavaFormat(libs.versions.gjf.get()) + googleJavaFormat(libs.googleJavaFormat.get().version) } java { configureCommonJavaFormat() @@ -52,7 +54,7 @@ spotless { targetExclude("**/build/**") } kotlin { - ktlint(libs.versions.ktlint.get()).editorConfigOverride( + ktlint(libs.ktlint.get().version).editorConfigOverride( mapOf("ktlint_standard_filename" to "disabled"), ) target("**/*.kt") @@ -61,7 +63,7 @@ spotless { targetExclude("**/Dependencies.kt", "**/build/**") } kotlinGradle { - ktlint(libs.versions.ktlint.get()) + ktlint(libs.ktlint.get().version) target("**/*.gradle.kts") trimTrailingWhitespace() endWithNewline() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index beb3bbc59..75b8777df 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,12 +1,10 @@ [versions] autoService = "1.1.1" -gjf = "1.15.0" jvmTarget = "1.8" kotlin = "1.9.21" kotlinCompileTesting = "0.4.0" kotlinpoet = "1.14.2" ksp = "1.9.22-1.0.17" -ktlint = "0.48.2" [plugins] dokka = { id = "org.jetbrains.dokka", version = "1.9.10" } @@ -33,10 +31,10 @@ kotlinxMetadata = "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.7.0" ksp = { module = "com.google.devtools.ksp:symbol-processing", version.ref = "ksp" } ksp-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } okio = "com.squareup.okio:okio:3.7.0" - -# Test libs assertj = "org.assertj:assertj-core:3.25.2" junit = "junit:junit:4.13.2" kotlinCompileTesting = { module = "dev.zacsweers.kctfork:core", version.ref = "kotlinCompileTesting" } kotlinCompileTesting-ksp = { module = "dev.zacsweers.kctfork:ksp", version.ref ="kotlinCompileTesting" } truth = "com.google.truth:truth:1.3.0" +googleJavaFormat = "com.google.googlejavaformat:google-java-format:1.19.2" +ktlint = "com.pinterest.ktlint:ktlint-cli:1.1.1" diff --git a/moshi-adapters/japicmp/build.gradle.kts b/moshi-adapters/japicmp/build.gradle.kts index 1f20896e4..50b34e110 100644 --- a/moshi-adapters/japicmp/build.gradle.kts +++ b/moshi-adapters/japicmp/build.gradle.kts @@ -18,16 +18,17 @@ dependencies { latest(project(":moshi-adapters")) } -val japicmp = tasks.register("japicmp") { - dependsOn("jar") - oldClasspath.from(baseline) - newClasspath.from(latest) - onlyBinaryIncompatibleModified.set(true) - failOnModification.set(true) - txtOutputFile.set(layout.buildDirectory.file("reports/japi.txt")) - ignoreMissingClasses.set(true) - includeSynthetic.set(true) -} +val japicmp = + tasks.register("japicmp") { + dependsOn("jar") + oldClasspath.from(baseline) + newClasspath.from(latest) + onlyBinaryIncompatibleModified.set(true) + failOnModification.set(true) + txtOutputFile.set(layout.buildDirectory.file("reports/japi.txt")) + ignoreMissingClasses.set(true) + includeSynthetic.set(true) + } tasks.named("check").configure { dependsOn(japicmp) diff --git a/moshi-adapters/src/main/java/com/squareup/moshi/adapters/Iso8601Utils.kt b/moshi-adapters/src/main/java/com/squareup/moshi/adapters/Iso8601Utils.kt index 12d2e2add..bd95440d0 100644 --- a/moshi-adapters/src/main/java/com/squareup/moshi/adapters/Iso8601Utils.kt +++ b/moshi-adapters/src/main/java/com/squareup/moshi/adapters/Iso8601Utils.kt @@ -81,19 +81,40 @@ internal fun String.parseIsoDate(): Date { var offset = 0 // extract year - val year = parseInt(this, offset, 4.let { offset += it; offset }) + val year = parseInt( + this, + offset, + 4.let { + offset += it + offset + }, + ) if (checkOffset(this, offset, '-')) { offset += 1 } // extract month - val month = parseInt(this, offset, 2.let { offset += it; offset }) + val month = parseInt( + this, + offset, + 2.let { + offset += it + offset + }, + ) if (checkOffset(this, offset, '-')) { offset += 1 } // extract day - val day = parseInt(this, offset, 2.let { offset += it; offset }) + val day = parseInt( + this, + offset, + 2.let { + offset += it + offset + }, + ) // default time value var hour = 0 var minutes = 0 @@ -108,11 +129,28 @@ internal fun String.parseIsoDate(): Date { } if (hasT) { // extract hours, minutes, seconds and milliseconds - hour = parseInt(this, 1.let { offset += it; offset }, 2.let { offset += it; offset }) + hour = parseInt( + this, + 1.let { + offset += it + offset + }, + 2.let { + offset += it + offset + }, + ) if (checkOffset(this, offset, ':')) { offset += 1 } - minutes = parseInt(this, offset, 2.let { offset += it; offset }) + minutes = parseInt( + this, + offset, + 2.let { + offset += it + offset + }, + ) if (checkOffset(this, offset, ':')) { offset += 1 } @@ -120,7 +158,14 @@ internal fun String.parseIsoDate(): Date { if (this.length > offset) { val c = this[offset] if (c != 'Z' && c != '+' && c != '-') { - seconds = parseInt(this, offset, 2.let { offset += it; offset }) + seconds = parseInt( + this, + offset, + 2.let { + offset += it + offset + }, + ) if (seconds in 60..62) seconds = 59 // truncate up to 3 leap seconds // milliseconds can be optional in the format if (checkOffset(this, offset, '.')) { diff --git a/moshi-kotlin-codegen/build.gradle.kts b/moshi-kotlin-codegen/build.gradle.kts index e6f48fb54..4dd3ba8e9 100644 --- a/moshi-kotlin-codegen/build.gradle.kts +++ b/moshi-kotlin-codegen/build.gradle.kts @@ -83,19 +83,20 @@ dependencies { testImplementation(libs.kotlinCompileTesting) } -val shadowJar = tasks.shadowJar.apply { - configure { - archiveClassifier.set("") - configurations = listOf(shade) - relocate("com.squareup.kotlinpoet.metadata", "com.squareup.moshi.kotlinpoet.metadata") - relocate( - "com.squareup.kotlinpoet.classinspector", - "com.squareup.moshi.kotlinpoet.classinspector", - ) - relocate("kotlinx.metadata", "com.squareup.moshi.kotlinx.metadata") - transformers.add(ServiceFileTransformer()) +val shadowJar = + tasks.shadowJar.apply { + configure { + archiveClassifier.set("") + configurations = listOf(shade) + relocate("com.squareup.kotlinpoet.metadata", "com.squareup.moshi.kotlinpoet.metadata") + relocate( + "com.squareup.kotlinpoet.classinspector", + "com.squareup.moshi.kotlinpoet.classinspector", + ) + relocate("kotlinx.metadata", "com.squareup.moshi.kotlinx.metadata") + transformers.add(ServiceFileTransformer()) + } } -} artifacts { runtimeOnly(shadowJar) diff --git a/moshi-kotlin-tests/build.gradle.kts b/moshi-kotlin-tests/build.gradle.kts index c54d37250..be353312e 100644 --- a/moshi-kotlin-tests/build.gradle.kts +++ b/moshi-kotlin-tests/build.gradle.kts @@ -10,12 +10,15 @@ plugins { } enum class TestMode { - REFLECT, KAPT, KSP + REFLECT, + KAPT, + KSP, } -val testMode = findProperty("kotlinTestMode")?.toString() - ?.let(TestMode::valueOf) - ?: REFLECT +val testMode = + findProperty("kotlinTestMode")?.toString() + ?.let(TestMode::valueOf) + ?: REFLECT when (testMode) { REFLECT -> { diff --git a/moshi-kotlin-tests/codegen-only/build.gradle.kts b/moshi-kotlin-tests/codegen-only/build.gradle.kts index 24618e64d..306671752 100644 --- a/moshi-kotlin-tests/codegen-only/build.gradle.kts +++ b/moshi-kotlin-tests/codegen-only/build.gradle.kts @@ -10,12 +10,15 @@ plugins { } enum class TestMode { - REFLECT, KAPT, KSP + REFLECT, + KAPT, + KSP, } -val testMode = findProperty("kotlinTestMode")?.toString() - ?.let(TestMode::valueOf) - ?: KSP +val testMode = + findProperty("kotlinTestMode")?.toString() + ?.let(TestMode::valueOf) + ?: KSP when (testMode) { REFLECT -> { diff --git a/moshi-kotlin-tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt b/moshi-kotlin-tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt index 559d727ee..e334f6846 100644 --- a/moshi-kotlin-tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt +++ b/moshi-kotlin-tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest.kt @@ -1189,6 +1189,7 @@ class GeneratedAdaptersTest { } @JsonClass(generateAdapter = true) + @Suppress("ktlint:standard:property-naming") class MutableUppercasePropertyName { var AAA: Int = -1 var BBB: Int = -1 diff --git a/moshi-kotlin-tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter.kt b/moshi-kotlin-tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter.kt index db16492ad..694d55ebc 100644 --- a/moshi-kotlin-tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter.kt +++ b/moshi-kotlin-tests/codegen-only/src/test/kotlin/com/squareup/moshi/kotlin/codegen/GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter.kt @@ -21,6 +21,7 @@ import com.squareup.moshi.JsonWriter import com.squareup.moshi.kotlin.codegen.GeneratedAdaptersTest.CustomGeneratedClass // This also tests custom generated types with no moshi constructor +@Suppress("ktlint:standard:class-naming") class GeneratedAdaptersTest_CustomGeneratedClassJsonAdapter : JsonAdapter() { override fun fromJson(reader: JsonReader): CustomGeneratedClass? { TODO() diff --git a/moshi-kotlin-tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt b/moshi-kotlin-tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt index ce08d338e..b6a742307 100644 --- a/moshi-kotlin-tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt +++ b/moshi-kotlin-tests/src/test/kotlin/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterTest.kt @@ -569,7 +569,8 @@ class KotlinJsonAdapterTest { data class UsingEnum(val e: KotlinEnum) enum class KotlinEnum { - A, B + A, + B, } @Test fun interfacesNotSupported() { diff --git a/moshi-kotlin/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterFactory.kt b/moshi-kotlin/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterFactory.kt index 02555d753..993751c50 100644 --- a/moshi-kotlin/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterFactory.kt +++ b/moshi-kotlin/src/main/java/com/squareup/moshi/kotlin/reflect/KotlinJsonAdapterFactory.kt @@ -190,8 +190,7 @@ internal class KotlinJsonAdapter( } public class KotlinJsonAdapterFactory : JsonAdapter.Factory { - override fun create(type: Type, annotations: Set, moshi: Moshi): - JsonAdapter<*>? { + override fun create(type: Type, annotations: Set, moshi: Moshi): JsonAdapter<*>? { if (annotations.isNotEmpty()) return null val rawType = type.rawType diff --git a/moshi/build.gradle.kts b/moshi/build.gradle.kts index 8c5122a12..0fcfa0dee 100644 --- a/moshi/build.gradle.kts +++ b/moshi/build.gradle.kts @@ -21,9 +21,10 @@ val java16: SourceSet by sourceSets.creating { // We use JDK 17 for latest but target 16 for maximum compatibility val service = project.extensions.getByType() -val customLauncher = service.launcherFor { - languageVersion.set(JavaLanguageVersion.of(17)) -} +val customLauncher = + service.launcherFor { + languageVersion.set(JavaLanguageVersion.of(17)) + } tasks.named("compileJava16Java") { options.release.set(16) diff --git a/moshi/japicmp/build.gradle.kts b/moshi/japicmp/build.gradle.kts index 813f09df9..f34fce6d4 100644 --- a/moshi/japicmp/build.gradle.kts +++ b/moshi/japicmp/build.gradle.kts @@ -18,42 +18,49 @@ dependencies { latest(project(":moshi")) } -val japicmp = tasks.register("japicmp") { - dependsOn("jar") - oldClasspath.from(baseline) - newClasspath.from(latest) - onlyBinaryIncompatibleModified.set(true) - failOnModification.set(true) - txtOutputFile.set(layout.buildDirectory.file("reports/japi.txt")) - ignoreMissingClasses.set(true) - includeSynthetic.set(true) - classExcludes.addAll( - "com.squareup.moshi.AdapterMethodsFactory", // Internal. - "com.squareup.moshi.ClassJsonAdapter", // Internal. - "com.squareup.moshi.RecordJsonAdapter\$ComponentBinding", // Package-private - "com.squareup.moshi.StandardJsonAdapters", // Package-private - "com.squareup.moshi.internal.NonNullJsonAdapter", // Internal. - "com.squareup.moshi.internal.NullSafeJsonAdapter", // Internal. - "com.squareup.moshi.internal.Util\$GenericArrayTypeImpl", // Internal. - "com.squareup.moshi.internal.Util\$ParameterizedTypeImpl", // Internal. - "com.squareup.moshi.internal.Util\$WildcardTypeImpl", // Internal. - ) - methodExcludes.addAll( - "com.squareup.moshi.JsonAdapter#indent(java.lang.String)", // Was unintentionally open before - "com.squareup.moshi.internal.Util#hasNullable(java.lang.annotation.Annotation[])", - "com.squareup.moshi.internal.Util#jsonAnnotations(java.lang.annotation.Annotation[])", - "com.squareup.moshi.internal.Util#jsonAnnotations(java.lang.reflect.AnnotatedElement)", - "com.squareup.moshi.internal.Util#jsonName(java.lang.String, com.squareup.moshi.Json)", - "com.squareup.moshi.internal.Util#jsonName(java.lang.String, java.lang.reflect.AnnotatedElement)", - "com.squareup.moshi.internal.Util#resolve(java.lang.reflect.Type, java.lang.Class, java.lang.reflect.Type)", - "com.squareup.moshi.internal.Util#typeAnnotatedWithAnnotations(java.lang.reflect.Type, java.util.Set)", - ) - fieldExcludes.addAll( - "com.squareup.moshi.CollectionJsonAdapter#FACTORY", // False-positive, class is not public anyway - "com.squareup.moshi.MapJsonAdapter#FACTORY", // Class is not public - "com.squareup.moshi.ArrayJsonAdapter#FACTORY", // Class is not public - ) -} +val japicmp = + tasks.register("japicmp") { + dependsOn("jar") + oldClasspath.from(baseline) + newClasspath.from(latest) + onlyBinaryIncompatibleModified.set(true) + failOnModification.set(true) + txtOutputFile.set(layout.buildDirectory.file("reports/japi.txt")) + ignoreMissingClasses.set(true) + includeSynthetic.set(true) + classExcludes.addAll( + // Internal. + "com.squareup.moshi.AdapterMethodsFactory", + "com.squareup.moshi.ClassJsonAdapter", + "com.squareup.moshi.internal.NonNullJsonAdapter", + "com.squareup.moshi.internal.NullSafeJsonAdapter", + "com.squareup.moshi.internal.Util\$GenericArrayTypeImpl", + "com.squareup.moshi.internal.Util\$ParameterizedTypeImpl", + "com.squareup.moshi.internal.Util\$WildcardTypeImpl", + // Package-private + "com.squareup.moshi.RecordJsonAdapter\$ComponentBinding", + "com.squareup.moshi.StandardJsonAdapters", + ) + methodExcludes.addAll( + // Was unintentionally open before + "com.squareup.moshi.JsonAdapter#indent(java.lang.String)", + "com.squareup.moshi.internal.Util#hasNullable(java.lang.annotation.Annotation[])", + "com.squareup.moshi.internal.Util#jsonAnnotations(java.lang.annotation.Annotation[])", + "com.squareup.moshi.internal.Util#jsonAnnotations(java.lang.reflect.AnnotatedElement)", + "com.squareup.moshi.internal.Util#jsonName(java.lang.String, com.squareup.moshi.Json)", + "com.squareup.moshi.internal.Util#jsonName(java.lang.String, java.lang.reflect.AnnotatedElement)", + "com.squareup.moshi.internal.Util#resolve(java.lang.reflect.Type, java.lang.Class, java.lang.reflect.Type)", + "com.squareup.moshi.internal.Util#typeAnnotatedWithAnnotations(java.lang.reflect.Type, java.util.Set)", + ) + fieldExcludes.addAll( + // False-positive, class is not public anyway + "com.squareup.moshi.CollectionJsonAdapter#FACTORY", + // Class is not public + "com.squareup.moshi.MapJsonAdapter#FACTORY", + // Class is not public + "com.squareup.moshi.ArrayJsonAdapter#FACTORY", + ) + } tasks.named("check").configure { dependsOn(japicmp) diff --git a/moshi/src/main/java/com/squareup/moshi/JsonUtf8Reader.kt b/moshi/src/main/java/com/squareup/moshi/JsonUtf8Reader.kt index 75ec851d1..21a7981e3 100644 --- a/moshi/src/main/java/com/squareup/moshi/JsonUtf8Reader.kt +++ b/moshi/src/main/java/com/squareup/moshi/JsonUtf8Reader.kt @@ -448,7 +448,8 @@ internal class JsonUtf8Reader : JsonReader { checkLenient() // fall-through false } - '{', '}', '[', ']', ':', ',', ' ', '\t', '\u000C'/*\f*/, '\r', '\n' -> false + // 0x000C = \f + '{', '}', '[', ']', ':', ',', ' ', '\t', '\u000C', '\r', '\n' -> false else -> true } } diff --git a/moshi/src/main/java/com/squareup/moshi/JsonWriter.kt b/moshi/src/main/java/com/squareup/moshi/JsonWriter.kt index 4d05b8276..e866ccc78 100644 --- a/moshi/src/main/java/com/squareup/moshi/JsonWriter.kt +++ b/moshi/src/main/java/com/squareup/moshi/JsonWriter.kt @@ -151,6 +151,7 @@ public sealed class JsonWriter : Closeable, Flushable { * pretty printing. */ @JvmField + @Suppress("ktlint:standard:property-naming") // Exposed to sealed subtypes. protected var _indent: String? = null public open var indent: String /**