diff options
author | Roman Elizarov <elizarov@gmail.com> | 2019-08-27 14:21:00 +0300 |
---|---|---|
committer | Roman Elizarov <elizarov@gmail.com> | 2019-08-27 17:55:38 +0300 |
commit | 071f53658c7bb79e67d3c516dcc4ac1c8cdda6b4 (patch) | |
tree | 316c9e4006d3cdaae44ac958590af626d342956a | |
parent | e95d808cfd7953ccd7f14b70c654ae47c9afaf66 (diff) | |
download | kotlinx.coroutines-071f53658c7bb79e67d3c516dcc4ac1c8cdda6b4.tar.gz |
Update top-level README with links:
* All API references are converted to links via knit
* Knit support short names to external extensions (like [Promise.await])
* Added Flow reference to the readme
Fixes #1468
-rw-r--r-- | README.md | 120 | ||||
-rw-r--r-- | knit/src/Knit.kt | 26 |
2 files changed, 113 insertions, 33 deletions
@@ -22,34 +22,36 @@ suspend fun main() = coroutineScope { ## Modules * [core](kotlinx-coroutines-core/README.md) — common coroutines across all platforms: - * `launch` and `async` coroutine builders; - * `Job` and `Deferred` light-weight future with cancellation support; - * `MainScope` for Android and UI applications. - * `Dispatchers` object with `Main` dispatcher for Android/Swing/JavaFx, and `Default` dispatcher for background coroutines; - * `delay` and `yield` top-level suspending functions; - * `Channel` and `Mutex` communication and synchronization primitives; - * `coroutineScope` and `supervisorScope` scope builders; - * `SupervisorJob` and `CoroutineExceptionHandler` for supervision of coroutines hierarchies; - * `select` expression support and more. + * [launch] and [async] coroutine builders returning [Job] and [Deferred] light-weight futures with cancellation support; + * [Dispatchers] object with [Main][Dispatchers.Main] dispatcher for Android/Swing/JavaFx, and [Default][Dispatchers.Default] dispatcher for background coroutines; + * [delay] and [yield] top-level suspending functions; + * [Flow] — cold asynchronous stream with [flow][_flow] builder and comprehensive operator set ([filter], [map], etc); + * [Channel], [Mutex], and [Semaphore] communication and synchronization primitives; + * [coroutineScope], [supervisorScope], [withContext], and [withTimeout] scope builders; + * [MainScope()] for Android and UI applications; + * [SupervisorJob()] and [CoroutineExceptionHandler] for supervision of coroutines hierarchies; + * [select] expression support and more. * [core/jvm](kotlinx-coroutines-core/jvm/) — additional core features available on Kotlin/JVM: - * `Dispatchers.IO` dispatcher for blocking coroutines; - * `Executor.asCoroutineDispatcher()` extension, custom thread pools, and more. + * [Dispatchers.IO] dispatcher for blocking coroutines; + * [Executor.asCoroutineDispatcher] extension, custom thread pools, and more. * [core/js](kotlinx-coroutines-core/js/) — additional core features available on Kotlin/JS: - * Integration with `Promise`; - * Integration with `Window`. -* [test](kotlinx-coroutines-test/README.md) — test utilities for coroutines - * `Dispatchers.setMain` to override `Dispatchers.Main` in tests. - * `TestCoroutineScope` to test suspending functions and coroutines. -* [debug](kotlinx-coroutines-debug/README.md) — debug utilities for coroutines. - * `DebugProbes` API to probe, keep track of, print and dump active coroutines. - * `CoroutinesTimeout` test rule to automatically dump coroutines on test timeout. + * Integration with `Promise` via [Promise.await] and [promise] builder; + * Integration with `Window` via [Window.asCoroutineDispatcher], etc. +* [test](kotlinx-coroutines-test/README.md) — test utilities for coroutines: + * [Dispatchers.setMain] to override [Dispatchers.Main] in tests; + * [TestCoroutineScope] to test suspending functions and coroutines. +* [debug](kotlinx-coroutines-debug/README.md) — debug utilities for coroutines: + * [DebugProbes] API to probe, keep track of, print and dump active coroutines; + * [CoroutinesTimeout] test rule to automatically dump coroutines on test timeout. * [reactive](reactive/README.md) — modules that provide builders and iteration support for various reactive streams libraries: - * Reactive Streams, RxJava 2.x, and Project Reactor. + * Reactive Streams ([Publisher.collect], [Publisher.awaitSingle], [publish], etc), + RxJava 2.x ([rxFlowable], [rxSingle], etc), and + Project Reactor ([flux], [mono], etc). * [ui](ui/README.md) — modules that provide coroutine dispatchers for various single-threaded UI libraries: * Android, JavaFX, and Swing. -* [integration](integration/README.md) — modules that provide integration with various asynchronous callback- and future-based libraries. - * JDK8 `CompletableFuture`, Guava `ListenableFuture`, and Google Play Services `Task`; - * SLF4J MDC integration via `MDCContext`. +* [integration](integration/README.md) — modules that provide integration with various asynchronous callback- and future-based libraries: + * JDK8 [CompletionStage.await], Guava [ListenableFuture.await], and Google Play Services [Task.await]; + * SLF4J MDC integration via [MDCContext]. ## Documentation @@ -156,7 +158,7 @@ module as dependency when using `kotlinx.coroutines` on Android: implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0' ``` -This gives you access to Android [Dispatchers.Main](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-android/kotlinx.coroutines.android/kotlinx.coroutines.-dispatchers/index.html) +This gives you access to Android [Dispatchers.Main] coroutine dispatcher and also makes sure that in case of crashed coroutine with unhandled exception this exception is logged before crashing Android application, similarly to the way uncaught exceptions in threads are handled by Android runtime. @@ -217,3 +219,73 @@ The `develop` branch is pushed to `master` during release. * Full release procedure checklist is [here](RELEASE.md). * Steps for contributing new integration modules are explained [here](integration/README.md#Contributing). +<!--- MODULE kotlinx-coroutines-core --> +<!--- INDEX kotlinx.coroutines --> +[launch]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/launch.html +[async]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/async.html +[Job]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/index.html +[Deferred]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-deferred/index.html +[Dispatchers]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/index.html +[Dispatchers.Main]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-main.html +[Dispatchers.Default]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-default.html +[delay]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/delay.html +[yield]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/yield.html +[coroutineScope]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/coroutine-scope.html +[supervisorScope]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/supervisor-scope.html +[withContext]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/with-context.html +[withTimeout]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/with-timeout.html +[MainScope()]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-main-scope.html +[SupervisorJob()]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-supervisor-job.html +[CoroutineExceptionHandler]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-exception-handler/index.html +[Dispatchers.IO]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-i-o.html +[Executor.asCoroutineDispatcher]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/java.util.concurrent.-executor/as-coroutine-dispatcher.html +[Promise.await]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/kotlin.js.-promise/await.html +[promise]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/promise.html +[Window.asCoroutineDispatcher]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/org.w3c.dom.-window/as-coroutine-dispatcher.html +<!--- INDEX kotlinx.coroutines.flow --> +[Flow]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/index.html +[_flow]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/flow.html +[filter]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/filter.html +[map]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/map.html +<!--- INDEX kotlinx.coroutines.channels --> +[Channel]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.channels/-channel/index.html +<!--- INDEX kotlinx.coroutines.selects --> +[select]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.selects/select.html +<!--- INDEX kotlinx.coroutines.sync --> +[Mutex]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-mutex/index.html +[Semaphore]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.sync/-semaphore/index.html +<!--- MODULE kotlinx-coroutines-test --> +<!--- INDEX kotlinx.coroutines.test --> +[Dispatchers.setMain]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/kotlinx.coroutines.-dispatchers/set-main.html +[TestCoroutineScope]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/kotlinx.coroutines.test/-test-coroutine-scope/index.html +<!--- MODULE kotlinx-coroutines-debug --> +<!--- INDEX kotlinx.coroutines.debug --> +[DebugProbes]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-debug/kotlinx.coroutines.debug/-debug-probes/index.html +<!--- INDEX kotlinx.coroutines.debug.junit4 --> +[CoroutinesTimeout]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-debug/kotlinx.coroutines.debug.junit4/-coroutines-timeout/index.html +<!--- MODULE kotlinx-coroutines-slf4j --> +<!--- INDEX kotlinx.coroutines.slf4j --> +[MDCContext]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-slf4j/kotlinx.coroutines.slf4j/-m-d-c-context/index.html +<!--- MODULE kotlinx-coroutines-jdk8 --> +<!--- INDEX kotlinx.coroutines.future --> +[CompletionStage.await]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-jdk8/kotlinx.coroutines.future/java.util.concurrent.-completion-stage/await.html +<!--- MODULE kotlinx-coroutines-guava --> +<!--- INDEX kotlinx.coroutines.guava --> +[ListenableFuture.await]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-guava/kotlinx.coroutines.guava/com.google.common.util.concurrent.-listenable-future/await.html +<!--- MODULE kotlinx-coroutines-play-services --> +<!--- INDEX kotlinx.coroutines.tasks --> +[Task.await]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-play-services/kotlinx.coroutines.tasks/com.google.android.gms.tasks.-task/await.html +<!--- MODULE kotlinx-coroutines-reactive --> +<!--- INDEX kotlinx.coroutines.reactive --> +[Publisher.collect]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/org.reactivestreams.-publisher/collect.html +[Publisher.awaitSingle]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/org.reactivestreams.-publisher/await-single.html +[publish]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactive/kotlinx.coroutines.reactive/publish.html +<!--- MODULE kotlinx-coroutines-rx2 --> +<!--- INDEX kotlinx.coroutines.rx2 --> +[rxFlowable]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-rx2/kotlinx.coroutines.rx2/rx-flowable.html +[rxSingle]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-rx2/kotlinx.coroutines.rx2/rx-single.html +<!--- MODULE kotlinx-coroutines-reactor --> +<!--- INDEX kotlinx.coroutines.reactor --> +[flux]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactor/kotlinx.coroutines.reactor/flux.html +[mono]: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-reactor/kotlinx.coroutines.reactor/mono.html +<!--- END --> diff --git a/knit/src/Knit.kt b/knit/src/Knit.kt index d3e0a358..30dd678f 100644 --- a/knit/src/Knit.kt +++ b/knit/src/Knit.kt @@ -505,7 +505,7 @@ data class ApiIndexKey( val apiIndexCache: MutableMap<ApiIndexKey, Map<String, List<String>>> = HashMap() -val REF_LINE_REGEX = Regex("<a href=\"([a-z_/.\\-]+)\">([a-zA-z.]+)</a>") +val REF_LINE_REGEX = Regex("<a href=\"([a-z0-9_/.\\-]+)\">([a-zA-z0-9.]+)</a>") val INDEX_HTML = "/index.html" val INDEX_MD = "/index.md" val FUNCTIONS_SECTION_HEADER = "### Functions" @@ -526,33 +526,41 @@ fun loadApiIndex( pkg: String, namePrefix: String = "" ): Map<String, MutableList<String>>? { - val fileName = docsRoot + "/" + path + INDEX_MD + val fileName = "$docsRoot/$path$INDEX_MD" val visited = mutableSetOf<String>() val map = HashMap<String, MutableList<String>>() var inFunctionsSection = false - File(fileName).withLineNumberReader<LineNumberReader>(::LineNumberReader) { + File(fileName).withLineNumberReader(::LineNumberReader) { while (true) { val line = readLine() ?: break if (line == FUNCTIONS_SECTION_HEADER) inFunctionsSection = true val result = REF_LINE_REGEX.matchEntire(line) ?: continue val link = result.groups[1]!!.value if (link.startsWith("..")) continue // ignore cross-references - val absLink = path + "/" + link + val absLink = "$path/$link" var name = result.groups[2]!!.value // a special disambiguation fix for pseudo-constructor functions if (inFunctionsSection && name[0] in 'A'..'Z') name += "()" val refName = namePrefix + name - val fqName = pkg + "." + refName - // Put short names for extensions on 3rd party classes (prefix is FQname of those classes) - if (namePrefix != "" && namePrefix[0] in 'a'..'z') map.putUnambiguous(name, absLink) + val fqName = "$pkg.$refName" + // Put shorter names for extensions on 3rd party classes (prefix is FQname of those classes) + if (namePrefix != "" && namePrefix[0] in 'a'..'z') { + val i = namePrefix.dropLast(1).lastIndexOf('.') + if (i >= 0) map.putUnambiguous(namePrefix.substring(i + 1) + name, absLink) + map.putUnambiguous(name, absLink) + } + // Disambiguate lower-case names with leading underscore (e.g. Flow class vs flow builder ambiguity) + if (namePrefix == "" && name[0] in 'a'..'z') { + map.putUnambiguous("_$name", absLink) + } // Always put fully qualified names map.putUnambiguous(refName, absLink) map.putUnambiguous(fqName, absLink) if (link.endsWith(INDEX_HTML)) { if (visited.add(link)) { val path2 = path + "/" + link.substring(0, link.length - INDEX_HTML.length) - map += loadApiIndex(docsRoot, path2, pkg, refName + ".") - ?: throw IllegalArgumentException("Failed to parse ${docsRoot + "/" + path2}") + map += loadApiIndex(docsRoot, path2, pkg, "$refName.") + ?: throw IllegalArgumentException("Failed to parse $docsRoot/$path2") } } } |