gradle: improve performance of ast codegen

This commit is contained in:
Alex Zenla 2023-09-20 18:58:05 -07:00
parent 21ff33f776
commit 1a759b9746
Signed by: alex
GPG Key ID: C0780728420EBFE5
3 changed files with 77 additions and 40 deletions

View File

@ -6,10 +6,10 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.StandardOpenOption
import kotlin.io.path.deleteExisting import kotlin.io.path.deleteExisting
import kotlin.io.path.deleteIfExists
import kotlin.io.path.listDirectoryEntries import kotlin.io.path.listDirectoryEntries
import kotlin.io.path.writeText import kotlin.io.path.writeBytes
abstract class AstCodegenShared(val pkg: String, val outputDirectory: Path, val world: AstWorld) { abstract class AstCodegenShared(val pkg: String, val outputDirectory: Path, val world: AstWorld) {
abstract suspend fun generate() abstract suspend fun generate()
@ -21,10 +21,17 @@ abstract class AstCodegenShared(val pkg: String, val outputDirectory: Path, val
} }
protected fun write(fileName: String, writer: KotlinWriter) { protected fun write(fileName: String, writer: KotlinWriter) {
val content = "// GENERATED CODE FROM PORK AST CODEGEN\n$writer" writeWithHeader(fileName, writer.buffer)
}
private fun writeWithHeader(fileName: String, content: CharSequence) {
val textContent = buildString {
append("// GENERATED CODE FROM PORK AST CODEGEN\n")
append(content)
}
val path = outputDirectory.resolve(fileName) val path = outputDirectory.resolve(fileName)
path.deleteIfExists() val bytes = textContent.toByteArray(StandardCharsets.UTF_8)
path.writeText(content, StandardCharsets.UTF_8) path.writeBytes(bytes, StandardOpenOption.CREATE_NEW)
} }
fun runUntilCompletion() { fun runUntilCompletion() {

View File

@ -80,8 +80,8 @@ class AstWorld {
} }
fun read(path: Path): AstWorld { fun read(path: Path): AstWorld {
val astYamlText = path.readText() val astYamlString= path.readText()
val astDescription =Yaml.default.decodeFromString(AstDescription.serializer(), astYamlText) val astDescription = Yaml.default.decodeFromString(AstDescription.serializer(), astYamlString)
return build(astDescription) return build(astDescription)
} }
} }

View File

@ -1,7 +1,7 @@
package gay.pizza.pork.buildext.codegen package gay.pizza.pork.buildext.codegen
class KotlinWriter() { class KotlinWriter() {
private val buffer = StringBuilder() val buffer = StringBuilder()
constructor(writable: Any) : this() { constructor(writable: Any) : this() {
write(writable) write(writable)
@ -48,21 +48,25 @@ class KotlinWriter() {
member.protected -> "protected " member.protected -> "protected "
else -> "" else -> ""
} }
val form = if (member.mutable) "${privacy}var" else "${privacy}val" val form = if (member.mutable) "var" else "val"
if (member.abstract) { append(" ")
appendLine(" abstract $form ${member.name}: ${member.type}") if (member.overridden) {
} else { append("override ")
append(" ")
if (member.overridden) {
append("override ")
}
append("$form ${member.name}: ${member.type}")
if (member.value != null) {
append(" = ")
append(member.value)
}
appendLine()
} }
if (member.abstract) {
append("abstract ")
}
append(privacy)
append(form)
append(" ")
append(member.name)
append(": ")
append(member.type)
if (member.value != null) {
append(" = ")
append(member.value)
}
appendLine()
if (index != members.size - 1) { if (index != members.size - 1) {
appendLine() appendLine()
@ -97,7 +101,8 @@ class KotlinWriter() {
} }
for ((index, entry) in kotlinEnum.entries.withIndex()) { for ((index, entry) in kotlinEnum.entries.withIndex()) {
append(" ${entry.name}") append(" ")
append(entry.name)
if (entry.parameters.isNotEmpty()) { if (entry.parameters.isNotEmpty()) {
append("(") append("(")
append(entry.parameters.joinToString(", ")) append(entry.parameters.joinToString(", "))
@ -131,31 +136,54 @@ class KotlinWriter() {
appendLine("@${annotation}") appendLine("@${annotation}")
} }
append("$classType ${kotlinClass.name}") append(classType)
append(" ")
append(kotlinClass.name)
if (kotlinClass.typeParameters.isNotEmpty()) { if (kotlinClass.typeParameters.isNotEmpty()) {
append("<")
val typeParameters = kotlinClass.typeParameters.joinToString(", ") val typeParameters = kotlinClass.typeParameters.joinToString(", ")
append("<${typeParameters}>") append(typeParameters)
append(">")
} }
val contructedMembers = kotlinClass.members.filter { val constructedMembers = kotlinClass.members.filter {
!it.abstract && !(it.overridden && it.value != null) && !it.notInsideConstructor !it.abstract &&
!(it.overridden && it.value != null) &&
!it.notInsideConstructor
} }
if (contructedMembers.isNotEmpty()) { if (constructedMembers.isNotEmpty()) {
val constructor = contructedMembers.joinToString(", ") { append("(")
val prefix = if (it.overridden) "override " else "" for ((index, constructedMember) in constructedMembers.withIndex()) {
val form = if (it.mutable) "var" else "val" val prefix = if (constructedMember.overridden) "override " else ""
val start = "${prefix}$form ${it.name}: ${it.type}" val form = if (constructedMember.mutable) "var" else "val"
if (it.value != null) { append(prefix)
"$start = ${it.value}" append(form)
} else start append(" ")
append(constructedMember.name)
append(": ")
append(constructedMember.type)
if (constructedMember.value != null) {
append(" = ")
append(constructedMember.value)
}
if (index < constructedMembers.size - 1) {
append(", ")
}
} }
append("(${constructor})") append(")")
} else if (kotlinClass.constructorParameters.isNotEmpty()) { } else if (kotlinClass.constructorParameters.isNotEmpty()) {
val constructor = kotlinClass.constructorParameters.entries.joinToString(", ") { append("(")
"${it.key}: ${it.value}" for ((index, constructorParameter) in kotlinClass.constructorParameters.entries.withIndex()) {
append(constructorParameter.key)
append(": ")
append(constructorParameter.value)
if (index < kotlinClass.constructorParameters.size - 1) {
append(", ")
}
} }
append("(${constructor})") append(")")
} }
if (kotlinClass.inherits.isNotEmpty()) { if (kotlinClass.inherits.isNotEmpty()) {
@ -233,7 +261,9 @@ class KotlinWriter() {
appendLine() appendLine()
for (item in function.body) { for (item in function.body) {
appendLine("$indent $item") append(indent)
append(" ")
appendLine(item)
} }
} }