ruby-lsp-ree 0.1.11 → 0.1.13

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: d34821c4dab78822a47dd7fc927dbfaa8172992c8b51e62efe5650e4ed82a258
4
- data.tar.gz: a2e0d86639041a0f0810da2309e3d0d1a5d95d60069d1815a01d27d1d720889a
3
+ metadata.gz: 830eb15946648bcdb6d03779678f3a4ed0d1f25081bf948d9951496b050a51b0
4
+ data.tar.gz: 6fb752c0d447d1e5a3e4d680b24ff8295555af253875d95498430951d872e919
5
5
  SHA512:
6
- metadata.gz: 4c234cf9d220472e15fce43d01a5e304fb16a63de4c9b913110567f9e7f099950221308ce7b93f0637bc2d24492a4d3cafcc1da32e877fa7d0feb2a0aea2d4fa
7
- data.tar.gz: 8323e4a46dcce71fd00c480374c58022415ba34603c640af812e7356bf8d0ce314fd0a8a919dc6bc54f0b23c82f2dc34c0df3f097930dc8f37bfadf56cc8a327
6
+ metadata.gz: 9766f1c674d1a3d695db8f181931c72d76993c46133d733e92f996c3d016d66bcc2b158f29a4e231b6dc39d5754b0586b9714496e13cb0d365169a96841d6626
7
+ data.tar.gz: b2883d1193a0039850fc343e2baf6aea0e374b08fbd1dc8c04e44c76f9c16a3fb4a755269b33e260e7a38dc7d0ff2f8d9fcb90b24d83bf0d1b242a82560bfdd6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [0.1.13] - 2025-04-04
2
+
3
+ - Go To Definition for action and serializers in routes
4
+ - support for `schema` objects
5
+ - better support for both ree locale conventions
6
+
1
7
  ## [0.1.11] - 2025-03-28
2
8
 
3
9
  - fixed formatting errors for methods with `rescue`
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-lsp-ree (0.1.11)
4
+ ruby-lsp-ree (0.1.13)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -14,24 +14,30 @@ module RubyLsp
14
14
  locales_folder = package_locales_folder_path(get_uri_path(uri))
15
15
  return source if !locales_folder || !File.directory?(locales_folder)
16
16
 
17
+ file_name = File.basename(uri.to_s, '.rb')
18
+
17
19
  result = []
18
20
  key_paths = []
19
21
  parsed_doc.parse_error_definitions
20
22
  parsed_doc.error_definitions.each do |error_definition|
21
- key_path = if error_definition.value.arguments.arguments.size > 1
22
- error_definition.value.arguments.arguments[1].unescaped
23
+ key_path_entries = if error_definition.value.arguments.arguments.size > 1
24
+ [error_definition.value.arguments.arguments[1].unescaped]
23
25
  else
24
26
  mod = underscore(parsed_doc.module_name)
25
- "#{mod}.errors.#{error_definition.value.arguments.arguments[0].unescaped}"
27
+ [
28
+ "#{mod}.errors.#{error_definition.value.arguments.arguments[0].unescaped}",
29
+ "#{mod}.errors.#{file_name}.#{error_definition.value.arguments.arguments[0].unescaped}"
30
+ ]
26
31
  end
27
32
 
28
- key_paths << key_path
33
+ key_paths << key_path_entries
29
34
  end
30
35
 
31
36
  Dir.glob(File.join(locales_folder, '**/*.yml')).each do |locale_file|
32
- key_paths.each do |key_path|
33
- value = find_locale_value(locale_file, key_path)
37
+ key_paths.each do |key_path_entries|
38
+ value = key_path_entries.map{ find_locale_value(locale_file, _1) }.compact.first
34
39
  unless value
40
+ key_path = key_path_entries.last
35
41
  loc_key = File.basename(locale_file, '.yml')
36
42
 
37
43
  add_locale_placeholder(locale_file, key_path)
@@ -160,13 +160,14 @@ module RubyLsp
160
160
  class_name = full_class_name.split('::').last
161
161
  package_name = package_name_from_uri(entry.uri)
162
162
  file_name = File.basename(entry.uri.to_s)
163
+ entry_comment = entry.comments && entry.comments.size > 0 ? " (#{entry.comments})" : ''
163
164
 
164
165
  matched_import = parsed_doc.find_import_for_package(class_name, package_name)
165
166
 
166
167
  if matched_import
167
168
  label_details = Interface::CompletionItemLabelDetails.new(
168
169
  description: "imported from: :#{package_name}",
169
- detail: ""
170
+ detail: entry_comment
170
171
  )
171
172
 
172
173
  imported_consts << Interface::CompletionItem.new(
@@ -183,7 +184,7 @@ module RubyLsp
183
184
  else
184
185
  label_details = Interface::CompletionItemLabelDetails.new(
185
186
  description: "from: :#{package_name}",
186
- detail: " #{file_name}"
187
+ detail: entry_comment + " #{file_name}"
187
188
  )
188
189
 
189
190
  not_imported_consts << Interface::CompletionItem.new(
@@ -46,7 +46,11 @@ module RubyLsp
46
46
  else
47
47
  # add new link
48
48
 
49
- link_text = "\s\slink #{const_link[:link_name]}, import: -> { #{@const_name} }"
49
+ link_text = if const_link[:link_type] == :file_path
50
+ "\s\slink #{const_link[:link_name]}, -> { #{@const_name} }"
51
+ else
52
+ "\s\slink #{const_link[:link_name]}, import: -> { #{@const_name} }"
53
+ end
50
54
 
51
55
  if @parsed_doc.links_container_node
52
56
  link_text = "\s\s" + link_text
@@ -84,10 +88,12 @@ module RubyLsp
84
88
 
85
89
  ree_obj_name = nil
86
90
  link_name = nil
91
+ link_type = nil
87
92
 
88
93
  if is_ree_object?(@entry.uri)
89
94
  ree_obj_name = File.basename(entry_uri, ".*")
90
95
  link_name = ":#{ree_obj_name}"
96
+ link_type = :ree_object
91
97
 
92
98
  if @package_name != @parsed_doc.package_name
93
99
  link_name += ", from: :#{@package_name}"
@@ -95,9 +101,10 @@ module RubyLsp
95
101
  else
96
102
  ree_obj_name = path_from_package_folder(entry_uri)
97
103
  link_name = "\"#{ree_obj_name}\""
104
+ link_type = :file_path
98
105
  end
99
106
 
100
- return { link_name: link_name, object_name: ree_obj_name }
107
+ return { link_name: link_name, object_name: ree_obj_name, link_type: link_type }
101
108
  end
102
109
  end
103
110
  end
@@ -102,7 +102,6 @@ module RubyLsp
102
102
  def get_linked_object_definition_items(node)
103
103
  result = []
104
104
  parent_node = @node_context.parent
105
- return [] unless parent_node.name == :link
106
105
 
107
106
  link_node = RubyLsp::Ree::ParsedLinkNode.new(parent_node, package_name_from_uri(@uri))
108
107
  package_name = link_node.link_package_name
@@ -124,6 +123,33 @@ module RubyLsp
124
123
  result
125
124
  end
126
125
 
126
+ def get_routes_definition_items(node)
127
+ parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@root_node, @uri, :route)
128
+
129
+ return [] unless parsed_doc.includes_routes_dsl?
130
+
131
+ parent_node = @node_context.parent
132
+
133
+ package_name = if parsed_doc.has_route_option?(:from)
134
+ parsed_doc.route_option_value(:from)
135
+ else
136
+ package_name_from_uri(@uri)
137
+ end
138
+
139
+ ree_object = @finder.find_object_for_package(node.unescaped, package_name)
140
+ return [] unless ree_object
141
+
142
+ [
143
+ Interface::Location.new(
144
+ uri: ree_object.uri.to_s,
145
+ range: Interface::Range.new(
146
+ start: Interface::Position.new(line: 0, character: 0),
147
+ end: Interface::Position.new(line: 0, character: 0),
148
+ ),
149
+ )
150
+ ]
151
+ end
152
+
127
153
  def get_linked_filepath_definition_items(node)
128
154
  result = []
129
155
  local_path = find_local_file_path(node.unescaped)
@@ -168,17 +194,25 @@ module RubyLsp
168
194
 
169
195
  result = []
170
196
 
171
- key_path = if @node_context.parent.arguments.arguments.size > 1
172
- @node_context.parent.arguments.arguments[1].unescaped
197
+ key_path_entries = if @node_context.parent.arguments.arguments.size > 1
198
+ [@node_context.parent.arguments.arguments[1].unescaped]
173
199
  else
174
200
  parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@root_node, @uri)
201
+ file_name = File.basename(@uri.path, '.rb')
175
202
 
176
203
  mod = underscore(parsed_doc.module_name)
177
- "#{mod}.errors.#{node.unescaped}"
204
+ [
205
+ "#{mod}.errors.#{node.unescaped}",
206
+ "#{mod}.errors.#{file_name}.#{node.unescaped}"
207
+ ]
178
208
  end
179
209
 
180
210
  Dir.glob(File.join(locales_folder, '**/*.yml')).each do |locale_file|
181
- location = find_locale_key_location(locale_file, key_path)
211
+ values = key_path_entries.map{ [_1, find_locale_value(locale_file, _1)] }
212
+ key_path = values.select{ |val| !val[1].nil? }.last
213
+ next unless key_path
214
+
215
+ location = find_locale_key_location(locale_file, key_path[0])
182
216
 
183
217
  result << Interface::Location.new(
184
218
  uri: locale_file,
@@ -109,17 +109,22 @@ module RubyLsp
109
109
 
110
110
  result = []
111
111
 
112
- key_path = if @node_context.parent.arguments.arguments.size > 1
113
- @node_context.parent.arguments.arguments[1].unescaped
112
+ key_path_entries = if @node_context.parent.arguments.arguments.size > 1
113
+ [@node_context.parent.arguments.arguments[1].unescaped]
114
114
  else
115
+ file_name = File.basename(uri.path, '.rb')
116
+
115
117
  mod = underscore(parsed_doc.module_name)
116
- "#{mod}.errors.#{node.unescaped}"
118
+ [
119
+ "#{mod}.errors.#{node.unescaped}",
120
+ "#{mod}.errors.#{file_name}.#{node.unescaped}"
121
+ ]
117
122
  end
118
123
 
119
124
  documentation = ''
120
125
 
121
126
  Dir.glob(File.join(locales_folder, '**/*.yml')).each do |locale_file|
122
- value = find_locale_value(locale_file, key_path)
127
+ value = key_path_entries.map{ find_locale_value(locale_file, _1) }.compact.first
123
128
 
124
129
  loc_key = File.basename(locale_file, '.yml')
125
130
 
@@ -44,8 +44,10 @@ module RubyLsp
44
44
  def on_symbol_node_enter(node)
45
45
  definition_items = if @ree_context.is_error_definition?
46
46
  @handler.get_error_code_definition_items(node)
47
- else
47
+ elsif @ree_context.is_link_object?
48
48
  @handler.get_linked_object_definition_items(node)
49
+ else
50
+ @handler.get_routes_definition_items(node)
49
51
  end
50
52
 
51
53
  put_items_into_response(definition_items)
@@ -16,6 +16,14 @@ class RubyLsp::Ree::ParsedBaseDocument
16
16
  false
17
17
  end
18
18
 
19
+ def includes_link_dsl?
20
+ false
21
+ end
22
+
23
+ def includes_routes_dsl?
24
+ false
25
+ end
26
+
19
27
  def includes_linked_object?(obj_name)
20
28
  @link_nodes.map(&:name).include?(obj_name)
21
29
  end
@@ -42,10 +50,6 @@ class RubyLsp::Ree::ParsedBaseDocument
42
50
  raise "abstract method"
43
51
  end
44
52
 
45
- def includes_link_dsl?
46
- raise "abstract method"
47
- end
48
-
49
53
  def parse_links
50
54
  raise "abstract method"
51
55
  end
@@ -33,6 +33,10 @@ class RubyLsp::Ree::ParsedClassDocument < RubyLsp::Ree::ParsedBaseDocument
33
33
  @class_includes.any?{ node_name(_1) == LINK_DSL_MODULE }
34
34
  end
35
35
 
36
+ def includes_routes_dsl?
37
+ @class_includes.any?{ node_name(_1) == ROUTES_DSL_MODULE }
38
+ end
39
+
36
40
  def includes_linked_constant?(const_name)
37
41
  @link_nodes.map(&:imports).flatten.include?(const_name)
38
42
  end
@@ -69,11 +73,22 @@ class RubyLsp::Ree::ParsedClassDocument < RubyLsp::Ree::ParsedBaseDocument
69
73
  return unless has_body?
70
74
 
71
75
  @class_includes ||= class_node.body.body.select{ node_name(_1) == :include }.map do |class_include|
72
- parent_name = class_include.arguments.arguments.first.parent.name.to_s
73
- module_name = class_include.arguments.arguments.first.name
76
+ first_arg = class_include.arguments.arguments.first
77
+
78
+ include_name = case first_arg
79
+ when Prism::ConstantPathNode
80
+ parent_name = class_include.arguments.arguments.first.parent.name.to_s
81
+ module_name = class_include.arguments.arguments.first.name
82
+
83
+ [parent_name, module_name].compact.join('::')
84
+ when Prism::ConstantReadNode
85
+ first_arg.name.to_s
86
+ else
87
+ ''
88
+ end
74
89
 
75
90
  OpenStruct.new(
76
- name: [parent_name, module_name].compact.join('::')
91
+ name: include_name, location: class_include.location
77
92
  )
78
93
  end
79
94
  end
@@ -1,6 +1,7 @@
1
1
  require 'prism'
2
2
  require_relative 'parsed_class_document'
3
3
  require_relative 'parsed_rspec_document'
4
+ require_relative 'parsed_route_document'
4
5
 
5
6
  class RubyLsp::Ree::ParsedDocumentBuilder
6
7
  extend RubyLsp::Ree::ReeLspUtils
@@ -37,6 +38,8 @@ class RubyLsp::Ree::ParsedDocumentBuilder
37
38
  build_dao_document(ast)
38
39
  when :bean
39
40
  build_bean_document(ast)
41
+ when :route
42
+ build_route_document(ast)
40
43
  else
41
44
  build_detected_document_type(ast, package_name)
42
45
  end
@@ -104,6 +107,10 @@ class RubyLsp::Ree::ParsedDocumentBuilder
104
107
  document
105
108
  end
106
109
 
110
+ def self.build_route_document(ast)
111
+ RubyLsp::Ree::ParsedRouteDocument.new(ast)
112
+ end
113
+
107
114
  def self.is_ruby_file?(uri)
108
115
  File.extname(uri.to_s) == '.rb'
109
116
  end
@@ -108,7 +108,7 @@ class RubyLsp::Ree::ParsedMethodNode
108
108
  elsif node.respond_to?(:statements)
109
109
  call_nodes += parse_body_call_objects(node.statements.body)
110
110
  elsif node.respond_to?(:block) && node.block
111
- call_nodes += parse_body_call_objects(node.block.body.body)
111
+ call_nodes += parse_body_call_objects(get_method_body(node.block))
112
112
  end
113
113
  end
114
114
 
@@ -0,0 +1,30 @@
1
+ class RubyLsp::Ree::ParsedRouteDocument < RubyLsp::Ree::ParsedClassDocument
2
+ include RubyLsp::Ree::ReeLspUtils
3
+
4
+ def initialize(ast, package_name = nil)
5
+ super
6
+ parse_class_includes
7
+ parse_route_options
8
+ end
9
+
10
+ def parse_route_options
11
+ @route_options ||= {}
12
+ return unless @class_node
13
+
14
+ @routes_node = @class_node.body.body.detect{ node_name(_1) == :routes }
15
+ return if !@routes_node || !@routes_node.block
16
+
17
+ @route_opts_node = @routes_node.block.body.body.detect{ node_name(_1) == :opts }
18
+ @route_opts_node.value.elements.each do |assoc_node|
19
+ @route_options[assoc_node.key.unescaped] = assoc_node.value.unescaped
20
+ end
21
+ end
22
+
23
+ def has_route_option?(option_name)
24
+ @route_options.has_key?(option_name.to_s)
25
+ end
26
+
27
+ def route_option_value(option_name)
28
+ @route_options[option_name.to_s]
29
+ end
30
+ end
@@ -31,10 +31,6 @@ class RubyLsp::Ree::ParsedRspecDocument < RubyLsp::Ree::ParsedBaseDocument
31
31
  false
32
32
  end
33
33
 
34
- def includes_link_dsl?
35
- false
36
- end
37
-
38
34
  def parse_describe_node
39
35
  @describe_node ||= @ast.statements.body.detect{ |node| node.is_a?(Prism::CallNode) && node.name == :describe }
40
36
  end
@@ -2,7 +2,8 @@ module RubyLsp
2
2
  module Ree
3
3
  module ReeConstants
4
4
  LINK_DSL_MODULE = 'Ree::LinkDSL'
5
-
5
+ ROUTES_DSL_MODULE = 'ReeRoutes::DSL'
6
+
6
7
  LINKS_CONTAINER_TYPES = [
7
8
  :fn,
8
9
  :action,
@@ -15,6 +15,12 @@ module RubyLsp
15
15
 
16
16
  ERROR_DEFINITION_NAMES.include?(@node_context.parent.name)
17
17
  end
18
+
19
+ def is_link_object?
20
+ return false if !@node_context || !@node_context.parent || !@node_context.parent.is_a?(Prism::CallNode)
21
+
22
+ @node_context.parent.name == :link
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -47,29 +47,34 @@ module RubyLsp
47
47
 
48
48
  result = []
49
49
  error_keys = []
50
+ file_name = File.basename(uri.to_s, '.rb')
50
51
 
51
52
  parsed_doc.parse_error_definitions
52
53
  parsed_doc.error_definitions.each do |error_definition|
53
- key_path = if error_definition.value.arguments.arguments.size > 1
54
- error_definition.value.arguments.arguments[1].unescaped
54
+ key_path_entries = if error_definition.value.arguments.arguments.size > 1
55
+ [error_definition.value.arguments.arguments[1].unescaped]
55
56
  else
56
57
  mod = underscore(parsed_doc.module_name)
57
- "#{mod}.errors.#{error_definition.value.arguments.arguments[0].unescaped}"
58
+ [
59
+ "#{mod}.errors.#{error_definition.value.arguments.arguments[0].unescaped}",
60
+ "#{mod}.errors.#{file_name}.#{error_definition.value.arguments.arguments[0].unescaped}"
61
+ ]
58
62
  end
59
63
 
60
- error_keys << [key_path, error_definition]
64
+ error_keys << [key_path_entries, error_definition]
61
65
  end
62
66
 
63
67
  Dir.glob(File.join(locales_folder, '**/*.yml')).each do |locale_file|
64
68
  error_keys.each do |error_key|
65
- key_path = error_key[0]
66
- value = find_locale_value(locale_file, key_path)
69
+ key_path_entries = error_key[0]
70
+ value = key_path_entries.map{ find_locale_value(locale_file, _1) }.compact.first
71
+
67
72
  if !value || value == MISSING_LOCALE_PLACEHOLDER
68
73
  loc_key = File.basename(locale_file, '.yml')
69
74
  error_definition = error_key[1]
70
75
 
71
76
  result << RubyLsp::Interface::Diagnostic.new(
72
- message: "Missing locale #{loc_key}: #{key_path}",
77
+ message: "Missing locale #{loc_key}: #{key_path_entries[0]} or #{key_path_entries[1]} ",
73
78
  source: "Ree formatter",
74
79
  severity: RubyLsp::Constant::DiagnosticSeverity::ERROR,
75
80
  range: RubyLsp::Interface::Range.new(
@@ -7,9 +7,14 @@ module RubyLsp
7
7
  include RubyLsp::Ree::ReeLspUtils
8
8
 
9
9
  REE_INDEXED_OBJECTS = [:fn, :enum, :action, :dao, :bean, :mapper, :aggregate, :async_bean]
10
+ SCHEMA_NODE_NAME = :schema
10
11
 
11
12
  def on_call_node_enter(node)
12
13
  return unless @listener.current_owner
14
+
15
+ if node.name == SCHEMA_NODE_NAME
16
+ return index_ree_schema(node)
17
+ end
13
18
 
14
19
  return unless REE_INDEXED_OBJECTS.include?(node.name)
15
20
  return unless node.arguments
@@ -37,6 +42,19 @@ module RubyLsp
37
42
 
38
43
  private
39
44
 
45
+ def index_ree_schema(node)
46
+ return if node.receiver
47
+ return if !node.arguments || !node.block
48
+
49
+ @listener.add_class(
50
+ node.arguments.arguments.first.name.to_s,
51
+ node.location,
52
+ node.location,
53
+ parent_class_name: nil,
54
+ comments: "ree_schema"
55
+ )
56
+ end
57
+
40
58
  def parse_signatures(fn_name, ast)
41
59
  class_node = ast.statements.body.detect{ |node| node.is_a?(Prism::ClassNode) }
42
60
  return [] unless class_node
@@ -68,8 +68,13 @@ 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.last.location.start_line
72
- position = parsed_doc.link_nodes.last.location.end_column + 1
71
+ if parsed_doc.link_nodes.size > 0
72
+ fn_line = parsed_doc.link_nodes.last.location.start_line
73
+ position = parsed_doc.link_nodes.last.location.end_column + 1
74
+ else
75
+ fn_line = parsed_doc.class_includes.last.location.start_line
76
+ position = parsed_doc.class_includes.last.location.end_column + 1
77
+ end
73
78
  elsif parsed_doc.allows_root_links?
74
79
  root_node_location = parsed_doc.root_node_line_location
75
80
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RubyLsp
4
4
  module Ree
5
- VERSION = "0.1.11"
5
+ VERSION = "0.1.13"
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.11
4
+ version: 0.1.13
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-28 00:00:00.000000000 Z
11
+ date: 2025-04-04 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,6 +44,7 @@ files:
44
44
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document_builder.rb
45
45
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node.rb
46
46
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_method_node.rb
47
+ - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_route_document.rb
47
48
  - lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_rspec_document.rb
48
49
  - lib/ruby_lsp/ruby_lsp_ree/ree_constants.rb
49
50
  - lib/ruby_lsp/ruby_lsp_ree/ree_context.rb