Prepare project for Kotlin migration (#1257)

This commit is contained in:
Zac Sweers
2021-02-02 13:11:38 -05:00
committed by GitHub
parent 8518f47f52
commit 6e5bb3a29b
17 changed files with 162 additions and 45 deletions

View File

@@ -15,8 +15,9 @@
*/ */
plugins { plugins {
`java-library` kotlin("jvm")
id("com.vanniktech.maven.publish") id("com.vanniktech.maven.publish")
id("ru.vyarus.animalsniffer")
} }
dependencies { dependencies {

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2020 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import me.champeau.gradle.japicmp.JapicmpTask
plugins {
`java-library`
id("me.champeau.gradle.japicmp")
}
val baseline = configurations.create("baseline")
val latest = configurations.create("latest")
dependencies {
baseline("com.squareup.moshi:moshi-adapters:1.11.0") {
isTransitive = false
isForce = true
}
latest(project(":adapters"))
}
val japicmp = tasks.register<JapicmpTask>("japicmp") {
dependsOn("jar")
oldClasspath = baseline
newClasspath = latest
onlyBinaryIncompatibleModified = true
failOnModification = true
txtOutputFile = file("$buildDir/reports/japi.txt")
ignoreMissingClasses = true
includeSynthetic = true
}
tasks.named("check").configure {
dependsOn(japicmp)
}

View File

@@ -17,11 +17,15 @@
import com.diffplug.gradle.spotless.JavaExtension import com.diffplug.gradle.spotless.JavaExtension
import org.gradle.jvm.tasks.Jar import org.gradle.jvm.tasks.Jar
import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.net.URL import java.net.URL
buildscript { buildscript {
dependencies { dependencies {
classpath(kotlin("gradle-plugin", version = Dependencies.Kotlin.version)) classpath(kotlin("gradle-plugin", version = Dependencies.Kotlin.version))
// https://github.com/melix/japicmp-gradle-plugin/issues/36
classpath("com.google.guava:guava:28.2-jre")
} }
} }
@@ -29,6 +33,8 @@ plugins {
id("com.vanniktech.maven.publish") version "0.13.0" apply false id("com.vanniktech.maven.publish") version "0.13.0" apply false
id("org.jetbrains.dokka") version "1.4.10" apply false id("org.jetbrains.dokka") version "1.4.10" apply false
id("com.diffplug.spotless") version "5.6.0" id("com.diffplug.spotless") version "5.6.0"
id("ru.vyarus.animalsniffer") version "1.5.1" apply false
id("me.champeau.gradle.japicmp") version "0.2.8" apply false
} }
spotless { spotless {
@@ -128,6 +134,28 @@ subprojects {
} }
} }
pluginManager.withPlugin("ru.vyarus.animalsniffer") {
dependencies {
"compileOnly"(Dependencies.AnimalSniffer.annotations)
"signature"(Dependencies.AnimalSniffer.java7Signature)
}
}
pluginManager.withPlugin("org.jetbrains.kotlin.jvm") {
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
@Suppress("SuspiciousCollectionReassignment")
freeCompilerArgs += listOf("-progressive")
}
}
configure<KotlinProjectExtension> {
if (project.name != "examples") {
explicitApi()
}
}
}
// Configure publishing // Configure publishing
pluginManager.withPlugin("com.vanniktech.maven.publish") { pluginManager.withPlugin("com.vanniktech.maven.publish") {
// Configure automatic-module-name, but only for published modules // Configure automatic-module-name, but only for published modules

View File

@@ -21,6 +21,11 @@ object Dependencies {
const val ktlintVersion = "0.39.0" const val ktlintVersion = "0.39.0"
const val okio = "com.squareup.okio:okio:2.10.0" const val okio = "com.squareup.okio:okio:2.10.0"
object AnimalSniffer {
const val annotations = "org.codehaus.mojo:animal-sniffer-annotations:1.16"
const val java7Signature = "org.codehaus.mojo.signature:java17:1.0@signature"
}
object AutoService { object AutoService {
private const val version = "1.0-rc7" private const val version = "1.0-rc7"
const val annotations = "com.google.auto.service:auto-service-annotations:$version" const val annotations = "com.google.auto.service:auto-service-annotations:$version"
@@ -35,7 +40,6 @@ object Dependencies {
object Kotlin { object Kotlin {
const val version = "1.4.10" const val version = "1.4.10"
const val stdlib = "org.jetbrains.kotlin:kotlin-stdlib:$version"
const val metadata = "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0" const val metadata = "org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0"
} }

View File

@@ -14,19 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
kotlin("jvm") kotlin("jvm")
kotlin("kapt") kotlin("kapt")
} }
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
freeCompilerArgs = listOf("-progressive")
}
}
dependencies { dependencies {
kapt(project(":kotlin:codegen")) kapt(project(":kotlin:codegen"))
compileOnly(Dependencies.jsr305) compileOnly(Dependencies.jsr305)

View File

@@ -25,16 +25,11 @@ plugins {
id("com.github.johnrengelman.shadow") version "6.0.0" id("com.github.johnrengelman.shadow") version "6.0.0"
} }
configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<KotlinCompile>().configureEach { tasks.withType<KotlinCompile>().configureEach {
kotlinOptions { kotlinOptions {
jvmTarget = "1.8" jvmTarget = "1.8"
freeCompilerArgs = listOf( @Suppress("SuspiciousCollectionReassignment")
"-progressive", freeCompilerArgs += listOf(
"-Xopt-in=com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview" "-Xopt-in=com.squareup.kotlinpoet.metadata.KotlinPoetMetadataPreview"
) )
} }

View File

@@ -46,9 +46,9 @@ import javax.tools.Diagnostic
*/ */
@AutoService(Processor::class) @AutoService(Processor::class)
@IncrementalAnnotationProcessor(ISOLATING) @IncrementalAnnotationProcessor(ISOLATING)
class JsonClassCodegenProcessor : AbstractProcessor() { public class JsonClassCodegenProcessor : AbstractProcessor() {
companion object { public companion object {
/** /**
* This annotation processing argument can be specified to have a `@Generated` annotation * This annotation processing argument can be specified to have a `@Generated` annotation
* included in the generated code. It is not encouraged unless you need it for static analysis * included in the generated code. It is not encouraged unless you need it for static analysis
@@ -58,7 +58,7 @@ class JsonClassCodegenProcessor : AbstractProcessor() {
* * `"javax.annotation.processing.Generated"` (JRE 9+) * * `"javax.annotation.processing.Generated"` (JRE 9+)
* * `"javax.annotation.Generated"` (JRE <9) * * `"javax.annotation.Generated"` (JRE <9)
*/ */
const val OPTION_GENERATED = "moshi.generated" public const val OPTION_GENERATED: String = "moshi.generated"
private val POSSIBLE_GENERATED_NAMES = arrayOf( private val POSSIBLE_GENERATED_NAMES = arrayOf(
ClassName("javax.annotation.processing", "Generated"), ClassName("javax.annotation.processing", "Generated"),
ClassName("javax.annotation", "Generated") ClassName("javax.annotation", "Generated")
@@ -73,11 +73,11 @@ class JsonClassCodegenProcessor : AbstractProcessor() {
private val annotation = JsonClass::class.java private val annotation = JsonClass::class.java
private var generatedType: ClassName? = null private var generatedType: ClassName? = null
override fun getSupportedAnnotationTypes() = setOf(annotation.canonicalName) override fun getSupportedAnnotationTypes(): Set<String> = setOf(annotation.canonicalName)
override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latest() override fun getSupportedSourceVersion(): SourceVersion = SourceVersion.latest()
override fun getSupportedOptions() = setOf(OPTION_GENERATED) override fun getSupportedOptions(): Set<String> = setOf(OPTION_GENERATED)
override fun init(processingEnv: ProcessingEnvironment) { override fun init(processingEnv: ProcessingEnvironment) {
super.init(processingEnv) super.init(processingEnv)

View File

@@ -37,7 +37,7 @@ import com.squareup.moshi.Types
* Rendering is pluggable so that type variables can either be resolved or emitted as other code * Rendering is pluggable so that type variables can either be resolved or emitted as other code
* blocks. * blocks.
*/ */
abstract class TypeRenderer { internal abstract class TypeRenderer {
abstract fun renderTypeVariable(typeVariable: TypeVariableName): CodeBlock abstract fun renderTypeVariable(typeVariable: TypeVariableName): CodeBlock
fun render(typeName: TypeName, forceBox: Boolean = false): CodeBlock { fun render(typeName: TypeName, forceBox: Boolean = false): CodeBlock {

View File

@@ -21,5 +21,5 @@ import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
message = "this moved to avoid a package name conflict in the Java Platform Module System.", message = "this moved to avoid a package name conflict in the Java Platform Module System.",
replaceWith = ReplaceWith("com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory") replaceWith = ReplaceWith("com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory")
) )
class KotlinJsonAdapterFactory : public class KotlinJsonAdapterFactory :
JsonAdapter.Factory by KotlinJsonAdapterFactory() JsonAdapter.Factory by KotlinJsonAdapterFactory()

View File

@@ -179,7 +179,7 @@ internal class KotlinJsonAdapter<T>(
} }
} }
class KotlinJsonAdapterFactory : JsonAdapter.Factory { public class KotlinJsonAdapterFactory : JsonAdapter.Factory {
override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi): override fun create(type: Type, annotations: MutableSet<out Annotation>, moshi: Moshi):
JsonAdapter<*>? { JsonAdapter<*>? {
if (annotations.isNotEmpty()) return null if (annotations.isNotEmpty()) return null

View File

@@ -23,7 +23,8 @@ plugins {
tasks.withType<KotlinCompile>().configureEach { tasks.withType<KotlinCompile>().configureEach {
kotlinOptions { kotlinOptions {
freeCompilerArgs = listOf( @Suppress("SuspiciousCollectionReassignment")
freeCompilerArgs += listOf(
"-Werror", "-Werror",
"-Xopt-in=kotlin.ExperimentalStdlibApi", "-Xopt-in=kotlin.ExperimentalStdlibApi",
"-Xinline-classes" "-Xinline-classes"

View File

@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
kotlin("jvm") kotlin("jvm")
id("com.vanniktech.maven.publish") id("com.vanniktech.maven.publish")
id("ru.vyarus.animalsniffer")
} }
tasks.withType<KotlinCompile>() tasks.withType<KotlinCompile>()
@@ -26,18 +27,14 @@ tasks.withType<KotlinCompile>()
.configureEach { .configureEach {
kotlinOptions { kotlinOptions {
@Suppress("SuspiciousCollectionReassignment") // It's not suspicious @Suppress("SuspiciousCollectionReassignment") // It's not suspicious
freeCompilerArgs += listOf( freeCompilerArgs += listOf("-Xopt-in=kotlin.ExperimentalStdlibApi")
"-Xopt-in=kotlin.ExperimentalStdlibApi"
)
} }
} }
dependencies { dependencies {
compileOnly(Dependencies.jsr305) compileOnly(Dependencies.jsr305)
compileOnly(Dependencies.Kotlin.stdlib)
api(Dependencies.okio) api(Dependencies.okio)
testImplementation(Dependencies.Kotlin.stdlib)
testCompileOnly(Dependencies.jsr305) testCompileOnly(Dependencies.jsr305)
testImplementation(Dependencies.Testing.junit) testImplementation(Dependencies.Testing.junit)
testImplementation(Dependencies.Testing.truth) testImplementation(Dependencies.Testing.truth)

View File

@@ -18,7 +18,3 @@ POM_NAME=Moshi
POM_ARTIFACT_ID=moshi POM_ARTIFACT_ID=moshi
POM_PACKAGING=jar POM_PACKAGING=jar
AUTOMATIC_MODULE_NAME=com.squareup.moshi AUTOMATIC_MODULE_NAME=com.squareup.moshi
# Kotlin adds the stdlib dep by default in 1.4.0+, but we want to effectively make it compileOnly
# for our case to avoid imposing it on consumers.
kotlin.stdlib.default.dependency=false

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2020 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import me.champeau.gradle.japicmp.JapicmpTask
plugins {
`java-library`
id("me.champeau.gradle.japicmp")
}
val baseline = configurations.create("baseline")
val latest = configurations.create("latest")
dependencies {
baseline("com.squareup.moshi:moshi:1.11.0") {
isTransitive = false
isForce = true
}
latest(project(":moshi"))
}
val japicmp = tasks.register<JapicmpTask>("japicmp") {
dependsOn("jar")
oldClasspath = baseline
newClasspath = latest
onlyBinaryIncompatibleModified = true
failOnModification = true
txtOutputFile = file("$buildDir/reports/japi.txt")
ignoreMissingClasses = true
includeSynthetic = true
classExcludes = listOf(
"com.squareup.moshi.internal.NonNullJsonAdapter", // Internal.
"com.squareup.moshi.internal.NullSafeJsonAdapter", // Internal.
"com.squareup.moshi.internal.Util" // Internal.
)
}
tasks.named("check").configure {
dependsOn(japicmp)
}

View File

@@ -26,17 +26,17 @@ import kotlin.reflect.typeOf
* itself is handled, nested types (such as in generics) are not resolved. * itself is handled, nested types (such as in generics) are not resolved.
*/ */
@ExperimentalStdlibApi @ExperimentalStdlibApi
inline fun <reified T> Moshi.adapter(): JsonAdapter<T> = adapter(typeOf<T>()) public inline fun <reified T> Moshi.adapter(): JsonAdapter<T> = adapter(typeOf<T>())
@ExperimentalStdlibApi @ExperimentalStdlibApi
inline fun <reified T> Moshi.Builder.addAdapter(adapter: JsonAdapter<T>): Moshi.Builder = add(typeOf<T>().javaType, adapter) public inline fun <reified T> Moshi.Builder.addAdapter(adapter: JsonAdapter<T>): Moshi.Builder = add(typeOf<T>().javaType, adapter)
/** /**
* @return a [JsonAdapter] for [ktype], creating it if necessary. Note that while nullability of * @return a [JsonAdapter] for [ktype], creating it if necessary. Note that while nullability of
* [ktype] itself is handled, nested types (such as in generics) are not resolved. * [ktype] itself is handled, nested types (such as in generics) are not resolved.
*/ */
@ExperimentalStdlibApi @ExperimentalStdlibApi
fun <T> Moshi.adapter(ktype: KType): JsonAdapter<T> { public fun <T> Moshi.adapter(ktype: KType): JsonAdapter<T> {
val adapter = adapter<T>(ktype.javaType) val adapter = adapter<T>(ktype.javaType)
return if (adapter is NullSafeJsonAdapter || adapter is NonNullJsonAdapter) { return if (adapter is NullSafeJsonAdapter || adapter is NonNullJsonAdapter) {
// TODO CR - Assume that these know what they're doing? Or should we defensively avoid wrapping for matching nullability? // TODO CR - Assume that these know what they're doing? Or should we defensively avoid wrapping for matching nullability?

View File

@@ -25,13 +25,13 @@ import kotlin.reflect.javaType
import kotlin.reflect.typeOf import kotlin.reflect.typeOf
/** Returns the raw [Class] type of this type. */ /** Returns the raw [Class] type of this type. */
val Type.rawType: Class<*> get() = Types.getRawType(this) public val Type.rawType: Class<*> get() = Types.getRawType(this)
/** /**
* Checks if [this] contains [T]. Returns the subset of [this] without [T], or null if * Checks if [this] contains [T]. Returns the subset of [this] without [T], or null if
* [this] does not contain [T]. * [this] does not contain [T].
*/ */
inline fun <reified T : Annotation> Set<Annotation>.nextAnnotations(): Set<Annotation>? = Types.nextAnnotations(this, T::class.java) public inline fun <reified T : Annotation> Set<Annotation>.nextAnnotations(): Set<Annotation>? = Types.nextAnnotations(this, T::class.java)
/** /**
* Returns a type that represents an unknown type that extends [T]. For example, if * Returns a type that represents an unknown type that extends [T]. For example, if
@@ -39,7 +39,7 @@ inline fun <reified T : Annotation> Set<Annotation>.nextAnnotations(): Set<Annot
* [T] is [Any], this returns `*`, which is shorthand for `out Any?`. * [T] is [Any], this returns `*`, which is shorthand for `out Any?`.
*/ */
@ExperimentalStdlibApi @ExperimentalStdlibApi
inline fun <reified T> subtypeOf(): WildcardType { public inline fun <reified T> subtypeOf(): WildcardType {
var type = typeOf<T>().javaType var type = typeOf<T>().javaType
if (type is Class<*>) { if (type is Class<*>) {
type = Util.boxIfPrimitive(type) type = Util.boxIfPrimitive(type)
@@ -52,7 +52,7 @@ inline fun <reified T> subtypeOf(): WildcardType {
* [String], this returns `in String`. * [String], this returns `in String`.
*/ */
@ExperimentalStdlibApi @ExperimentalStdlibApi
inline fun <reified T> supertypeOf(): WildcardType { public inline fun <reified T> supertypeOf(): WildcardType {
var type = typeOf<T>().javaType var type = typeOf<T>().javaType
if (type is Class<*>) { if (type is Class<*>) {
type = Util.boxIfPrimitive(type) type = Util.boxIfPrimitive(type)
@@ -62,10 +62,10 @@ inline fun <reified T> supertypeOf(): WildcardType {
/** Returns a [GenericArrayType] with [this] as its [GenericArrayType.getGenericComponentType]. */ /** Returns a [GenericArrayType] with [this] as its [GenericArrayType.getGenericComponentType]. */
@ExperimentalStdlibApi @ExperimentalStdlibApi
fun KType.asArrayType(): GenericArrayType = javaType.asArrayType() public fun KType.asArrayType(): GenericArrayType = javaType.asArrayType()
/** Returns a [GenericArrayType] with [this] as its [GenericArrayType.getGenericComponentType]. */ /** Returns a [GenericArrayType] with [this] as its [GenericArrayType.getGenericComponentType]. */
fun KClass<*>.asArrayType(): GenericArrayType = java.asArrayType() public fun KClass<*>.asArrayType(): GenericArrayType = java.asArrayType()
/** Returns a [GenericArrayType] with [this] as its [GenericArrayType.getGenericComponentType]. */ /** Returns a [GenericArrayType] with [this] as its [GenericArrayType.getGenericComponentType]. */
fun Type.asArrayType(): GenericArrayType = Types.arrayOf(this) public fun Type.asArrayType(): GenericArrayType = Types.arrayOf(this)

View File

@@ -23,7 +23,9 @@ pluginManagement {
rootProject.name = "moshi-root" rootProject.name = "moshi-root"
include(":moshi") include(":moshi")
include(":moshi:japicmp")
include(":adapters") include(":adapters")
include(":adapters:japicmp")
include(":examples") include(":examples")
include(":kotlin:reflect") include(":kotlin:reflect")
include(":kotlin:codegen") include(":kotlin:codegen")