stevearc / aerial.nvim

Neovim plugin for a code outline window
MIT License
1.58k stars 77 forks source link

Ruby public methods missing after a class method call without arguments #382

Open dzirtusss opened 1 week ago

dzirtusss commented 1 week ago

Language: ruby AerialInfo:

Aerial Info
-----------
Filetype: ruby
Configured backends:
  treesitter (supported) (attached)
  lsp (supported)
  markdown (not supported) [Filetype is not markdown]
  asciidoc (not supported) [Filetype is not asciidoc]
  man (not supported) [Filetype is not man]
Show symbols: Class, Constructor, Enum, Function, Interface, Module, Method, Struct

The minimal amount of code that demonstrates the missing symbol:

class Test
  something # calling w/o args

  def self.myclass; end # this is visible
  def mypublic1; end # this is not visible
  def mypublic2; end # this is not visible
  private
  def myprivate; end # this is visible
end

class Test
  something 1 # calling with args

  ... # all works ok
end

Expected symbol: Function

dzirtusss commented 1 week ago

P.S. This is query version fixed by ChatGPT 🙄 , sorry I'm not huge pro of TS syntax. It fixes the bug, and methods are shown now. New sections that added are (body_statement....

Guess, please review if that makes sense.

(class
  name: [
    (constant)
    (scope_resolution)
  ] @name
  (#set! "kind" "Class")) @symbol

(call
  ((identifier) @scope
    (#any-of? @scope "private" "protected" "public"))?
  .
  (argument_list
    (method
      name: (_) @name
      (#set! "kind" "Method")) @symbol))

(body_statement
  [
    (_)
    ((identifier) @scope
      (#any-of? @scope "private" "protected" "public"))
  ]*
  .
  (method
    name: (_) @name
    (#set! "kind" "Method")) @symbol)

(singleton_method
  object: [
    (constant)
    (self)
    (identifier)
  ] @receiver
  ([
    "."
    "::"
  ] @separator)?
  name: [
    (operator)
    (identifier)
  ] @name
  (#set! "kind" "Method")) @symbol

(singleton_class
  value: (_) @name
  (#set! "kind" "Class")) @symbol

(module
  name: [
    (constant)
    (scope_resolution)
  ] @name
  (#set! "kind" "Module")) @symbol

; For Rspec, Rake, and Shoulda
(call
  method: (identifier) @method @name
  (#any-of? @method
    "describe" "it" "before" "after" ; Rspec
     "namespace" "task" "multitask" "file" ; Rake
     "setup" "teardown" "should" "should_not" "should_eventually" "context")
  ; Shoulda
  arguments: (argument_list
    [
      (string
        (string_content) @name)
      (simple_symbol) @name
      (pair
        key: [
          (string
            (string_content) @name)
          (hash_key_symbol) @name
        ])
      (call) @name
    ])?
  (#set! "kind" "Method")) @symbol @selection

; these are new sections that fix the issue
(body_statement
  [
    (singleton_method)
    (method)
  ] @method_def)

(body_statement
  [
    ((identifier) @scope
      (#any-of? @scope "private" "protected" "public"))
    (method
      name: (_) @name
      (#set! "kind" "Method")) @symbol
  ] @public_scope)

(body_statement
  (singleton_method
    object: [
      (constant)
      (self)
      (identifier)
    ] @receiver
    ([
      "."
      "::"
    ] @separator)?
    name: [
      (operator)
      (identifier)
    ] @name
    (#set! "kind" "Method")) @symbol
  (#set! "scope" "public"))

In this updated query:

• I added an additional rule to handle singleton methods and methods within body_statement to ensure proper scoping. • The rule for handling public methods within the body_statement is adjusted to correctly identify methods following singleton methods. • The #set! "scope" "public" ensures that the public methods are correctly picked up after singleton methods.

Test this query with your Treesitter setup to ensure it resolves the issue with singleton methods affecting the scope of subsequent public methods.

dzirtusss commented 1 week ago

PS2 it is possible to just save this new file to .config/nvim/queries/ruby/aerial.scm and TS picks it over the file provided with plugin. Works as a temporary solution, w/o need for a local repo clone.