Skip to content

Migrate to use RBS annotations #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ GEM
rbs (>= 3, < 4)
sorbet-runtime (>= 0.5.10782)
ruby-progressbar (1.13.0)
sorbet (0.5.12048)
sorbet-static (= 0.5.12048)
sorbet-runtime (0.5.12048)
sorbet-static (0.5.12048-universal-darwin)
sorbet-static (0.5.12048-x86_64-linux)
sorbet-static-and-runtime (0.5.12048)
sorbet (= 0.5.12048)
sorbet-runtime (= 0.5.12048)
sorbet (0.5.12087)
sorbet-static (= 0.5.12087)
sorbet-runtime (0.5.12087)
sorbet-static (0.5.12087-universal-darwin)
sorbet-static (0.5.12087-x86_64-linux)
sorbet-static-and-runtime (0.5.12087)
sorbet (= 0.5.12087)
sorbet-runtime (= 0.5.12087)
spoom (1.6.1)
erubi (>= 1.10.0)
prism (>= 0.28.0)
Expand Down
1 change: 0 additions & 1 deletion lib/ruby-lsp-rspec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# typed: strict
# frozen_string_literal: true

require "sorbet-runtime"
require "ruby_lsp_rspec/version"

module RubyLsp
Expand Down
100 changes: 48 additions & 52 deletions lib/ruby_lsp/ruby_lsp_rspec/addon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,86 +14,86 @@
module RubyLsp
module RSpec
class Addon < ::RubyLsp::Addon
extend T::Sig
FORMATTER_PATH = File.expand_path("rspec_formatter.rb", __dir__) #: String
FORMATTER_NAME = "RubyLsp::RSpec::RSpecFormatter" #: String

FORMATTER_PATH = T.let(File.expand_path("rspec_formatter.rb", __dir__), String)
FORMATTER_NAME = T.let("RubyLsp::RSpec::RSpecFormatter", String)

sig { returns(T::Boolean) }
#: bool
attr_reader :debug

sig { void }
#: -> void
def initialize
super
@debug = T.let(false, T::Boolean)
@rspec_command = T.let(nil, T.nilable(String))
@debug = false #: bool
@rspec_command = nil #: String?
end

sig { override.params(global_state: GlobalState, message_queue: Thread::Queue).void }
# @override
#: (GlobalState, Thread::Queue) -> void
def activate(global_state, message_queue)
@index = T.let(global_state.index, T.nilable(RubyIndexer::Index))
@index = global_state.index #: RubyIndexer::Index?

settings = global_state.settings_for_addon(name)
@rspec_command = rspec_command(settings)
@workspace_path = T.let(global_state.workspace_path, T.nilable(String))
@workspace_path = global_state.workspace_path #: String?
@debug = settings&.dig(:debug) || false
end

sig { override.void }
# @override
#: -> void
def deactivate; end

sig { override.returns(String) }
# @override
#: -> String
def name
"ruby-lsp-rspec"
end

sig { override.returns(String) }
# @override
#: -> String
def version
VERSION
end

# Creates a new CodeLens listener. This method is invoked on every CodeLens request
sig do
override.params(
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
uri: URI::Generic,
dispatcher: Prism::Dispatcher,
).void
end
# @override
#: (ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens], URI::Generic, Prism::Dispatcher) -> void
def create_code_lens_listener(response_builder, uri, dispatcher)
return unless uri.to_standardized_path&.end_with?("_test.rb") || uri.to_standardized_path&.end_with?("_spec.rb")

CodeLens.new(response_builder, uri, dispatcher, T.must(@rspec_command), debug: debug)
CodeLens.new(
response_builder,
uri,
dispatcher,
@rspec_command, #: as !nil
debug: debug,
)
end

# Creates a new Discover Tests listener. This method is invoked on every DiscoverTests request
sig do
override.params(
response_builder: ResponseBuilders::TestCollection,
dispatcher: Prism::Dispatcher,
uri: URI::Generic,
).void
end
# @override
#: (ResponseBuilders::TestCollection, Prism::Dispatcher, URI::Generic) -> void
def create_discover_tests_listener(response_builder, dispatcher, uri)
return unless uri.to_standardized_path&.end_with?("_spec.rb")

TestDiscovery.new(response_builder, dispatcher, uri, T.must(@workspace_path))
TestDiscovery.new(
response_builder,
dispatcher,
uri,
@workspace_path, #: as !nil
)
end

# Resolves the minimal set of commands required to execute the requested tests
sig do
override.params(
items: T::Array[T::Hash[Symbol, T.untyped]],
).returns(T::Array[String])
end
# @override
#: (Array[Hash[Symbol, untyped]]) -> Array[String]
def resolve_test_commands(items)
commands = []
queue = items.dup

full_files = []

until queue.empty?
item = T.must(queue.shift)
item = queue.shift #: as !nil
tags = Set.new(item[:tags])
next unless tags.include?("framework:rspec")

Expand Down Expand Up @@ -128,33 +128,29 @@ def resolve_test_commands(items)
commands
end

sig do
override.params(
response_builder: ResponseBuilders::DocumentSymbol,
dispatcher: Prism::Dispatcher,
).void
end
# @override
#: (ResponseBuilders::DocumentSymbol, Prism::Dispatcher) -> void
def create_document_symbol_listener(response_builder, dispatcher)
DocumentSymbol.new(response_builder, dispatcher)
end

sig do
override.params(
response_builder: ResponseBuilders::CollectionResponseBuilder[T.any(Interface::Location, Interface::LocationLink)],
uri: URI::Generic,
node_context: NodeContext,
dispatcher: Prism::Dispatcher,
).void
end
# @override
#: (ResponseBuilders::CollectionResponseBuilder[Interface::Location | Interface::LocationLink], URI::Generic, NodeContext, Prism::Dispatcher) -> void
def create_definition_listener(response_builder, uri, node_context, dispatcher)
return unless uri.to_standardized_path&.end_with?("_test.rb") || uri.to_standardized_path&.end_with?("_spec.rb")

Definition.new(response_builder, uri, node_context, T.must(@index), dispatcher)
Definition.new(
response_builder,
uri,
node_context,
@index, #: as !nil
dispatcher,
)
end

private

sig { params(settings: T.nilable(T::Hash[Symbol, T.untyped])).returns(String) }
#: (Hash[Symbol, untyped]?) -> String
def rspec_command(settings)
@rspec_command ||= settings&.dig(:rspecCommand) || begin
cmd = if File.exist?(File.join(Dir.pwd, "bin", "rspec"))
Expand Down
33 changes: 12 additions & 21 deletions lib/ruby_lsp/ruby_lsp_rspec/code_lens.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,24 @@
module RubyLsp
module RSpec
class CodeLens
extend T::Sig

include ::RubyLsp::Requests::Support::Common

sig do
params(
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
uri: URI::Generic,
dispatcher: Prism::Dispatcher,
rspec_command: String,
debug: T::Boolean,
).void
end
#: (ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens], URI::Generic, Prism::Dispatcher, String, ?debug: bool) -> void
def initialize(response_builder, uri, dispatcher, rspec_command, debug: false)
@response_builder = response_builder
# Listener is only initialized if uri.to_standardized_path is valid
@path = T.let(T.must(uri.to_standardized_path), String)
@group_id = T.let(1, Integer)
@group_id_stack = T.let([], T::Array[Integer])
path = uri.to_standardized_path #: as !nil
@path = path #: String
@group_id = 1 #: Integer
@group_id_stack = [] #: Array[Integer]
@rspec_command = rspec_command
@anonymous_example_count = T.let(0, Integer)
@anonymous_example_count = 0 #: Integer
dispatcher.register(self, :on_call_node_enter, :on_call_node_leave)

@debug = debug
end

sig { params(node: Prism::CallNode).void }
#: (Prism::CallNode) -> void
def on_call_node_enter(node)
case node.message
when "example", "it", "specify"
Expand All @@ -47,7 +38,7 @@ def on_call_node_enter(node)
end
end

sig { params(node: Prism::CallNode).void }
#: (Prism::CallNode) -> void
def on_call_node_leave(node)
case node.message
when "context", "describe"
Expand All @@ -59,17 +50,17 @@ def on_call_node_leave(node)

private

sig { params(message: String).void }
#: (String) -> void
def log_message(message)
puts "[#{self.class}]: #{message}"
end

sig { params(node: Prism::CallNode).returns(T::Boolean) }
#: (Prism::CallNode) -> bool
def valid_group?(node)
!(node.block.nil? || (node.receiver && node.receiver&.slice != "RSpec"))
end

sig { params(node: Prism::CallNode).returns(String) }
#: (Prism::CallNode) -> String
def generate_name(node)
arguments = node.arguments&.arguments

Expand All @@ -92,7 +83,7 @@ def generate_name(node)
end
end

sig { params(node: Prism::Node, name: String, kind: Symbol).void }
#: (Prism::Node, name: String, kind: Symbol) -> void
def add_test_code_lens(node, name:, kind:)
line_number = node.location.start_line
command = "#{@rspec_command} #{@path}:#{line_number}"
Expand Down
17 changes: 2 additions & 15 deletions lib/ruby_lsp/ruby_lsp_rspec/definition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,9 @@
module RubyLsp
module RSpec
class Definition
extend T::Sig

include ::RubyLsp::Requests::Support::Common

sig do
params(
response_builder: ResponseBuilders::CollectionResponseBuilder[T.any(
Interface::Location,
Interface::LocationLink,
)],
uri: URI::Generic,
node_context: NodeContext,
index: RubyIndexer::Index,
dispatcher: Prism::Dispatcher,
).void
end
#: (ResponseBuilders::CollectionResponseBuilder[Interface::LocationLink | Interface::Location], URI::Generic, NodeContext, RubyIndexer::Index, Prism::Dispatcher) -> void
def initialize(response_builder, uri, node_context, index, dispatcher)
@response_builder = response_builder
@uri = uri
Expand All @@ -28,7 +15,7 @@ def initialize(response_builder, uri, node_context, index, dispatcher)
dispatcher.register(self, :on_call_node_enter)
end

sig { params(node: Prism::CallNode).void }
#: (Prism::CallNode) -> void
def on_call_node_enter(node)
message = node.message
return unless message
Expand Down
15 changes: 4 additions & 11 deletions lib/ruby_lsp/ruby_lsp_rspec/document_symbol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,16 @@
module RubyLsp
module RSpec
class DocumentSymbol
extend T::Sig

include ::RubyLsp::Requests::Support::Common

sig do
params(
response_builder: ResponseBuilders::DocumentSymbol,
dispatcher: Prism::Dispatcher,
).void
end
#: (ResponseBuilders::DocumentSymbol, Prism::Dispatcher) -> void
def initialize(response_builder, dispatcher)
@response_builder = response_builder

dispatcher.register(self, :on_call_node_enter, :on_call_node_leave)
end

sig { params(node: Prism::CallNode).void }
#: (Prism::CallNode) -> void
def on_call_node_enter(node)
case node.message
when "example", "it", "specify"
Expand Down Expand Up @@ -54,7 +47,7 @@ def on_call_node_enter(node)
end
end

sig { params(node: Prism::CallNode).void }
#: (Prism::CallNode) -> void
def on_call_node_leave(node)
case node.message
when "context", "describe", "shared_examples", "shared_context", "shared_examples_for"
Expand All @@ -64,7 +57,7 @@ def on_call_node_leave(node)
end
end

sig { params(node: Prism::CallNode).returns(T.nilable(String)) }
#: (Prism::CallNode) -> String?
def generate_name(node)
arguments = node.arguments&.arguments

Expand Down
9 changes: 4 additions & 5 deletions lib/ruby_lsp/ruby_lsp_rspec/indexing_enhancement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
module RubyLsp
module RSpec
class IndexingEnhancement < RubyIndexer::Enhancement
extend T::Sig

sig { override.params(node: Prism::CallNode).void }
# @override
#: (Prism::CallNode) -> void
def on_call_node_enter(node)
return if node.receiver

Expand All @@ -22,7 +21,7 @@ def on_call_node_enter(node)

return if arguments.arguments.count != 1

method_name_node = T.must(arguments.arguments.first)
method_name_node = arguments.arguments.first #: as !nil

method_name = case method_name_node
when Prism::StringNode
Expand All @@ -41,7 +40,7 @@ def on_call_node_enter(node)
arguments = node.arguments

if arguments && arguments.arguments.count == 1
method_name_node = T.must(arguments.arguments.first)
method_name_node = arguments.arguments.first #: as !nil
end

method_name = if method_name_node
Expand Down
4 changes: 1 addition & 3 deletions lib/ruby_lsp/ruby_lsp_rspec/spec_style_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ module RubyLsp
module Listeners
# Patching this listener so it doesn't generate test items for RSpec tests
class SpecStyle
extend T::Sig

sig { params(response_builder: ResponseBuilders::TestCollection, global_state: GlobalState, dispatcher: Prism::Dispatcher, uri: URI::Generic).void }
#: (ResponseBuilders::TestCollection, GlobalState, Prism::Dispatcher, URI::Generic) -> void
def initialize(response_builder, global_state, dispatcher, uri)
super
end
Expand Down
Loading