ruby-lsp-ree 0.1.22 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile.lock +1 -1
  4. data/lib/ruby_lsp/ruby_lsp_ree/formatters/import_packages_formatter.rb +1 -0
  5. data/lib/ruby_lsp/ruby_lsp_ree/formatters/missing_imports_formatter.rb +1 -1
  6. data/lib/ruby_lsp/ruby_lsp_ree/formatters/sort_links_formatter.rb +28 -35
  7. data/lib/ruby_lsp/ruby_lsp_ree/formatters/unused_links_formatter.rb +14 -5
  8. data/lib/ruby_lsp/ruby_lsp_ree/handlers/definition_handler.rb +53 -13
  9. data/lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/basic_parser.rb +19 -0
  10. data/lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/body_objects_parser.rb +36 -18
  11. data/lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/call_objects_parser.rb +2 -2
  12. data/lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/const_objects_parser.rb +2 -2
  13. data/lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/links_parser.rb +19 -0
  14. data/lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/local_variables_parser.rb +3 -11
  15. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_base_document.rb +1 -1
  16. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_class_document.rb +8 -10
  17. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_file_path_link_node.rb +45 -0
  18. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_import_link_node.rb +44 -0
  19. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node.rb +44 -64
  20. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node_builder.rb +22 -0
  21. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_method_node.rb +4 -0
  22. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_object_link_node.rb +51 -0
  23. data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_rspec_document.rb +3 -7
  24. data/lib/ruby_lsp/ruby_lsp_ree/ree_context.rb +9 -2
  25. data/lib/ruby_lsp/ruby_lsp_ree/ree_formatter.rb +1 -0
  26. data/lib/ruby_lsp/ruby_lsp_ree/ree_source_editor.rb +44 -4
  27. data/lib/ruby_lsp/ruby_lsp_ree/renderers/link_renderer.rb +130 -0
  28. data/lib/ruby_lsp_ree/version.rb +1 -1
  29. metadata +9 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be41c6719d100fed8169e29ecfb808cf73611625cd14982727ee7763ab55d809
4
- data.tar.gz: 2dac21136c9605aadeb19544f3efb6d9cf3044b40cfeaca2279203ba846f101d
3
+ metadata.gz: 149a5de21eba9546be0724fa9af412299bb013bb4f413ff0f59d8ba8676261d8
4
+ data.tar.gz: bf136b0f946e1d79c43a67c29e32084b3aa90f8f4725984063789ec91c3e3404
5
5
  SHA512:
6
- metadata.gz: 03f9fd7161d065c127b7f479b547b92edad8923b9a24eaa12b687382ad50b1946fa37029281bdda7aa9b9159ddc19f281f304479ec9c35e8516701eaf13b4e6b
7
- data.tar.gz: d2324472049d592331c2ad8a32e156fa374f85f644ab67ce366cecdd486260804c0830aa6372c040669ca291584cd39368860b8ebc29f1c4013bb927a20e5a12
6
+ metadata.gz: 792a7249438e7b086bc98b274077a2fb3af406558167bb0a910a4787440550da742a90d7a97a1e5bd56b8db8c15abc2848d835812c90d275a4d0169ae32b156e
7
+ data.tar.gz: 31dbbcc00c85d4cfc9913e156589f112809e73d8b4d80ac27f6f9ca4d481c383c3e4adb7ed131e2c9d002bc0224dfce545761bde2c5d8fc78d1883a440abda61
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [0.1.24] - 2025-06-27
2
+
3
+ - ree 1.2 syntax support
4
+ - links section sorting updated
5
+
1
6
  ## [0.1.22] - 2025-05-30
2
7
 
3
8
  - unused links formatter: improve usage detection
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-lsp-ree (0.1.22)
4
+ ruby-lsp-ree (0.1.24)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -11,6 +11,7 @@ module RubyLsp
11
11
 
12
12
  current_package = package_name_from_uri(uri)
13
13
  parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_source(source, package_name: current_package)
14
+ return source if !parsed_doc
14
15
 
15
16
  finder = ReeObjectFinder.new(@index)
16
17
  editor = RubyLsp::Ree::ReeSourceEditor.new(source)
@@ -73,4 +73,4 @@ module RubyLsp
73
73
  end
74
74
  end
75
75
  end
76
- end
76
+ end
@@ -1,4 +1,6 @@
1
1
  require_relative 'base_formatter'
2
+ require_relative '../ree_source_editor'
3
+ require_relative '../renderers/link_renderer'
2
4
 
3
5
  module RubyLsp
4
6
  module Ree
@@ -7,44 +9,35 @@ module RubyLsp
7
9
  parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_source(source)
8
10
  return source if !parsed_doc || !parsed_doc.link_nodes&.any?
9
11
 
10
- if parsed_doc.link_nodes.any?{ _1.location.start_line != _1.location.end_line }
11
- $stderr.puts("multiline link definitions, don't sort")
12
- return source
12
+ # Order of groups:
13
+ # - links from the current package without options
14
+ # - links from the current package with options
15
+ # - links from other packages
16
+ # - links with filenames
17
+ # - import links
18
+
19
+ editor = RubyLsp::Ree::ReeSourceEditor.new(source)
20
+ renderer = RubyLsp::Ree::LinkRenderer.new
21
+ # cleanup old links
22
+ parsed_doc.link_nodes.each do |link_node|
23
+ editor.remove_link(link_node)
13
24
  end
14
-
15
- # sort link nodes
16
- sorted_link_nodes = parsed_doc.link_nodes.sort{ |a, b|
17
- a_name = a.node.arguments.arguments.first
18
- b_name = b.node.arguments.arguments.first
19
-
20
- if a_name.is_a?(Prism::SymbolNode) && !b_name.is_a?(Prism::SymbolNode)
21
- -1
22
- elsif b_name.is_a?(Prism::SymbolNode) && !a_name.is_a?(Prism::SymbolNode)
23
- 1
24
- else
25
- a_name.unescaped <=> b_name.unescaped
26
- end
27
- }
28
-
29
- # check if no re-order
30
- if parsed_doc.link_nodes.map{ _1.node.arguments.arguments.first.unescaped } == sorted_link_nodes.map{ _1.node.arguments.arguments.first.unescaped }
31
- return source
32
- end
33
-
34
- # insert nodes to source
35
- link_lines = parsed_doc.link_nodes.map{ _1.location.start_line }
36
-
37
- source_lines = source.lines
38
-
39
- sorted_lines = sorted_link_nodes.map do |sorted_link|
40
- source_lines[sorted_link.location.start_line - 1]
41
- end
42
-
43
- link_lines.each_with_index do |link_line, index|
44
- source_lines[link_line - 1] = sorted_lines[index]
25
+ editor.cleanup_blank_lines(parsed_doc.link_nodes.first.location.start_line-1, parsed_doc.link_nodes.last.location.end_line-1)
26
+
27
+ link_groups = [
28
+ parsed_doc.link_nodes.select(&:object_name_type?).select{ !_1.has_kwargs? }.sort_by(&:name),
29
+ parsed_doc.link_nodes.select(&:object_name_type?).select(&:has_kwargs?).select{ !_1.from_arg_value }.sort_by(&:name),
30
+ parsed_doc.link_nodes.select(&:object_name_type?).select{ !!_1.from_arg_value }.sort_by(&:link_package_name),
31
+ parsed_doc.link_nodes.select(&:file_path_type?).sort_by(&:name),
32
+ parsed_doc.link_nodes.select(&:import_link_type?).sort_by(&:link_package_name),
33
+ ]
34
+
35
+ link_groups_texts = link_groups.map do |link_group|
36
+ link_group.map{ renderer.render(_1) }.join('')
45
37
  end
46
38
 
47
- source_lines.join()
39
+ editor.insert_link_block(parsed_doc, link_groups_texts.select{ _1.size > 0 }.join("\n"))
40
+ editor.source
48
41
  end
49
42
  end
50
43
  end
@@ -25,6 +25,7 @@ module RubyLsp
25
25
  parsed_doc.link_nodes.each do |link_node|
26
26
  remove_imports = []
27
27
 
28
+ link_node.has_import_section?
28
29
  if link_node.has_import_section?
29
30
  remove_imports = link_node.imports.reject{ |imp| import_is_used?(parsed_doc, link_node, imp) }
30
31
  editor.remove_link_imports(link_node, remove_imports)
@@ -34,10 +35,18 @@ module RubyLsp
34
35
  end
35
36
  end
36
37
 
37
- next if link_is_used?(parsed_doc, link_node, remove_imports) || parsed_doc.includes_mapper_dsl?
38
+ next if parsed_doc.includes_mapper_dsl?
39
+
40
+ has_imports = link_node.imports.size > remove_imports.size
41
+ next if has_imports
38
42
 
39
- editor.remove_link(link_node)
40
- removed_links += 1
43
+ remove_objects = link_node.linked_objects.select{ !link_object_is_used?(parsed_doc, link_node, _1) }
44
+ editor.remove_linked_objects(link_node, remove_objects)
45
+
46
+ if link_node.linked_objects.size == remove_objects.size
47
+ editor.remove_link(link_node)
48
+ removed_links += 1
49
+ end
41
50
  end
42
51
 
43
52
  if removed_links == links_count
@@ -54,8 +63,8 @@ module RubyLsp
54
63
  editor.contains_link_import_usage?(parsed_doc, link_node, link_import) || dsl_parser.contains_object_usage?(link_import)
55
64
  end
56
65
 
57
- def link_is_used?(parsed_doc, link_node, remove_imports)
58
- editor.contains_link_usage?(parsed_doc, link_node) || link_node.imports.size > remove_imports.size || dsl_parser.contains_object_usage?(link_node.name)
66
+ def link_object_is_used?(parsed_doc, link_node, linked_object)
67
+ editor.contains_linked_object_usage?(parsed_doc, link_node, linked_object) || dsl_parser.contains_object_usage?(linked_object.usage_name)
59
68
  end
60
69
  end
61
70
  end
@@ -1,8 +1,10 @@
1
1
  require_relative "../utils/ree_lsp_utils"
2
2
  require_relative "../ree_object_finder"
3
3
  require_relative "../parsing/parsed_link_node"
4
+ require_relative "../parsing/parsed_link_node_builder"
4
5
  require_relative "../parsing/parsed_document_builder"
5
6
  require_relative "../utils/ree_locale_utils"
7
+ require_relative "../ree_context"
6
8
 
7
9
  module RubyLsp
8
10
  module Ree
@@ -17,15 +19,15 @@ module RubyLsp
17
19
  @node_context = node_context
18
20
  @root_node = @node_context.instance_variable_get(:@nesting_nodes).first
19
21
  @finder = ReeObjectFinder.new(@index)
22
+ @ree_context = RubyLsp::Ree::ReeContext.new(node_context)
20
23
  end
21
24
 
22
25
  def get_constant_definition_items(node)
23
26
  result = []
24
27
 
25
- link_nodes = if @node_context.parent.is_a?(Prism::CallNode) && @node_context.parent.name == :link
28
+ link_nodes = if @ree_context.is_link_object?
26
29
  # inside link node
27
- link_node = RubyLsp::Ree::ParsedLinkNode.new(@node_context.parent)
28
- link_node.parse_imports
30
+ link_node = RubyLsp::Ree::ParsedLinkNodeBuilder.build_from_node(@node_context.parent, nil)
29
31
  [link_node]
30
32
  else
31
33
  parsed_doc = if @node_context.parent.is_a?(Prism::CallNode)
@@ -36,7 +38,7 @@ module RubyLsp
36
38
 
37
39
  parsed_doc.link_nodes
38
40
  end
39
-
41
+
40
42
  link_nodes.each do |link_node|
41
43
  if link_node.imports.include?(node.name.to_s)
42
44
  uri = ''
@@ -45,6 +47,16 @@ module RubyLsp
45
47
  next unless path
46
48
 
47
49
  uri = File.join(Dir.pwd, path)
50
+ elsif link_node.import_link_type?
51
+ class_candidates = @finder.search_classes(node.name.to_s)
52
+ next unless class_candidates
53
+
54
+ class_candidates = class_candidates.flatten
55
+ package_name = link_node.link_package_name || package_name_from_uri(@uri)
56
+ class_candidate = class_candidates.detect{ package_name_from_uri(_1.uri) == package_name }
57
+ next unless class_candidate
58
+
59
+ uri = class_candidate.uri.to_s
48
60
  else
49
61
  package_name = link_node.link_package_name || package_name_from_uri(@uri)
50
62
 
@@ -103,10 +115,16 @@ module RubyLsp
103
115
  result = []
104
116
  parent_node = @node_context.parent
105
117
 
106
- link_node = RubyLsp::Ree::ParsedLinkNode.new(parent_node, package_name_from_uri(@uri))
118
+ link_node = RubyLsp::Ree::ParsedLinkNodeBuilder.build_from_node(parent_node, package_name_from_uri(@uri))
107
119
  package_name = link_node.link_package_name
108
120
 
109
- method_candidates = @index[link_node.name]
121
+ object_name = if link_node.multi_object_link? && node.is_a?(Prism::SymbolNode) && link_node.has_linked_object?(node.unescaped)
122
+ node.unescaped
123
+ else
124
+ link_node.name
125
+ end
126
+
127
+ method_candidates = @index[object_name]
110
128
  return [] if !method_candidates || method_candidates.size == 0
111
129
 
112
130
  method = method_candidates.detect{ package_name_from_uri(_1.uri) == package_name }
@@ -230,15 +248,12 @@ module RubyLsp
230
248
  package_name = node.unescaped
231
249
 
232
250
  parent_node = @node_context.parent
233
- link_node = RubyLsp::Ree::ParsedLinkNode.new(parent_node, package_name_from_uri(@uri))
251
+ link_node = RubyLsp::Ree::ParsedLinkNodeBuilder.build_from_node(parent_node, package_name_from_uri(@uri))
234
252
 
235
- method_candidates = @index[link_node.name]
236
- return [] if !method_candidates || method_candidates.size == 0
237
-
238
- method = method_candidates.detect{ package_name_from_uri(_1.uri) == package_name }
239
- return [] unless method
253
+ object_uri = find_object_uri_for_package(link_node, package_name).to_s
254
+ return [] unless object_uri
240
255
 
241
- package_path = package_path_from_uri(method.uri.to_s)
256
+ package_path = package_path_from_uri(object_uri.to_s)
242
257
  package_main_file_path = File.join(package_path, 'package', "#{package_name}.rb")
243
258
 
244
259
  [
@@ -251,6 +266,31 @@ module RubyLsp
251
266
  )
252
267
  ]
253
268
  end
269
+
270
+ private
271
+
272
+ def find_object_uri_for_package(link_node, package_name)
273
+ if link_node.import_link_type?
274
+ class_candidates = @finder.search_classes(link_node.imports.first)
275
+ return nil unless class_candidates
276
+
277
+ class_candidates = class_candidates.flatten
278
+ class_candidate = class_candidates.detect{ package_name_from_uri(_1.uri) == package_name }
279
+ return nil unless class_candidate
280
+
281
+ class_candidate.uri
282
+ else
283
+ link_node.name
284
+
285
+ method_candidates = @index[link_node.name]
286
+ return nil if !method_candidates || method_candidates.size == 0
287
+
288
+ method = method_candidates.detect{ package_name_from_uri(_1.uri) == package_name }
289
+ return unless method
290
+
291
+ method.uri
292
+ end
293
+ end
254
294
  end
255
295
  end
256
296
  end
@@ -0,0 +1,19 @@
1
+ require 'prism'
2
+
3
+ class RubyLsp::Ree::BasicParser
4
+ def node_name(node)
5
+ return nil unless node.respond_to?(:name)
6
+
7
+ node.name
8
+ end
9
+
10
+ def get_method_body(node)
11
+ return unless node.body
12
+
13
+ if node.body.is_a?(Prism::BeginNode)
14
+ node.body.statements.body
15
+ else
16
+ node.body.body
17
+ end
18
+ end
19
+ end
@@ -1,6 +1,6 @@
1
- require 'prism'
1
+ require_relative 'basic_parser'
2
2
 
3
- class RubyLsp::Ree::BodyObjectsParser
3
+ class RubyLsp::Ree::BodyObjectsParser < RubyLsp::Ree::BasicParser
4
4
  class ConstObject
5
5
  attr_reader :name
6
6
 
@@ -32,12 +32,14 @@ class RubyLsp::Ree::BodyObjectsParser
32
32
  @target_type = target_type
33
33
  end
34
34
 
35
- def parse(node_body)
35
+ def parse(nodes)
36
36
  target_objects = []
37
37
 
38
- return target_objects unless node_body
39
-
40
- node_body.each do |node|
38
+ return target_objects unless nodes
39
+
40
+ nodes.each do |node|
41
+ next if node.is_a?(Prism::DefNode) # for now don't step into method, parse each method separately
42
+
41
43
  if node.is_a?(Prism::ConstantReadNode) && @target_type == :const_object
42
44
  target_objects << ConstObject.new(name: node.name)
43
45
  end
@@ -46,6 +48,8 @@ class RubyLsp::Ree::BodyObjectsParser
46
48
  if node.receiver
47
49
  target_objects += parse([node.receiver])
48
50
  else
51
+ next if node.name == :link || node.name == :import # don't parse objects inside links
52
+
49
53
  if @target_type == :call_object
50
54
  target_objects << CallObject.new(name: node.name, type: :method_call)
51
55
  end
@@ -62,7 +66,7 @@ class RubyLsp::Ree::BodyObjectsParser
62
66
  end
63
67
 
64
68
  if node.respond_to?(:statements)
65
- target_objects += parse(node.statements.body)
69
+ target_objects += parse([node.statements])
66
70
  end
67
71
 
68
72
  if node.respond_to?(:subsequent)
@@ -88,10 +92,34 @@ class RubyLsp::Ree::BodyObjectsParser
88
92
  if node.respond_to?(:parts) && node.parts
89
93
  target_objects += parse(node.parts)
90
94
  end
95
+
96
+ if node.respond_to?(:rescue_clause) && node.rescue_clause
97
+ target_objects += parse([node.rescue_clause])
98
+ end
99
+
100
+ if node.respond_to?(:else_clause) && node.else_clause
101
+ target_objects += parse([node.else_clause])
102
+ end
103
+
104
+ if node.respond_to?(:ensure_clause) && node.ensure_clause
105
+ target_objects += parse([node.ensure_clause])
106
+ end
107
+
108
+ if node.respond_to?(:body) && node.body
109
+ if node.body.is_a?(Array)
110
+ target_objects += parse(node.body)
111
+ else
112
+ target_objects += parse([node.body])
113
+ end
114
+ end
91
115
  end
92
116
 
93
117
  if node.respond_to?(:block) && node.block && node.block.is_a?(Prism::BlockNode)
94
- target_objects += parse(get_method_body(node.block))
118
+ if node.block.body.is_a?(Array)
119
+ target_objects += parse(node.block.body)
120
+ else
121
+ target_objects += parse([node.block.body])
122
+ end
95
123
  end
96
124
  end
97
125
 
@@ -104,14 +132,4 @@ class RubyLsp::Ree::BodyObjectsParser
104
132
  return [] if !node_arguments || !node_arguments.arguments
105
133
  parse(node_arguments.arguments)
106
134
  end
107
-
108
- def get_method_body(node)
109
- return unless node.body
110
-
111
- if node.body.is_a?(Prism::BeginNode)
112
- node.body.statements.body
113
- else
114
- node.body.body
115
- end
116
- end
117
135
  end
@@ -23,10 +23,10 @@ class RubyLsp::Ree::CallObjectsParser
23
23
  end
24
24
 
25
25
  def method_call_objects(method_object)
26
- method_body = method_object.method_body
26
+ method_body = method_object.full_method_body
27
27
  return [] unless method_body
28
28
 
29
- call_objects = @body_parser.parse(method_body)
29
+ call_objects = @body_parser.parse([method_body])
30
30
 
31
31
  call_objects.each{ |call_object| call_object.set_method_name(method_object.name) }
32
32
  call_objects
@@ -23,10 +23,10 @@ class RubyLsp::Ree::ConstObjectsParser
23
23
  end
24
24
 
25
25
  def method_const_objects(method_object)
26
- method_body = method_object.method_body
26
+ method_body = method_object.full_method_body
27
27
  return [] unless method_body
28
28
 
29
- const_objects = @body_parser.parse(method_body)
29
+ const_objects = @body_parser.parse([method_body])
30
30
 
31
31
  if method_object.has_contract?
32
32
  const_objects += @body_parser.parse([method_object.contract_node])
@@ -0,0 +1,19 @@
1
+ require_relative 'basic_parser'
2
+ require_relative '../parsed_link_node_builder'
3
+
4
+ class RubyLsp::Ree::LinksParser < RubyLsp::Ree::BasicParser
5
+ attr_reader :container
6
+
7
+ def initialize(container, package_name)
8
+ @container = container
9
+ @document_package_name = package_name
10
+ end
11
+
12
+ def parse_links
13
+ nodes = container.select{ |node| node_name(node) == :link || node_name(node) == :import }
14
+
15
+ nodes.map do |link_node|
16
+ RubyLsp::Ree::ParsedLinkNodeBuilder.build_from_node(link_node, @document_package_name)
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,6 @@
1
- class RubyLsp::Ree::LocalVariablesParser
1
+ require_relative 'basic_parser'
2
+
3
+ class RubyLsp::Ree::LocalVariablesParser < RubyLsp::Ree::BasicParser
2
4
  attr_reader :parsed_doc, :method_object
3
5
 
4
6
  class LocalVariable
@@ -39,14 +41,4 @@ class RubyLsp::Ree::LocalVariablesParser
39
41
 
40
42
  local_variables
41
43
  end
42
-
43
- def get_method_body(node)
44
- return unless node.body
45
-
46
- if node.body.is_a?(Prism::BeginNode)
47
- node.body.statements.body
48
- else
49
- node.body.body
50
- end
51
- end
52
44
  end
@@ -37,7 +37,7 @@ class RubyLsp::Ree::ParsedBaseDocument
37
37
  end
38
38
 
39
39
  def includes_linked_object?(obj_name)
40
- @link_nodes.map(&:name).include?(obj_name)
40
+ @link_nodes.map(&:linked_objects).flatten.map(&:name).include?(obj_name)
41
41
  end
42
42
 
43
43
  def find_link_node(name)
@@ -4,6 +4,7 @@ require_relative 'parsed_method_node'
4
4
  require_relative "../ree_constants"
5
5
  require_relative "body_parsers/call_objects_parser"
6
6
  require_relative "body_parsers/const_objects_parser"
7
+ require_relative "body_parsers/links_parser"
7
8
 
8
9
  require 'ostruct'
9
10
 
@@ -106,21 +107,18 @@ class RubyLsp::Ree::ParsedClassDocument < RubyLsp::Ree::ParsedBaseDocument
106
107
  end
107
108
 
108
109
  def parse_links
109
- return unless has_body?
110
+ @link_nodes = []
111
+ return [] unless has_body?
110
112
 
111
- nodes = if links_container_node && @links_container_block_node && @links_container_block_node.body
112
- @links_container_block_node.body.body.select{ |node| node_name(node) == :link }
113
+ links_container_body = if links_container_node && @links_container_block_node && @links_container_block_node.body
114
+ @links_container_block_node.body.body
113
115
  elsif class_includes.any?{ node_name(_1) == LINK_DSL_MODULE }
114
- class_node.body.body.select{ |node| node_name(node) == :link }
116
+ class_node.body.body
115
117
  else
116
- []
118
+ return []
117
119
  end
118
120
 
119
- @link_nodes = nodes.map do |link_node|
120
- link_node = RubyLsp::Ree::ParsedLinkNode.new(link_node, package_name)
121
- link_node.parse_imports # TODO move parse imports inside link_node constructor
122
- link_node
123
- end
121
+ @link_nodes = RubyLsp::Ree::LinksParser.new(links_container_body, package_name).parse_links
124
122
  end
125
123
 
126
124
  def parse_values
@@ -0,0 +1,45 @@
1
+ require_relative 'parsed_link_node'
2
+
3
+ class RubyLsp::Ree::ParsedFilePathLinkNode < RubyLsp::Ree::ParsedLinkNode
4
+ def link_package_name
5
+ @name.split('/').first
6
+ end
7
+
8
+ def link_type
9
+ :file_path
10
+ end
11
+
12
+ def file_path_type?
13
+ true
14
+ end
15
+
16
+ def import_block_open_location
17
+ import_arg.opening_loc
18
+ end
19
+
20
+ def import_block_close_location
21
+ import_arg.closing_loc
22
+ end
23
+
24
+ private
25
+
26
+ def parse_name
27
+ name_arg_node.unescaped
28
+ end
29
+
30
+ def parse_linked_objects
31
+ @linked_objects = []
32
+ end
33
+
34
+ def import_arg
35
+ @node.arguments.arguments.detect{ _1.is_a?(Prism::LambdaNode) }
36
+ end
37
+
38
+ def get_import_items
39
+ return [] unless has_import_section?
40
+ return [] unless import_arg.body
41
+
42
+ import_body = import_arg.body.body.first
43
+ parse_object_link_multiple_imports(import_body)
44
+ end
45
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'parsed_link_node'
2
+
3
+ class RubyLsp::Ree::ParsedImportLinkNode < RubyLsp::Ree::ParsedLinkNode
4
+ def link_package_name
5
+ from_arg_value || document_package
6
+ end
7
+
8
+ def link_type
9
+ :import_link
10
+ end
11
+
12
+ def import_link_type?
13
+ true
14
+ end
15
+
16
+ def import_block_open_location
17
+ import_arg.opening_loc
18
+ end
19
+
20
+ def import_block_close_location
21
+ import_arg.closing_loc
22
+ end
23
+
24
+ private
25
+
26
+ def parse_name
27
+ ''
28
+ end
29
+
30
+ def parse_linked_objects
31
+ @linked_objects = []
32
+ end
33
+
34
+ def import_arg
35
+ @node.arguments.arguments.detect{ _1.is_a?(Prism::LambdaNode) }
36
+ end
37
+
38
+ def get_import_items
39
+ return [] unless has_import_section?
40
+
41
+ import_body = import_arg.body.body.first
42
+ parse_object_link_multiple_imports(import_body)
43
+ end
44
+ end
@@ -1,7 +1,7 @@
1
1
  require 'prism'
2
2
 
3
3
  class RubyLsp::Ree::ParsedLinkNode
4
- attr_reader :node, :document_package, :name, :import_items, :from_param
4
+ attr_reader :node, :document_package, :name, :import_items, :from_param, :linked_objects, :kw_args
5
5
 
6
6
  FROM_ARG_KEY = 'from'
7
7
  IMPORT_ARG_KEY = 'import'
@@ -24,21 +24,36 @@ class RubyLsp::Ree::ParsedLinkNode
24
24
  end
25
25
  end
26
26
 
27
+ class LinkedObject
28
+ attr_reader :name, :alias_name, :location
29
+
30
+ def initialize(name:, alias_name:, location:)
31
+ @name = name
32
+ @alias_name = alias_name
33
+ @location = location
34
+ end
35
+
36
+ def usage_name
37
+ return @alias_name if @alias_name
38
+ @name
39
+ end
40
+ end
41
+
27
42
  def initialize(node, document_package = nil)
28
43
  @node = node
29
44
  @document_package = document_package
30
45
  @name = parse_name
31
46
 
32
47
  parse_params
48
+ parse_linked_objects
49
+ end
50
+
51
+ def multi_object_link?
52
+ false
33
53
  end
34
54
 
35
55
  def link_package_name
36
- case link_type
37
- when :object_name
38
- from_arg_value || document_package
39
- when :file_path
40
- @name.split('/').first
41
- end
56
+ raise "abstract method"
42
57
  end
43
58
 
44
59
  def location
@@ -52,7 +67,6 @@ class RubyLsp::Ree::ParsedLinkNode
52
67
 
53
68
  def from_arg_value
54
69
  return unless @from_param
55
-
56
70
  @from_param.value.respond_to?(:unescaped) ? @from_param.value.unescaped : nil
57
71
  end
58
72
 
@@ -61,24 +75,19 @@ class RubyLsp::Ree::ParsedLinkNode
61
75
  end
62
76
 
63
77
  def link_type
64
- return @link_type if @link_type
65
-
66
- @link_type = case name_arg_node
67
- when Prism::SymbolNode
68
- :object_name
69
- when Prism::StringNode
70
- :file_path
71
- else
72
- nil
73
- end
78
+ raise "abstract method"
74
79
  end
75
80
 
76
81
  def file_path_type?
77
- link_type == :file_path
82
+ false
78
83
  end
79
84
 
80
85
  def object_name_type?
81
- link_type == :object_name
86
+ false
87
+ end
88
+
89
+ def import_link_type?
90
+ false
82
91
  end
83
92
 
84
93
  def parse_imports
@@ -90,43 +99,33 @@ class RubyLsp::Ree::ParsedLinkNode
90
99
  end
91
100
 
92
101
  def has_import_section?
93
- return false if @node.arguments.arguments.size == 1
94
-
95
102
  !!import_arg
96
103
  end
97
104
 
105
+ def has_kwargs?
106
+ !!@kw_args
107
+ end
108
+
98
109
  def first_arg_location
99
110
  @node.arguments.arguments.first.location
100
111
  end
101
112
 
102
113
  def import_block_open_location
103
- if object_name_type?
104
- import_arg.value.opening_loc
105
- else
106
- import_arg.opening_loc
107
- end
114
+ raise "abstract method"
108
115
  end
109
116
 
110
117
  def import_block_close_location
111
- # TODO maybe use two classes for link types
112
- if object_name_type?
113
- import_arg.value.closing_loc
114
- else
115
- import_arg.closing_loc
116
- end
118
+ raise "abstract method"
119
+ end
120
+
121
+ def has_linked_object?(object_name)
122
+ @linked_objects.map(&:name).include?(object_name)
117
123
  end
118
124
 
119
125
  private
120
126
 
121
127
  def parse_name
122
- case name_arg_node
123
- when Prism::SymbolNode
124
- name_arg_node.value
125
- when Prism::StringNode
126
- name_arg_node.unescaped
127
- else
128
- ""
129
- end
128
+ raise "abstract method"
130
129
  end
131
130
 
132
131
  def parse_params
@@ -139,35 +138,16 @@ class RubyLsp::Ree::ParsedLinkNode
139
138
  @alias_name = @as_param ? @as_param.value.unescaped : nil
140
139
  end
141
140
 
142
- def last_arg
143
- @node.arguments.arguments.last
141
+ def parse_linked_objects
142
+ raise "abstract method"
144
143
  end
145
144
 
146
145
  def import_arg
147
- if object_name_type?
148
- last_arg.elements.detect{ _1.key.unescaped == IMPORT_ARG_KEY }
149
- else
150
- last_arg
151
- end
146
+ raise "abstract method"
152
147
  end
153
148
 
154
149
  def get_import_items
155
- return [] if @node.arguments.arguments.size == 1
156
-
157
- if object_name_type?
158
- return [] unless import_arg
159
- import_body = import_arg.value.body.body.first
160
- parse_object_link_multiple_imports(import_body)
161
- elsif last_arg.is_a?(Prism::LambdaNode)
162
- return [] unless last_arg.body
163
- import_body = last_arg.body.body.first
164
- parse_object_link_multiple_imports(import_body)
165
- else
166
- return []
167
- end
168
- rescue => e
169
- $stderr.puts("can't parse imports: #{e.message}")
170
- return []
150
+ raise "abstract method"
171
151
  end
172
152
 
173
153
  def parse_object_link_multiple_imports(import_body)
@@ -0,0 +1,22 @@
1
+ require 'prism'
2
+ require_relative 'parsed_link_node'
3
+ require_relative 'parsed_object_link_node'
4
+ require_relative 'parsed_file_path_link_node'
5
+ require_relative 'parsed_import_link_node'
6
+
7
+ class RubyLsp::Ree::ParsedLinkNodeBuilder
8
+ def self.build_from_node(node, package_name)
9
+ first_arg = node.arguments.arguments.first
10
+
11
+ link_node = if first_arg.is_a?(Prism::SymbolNode)
12
+ RubyLsp::Ree::ParsedObjectLinkNode.new(node, package_name)
13
+ elsif first_arg.is_a?(Prism::StringNode)
14
+ RubyLsp::Ree::ParsedFilePathLinkNode.new(node, package_name)
15
+ else
16
+ RubyLsp::Ree::ParsedImportLinkNode.new(node, package_name)
17
+ end
18
+
19
+ link_node.parse_imports
20
+ link_node
21
+ end
22
+ end
@@ -38,6 +38,10 @@ class RubyLsp::Ree::ParsedMethodNode
38
38
  get_method_body(@method_node)
39
39
  end
40
40
 
41
+ def full_method_body
42
+ @method_node.body
43
+ end
44
+
41
45
  def raised_errors_nested
42
46
  return @raised_errors_nested if @raised_errors_nested
43
47
  raised = raised_errors
@@ -0,0 +1,51 @@
1
+ require_relative 'parsed_link_node'
2
+
3
+ class RubyLsp::Ree::ParsedObjectLinkNode < RubyLsp::Ree::ParsedLinkNode
4
+ def multi_object_link?
5
+ @linked_objects.size > 1
6
+ end
7
+
8
+ def link_package_name
9
+ from_arg_value || document_package
10
+ end
11
+
12
+ def link_type
13
+ :object_name
14
+ end
15
+
16
+ def object_name_type?
17
+ true
18
+ end
19
+
20
+ def import_block_open_location
21
+ import_arg.value.opening_loc
22
+ end
23
+
24
+ def import_block_close_location
25
+ import_arg.value.closing_loc
26
+ end
27
+
28
+ private
29
+
30
+ def parse_name
31
+ name_arg_node.value
32
+ end
33
+
34
+ def parse_linked_objects
35
+ @linked_objects = @node.arguments.arguments.select{ _1.is_a?(Prism::SymbolNode) }.map do |arg|
36
+ LinkedObject.new(name: arg.unescaped, alias_name: @alias_name, location: arg.location)
37
+ end
38
+ end
39
+
40
+ def import_arg
41
+ return unless @kw_args
42
+ @kw_args.elements.detect{ _1.key.unescaped == IMPORT_ARG_KEY }
43
+ end
44
+
45
+ def get_import_items
46
+ return [] unless has_import_section?
47
+
48
+ import_body = import_arg.value.body.body.first
49
+ parse_object_link_multiple_imports(import_body)
50
+ end
51
+ end
@@ -1,5 +1,6 @@
1
1
  require_relative 'parsed_base_document'
2
2
  require_relative 'parsed_link_node'
3
+ require_relative "body_parsers/links_parser"
3
4
  require 'ostruct'
4
5
 
5
6
  class RubyLsp::Ree::ParsedRspecDocument < RubyLsp::Ree::ParsedBaseDocument
@@ -36,12 +37,7 @@ class RubyLsp::Ree::ParsedRspecDocument < RubyLsp::Ree::ParsedBaseDocument
36
37
  end
37
38
 
38
39
  def parse_links
39
- nodes = @describe_node.block.body.body.select{ |node| node.name == :link }
40
-
41
- @link_nodes = nodes.map do |link_node|
42
- link_node = RubyLsp::Ree::ParsedLinkNode.new(link_node, package_name)
43
- link_node.parse_imports
44
- link_node
45
- end
40
+ container = @describe_node.block.body.body
41
+ @link_nodes = RubyLsp::Ree::LinksParser.new(container, package_name).parse_links
46
42
  end
47
43
  end
@@ -21,13 +21,15 @@ module RubyLsp
21
21
  def is_link_object?
22
22
  return false unless has_call_parent?
23
23
 
24
- @node_context.parent.name == :link
24
+ @node_context.parent.name == :link || @node_context.parent.name == :import
25
25
  end
26
26
 
27
27
  def is_package_argument?
28
28
  return false unless has_call_parent?
29
29
  return false if !@node_context.parent.arguments || @node_context.parent.arguments.arguments.size < 2
30
- return false if @node_context.node.unescaped == @node_context.parent.arguments.arguments.first.unescaped
30
+
31
+ first_arg = @node_context.parent.arguments.arguments.first
32
+ return false if @node_context.node.unescaped == symbol_node_name(first_arg)
31
33
 
32
34
  kw_args = @node_context.parent.arguments.arguments.detect{ |arg| arg.is_a?(Prism::KeywordHashNode) }
33
35
  return false unless kw_args
@@ -41,6 +43,11 @@ module RubyLsp
41
43
  def has_call_parent?
42
44
  @node_context && @node_context.parent && @node_context.parent.is_a?(Prism::CallNode)
43
45
  end
46
+
47
+ def symbol_node_name(node)
48
+ return nil unless node.is_a?(Prism::SymbolNode)
49
+ node.unescaped
50
+ end
44
51
  end
45
52
  end
46
53
  end
@@ -54,6 +54,7 @@ module RubyLsp
54
54
 
55
55
  def detect_missing_error_locales(uri, document)
56
56
  parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_source(document.source)
57
+ return [] unless parsed_doc
57
58
 
58
59
  locales_folder = package_locales_folder_path(uri.path)
59
60
  return [] if !locales_folder || !File.directory?(locales_folder)
@@ -13,15 +13,15 @@ module RubyLsp
13
13
  @source_lines.join
14
14
  end
15
15
 
16
- def contains_link_usage?(parsed_doc, link_node)
16
+ def contains_linked_object_usage?(parsed_doc, link_node, linked_object)
17
17
  if parsed_doc.respond_to?(:parse_method_calls)
18
18
  method_calls = parsed_doc.parse_method_calls
19
19
  no_receiver_method_names = method_calls.reject(&:has_receiver?).map(&:name).map(&:to_s)
20
- return no_receiver_method_names.include?(link_node.usage_name)
20
+ return no_receiver_method_names.include?(linked_object.usage_name)
21
21
  end
22
22
 
23
23
  source_lines_except_link = source_lines[0...(link_node.location.start_line-1)] + source_lines[(link_node.location.end_line)..-1]
24
- source_lines_except_link.any?{ |source_line| source_line.match?(/\W#{link_node.usage_name}\W/)}
24
+ source_lines_except_link.any?{ |source_line| source_line.match?(/\W#{linked_object.usage_name}\W/)}
25
25
  end
26
26
 
27
27
  def contains_link_import_usage?(parsed_doc, link_node, link_import)
@@ -38,14 +38,38 @@ module RubyLsp
38
38
  set_empty_lines_for_location!(link_node.location)
39
39
  end
40
40
 
41
+ def remove_linked_objects(link_node, linked_objects)
42
+ return if linked_objects.size == 0
43
+
44
+ if link_node.multi_object_link?
45
+ set_empty_lines_for_location!(link_node.location)
46
+ line = link_node.location.start_line - 1
47
+ offset = link_node.location.start_column - 1
48
+ offset_str = " " * offset
49
+ # TODO use renderer class
50
+ linked_object_names = linked_objects.map(&:name)
51
+ remaining_objects = link_node.linked_objects.select{ !linked_object_names.include?(_1.name) }
52
+ source_lines[line] = "#{offset_str}link #{remaining_objects.map{ ":#{_1.name}" }.join(', ')}"
53
+ if link_node.from_arg_value
54
+ source_lines[line] += ", from: :#{link_node.from_arg_value}"
55
+ end
56
+ source_lines[line] += "\n"
57
+ else
58
+ set_empty_lines_for_location!(link_node.location)
59
+ end
60
+ end
61
+
41
62
  def remove_link_imports(link_node, link_imports)
63
+ return if link_imports.size == 0
42
64
  imports_str = link_node.import_items.reject{ link_imports.include?(_1.name) }.map(&:to_s).join(' & ')
43
65
 
44
66
  block_start_col = link_node.import_block_open_location.start_column
45
67
  block_line = link_node.import_block_open_location.start_line-1
46
68
  block_end_line = link_node.import_block_close_location.end_line-1
69
+ block_end_col = link_node.import_block_close_location.end_column
70
+ # TODO use renderer class
47
71
 
48
- source_lines[block_line] = source_lines[block_line][0..block_start_col] + " #{imports_str} }\n"
72
+ source_lines[block_line] = source_lines[block_line][0..block_start_col] + " #{imports_str} }" + source_lines[block_end_line][block_end_col..-1]
49
73
  set_empty_lines!(block_line+1, block_end_line)
50
74
  end
51
75
 
@@ -73,6 +97,22 @@ module RubyLsp
73
97
  set_empty_lines_for_location!(field.location)
74
98
  end
75
99
 
100
+ def cleanup_blank_lines(start_line, end_line)
101
+ (start_line .. end_line).each do |i|
102
+ source_lines[i] = '' if source_lines[i].strip == ''
103
+ end
104
+ end
105
+
106
+ def insert_link_block(parsed_doc, links_text)
107
+ line = if parsed_doc.links_container_node
108
+ parsed_doc.links_container_node.location.start_line
109
+ else
110
+ parsed_doc.link_nodes.first.location.start_line - 1
111
+ end
112
+
113
+ source_lines[line] = links_text
114
+ end
115
+
76
116
  def add_links(parsed_doc, ree_objects, current_package)
77
117
  new_text = ''
78
118
 
@@ -0,0 +1,130 @@
1
+ module RubyLsp
2
+ module Ree
3
+ class LinkRenderer
4
+ LINE_LENGTH = 80
5
+
6
+ def render(link_node)
7
+ offset = link_node.location.start_column
8
+ offset_str = " " * offset
9
+
10
+ if link_node.object_name_type?
11
+ render_object_link(link_node, offset_str)
12
+ elsif link_node.file_path_type?
13
+ render_file_path_link(link_node, offset_str)
14
+ elsif link_node.import_link_type?
15
+ render_import_link(link_node, offset_str)
16
+ else
17
+ raise "unknown link type for render"
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def render_object_link(link_node, offset_str)
24
+ link_text = "#{offset_str}link "
25
+ last_line = link_text
26
+
27
+ link_node.linked_objects.each_with_index do |linked_object, index|
28
+ linked_object_str = ":#{linked_object.name}"
29
+ last_line = link_text.lines.last
30
+
31
+ if index == 0
32
+ link_text += linked_object_str
33
+ next
34
+ end
35
+
36
+ if (last_line + ", #{linked_object_str}").size <= LINE_LENGTH
37
+ link_text += ", #{linked_object_str}"
38
+ else
39
+ link_text += ",\n#{offset_str} #{linked_object_str}"
40
+ end
41
+ end
42
+
43
+ link_text = render_kwargs(link_text, link_node, offset_str)
44
+
45
+ link_text += "\n"
46
+ link_text
47
+ end
48
+
49
+ def render_file_path_link(link_node, offset_str)
50
+ link_text = "#{offset_str}link '#{link_node.name}', -> {"
51
+ link_text = render_imports(link_text, link_node, offset_str)
52
+
53
+ if link_node.has_kwargs?
54
+ kwargs_str = link_node.kw_args.elements.map{ "#{_1.key.unescaped}: :#{_1.value.unescaped}"}.join(', ')
55
+ link_text += ", #{kwargs_str}"
56
+ end
57
+
58
+ link_text += "\n"
59
+ link_text
60
+ end
61
+
62
+ def render_import_link(link_node, offset_str)
63
+ link_text = "#{offset_str}import -> {"
64
+ link_text = render_imports(link_text, link_node, offset_str)
65
+
66
+ if link_node.has_kwargs?
67
+ kwargs_str = link_node.kw_args.elements.map{ "#{_1.key.unescaped}: :#{_1.value.unescaped}"}.join(', ')
68
+ link_text += ", #{kwargs_str}"
69
+ end
70
+
71
+ link_text += "\n"
72
+ link_text
73
+ end
74
+
75
+ def render_imports(link_text, link_node, offset_str)
76
+ imports_str = link_node.import_items.map(&:to_s).join(' & ')
77
+
78
+ if (link_text+imports_str).size < LINE_LENGTH
79
+ link_text += " #{imports_str} }"
80
+ else
81
+ link_text += "\n"
82
+
83
+ imports_str = "#{offset_str} "
84
+ last_line = imports_str
85
+ link_node.import_items.each_with_index do |import_item, index|
86
+ last_line = imports_str.lines.last
87
+
88
+ if index == 0
89
+ imports_str += import_item.to_s
90
+ next
91
+ end
92
+
93
+ if (last_line + " & #{import_item.to_s}").size <= LINE_LENGTH
94
+ imports_str += " & #{import_item.to_s}"
95
+ else
96
+ imports_str += " &\n#{offset_str} #{import_item.to_s}"
97
+ end
98
+ end
99
+
100
+ link_text += imports_str
101
+ link_text += "\n#{offset_str}}"
102
+ end
103
+
104
+ link_text
105
+ end
106
+
107
+ def render_kwargs(link_text, link_node, offset_str)
108
+ return link_text unless link_node.has_kwargs?
109
+
110
+ if link_node.object_name_type? && link_node.has_import_section?
111
+ link_text += ", import: -> {"
112
+ link_text = render_imports(link_text, link_node, offset_str)
113
+ end
114
+
115
+ kwargs_str = link_node.kw_args.elements.reject{ _1.key.unescaped == 'import' }.map{ "#{_1.key.unescaped}: #{value_name(_1)}"}.join(', ')
116
+ link_text += ", #{kwargs_str}" if kwargs_str.size > 0
117
+
118
+ link_text
119
+ end
120
+
121
+ def value_name(elem)
122
+ if elem.value.respond_to?(:unescaped)
123
+ ":#{elem.value.unescaped}"
124
+ else
125
+ elem.value.name.to_s
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RubyLsp
4
4
  module Ree
5
- VERSION = "0.1.22"
5
+ VERSION = "0.1.24"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp-ree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.22
4
+ version: 0.1.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-05-30 00:00:00.000000000 Z
11
+ date: 2025-06-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A Ruby LSP addon that adds extra editor functionality for Ree applications
14
14
  email:
@@ -44,17 +44,23 @@ files:
44
44
  - lib/ruby_lsp/ruby_lsp_ree/listeners/completion_listener.rb
45
45
  - lib/ruby_lsp/ruby_lsp_ree/listeners/definition_listener.rb
46
46
  - lib/ruby_lsp/ruby_lsp_ree/listeners/hover_listener.rb
47
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/basic_parser.rb
47
48
  - lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/body_objects_parser.rb
48
49
  - lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/call_objects_parser.rb
49
50
  - lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/const_objects_parser.rb
51
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/links_parser.rb
50
52
  - lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/local_variables_parser.rb
51
53
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_base_document.rb
52
54
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_class_document.rb
53
55
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_dao_document.rb
54
56
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document_builder.rb
55
57
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_entity_document.rb
58
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_file_path_link_node.rb
59
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_import_link_node.rb
56
60
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node.rb
61
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node_builder.rb
57
62
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_method_node.rb
63
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_object_link_node.rb
58
64
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_route_document.rb
59
65
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_rspec_document.rb
60
66
  - lib/ruby_lsp/ruby_lsp_ree/ree_constants.rb
@@ -66,6 +72,7 @@ files:
66
72
  - lib/ruby_lsp/ruby_lsp_ree/ree_rename_handler.rb
67
73
  - lib/ruby_lsp/ruby_lsp_ree/ree_source_editor.rb
68
74
  - lib/ruby_lsp/ruby_lsp_ree/ree_template_applicator.rb
75
+ - lib/ruby_lsp/ruby_lsp_ree/renderers/link_renderer.rb
69
76
  - lib/ruby_lsp/ruby_lsp_ree/utils/ree_locale_utils.rb
70
77
  - lib/ruby_lsp/ruby_lsp_ree/utils/ree_lsp_utils.rb
71
78
  - lib/ruby_lsp/ruby_lsp_ree/utils/yaml_file_parser.rb