init research
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
## :plugins:keywords-generator
|
||||
|
||||
This module holds a little Gradle plugin whose sole purpose is to provide
|
||||
[:core](../../core) with the `generateKeywordsSrc` task.
|
||||
|
||||
This task, generates three enum classes: `HardKeywords`, `ModifierKeywords`, and `SoftKeywords`.
|
||||
These enums together contain all restricted Kotlin keywords to be taken into account when generating our own
|
||||
code in Notebooks or any of our [plugins](..). Words like "package", "fun", "suspend", etc...
|
||||
|
||||
As the Kotlin language can change over time, this task ensures that any changes to the language
|
||||
will be reflected in our code generation.
|
||||
@@ -0,0 +1,28 @@
|
||||
@file:OptIn(ExperimentalBuildToolsApi::class, ExperimentalKotlinGradlePluginApi::class)
|
||||
|
||||
import org.jetbrains.kotlin.buildtools.api.ExperimentalBuildToolsApi
|
||||
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
||||
|
||||
plugins {
|
||||
`java-gradle-plugin`
|
||||
`kotlin-dsl`
|
||||
with(convention.plugins) {
|
||||
alias(kotlinJvm8)
|
||||
alias(buildConfig)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(kotlin("compiler-embeddable", kotlin.compilerVersion.get()))
|
||||
implementation(libs.kotlinpoet)
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("dependencies") {
|
||||
id = "org.jetbrains.dataframe.generator"
|
||||
version = "1.0"
|
||||
implementationClass = "org.jetbrains.dataframe.keywords.KeywordsGeneratorPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
pluginManagement {
|
||||
includeBuild("../../build-settings-logic")
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("dfsettings.catalogs")
|
||||
}
|
||||
|
||||
includeBuild("../../build-logic")
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
package org.jetbrains.dataframe.keywords
|
||||
|
||||
public data class EnumEntry(
|
||||
public val name: String,
|
||||
public val strValue: String
|
||||
)
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package org.jetbrains.dataframe.keywords
|
||||
|
||||
import com.squareup.kotlinpoet.FileSpec
|
||||
import com.squareup.kotlinpoet.FunSpec
|
||||
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
|
||||
import com.squareup.kotlinpoet.PropertySpec
|
||||
import com.squareup.kotlinpoet.TypeSpec
|
||||
import org.gradle.workers.WorkAction
|
||||
import org.gradle.workers.WorkParameters
|
||||
import org.jetbrains.kotlin.com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import java.io.File
|
||||
|
||||
public abstract class KeywordsGeneratorAction : WorkAction<KeywordsGeneratorAction.Parameters> {
|
||||
|
||||
public interface Parameters : WorkParameters {
|
||||
public var srcDir: File
|
||||
}
|
||||
|
||||
private val taskPackageName = "org.jetbrains.kotlinx.dataframe.keywords"
|
||||
|
||||
override fun execute() {
|
||||
println("Generating keywords using Kotlin compiler: ${KotlinCompilerVersion.getVersion()}")
|
||||
parameters.srcDir.deleteRecursively()
|
||||
generateKeywordEnums()
|
||||
}
|
||||
|
||||
private fun generateKeywordEnums() {
|
||||
listOf(
|
||||
"HardKeywords" to KtTokens.KEYWORDS,
|
||||
"SoftKeywords" to KtTokens.SOFT_KEYWORDS,
|
||||
"ModifierKeywords" to KtTokens.MODIFIER_KEYWORDS,
|
||||
).forEach { (name, set) ->
|
||||
generateKeywordsEnum(name, set)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateKeywordsEnum(name: String, tokenSet: TokenSet) {
|
||||
buildKwEnum(name, getKeywords(tokenSet)).writeTo(parameters.srcDir)
|
||||
}
|
||||
|
||||
private fun getKeywords(tokenSet: TokenSet): List<EnumEntry> {
|
||||
fun id(value: String) = value.uppercase().replace("!", "NOT_")
|
||||
|
||||
return tokenSet.types.map { t ->
|
||||
t as KtKeywordToken
|
||||
EnumEntry(id(t.value), t.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildKwEnum(name: String, values: List<EnumEntry>): FileSpec {
|
||||
val fileBuilder = FileSpec.builder(taskPackageName, name)
|
||||
val valList = mutableListOf<String>()
|
||||
|
||||
val enumBuilder = TypeSpec.enumBuilder(name).apply {
|
||||
primaryConstructor(
|
||||
FunSpec.constructorBuilder()
|
||||
.addParameter("value", String::class)
|
||||
.build()
|
||||
)
|
||||
|
||||
values.forEach { entry ->
|
||||
valList.add("\"${entry.strValue}\"")
|
||||
addEnumConstant(
|
||||
entry.name, TypeSpec.anonymousClassBuilder()
|
||||
.addSuperclassConstructorParameter("%S", entry.strValue)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
val compObj = TypeSpec.companionObjectBuilder().addProperty(
|
||||
PropertySpec
|
||||
.builder("VALUES", List::class.parameterizedBy(String::class))
|
||||
.initializer(valList.joinToString(", ", "listOf(", ")"))
|
||||
.build()
|
||||
).build()
|
||||
|
||||
addType(compObj)
|
||||
}
|
||||
|
||||
fileBuilder.addType(enumBuilder.build())
|
||||
|
||||
return fileBuilder.build()
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package org.jetbrains.dataframe.keywords
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.DependencyScopeConfiguration
|
||||
import org.gradle.api.artifacts.ResolvableConfiguration
|
||||
import org.gradle.api.tasks.SourceSet
|
||||
import org.gradle.api.tasks.SourceSetContainer
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import org.jetbrains.kotlinx.dataframe.BuildConfig
|
||||
import java.io.File
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
public abstract class KeywordsGeneratorPlugin : Plugin<Project> {
|
||||
|
||||
override fun apply(target: Project): Unit = with(target) {
|
||||
// from https://kotlinlang.org/docs/whatsnew21.html#compiler-symbols-hidden-from-the-kotlin-gradle-plugin-api
|
||||
val dependencyScopeConfiguration: DependencyScopeConfiguration = configurations.dependencyScope("keywordsGeneratorDependencyScope").get()
|
||||
dependencies.add(dependencyScopeConfiguration.name, "$KOTLIN_COMPILER_EMBEDDABLE:$KOTLIN_COMPILER_VERSION")
|
||||
|
||||
val resolvableConfiguration: ResolvableConfiguration = configurations.resolvable("keywordGeneratorResolvable") {
|
||||
extendsFrom(dependencyScopeConfiguration)
|
||||
}.get()
|
||||
|
||||
val genSrcDir = layout.buildDirectory.asFile.get().resolve("generatedSrc")
|
||||
|
||||
val sourceSets = project.extensions.getByName("sourceSets") as SourceSetContainer
|
||||
val mainSourceSet = sourceSets.named("main").get()
|
||||
mainSourceSet.addDir(genSrcDir)
|
||||
|
||||
val genTask = tasks.register<KeywordsGeneratorTask>(KeywordsGeneratorTask.NAME) {
|
||||
kotlinCompiler.from(resolvableConfiguration)
|
||||
srcDir = genSrcDir
|
||||
}
|
||||
|
||||
tasks["compileKotlin"].dependsOn(genTask)
|
||||
}
|
||||
|
||||
private fun SourceSet.addDir(dir: File) {
|
||||
java.setSrcDirs(java.srcDirs + dir)
|
||||
}
|
||||
|
||||
public companion object {
|
||||
public const val KOTLIN_COMPILER_EMBEDDABLE: String = "org.jetbrains.kotlin:kotlin-compiler-embeddable"
|
||||
public const val KOTLIN_COMPILER_VERSION: String = BuildConfig.KOTLIN_COMPILER_VERSION
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package org.jetbrains.dataframe.keywords
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.file.ConfigurableFileCollection
|
||||
import org.gradle.api.tasks.Classpath
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.submit
|
||||
import org.gradle.workers.WorkerExecutor
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
public abstract class KeywordsGeneratorTask: DefaultTask() {
|
||||
|
||||
@get:Inject
|
||||
public abstract val executor: WorkerExecutor
|
||||
|
||||
@get:Classpath
|
||||
public abstract val kotlinCompiler: ConfigurableFileCollection
|
||||
|
||||
@OutputDirectory
|
||||
public lateinit var srcDir: File
|
||||
|
||||
@Input
|
||||
override fun getGroup(): String = "codegen"
|
||||
|
||||
@TaskAction
|
||||
public fun generate() {
|
||||
val workQueue = executor.classLoaderIsolation {
|
||||
classpath.from(kotlinCompiler)
|
||||
}
|
||||
workQueue.submit(KeywordsGeneratorAction::class) {
|
||||
srcDir = this@KeywordsGeneratorTask.srcDir
|
||||
}
|
||||
}
|
||||
|
||||
public companion object {
|
||||
public const val NAME: String = "generateKeywordsSrc"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user