Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
andyw8 committed Aug 31, 2023
1 parent cfc3153 commit 16249b9
Show file tree
Hide file tree
Showing 12 changed files with 161 additions and 106 deletions.
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
117 changes: 60 additions & 57 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_node: 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,18 +114,18 @@ 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_node: argument.location,
)
end
end

sig { params(node: YARP::ConstantPathWriteNode).void }
sig { params(node: YARP::ConstantPathWrite).void }
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,
)
Expand All @@ -156,7 +135,7 @@ def on_constant_path_write(node)
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,
)
Expand All @@ -176,9 +155,9 @@ def on_def(node)

symbol = create_document_symbol(
name: name,
kind: kind,
kind: Constant::SymbolKind::METHOD,
range_node: node,
selection_range_node: node.name_loc,
selection_range_node: 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_node: node.constant_path.location
)
end

Expand All @@ -208,7 +187,7 @@ 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,
)
Expand All @@ -218,34 +197,58 @@ def on_instance_variable_write(node)
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,
)
end

# sig { params(node: YARP::TopConstField).void }
# def on_top_const_field(node)
# create_document_symbol(
# name: node.constant.value,
# kind: Constant::SymbolKind::CONSTANT,
# range_node: node,
# selection_range_node: node.constant,
# )
# end

# sig { params(node: YARP::VarField).void }
# def on_var_field(node)
# value = node.value
# kind = case value
# when YARP::Const
# Constant::SymbolKind::CONSTANT
# when YARP::CVar, YARP::IVar
# Constant::SymbolKind::VARIABLE
# else
# return
# end

# create_document_symbol(
# name: value.value,
# kind: kind,
# range_node: node,
# selection_range_node: value,
# )
# end

private

sig do
params(
name: String,
kind: Symbol,
kind: Integer,
range_node: YARP::Node,
selection_range_node: T.any(YARP::Node, YARP::Location),
selection_range_node: 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

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_node),
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

0 comments on commit 16249b9

Please sign in to comment.