|
| 1 | +# Inkuire |
| 2 | + |
| 3 | +Inkuire is a Hoogle-like search engine for Scala 3 (and Kotlin). |
| 4 | + |
| 5 | +# Usage |
| 6 | + |
| 7 | +To include Inkuire in scaladoc one should add `-generate-inkuire` flag. This will allow the usage of Inkuire for generated Scaladoc with project sources and available sources from external-mappings. |
| 8 | + |
| 9 | +The Inkuire worker works in Scaladoc searchbar. It is triggered once an input containing `=>` is detected in searchbar. There is 1s debounce on searches with Inkuire. |
| 10 | + |
| 11 | +## Generated Files |
| 12 | + |
| 13 | +When including `-generate-inkuire` flag database for project sources and a config should be generated. Which are namely files: `inkuire-db.json` and `scripts/inkuire-config.json`. Config file includes addresses of possible inkuire-db files. There always is at least one - generated one. But also links for external mappings are addes on relative path `../inkuire-db.json`. |
| 14 | + |
| 15 | +`inkuire-db.json` contains a json with Inkuire engine's representation of: |
| 16 | +- types (or rather classes and objects for now) |
| 17 | +- functions |
| 18 | +- implicit conversions |
| 19 | + |
| 20 | + |
| 21 | +## Code |
| 22 | + |
| 23 | +The source code is available [here](https://github.com/VirtusLab/Inkuire). |
| 24 | + |
| 25 | +Important parts are: |
| 26 | +- engineCommon - provides most of the logic for search engine |
| 27 | +- engineJs - provides the way of using Inkuire as a Web Worker |
| 28 | + |
| 29 | +## Integration with Scaladoc |
| 30 | + |
| 31 | +Since Inkuire has quite a lot of dependencies it's sources cannot be easily integrated into Scaladoc. |
| 32 | +That is why Inkuire is included as a resource, namely `inkuire.js` file and loaded as Web Worker. |
| 33 | + |
| 34 | +Web worker accepts String messages. Each message should be a requested signature. |
| 35 | +Web worker can send different messages: |
| 36 | +- engine_ready - sent after database has been loaded |
| 37 | +- new_query - sent once a new signature is accepted |
| 38 | +- query_ended(`msg`) - After processing a single signature has finished. `msg` is optional and contains an error to be displayed. |
| 39 | +- json of format [`ResultFormat`](https://github.com/VirtusLab/Inkuire/blob/68d1e0bb2732deda714de9cfca3fe45f75fb5239/engineCommon/shared/src/main/scala/org/virtuslab/inkuire/engine/common/model/OutputFormat.scala#L12) - resulting function found with some additional information, like package location and documentation link. |
| 40 | + |
| 41 | +## Input format |
| 42 | + |
| 43 | +Signature format accepted by Inkuire is pretty much a Scala curried function. With some minor changes: |
| 44 | +- Types with names as single letters or single letters with digits are considered by default type variables. But other type variables can be declared with [polymorphic function types syntax](https://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html). |
| 45 | +- `_` is treated as sort of wildcard, so matches to any type on any position. So searching for any one-argument function from `Int` can be done like this: `Int => _`. |
| 46 | + |
| 47 | +Some example signatures with expected (not exclusive)results: |
| 48 | +- `Seq[Int] => (Int => Long) => Seq[Long]` -> `IterableOps.map` |
| 49 | +- `(A, B) => A` -> `Product2._1` |
| 50 | +- `Set[Long] => Long => Boolean` -> `SetOps.contains` |
| 51 | +- `BigDecimal => Byte` -> `ScalaNumericAnyConversions.toByte` |
| 52 | +- `Int => Long => Int` -> `Function.const` |
| 53 | +- `String => Int => Char` -> `StringOps.apply` |
| 54 | + |
| 55 | +## Signature processing |
| 56 | + |
| 57 | +Some improvements done on engine side: |
| 58 | +- first argument can be interpreted as a receiver. More specifically there is no difference between a function on type `A` and a function with the first parameter as `A` (provided other parameters and return type are the same). |
| 59 | +- permutating arguments. This may have to be dropped/limited in the future. But for now every permutation of arguments can be matched, so for example: `Int => String => String` matches `Function.const`, even though the arguments are switched. |
0 commit comments