Skip to content

Commit

Permalink
Cleaning up code
Browse files Browse the repository at this point in the history
  • Loading branch information
severn-everett committed Mar 21, 2024
1 parent 8b32285 commit 6621007
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 93 deletions.
50 changes: 17 additions & 33 deletions buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,7 @@ fun generate(pkg: String, todir: String, jsdir: String, wasmJsDir: String) {

repository.tags.values.filterIgnored().groupBy { it.name[0] }.entries.forEach { e ->
writeIntoFile("$todir/gen-tags-${e.key}.kt") {
packg(pkg)
emptyLine()
contractImports()
import("kotlinx.html.*")
import("kotlinx.html.impl.*")
import("kotlinx.html.attributes.*")
emptyLine()

doNotEditWarning()
emptyLine()
emptyLine()
fullImportsHeader(pkg)

e.value.forEach {
tagClass(repository, it, emptySet())
Expand Down Expand Up @@ -125,17 +115,7 @@ fun generate(pkg: String, todir: String, jsdir: String, wasmJsDir: String) {

FileOutputStream("$todir/gen-tag-unions.kt").writer(Charsets.UTF_8).use {
with(it) {
packg(pkg)
emptyLine()
contractImports()
import("kotlinx.html.*")
import("kotlinx.html.impl.*")
import("kotlinx.html.attributes.*")
emptyLine()

doNotEditWarning()
emptyLine()
emptyLine()
fullImportsHeader(pkg)

repository.groupUnions.values.forEach { union ->
clazz(
Expand Down Expand Up @@ -165,17 +145,7 @@ fun generate(pkg: String, todir: String, jsdir: String, wasmJsDir: String) {

FileOutputStream("$todir/gen-tag-groups.kt").writer(Charsets.UTF_8).use {
with(it) {
packg(pkg)
emptyLine()
contractImports()
import("kotlinx.html.*")
import("kotlinx.html.impl.*")
import("kotlinx.html.attributes.*")
emptyLine()

doNotEditWarning()
emptyLine()
emptyLine()
fullImportsHeader(pkg)

repository.tagGroups.values.forEach { group ->
val unions = repository.unionsByGroups[group.name].orEmpty().map { it.name }
Expand Down Expand Up @@ -384,6 +354,20 @@ private fun Appendable.writeKotlinPoet(builder: FileSpec.Builder.() -> Unit) {
.writeTo(this)
}

private fun Appendable.fullImportsHeader(pkg: String) {
packg(pkg)
emptyLine()
contractImports()
import("kotlinx.html.*")
import("kotlinx.html.impl.*")
import("kotlinx.html.attributes.*")
emptyLine()

doNotEditWarning()
emptyLine()
emptyLine()
}

private fun Appendable.contractImports() {
import("kotlin.contracts.ExperimentalContracts")
import("kotlin.contracts.InvocationKind")
Expand Down
129 changes: 69 additions & 60 deletions buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import com.squareup.kotlinpoet.TypeVariableName
import com.squareup.kotlinpoet.asTypeName
import java.util.*

private const val BLOCK_LAMBDA = "block"
private const val CONTENT_LAMBDA = "{+content}"

fun Appendable.tagClass(repository: Repository, tag: TagInfo, excludeAttributes: Set<String>) {
val parentAttributeIfaces = tag.attributeGroups.map { it.name.capitalize() + "Facade" }
val parentElementIfaces = tag.tagGroupNames.map { it.humanize().capitalize() }
Expand All @@ -21,24 +24,39 @@ fun Appendable.tagClass(repository: Repository, tag: TagInfo, excludeAttributes:
val namespace = tagNamespaces[tag.name.lowercase()]
val customizableNamespace = tag.name.lowercase() in tagsWithCustomizableNamespace

val parameters = mutableListOf(
Var("initialAttributes", "Map<String, String>", false, false, true),
Var("consumer", "TagConsumer<*>", false, true)
)
val superConstructorArguments = mutableListOf(
val parameters = buildList {
add(
Var(
name = "initialAttributes",
type = "Map<String, String>",
mutable = false,
override = false,
forceOmitValVar = true
)
)
add(Var(name = "consumer", type = "TagConsumer<*>", mutable = false, override = true))
if (customizableNamespace) {
add(
Var(
name = "namespace",
type = "String?",
mutable = false,
override = false,
forceOmitValVar = true,
defaultValue = namespace?.quote() ?: "null"
)
)
}
}
val superConstructorArguments = listOf(
tag.name.quote(),
"consumer",
"initialAttributes",
namespace?.quote().toString(),
if (customizableNamespace) "namespace" else namespace?.quote().toString(),
(tag.name in inlineTags).toString(),
(tag.name in emptyTags).toString()
)

if (customizableNamespace) {
parameters.add(Var("namespace", "String?", false, false, true, namespace?.quote() ?: "null"))
superConstructorArguments[3] = "namespace"
}

appendLine("@Suppress(\"unused\")")
clazz(Clazz(
name = tag.className,
Expand Down Expand Up @@ -141,7 +159,7 @@ fun Appendable.tagClass(repository: Repository, tag: TagInfo, excludeAttributes:
}

if (parentElementIfaces.size > 1) {
val commons = tag.tagGroupNames.map { repository.tagGroups[it]?.tags?.toSet() }.filterNotNull()
val commons = tag.tagGroupNames.mapNotNull { repository.tagGroups[it]?.tags?.toSet() }
.reduce { a, b -> a.intersect(b) }
if (commons.isNotEmpty()) {
parentElementIfaces.forEach { group ->
Expand Down Expand Up @@ -183,8 +201,6 @@ internal fun Appendable.tagAttributeVar(
return attributeRequest
}

fun probeType(htmlClassName: String): Boolean = htmlClassName in knownTagClasses

private fun tagCandidates(tag: TagInfo) = (listOf(tag.memberName) + tagReplacements.map {
tag.memberName.replace(
it.first.toRegex(),
Expand All @@ -195,13 +211,7 @@ private fun tagCandidates(tag: TagInfo) = (listOf(tag.memberName) + tagReplaceme
fun getTagResultClass(tag: TagInfo): String? =
tagCandidates(tag)
.map { "HTML${it}Element" }
.firstOrNull { probeType(it) }

fun contentArgumentValue(tag: TagInfo, blockOrContent: Boolean) = when {
tag.name.lowercase() in emptyTags -> "block"
blockOrContent -> "block"
else -> "{+content}"
}
.firstOrNull { it in knownTagClasses }

fun tagConsumerJs(parameter: String): TypeName =
ClassName("kotlinx.html", "TagConsumer")
Expand Down Expand Up @@ -267,15 +277,15 @@ fun consumerBuilderJsPoet(
"""
|contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|return %T(${constructorArgs.joinToString(", ")})
| .visitAndFinalize(this, ${contentArgumentValue(tag, blockOrContent)}) $cast
| .visitAndFinalize(this, $BLOCK_LAMBDA) $cast
""".trimMargin(),
tagClass,
)
} else {
addCode(
"""
|return %T(${constructorArgs.joinToString(", ")})
| .visitAndFinalize(this, ${contentArgumentValue(tag, blockOrContent)}) $cast
| .visitAndFinalize(this, $CONTENT_LAMBDA) $cast
""".trimMargin(),
tagClass,
)
Expand Down Expand Up @@ -323,15 +333,15 @@ fun consumerBuilderSharedPoet(
"""
|contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|return %T(${constructorArgs.joinToString(", ")})
| .visitAndFinalize(this, ${contentArgumentValue(tag, blockOrContent)})
| .visitAndFinalize(this, $BLOCK_LAMBDA)
""".trimMargin(),
tagClass,
)
} else {
addCode(
"""
|return %T(${constructorArgs.joinToString(", ")})
| .visitAndFinalize(this, ${contentArgumentValue(tag, blockOrContent)})
| .visitAndFinalize(this, $CONTENT_LAMBDA)
""".trimMargin(),
tagClass,
)
Expand Down Expand Up @@ -363,23 +373,7 @@ fun Appendable.htmlTagBuilderMethod(receiver: String, tag: TagInfo, blockOrConte
append("inline ")
}
function(tag.memberName, arguments, "Unit", receiver = receiver)
if (tagBuilderCouldBeInline) {
block {
indent()
appendLine("contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }")
indent()
functionCall(tag.className, constructorArgs)
append(".")
functionCall("visit", listOf(contentArgumentValue(tag, blockOrContent)))
appendLine()
}
} else {
defineIs(buildString {
functionCall(tag.className, constructorArgs)
append(".")
functionCall("visit", listOf(contentArgumentValue(tag, blockOrContent)))
})
}
tagBody(tagBuilderCouldBeInline, tag, constructorArgs)
}

fun Appendable.htmlTagEnumBuilderMethod(
Expand Down Expand Up @@ -421,23 +415,7 @@ fun Appendable.htmlTagEnumBuilderMethod(
append("inline ")
}
function(enumValue.fieldName + tag.memberName.capitalize(), arguments, "Unit", receiver = receiver)
if (tagBuilderCouldBeInline) {
block {
indent()
appendLine("contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }")
indent()
functionCall(tag.className, constructorArgs)
append(".")
functionCall("visit", listOf(contentArgumentValue(tag, blockOrContent)))
appendLine()
}
} else {
defineIs(buildString {
functionCall(tag.className, constructorArgs)
append(".")
functionCall("visit", listOf(contentArgumentValue(tag, blockOrContent)))
})
}
tagBody(tagBuilderCouldBeInline, tag, constructorArgs)
}
}

Expand Down Expand Up @@ -542,7 +520,16 @@ private fun tagBuilderFunctionArguments(tag: TagInfo, blockOrContent: Boolean):

fun addNamespaceParameter() {
if (customizableNamespace) {
arguments.add(Var("namespace", "String?", false, false, true, defaultNamespace))
arguments.add(
Var(
name = "namespace",
type = "String?",
mutable = false,
override = false,
forceOmitValVar = true,
defaultValue = defaultNamespace
)
)
}
}

Expand Down Expand Up @@ -584,6 +571,28 @@ private fun Appendable.tagKdoc(tag: TagInfo) {
appendLine(" */")
}

private fun Appendable.tagBody(tagBuilderCouldBeInline: Boolean, tag: TagInfo, constructorArgs: List<String>) {
if (tagBuilderCouldBeInline) {
block {
indent()
appendLine("contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }")
indent()
functionCall(tag.className, constructorArgs)
append(".")
functionCall("visit", listOf(BLOCK_LAMBDA))
appendLine()
}
} else {
defineIs(
buildString {
functionCall(tag.className, constructorArgs)
append(".")
functionCall("visit", listOf(CONTENT_LAMBDA))
}
)
}
}

private val inlineTags = """a
abbr
acronym
Expand Down

0 comments on commit 6621007

Please sign in to comment.