Skip to content

Commit

Permalink
Fix extracting a method without another declaration to anchor replace…
Browse files Browse the repository at this point in the history
…ment
  • Loading branch information
vinistock committed Aug 19, 2024
1 parent 3388ef8 commit 86130e7
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 16 deletions.
48 changes: 32 additions & 16 deletions lib/ruby_lsp/requests/code_action_resolve.rb
Original file line number Diff line number Diff line change
Expand Up @@ -207,27 +207,43 @@ def refactor_method

# Find the closest method declaration node, so that we place the refactor in a valid position
node_context = RubyDocument.locate(@document.parse_result.value, start_index, node_types: [Prism::DefNode])
closest_def = T.cast(node_context.node, Prism::DefNode)
return Error::InvalidTargetRange if closest_def.nil?
closest_node = node_context.node
return Error::InvalidTargetRange unless closest_node

end_keyword_loc = closest_def.end_keyword_loc
return Error::InvalidTargetRange if end_keyword_loc.nil?
target_range = if closest_node.is_a?(Prism::DefNode)
end_keyword_loc = closest_node.end_keyword_loc
return Error::InvalidTargetRange unless end_keyword_loc

end_line = end_keyword_loc.end_line - 1
character = end_keyword_loc.end_column
indentation = " " * end_keyword_loc.start_column
target_range = {
start: { line: end_line, character: character },
end: { line: end_line, character: character },
}
end_line = end_keyword_loc.end_line - 1
character = end_keyword_loc.end_column
indentation = " " * end_keyword_loc.start_column

new_method_source = <<~RUBY.chomp
new_method_source = <<~RUBY.chomp
#{indentation}def #{NEW_METHOD_NAME}
#{indentation} #{extracted_source}
#{indentation}end
RUBY
#{indentation}def #{NEW_METHOD_NAME}
#{indentation} #{extracted_source}
#{indentation}end
RUBY

{
start: { line: end_line, character: character },
end: { line: end_line, character: character },
}
else
new_method_source = <<~RUBY
#{indentation}def #{NEW_METHOD_NAME}
#{indentation} #{extracted_source.gsub("\n", "\n ")}
#{indentation}end
RUBY

line = [0, source_range.dig(:start, :line) - 1].max
{
start: { line: line, character: source_range.dig(:start, :character) },
end: { line: line, character: source_range.dig(:start, :character) },
}
end

Interface::CodeAction.new(
title: CodeActions::EXTRACT_TO_METHOD_TITLE,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"params": {
"kind": "refactor.extract",
"title": "Refactor: Extract Method",
"data": {
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 2,
"character": 6
}
},
"uri": "file:///fake"
}
},
"result": {
"title": "Refactor: Extract Method",
"edit": {
"documentChanges": [
{
"textDocument": {
"uri": "file:///fake",
"version": null
},
"edits": [
{
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 0,
"character": 0
}
},
"newText": "def new_method\n a = 5 + 2\n a * 10\n \nend\n\n"
},
{
"range": {
"start": {
"line": 0,
"character": 0
},
"end": {
"line": 2,
"character": 6
}
},
"newText": "new_method"
}
]
}
]
}
}
}
2 changes: 2 additions & 0 deletions test/fixtures/extract_method_script.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a = 5 + 2
a * 10

0 comments on commit 86130e7

Please sign in to comment.