Skip to content

Commit

Permalink
WIP: Refactor folding ranges to use emitter pattern (alternative appr…
Browse files Browse the repository at this point in the history
…oach)
  • Loading branch information
andyw8 committed Jun 7, 2023
1 parent efb1d9a commit 4ebf884
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 27 deletions.
6 changes: 6 additions & 0 deletions lib/ruby_lsp/event_emitter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ def emit_for_target(node)
end
end

sig { override.params(node: T.nilable(SyntaxTree::Node)).void }
def visit(node)
@listeners[:on_visit]&.each { |l| T.unsafe(l).on_visit(node) }
super
end

# Visit dispatchers are below. Notice that for nodes that create a new scope (e.g.: classes, modules, method defs)
# we need both an `on_*` and `after_*` event. This is because some requests must know when we exit the scope
sig { override.params(node: SyntaxTree::ClassDeclaration).void }
Expand Down
11 changes: 3 additions & 8 deletions lib/ruby_lsp/executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def run(request)
when "textDocument/selectionRange"
selection_range(uri, request.dig(:params, :positions))
when "textDocument/documentSymbol", "textDocument/documentLink", "textDocument/codeLens",
"textDocument/semanticTokens/full"
"textDocument/semanticTokens/full", "textDocument/foldingRange"
document = @store.get(uri)

# If the response has already been cached by another request, return it
Expand All @@ -93,6 +93,7 @@ def run(request)
emitter = EventEmitter.new
document_symbol = Requests::DocumentSymbol.new(emitter, @message_queue)
document_link = Requests::DocumentLink.new(uri, emitter, @message_queue)
folding_ranges = Requests::FoldingRanges.new(emitter, @message_queue)
code_lens = Requests::CodeLens.new(uri, emitter, @message_queue)
code_lens_extensions_listeners = Requests::CodeLens.listeners.map do |l|
T.unsafe(l).new(document.uri, emitter, @message_queue)
Expand All @@ -111,6 +112,7 @@ def run(request)
"textDocument/semanticTokens/full",
Requests::Support::SemanticTokenEncoder.new.encode(semantic_highlighting.response),
)
document.cache_set("textDocument/foldingRange", folding_ranges.response)
document.cache_get(request[:method])
when "textDocument/semanticTokens/range"
semantic_tokens_range(uri, request.dig(:params, :range))
Expand Down Expand Up @@ -169,13 +171,6 @@ def run(request)
end
end

sig { params(uri: String).returns(T::Array[Interface::FoldingRange]) }
def folding_range(uri)
@store.cache_fetch(uri, "textDocument/foldingRange") do |document|
Requests::FoldingRanges.new(document).run
end
end

sig do
params(
uri: String,
Expand Down
40 changes: 21 additions & 19 deletions lib/ruby_lsp/requests/folding_ranges.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ module Requests
# puts "Hello"
# end # <-- folding range end
# ```
class FoldingRanges < BaseRequest
class FoldingRanges < Listener
extend T::Sig

sig { override.returns(ResponseType) }
attr_reader :response

SIMPLE_FOLDABLES = T.let(
[
SyntaxTree::ArrayLiteral,
Expand Down Expand Up @@ -59,27 +62,26 @@ class FoldingRanges < BaseRequest
)
end

sig { params(document: Document).void }
def initialize(document)
sig { params(emitter: EventEmitter, message_queue: Thread::Queue).void }
def initialize(emitter, message_queue)
super

@ranges = T.let([], T::Array[Interface::FoldingRange])
@response = T.let([], ResponseType)
@partial_range = T.let(nil, T.nilable(PartialRange))
end

sig { override.returns(T.all(T::Array[Interface::FoldingRange], Object)) }
def run
if @document.parsed?
visit(@document.tree)
emit_partial_range
end
# listeners[:on_visit]&.each { |l| T.unsafe(l).on_visit(node) }
emitter.register(self, :on_visit)
super
end

@ranges
sig { params(node: T.nilable(SyntaxTree::Node)).returns(T.untyped) } # TODO: fix sig
def on_visit(node)
visit(node)
emit_partial_range
end

private

sig { override.params(node: T.nilable(SyntaxTree::Node)).void }
sig { params(node: T.nilable(SyntaxTree::Node)).void }
def visit(node)
return unless handle_partial_range(node)

Expand All @@ -97,7 +99,7 @@ def visit(node)
add_lines_range(location.start_line, location.end_line - 1)
else
add_call_range(node)
return
nil
end
when SyntaxTree::Command
unless same_lines_for_command_and_block?(node)
Expand All @@ -108,10 +110,10 @@ def visit(node)
add_def_range(node)
when SyntaxTree::StringConcat
add_string_concat(node)
return
nil
end

super
# super
end

# This is to prevent duplicate ranges
Expand Down Expand Up @@ -214,7 +216,7 @@ def partial_range_kind(node)
def emit_partial_range
return if @partial_range.nil?

@ranges << @partial_range.to_range if @partial_range.multiline?
@response << @partial_range.to_range if @partial_range.multiline?
@partial_range = nil
end

Expand Down Expand Up @@ -295,7 +297,7 @@ def add_string_concat(node)
def add_lines_range(start_line, end_line)
return if start_line >= end_line

@ranges << Interface::FoldingRange.new(
@response << Interface::FoldingRange.new(
start_line: start_line - 1,
end_line: end_line - 1,
kind: "region",
Expand Down

0 comments on commit 4ebf884

Please sign in to comment.