Skip to content

Commit

Permalink
Merge pull request #157 from yandex/wp/refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeffset authored May 24, 2024
2 parents 32e3a43 + 8c5b787 commit 4b82b9d
Show file tree
Hide file tree
Showing 16 changed files with 178 additions and 145 deletions.
47 changes: 23 additions & 24 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import io.github.gradlenexus.publishplugin.NexusPublishExtension
import kotlinx.kover.gradle.plugin.dsl.KoverProjectExtension
import kotlinx.kover.gradle.plugin.dsl.tasks.KoverXmlReport

plugins {
id("yatagan.base-module")
Expand Down Expand Up @@ -41,24 +42,26 @@ tasks {
}
}

koverReport {
filters {
includes {
classes("com.yandex.yatagan.**")
}
excludes {
classes(
// Do not cover internal stuff
"**.internal.**",
// Mostly inline utility code
"**.ExtensionsKt",
// Testing code
"com.yandex.yatagan.testing.**",
// Code generation utility code
"com.yandex.yatagan.codegen.poetry.**",
// Just in case some build code gets instrumented
"com.yandex.yatagan.gradle.**",
)
kover {
reports {
filters {
includes {
classes("com.yandex.yatagan.**")
}
excludes {
classes(
// Do not cover internal stuff
"**.internal.**",
// Mostly inline utility code
"**.ExtensionsKt",
// Testing code
"com.yandex.yatagan.testing.**",
// Code generation utility code
"com.yandex.yatagan.codegen.poetry.**",
// Just in case some build code gets instrumented
"com.yandex.yatagan.gradle.**",
)
}
}
}
}
Expand Down Expand Up @@ -148,11 +151,7 @@ if (enableCoverage) {
}
}

koverReport {
defaults {
xml {
onCheck = true
}
}
tasks.check {
dependsOn(tasks.withType<KoverXmlReport>())
}
}
2 changes: 2 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ dependencies {

implementation(kotlin("stdlib"))
implementation(kotlin("reflect"))

implementation(libs.poets.kotlin)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,74 @@

package com.yandex.yatagan.gradle

import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.CodeBlock
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.STRING
import com.squareup.kotlinpoet.TypeSpec
import org.gradle.api.DefaultTask
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFile
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.property
import java.io.File
import java.nio.file.Files
import javax.inject.Inject

/**
* Generates Kotlin source, that contains declarations of a top-level const property with the given name and
* given classpath value.
* Generates constant declarations in Kotlin containing configured classpath values.
*
* Classpath is a list of files joined with [File.pathSeparatorChar] into a single string.
* Objects inside [groups] denote a Kotlin `object` container declaration for properties.
* For each group, objects inside [properties][NamedClasspathGroup.properties] denote a generated property.
*/
@CacheableTask
abstract class ClasspathSourceGeneratorTask @Inject constructor(
objects: ObjectFactory,
private val objects: ObjectFactory,
) : DefaultTask() {
@get:Input
val packageName: Property<String> = objects.property()

/**
* Kotlin object declaration
*/
interface NamedClasspathGroup {
@get:Input
val name: String

@get:Nested
val properties: NamedDomainObjectContainer<NamedClasspath>
}

/**
* `const val` property declaration.
* [classpath] is represented by a string delimited with [File.pathSeparatorChar].
*/
interface NamedClasspath {
@get:Input
val name: String

@get:Classpath
@get:InputFiles
val classpath: Property<FileCollection>
}

/**
* Generated package name.
*/
@get:Input
val propertyName: Property<String> = objects.property()
abstract val packageName: Property<String>

@get:InputFiles
val classpath: Property<FileCollection> = objects.property()
@get:Nested
abstract val groups: NamedDomainObjectContainer<NamedClasspathGroup>

@get:OutputDirectory
val generatedSourceDir: DirectoryProperty = objects.directoryProperty().apply {
Expand All @@ -57,27 +92,43 @@ abstract class ClasspathSourceGeneratorTask @Inject constructor(

@get:Input
val generatedSourceName: Property<String> = objects.property<String>().apply {
convention("$name.kt")
@Suppress("DEPRECATION")
val defaultName = name.capitalize()
convention("$defaultName.kt")
}

val generatedSource: Provider<RegularFile>
@OutputFile get() = generatedSourceDir.file(generatedSourceName)

@TaskAction
fun action() {
generatedSourceDir.get().asFile.listFiles()?.forEach { it.deleteRecursively() }

val classpathSeparator = File.pathSeparatorChar
val text = buildString {
append("// This source is GENERATED by gradle task `").append(name).appendLine("`. Do not edit!")
append("package ").appendLine(packageName.get())
append("const val ").append(propertyName.get()).appendLine(" =")
classpath.get().joinTo(
buffer = this,
separator = "$classpathSeparator$RAW_QUOTE + \n $RAW_QUOTE",
prefix = " $RAW_QUOTE",
postfix = RAW_QUOTE,
)
for (group in groups) {
val spec = FileSpec.builder(packageName.get(), group.name)
.addFileComment("This source is GENERATED by gradle task `%L`. Do not edit!", this.name)
.addType(TypeSpec.objectBuilder(group.name)
.run {
group.properties.forEach { property ->
addProperty(PropertySpec.builder(property.name, STRING, KModifier.CONST)
.addAnnotation(AnnotationSpec.builder(Suppress::class).run {
addMember("%S", "ConstPropertyName")
build()
})
.initializer(CodeBlock.builder().run {
val paths = property.classpath.get().map { it.absolutePath }
paths.forEachIndexed { index, path ->
val isLast = index != paths.lastIndex
add("%S", if (isLast) path + classpathSeparator else path)
if (isLast) add(" +\n")
}
build()
}).build()
)
}
build()
})
.build()
generatedSourceDir.get().file(group.name + ".kt").asFile.writeText(spec.toString())
}
generatedSource.get().asFile.writeText(text)
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ kotlin-binaryCompatibilityGradle.group = "org.jetbrains.kotlinx.binary-compatibi
kotlin-binaryCompatibilityGradle.name = "org.jetbrains.kotlinx.binary-compatibility-validator.gradle.plugin"
kotlin-binaryCompatibilityGradle.version = "0.13.2"

kotlin-koverGradle = "org.jetbrains.kotlinx:kover-gradle-plugin:0.7.6"
kotlin-koverGradle = "org.jetbrains.kotlinx:kover-gradle-plugin:0.8.0"

ksp-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" }
ksp-gradle = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
Expand Down
7 changes: 5 additions & 2 deletions lang/api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ dependencies {

val generateStdLibClasspath by tasks.registering(ClasspathSourceGeneratorTask::class) {
packageName.set("com.yandex.yatagan.lang")
propertyName.set("StdLibClasspath")
classpath.set(stdLib)
groups.register("GeneratedClasspath") {
properties.register("StdLib") {
classpath = stdLib
}
}
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ interface LangTestDriver : SourceSet {
return TestCompilationArguments(
sources = sourceFiles,
inheritClasspath = false,
classpath = StdLibClasspath.split(File.pathSeparatorChar).map(::File),
classpath = GeneratedClasspath.StdLib.split(File.pathSeparatorChar).map(::File),
javacArguments = listOf("-Xdiags:verbose"),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
* limitations under the License.
*/

@file:OptIn(ConditionsApi::class, VariantApi::class)

package com.yandex.yatagan.lang.compiled

import com.yandex.yatagan.AssistedFactory
Expand All @@ -40,6 +38,7 @@ import com.yandex.yatagan.lang.common.isDaggerCompat
abstract class CtTypeDeclarationBase : TypeDeclarationBase() {
abstract override val annotations: Sequence<CtAnnotationBase>

@OptIn(ConditionsApi::class, VariantApi::class)
override fun <T : BuiltinAnnotation.OnClass> getAnnotation(
which: BuiltinAnnotation.Target.OnClass<T>
): T? {
Expand Down Expand Up @@ -73,6 +72,7 @@ abstract class CtTypeDeclarationBase : TypeDeclarationBase() {
return which.modelClass.cast(value)
}

@OptIn(ConditionsApi::class)
override fun <T : BuiltinAnnotation.OnClassRepeatable> getAnnotations(
which: BuiltinAnnotation.Target.OnClassRepeatable<T>
): List<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
* limitations under the License.
*/

@file:OptIn(ConditionsApi::class, VariantApi::class)

package com.yandex.yatagan.lang.rt

import com.yandex.yatagan.AssistedFactory
Expand Down Expand Up @@ -165,6 +163,7 @@ internal class RtTypeDeclarationImpl private constructor(
override val platformModel: Class<*>
get() = impl

@OptIn(ConditionsApi::class, VariantApi::class)
override fun <T : BuiltinAnnotation.OnClass> getAnnotation(
which: BuiltinAnnotation.Target.OnClass<T>
): T? {
Expand All @@ -189,6 +188,7 @@ internal class RtTypeDeclarationImpl private constructor(
return which.modelClass.cast(value)
}

@OptIn(ConditionsApi::class)
override fun <T : BuiltinAnnotation.OnClassRepeatable> getAnnotations(
which: BuiltinAnnotation.Target.OnClassRepeatable<T>
): List<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
* limitations under the License.
*/

@file:OptIn(ConditionsApi::class, VariantApi::class)

package com.yandex.yatagan.lang.rt

import com.yandex.yatagan.Assisted
Expand All @@ -27,7 +25,6 @@ import com.yandex.yatagan.ConditionsApi
import com.yandex.yatagan.IntoList
import com.yandex.yatagan.IntoSet
import com.yandex.yatagan.Module
import com.yandex.yatagan.Provides
import com.yandex.yatagan.ValueOf
import com.yandex.yatagan.VariantApi
import com.yandex.yatagan.lang.BuiltinAnnotation
Expand Down Expand Up @@ -72,6 +69,7 @@ internal class RtModuleAnnotationImpl private constructor(
}
}

@OptIn(ConditionsApi::class)
internal class RtConditionalAnnotationImpl private constructor(
lexicalScope: LexicalScope,
impl: Conditional,
Expand All @@ -98,6 +96,7 @@ internal class RtIntoSetAnnotationImpl(
get() = impl.flatten
}

@OptIn(ConditionsApi::class)
internal class RtConditionExpressionAnnotationImpl private constructor(
lexicalScope: LexicalScope,
impl: ConditionExpression,
Expand Down Expand Up @@ -130,6 +129,7 @@ internal class RtConditionExpressionAnnotationImpl private constructor(
}
}

@OptIn(ConditionsApi::class)
internal class RtValueOfAnnotationImpl private constructor(
lexicalScope: LexicalScope,
impl: ValueOf,
Expand All @@ -142,6 +142,7 @@ internal class RtValueOfAnnotationImpl private constructor(
}
}

@OptIn(VariantApi::class)
internal class RtComponentFlavorAnnotationImpl private constructor(
lexicalScope: LexicalScope,
impl: ComponentFlavor,
Expand Down
Loading

0 comments on commit 4b82b9d

Please sign in to comment.