From 1a759b9746e1e73935104b0a32e0a7f9b1c4120e Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Wed, 20 Sep 2023 18:58:05 -0700 Subject: [PATCH] gradle: improve performance of ast codegen --- .../pork/buildext/ast/AstCodegenShared.kt | 17 +++- .../gay/pizza/pork/buildext/ast/AstWorld.kt | 4 +- .../pork/buildext/codegen/KotlinWriter.kt | 96 ++++++++++++------- 3 files changed, 77 insertions(+), 40 deletions(-) diff --git a/buildext/src/main/kotlin/gay/pizza/pork/buildext/ast/AstCodegenShared.kt b/buildext/src/main/kotlin/gay/pizza/pork/buildext/ast/AstCodegenShared.kt index c42df90..41c6094 100644 --- a/buildext/src/main/kotlin/gay/pizza/pork/buildext/ast/AstCodegenShared.kt +++ b/buildext/src/main/kotlin/gay/pizza/pork/buildext/ast/AstCodegenShared.kt @@ -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() { diff --git a/buildext/src/main/kotlin/gay/pizza/pork/buildext/ast/AstWorld.kt b/buildext/src/main/kotlin/gay/pizza/pork/buildext/ast/AstWorld.kt index b6a4755..c4ce2f9 100644 --- a/buildext/src/main/kotlin/gay/pizza/pork/buildext/ast/AstWorld.kt +++ b/buildext/src/main/kotlin/gay/pizza/pork/buildext/ast/AstWorld.kt @@ -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) } } diff --git a/buildext/src/main/kotlin/gay/pizza/pork/buildext/codegen/KotlinWriter.kt b/buildext/src/main/kotlin/gay/pizza/pork/buildext/codegen/KotlinWriter.kt index beb8043..93c4d53 100644 --- a/buildext/src/main/kotlin/gay/pizza/pork/buildext/codegen/KotlinWriter.kt +++ b/buildext/src/main/kotlin/gay/pizza/pork/buildext/codegen/KotlinWriter.kt @@ -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) } }