Skip to content

Commit

Permalink
Minor: Inline has_link_support and add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jansul committed Aug 19, 2023
1 parent 17b8ab1 commit 7ebb0cb
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 16 deletions.
30 changes: 18 additions & 12 deletions src/ls/definition.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,26 @@ module Mint

return unless node = stack[0]?

has_link_support =
server
.params
.try(&.capabilities.text_document)
.try(&.definition)
.try(&.link_support) || false

links = definition(node, workspace, stack)

case links
when Array(LSP::LocationLink)
return links.map { |x| to_location(x) } if !has_link_support?(server)
# Return a singular `LSP::Location` if possible
return to_lsp_location(links.first) if !has_link_support && links.size == 1

return links.map { |link| to_lsp_location(link) } if !has_link_support

links
# Prefer nil rather than an empty array
links unless links.empty?
when LSP::LocationLink
return to_location(links) if !has_link_support?(server)
return to_lsp_location(links) if !has_link_support

[links]
end
Expand Down Expand Up @@ -55,10 +66,6 @@ module Mint
workspace.ast.components.find(&.name.value.== name)
end

def has_link_support?(server : Server)
!!(server.params.try &.capabilities.try &.text_document.try &.definition.try &.link_support)
end

def to_lsp_range(location : Ast::Node::Location) : LSP::Range
LSP::Range.new(
start: LSP::Position.new(
Expand All @@ -72,19 +79,18 @@ module Mint
)
end

def to_location(location_link : LSP::LocationLink) : LSP::Location
def to_lsp_location(location_link : LSP::LocationLink) : LSP::Location
LSP::Location.new(
range: location_link.target_selection_range,
uri: location_link.target_uri,
)
end

# Returns a `LSP::LocationLink` that links from *source* to the *target* node
# if the language server client has link support, otherwise it returns `LSP::Location`.
#
# When returning a `LSP::LocationLink`, *parent* is used to provide the full range
# for the *target* node. For example, for a function, *target* would be the function name,
# and *parent* would be the whole node, including function body and any comments
# The *parent* node is used to provide the full range for the *target* node.
# For example, for a function, *target* would be the function name, and *parent*
# would be the whole node, including function body and any comments
def location_link(source : Ast::Node, target : Ast::Node, parent : Ast::Node) : LSP::LocationLink
LSP::LocationLink.new(
origin_selection_range: to_lsp_range(source.location),
Expand Down
4 changes: 2 additions & 2 deletions src/ls/definition/module_access.cr
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Mint
module LS
class Definition < LSP::RequestMessage
def definition(node : Ast::ModuleAccess, server : Server, workspace : Workspace, stack : Array(Ast::Node))
def definition(node : Ast::ModuleAccess, workspace : Workspace, stack : Array(Ast::Node))
lookup = workspace.type_checker.lookups[node.variable]?

if lookup
Expand All @@ -11,7 +11,7 @@ module Mint
Ast::Function,
Ast::State,
Ast::Get
location_link server, node.variable, lookup.name, lookup
location_link node.variable, lookup.name, lookup
end
end
end
Expand Down
3 changes: 1 addition & 2 deletions src/ls/definition/type_id.cr
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ module Mint
.reject(&.in?(Core.ast.nodes))
.sort_by!(&.input.file)
.map do |mod|
location_link server, node, mod.name, mod
location_link node, mod.name, mod
end

return links.first if links.size == 1
return links unless links.empty?
end

Expand Down

0 comments on commit 7ebb0cb

Please sign in to comment.