Skip to content
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

Sync yarp branch with main #960

Closed
wants to merge 1 commit into from
Closed
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
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
ruby-lsp (0.9.1)
ruby-lsp (0.9.2)
language_server-protocol (~> 3.17.0)
sorbet-runtime
syntax_tree (>= 6.1.1, < 7)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.9.1
0.9.2
2 changes: 1 addition & 1 deletion lib/ruby_indexer/lib/ruby_indexer/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def files_to_index

sig { returns(Regexp) }
def magic_comment_regex
/^\s*#\s*#{@excluded_magic_comments.join("|")}/
@magic_comment_regex ||= T.let(/^\s*#\s*#{@excluded_magic_comments.join("|")}/, T.nilable(Regexp))
end

private
Expand Down
58 changes: 27 additions & 31 deletions lib/ruby_lsp/executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,6 @@ def did_change_watched_files(changes)

sig { void }
def perform_initial_indexing
return unless @store.experimental_features

# The begin progress invocation happens during `initialize`, so that the notification is sent before we are
# stuck indexing files
RubyIndexer.configuration.load_config
Expand Down Expand Up @@ -567,7 +565,7 @@ def initialize_request(options)
Interface::DocumentSymbolClientCapabilities.new(
hierarchical_document_symbol_support: true,
symbol_kind: {
value_set: Requests::DocumentSymbol::SYMBOL_KIND.values,
value_set: (Constant::SymbolKind::FILE..Constant::SymbolKind::TYPE_PARAMETER).to_a,
},
)
end
Expand Down Expand Up @@ -629,37 +627,35 @@ def initialize_request(options)
)
end

if @store.experimental_features
# Dynamically registered capabilities
file_watching_caps = options.dig(:capabilities, :workspace, :didChangeWatchedFiles)

# Not every client supports dynamic registration or file watching
if file_watching_caps&.dig(:dynamicRegistration) && file_watching_caps&.dig(:relativePatternSupport)
@message_queue << Request.new(
message: "client/registerCapability",
params: Interface::RegistrationParams.new(
registrations: [
# Register watching Ruby files
Interface::Registration.new(
id: "workspace/didChangeWatchedFiles",
method: "workspace/didChangeWatchedFiles",
register_options: Interface::DidChangeWatchedFilesRegistrationOptions.new(
watchers: [
Interface::FileSystemWatcher.new(
glob_pattern: "**/*.rb",
kind: Constant::WatchKind::CREATE | Constant::WatchKind::CHANGE | Constant::WatchKind::DELETE,
),
],
),
# Dynamically registered capabilities
file_watching_caps = options.dig(:capabilities, :workspace, :didChangeWatchedFiles)

# Not every client supports dynamic registration or file watching
if file_watching_caps&.dig(:dynamicRegistration) && file_watching_caps&.dig(:relativePatternSupport)
@message_queue << Request.new(
message: "client/registerCapability",
params: Interface::RegistrationParams.new(
registrations: [
# Register watching Ruby files
Interface::Registration.new(
id: "workspace/didChangeWatchedFiles",
method: "workspace/didChangeWatchedFiles",
register_options: Interface::DidChangeWatchedFilesRegistrationOptions.new(
watchers: [
Interface::FileSystemWatcher.new(
glob_pattern: "**/*.rb",
kind: Constant::WatchKind::CREATE | Constant::WatchKind::CHANGE | Constant::WatchKind::DELETE,
),
],
),
],
),
)
end

begin_progress("indexing-progress", "Ruby LSP: indexing files")
),
],
),
)
end

begin_progress("indexing-progress", "Ruby LSP: indexing files")

Interface::InitializeResult.new(
capabilities: Interface::ServerCapabilities.new(
text_document_sync: Interface::TextDocumentSyncOptions.new(
Expand Down
4 changes: 2 additions & 2 deletions lib/ruby_lsp/requests/code_lens.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def on_class(node)
class_name = node.constant.constant.value
@class_stack.push(class_name)

if class_name.end_with?("Test")
if @path && class_name.end_with?("Test")
add_test_code_lens(
node,
name: class_name,
Expand All @@ -89,7 +89,7 @@ def on_def(node)
visibility, _ = @visibility_stack.last
if visibility == "public"
method_name = node.name.value
if method_name.start_with?("test_")
if @path && method_name.start_with?("test_")
add_test_code_lens(
node,
name: method_name,
Expand Down
97 changes: 35 additions & 62 deletions lib/ruby_lsp/requests/document_symbol.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,38 +32,6 @@ class DocumentSymbol < Listener

ResponseType = type_member { { fixed: T::Array[Interface::DocumentSymbol] } }

SYMBOL_KIND = T.let(
{
file: 1,
module: 2,
namespace: 3,
package: 4,
class: 5,
method: 6,
property: 7,
field: 8,
constructor: 9,
enum: 10,
interface: 11,
function: 12,
variable: 13,
constant: 14,
string: 15,
number: 16,
boolean: 17,
array: 18,
object: 19,
key: 20,
null: 21,
enummember: 22,
struct: 23,
event: 24,
operator: 25,
typeparameter: 26,
}.freeze,
T::Hash[Symbol, Integer],
)

ATTR_ACCESSORS = T.let(["attr_reader", "attr_writer", "attr_accessor"].freeze, T::Array[String])

class SymbolHierarchyRoot
Expand Down Expand Up @@ -92,13 +60,17 @@ def initialize(emitter, message_queue)
T::Array[T.any(SymbolHierarchyRoot, Interface::DocumentSymbol)],
)

@external_listeners.concat(
Extension.extensions.filter_map { |ext| ext.create_document_symbol_listener(emitter, message_queue) },
)

emitter.register(
self,
:on_class,
:after_class,
:on_call,
:on_constant_path_write,
:on_constant_write,
:on_constant_path_write,
:on_def,
:after_def,
:on_module,
Expand All @@ -108,13 +80,20 @@ def initialize(emitter, message_queue)
)
end

# Merges responses from other listeners
sig { override.params(other: Listener[ResponseType]).returns(T.self_type) }
def merge_response!(other)
@response.concat(other.response)
self
end

sig { params(node: YARP::ClassNode).void }
def on_class(node)
@stack << create_document_symbol(
name: node.constant_path.location.slice,
kind: :class,
kind: Constant::SymbolKind::CLASS,
range_node: node,
selection_range_node: node.constant_path,
selection_range_location: node.constant_path.location,
)
end

Expand All @@ -125,7 +104,7 @@ def after_class(node)

sig { params(node: YARP::CallNode).void }
def on_call(node)
return unless ATTR_ACCESSORS.include?(node.name) && node.receiver.nil?
return unless ATTR_ACCESSORS.include?(node.name)

arguments = node.arguments
return unless arguments
Expand All @@ -135,9 +114,9 @@ def on_call(node)

create_document_symbol(
name: argument.value,
kind: :field,
kind: Constant::SymbolKind::FIELD,
range_node: argument,
selection_range_node: argument,
selection_range_location: argument.location,
)
end
end
Expand All @@ -146,19 +125,19 @@ def on_call(node)
def on_constant_path_write(node)
create_document_symbol(
name: node.target.location.slice,
kind: :constant,
kind: Constant::SymbolKind::CONSTANT,
range_node: node,
selection_range_node: node.target,
selection_range_location: node.target.location,
)
end

sig { params(node: YARP::ConstantWriteNode).void }
def on_constant_write(node)
create_document_symbol(
name: node.name,
kind: :constant,
kind: Constant::SymbolKind::CONSTANT,
range_node: node,
selection_range_node: node.name_loc,
selection_range_location: node.name_loc,
)
end

Expand All @@ -168,17 +147,17 @@ def on_def(node)

if receiver.is_a?(YARP::SelfNode)
name = "self.#{node.name}"
kind = :method
kind = Constant::SymbolKind::METHOD
else
name = node.name
kind = name == "initialize" ? :constructor : :method
kind = name == "initialize" ? Constant::SymbolKind::CONSTRUCTOR : Constant::SymbolKind::METHOD
end

symbol = create_document_symbol(
name: name,
kind: kind,
range_node: node,
selection_range_node: node.name_loc,
selection_range_location: node.name_loc,
)

@stack << symbol
Expand All @@ -193,9 +172,9 @@ def after_def(node)
def on_module(node)
@stack << create_document_symbol(
name: node.constant_path.location.slice,
kind: :module,
kind: Constant::SymbolKind::MODULE,
range_node: node,
selection_range_node: node.constant_path,
selection_range_location: node.constant_path.location,
)
end

Expand All @@ -208,19 +187,19 @@ def after_module(node)
def on_instance_variable_write(node)
create_document_symbol(
name: node.name,
kind: :variable,
kind: Constant::SymbolKind::VARIABLE,
range_node: node,
selection_range_node: node.name_loc,
selection_range_location: node.name_loc,
)
end

sig { params(node: YARP::ClassVariableWriteNode).void }
def on_class_variable_write(node)
create_document_symbol(
name: node.name,
kind: :variable,
kind: Constant::SymbolKind::VARIABLE,
range_node: node,
selection_range_node: node.name_loc,
selection_range_location: node.name_loc,
)
end

Expand All @@ -229,23 +208,17 @@ def on_class_variable_write(node)
sig do
params(
name: String,
kind: Symbol,
kind: Integer,
range_node: YARP::Node,
selection_range_node: T.any(YARP::Node, YARP::Location),
selection_range_location: YARP::Location,
).returns(Interface::DocumentSymbol)
end
def create_document_symbol(name:, kind:, range_node:, selection_range_node:)
selection_range = if selection_range_node.is_a?(YARP::Node)
range_from_syntax_tree_node(selection_range_node)
else
range_from_location(selection_range_node)
end

def create_document_symbol(name:, kind:, range_node:, selection_range_location:)
symbol = Interface::DocumentSymbol.new(
name: name,
kind: SYMBOL_KIND[kind],
kind: kind,
range: range_from_syntax_tree_node(range_node),
selection_range: selection_range,
selection_range: range_from_location(selection_range_location),
children: [],
)

Expand Down
7 changes: 4 additions & 3 deletions lib/ruby_lsp/requests/on_type_formatting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,12 @@ def handle_statement_end
next_line = @lines[@position[:line] + 1]

if current_line.nil? || current_line.strip.empty?
add_edit_with_text(" \n#{indents}end")
add_edit_with_text("\n")
add_edit_with_text("#{indents}end")
move_cursor_to(@position[:line], @indentation + 2)
elsif next_line.nil? || next_line.strip.empty?
add_edit_with_text("#{indents}end", { line: @position[:line] + 1, character: @position[:character] })
move_cursor_to(@position[:line], @indentation + 3)
add_edit_with_text("#{indents}end\n", { line: @position[:line] + 1, character: @position[:character] })
move_cursor_to(@position[:line] - 1, @indentation + @previous_line.size + 1)
end
end

Expand Down
8 changes: 6 additions & 2 deletions test/executor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,12 @@ def test_initialize_uses_utf_16_if_no_encodings_are_specified
end

def test_initialized_populates_index
@store.experimental_features = true
@executor.execute({ method: "initialized", params: {} })
index = @executor.instance_variable_get(:@index)
refute_empty(index.instance_variable_get(:@entries))
end

def test_initialized_recovers_from_indexing_failures
@store.experimental_features = true
RubyIndexer::Index.any_instance.expects(:index_all).once.raises(StandardError, "boom!")

@executor.execute({ method: "initialized", params: {} })
Expand Down Expand Up @@ -204,6 +202,12 @@ def test_shows_error_if_formatter_set_to_rubocop_but_rubocop_not_available

assert_equal("none", @store.formatter)
refute_empty(@message_queue)

# Account for starting and ending the progress notifications during initialized
assert_equal("window/workDoneProgress/create", @message_queue.pop.message)
assert_equal("$/progress", @message_queue.pop.message)
assert_equal("$/progress", @message_queue.pop.message)

notification = T.must(@message_queue.pop)
assert_equal("window/showMessage", notification.message)
assert_equal(
Expand Down
Loading