From 8842b6894ec380029e51b27445ec7480829d5c5d Mon Sep 17 00:00:00 2001 From: Sergey Mashkov Date: Fri, 10 Mar 2017 18:29:43 +0300 Subject: [PATCH] KT-16572 Add links to Mozilla Developer Network to kdocs of classes that we generate from IDL --- libraries/tools/idl2k/src/main/kotlin/main.kt | 38 +++++++++++++++++-- libraries/tools/idl2k/src/main/kotlin/mdn.kt | 38 +++++++++++++++++++ .../tools/idl2k/src/main/kotlin/render.kt | 14 +++++-- 3 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 libraries/tools/idl2k/src/main/kotlin/mdn.kt diff --git a/libraries/tools/idl2k/src/main/kotlin/main.kt b/libraries/tools/idl2k/src/main/kotlin/main.kt index e4ec940856b..7edefc03a0b 100644 --- a/libraries/tools/idl2k/src/main/kotlin/main.kt +++ b/libraries/tools/idl2k/src/main/kotlin/main.kt @@ -1,10 +1,13 @@ package org.jetbrains.idl2k import org.antlr.v4.runtime.ANTLRFileStream -import java.io.File +import java.io.* +import java.net.* import java.util.* +import kotlin.collections.HashSet fun main(args: Array) { + val mdnCacheFile = File("target/mdn-cache.txt") val outDir = File("../../../js/js.libraries/src/generated") val srcDir = File("../../idl") if (!srcDir.exists()) { @@ -26,7 +29,7 @@ fun main(args: Array) { ) } - println("Generating...") + println("Prepare...") val repository = repositoryPre.copy(typeDefs = repositoryPre.typeDefs.mapValues { it.value.copy(mapType(repositoryPre, it.value.types)) }) @@ -46,6 +49,35 @@ fun main(args: Array) { outDir.deleteRecursively() outDir.mkdirs() + println("Processing MDN") + val oldMdnCache = if (mdnCacheFile.canRead()) MDNDocumentationCache.read(mdnCacheFile) else MDNDocumentationCache.Empty + val newMdnCacheExisting = HashSet(oldMdnCache.existing) + val newMdnCacheNonExisting = HashSet(oldMdnCache.nonExisting) + + for (iface in definitions) { + val url = "https://developer.mozilla.org/en/docs/Web/API/${iface.name}" + val addUrl = when (oldMdnCache.checkInCache(url)) { + true -> true + false -> false + else -> try { + val text = URL(url).openStream().reader().use { it.readText() } + text.contains(iface.name, ignoreCase = true) + } catch (ignore: IOException) { + false + } + } + + if (addUrl) + newMdnCacheExisting.add(url) + else + newMdnCacheNonExisting.add(url) + } + + val mdnCache = MDNDocumentationCache(newMdnCacheExisting, newMdnCacheNonExisting) + MDNDocumentationCache.writeTo(mdnCache, mdnCacheFile) + + println("Generating...") + allPackages.forEach { pkg -> File(outDir, pkg + ".kt").bufferedWriter().use { w -> println("Generating for package $pkg...") @@ -68,7 +100,7 @@ fun main(args: Array) { } w.appendln() - w.render(pkg, definitions, unions, repository.enums.values.toList()) + w.render(pkg, definitions, unions, repository.enums.values.toList(), mdnCache) } } } diff --git a/libraries/tools/idl2k/src/main/kotlin/mdn.kt b/libraries/tools/idl2k/src/main/kotlin/mdn.kt new file mode 100644 index 00000000000..59ca51d19ae --- /dev/null +++ b/libraries/tools/idl2k/src/main/kotlin/mdn.kt @@ -0,0 +1,38 @@ +package org.jetbrains.idl2k + +import java.io.* + +class MDNDocumentationCache(val existing: Set, val nonExisting: Set) { + + fun checkInCache(url: String): Boolean? = when (url) { + in existing -> true + in nonExisting -> false + else -> null + } + + companion object { + val Empty = MDNDocumentationCache(emptySet(), emptySet()) + + fun read(file: File): MDNDocumentationCache { + val existing = HashSet() + val nonExisting = HashSet() + + file.forEachLine { line -> + val parts = line.split("|") + if (parts.size == 2) { + val url = parts[0] + if (parts[1] == "Y") existing.add(url) + else if (parts[1] == "N") nonExisting.add(url) + } + } + + return MDNDocumentationCache(existing, nonExisting) + } + + fun writeTo(c: MDNDocumentationCache, file: File) { + file.bufferedWriter().use { + (c.existing + c.nonExisting).sorted().joinTo(it, separator = "\n") { "$it|${if (it in c.existing) "Y" else "N"}" } + } + } + } +} \ No newline at end of file diff --git a/libraries/tools/idl2k/src/main/kotlin/render.kt b/libraries/tools/idl2k/src/main/kotlin/render.kt index c17f46df90c..58bcefdde36 100644 --- a/libraries/tools/idl2k/src/main/kotlin/render.kt +++ b/libraries/tools/idl2k/src/main/kotlin/render.kt @@ -17,6 +17,7 @@ package org.jetbrains.idl2k import org.jetbrains.idl2k.util.mapEnumConstant +import java.io.* import java.math.BigInteger private fun O.indent(commented: Boolean = false, level: Int) { @@ -146,7 +147,14 @@ private fun GenerateFunction.isCommented(parent: String) = private fun GenerateAttribute.isRequiredFunctionArgument(owner: String, functionName: String) = "$owner.$functionName.$name" in requiredArguments private fun GenerateFunction.fixRequiredArguments(parent: String) = copy(arguments = arguments.map { arg -> arg.copy(initializer = if (arg.isRequiredFunctionArgument(parent, name)) null else arg.initializer) }) -fun Appendable.render(allTypes: Map, enums: List, typeNamesToUnions: Map>, iface: GenerateTraitOrClass, markerAnnotation: Boolean = false) { +fun Appendable.render(allTypes: Map, enums: List, typeNamesToUnions: Map>, iface: GenerateTraitOrClass, markerAnnotation: Boolean = false, mdnCache: MDNDocumentationCache? = null) { + val url = "https://developer.mozilla.org/en/docs/Web/API/${iface.name}" + if (mdnCache?.checkInCache(url) == true) { + appendln("/**") + appendln(" * Exposes the JavaScript [${iface.name}]($url) to Kotlin") + appendln(" */") + } + val allTypesAndEnums = allTypes.keys + enums.map { it.name } append("public external ") @@ -374,12 +382,12 @@ fun Appendable.render(enumDefinition: EnumDefinition) { appendln() } -fun Appendable.render(namespace: String, ifaces: List, unions: GenerateUnionTypes, enums: List) { +fun Appendable.render(namespace: String, ifaces: List, unions: GenerateUnionTypes, enums: List, mdnCache: MDNDocumentationCache) { val declaredTypes = ifaces.associateBy { it.name } val allTypes = declaredTypes + unions.anonymousUnionsMap + unions.typedefsMarkersMap declaredTypes.values.filter { it.namespace == namespace }.forEach { - render(allTypes, enums, unions.typeNamesToUnionsMap, it) + render(allTypes, enums, unions.typeNamesToUnionsMap, it, mdnCache = mdnCache) } unions.anonymousUnionsMap.values.filter { it.namespace == "" || it.namespace == namespace }.forEach {