Skip to content

Commit

Permalink
Integrate ktlint (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
serras committed Sep 27, 2022
1 parent 7717ca7 commit ab62d6c
Show file tree
Hide file tree
Showing 18 changed files with 99 additions and 60 deletions.
7 changes: 7 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
root = true

[*.kt]
indent_size = 2

[*.kts]
indent_size = 4
31 changes: 30 additions & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,33 @@ jobs:
path: '**/build/reports/**'

- name: Stop Gradle daemons
run: ./gradlew --stop
run: ./gradlew --stop

ktlint:
runs-on: ubuntu-latest
timeout-minutes: 60

steps:
- uses: actions/[email protected]
with:
fetch-depth: 0

- name: Set up Java
uses: actions/[email protected]
with:
distribution: 'adopt'
java-version: 11

- name: Format
uses: gradle/[email protected]
with:
arguments: ktlintFormat

- name: Stop Gradle daemons
run: ./gradlew --stop

- name: "Commit formatted files"
uses: stefanzweifel/[email protected]
with:
commit_message: Format files using ktlint
file_pattern: "**/*.kt"
1 change: 1 addition & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ dependencies {
// This should be the only place where Gradle plugins versions are defined.

implementation(libs.gradlePlugin.kotlinJvm)
implementation(libs.gradlePlugin.ktLint)
}


Expand Down
6 changes: 0 additions & 6 deletions buildSrc/repositories.settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,13 @@ dependencyResolutionManagement {

repositories {
mavenCentral()
jitpack()
gradlePluginPortal()
}

pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
jitpack()
}
}
}

fun RepositoryHandler.jitpack() {
maven("https://jitpack.io")
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ plugins {
id("buildsrc.conventions.kopykat-base")
kotlin("jvm")
`java-library`
id("org.jlleitschuh.gradle.ktlint")
}

dependencies {
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ kotlinCompileTesting = "1.4.9"
assertj = "3.23.1"
classgraph = "4.8.149"
commons = "1.3.2"
ktlint = "11.0.0"

[libraries]
kotlin-bom = { module = "org.jetbrains.kotlin:kotlin-bom", version.ref = "kotlin" }
Expand All @@ -24,6 +25,7 @@ apache-commons-io = { module = "org.apache.commons:commons-io", version.ref = "c
# the *Maven coodinates* of Gradle plugins. Use in ./buildSrc/build.gradle.kts.

gradlePlugin-kotlinJvm = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
gradlePlugin-ktLint = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref = "ktlint" }


[plugins]
Expand Down
4 changes: 2 additions & 2 deletions kopykat-annotations/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
plugins {
buildsrc.conventions.`kotlin-jvm`
buildsrc.conventions.`maven-publish`
buildsrc.conventions.`kotlin-jvm`
buildsrc.conventions.`maven-publish`
}
4 changes: 2 additions & 2 deletions kopykat-ksp/src/main/kotlin/at/kopyk/CopyMap.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package at.kopyk

import at.kopyk.poet.append
import com.squareup.kotlinpoet.FileSpec
import at.kopyk.poet.addParameter
import at.kopyk.poet.addReturn
import at.kopyk.poet.append
import at.kopyk.poet.asTransformLambda
import at.kopyk.utils.TypeCategory.Known.Data
import at.kopyk.utils.TypeCategory.Known.Sealed
Expand All @@ -17,6 +16,7 @@ import at.kopyk.utils.lang.mapRun
import at.kopyk.utils.lang.onEachRun
import at.kopyk.utils.sealedTypes
import at.kopyk.utils.typeCategory
import com.squareup.kotlinpoet.FileSpec

internal val TypeCompileScope.copyMapFunctionKt: FileSpec
get() = buildFile(fileName = target.append("CopyMap").reflectionName()) {
Expand Down
26 changes: 16 additions & 10 deletions kopykat-ksp/src/main/kotlin/at/kopyk/KopyKatProcessor.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
package at.kopyk

import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import at.kopyk.poet.writeTo
import at.kopyk.utils.ClassCompileScope
import at.kopyk.utils.TypeCategory.Known
Expand All @@ -20,6 +14,12 @@ import at.kopyk.utils.onKnownCategory
import at.kopyk.utils.typeCategory
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.isAnnotationPresent
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import org.apache.commons.io.FilenameUtils.wildcardMatch

internal class KopyKatProcessor(
Expand Down Expand Up @@ -76,18 +76,24 @@ internal class KopyKatProcessor(
private fun KSClassDeclaration.checkAnnotationMisuse() {
if (isAnnotationPresent(CopyExtensions::class)) {
if (typeCategory !is Known) {
logger.error("""
logger.error(
"""
'@CopyExtensions' may only be used in data or value classes,
or sealed hierarchies of those.
""".trimIndent(), this)
""".trimIndent(),
this
)
return
}
if (options.generate is KopyKatGenerate.NotAnnotated) {
logger.warn("""
logger.warn(
"""
Unused '@CopyExtensions' annotation, the plug-in is configured to process all classes.
Add 'arg("annotatedOnly", "true")' to your KSP configuration to change this option.
More info at https://kopyk.at/#enable-only-for-selected-classes.
""".trimIndent(), this)
""".trimIndent(),
this
)
return
}
}
Expand Down
16 changes: 9 additions & 7 deletions kopykat-ksp/src/main/kotlin/at/kopyk/MutableCopy.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package at.kopyk

import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import at.kopyk.poet.addClass
import at.kopyk.poet.addMutableProperty
import at.kopyk.poet.addParameter
Expand All @@ -28,6 +25,9 @@ import at.kopyk.utils.mutable
import at.kopyk.utils.onKnownCategory
import at.kopyk.utils.sealedTypes
import at.kopyk.utils.typeCategory
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier

internal val TypeCompileScope.mutableCopyKt: FileSpec
get() = buildFile(target.mutable.reflectionName()) {
Expand All @@ -49,7 +49,7 @@ internal fun FileCompilerScope.addMutableCopy() {
addTypeVariables(typeVariableNames.map { it.makeInvariant() })
primaryConstructor {
mutationInfo.forEach { (property, mutationInfo) ->
with (property) {
with(property) {
addParameter(
name = baseName,
type = mutationInfo.className,
Expand Down Expand Up @@ -102,9 +102,11 @@ internal fun FileCompilerScope.addCopyClosure() {
private fun FileCompilerScope.addRetrofittedCopyFunction() {
addCopyFunction {
properties.forEachRun { addParameter(name = baseName, type = typeName, defaultValue = "this.$baseName") }
addReturn(sealedTypes.joinWithWhen { type ->
"is ${type.fullName} -> this.copy(${properties.joinToString { "${it.baseName} = ${it.baseName}" }})"
})
addReturn(
sealedTypes.joinWithWhen { type ->
"is ${type.fullName} -> this.copy(${properties.joinToString { "${it.baseName} = ${it.baseName}" }})"
}
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package at.kopyk.utils

import com.squareup.kotlinpoet.ClassName
import at.kopyk.poet.flattenWithSuffix
import com.squareup.kotlinpoet.ClassName

internal val ClassName.mutable: ClassName get() = flattenWithSuffix("Mutable")
internal val ClassName.dslMarker: ClassName get() = flattenWithSuffix("DslMarker")
4 changes: 2 additions & 2 deletions kopykat-ksp/src/main/kotlin/at/kopyk/utils/TypeCategory.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package at.kopyk.utils

import at.kopyk.utils.TypeCategory.Known
import at.kopyk.utils.TypeCategory.Unknown
import com.google.devtools.ksp.isAbstract
import com.google.devtools.ksp.isPublic
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.Modifier
import com.google.devtools.ksp.symbol.Modifier.SEALED
import at.kopyk.utils.TypeCategory.Known
import at.kopyk.utils.TypeCategory.Unknown

internal val KSClassDeclaration.typeCategory: TypeCategory
get() = when {
Expand Down
41 changes: 21 additions & 20 deletions kopykat-ksp/src/main/kotlin/at/kopyk/utils/TypeCompileScope.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package at.kopyk.utils

import at.kopyk.poet.className
import at.kopyk.poet.makeInvariant
import at.kopyk.poet.parameterizedWhenNotEmpty
import com.google.devtools.ksp.closestClassDeclaration
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.symbol.KSClassDeclaration
Expand All @@ -9,19 +12,16 @@ import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.ksp.toTypeName
import com.squareup.kotlinpoet.ksp.toTypeParameterResolver
import com.squareup.kotlinpoet.ksp.toTypeVariableName
import at.kopyk.poet.className
import at.kopyk.poet.makeInvariant
import at.kopyk.poet.parameterizedWhenNotEmpty
import com.squareup.kotlinpoet.LIST
import com.squareup.kotlinpoet.MAP
import com.squareup.kotlinpoet.SET
import com.squareup.kotlinpoet.TypeName
import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.ksp.TypeParameterResolver
import com.squareup.kotlinpoet.ksp.toClassName
import com.squareup.kotlinpoet.ksp.toTypeName
import com.squareup.kotlinpoet.ksp.toTypeParameterResolver
import com.squareup.kotlinpoet.ksp.toTypeVariableName

internal data class MutationInfo<out T : TypeName>(
val className: T,
Expand All @@ -47,13 +47,12 @@ internal sealed interface TypeCompileScope : KSClassDeclaration {
"$baseName = ${wrapper("${source ?: ""}$baseName")}"
fun Sequence<Pair<KSPropertyDeclaration, MutationInfo<TypeName>>>.joinAsAssignmentsWithMutation(
wrapper: MutationInfo<TypeName>.(String) -> String,
) = joinToString { (prop, mut) -> prop.toAssignment( { wrapper(mut, it) }) }
) = joinToString { (prop, mut) -> prop.toAssignment({ wrapper(mut, it) }) }

fun buildFile(fileName: String, block: FileCompilerScope.() -> Unit): FileSpec =
FileSpec.builder(packageName.asString(), fileName).also { toFileScope(it).block() }.build()

fun toFileScope(file: FileSpec.Builder): FileCompilerScope

}

internal class ClassCompileScope(
Expand Down Expand Up @@ -99,11 +98,13 @@ internal class FileCompilerScope(
returns: TypeName,
block: FunSpec.Builder.() -> Unit = {},
) {
file.addFunction(FunSpec.builder(name).apply {
receiver(receives)
returns(returns)
addTypeVariables(typeVariableNames.map { it.makeInvariant() })
}.apply(block).build())
file.addFunction(
FunSpec.builder(name).apply {
receiver(receives)
returns(returns)
addTypeVariables(typeVariableNames.map { it.makeInvariant() })
}.apply(block).build()
)
}

fun addInlinedFunction(
Expand All @@ -127,26 +128,26 @@ internal fun TypeCompileScope.mutationInfo(ty: KSType): MutationInfo<TypeName> =
className == LIST ->
MutationInfo(
ClassName(className.packageName, "MutableList"),
{ "${it}.toMutableList()" },
{ "$it.toMutableList()" },
{ it }
)
className == MAP ->
MutationInfo(
ClassName(className.packageName, "MutableMap"),
{ "${it}.toMutableMap()" },
{ "$it.toMutableMap()" },
{ it }
)
className == SET ->
MutationInfo(
ClassName(className.packageName, "MutableSet"),
{ "${it}.toMutableSet()" },
{ "$it.toMutableSet()" },
{ it }
)
ty.hasMutableCopy() ->
MutationInfo(
className.mutable,
{ "${it}.toMutable()" },
{ "${it}.freeze()" }
{ "$it.toMutable()" },
{ "$it.freeze()" }
)
else ->
MutationInfo(className, { it }, { it })
Expand Down
10 changes: 5 additions & 5 deletions kopykat-ksp/src/test/kotlin/at/kopyk/AnnotationTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class AnnotationTest {
|val p1 = Person("Alex", 1)
|val p2 = p1.copyMap(age = { it + 1 })
|val r = p2.age
""".evalsWithArgs(mapOf(KopyKatOptions.GENERATE to KopyKatGenerate.ANNOTATED),"r" to 2)
""".evalsWithArgs(mapOf(KopyKatOptions.GENERATE to KopyKatGenerate.ANNOTATED), "r" to 2)
}

@Test
Expand All @@ -27,8 +27,8 @@ class AnnotationTest {
|val p2 = p1.copyMap(age = { it + 1 })
|val r = p2.age
""".failsWith(mapOf(KopyKatOptions.GENERATE to KopyKatGenerate.ANNOTATED)) {
it.contains("Unresolved reference: copyMap")
}
it.contains("Unresolved reference: copyMap")
}
}

@Test
Expand Down Expand Up @@ -59,8 +59,8 @@ class AnnotationTest {
|val p2 = p1.copyMap(age = { it + 1 })
|val r = p2.age
""".compilesWith(mapOf(KopyKatOptions.GENERATE to KopyKatGenerate.ALL)) {
it.contains("Unused '@CopyExtensions' annotation")
}
it.contains("Unused '@CopyExtensions' annotation")
}
}

@Test
Expand Down
1 change: 0 additions & 1 deletion kopykat-ksp/src/test/kotlin/at/kopyk/CopyMapTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ class CopyMapTest {
""".failsWith { it.contains("Unresolved reference: copyMap") }
}


@Test
fun `simple test with additional property`() {
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class NestedMutableCopyTest {
""".evals("r" to "Señor Developer")
}


@Test
fun `mutate nested property with value type`() {
"""
Expand Down
1 change: 0 additions & 1 deletion kopykat-ksp/src/test/kotlin/at/kopyk/ValueCopyMapTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,4 @@ class ValueCopyMapTest {
|val r = a2.age
""".evals("r" to 1)
}

}
Loading

0 comments on commit ab62d6c

Please sign in to comment.