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

Migrate path completion to YARP #873

Merged
merged 1 commit into from
Aug 21, 2023
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
2 changes: 1 addition & 1 deletion lib/ruby_lsp/event_emitter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def emit_for_target(node)
when YARP::ConstantPathNode
@listeners[:on_constant_path_node]&.each { |l| T.unsafe(l).on_constant_path_node(node) }
when YARP::StringNode
@listeners[:on_string_node]&.each { |l| T.unsafe(l).on_string_node(node) }
@listeners[:on_string]&.each { |l| T.unsafe(l).on_string(node) }
end
end

Expand Down
37 changes: 12 additions & 25 deletions lib/ruby_lsp/executor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -396,42 +396,29 @@ def semantic_tokens_range(uri, range)
end
def completion(uri, position)
document = @store.get(uri)
return unless document.parsed?

char_position = document.create_scanner.find_char_position(position)
matched, parent = document.locate(
T.must(document.tree),
char_position,
node_types: [SyntaxTree::Command, SyntaxTree::CommandCall, SyntaxTree::CallNode],
)

matched, parent =
document.locate(document.tree, char_position, node_types: [YARP::CallNode])
return unless matched && parent

target = case matched
when SyntaxTree::Command, SyntaxTree::CallNode, SyntaxTree::CommandCall
message = matched.message
return if message.is_a?(Symbol)
return unless message.value == "require"
message = matched.message
return unless message == "require"

args = matched.arguments
args = args.arguments if args.is_a?(SyntaxTree::ArgParen)
return if args.nil? || args.is_a?(SyntaxTree::ArgsForward)
args = matched.arguments
return unless args

argument = args.parts.first
return unless argument.is_a?(SyntaxTree::StringLiteral)
args = args.arguments
return if args.is_a?(YARP::ForwardingArgumentsNode)

path_node = argument.parts.first
return unless path_node.is_a?(SyntaxTree::TStringContent)
return unless (path_node.location.start_char..path_node.location.end_char).cover?(char_position)
argument = args.first
return unless argument.is_a?(YARP::StringNode)

path_node
end

return unless target
return unless (argument.location.start_offset..argument.location.end_offset).cover?(char_position)

emitter = EventEmitter.new
listener = Requests::PathCompletion.new(emitter, @message_queue)
emitter.emit_for_target(target)
emitter.emit_for_target(argument)
listener.response
end

Expand Down
13 changes: 7 additions & 6 deletions lib/ruby_lsp/requests/path_completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ def initialize(emitter, message_queue)
@response = T.let([], ResponseType)
@tree = T.let(Support::PrefixTree.new(collect_load_path_files), Support::PrefixTree)

emitter.register(self, :on_tstring_content)
emitter.register(self, :on_string)
end

sig { params(node: SyntaxTree::TStringContent).void }
def on_tstring_content(node)
@tree.search(node.value).sort.each do |path|
sig { params(node: YARP::StringNode).void }
def on_string(node)
@tree.search(node.content).sort.each do |path|
@response << build_completion(path, node)
end
end
Expand All @@ -49,12 +49,13 @@ def collect_load_path_files
end
end

sig { params(label: String, node: SyntaxTree::TStringContent).returns(Interface::CompletionItem) }
sig { params(label: String, node: YARP::StringNode).returns(Interface::CompletionItem) }
def build_completion(label, node)
# debugger
Interface::CompletionItem.new(
label: label,
text_edit: Interface::TextEdit.new(
range: range_from_syntax_tree_node(node),
range: range_from_location(node.content_loc),
new_text: label,
),
kind: Constant::CompletionItemKind::REFERENCE,
Expand Down
8 changes: 4 additions & 4 deletions test/requests/path_completion_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_completion_command
}
end_position = {
line: 0,
character: document.source.rindex('"'),
character: T.must(document.source.rindex('"')) - 1,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These off by one errors need to be fixed in YARP. I wonder how hard it would be to help them get this done, so that we can stop altering our tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

result = with_file_structure do
Expand Down Expand Up @@ -64,7 +64,7 @@ def test_completion_call
}
end_position = {
line: 0,
character: document.source.rindex('"'),
character: T.must(document.source.rindex('"')) - 1,
}

result = with_file_structure do
Expand Down Expand Up @@ -100,7 +100,7 @@ def test_completion_command_call
}
end_position = {
line: 0,
character: document.source.rindex('"'),
character: T.must(document.source.rindex('"')) - 1,
}

result = with_file_structure do
Expand Down Expand Up @@ -136,7 +136,7 @@ def test_completion_with_partial_path
}
end_position = {
line: 0,
character: document.source.rindex('"'),
character: T.must(document.source.rindex('"')) - 1,
}

result = with_file_structure do
Expand Down