The bracket that I wrote inside effects does not properly handle
asynchronous exceptions, as it has no way to call the mask function.
As such, because the asynchronous exception is rethrown by both
`bracket` and `wait`, the exception handler will trigger twice. This
is what is causing the crash: `bracket` is passing the TSParser we
create in parseToAST to ts_parser_delete twice.
The best thing to do here is to create the new `Resource` effect,
which is interpreted down to `Control.Exception.bracket`, which has
the correct asynchronous-masking behavior, unlike the `bracket` in
`Control.Monad.Effect.Exception`, which I propose to remove in a patch
to `effects`.
This also bumps haskell-tree-sitter so that the
`ts_node_copy_child_nodes` function is considered `interruptible`.
To test:
1. Download [this file](https://gist.ghe.io/tclem/c2ffe3d20b248fdac59588aa98f168ae)
2. Run `TREE_SITTER_PARSE_TIMEOUT=1000 stack exec semantic -- --log-level=debug parse lexer.rb`
Before applying this patch, you will see a crash associated with a
double-free; afterwards, it should time out normally.
Right now, when opening a shell with `script/ghci`, you can encounter
a tremendous slowdown by turning on pretty-printing (with `pretty`)
then printing any value (`[0..3]` should work).
This stems from the fact that our `.ghci` specifies the `prettyShow`
function, defined in Semantic.Util, as its `-interactive-print`
function. While this is a good choice of a pretty-printer, the fact
that it is in Util, a file which imports many modules and uses fancy
types, is not good: pretty-printing cannot begin until Util is
recompiled and linked in. This explains why benchmarking this slowdown
revealed nothing but `dlsym` calls: we thought it was due to linking
in the tree-sitter libraries, but it was actually waiting for Util to
compile and link in.
The fix is simple: define `prettyShow` in another module. This should
provide significant speedups to our developer workflow.
Prefixes on data constructors are generally an antipattern in Haskell:
if you're concerned about name collisions, have clients use qualified
imports for whatever modules they need. As such, this removes the T-
prefixes from the `Token` and `Context` types. This also renames
Context to Scope, which is a more exact and readable name.
I figure that since we're starting to show this to other teams, it
behooves our documentation to have a more meaningful description.
Happy to change this if y'all can come up with a snappier synopsis.