gleam-lang / tree-sitter-gleam

🌳 A tree-sitter grammar for the Gleam programming language
Apache License 2.0
71 stars 13 forks source link

highlight modules #2

Closed the-mikedavis closed 2 years ago

the-mikedavis commented 2 years ago

:wave: hello!

This grammar is awesome, great work! :heart_eyes:

I think it's possible to highlight modules. There's this query which is pretty straight-forward:

(module) @module

which captures things like

import gleam/io

But as you mention in the readme, it's a bit ambiguous what to do in this case:

fn pipe_case() {
  string
  |> iodata.new
  |> iodata.reverse
}

Because you might have a record with function that looks syntactically the same.

type Foo {
  Foo(bar: fn() -> Int)
}

pub fn main() {
  let f = Foo(bar: fn() { 5 })
  let _ = f.bar() // 'f' is a module? or a variable?
}

So to get around that, I believe we can use local.scm queries, which define scopes and capture variable definitions and usages ("references"). We can be pretty confident that if we have a function call or pipe and a record access, it's variable if that variable has been defined in the current scope, and otherwise we can say that it's a module. I think I have all the cases of variable definitions correct here, but it's always complicated in languages that have destructuring :sweat_smile:, let me know if I missed some!

What do you think?

J3RN commented 2 years ago

@the-mikedavis Thank you for this! :pray: Here I thought I needed to write an external scanner to build a symbol table etc, etc, but I'm delighted that I don't have to do that :sweat_smile:

I'll need a bit to read up on "locals queries" which I somehow missed (actually, intentionally skipped for simplicity) before I can give this a thorough review :book:

J3RN commented 2 years ago

OK, after doing my research I can confirm that this rocks! :guitar: Thanks!