Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ fun Appendable.attributePseudoDelegate(request: AttributeRequest) {
emptyLine()
}

fun Appendable.attributeProperty(attribute: AttributeInfo, receiver: String? = null, indent: Int = 1) {
fun Appendable.attributeProperty(
repository: Repository,
attribute: AttributeInfo,
receiver: String? = null,
indent: Int = 1
) {
val attributeName = attribute.name
val request = tagAttributeVar(attribute, receiver, indent)
val request = tagAttributeVar(repository, attribute, receiver, indent)
append("\n")

indent(indent)
Expand All @@ -34,15 +39,15 @@ fun Appendable.attributeProperty(attribute: AttributeInfo, receiver: String? = n
emptyLine()
}

fun Appendable.facade(facade: AttributeFacade) {
fun Appendable.facade(repository: Repository, facade: AttributeFacade) {
val facadeName = facade.name.capitalize() + "Facade"

clazz(Clazz(facadeName, isInterface = true, parents = listOf("Tag"))) {
}

facade.attributes.filter { !isAttributeExcluded(it.name) }.forEach { attribute ->
if (attribute.name.isLowerCase() || attribute.name.lowercase() !in facade.attributeNames) {
attributeProperty(attribute, receiver = facadeName, indent = 0)
attributeProperty(repository, attribute, receiver = facadeName, indent = 0)
}
}
}
Expand Down
41 changes: 21 additions & 20 deletions buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package kotlinx.html.generate
import java.io.*

fun generate(packg: String, todir: String, jsdir: String) {
fillRepository()
val repository = Repository()
fillRepository(repository)
fillKdocRepositoryExtension()

File(todir).mkdirs()
Expand All @@ -21,14 +22,14 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()
emptyLine()

Repository.attributeFacades.values.forEach {
facade(it)
repository.attributeFacades.values.forEach {
facade(repository, it)
emptyLine()
}
}
}

Repository.tags.values.filterIgnored().groupBy { it.name[0] }.entries.forEach { e ->
repository.tags.values.filterIgnored().groupBy { it.name[0] }.entries.forEach { e ->
FileOutputStream("$todir/gen-tags-${e.key}.kt").writer(Charsets.UTF_8).use {
it.with {
packg(packg)
Expand All @@ -43,7 +44,7 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()

e.value.forEach {
tagClass(it, emptySet())
tagClass(repository, it, emptySet())
}
}
}
Expand All @@ -62,7 +63,7 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()
emptyLine()

Repository.tags.values.filterIgnored().forEach {
repository.tags.values.filterIgnored().forEach {
val contentlessTag = it.name.lowercase() in contentlessTags
if (it.possibleChildren.isEmpty() && it.name.lowercase() !in emptyTags && !contentlessTag) {
consumerBuilderShared(it, false)
Expand Down Expand Up @@ -91,7 +92,7 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()
emptyLine()

Repository.tags.values.filterIgnored().forEach {
repository.tags.values.filterIgnored().forEach {
val contentlessTag = it.name.lowercase() in contentlessTags
if (it.possibleChildren.isEmpty() && it.name.lowercase() !in emptyTags && !contentlessTag) {
consumerBuilderJS(it, false)
Expand All @@ -118,7 +119,7 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()
emptyLine()

Repository.attributeFacades.filter { it.value.attributeNames.any { it.startsWith("on") } }.forEach { facade ->
repository.attributeFacades.filter { it.value.attributeNames.any { it.startsWith("on") } }.forEach { facade ->
facade.value.attributes.filter { it.name.startsWith("on") }.forEach {
eventProperty(facade.value.name.capitalize() + "Facade", it)
}
Expand Down Expand Up @@ -147,13 +148,13 @@ fun generate(packg: String, todir: String, jsdir: String) {
}
}

Repository.attributeFacades.values.forEach { facade ->
repository.attributeFacades.values.forEach { facade ->
facade.attributes.filter { it.enumValues.isNotEmpty() }.filter { !isAttributeExcluded(it.name) }.forEach { attribute ->
genEnumAttribute(attribute)
}
}

Repository.tags.values.filterIgnored().forEach { tag ->
repository.tags.values.filterIgnored().forEach { tag ->
tag.attributes.filter { it.enumValues.isNotEmpty() }.filter { !isAttributeExcluded(it.name) }.forEach { attribute ->
genEnumAttribute(attribute)
}
Expand All @@ -173,7 +174,7 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()
emptyLine()

Repository.attributeDelegateRequests.toList().forEach {
repository.attributeDelegateRequests.toList().forEach {
attributePseudoDelegate(it)
}
}
Expand All @@ -192,7 +193,7 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()
emptyLine()

Repository.groupUnions.values.forEach { union ->
repository.groupUnions.values.forEach { union ->
clazz(Clazz(
name = union.name,
isInterface = true,
Expand All @@ -205,8 +206,8 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()
emptyLine()

Repository.groupUnions.values.forEach { union ->
(union.additionalTags + union.ambiguityTags).mapNotNull { Repository.tags[it] }.filterIgnored().forEach { tag ->
repository.groupUnions.values.forEach { union ->
(union.additionalTags + union.ambiguityTags).mapNotNull { repository.tags[it] }.filterIgnored().forEach { tag ->
htmlTagBuilders(union.name, tag)
}

Expand All @@ -228,19 +229,19 @@ fun generate(packg: String, todir: String, jsdir: String) {
emptyLine()
emptyLine()

Repository.tagGroups.values.forEach { group ->
val unions = Repository.unionsByGroups[group.name].orEmpty().map { it.name }
repository.tagGroups.values.forEach { group ->
val unions = repository.unionsByGroups[group.name].orEmpty().map { it.name }

clazz(Clazz(name = group.typeName, parents = unions + "Tag", isPublic = true, isInterface = true)) {
}
emptyLine()
}

Repository.tagGroups.values.forEach { group ->
repository.tagGroups.values.forEach { group ->
val receiver = group.typeName
val unions = Repository.unionsByGroups[group.name].orEmpty()
val unions = repository.unionsByGroups[group.name].orEmpty()

group.tags.mapNotNull { Repository.tags[it] }.filterIgnored().filter { tag -> unions.count { tag.name in it.intersectionTags } == 0 }.forEach {
group.tags.mapNotNull { repository.tags[it] }.filterIgnored().filter { tag -> unions.count { tag.name in it.intersectionTags } == 0 }.forEach {
htmlTagBuilders(receiver, it)
}
}
Expand Down Expand Up @@ -290,5 +291,5 @@ fun generate(packg: String, todir: String, jsdir: String) {
}
}

generateParentInterfaces(todir, packg)
generateParentInterfaces(repository, todir, packg)
}
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package kotlinx.html.generate
import java.util.*
import kotlin.collections.HashMap

object Repository {
class Repository {
val tags = TreeMap<String, TagInfo>()

val attributeDelegateRequests = TreeSet<AttributeRequest> (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package kotlinx.html.generate
import java.io.*
import java.util.*

fun generateParentInterfaces(todir: String, packg: String) {
val allParentIfaces = Repository.tags.values.filterIgnored().map { tag ->
fun generateParentInterfaces(repository: Repository, todir: String, packg: String) {
val allParentIfaces = repository.tags.values.filterIgnored().map { tag ->
val parentAttributeIfaces = tag.attributeGroups.map { it.name.humanize().capitalize() + "Facade" }
val parentElementIfaces = tag.tagGroupNames.map { it.humanize().capitalize() }
val sum = parentAttributeIfaces + parentElementIfaces
Expand Down
10 changes: 5 additions & 5 deletions buildSrc/src/main/kotlin/kotlinx/html/generate/tag-unions.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package kotlinx.html.generate

fun tagUnions() {
val groupings = Repository.groupsByTags.filter { it.value.size > 1 }
fun tagUnions(repository: Repository) {
val groupings = repository.groupsByTags.filter { it.value.size > 1 }
val groups = groupings.values.map { it.map { it.name }.toHashSet() }.distinct().sortedByDescending { it.size }
val allUnions = Repository.groupUnions
val allUnions = repository.groupUnions

// initial pass
groups.forEach { group ->
val name = unionName(group)
val superGroups = groups.filter { it !== group && it.containsAll(group) }
val members = group.toList()
val intersection = members.map { Repository.tagGroups[it]!!.tags.toSet() }.reduce { a, b -> a.intersect(b) }
val intersection = members.map { repository.tagGroups[it]!!.tags.toSet() }.reduce { a, b -> a.intersect(b) }

val union = GroupUnion(members, intersection, emptyList(), emptyList(), superGroups.map(::unionName))
require(union.name == name)
Expand All @@ -31,7 +31,7 @@ fun tagUnions() {

// transpose map
val unionsByGroups = allUnions.values.flatMap { u -> u.members.map { it to u.name } }.groupBy({ it.first }, { allUnions[it.second]!! })
Repository.unionsByGroups = unionsByGroups
repository.unionsByGroups = unionsByGroups
}

fun unionName(members: Iterable<String>) = humanizeJoin(members, "Or")
17 changes: 11 additions & 6 deletions buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package kotlinx.html.generate

import java.util.*

fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set<String>) {
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() }
val allParentIfaces = parentAttributeIfaces + parentElementIfaces
Expand Down Expand Up @@ -48,7 +48,7 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set<String>) {

attributes.filter {!isAttributeExcluded(it.name) }.forEach { attribute ->
if (attribute.name[0].isLowerCase() || attribute.name.lowercase() !in lowerCasedNames) {
attributeProperty(attribute)
attributeProperty(repository, attribute)
}
}

Expand Down Expand Up @@ -126,12 +126,12 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set<String>) {
emptyLine()
}

tag.directChildren.map {Repository.tags[it]}.filterNotNull().filterIgnored().forEach { children ->
tag.directChildren.map {repository.tags[it]}.filterNotNull().filterIgnored().forEach { children ->
htmlTagBuilders(tag.className, children)
}

if (parentElementIfaces.size > 1) {
val commons = tag.tagGroupNames.map {Repository.tagGroups[it]?.tags?.toSet()}.filterNotNull().reduce { a, b -> a.intersect(b) }
val commons = tag.tagGroupNames.map {repository.tagGroups[it]?.tags?.toSet()}.filterNotNull().reduce { a, b -> a.intersect(b) }
if (commons.isNotEmpty()) {
parentElementIfaces.forEach { group ->
variable(Var(name = "as" + group, type = group), receiver = tag.className)
Expand All @@ -146,7 +146,12 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set<String>) {
emptyLine()
}

internal fun Appendable.tagAttributeVar(attribute: AttributeInfo, receiver: String?, indent: Int = 1): AttributeRequest {
internal fun Appendable.tagAttributeVar(
repository: Repository,
attribute: AttributeInfo,
receiver: String?,
indent: Int = 1
): AttributeRequest {
val options = LinkedList<Const<*>>()

if (attribute.type == AttributeType.ENUM) {
Expand All @@ -156,7 +161,7 @@ internal fun Appendable.tagAttributeVar(attribute: AttributeInfo, receiver: Stri
}

val attributeRequest = AttributeRequest(attribute.type, if (attribute.type == AttributeType.ENUM) attribute.enumTypeName else "", options)
Repository.attributeDelegateRequests.add(attributeRequest)
repository.attributeDelegateRequests.add(attributeRequest)

indent(indent)
variable(Var(attribute.fieldName, attribute.typeName, true), receiver = receiver ?: "")
Expand Down
29 changes: 14 additions & 15 deletions buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ fun handleAttributeDeclaration(prefix: String, attributeDeclaration: XSAttribute
.filter { it.name == "enumeration" }
.map { it.value.value }

if (enumEntries.size == 1 && enumEntries.single() == name) {
return if (enumEntries.size == 1 && enumEntries.single() == name) {
// probably ticker
return AttributeInfo(name, AttributeType.TICKER)
AttributeInfo(name, AttributeType.TICKER)
} else if (enumEntries.size == 2 && enumEntries.sorted() == listOf("off", "on")) {
return AttributeInfo(name, AttributeType.BOOLEAN, trueFalse = listOf("on", "off"))
AttributeInfo(name, AttributeType.BOOLEAN, trueFalse = listOf("on", "off"))
} else if (enumEntries.isEmpty()) {
return AttributeInfo(name, AttributeType.STRING)
AttributeInfo(name, AttributeType.STRING)
} else {
return AttributeInfo(name, AttributeType.ENUM, enumValues = enumEntries.toAttributeValues(), enumTypeName = prefix.capitalize() + name.humanize().capitalize())
AttributeInfo(name, AttributeType.ENUM, enumValues = enumEntries.toAttributeValues(), enumTypeName = prefix.capitalize() + name.humanize().capitalize())
}
} else {
return AttributeInfo(name, AttributeType.STRING)
Expand All @@ -72,13 +72,12 @@ fun AttributeInfo.handleSpecialType(tagName: String = ""): AttributeInfo = speci
this.copy(type = type)
} ?: this

fun fillRepository() {
fun fillRepository(repository: Repository) {
val parser = XSOMParser(SAXParserFactory.newInstance())
parser.parse(SCHEME_URL)
val schema = parser.result.getSchema(HTML_NAMESPACE)

@Suppress("UNCHECKED_CAST")
val alreadyIncluded = TreeSet<String>() { a, b -> a.compareTo(b, true) }
val alreadyIncluded = TreeSet<String> { a, b -> a.compareTo(b, true) }
schema.attGroupDecls.values.sortedByDescending { it.attributeUses.size }.forEach { attributeGroup ->
val requiredNames = HashSet<String>()
val facadeAttributes = attributeGroup.attributeUses.map { attributeUse ->
Expand All @@ -95,7 +94,7 @@ fun fillRepository() {
val name = attributeGroup.name

if (facadeAttributes.isNotEmpty()) {
Repository.attributeFacades[name] = AttributeFacade(name, facadeAttributes, requiredNames)
repository.attributeFacades[name] = AttributeFacade(name, facadeAttributes, requiredNames)
alreadyIncluded.addAll(facadeAttributes.map { it.name })
}
}
Expand All @@ -109,9 +108,9 @@ fun fillRepository() {
.map { it.asElementDecl().name }

val group = TagGroup(name, children)
Repository.tagGroups[name] = group
repository.tagGroups[name] = group
children.forEach {
Repository.groupsByTags.getOrPut(it) { ArrayList<TagGroup>() }.add(group)
repository.groupsByTags.getOrPut(it) { ArrayList<TagGroup>() }.add(group)
}
}

Expand All @@ -128,7 +127,7 @@ fun fillRepository() {
if (type.isComplexType) {
val complex = type.asComplexType()
val groupDeclarations = complex.attGroups.flatMap { flattenGroups(it) }.distinct().toList()
val attributeGroups = groupDeclarations.map { Repository.attributeFacades[it.name] }.filterNotNull()
val attributeGroups = groupDeclarations.map { repository.attributeFacades[it.name] }.filterNotNull()

val attributes = complex.declaredAttributeUses.map {
if (it.isRequired) {
Expand All @@ -149,7 +148,7 @@ fun fillRepository() {
}
}

modelGroupNames.addAll(Repository.groupsByTags[name]?.map { it.name }.orEmpty())
modelGroupNames.addAll(repository.groupsByTags[name]?.map { it.name }.orEmpty())

suggestedNames.addAll(attributes.filter { it.type == AttributeType.ENUM }.map { it.name })
suggestedNames.addAll(attributes.filter { it.name in globalSuggestedAttributeNames }.map { it.name })
Expand All @@ -161,10 +160,10 @@ fun fillRepository() {
throw UnsupportedOperationException()
}

Repository.tags[name] = tagInfo
repository.tags[name] = tagInfo
}

tagUnions()
tagUnions(repository)
}

private val xsdToType = mapOf(
Expand Down