ruby-lsp-ree 0.1.10 → 0.1.11

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 363caa1c6e2f1d4bdedac1791e0edf969fab9fa7037039a6146de7f0d98d0056
4
- data.tar.gz: 750e5d2bba1606b9f50d465b7a86aafb830ee43c18637053421b68e59fabf1f9
3
+ metadata.gz: d34821c4dab78822a47dd7fc927dbfaa8172992c8b51e62efe5650e4ed82a258
4
+ data.tar.gz: a2e0d86639041a0f0810da2309e3d0d1a5d95d60069d1815a01d27d1d720889a
5
5
  SHA512:
6
- metadata.gz: 422890cf9cb718b345df5290c2493a0647ad699636e166c9989b4b91a88909c068a0f3b866b32481303d47e0a1eb29f3cfb1a45d3ba14431a9c8aece0aa85b37
7
- data.tar.gz: b6a374374b8070b679bc2d2720f8a97c49116f21f91d63ba202a98838ec110d90e61c18936963e2aeaa0ff613a3c3fbe89c7ac48c151495045690e46eacd35c7
6
+ metadata.gz: 4c234cf9d220472e15fce43d01a5e304fb16a63de4c9b913110567f9e7f099950221308ce7b93f0637bc2d24492a4d3cafcc1da32e877fa7d0feb2a0aea2d4fa
7
+ data.tar.gz: 8323e4a46dcce71fd00c480374c58022415ba34603c640af812e7356bf8d0ce314fd0a8a919dc6bc54f0b23c82f2dc34c0df3f097930dc8f37bfadf56cc8a327
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.1.11] - 2025-03-28
2
+
3
+ - fixed formatting errors for methods with `rescue`
4
+ - fixed imports from enums
5
+ - improved Add Link for constants
6
+
1
7
  ## [0.1.10] - 2025-03-26
2
8
 
3
9
  - async_bean support
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-lsp-ree (0.1.10)
4
+ ruby-lsp-ree (0.1.11)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -7,6 +7,7 @@ require_relative "utils/ree_lsp_utils"
7
7
  require_relative "ree_formatter"
8
8
  require_relative "ree_template_applicator"
9
9
  require_relative "ree_rename_handler"
10
+ require_relative "ree_constants"
10
11
  require_relative "parsing/parsed_document_builder"
11
12
 
12
13
  module RubyLsp
@@ -1,5 +1,7 @@
1
1
  require_relative "../utils/ree_lsp_utils"
2
2
  require_relative "../ree_object_finder"
3
+ require_relative 'const_additional_text_edits_creator'
4
+ require_relative 'method_additional_text_edits_creator'
3
5
 
4
6
  module RubyLsp
5
7
  module Ree
@@ -193,7 +195,7 @@ module RubyLsp
193
195
  new_text: class_name,
194
196
  ),
195
197
  kind: Constant::CompletionItemKind::CLASS,
196
- additional_text_edits: get_additional_text_edits_for_constant(parsed_doc, class_name, package_name, entry)
198
+ additional_text_edits: ConstAdditionalTextEditsCreator.call(parsed_doc, class_name, package_name, entry)
197
199
  )
198
200
  end
199
201
  end
@@ -234,7 +236,7 @@ module RubyLsp
234
236
  owner_name: "Object",
235
237
  guessed_type: false,
236
238
  },
237
- additional_text_edits: get_additional_text_edits_for_method(parsed_doc, ree_object_name, package_name)
239
+ additional_text_edits: MethodAdditionalTextEditsCreator.call(parsed_doc, ree_object_name, package_name)
238
240
  )
239
241
  end
240
242
  end
@@ -269,76 +271,6 @@ module RubyLsp
269
271
  end
270
272
  end.join(', ')
271
273
  end
272
-
273
- def get_additional_text_edits_for_constant(parsed_doc, class_name, package_name, entry)
274
- if parsed_doc.includes_linked_constant?(class_name)
275
- return []
276
- end
277
-
278
- entry_uri = entry.uri.to_s
279
-
280
- link_text = if parsed_doc.package_name == package_name
281
- fn_name = File.basename(entry_uri, ".*")
282
- "\s\slink :#{fn_name}, import: -> { #{class_name} }"
283
- else
284
- path = path_from_package_folder(entry_uri)
285
- "\s\slink \"#{path}\", import: -> { #{class_name} }"
286
- end
287
-
288
- if parsed_doc.links_container_node
289
- link_text = "\s\s" + link_text
290
- end
291
-
292
- new_text = "\n" + link_text
293
-
294
-
295
- if parsed_doc.has_blank_links_container?
296
- new_text = "\sdo#{link_text}\n\s\send\n"
297
- end
298
-
299
- range = get_range_for_fn_insert(parsed_doc, link_text)
300
-
301
- [
302
- Interface::TextEdit.new(
303
- range: range,
304
- new_text: new_text,
305
- )
306
- ]
307
- end
308
-
309
- def get_additional_text_edits_for_method(parsed_doc, fn_name, package_name)
310
- return [] unless parsed_doc
311
-
312
- if parsed_doc.includes_linked_object?(fn_name)
313
- return []
314
- end
315
-
316
- link_text = if parsed_doc.package_name == package_name
317
- "\s\slink :#{fn_name}"
318
- else
319
- "\s\slink :#{fn_name}, from: :#{package_name}"
320
- end
321
-
322
- if parsed_doc.links_container_node
323
- link_text = "\s\s" + link_text
324
- end
325
-
326
- new_text = "\n" + link_text
327
-
328
- if parsed_doc.has_blank_links_container?
329
- new_text = "\sdo#{link_text}\n\s\send\n"
330
- end
331
-
332
- range = get_range_for_fn_insert(parsed_doc, link_text)
333
- return unless range
334
-
335
- [
336
- Interface::TextEdit.new(
337
- range: range,
338
- new_text: new_text,
339
- )
340
- ]
341
- end
342
274
  end
343
275
  end
344
276
  end
@@ -0,0 +1,104 @@
1
+ module RubyLsp
2
+ module Ree
3
+ class ConstAdditionalTextEditsCreator
4
+ include RubyLsp::Ree::ReeLspUtils
5
+
6
+ def self.call(parsed_doc, const_name, package_name, entry)
7
+ new(parsed_doc, const_name, package_name, entry).call
8
+ end
9
+
10
+ def initialize(parsed_doc, const_name, package_name, entry)
11
+ @parsed_doc = parsed_doc
12
+ @const_name = const_name
13
+ @package_name = package_name
14
+ @entry = entry
15
+ end
16
+
17
+ def call
18
+ if @parsed_doc.includes_linked_constant?(@const_name)
19
+ return []
20
+ end
21
+
22
+ const_link = get_constant_link
23
+
24
+ if existing_link = @parsed_doc.find_link_node(const_link[:object_name])
25
+ # attach to existing link
26
+ if existing_link.has_import_section?
27
+ new_text = "& #{@const_name} }"
28
+ position = existing_link.location.end_column - 1
29
+ range = Interface::Range.new(
30
+ start: Interface::Position.new(line: existing_link.location.start_line-1, character: position),
31
+ end: Interface::Position.new(line: existing_link.location.start_line-1, character: position + new_text.size),
32
+ )
33
+ else
34
+ if existing_link.object_name_type?
35
+ new_text = ", import: -> { #{@const_name} }"
36
+ else
37
+ new_text = ", -> { #{@const_name} }"
38
+ end
39
+
40
+ position = existing_link.location.end_column + 1
41
+ range = Interface::Range.new(
42
+ start: Interface::Position.new(line: existing_link.location.start_line-1, character: position),
43
+ end: Interface::Position.new(line: existing_link.location.start_line-1, character: position + new_text.size),
44
+ )
45
+ end
46
+ else
47
+ # add new link
48
+
49
+ link_text = "\s\slink #{const_link[:link_name]}, import: -> { #{@const_name} }"
50
+
51
+ if @parsed_doc.links_container_node
52
+ link_text = "\s\s" + link_text
53
+ end
54
+
55
+ new_text = "\n" + link_text
56
+
57
+ if @parsed_doc.has_blank_links_container?
58
+ new_text = "\sdo#{link_text}\n\s\send\n"
59
+ end
60
+
61
+ range = get_range_for_fn_insert(@parsed_doc, link_text)
62
+ end
63
+
64
+ [
65
+ Interface::TextEdit.new(
66
+ range: range,
67
+ new_text: new_text,
68
+ )
69
+ ]
70
+ end
71
+
72
+ private
73
+
74
+ def is_ree_object?(uri)
75
+ doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_uri(uri)
76
+ return false if !doc || !doc.has_root_class?
77
+
78
+ doc.parse_links_container_node
79
+ return !!doc.links_container_node
80
+ end
81
+
82
+ def get_constant_link
83
+ entry_uri = @entry.uri.to_s
84
+
85
+ ree_obj_name = nil
86
+ link_name = nil
87
+
88
+ if is_ree_object?(@entry.uri)
89
+ ree_obj_name = File.basename(entry_uri, ".*")
90
+ link_name = ":#{ree_obj_name}"
91
+
92
+ if @package_name != @parsed_doc.package_name
93
+ link_name += ", from: :#{@package_name}"
94
+ end
95
+ else
96
+ ree_obj_name = path_from_package_folder(entry_uri)
97
+ link_name = "\"#{ree_obj_name}\""
98
+ end
99
+
100
+ return { link_name: link_name, object_name: ree_obj_name }
101
+ end
102
+ end
103
+ end
104
+ end
@@ -85,9 +85,10 @@ module RubyLsp
85
85
 
86
86
  if value
87
87
  if value == MISSING_LOCALE_PLACEHOLDER
88
- value_location = find_locale_key_location(locale_file, key_path)
89
- file_uri = "file://#{locale_file}##{value_location.line+1}"
90
- documentation += "#{loc_key}: [#{value}](#{file_uri})\n\n"
88
+ # value_location = find_locale_key_location(locale_file, key_path)
89
+ # file_uri = "file://#{locale_file}##{value_location.line+1}"
90
+ # link doesn't work with ssh remote mode
91
+ documentation += "#{loc_key}: #{value}\n\n"
91
92
  else
92
93
  documentation += "#{loc_key}: #{value}\n\n"
93
94
  end
@@ -124,9 +125,10 @@ module RubyLsp
124
125
 
125
126
  if value
126
127
  if value == MISSING_LOCALE_PLACEHOLDER
127
- value_location = find_locale_key_location(locale_file, key_path)
128
- file_uri = "#{locale_file}" # TODO add line to uri :#{value_location.line+1}:#{value_location.column}"
129
- documentation += "#{loc_key}: [#{value}](#{file_uri})\n\n"
128
+ # value_location = find_locale_key_location(locale_file, key_path)
129
+ # file_uri = "file://#{locale_file}##{value_location.line+1}"
130
+ # link doesn't work with ssh remote mode
131
+ documentation += "#{loc_key}: #{value}\n\n"
130
132
  else
131
133
  documentation += "#{loc_key}: #{value}\n\n"
132
134
  end
@@ -0,0 +1,51 @@
1
+ module RubyLsp
2
+ module Ree
3
+ class MethodAdditionalTextEditsCreator
4
+ include RubyLsp::Ree::ReeLspUtils
5
+
6
+ def self.call(parsed_doc, ree_object_name, package_name)
7
+ new(parsed_doc, ree_object_name, package_name).call
8
+ end
9
+
10
+ def initialize(parsed_doc, ree_object_name, package_name)
11
+ @parsed_doc = parsed_doc
12
+ @ree_object_name = ree_object_name
13
+ @package_name = package_name
14
+ end
15
+
16
+ def call
17
+ return [] unless @parsed_doc
18
+
19
+ if @parsed_doc.includes_linked_object?(@ree_object_name)
20
+ return []
21
+ end
22
+
23
+ link_text = if @parsed_doc.package_name == @package_name
24
+ "\s\slink :#{@ree_object_name}"
25
+ else
26
+ "\s\slink :#{@ree_object_name}, from: :#{@package_name}"
27
+ end
28
+
29
+ if @parsed_doc.links_container_node
30
+ link_text = "\s\s" + link_text
31
+ end
32
+
33
+ new_text = "\n" + link_text
34
+
35
+ if @parsed_doc.has_blank_links_container?
36
+ new_text = "\sdo#{link_text}\n\s\send\n"
37
+ end
38
+
39
+ range = get_range_for_fn_insert(@parsed_doc, link_text)
40
+ return unless range
41
+
42
+ [
43
+ Interface::TextEdit.new(
44
+ range: range,
45
+ new_text: new_text,
46
+ )
47
+ ]
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,52 @@
1
+ class RubyLsp::Ree::ParsedBaseDocument
2
+ include RubyLsp::Ree::ReeLspUtils
3
+
4
+ attr_reader :ast, :package_name, :link_nodes
5
+
6
+ def initialize(ast, package_name = nil)
7
+ @ast = ast
8
+ set_package_name(package_name) if package_name
9
+ end
10
+
11
+ def set_package_name(package_name)
12
+ @package_name = package_name
13
+ end
14
+
15
+ def has_root_class?
16
+ false
17
+ end
18
+
19
+ def includes_linked_object?(obj_name)
20
+ @link_nodes.map(&:name).include?(obj_name)
21
+ end
22
+
23
+ def find_link_node(name)
24
+ @link_nodes.detect{ node_name(_1) == name }
25
+ end
26
+
27
+ def node_name(node)
28
+ return nil unless node.respond_to?(:name)
29
+
30
+ node.name
31
+ end
32
+
33
+ def allows_root_links?
34
+ raise "abstract method"
35
+ end
36
+
37
+ def has_blank_links_container?
38
+ raise "abstract method"
39
+ end
40
+
41
+ def links_container_node
42
+ raise "abstract method"
43
+ end
44
+
45
+ def includes_link_dsl?
46
+ raise "abstract method"
47
+ end
48
+
49
+ def parse_links
50
+ raise "abstract method"
51
+ end
52
+ end
@@ -1,47 +1,34 @@
1
+ require_relative 'parsed_base_document'
1
2
  require_relative 'parsed_link_node'
2
3
  require_relative 'parsed_method_node'
4
+ require_relative "../ree_constants"
3
5
  require 'ostruct'
4
6
 
5
- class RubyLsp::Ree::ParsedDocument
7
+ class RubyLsp::Ree::ParsedClassDocument < RubyLsp::Ree::ParsedBaseDocument
6
8
  include RubyLsp::Ree::ReeLspUtils
9
+ include RubyLsp::Ree::ReeConstants
7
10
 
8
- LINK_DSL_MODULE = 'Ree::LinkDSL'
9
-
10
- ERROR_DEFINITION_NAMES = [
11
- :auth_error,
12
- :build_error,
13
- :conflict_error,
14
- :invalid_param_error,
15
- :not_found_error,
16
- :payment_required_error,
17
- :permission_error,
18
- :validation_error
19
- ]
20
-
21
- CONTRACT_CALL_NODE_NAMES = [
22
- :contract,
23
- :throws
24
- ]
25
-
26
- attr_reader :ast, :package_name, :class_node, :fn_node, :class_includes,
27
- :link_nodes, :values, :action_node, :dao_node, :filters,
28
- :bean_node, :bean_methods, :mapper_node, :links_container_block_node, :aggregate_node,
29
- :error_definitions, :error_definition_names, :doc_instance_methods
11
+ attr_reader :class_node, :class_includes,
12
+ :values, :filters, :bean_methods, :links_container_block_node, :error_definitions,
13
+ :error_definition_names, :doc_instance_methods, :links_container_node
30
14
 
31
15
  def initialize(ast, package_name = nil)
32
- @ast = ast
33
- set_package_name(package_name) if package_name
16
+ super
17
+ parse_class_node
34
18
  end
35
19
 
36
- def links_container_node
37
- # TODO don't use separate node, use one field for all and additional type field: links_container_node_type
38
- @fn_node || @action_node || @dao_node || @bean_node || @mapper_node || @aggregate_node
20
+ def has_root_class?
21
+ true
39
22
  end
40
23
 
41
24
  def allows_root_links?
42
25
  false
43
26
  end
44
27
 
28
+ def has_body?
29
+ class_node && class_node.body && class_node.body.body
30
+ end
31
+
45
32
  def includes_link_dsl?
46
33
  @class_includes.any?{ node_name(_1) == LINK_DSL_MODULE }
47
34
  end
@@ -50,14 +37,6 @@ class RubyLsp::Ree::ParsedDocument
50
37
  @link_nodes.map(&:imports).flatten.include?(const_name)
51
38
  end
52
39
 
53
- def includes_linked_object?(obj_name)
54
- @link_nodes.map{ node_name(_1) }.include?(obj_name)
55
- end
56
-
57
- def find_link_node(name)
58
- @link_nodes.detect{ node_name(_1) == name }
59
- end
60
-
61
40
  def find_link_with_imported_object(name)
62
41
  @link_nodes.detect do |link_node|
63
42
  link_node.imports.include?(name)
@@ -74,58 +53,20 @@ class RubyLsp::Ree::ParsedDocument
74
53
  links_container_node && !@links_container_block_node
75
54
  end
76
55
 
77
- def set_package_name(package_name)
78
- @package_name = package_name
79
- end
80
-
81
56
  def parse_class_node
82
57
  @class_node ||= ast.statements.body.detect{ |node| node.is_a?(Prism::ClassNode) }
83
58
  end
84
59
 
85
- def parse_fn_node
86
- return unless class_node
87
-
88
- @fn_node ||= class_node.body.body.detect{ |node| node_name(node) == :fn }
89
- @links_container_block_node ||= @fn_node&.block
90
- end
91
-
92
- def parse_action_node
93
- return unless class_node
94
-
95
- @action_node ||= class_node.body.body.detect{ |node| node_name(node) == :action }
96
- @links_container_block_node ||= @action_node&.block
97
- end
98
-
99
- def parse_dao_node
100
- return unless class_node
60
+ def parse_links_container_node
61
+ return unless has_body?
101
62
 
102
- @dao_node ||= class_node.body.body.detect{ |node| node_name(node) == :dao }
103
- @links_container_block_node ||= @dao_node&.block
104
- end
105
-
106
- def parse_bean_node
107
- return unless class_node
108
-
109
- @bean_node ||= class_node.body.body.detect{ |node| node_name(node) == :bean || node_name(node) == :async_bean}
110
- @links_container_block_node ||= @bean_node&.block
111
- end
112
-
113
- def parse_mapper_node
114
- return unless class_node
115
-
116
- @mapper_node ||= class_node.body.body.detect{ |node| node_name(node) == :mapper }
117
- @links_container_block_node ||= @mapper_node&.block
118
- end
119
-
120
- def parse_aggregate_node
121
- return unless class_node
122
-
123
- @aggregate_node ||= class_node.body.body.detect{ |node| node_name(node) == :aggregate }
124
- @links_container_block_node ||= @aggregate_node&.block
63
+ @links_container_node ||= class_node.body.body.detect{ |node| LINKS_CONTAINER_TYPES.include?(node_name(node)) }
64
+ @links_container_node_type = node_name(@links_container_node)
65
+ @links_container_block_node ||= @links_container_node&.block
125
66
  end
126
67
 
127
68
  def parse_class_includes
128
- return unless class_node
69
+ return unless has_body?
129
70
 
130
71
  @class_includes ||= class_node.body.body.select{ node_name(_1) == :include }.map do |class_include|
131
72
  parent_name = class_include.arguments.arguments.first.parent.name.to_s
@@ -138,7 +79,7 @@ class RubyLsp::Ree::ParsedDocument
138
79
  end
139
80
 
140
81
  def parse_links
141
- return unless class_node
82
+ return unless has_body?
142
83
 
143
84
  nodes = if links_container_node && @links_container_block_node && @links_container_block_node.body
144
85
  @links_container_block_node.body.body.select{ |node| node_name(node) == :link }
@@ -156,7 +97,7 @@ class RubyLsp::Ree::ParsedDocument
156
97
  end
157
98
 
158
99
  def parse_values
159
- return unless class_node
100
+ return unless has_body?
160
101
 
161
102
  @values ||= class_node.body.body
162
103
  .select{ node_name(_1) == :val }
@@ -173,8 +114,8 @@ class RubyLsp::Ree::ParsedDocument
173
114
  end
174
115
 
175
116
  def parse_bean_methods
176
- return unless class_node
177
-
117
+ return unless has_body?
118
+
178
119
  @bean_methods ||= class_node.body.body
179
120
  .select{ _1.is_a?(Prism::DefNode) }
180
121
  .map{ OpenStruct.new(name: node_name(_1).to_s, signatures: parse_signatures_from_params(_1.parameters)) }
@@ -214,7 +155,7 @@ class RubyLsp::Ree::ParsedDocument
214
155
  end
215
156
 
216
157
  def parse_error_definitions
217
- return unless class_node
158
+ return unless has_body?
218
159
 
219
160
  @error_definitions = class_node.body.body
220
161
  .select{ _1.is_a?(Prism::ConstantWriteNode) }
@@ -240,12 +181,6 @@ class RubyLsp::Ree::ParsedDocument
240
181
  links_container_node.arguments.arguments.first.unescaped
241
182
  end
242
183
 
243
- def node_name(node)
244
- return nil unless node.respond_to?(:name)
245
-
246
- node.name
247
- end
248
-
249
184
  def imported_constants
250
185
  @link_nodes.map(&:imports).flatten.map(&:to_sym)
251
186
  end
@@ -1,11 +1,13 @@
1
1
  require 'prism'
2
- require_relative 'parsed_document'
2
+ require_relative 'parsed_class_document'
3
3
  require_relative 'parsed_rspec_document'
4
4
 
5
5
  class RubyLsp::Ree::ParsedDocumentBuilder
6
6
  extend RubyLsp::Ree::ReeLspUtils
7
7
 
8
8
  def self.build_from_uri(uri, type = nil)
9
+ return unless is_ruby_file?(uri)
10
+
9
11
  ast = Prism.parse_file(uri.path).value
10
12
  document = build_document(ast, type, package_name_from_uri(uri))
11
13
  return unless document
@@ -14,6 +16,8 @@ class RubyLsp::Ree::ParsedDocumentBuilder
14
16
  end
15
17
 
16
18
  def self.build_from_ast(ast, uri, type = nil)
19
+ return if uri && !is_ruby_file?(uri)
20
+
17
21
  document = build_document(ast, type, package_name_from_uri(uri))
18
22
  return unless document
19
23
 
@@ -40,7 +44,7 @@ class RubyLsp::Ree::ParsedDocumentBuilder
40
44
 
41
45
  def self.build_detected_document_type(ast, package_name = nil)
42
46
  if has_root_class?(ast)
43
- build_regular_document(ast, package_name)
47
+ build_class_document(ast, package_name)
44
48
  elsif has_root_rspec_call?(ast)
45
49
  build_rspec_document(ast)
46
50
  else
@@ -58,23 +62,15 @@ class RubyLsp::Ree::ParsedDocumentBuilder
58
62
 
59
63
  def self.build_rspec_document(ast)
60
64
  document = RubyLsp::Ree::ParsedRspecDocument.new(ast)
61
-
62
- document.parse_describe_node
63
65
  document.parse_links
64
66
 
65
67
  document
66
68
  end
67
69
 
68
- def self.build_regular_document(ast, package_name)
69
- document = RubyLsp::Ree::ParsedDocument.new(ast, package_name)
70
+ def self.build_class_document(ast, package_name)
71
+ document = RubyLsp::Ree::ParsedClassDocument.new(ast, package_name)
70
72
 
71
- document.parse_class_node
72
- document.parse_fn_node
73
- document.parse_action_node
74
- document.parse_bean_node
75
- document.parse_dao_node
76
- document.parse_mapper_node
77
- document.parse_aggregate_node
73
+ document.parse_links_container_node
78
74
  document.parse_class_includes
79
75
  document.parse_links
80
76
 
@@ -82,7 +78,7 @@ class RubyLsp::Ree::ParsedDocumentBuilder
82
78
  end
83
79
 
84
80
  def self.build_enum_document(ast)
85
- document = RubyLsp::Ree::ParsedDocument.new(ast)
81
+ document = RubyLsp::Ree::ParsedClassDocument.new(ast)
86
82
 
87
83
  document.parse_class_node
88
84
  document.parse_values
@@ -91,7 +87,7 @@ class RubyLsp::Ree::ParsedDocumentBuilder
91
87
  end
92
88
 
93
89
  def self.build_dao_document(ast)
94
- document = RubyLsp::Ree::ParsedDocument.new(ast)
90
+ document = RubyLsp::Ree::ParsedClassDocument.new(ast)
95
91
 
96
92
  document.parse_class_node
97
93
  document.parse_filters
@@ -100,11 +96,15 @@ class RubyLsp::Ree::ParsedDocumentBuilder
100
96
  end
101
97
 
102
98
  def self.build_bean_document(ast)
103
- document = RubyLsp::Ree::ParsedDocument.new(ast)
99
+ document = RubyLsp::Ree::ParsedClassDocument.new(ast)
104
100
 
105
101
  document.parse_class_node
106
102
  document.parse_bean_methods
107
103
 
108
104
  document
109
105
  end
106
+
107
+ def self.is_ruby_file?(uri)
108
+ File.extname(uri.to_s) == '.rb'
109
+ end
110
110
  end
@@ -75,17 +75,31 @@ class RubyLsp::Ree::ParsedLinkNode
75
75
  @imports ||= get_imports
76
76
  end
77
77
 
78
+ def has_import_section?
79
+ return false if @node.arguments.arguments.size == 1
80
+
81
+ !!import_arg
82
+ end
83
+
78
84
  private
79
85
 
86
+ def last_arg
87
+ @node.arguments.arguments.last
88
+ end
89
+
90
+ def import_arg
91
+ if object_name_type?
92
+ last_arg.elements.detect{ _1.key.unescaped == IMPORT_ARG_KEY }
93
+ else
94
+ last_arg
95
+ end
96
+ end
97
+
80
98
  def get_imports
81
99
  return [] if @node.arguments.arguments.size == 1
82
100
 
83
- last_arg = @node.arguments.arguments.last
84
-
85
- if last_arg.is_a?(Prism::KeywordHashNode)
86
- import_arg = last_arg.elements.detect{ _1.key.unescaped == IMPORT_ARG_KEY }
101
+ if object_name_type?
87
102
  return [] unless import_arg
88
-
89
103
  [import_arg.value.body.body.first.name.to_s]
90
104
  elsif last_arg.is_a?(Prism::LambdaNode)
91
105
  [last_arg.body.body.first.name.to_s]
@@ -39,7 +39,7 @@ class RubyLsp::Ree::ParsedMethodNode
39
39
  return @raised_errors if @raised_errors
40
40
  return [] unless @method_node.body
41
41
 
42
- call_objects = parse_body_call_objects(@method_node.body.body)
42
+ call_objects = parse_body_call_objects(get_method_body(@method_node))
43
43
  raise_objects = call_objects.select{ _1.name == :raise }
44
44
  @raised_errors = raise_objects.map{ parse_raised_class_name(_1) }.compact
45
45
  end
@@ -1,27 +1,21 @@
1
+ require_relative 'parsed_base_document'
1
2
  require_relative 'parsed_link_node'
2
3
  require 'ostruct'
3
4
 
4
- class RubyLsp::Ree::ParsedRspecDocument
5
+ class RubyLsp::Ree::ParsedRspecDocument < RubyLsp::Ree::ParsedBaseDocument
5
6
  include RubyLsp::Ree::ReeLspUtils
6
7
 
7
- attr_reader :ast, :package_name, :describe_node
8
+ attr_reader :describe_node
8
9
 
9
- def initialize(ast)
10
- @ast = ast
11
- end
12
-
13
- def set_package_name(package_name)
14
- @package_name = package_name
10
+ def initialize(ast, package_name = nil)
11
+ super
12
+ parse_describe_node
15
13
  end
16
14
 
17
15
  def allows_root_links?
18
16
  true
19
17
  end
20
18
 
21
- def includes_linked_object?(obj_name)
22
- @link_nodes.map(&:name).include?(obj_name)
23
- end
24
-
25
19
  def links_container_node
26
20
  nil
27
21
  end
@@ -0,0 +1,34 @@
1
+ module RubyLsp
2
+ module Ree
3
+ module ReeConstants
4
+ LINK_DSL_MODULE = 'Ree::LinkDSL'
5
+
6
+ LINKS_CONTAINER_TYPES = [
7
+ :fn,
8
+ :action,
9
+ :dao,
10
+ :bean,
11
+ :async_bean,
12
+ :mapper,
13
+ :aggregate,
14
+ :enum
15
+ ]
16
+
17
+ ERROR_DEFINITION_NAMES = [
18
+ :auth_error,
19
+ :build_error,
20
+ :conflict_error,
21
+ :invalid_param_error,
22
+ :not_found_error,
23
+ :payment_required_error,
24
+ :permission_error,
25
+ :validation_error
26
+ ]
27
+
28
+ CONTRACT_CALL_NODE_NAMES = [
29
+ :contract,
30
+ :throws
31
+ ]
32
+ end
33
+ end
34
+ end
@@ -1,18 +1,10 @@
1
1
  require 'prism'
2
+ require_relative "ree_constants"
2
3
 
3
4
  module RubyLsp
4
5
  module Ree
5
6
  class ReeContext
6
- ERROR_DEFINITION_NAMES = [
7
- :auth_error,
8
- :build_error,
9
- :conflict_error,
10
- :invalid_param_error,
11
- :not_found_error,
12
- :payment_required_error,
13
- :permission_error,
14
- :validation_error
15
- ]
7
+ include RubyLsp::Ree::ReeConstants
16
8
 
17
9
  def initialize(node_context)
18
10
  @node_context = node_context
@@ -8,11 +8,6 @@ module RubyLsp
8
8
  MAX_LIMIT = 1000
9
9
 
10
10
  REE_OBJECT_STRING = 'ree_object'
11
- ENUM_TYPE_STRING = 'type: :enum'
12
- DAO_TYPE_STRING = 'type: :dao'
13
- BEAN_TYPE_STRING = 'type: :bean'
14
- MAPPER_TYPE_STRING = 'type: :mapper'
15
- AGGREGATE_TYPE_STRING = 'type: :aggregate'
16
11
 
17
12
  def initialize(index)
18
13
  @index = index
@@ -60,27 +55,6 @@ module RubyLsp
60
55
  objects_by_name.select{ types.include?(object_type(_1)) }
61
56
  end
62
57
 
63
- def find_enum(name)
64
- objects_by_name = @index[name]
65
- return unless objects_by_name
66
-
67
- objects_by_name.detect{ _1.comments.lines[1]&.chomp == ENUM_TYPE_STRING }
68
- end
69
-
70
- def find_dao(name)
71
- objects_by_name = @index[name]
72
- return unless objects_by_name
73
-
74
- objects_by_name.detect{ _1.comments.lines[1]&.chomp == DAO_TYPE_STRING }
75
- end
76
-
77
- def find_bean(index, name)
78
- objects_by_name = @index[name]
79
- return unless objects_by_name
80
-
81
- objects_by_name.detect{ _1.comments.lines[1]&.chomp == BEAN_TYPE_STRING }
82
- end
83
-
84
58
  def object_type(ree_object)
85
59
  type_str = ree_object.comments.lines[1]&.chomp
86
60
  return unless type_str
@@ -68,8 +68,8 @@ module RubyLsp
68
68
  links_container_node.arguments.location.end_column + 1
69
69
  end
70
70
  elsif parsed_doc.includes_link_dsl?
71
- fn_line = parsed_doc.link_nodes.first.location.start_line - 1
72
- position = parsed_doc.link_nodes.first.location.start_column
71
+ fn_line = parsed_doc.link_nodes.last.location.start_line
72
+ position = parsed_doc.link_nodes.last.location.end_column + 1
73
73
  elsif parsed_doc.allows_root_links?
74
74
  root_node_location = parsed_doc.root_node_line_location
75
75
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RubyLsp
4
4
  module Ree
5
- VERSION = "0.1.10"
5
+ VERSION = "0.1.11"
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.10
4
+ version: 0.1.11
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-03-26 00:00:00.000000000 Z
11
+ date: 2025-03-28 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:
@@ -32,16 +32,20 @@ files:
32
32
  - lib/ruby_lsp/ruby_lsp_ree/formatters/missing_error_locales_formatter.rb
33
33
  - lib/ruby_lsp/ruby_lsp_ree/formatters/sort_links_formatter.rb
34
34
  - lib/ruby_lsp/ruby_lsp_ree/handlers/completion_handler.rb
35
+ - lib/ruby_lsp/ruby_lsp_ree/handlers/const_additional_text_edits_creator.rb
35
36
  - lib/ruby_lsp/ruby_lsp_ree/handlers/definition_handler.rb
36
37
  - lib/ruby_lsp/ruby_lsp_ree/handlers/hover_handler.rb
38
+ - lib/ruby_lsp/ruby_lsp_ree/handlers/method_additional_text_edits_creator.rb
37
39
  - lib/ruby_lsp/ruby_lsp_ree/listeners/completion_listener.rb
38
40
  - lib/ruby_lsp/ruby_lsp_ree/listeners/definition_listener.rb
39
41
  - lib/ruby_lsp/ruby_lsp_ree/listeners/hover_listener.rb
40
- - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document.rb
42
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_base_document.rb
43
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_class_document.rb
41
44
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document_builder.rb
42
45
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node.rb
43
46
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_method_node.rb
44
47
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_rspec_document.rb
48
+ - lib/ruby_lsp/ruby_lsp_ree/ree_constants.rb
45
49
  - lib/ruby_lsp/ruby_lsp_ree/ree_context.rb
46
50
  - lib/ruby_lsp/ruby_lsp_ree/ree_formatter.rb
47
51
  - lib/ruby_lsp/ruby_lsp_ree/ree_indexing_enhancement.rb