That was a tough one to debug! I almost thought it was a bug in fennel,
but it, of course, turned out to be a fennel-ls problem.
When you have a symbol like (foo:bar), fennel compiles it by
"macroexpanding" it to (: foo :bar). When fennel macroexpands a macro,
it tries to clean up the output by giving it a best-guess
bytestart/byteend. Fennel-ls was picking up *both* the accurate
`foo:bar` sym and the best-guess virtual `foo` sym as separate
references to `foo`. When computing the renames, the best-guess values
were getting used, which made the replacement range inaccurate.
Although it was properly handled it before, there were no tests for
the unicode offset conversions that used characters that are 3 bytes
in utf8 and 2 bytes in utf16, so I added one. Now, every single
""type"" of charater is tested.
there should now be no cases where multivals and table destructures are
confused. ie, (local [_ x] (values 1 2)) and (local (_ x) [1 2]) are recognized
as nonsense.
Now unused variables and var-not-set lints use a different system.
References are now of type:
{:symbol sym :target ast :ref-type (or :read :write :mutate)}
instead of ast.
unused var will warn if all the references are :write references.
I kept the test from Tibor Classen's patch, but the code is fixed by
preventing & from ever being a definition, instead of ignoring it only
in the diagnostic.
Co-authored-by: Tibor Claassen <tc@codebeige.net>
This isn't a great fix, but now finding the definition of a number
doesn't cause a crash.
It used to crash because there's no way to get metadata about the
source-code location of a number.
When a symbol is recorded to be its own reference, fennel-ls
accidentally counts the reference twice. That's fine, but we don't want
to replace the same words multiple times
Now it does a two-level-deep search when creating competions for tables,
which means that a completion for module fields have better metadata.
the completion code is a bit of a mess, so I want to look into
refactoring it soon.