Module: Kapusta::LSP::Definition

Defined in:
lib/kapusta/lsp/definition.rb

Class Method Summary collapse

Class Method Details

.binding_range(binding) ⇒ Object



75
76
77
78
79
80
81
# File 'lib/kapusta/lsp/definition.rb', line 75

def binding_range(binding)
  line = binding.line - 1
  {
    start: { line:, character: binding.column - 1 },
    end: { line:, character: binding.end_column - 1 }
  }
end

.end_marker_at(text, line_zero, character) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/kapusta/lsp/definition.rb', line 31

def end_marker_at(text, line_zero, character)
  forms = Reader.read_all(text)
  walker = ScopeWalker.analyze(forms)
  line = line_zero + 1
  col = character + 1
  walker.end_markers.find do |m|
    m.line == line && col >= m.column && col <= m.end_column
  end
rescue Kapusta::Error
  nil
end

.find(uri, text, line_zero, character, workspace_index:) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/kapusta/lsp/definition.rb', line 12

def find(uri, text, line_zero, character, workspace_index:)
  marker = end_marker_at(text, line_zero, character)
  return location_for_binding(uri, marker.target) if marker&.target

  target = Rename.locate(text, line_zero, character)
  return unless target

  case target.kind
  when :local, :toplevel_fn, :constant
    location_for_binding(uri, target.binding) if target.binding
  when :macro
    locations_for_macro(uri, target.binding, workspace_index)
  when :free_toplevel
    locations_for_toplevel(target.name, workspace_index)
  when :free_constant
    locations_for_constant(target.segment_prefix, workspace_index)
  end
end

.location_for_binding(uri, binding) ⇒ Object



57
58
59
# File 'lib/kapusta/lsp/definition.rb', line 57

def location_for_binding(uri, binding)
  { uri:, range: binding_range(binding) }
end

.locations_for_constant(prefix, workspace_index) ⇒ Object



68
69
70
71
72
73
# File 'lib/kapusta/lsp/definition.rb', line 68

def locations_for_constant(prefix, workspace_index)
  defs = workspace_index.constant_definitions_with_prefix(prefix)
  return if defs.empty?

  defs.map { |uri, b| { uri:, range: binding_range(b) } }
end

.locations_for_macro(uri, binding, workspace_index) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/kapusta/lsp/definition.rb', line 43

def locations_for_macro(uri, binding, workspace_index)
  return unless binding

  case binding.kind
  when :macro
    location_for_binding(uri, binding)
  when :macro_import
    def_uri, def_binding = workspace_index.find_macro_definition(
      uri, binding.import_module, binding.import_key
    )
    location_for_binding(def_uri, def_binding) if def_uri && def_binding
  end
end

.locations_for_toplevel(name, workspace_index) ⇒ Object



61
62
63
64
65
66
# File 'lib/kapusta/lsp/definition.rb', line 61

def locations_for_toplevel(name, workspace_index)
  defs = workspace_index.toplevel_fn_definitions(name)
  return if defs.empty?

  defs.map { |uri, b| { uri:, range: binding_range(b) } }
end