Repository: Shopify/ruby-lsp-rails (Ruby)

Issue:
Support ActionMailbox callbacks for Definition requests
Similar to what we do for ActiveRecord callbacks, we could support the 3 callbacks that ActionMailbox provides:

* around_processing
* before_processing
* after_processing

https://api.rubyonrails.org/classes/ActionMailbox/Callbacks.html


Discussion:
I would like to tackle this one!
@andyw8 I just added a PR to solve this by reusing the implementation for ActiveRecord callbacks. Happy to receive feedback!



Patch:
diff --git a/lib/ruby_lsp/ruby_lsp_rails/support/callbacks.rb b/lib/ruby_lsp/ruby_lsp_rails/support/callbacks.rb
index 61d857a6..246b5023 100644
--- a/lib/ruby_lsp/ruby_lsp_rails/support/callbacks.rb
+++ b/lib/ruby_lsp/ruby_lsp_rails/support/callbacks.rb
@@ -55,7 +55,13 @@ module Callbacks
           "before_perform",
         ].freeze
 
-        ALL = (MODELS + CONTROLLERS + JOBS).freeze #: Array[String]
+        MAILBOX = [
+          "after_processing",
+          "before_processing",
+          "around_processing",
+        ].freeze
+
+        ALL = (MODELS + CONTROLLERS + JOBS + MAILBOX).freeze #: Array[String]
       end
     end
   end


Test patch:
diff --git a/test/ruby_lsp_rails/definition_test.rb b/test/ruby_lsp_rails/definition_test.rb
index 581cb10a..fa2db28a 100644
--- a/test/ruby_lsp_rails/definition_test.rb
+++ b/test/ruby_lsp_rails/definition_test.rb
@@ -221,6 +221,69 @@ def baz; end
         assert_empty(response)
       end
 
+      test "recognizes mailbox before_processing callback" do
+        response = generate_definitions_for_source(<<~RUBY, { line: 1, character: 20 })
+          class FooMailbox < ApplicationMailbox
+            before_processing :bar
+
+            private
+              def bar; end
+          end
+        RUBY
+
+        assert_equal(1, response.size)
+
+        response = response.first
+
+        assert_equal("file:///fake.rb", response.uri)
+        assert_equal(4, response.range.start.line)
+        assert_equal(4, response.range.start.character)
+        assert_equal(4, response.range.end.line)
+        assert_equal(16, response.range.end.character)
+      end
+
+      test "recognizes mailbox around_processing callback" do
+        response = generate_definitions_for_source(<<~RUBY, { line: 1, character: 20 })
+          class FooMailbox < ApplicationMailbox
+            around_processing :baz
+
+            private
+              def baz; end
+          end
+        RUBY
+
+        assert_equal(1, response.size)
+
+        response = response.first
+
+        assert_equal("file:///fake.rb", response.uri)
+        assert_equal(4, response.range.start.line)
+        assert_equal(4, response.range.start.character)
+        assert_equal(4, response.range.end.line)
+        assert_equal(16, response.range.end.character)
+      end
+
+      test "recognizes mailbox after_processing callback" do
+        response = generate_definitions_for_source(<<~RUBY, { line: 1, character: 20 })
+          class FooMailbox < ApplicationMailbox
+            after_processing :qux
+
+            private
+              def qux; end
+          end
+        RUBY
+
+        assert_equal(1, response.size)
+
+        response = response.first
+
+        assert_equal("file:///fake.rb", response.uri)
+        assert_equal(4, response.range.start.line)
+        assert_equal(4, response.range.start.character)
+        assert_equal(4, response.range.end.line)
+        assert_equal(16, response.range.end.character)
+      end
+
       private
 
       def generate_definitions_for_source(source, position)