aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Elizarov <elizarov@gmail.com>2019-08-27 14:21:00 +0300
committerRoman Elizarov <elizarov@gmail.com>2019-08-27 17:55:38 +0300
commit071f53658c7bb79e67d3c516dcc4ac1c8cdda6b4 (patch)
tree316c9e4006d3cdaae44ac958590af626d342956a
parente95d808cfd7953ccd7f14b70c654ae47c9afaf66 (diff)
downloadkotlinx.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.md120
-rw-r--r--knit/src/Knit.kt26
2 files changed, 113 insertions, 33 deletions
diff --git a/README.md b/README.md
index 4a522203..bc58ab7a 100644
--- a/README.md
+++ b/README.md
@@ -22,34 +22,36 @@ suspend fun main() = coroutineScope {
## Modules
* [core](kotlinx-coroutines-core/README.md) &mdash; 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] &mdash; 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/) &mdash; 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/) &mdash; additional core features available on Kotlin/JS:
- * Integration with `Promise`;
- * Integration with `Window`.
-* [test](kotlinx-coroutines-test/README.md) &mdash; 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) &mdash; 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) &mdash; 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) &mdash; 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) &mdash; 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) &mdash; modules that provide coroutine dispatchers for various single-threaded UI libraries:
* Android, JavaFX, and Swing.
-* [integration](integration/README.md) &mdash; 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) &mdash; 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")
}
}
}