diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt index 48e42873..07ab8462 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt @@ -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) @@ -34,7 +39,7 @@ 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"))) { @@ -42,7 +47,7 @@ fun Appendable.facade(facade: AttributeFacade) { 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) } } } diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt index 3243f49c..bb95c635 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt @@ -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() @@ -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) @@ -43,7 +44,7 @@ fun generate(packg: String, todir: String, jsdir: String) { emptyLine() e.value.forEach { - tagClass(it, emptySet()) + tagClass(repository, it, emptySet()) } } } @@ -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) @@ -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) @@ -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) } @@ -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) } @@ -173,7 +174,7 @@ fun generate(packg: String, todir: String, jsdir: String) { emptyLine() emptyLine() - Repository.attributeDelegateRequests.toList().forEach { + repository.attributeDelegateRequests.toList().forEach { attributePseudoDelegate(it) } } @@ -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, @@ -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) } @@ -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) } } @@ -290,5 +291,5 @@ fun generate(packg: String, todir: String, jsdir: String) { } } - generateParentInterfaces(todir, packg) + generateParentInterfaces(repository, todir, packg) } diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt index f240c81e..11c17529 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt @@ -3,7 +3,7 @@ package kotlinx.html.generate import java.util.* import kotlin.collections.HashMap -object Repository { +class Repository { val tags = TreeMap() val attributeDelegateRequests = TreeSet ( diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/parent-ifaces-gen.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/parent-ifaces-gen.kt index be361d11..d50d9b9a 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/parent-ifaces-gen.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/parent-ifaces-gen.kt @@ -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 diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-unions.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-unions.kt index 9dc29273..82519433 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-unions.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-unions.kt @@ -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) @@ -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) = humanizeJoin(members, "Or") diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt index 1bdca4a1..b87f88e6 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt @@ -2,7 +2,7 @@ package kotlinx.html.generate import java.util.* -fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { +fun Appendable.tagClass(repository: Repository, tag: TagInfo, excludeAttributes : Set) { val parentAttributeIfaces = tag.attributeGroups.map {it.name.capitalize() + "Facade"} val parentElementIfaces = tag.tagGroupNames.map { it.humanize().capitalize() } val allParentIfaces = parentAttributeIfaces + parentElementIfaces @@ -48,7 +48,7 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { attributes.filter {!isAttributeExcluded(it.name) }.forEach { attribute -> if (attribute.name[0].isLowerCase() || attribute.name.lowercase() !in lowerCasedNames) { - attributeProperty(attribute) + attributeProperty(repository, attribute) } } @@ -126,12 +126,12 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { 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) @@ -146,7 +146,12 @@ fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { 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>() if (attribute.type == AttributeType.ENUM) { @@ -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 ?: "") diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt index 0f3e1fb3..c4e3544c 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt @@ -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) @@ -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() { a, b -> a.compareTo(b, true) } + val alreadyIncluded = TreeSet { a, b -> a.compareTo(b, true) } schema.attGroupDecls.values.sortedByDescending { it.attributeUses.size }.forEach { attributeGroup -> val requiredNames = HashSet() val facadeAttributes = attributeGroup.attributeUses.map { attributeUse -> @@ -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 }) } } @@ -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() }.add(group) + repository.groupsByTags.getOrPut(it) { ArrayList() }.add(group) } } @@ -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) { @@ -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 }) @@ -161,10 +160,10 @@ fun fillRepository() { throw UnsupportedOperationException() } - Repository.tags[name] = tagInfo + repository.tags[name] = tagInfo } - tagUnions() + tagUnions(repository) } private val xsdToType = mapOf(