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 java.nio.charset.StandardCharsets
import java.nio.file.Path
import java.nio.file.StandardOpenOption
import kotlin.io.path.deleteExisting
import kotlin.io.path.deleteIfExists
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 suspend fun generate()
@ -21,10 +21,17 @@ abstract class AstCodegenShared(val pkg: String, val outputDirectory: Path, val
}
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)
path.deleteIfExists()
path.writeText(content, StandardCharsets.UTF_8)
val bytes = textContent.toByteArray(StandardCharsets.UTF_8)
path.writeBytes(bytes, StandardOpenOption.CREATE_NEW)
}
fun runUntilCompletion() {

View File

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

View File

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