mirror of
https://github.com/fankes/moshi.git
synced 2025-10-20 00:19:21 +08:00
Switch to kotlin-compile-testing for JsonClassCodegenProcessorTe… (#928)
* Add kotlin-compile-testing dependency * Add Okio dependency to tests to match kotlin-compile-testing Without this, Okio.sink() fails to resolve at runtime * Try converting privateConstructor() to kotlin-compile-testing * Space * Update to 1.2.2 * Use new kotlin source file API * Use temporaryFolder as workingDir * Extract prepareCompilation helper method This allows for modifying the compilation with extra bits as needed * Migrate tests entirely to new API * Remove incorrect error message This passed before, but was picked up in https://github.com/square/moshi/pull/903 before and observed to be incorrect. * Remove custom kotlin compiler implementations * Add an OK exit code test This wasn't possible before! * Remove jitpack dependency now that it's on mavencentral * Move versions to parent pom * Fix new test from rebase
This commit is contained in:
@@ -25,7 +25,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup</groupId>
|
<groupId>com.squareup</groupId>
|
||||||
<artifactId>kotlinpoet</artifactId>
|
<artifactId>kotlinpoet</artifactId>
|
||||||
<version>1.3.0</version>
|
<version>${kotlinpoet.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.ltgt.gradle.incap</groupId>
|
<groupId>net.ltgt.gradle.incap</groupId>
|
||||||
@@ -37,12 +37,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.auto</groupId>
|
<groupId>com.google.auto</groupId>
|
||||||
<artifactId>auto-common</artifactId>
|
<artifactId>auto-common</artifactId>
|
||||||
<version>0.10</version>
|
<version>${auto-common.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.auto.service</groupId>
|
<groupId>com.google.auto.service</groupId>
|
||||||
<artifactId>auto-service-annotations</artifactId>
|
<artifactId>auto-service-annotations</artifactId>
|
||||||
<version>${autoservice.version}</version>
|
<version>${auto-service.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
@@ -56,32 +56,31 @@
|
|||||||
<artifactId>assertj-core</artifactId>
|
<artifactId>assertj-core</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.truth</groupId>
|
||||||
|
<artifactId>truth</artifactId>
|
||||||
|
<version>${truth.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
The Kotlin compiler must be near the end of the list because its .jar file includes an
|
The Kotlin compiler usage must be near the end of the list because its .jar file includes an
|
||||||
obsolete version of Guava!
|
obsolete version of Guava!
|
||||||
-->
|
-->
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-compiler-embeddable</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-annotation-processing-embeddable</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.eugeniomarletti.kotlin.metadata</groupId>
|
<groupId>me.eugeniomarletti.kotlin.metadata</groupId>
|
||||||
<artifactId>kotlin-metadata</artifactId>
|
<artifactId>kotlin-metadata</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
|
||||||
Though we don't use compile-testing, including it is a convenient way to get tools.jar on the
|
|
||||||
classpath. This dependency is required by kapt3.
|
|
||||||
-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.testing.compile</groupId>
|
<groupId>com.github.tschuchortdev</groupId>
|
||||||
<artifactId>compile-testing</artifactId>
|
<artifactId>kotlin-compile-testing</artifactId>
|
||||||
|
<version>${kotlin-compile-testing.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup.okio</groupId>
|
||||||
|
<artifactId>okio</artifactId>
|
||||||
|
<version>${okio2.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -111,7 +110,7 @@
|
|||||||
<annotationProcessorPath>
|
<annotationProcessorPath>
|
||||||
<groupId>com.google.auto.service</groupId>
|
<groupId>com.google.auto.service</groupId>
|
||||||
<artifactId>auto-service</artifactId>
|
<artifactId>auto-service</artifactId>
|
||||||
<version>${autoservice.version}</version>
|
<version>${auto-service.version}</version>
|
||||||
</annotationProcessorPath>
|
</annotationProcessorPath>
|
||||||
<annotationProcessorPath>
|
<annotationProcessorPath>
|
||||||
<groupId>net.ltgt.gradle.incap</groupId>
|
<groupId>net.ltgt.gradle.incap</groupId>
|
||||||
|
@@ -15,384 +15,352 @@
|
|||||||
*/
|
*/
|
||||||
package com.squareup.moshi.kotlin.codegen
|
package com.squareup.moshi.kotlin.codegen
|
||||||
|
|
||||||
|
import com.tschuchort.compiletesting.KotlinCompilation
|
||||||
|
import com.tschuchort.compiletesting.SourceFile
|
||||||
|
import com.tschuchort.compiletesting.SourceFile.Companion.kotlin
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
|
||||||
import org.junit.Ignore
|
import org.junit.Ignore
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.rules.TemporaryFolder
|
import org.junit.rules.TemporaryFolder
|
||||||
import javax.annotation.processing.Processor
|
|
||||||
|
|
||||||
/** Execute kotlinc to confirm that either files are generated or errors are printed. */
|
/** Execute kotlinc to confirm that either files are generated or errors are printed. */
|
||||||
class JsonClassCodegenProcessorTest {
|
class JsonClassCodegenProcessorTest {
|
||||||
@Rule @JvmField var temporaryFolder: TemporaryFolder = TemporaryFolder()
|
@Rule @JvmField var temporaryFolder: TemporaryFolder = TemporaryFolder()
|
||||||
|
|
||||||
@Test fun privateConstructor() {
|
@Test fun privateConstructor() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class PrivateConstructor private constructor(var a: Int, var b: Int) {
|
|
||||||
| fun a() = a
|
|
||||||
| fun b() = b
|
|
||||||
| companion object {
|
|
||||||
| fun newInstance(a: Int, b: Int) = PrivateConstructor(a, b)
|
|
||||||
| }
|
|
||||||
|}
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
class PrivateConstructor private constructor(var a: Int, var b: Int) {
|
||||||
assertThat(result.systemErr).contains("constructor is not internal or public")
|
fun a() = a
|
||||||
|
fun b() = b
|
||||||
|
companion object {
|
||||||
|
fun newInstance(a: Int, b: Int) = PrivateConstructor(a, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains("constructor is not internal or public")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun privateConstructorParameter() {
|
@Test fun privateConstructorParameter() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class PrivateConstructorParameter(private var a: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
class PrivateConstructorParameter(private var a: Int)
|
||||||
assertThat(result.systemErr).contains("property a is not visible")
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains("property a is not visible")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun privateProperties() {
|
@Test fun privateProperties() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class PrivateProperties {
|
|
||||||
| private var a: Int = -1
|
|
||||||
| private var b: Int = -1
|
|
||||||
|}
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
class PrivateProperties {
|
||||||
assertThat(result.systemErr).contains("property a is not visible")
|
private var a: Int = -1
|
||||||
|
private var b: Int = -1
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains("property a is not visible")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun interfacesNotSupported() {
|
@Test fun interfacesNotSupported() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|interface Interface
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
interface Interface
|
||||||
assertThat(result.systemErr).contains(
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: @JsonClass can't be applied to Interface: must be a Kotlin class")
|
"error: @JsonClass can't be applied to Interface: must be a Kotlin class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun abstractClassesNotSupported() {
|
@Test fun interfacesDoNotErrorWhenGeneratorNotSet() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|abstract class AbstractClass(val a: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true, generator="customGenerator")
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
interface Interface
|
||||||
assertThat(result.systemErr).contains(
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test fun abstractClassesNotSupported() {
|
||||||
|
val result = compile(kotlin("source.kt",
|
||||||
|
"""
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
abstract class AbstractClass(val a: Int)
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: @JsonClass can't be applied to AbstractClass: must not be abstract")
|
"error: @JsonClass can't be applied to AbstractClass: must not be abstract")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun sealedClassesNotSupported() {
|
@Test fun sealedClassesNotSupported() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|sealed class SealedClass(val a: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
sealed class SealedClass(val a: Int)
|
||||||
assertThat(result.systemErr).contains(
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: @JsonClass can't be applied to SealedClass: must not be sealed")
|
"error: @JsonClass can't be applied to SealedClass: must not be sealed")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun innerClassesNotSupported() {
|
@Test fun innerClassesNotSupported() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|class Outer {
|
|
||||||
| @JsonClass(generateAdapter = true)
|
|
||||||
| inner class InnerClass(val a: Int)
|
|
||||||
|}
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
class Outer {
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.systemErr).contains(
|
inner class InnerClass(val a: Int)
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: @JsonClass can't be applied to Outer.InnerClass: must not be an inner class")
|
"error: @JsonClass can't be applied to Outer.InnerClass: must not be an inner class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun enumClassesNotSupported() {
|
@Test fun enumClassesNotSupported() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|enum class KotlinEnum {
|
|
||||||
| A, B
|
|
||||||
|}
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
enum class KotlinEnum {
|
||||||
assertThat(result.systemErr).contains(
|
A, B
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: @JsonClass with 'generateAdapter = \"true\"' can't be applied to KotlinEnum: code gen for enums is not supported or necessary")
|
"error: @JsonClass with 'generateAdapter = \"true\"' can't be applied to KotlinEnum: code gen for enums is not supported or necessary")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotation processors don't get called for local classes, so we don't have the opportunity to
|
// Annotation processors don't get called for local classes, so we don't have the opportunity to
|
||||||
// print an error message. Instead local classes will fail at runtime.
|
// print an error message. Instead local classes will fail at runtime.
|
||||||
@Ignore
|
@Ignore @Test fun localClassesNotSupported() {
|
||||||
@Test fun localClassesNotSupported() {
|
val result = compile(kotlin("source.kt",
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
"""
|
||||||
call.inheritClasspath = true
|
import com.squareup.moshi.JsonClass
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|fun outer() {
|
|
||||||
| @JsonClass(generateAdapter = true)
|
|
||||||
| class LocalClass(val a: Int)
|
|
||||||
|}
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
fun outer() {
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.systemErr).contains(
|
class LocalClass(val a: Int)
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: @JsonClass can't be applied to LocalClass: must not be local")
|
"error: @JsonClass can't be applied to LocalClass: must not be local")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun objectDeclarationsNotSupported() {
|
@Test fun objectDeclarationsNotSupported() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
@JsonClass(generateAdapter = true)
|
||||||
|
|
object ObjectDeclaration {
|
||||||
|@JsonClass(generateAdapter = true)
|
var a = 5
|
||||||
|object ObjectDeclaration {
|
}
|
||||||
| var a = 5
|
"""
|
||||||
|}
|
))
|
||||||
|""".trimMargin())
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
val result = call.execute()
|
assertThat(result.messages).contains(
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
|
||||||
assertThat(result.systemErr).contains(
|
|
||||||
"error: @JsonClass can't be applied to ObjectDeclaration: must be a Kotlin class")
|
"error: @JsonClass can't be applied to ObjectDeclaration: must be a Kotlin class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun objectExpressionsNotSupported() {
|
@Test fun objectExpressionsNotSupported() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|val expression = object : Any() {
|
|
||||||
| var a = 5
|
|
||||||
|}
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
val expression = object : Any() {
|
||||||
assertThat(result.systemErr).contains(
|
var a = 5
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: @JsonClass can't be applied to expression\$annotations(): must be a Kotlin class")
|
"error: @JsonClass can't be applied to expression\$annotations(): must be a Kotlin class")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun requiredTransientConstructorParameterFails() {
|
@Test fun requiredTransientConstructorParameterFails() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class RequiredTransientConstructorParameter(@Transient var a: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
class RequiredTransientConstructorParameter(@Transient var a: Int)
|
||||||
assertThat(result.systemErr).contains(
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: No default value for transient property a")
|
"error: No default value for transient property a")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun nonPropertyConstructorParameter() {
|
@Test fun nonPropertyConstructorParameter() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class NonPropertyConstructorParameter(a: Int, val b: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
import com.squareup.moshi.JsonClass
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.systemErr).contains(
|
class NonPropertyConstructorParameter(a: Int, val b: Int)
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"error: No property for required constructor parameter a")
|
"error: No property for required constructor parameter a")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun badGeneratedAnnotation() {
|
@Test fun badGeneratedAnnotation() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = prepareCompilation(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.kaptArgs[JsonClassCodegenProcessor.OPTION_GENERATED] = "javax.annotation.GeneratedBlerg"
|
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|data class Foo(val a: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
data class Foo(val a: Int)
|
||||||
assertThat(result.systemErr).contains(
|
"""
|
||||||
|
)).apply {
|
||||||
|
kaptArgs[JsonClassCodegenProcessor.OPTION_GENERATED] = "javax.annotation.GeneratedBlerg"
|
||||||
|
}.compile()
|
||||||
|
assertThat(result.messages).contains(
|
||||||
"Invalid option value for ${JsonClassCodegenProcessor.OPTION_GENERATED}")
|
"Invalid option value for ${JsonClassCodegenProcessor.OPTION_GENERATED}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun multipleErrors() {
|
@Test fun multipleErrors() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class Class1(private var a: Int, private var b: Int)
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class Class2(private var c: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
class Class1(private var a: Int, private var b: Int)
|
||||||
assertThat(result.systemErr).contains("property a is not visible")
|
|
||||||
assertThat(result.systemErr).contains("property b is not visible")
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.systemErr).contains("property c is not visible")
|
class Class2(private var c: Int)
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains("property a is not visible")
|
||||||
|
assertThat(result.messages).contains("property c is not visible")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun extendPlatformType() {
|
@Test fun extendPlatformType() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
import java.util.Date
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|import java.util.Date
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class ExtendsPlatformClass(var a: Int) : Date()
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
class ExtendsPlatformClass(var a: Int) : Date()
|
||||||
assertThat(result.systemErr).contains("supertype java.util.Date is not a Kotlin type")
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.messages).contains("supertype java.util.Date is not a Kotlin type")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun extendJavaType() {
|
@Test fun extendJavaType() {
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
val result = compile(kotlin("source.kt",
|
||||||
call.inheritClasspath = true
|
"""
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonClass
|
||||||
call.addKt("source.kt", """
|
import com.squareup.moshi.kotlin.codegen.JavaSuperclass
|
||||||
|import com.squareup.moshi.JsonClass
|
|
||||||
|import com.squareup.moshi.kotlin.codegen.JavaSuperclass
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class ExtendsJavaType(var b: Int) : JavaSuperclass()
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@JsonClass(generateAdapter = true)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
class ExtendsJavaType(var b: Int) : JavaSuperclass()
|
||||||
assertThat(result.systemErr)
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages)
|
||||||
.contains("supertype com.squareup.moshi.kotlin.codegen.JavaSuperclass is not a Kotlin type")
|
.contains("supertype com.squareup.moshi.kotlin.codegen.JavaSuperclass is not a Kotlin type")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test fun nonFieldApplicableQualifier() {
|
||||||
fun nonFieldApplicableQualifier() {
|
val result = compile(kotlin("source.kt",
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
"""
|
||||||
call.inheritClasspath = true
|
import com.squareup.moshi.JsonClass
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonQualifier
|
||||||
call.addKt("source.kt", """
|
import kotlin.annotation.AnnotationRetention.RUNTIME
|
||||||
|import com.squareup.moshi.JsonClass
|
import kotlin.annotation.AnnotationTarget.PROPERTY
|
||||||
|import com.squareup.moshi.JsonQualifier
|
import kotlin.annotation.Retention
|
||||||
|import kotlin.annotation.AnnotationRetention.RUNTIME
|
import kotlin.annotation.Target
|
||||||
|import kotlin.annotation.AnnotationTarget.PROPERTY
|
|
||||||
|import kotlin.annotation.Retention
|
|
||||||
|import kotlin.annotation.Target
|
|
||||||
|
|
|
||||||
|@Retention(RUNTIME)
|
|
||||||
|@Target(PROPERTY)
|
|
||||||
|@JsonQualifier
|
|
||||||
|annotation class UpperCase
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class ClassWithQualifier(@UpperCase val a: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@Retention(RUNTIME)
|
||||||
println(result.systemErr)
|
@Target(PROPERTY)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
@JsonQualifier
|
||||||
assertThat(result.systemErr).contains("JsonQualifier @UpperCase must support FIELD target")
|
annotation class UpperCase
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
class ClassWithQualifier(@UpperCase val a: Int)
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains("JsonQualifier @UpperCase must support FIELD target")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test fun nonRuntimeQualifier() {
|
||||||
fun nonRuntimeQualifier() {
|
val result = compile(kotlin("source.kt",
|
||||||
val call = KotlinCompilerCall(temporaryFolder.root)
|
"""
|
||||||
call.inheritClasspath = true
|
import com.squareup.moshi.JsonClass
|
||||||
call.addService(Processor::class, JsonClassCodegenProcessor::class)
|
import com.squareup.moshi.JsonQualifier
|
||||||
call.addKt("source.kt", """
|
import kotlin.annotation.AnnotationRetention.BINARY
|
||||||
|import com.squareup.moshi.JsonClass
|
import kotlin.annotation.AnnotationTarget.FIELD
|
||||||
|import com.squareup.moshi.JsonQualifier
|
import kotlin.annotation.AnnotationTarget.PROPERTY
|
||||||
|import kotlin.annotation.AnnotationRetention.BINARY
|
import kotlin.annotation.Retention
|
||||||
|import kotlin.annotation.AnnotationTarget.FIELD
|
import kotlin.annotation.Target
|
||||||
|import kotlin.annotation.AnnotationTarget.PROPERTY
|
|
||||||
|import kotlin.annotation.Retention
|
|
||||||
|import kotlin.annotation.Target
|
|
||||||
|
|
|
||||||
|@Retention(BINARY)
|
|
||||||
|@Target(PROPERTY, FIELD)
|
|
||||||
|@JsonQualifier
|
|
||||||
|annotation class UpperCase
|
|
||||||
|
|
|
||||||
|@JsonClass(generateAdapter = true)
|
|
||||||
|class ClassWithQualifier(@UpperCase val a: Int)
|
|
||||||
|""".trimMargin())
|
|
||||||
|
|
||||||
val result = call.execute()
|
@Retention(BINARY)
|
||||||
assertThat(result.exitCode).isEqualTo(ExitCode.COMPILATION_ERROR)
|
@Target(PROPERTY, FIELD)
|
||||||
assertThat(result.systemErr).contains("JsonQualifier @UpperCase must have RUNTIME retention")
|
@JsonQualifier
|
||||||
|
annotation class UpperCase
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
class ClassWithQualifier(@UpperCase val a: Int)
|
||||||
|
"""
|
||||||
|
))
|
||||||
|
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.COMPILATION_ERROR)
|
||||||
|
assertThat(result.messages).contains("JsonQualifier @UpperCase must have RUNTIME retention")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun prepareCompilation(vararg sourceFiles: SourceFile): KotlinCompilation {
|
||||||
|
return KotlinCompilation()
|
||||||
|
.apply {
|
||||||
|
workingDir = temporaryFolder.root
|
||||||
|
annotationProcessors = listOf(JsonClassCodegenProcessor())
|
||||||
|
inheritClassPath = true
|
||||||
|
sources = sourceFiles.asList()
|
||||||
|
verbose = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun compile(vararg sourceFiles: SourceFile): KotlinCompilation.Result {
|
||||||
|
return prepareCompilation(*sourceFiles).compile()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -1,193 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 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
|
|
||||||
*
|
|
||||||
* http://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.
|
|
||||||
*/
|
|
||||||
package com.squareup.moshi.kotlin.codegen
|
|
||||||
|
|
||||||
import com.google.common.collect.LinkedHashMultimap
|
|
||||||
import okio.Buffer
|
|
||||||
import okio.Okio
|
|
||||||
import org.jetbrains.kotlin.cli.common.CLITool
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
|
||||||
import java.io.File
|
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.ObjectOutputStream
|
|
||||||
import java.io.PrintStream
|
|
||||||
import java.net.URLClassLoader
|
|
||||||
import java.net.URLDecoder
|
|
||||||
import java.util.zip.ZipEntry
|
|
||||||
import java.util.zip.ZipOutputStream
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
/** Prepares an invocation of the Kotlin compiler. */
|
|
||||||
class KotlinCompilerCall(var scratchDir: File) {
|
|
||||||
val sourcesDir = File(scratchDir, "sources")
|
|
||||||
val classesDir = File(scratchDir, "classes")
|
|
||||||
val servicesJar = File(scratchDir, "services.jar")
|
|
||||||
|
|
||||||
var inheritClasspath = false
|
|
||||||
|
|
||||||
val args = mutableListOf<String>()
|
|
||||||
val kaptArgs = mutableMapOf<String, String>()
|
|
||||||
val classpath = mutableListOf<String>()
|
|
||||||
val services = LinkedHashMultimap.create<KClass<*>, KClass<*>>()
|
|
||||||
|
|
||||||
/** Adds a source file to be compiled. */
|
|
||||||
fun addKt(path: String, source: String) {
|
|
||||||
val sourceFile = File(sourcesDir, path)
|
|
||||||
sourceFile.parentFile.mkdirs()
|
|
||||||
Okio.buffer(Okio.sink(sourceFile)).use {
|
|
||||||
it.writeUtf8(source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds a service like an annotation processor to make available to the compiler. */
|
|
||||||
fun addService(serviceClass: KClass<*>, implementation: KClass<*>) {
|
|
||||||
services.put(serviceClass, implementation)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun execute(): KotlinCompilerResult {
|
|
||||||
val fullArgs = mutableListOf<String>()
|
|
||||||
fullArgs.addAll(args)
|
|
||||||
|
|
||||||
fullArgs.add("-d")
|
|
||||||
fullArgs.add(classesDir.toString())
|
|
||||||
|
|
||||||
val fullClasspath = fullClasspath()
|
|
||||||
if (fullClasspath.isNotEmpty()) {
|
|
||||||
fullArgs.add("-classpath")
|
|
||||||
fullArgs.add(fullClasspath.joinToString(separator = ":"))
|
|
||||||
}
|
|
||||||
|
|
||||||
for (source in sourcesDir.listFiles()) {
|
|
||||||
fullArgs.add(source.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
fullArgs.addAll(annotationProcessorArgs())
|
|
||||||
if (kaptArgs.isNotEmpty()) {
|
|
||||||
fullArgs.apply {
|
|
||||||
add("-P")
|
|
||||||
add("plugin:org.jetbrains.kotlin.kapt3:apoptions=${encodeOptions(kaptArgs)}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val systemErrBuffer = Buffer()
|
|
||||||
val oldSystemErr = System.err
|
|
||||||
System.setErr(PrintStream(systemErrBuffer.outputStream()))
|
|
||||||
try {
|
|
||||||
val exitCode = CLITool.doMainNoExit(K2JVMCompiler(), fullArgs.toTypedArray())
|
|
||||||
val systemErr = systemErrBuffer.readUtf8()
|
|
||||||
return KotlinCompilerResult(systemErr, exitCode)
|
|
||||||
} finally {
|
|
||||||
System.setErr(oldSystemErr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns arguments necessary to enable and configure kapt3. */
|
|
||||||
private fun annotationProcessorArgs(): List<String> {
|
|
||||||
val kaptSourceDir = File(scratchDir, "kapt/sources")
|
|
||||||
val kaptStubsDir = File(scratchDir, "kapt/stubs")
|
|
||||||
|
|
||||||
return listOf(
|
|
||||||
"-Xplugin=${kapt3Jar()}",
|
|
||||||
"-P", "plugin:org.jetbrains.kotlin.kapt3:sources=$kaptSourceDir",
|
|
||||||
"-P", "plugin:org.jetbrains.kotlin.kapt3:classes=$classesDir",
|
|
||||||
"-P", "plugin:org.jetbrains.kotlin.kapt3:stubs=$kaptStubsDir",
|
|
||||||
"-P", "plugin:org.jetbrains.kotlin.kapt3:apclasspath=$servicesJar",
|
|
||||||
"-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the classpath to use when compiling code. */
|
|
||||||
private fun fullClasspath(): List<String> {
|
|
||||||
val result = mutableListOf<String>()
|
|
||||||
result.addAll(classpath)
|
|
||||||
|
|
||||||
// Copy over the classpath of the running application.
|
|
||||||
if (inheritClasspath) {
|
|
||||||
for (classpathFile in classpathFiles()) {
|
|
||||||
result.add(classpathFile.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!services.isEmpty) {
|
|
||||||
writeServicesJar()
|
|
||||||
result.add(servicesJar.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a .jar file that holds ServiceManager registrations. Necessary because AutoService's
|
|
||||||
* results might not be visible to this test.
|
|
||||||
*/
|
|
||||||
private fun writeServicesJar() {
|
|
||||||
ZipOutputStream(FileOutputStream(servicesJar)).use { zipOutputStream ->
|
|
||||||
for (entry in services.asMap()) {
|
|
||||||
zipOutputStream.putNextEntry(
|
|
||||||
ZipEntry("META-INF/services/${entry.key.qualifiedName}"))
|
|
||||||
val serviceFile = Okio.buffer(Okio.sink(zipOutputStream))
|
|
||||||
for (implementation in entry.value) {
|
|
||||||
serviceFile.writeUtf8(implementation.qualifiedName!!)
|
|
||||||
serviceFile.writeUtf8("\n")
|
|
||||||
}
|
|
||||||
serviceFile.emit() // Don't close the entry; that closes the file.
|
|
||||||
zipOutputStream.closeEntry()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the files on the host process' classpath. */
|
|
||||||
private fun classpathFiles(): List<File> {
|
|
||||||
val classLoader = JsonClassCodegenProcessorTest::class.java.classLoader
|
|
||||||
if (classLoader !is URLClassLoader) {
|
|
||||||
throw UnsupportedOperationException("unable to extract classpath from $classLoader")
|
|
||||||
}
|
|
||||||
|
|
||||||
val result = mutableListOf<File>()
|
|
||||||
for (url in classLoader.urLs) {
|
|
||||||
if (url.protocol != "file") {
|
|
||||||
throw UnsupportedOperationException("unable to handle classpath element $url")
|
|
||||||
}
|
|
||||||
result.add(File(URLDecoder.decode(url.path, "UTF-8")))
|
|
||||||
}
|
|
||||||
return result.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the path to the kotlin-annotation-processing .jar file. */
|
|
||||||
private fun kapt3Jar(): File {
|
|
||||||
for (file in classpathFiles()) {
|
|
||||||
if (file.name.startsWith("kotlin-annotation-processing-embeddable")) return file
|
|
||||||
}
|
|
||||||
throw IllegalStateException("no kotlin-annotation-processing-embeddable jar on classpath:\n " +
|
|
||||||
"${classpathFiles().joinToString(separator = "\n ")}}")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base64 encodes a mapping of annotation processor args for kapt, as specified by
|
|
||||||
* https://kotlinlang.org/docs/reference/kapt.html#apjavac-options-encoding
|
|
||||||
*/
|
|
||||||
private fun encodeOptions(options: Map<String, String>): String {
|
|
||||||
val buffer = Buffer()
|
|
||||||
ObjectOutputStream(buffer.outputStream()).use { oos ->
|
|
||||||
oos.writeInt(options.size)
|
|
||||||
for ((key, value) in options.entries) {
|
|
||||||
oos.writeUTF(key)
|
|
||||||
oos.writeUTF(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buffer.readByteString().base64()
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 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
|
|
||||||
*
|
|
||||||
* http://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.
|
|
||||||
*/
|
|
||||||
package com.squareup.moshi.kotlin.codegen
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
|
||||||
|
|
||||||
class KotlinCompilerResult(
|
|
||||||
val systemErr: String,
|
|
||||||
var exitCode: ExitCode
|
|
||||||
)
|
|
19
pom.xml
19
pom.xml
@@ -29,20 +29,25 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<java.version>1.7</java.version>
|
<java.version>1.7</java.version>
|
||||||
<kotlin.version>1.3.40</kotlin.version>
|
|
||||||
<kotlin-metadata.version>1.4.0</kotlin-metadata.version>
|
|
||||||
<dokka.version>0.9.17</dokka.version>
|
|
||||||
<maven-assembly.version>3.1.0</maven-assembly.version>
|
|
||||||
<incap.version>0.2</incap.version>
|
|
||||||
<autoservice.version>1.0-rc5</autoservice.version>
|
|
||||||
|
|
||||||
<!-- Dependencies -->
|
<!-- Dependencies -->
|
||||||
|
<auto-common.version>0.10</auto-common.version>
|
||||||
|
<auto-service.version>1.0-rc5</auto-service.version>
|
||||||
|
<dokka.version>0.9.17</dokka.version>
|
||||||
|
<incap.version>0.2</incap.version>
|
||||||
<okio.version>1.16.0</okio.version>
|
<okio.version>1.16.0</okio.version>
|
||||||
|
<okio2.version>2.1.0</okio2.version>
|
||||||
|
<kotlin.version>1.3.40</kotlin.version>
|
||||||
|
<kotlinpoet.version>1.3.0</kotlinpoet.version>
|
||||||
|
<kotlin-metadata.version>1.4.0</kotlin-metadata.version>
|
||||||
|
<maven-assembly.version>3.1.0</maven-assembly.version>
|
||||||
|
|
||||||
<!-- Test Dependencies -->
|
<!-- Test Dependencies -->
|
||||||
|
<assertj.version>3.11.1</assertj.version>
|
||||||
<compile-testing.version>0.15</compile-testing.version>
|
<compile-testing.version>0.15</compile-testing.version>
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
<assertj.version>3.11.1</assertj.version>
|
<kotlin-compile-testing.version>1.2.2</kotlin-compile-testing.version>
|
||||||
|
<truth.version>1.0</truth.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
|
Reference in New Issue
Block a user