tree-sitter / tree-sitter-ruby

Ruby grammar for tree-sitter
MIT License
182 stars 58 forks source link

Query to get the body of a method #217

Closed olimorris closed 2 years ago

olimorris commented 2 years ago

In other languages there are nodes which allow you to easily get the body of a method (or function in their case). In Java, Lua and Python there are body: block nodes for example.

Is there a way to easily get the body of a method in Ruby?

With the following code snippet

def method_no_params
  # Just some dumb comment
  puts "cool"
end

def method_with_params(a)
  test = 1
  test_other = 11

  [test, test_other].each do |v|
    puts "#{a} #{v}"
  end
end

How would you extract everything in between the def and end lines? My current thinking is that maybe doing something with #make-range! is the only way we could accomplish it.

olimorris commented 2 years ago

Taking this from here:

 ((method . name: (identifier) (method_parameters)? . (_) @function.inner (_)? @function.end .)
   (#make-range! "function.inner" @function.inner @function.end)) @function.outer

get's me somewhere close:

Screen Shot 2022-05-24 at 23 26 37@2x
mbj commented 2 years ago

Beware of this:

def method_no_params; shadowed; end; def method_no_params; real_one; end

You have to return the last match. And yes this code exists in the wild (especially generated).

npezza93 commented 2 years ago

https://github.com/tree-sitter/tree-sitter-ruby/pull/224 will allow easily querying class, module, method, and block bodies.

olimorris commented 2 years ago

@npezza93 very intriguing. What does a query, before and after your pull request, look like?

npezza93 commented 2 years ago

You can see a before and after here. It's way quicker and simpler

olimorris commented 2 years ago

Oh boy. Yep that is an insane improvement! 👏🏼

Edit: Not to 💩 on the original work but it's a nightmare to work with. Any idea what the process is for this finding its way into official Playground?

npezza93 commented 2 years ago

Not to 💩 on the original work but it's a nightmare to work with.

Haha funny story, i actually wrote those original queries. Finally got tired of how slow it was to load those queries and decided to figure out how to tweak the grammar.

Any idea what the process is for this finding its way into official Playground?

No clue. Im a long time lurker, first time contributor to lower level treesitter stuff so not sure what the process is. Im guessing a new npm version has to be cut and then what ever repo that runs the site has to update it's packages.

olimorris commented 2 years ago

I've never actually noticed a performance issue with them, just when I came to add ruby support to refactoring.nvim, getting the body of a method was really challenging compared to most other languages.

Great to see some dialog on the pull request though. Will be following it closely!