ruby-lsp-ree 0.1.6 → 0.1.7
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/lib/ruby_lsp/ruby_lsp_ree/handlers/definition_handler.rb +66 -1
- data/lib/ruby_lsp/ruby_lsp_ree/handlers/hover_handler.rb +64 -0
- data/lib/ruby_lsp/ruby_lsp_ree/listeners/definition_listener.rb +14 -2
- data/lib/ruby_lsp/ruby_lsp_ree/listeners/hover_listener.rb +18 -1
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document.rb +50 -1
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document_builder.rb +3 -3
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_method_node.rb +109 -0
- data/lib/ruby_lsp/ruby_lsp_ree/ree_context.rb +28 -0
- data/lib/ruby_lsp/ruby_lsp_ree/ree_formatter.rb +44 -1
- data/lib/ruby_lsp/ruby_lsp_ree/ree_object_finder.rb +11 -0
- data/lib/ruby_lsp/ruby_lsp_ree/utils/ree_locale_utils.rb +47 -0
- data/lib/ruby_lsp/ruby_lsp_ree/utils/ree_lsp_utils.rb +12 -1
- data/lib/ruby_lsp_ree/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d8bf3dfcc23d881b4bc1248851b63de1073b810186baeebe6d60894ea6c366a
|
4
|
+
data.tar.gz: fe3e91cb35202109f9884bfb523d473b7d54921ae839299d4201b782ea6ee0ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fc76ea86567ce249f96af8a5d50732c9f23b1dd8e0f0a307ce82d7e74234cef0e908d3cd0ad644b6f5617ab4c3f450a26a9dfe707907a46e0009a12b920b206
|
7
|
+
data.tar.gz: 507f4c378489292422e1560cfda1bfe6e3d4fc8cf8642f3f8786e0d75d389b0a9a4881b035da089ede1a8f90377f0016590441b740b5f207eae1c74b143b6f11
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -2,17 +2,20 @@ require_relative "../utils/ree_lsp_utils"
|
|
2
2
|
require_relative "../ree_object_finder"
|
3
3
|
require_relative "../parsing/parsed_link_node"
|
4
4
|
require_relative "../parsing/parsed_document_builder"
|
5
|
+
require_relative "../utils/ree_locale_utils"
|
5
6
|
|
6
7
|
module RubyLsp
|
7
8
|
module Ree
|
8
9
|
class DefinitionHandler
|
9
10
|
include Requests::Support::Common
|
10
11
|
include RubyLsp::Ree::ReeLspUtils
|
12
|
+
include RubyLsp::Ree::ReeLocaleUtils
|
11
13
|
|
12
14
|
def initialize(index, uri, node_context)
|
13
15
|
@index = index
|
14
16
|
@uri = uri
|
15
17
|
@node_context = node_context
|
18
|
+
@root_node = @node_context.instance_variable_get(:@nesting_nodes).first
|
16
19
|
@finder = ReeObjectFinder.new(@index)
|
17
20
|
end
|
18
21
|
|
@@ -71,7 +74,15 @@ module RubyLsp
|
|
71
74
|
message = node.message
|
72
75
|
result = []
|
73
76
|
|
74
|
-
|
77
|
+
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@root_node, @uri)
|
78
|
+
link_node = parsed_doc.find_link_node(message)
|
79
|
+
|
80
|
+
definition_item = if link_node
|
81
|
+
@finder.find_object_for_package(message, link_node.link_package_name)
|
82
|
+
else
|
83
|
+
@finder.find_object(message)
|
84
|
+
end
|
85
|
+
|
75
86
|
return [] unless definition_item
|
76
87
|
|
77
88
|
definition_uri = definition_item.uri.to_s
|
@@ -127,6 +138,60 @@ module RubyLsp
|
|
127
138
|
),
|
128
139
|
)
|
129
140
|
end
|
141
|
+
|
142
|
+
def get_error_locales_definition_items(node)
|
143
|
+
locales_folder = package_locales_folder_path(@uri.path)
|
144
|
+
|
145
|
+
return [] unless File.directory?(locales_folder)
|
146
|
+
|
147
|
+
result = []
|
148
|
+
key_path = node.unescaped
|
149
|
+
|
150
|
+
Dir.glob(File.join(locales_folder, '**/*.yml')).each do |locale_file|
|
151
|
+
line = find_locale_key_line(locale_file, key_path)
|
152
|
+
|
153
|
+
result << Interface::Location.new(
|
154
|
+
uri: locale_file,
|
155
|
+
range: Interface::Range.new(
|
156
|
+
start: Interface::Position.new(line: line, character: 0),
|
157
|
+
end: Interface::Position.new(line: line, character: 0),
|
158
|
+
),
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
result
|
163
|
+
end
|
164
|
+
|
165
|
+
def get_error_code_definition_items(node)
|
166
|
+
locales_folder = package_locales_folder_path(@uri.path)
|
167
|
+
|
168
|
+
return [] unless File.directory?(locales_folder)
|
169
|
+
|
170
|
+
result = []
|
171
|
+
|
172
|
+
key_path = if @node_context.parent.arguments.arguments.size > 1
|
173
|
+
@node_context.parent.arguments.arguments[1].unescaped
|
174
|
+
else
|
175
|
+
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@root_node, @uri)
|
176
|
+
|
177
|
+
mod = underscore(parsed_doc.module_name)
|
178
|
+
"#{mod}.errors.#{node.unescaped}"
|
179
|
+
end
|
180
|
+
|
181
|
+
Dir.glob(File.join(locales_folder, '**/*.yml')).each do |locale_file|
|
182
|
+
line = find_locale_key_line(locale_file, key_path)
|
183
|
+
|
184
|
+
result << Interface::Location.new(
|
185
|
+
uri: locale_file,
|
186
|
+
range: Interface::Range.new(
|
187
|
+
start: Interface::Position.new(line: line, character: 0),
|
188
|
+
end: Interface::Position.new(line: line, character: 0),
|
189
|
+
),
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
result
|
194
|
+
end
|
130
195
|
end
|
131
196
|
end
|
132
197
|
end
|
@@ -2,17 +2,20 @@ require_relative "../ree_object_finder"
|
|
2
2
|
require_relative "../parsing/parsed_document_builder"
|
3
3
|
require_relative "../parsing/parsed_link_node"
|
4
4
|
require_relative "../utils/ree_lsp_utils"
|
5
|
+
require_relative "../utils/ree_locale_utils"
|
5
6
|
|
6
7
|
module RubyLsp
|
7
8
|
module Ree
|
8
9
|
class HoverHandler
|
9
10
|
include Requests::Support::Common
|
10
11
|
include RubyLsp::Ree::ReeLspUtils
|
12
|
+
include RubyLsp::Ree::ReeLocaleUtils
|
11
13
|
|
12
14
|
def initialize(index, node_context)
|
13
15
|
@index = index
|
14
16
|
@node_context = node_context
|
15
17
|
@finder = ReeObjectFinder.new(@index)
|
18
|
+
@root_node = @node_context.instance_variable_get(:@nesting_nodes).first
|
16
19
|
end
|
17
20
|
|
18
21
|
def get_ree_object_hover_items(node)
|
@@ -61,6 +64,67 @@ module RubyLsp
|
|
61
64
|
|
62
65
|
signature.parameters.map(&:decorated_name).join(', ')
|
63
66
|
end
|
67
|
+
|
68
|
+
def get_error_locales_hover_items(node)
|
69
|
+
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@root_node, nil)
|
70
|
+
uri = get_uri_from_object(parsed_doc)
|
71
|
+
|
72
|
+
locales_folder = package_locales_folder_path(uri.path)
|
73
|
+
return [] unless File.directory?(locales_folder)
|
74
|
+
|
75
|
+
result = []
|
76
|
+
key_path = node.unescaped
|
77
|
+
|
78
|
+
documentation = ''
|
79
|
+
|
80
|
+
Dir.glob(File.join(locales_folder, '**/*.yml')).each do |locale_file|
|
81
|
+
value = find_locale_value(locale_file, key_path)
|
82
|
+
|
83
|
+
if value
|
84
|
+
loc_key = File.basename(locale_file, '.yml')
|
85
|
+
documentation += "#{loc_key}: #{value}\n\n"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
[documentation]
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_error_code_hover_items(node)
|
93
|
+
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@root_node, nil)
|
94
|
+
uri = get_uri_from_object(parsed_doc)
|
95
|
+
|
96
|
+
locales_folder = package_locales_folder_path(uri.path)
|
97
|
+
return [] unless File.directory?(locales_folder)
|
98
|
+
|
99
|
+
result = []
|
100
|
+
|
101
|
+
key_path = if @node_context.parent.arguments.arguments.size > 1
|
102
|
+
@node_context.parent.arguments.arguments[1].unescaped
|
103
|
+
else
|
104
|
+
mod = underscore(parsed_doc.module_name)
|
105
|
+
"#{mod}.errors.#{node.unescaped}"
|
106
|
+
end
|
107
|
+
|
108
|
+
documentation = ''
|
109
|
+
|
110
|
+
Dir.glob(File.join(locales_folder, '**/*.yml')).each do |locale_file|
|
111
|
+
value = find_locale_value(locale_file, key_path)
|
112
|
+
|
113
|
+
if value
|
114
|
+
loc_key = File.basename(locale_file, '.yml')
|
115
|
+
documentation += "#{loc_key}: #{value}\n\n"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
[documentation]
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_uri_from_object(parsed_doc)
|
123
|
+
obj = parsed_doc.links_container_node_name
|
124
|
+
|
125
|
+
ree_obj = @finder.find_object(obj)
|
126
|
+
ree_obj.uri
|
127
|
+
end
|
64
128
|
end
|
65
129
|
end
|
66
130
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "../handlers/definition_handler"
|
2
|
+
require_relative "../ree_context"
|
2
3
|
|
3
4
|
module RubyLsp
|
4
5
|
module Ree
|
@@ -8,6 +9,7 @@ module RubyLsp
|
|
8
9
|
def initialize(response_builder, node_context, index, dispatcher, uri)
|
9
10
|
@response_builder = response_builder
|
10
11
|
@handler = RubyLsp::Ree::DefinitionHandler.new(index, uri, node_context)
|
12
|
+
@ree_context = RubyLsp::Ree::ReeContext.new(node_context)
|
11
13
|
|
12
14
|
dispatcher.register(
|
13
15
|
self,
|
@@ -40,14 +42,24 @@ module RubyLsp
|
|
40
42
|
end
|
41
43
|
|
42
44
|
def on_symbol_node_enter(node)
|
43
|
-
definition_items = @
|
45
|
+
definition_items = if @ree_context.is_error_definition?
|
46
|
+
@handler.get_error_code_definition_items(node)
|
47
|
+
else
|
48
|
+
@handler.get_linked_object_definition_items(node)
|
49
|
+
end
|
50
|
+
|
44
51
|
put_items_into_response(definition_items)
|
45
52
|
rescue => e
|
46
53
|
$stderr.puts("error in definition listener(on_symbol_node_enter): #{e.message} : #{e.backtrace.first}")
|
47
54
|
end
|
48
55
|
|
49
56
|
def on_string_node_enter(node)
|
50
|
-
definition_items = @
|
57
|
+
definition_items = if @ree_context.is_error_definition?
|
58
|
+
@handler.get_error_locales_definition_items(node)
|
59
|
+
else
|
60
|
+
@handler.get_linked_filepath_definition_items(node)
|
61
|
+
end
|
62
|
+
|
51
63
|
put_items_into_response(definition_items)
|
52
64
|
rescue => e
|
53
65
|
$stderr.puts("error in definition listener(on_string_node_enter): #{e.message} : #{e.backtrace.first}")
|
@@ -8,11 +8,13 @@ module RubyLsp
|
|
8
8
|
def initialize(response_builder, node_context, index, dispatcher)
|
9
9
|
@response_builder = response_builder
|
10
10
|
@handler = RubyLsp::Ree::HoverHandler.new(index, node_context)
|
11
|
+
@ree_context = RubyLsp::Ree::ReeContext.new(node_context)
|
11
12
|
|
12
13
|
dispatcher.register(
|
13
14
|
self,
|
14
15
|
:on_call_node_enter,
|
15
16
|
:on_symbol_node_enter,
|
17
|
+
:on_string_node_enter,
|
16
18
|
:on_constant_read_node_enter
|
17
19
|
)
|
18
20
|
end
|
@@ -36,8 +38,23 @@ module RubyLsp
|
|
36
38
|
$stderr.puts("error in hover listener(on_call_node_enter): #{e.message} : #{e.backtrace.first}")
|
37
39
|
end
|
38
40
|
|
41
|
+
def on_string_node_enter(node)
|
42
|
+
return unless @ree_context.is_error_definition?
|
43
|
+
|
44
|
+
hover_items = @handler.get_error_locales_hover_items(node)
|
45
|
+
|
46
|
+
put_items_into_response(hover_items)
|
47
|
+
rescue => e
|
48
|
+
$stderr.puts("error in hover listener(on_string_node_enter): #{e.message} : #{e.backtrace.first}")
|
49
|
+
end
|
50
|
+
|
39
51
|
def on_symbol_node_enter(node)
|
40
|
-
hover_items = @
|
52
|
+
hover_items = if @ree_context.is_error_definition?
|
53
|
+
@handler.get_error_code_hover_items(node)
|
54
|
+
else
|
55
|
+
@handler.get_linked_object_hover_items(node)
|
56
|
+
end
|
57
|
+
|
41
58
|
put_items_into_response(hover_items)
|
42
59
|
rescue => e
|
43
60
|
$stderr.puts("error in hover listener(on_symbol_node_enter): #{e.message} : #{e.backtrace.first}")
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'parsed_link_node'
|
2
|
+
require_relative 'parsed_method_node'
|
2
3
|
require 'ostruct'
|
3
4
|
|
4
5
|
class RubyLsp::Ree::ParsedDocument
|
@@ -6,9 +7,26 @@ class RubyLsp::Ree::ParsedDocument
|
|
6
7
|
|
7
8
|
LINK_DSL_MODULE = 'Ree::LinkDSL'
|
8
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
|
+
|
9
26
|
attr_reader :ast, :package_name, :class_node, :fn_node, :class_includes,
|
10
27
|
:link_nodes, :values, :action_node, :dao_node, :filters,
|
11
|
-
:bean_node, :bean_methods, :mapper_node, :links_container_block_node, :aggregate_node
|
28
|
+
:bean_node, :bean_methods, :mapper_node, :links_container_block_node, :aggregate_node,
|
29
|
+
:error_definitions, :doc_instance_methods
|
12
30
|
|
13
31
|
def initialize(ast)
|
14
32
|
@ast = ast
|
@@ -161,6 +179,25 @@ class RubyLsp::Ree::ParsedDocument
|
|
161
179
|
.map{ OpenStruct.new(name: node_name(_1).to_s, signatures: parse_signatures_from_params(_1.parameters)) }
|
162
180
|
end
|
163
181
|
|
182
|
+
def parse_instance_methods
|
183
|
+
@doc_instance_methods = []
|
184
|
+
|
185
|
+
current_contract_node = nil
|
186
|
+
class_node.body.body.each do |node|
|
187
|
+
if node.is_a?(Prism::CallNode) && CONTRACT_CALL_NODE_NAMES.include?(node_name(node))
|
188
|
+
current_contract_node = node
|
189
|
+
else
|
190
|
+
if node.is_a?(Prism::DefNode)
|
191
|
+
@doc_instance_methods << RubyLsp::Ree::ParsedMethodNode.new(node, current_contract_node)
|
192
|
+
end
|
193
|
+
|
194
|
+
current_contract_node = nil
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
@doc_instance_methods
|
199
|
+
end
|
200
|
+
|
164
201
|
def parse_filter_signature(filter_node)
|
165
202
|
return [] unless filter_node
|
166
203
|
|
@@ -175,10 +212,22 @@ class RubyLsp::Ree::ParsedDocument
|
|
175
212
|
[RubyIndexer::Entry::Signature.new(signature_params)]
|
176
213
|
end
|
177
214
|
|
215
|
+
def parse_error_definitions
|
216
|
+
return unless class_node
|
217
|
+
|
218
|
+
@error_definitions = class_node.body.body
|
219
|
+
.select{ _1.is_a?(Prism::ConstantWriteNode) }
|
220
|
+
.select{ ERROR_DEFINITION_NAMES.include?(node_name(_1.value)) }
|
221
|
+
end
|
222
|
+
|
178
223
|
def class_name
|
179
224
|
class_node.constant_path.name.to_s
|
180
225
|
end
|
181
226
|
|
227
|
+
def module_name
|
228
|
+
class_node.constant_path&.parent&.name.to_s
|
229
|
+
end
|
230
|
+
|
182
231
|
def full_class_name
|
183
232
|
name_parts = [class_node.constant_path&.parent&.name, class_node.constant_path.name]
|
184
233
|
name_parts.compact.map(&:to_s).join('::')
|
@@ -38,11 +38,11 @@ class RubyLsp::Ree::ParsedDocumentBuilder
|
|
38
38
|
when :bean
|
39
39
|
build_bean_document(ast)
|
40
40
|
else
|
41
|
-
|
41
|
+
build_detected_document_type(ast)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
def self.
|
45
|
+
def self.build_detected_document_type(ast)
|
46
46
|
if has_root_class?(ast)
|
47
47
|
build_regular_document(ast)
|
48
48
|
elsif has_root_rspec_call?(ast)
|
@@ -53,7 +53,7 @@ class RubyLsp::Ree::ParsedDocumentBuilder
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def self.has_root_class?(ast)
|
56
|
-
ast.statements.body.detect{ |node| node.is_a?(Prism::ClassNode) }
|
56
|
+
!!ast.statements.body.detect{ |node| node.is_a?(Prism::ClassNode) }
|
57
57
|
end
|
58
58
|
|
59
59
|
def self.has_root_rspec_call?(ast)
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'prism'
|
2
|
+
|
3
|
+
class RubyLsp::Ree::ParsedMethodNode
|
4
|
+
attr_reader :method_node, :contract_node
|
5
|
+
|
6
|
+
def initialize(method_node, contract_node)
|
7
|
+
@method_node = method_node
|
8
|
+
@contract_node = contract_node
|
9
|
+
end
|
10
|
+
|
11
|
+
def name
|
12
|
+
@method_node.name
|
13
|
+
end
|
14
|
+
|
15
|
+
def has_contract?
|
16
|
+
!!@contract_node
|
17
|
+
end
|
18
|
+
|
19
|
+
def start_line
|
20
|
+
@method_node.location.start_line - 1
|
21
|
+
end
|
22
|
+
|
23
|
+
def end_line
|
24
|
+
@method_node.location.end_line - 1
|
25
|
+
end
|
26
|
+
|
27
|
+
def raised_errors_nested(source, error_definitions)
|
28
|
+
return [] if error_definitions.size == 0
|
29
|
+
|
30
|
+
raised = raised_errors(source, error_definitions)
|
31
|
+
|
32
|
+
not_detected_errors = error_definitions.select{ !raised.include?(_1.name.to_s) }
|
33
|
+
@nested_local_methods.each do |nested_method|
|
34
|
+
raised += nested_method.raised_errors_nested(source, not_detected_errors)
|
35
|
+
not_detected_errors = error_definitions.select{ !raised.include?(_1.name.to_s) }
|
36
|
+
end
|
37
|
+
|
38
|
+
raised
|
39
|
+
end
|
40
|
+
|
41
|
+
def raised_errors(source, error_definitions)
|
42
|
+
raised = []
|
43
|
+
error_names = error_definitions.map(&:name).map(&:to_s)
|
44
|
+
|
45
|
+
source.lines[start_line+1 .. end_line-1].each do |line|
|
46
|
+
error_names.each do |error_name|
|
47
|
+
regex = /\braise #{Regexp.escape(error_name)}\b/
|
48
|
+
|
49
|
+
if line.match?(regex)
|
50
|
+
raised << error_name
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
raised.uniq
|
56
|
+
end
|
57
|
+
|
58
|
+
def throws_errors
|
59
|
+
return [] unless has_contract?
|
60
|
+
return [] unless has_throw_section?
|
61
|
+
|
62
|
+
@contract_node.arguments.arguments.map{ _1.name.to_s }
|
63
|
+
end
|
64
|
+
|
65
|
+
def has_throw_section?
|
66
|
+
@contract_node && @contract_node.name == :throws
|
67
|
+
end
|
68
|
+
|
69
|
+
def throw_arguments_end_position
|
70
|
+
@contract_node.arguments.arguments.last.location.end_column - 1
|
71
|
+
end
|
72
|
+
|
73
|
+
def throw_arguments_end_line
|
74
|
+
@contract_node.arguments.arguments.last.location.end_line - 1
|
75
|
+
end
|
76
|
+
|
77
|
+
def contract_node_end_position
|
78
|
+
@contract_node.location.end_column - 1
|
79
|
+
end
|
80
|
+
|
81
|
+
def contract_node_end_line
|
82
|
+
@contract_node.location.end_line - 1
|
83
|
+
end
|
84
|
+
|
85
|
+
def parse_nested_local_methods(local_methods)
|
86
|
+
local_method_names = local_methods.map(&:name)
|
87
|
+
call_nodes = parse_body_call_objects(@method_node.body.body)
|
88
|
+
call_node_names = call_nodes.map(&:name)
|
89
|
+
|
90
|
+
@nested_local_methods = local_methods.select{ call_node_names.include?(_1.name) }
|
91
|
+
@nested_local_methods.each{ _1.parse_nested_local_methods(local_methods) }
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse_body_call_objects(node_body)
|
95
|
+
call_nodes = []
|
96
|
+
|
97
|
+
node_body.each do |node|
|
98
|
+
if node.is_a?(Prism::CallNode) && !node.receiver
|
99
|
+
call_nodes << node
|
100
|
+
elsif node.respond_to?(:statements)
|
101
|
+
call_nodes += parse_body_call_objects(node.statements.body)
|
102
|
+
elsif node.respond_to?(:block) && node.block
|
103
|
+
call_nodes += parse_body_call_objects(node.block.body.body)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
call_nodes
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'prism'
|
2
|
+
|
3
|
+
module RubyLsp
|
4
|
+
module Ree
|
5
|
+
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
|
+
]
|
16
|
+
|
17
|
+
def initialize(node_context)
|
18
|
+
@node_context = node_context
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_error_definition?
|
22
|
+
return false if !@node_context || !@node_context.parent || !@node_context.parent.is_a?(Prism::CallNode)
|
23
|
+
|
24
|
+
ERROR_DEFINITION_NAMES.include?(@node_context.parent.name)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -9,7 +9,9 @@ module RubyLsp
|
|
9
9
|
|
10
10
|
def run_formatting(uri, document)
|
11
11
|
source = document.source
|
12
|
-
|
12
|
+
|
13
|
+
sorted_source = sort_links(source)
|
14
|
+
add_missing_error_contracts(sorted_source)
|
13
15
|
rescue => e
|
14
16
|
$stderr.puts("error in ree_formatter: #{e.message} : #{e.backtrace.first}")
|
15
17
|
end
|
@@ -57,6 +59,47 @@ module RubyLsp
|
|
57
59
|
source_lines[link_line - 1] = sorted_lines[index]
|
58
60
|
end
|
59
61
|
|
62
|
+
source_lines.join()
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_missing_error_contracts(source)
|
66
|
+
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_source(source)
|
67
|
+
return source if !parsed_doc || !parsed_doc.class_node
|
68
|
+
|
69
|
+
parsed_doc.parse_error_definitions
|
70
|
+
parsed_doc.parse_instance_methods
|
71
|
+
|
72
|
+
parsed_doc.doc_instance_methods.select(&:has_contract?).each do |doc_instance_method|
|
73
|
+
doc_instance_method.parse_nested_local_methods(parsed_doc.doc_instance_methods)
|
74
|
+
|
75
|
+
raised_errors = doc_instance_method.raised_errors_nested(source, parsed_doc.error_definitions)
|
76
|
+
throws_errors = doc_instance_method.throws_errors
|
77
|
+
|
78
|
+
missed_errors = raised_errors - throws_errors
|
79
|
+
source = add_missed_errors(source, doc_instance_method, missed_errors)
|
80
|
+
end
|
81
|
+
|
82
|
+
source
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_missed_errors(source, doc_instance_method, missed_errors)
|
86
|
+
return source if missed_errors.size == 0
|
87
|
+
|
88
|
+
source_lines = source.lines
|
89
|
+
|
90
|
+
if doc_instance_method.has_throw_section?
|
91
|
+
position = doc_instance_method.throw_arguments_end_position
|
92
|
+
line = doc_instance_method.throw_arguments_end_line
|
93
|
+
|
94
|
+
source_lines[line] = source_lines[line][0..position] + ", #{missed_errors.join(', ')})\n"
|
95
|
+
else
|
96
|
+
position = doc_instance_method.contract_node_end_position
|
97
|
+
line = doc_instance_method.contract_node_end_line
|
98
|
+
|
99
|
+
source_lines[line] = source_lines[line][0..position] + ".throws(#{missed_errors.join(', ')})\n"
|
100
|
+
end
|
101
|
+
|
102
|
+
|
60
103
|
source_lines.join()
|
61
104
|
end
|
62
105
|
end
|
@@ -1,6 +1,10 @@
|
|
1
|
+
require_relative "utils/ree_lsp_utils"
|
2
|
+
|
1
3
|
module RubyLsp
|
2
4
|
module Ree
|
3
5
|
class ReeObjectFinder
|
6
|
+
include RubyLsp::Ree::ReeLspUtils
|
7
|
+
|
4
8
|
MAX_LIMIT = 1000
|
5
9
|
|
6
10
|
REE_OBJECT_STRING = 'ree_object'
|
@@ -42,6 +46,13 @@ module RubyLsp
|
|
42
46
|
objects_by_name.detect{ _1.comments.to_s.lines.first&.chomp == REE_OBJECT_STRING }
|
43
47
|
end
|
44
48
|
|
49
|
+
def find_object_for_package(name, package_name)
|
50
|
+
objects_by_name = @index[name]
|
51
|
+
return unless objects_by_name
|
52
|
+
|
53
|
+
objects_by_name.detect{ _1.comments.to_s.lines.first&.chomp == REE_OBJECT_STRING && package_name_from_uri(_1.uri) == package_name }
|
54
|
+
end
|
55
|
+
|
45
56
|
def find_objects_by_types(name, types)
|
46
57
|
objects_by_name = @index[name]
|
47
58
|
return [] unless objects_by_name
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module RubyLsp
|
4
|
+
module Ree
|
5
|
+
module ReeLocaleUtils
|
6
|
+
def package_locales_folder_path(uri)
|
7
|
+
uri_parts = uri.to_s.chomp(File.extname(uri.to_s)).split('/')
|
8
|
+
|
9
|
+
package_folder_index = uri_parts.index('package')
|
10
|
+
return unless package_folder_index
|
11
|
+
|
12
|
+
path_parts = uri_parts.take(package_folder_index+2) + ['locales']
|
13
|
+
path_parts.join('/')
|
14
|
+
end
|
15
|
+
|
16
|
+
def find_locale_value(file_path, key_path)
|
17
|
+
loc_yaml = YAML.load_file(file_path)
|
18
|
+
loc_key = File.basename(file_path, '.yml')
|
19
|
+
key_parts = [loc_key] + key_path.split('.')
|
20
|
+
|
21
|
+
loc_yaml.dig(*key_parts)
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_locale_key_line(file_path, key_path)
|
25
|
+
loc_key = File.basename(file_path, '.yml')
|
26
|
+
|
27
|
+
key_parts = [loc_key] + key_path.split('.')
|
28
|
+
|
29
|
+
current_key_index = 0
|
30
|
+
current_key = key_parts[current_key_index]
|
31
|
+
regex = /^\s*#{Regexp.escape(current_key)}:/
|
32
|
+
|
33
|
+
File.open(file_path, 'r:UTF-8').each_with_index do |line, line_index|
|
34
|
+
if line.match?(regex)
|
35
|
+
current_key_index += 1
|
36
|
+
current_key = key_parts[current_key_index]
|
37
|
+
return line_index unless current_key
|
38
|
+
|
39
|
+
regex = /^\s*#{Regexp.escape(current_key)}:/
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
0
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -7,7 +7,7 @@ module RubyLsp
|
|
7
7
|
file_name = file_path + ".rb"
|
8
8
|
Dir[File.join('**', file_name)].first
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def package_name_from_uri(uri)
|
12
12
|
uri_parts = uri.to_s.split('/')
|
13
13
|
|
@@ -170,6 +170,17 @@ module RubyLsp
|
|
170
170
|
:"(#{names_with_commas})"
|
171
171
|
end
|
172
172
|
end
|
173
|
+
|
174
|
+
# copied from ree string_utils
|
175
|
+
def underscore(camel_cased_word)
|
176
|
+
return camel_cased_word unless /[A-Z-]|::/.match?(camel_cased_word)
|
177
|
+
word = camel_cased_word.to_s.gsub("::".freeze, "/".freeze)
|
178
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2'.freeze)
|
179
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2'.freeze)
|
180
|
+
word.tr!("-".freeze, "_".freeze)
|
181
|
+
word.downcase!
|
182
|
+
word
|
183
|
+
end
|
173
184
|
end
|
174
185
|
end
|
175
186
|
end
|
data/lib/ruby_lsp_ree/version.rb
CHANGED
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.
|
4
|
+
version: 0.1.7
|
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-
|
11
|
+
date: 2025-03-20 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:
|
@@ -35,12 +35,15 @@ files:
|
|
35
35
|
- lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document.rb
|
36
36
|
- lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document_builder.rb
|
37
37
|
- lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node.rb
|
38
|
+
- lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_method_node.rb
|
38
39
|
- lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_rspec_document.rb
|
40
|
+
- lib/ruby_lsp/ruby_lsp_ree/ree_context.rb
|
39
41
|
- lib/ruby_lsp/ruby_lsp_ree/ree_formatter.rb
|
40
42
|
- lib/ruby_lsp/ruby_lsp_ree/ree_indexing_enhancement.rb
|
41
43
|
- lib/ruby_lsp/ruby_lsp_ree/ree_object_finder.rb
|
42
44
|
- lib/ruby_lsp/ruby_lsp_ree/ree_rename_handler.rb
|
43
45
|
- lib/ruby_lsp/ruby_lsp_ree/ree_template_applicator.rb
|
46
|
+
- lib/ruby_lsp/ruby_lsp_ree/utils/ree_locale_utils.rb
|
44
47
|
- lib/ruby_lsp/ruby_lsp_ree/utils/ree_lsp_utils.rb
|
45
48
|
- lib/ruby_lsp_ree.rb
|
46
49
|
- lib/ruby_lsp_ree/version.rb
|