ruby-lsp-ree 0.1.14 → 0.1.16
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 +9 -0
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/lib/ruby_lsp/ruby_lsp_ree/completion/completion_items_mapper.rb +183 -0
- data/lib/ruby_lsp/ruby_lsp_ree/{handlers → completion}/method_additional_text_edits_creator.rb +1 -1
- data/lib/ruby_lsp/ruby_lsp_ree/formatters/base_formatter.rb +3 -0
- data/lib/ruby_lsp/ruby_lsp_ree/formatters/missing_imports_formatter.rb +63 -0
- data/lib/ruby_lsp/ruby_lsp_ree/formatters/unused_links_formatter.rb +19 -13
- data/lib/ruby_lsp/ruby_lsp_ree/handlers/completion_handler.rb +13 -208
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/call_objects_parser.rb +104 -0
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/local_variables_parser.rb +52 -0
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_class_document.rb +11 -0
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node.rb +34 -6
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_method_node.rb +27 -0
- data/lib/ruby_lsp/ruby_lsp_ree/ree_formatter.rb +3 -1
- data/lib/ruby_lsp/ruby_lsp_ree/ree_source_editor.rb +32 -2
- data/lib/ruby_lsp_ree/version.rb +1 -1
- metadata +8 -4
- /data/lib/ruby_lsp/ruby_lsp_ree/{handlers → completion}/const_additional_text_edits_creator.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d1b2bf9c373c729b6412704fd6daf364ed4c8b278405f52b4c1fc32b256570c
|
4
|
+
data.tar.gz: 0bde5c4413ec6d4ccfd807dc6e6eb33d1e47ab018dfbfaad47200775b2c3badb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a97047d4924f208415ba6c5ed45e6abb57141e74fd44ad79368a9a7dd025a2ce0c36cfe2ca95db6fd0dab9586d9a1c5484be2e930ab129ab6acb7975fce310f
|
7
|
+
data.tar.gz: 17daba371512607775021704c56895bcc9e41666e598c9603c7da22ebac567de1cc7a2957f050a6657429057557dcbbc86654141eba98faa8c7ddde6e892a030
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## [0.1.16] - 2025-04-24
|
2
|
+
|
3
|
+
- formatter: add missing imports
|
4
|
+
|
5
|
+
## [0.1.15] - 2025-04-18
|
6
|
+
|
7
|
+
- autocomplete - don't overwrite existing arguments
|
8
|
+
- unused links formatter - handle const aliases
|
9
|
+
|
1
10
|
## [0.1.14] - 2025-04-15
|
2
11
|
|
3
12
|
- do not create error definition for defined class
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -32,7 +32,7 @@ To switch off/on formatter features, use Ruby LSP addon settings:
|
|
32
32
|
}
|
33
33
|
}
|
34
34
|
```
|
35
|
-
available formatters: `SortLinksFormatter`, `MissingErrorDefinitionsFormatter`, `MissingErrorContractsFormatter`, `MissingErrorLocalesFormatter`, `UnusedLinksFormatter`
|
35
|
+
available formatters: `SortLinksFormatter`, `MissingErrorDefinitionsFormatter`, `MissingErrorContractsFormatter`, `MissingErrorLocalesFormatter`, `UnusedLinksFormatter`, `MissingImportsFormatter`
|
36
36
|
|
37
37
|
## Functions
|
38
38
|
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require_relative 'method_additional_text_edits_creator'
|
2
|
+
require_relative 'const_additional_text_edits_creator'
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module Ree
|
6
|
+
class CompletionItemsMapper
|
7
|
+
include Requests::Support::Common
|
8
|
+
include RubyLsp::Ree::ReeLspUtils
|
9
|
+
|
10
|
+
def initialize(index)
|
11
|
+
@index = index
|
12
|
+
end
|
13
|
+
|
14
|
+
def map_ree_object_methods(ree_object_methods, location, node, description)
|
15
|
+
default_range = Interface::Range.new(
|
16
|
+
start: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
17
|
+
end: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
18
|
+
)
|
19
|
+
|
20
|
+
ree_object_methods.map do |object_method|
|
21
|
+
signature = object_method.signatures&.first
|
22
|
+
|
23
|
+
label_details = Interface::CompletionItemLabelDetails.new(
|
24
|
+
description: description,
|
25
|
+
detail: get_detail_string(signature)
|
26
|
+
)
|
27
|
+
|
28
|
+
if node.arguments && node.name.to_s == object_method.name
|
29
|
+
new_text = object_method.name
|
30
|
+
method_range = range_from_location(node.message_loc)
|
31
|
+
else
|
32
|
+
new_text = get_method_string(object_method.name, signature)
|
33
|
+
method_range = default_range
|
34
|
+
end
|
35
|
+
|
36
|
+
Interface::CompletionItem.new(
|
37
|
+
label: object_method.name,
|
38
|
+
label_details: label_details,
|
39
|
+
filter_text: object_method.name,
|
40
|
+
text_edit: Interface::TextEdit.new(
|
41
|
+
range: method_range,
|
42
|
+
new_text: new_text
|
43
|
+
),
|
44
|
+
kind: Constant::CompletionItemKind::METHOD,
|
45
|
+
insert_text_format: Constant::InsertTextFormat::SNIPPET,
|
46
|
+
data: {
|
47
|
+
owner_name: "Object",
|
48
|
+
guessed_type: false,
|
49
|
+
}
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def map_ree_objects(ree_objects, node, parsed_doc)
|
55
|
+
ree_objects.map do |ree_object|
|
56
|
+
ree_object_name = ree_object.name
|
57
|
+
package_name = package_name_from_uri(ree_object.uri)
|
58
|
+
signature = ree_object.signatures.first
|
59
|
+
ree_type = get_ree_type(ree_object)
|
60
|
+
|
61
|
+
label_details = Interface::CompletionItemLabelDetails.new(
|
62
|
+
description: "#{ree_type}, from: :#{package_name}",
|
63
|
+
detail: get_detail_string(signature)
|
64
|
+
)
|
65
|
+
|
66
|
+
if node.arguments && node.name.to_s == ree_object_name
|
67
|
+
new_text = ree_object_name
|
68
|
+
range = range_from_location(node.message_loc)
|
69
|
+
else
|
70
|
+
new_text = get_method_string(ree_object_name, signature)
|
71
|
+
range = range_from_location(node.location)
|
72
|
+
end
|
73
|
+
|
74
|
+
Interface::CompletionItem.new(
|
75
|
+
label: ree_object_name,
|
76
|
+
label_details: label_details,
|
77
|
+
filter_text: ree_object_name,
|
78
|
+
text_edit: Interface::TextEdit.new(
|
79
|
+
range: range,
|
80
|
+
new_text: new_text
|
81
|
+
),
|
82
|
+
kind: Constant::CompletionItemKind::METHOD,
|
83
|
+
insert_text_format: Constant::InsertTextFormat::SNIPPET,
|
84
|
+
data: {
|
85
|
+
owner_name: "Object",
|
86
|
+
guessed_type: false,
|
87
|
+
},
|
88
|
+
additional_text_edits: MethodAdditionalTextEditsCreator.call(parsed_doc, ree_object_name, package_name)
|
89
|
+
)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def map_class_name_objects(class_name_objects, node, parsed_doc)
|
94
|
+
imported_consts = []
|
95
|
+
not_imported_consts = []
|
96
|
+
|
97
|
+
class_name_objects.each do |full_class_name|
|
98
|
+
entries = @index[full_class_name]
|
99
|
+
|
100
|
+
entries.each do |entry|
|
101
|
+
class_name = full_class_name.split('::').last
|
102
|
+
package_name = package_name_from_uri(entry.uri)
|
103
|
+
file_name = File.basename(entry.uri.to_s)
|
104
|
+
entry_comment = entry.comments && entry.comments.size > 0 ? " (#{entry.comments})" : ''
|
105
|
+
|
106
|
+
matched_import = parsed_doc.find_import_for_package(class_name, package_name)
|
107
|
+
|
108
|
+
if matched_import
|
109
|
+
label_details = Interface::CompletionItemLabelDetails.new(
|
110
|
+
description: "imported from: :#{package_name}",
|
111
|
+
detail: entry_comment
|
112
|
+
)
|
113
|
+
|
114
|
+
imported_consts << Interface::CompletionItem.new(
|
115
|
+
label: class_name,
|
116
|
+
label_details: label_details,
|
117
|
+
filter_text: class_name,
|
118
|
+
text_edit: Interface::TextEdit.new(
|
119
|
+
range: range_from_location(node.location),
|
120
|
+
new_text: class_name,
|
121
|
+
),
|
122
|
+
kind: Constant::CompletionItemKind::CLASS,
|
123
|
+
additional_text_edits: []
|
124
|
+
)
|
125
|
+
else
|
126
|
+
label_details = Interface::CompletionItemLabelDetails.new(
|
127
|
+
description: "from: :#{package_name}",
|
128
|
+
detail: entry_comment + " #{file_name}"
|
129
|
+
)
|
130
|
+
|
131
|
+
not_imported_consts << Interface::CompletionItem.new(
|
132
|
+
label: class_name,
|
133
|
+
label_details: label_details,
|
134
|
+
filter_text: class_name,
|
135
|
+
text_edit: Interface::TextEdit.new(
|
136
|
+
range: range_from_location(node.location),
|
137
|
+
new_text: class_name,
|
138
|
+
),
|
139
|
+
kind: Constant::CompletionItemKind::CLASS,
|
140
|
+
additional_text_edits: ConstAdditionalTextEditsCreator.call(parsed_doc, class_name, package_name, entry)
|
141
|
+
)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
imported_consts + not_imported_consts
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def get_detail_string(signature)
|
152
|
+
return '' unless signature
|
153
|
+
|
154
|
+
"(#{get_parameters_string(signature)})"
|
155
|
+
end
|
156
|
+
|
157
|
+
def get_parameters_string(signature)
|
158
|
+
return '' unless signature
|
159
|
+
|
160
|
+
signature.parameters.map(&:decorated_name).join(', ')
|
161
|
+
end
|
162
|
+
|
163
|
+
def get_method_string(fn_name, signature)
|
164
|
+
return fn_name unless signature
|
165
|
+
|
166
|
+
"#{fn_name}(#{get_parameters_placeholder(signature)})"
|
167
|
+
end
|
168
|
+
|
169
|
+
def get_parameters_placeholder(signature)
|
170
|
+
return '' unless signature
|
171
|
+
|
172
|
+
signature.parameters.to_enum.with_index.map do |signature_param, index|
|
173
|
+
case signature_param
|
174
|
+
when RubyIndexer::Entry::KeywordParameter, RubyIndexer::Entry::OptionalKeywordParameter
|
175
|
+
"#{signature_param.name}: ${#{index+1}:#{signature_param.name}}"
|
176
|
+
else
|
177
|
+
"${#{index+1}:#{signature_param.name}}"
|
178
|
+
end
|
179
|
+
end.join(', ')
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -3,6 +3,9 @@ module RubyLsp
|
|
3
3
|
class BaseFormatter
|
4
4
|
def self.call(source, uri, message_queue, index)
|
5
5
|
new(message_queue, index).call(source, uri)
|
6
|
+
rescue => e
|
7
|
+
$stderr.puts("error in #{self}: #{e.message} : #{e.backtrace.first}")
|
8
|
+
source
|
6
9
|
end
|
7
10
|
|
8
11
|
def initialize(message_queue, index)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative 'base_formatter'
|
2
|
+
require_relative "../ree_object_finder"
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module Ree
|
6
|
+
class MissingImportsFormatter < BaseFormatter
|
7
|
+
include RubyLsp::Ree::ReeLspUtils
|
8
|
+
|
9
|
+
def call(source, uri)
|
10
|
+
return source unless @index
|
11
|
+
|
12
|
+
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_source(source)
|
13
|
+
return source if !parsed_doc || !parsed_doc.has_root_class?
|
14
|
+
|
15
|
+
finder = ReeObjectFinder.new(@index)
|
16
|
+
editor = RubyLsp::Ree::ReeSourceEditor.new(source)
|
17
|
+
|
18
|
+
current_package = package_name_from_uri(uri)
|
19
|
+
|
20
|
+
fn_calls = parsed_doc.parse_fn_calls
|
21
|
+
filtered_fn_calls = filter_fn_calls(parsed_doc, fn_calls)
|
22
|
+
objects_to_add = filtered_fn_calls.map{ |fn_call|
|
23
|
+
finder.find_object(fn_call.name.to_s)
|
24
|
+
}.compact
|
25
|
+
|
26
|
+
bean_calls = parsed_doc.parse_bean_calls
|
27
|
+
filtered_bean_calls = filter_bean_calls(parsed_doc, bean_calls)
|
28
|
+
objects_to_add += filtered_bean_calls.map{ |bean_call|
|
29
|
+
finder.find_object(bean_call.receiver_name.to_s)
|
30
|
+
}.compact
|
31
|
+
|
32
|
+
objects_to_add.uniq!{ |obj| obj.name }
|
33
|
+
objects_to_add.reject!{ |obj| parsed_doc.includes_linked_object?(obj.name) }
|
34
|
+
return editor.source if objects_to_add.size == 0
|
35
|
+
|
36
|
+
editor.add_links(parsed_doc, objects_to_add, current_package)
|
37
|
+
editor.source
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def filter_fn_calls(parsed_doc, fn_calls)
|
43
|
+
parsed_doc.parse_instance_methods
|
44
|
+
|
45
|
+
fn_calls.reject{ |fn_call|
|
46
|
+
parsed_doc.doc_instance_methods.map(&:name).include?(fn_call.name)
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def filter_bean_calls(parsed_doc, bean_calls)
|
51
|
+
bean_calls.select do |bean_call|
|
52
|
+
if !bean_call.method_name
|
53
|
+
true
|
54
|
+
else
|
55
|
+
method_obj = parsed_doc.doc_instance_methods.detect{ _1.name == bean_call.method_name }
|
56
|
+
local_variables = method_obj.parse_local_variables
|
57
|
+
!local_variables.map(&:name).include?(bean_call.receiver_name)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -7,38 +7,34 @@ module RubyLsp
|
|
7
7
|
class UnusedLinksFormatter < BaseFormatter
|
8
8
|
include RubyLsp::Ree::ReeLspUtils
|
9
9
|
|
10
|
+
attr_reader :editor, :dsl_parser
|
11
|
+
|
10
12
|
def call(source, _uri)
|
11
13
|
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_source(source)
|
12
14
|
return source if !parsed_doc
|
13
15
|
|
14
16
|
parsed_doc.parse_links
|
15
17
|
|
16
|
-
editor = RubyLsp::Ree::ReeSourceEditor.new(source)
|
17
|
-
dsl_parser = RubyLsp::Ree::ReeDslParser.new(parsed_doc, @index)
|
18
|
+
@editor = RubyLsp::Ree::ReeSourceEditor.new(source)
|
19
|
+
@dsl_parser = RubyLsp::Ree::ReeDslParser.new(parsed_doc, @index)
|
18
20
|
|
19
21
|
links_count = parsed_doc.link_nodes.size
|
20
22
|
|
21
23
|
removed_links = 0
|
22
24
|
|
23
25
|
parsed_doc.link_nodes.each do |link_node|
|
24
|
-
|
26
|
+
remove_imports = []
|
25
27
|
|
26
28
|
if link_node.has_import_section?
|
27
|
-
link_node.imports.
|
28
|
-
|
29
|
-
next if editor.contains_link_import_usage?(link_node, link_import) || dsl_parser.contains_object_usage?(link_import)
|
30
|
-
|
31
|
-
editor.remove_link_import(link_node, link_import)
|
32
|
-
removed_imports += 1
|
33
|
-
end
|
29
|
+
remove_imports = link_node.imports.reject{ |imp| import_is_used?(link_node, imp) }
|
30
|
+
editor.remove_link_imports(link_node, remove_imports)
|
34
31
|
|
35
|
-
if link_node.imports.size ==
|
32
|
+
if link_node.imports.size == remove_imports.size
|
36
33
|
editor.remove_link_import_arg(link_node)
|
37
34
|
end
|
38
35
|
end
|
39
36
|
|
40
|
-
|
41
|
-
next if editor.contains_link_usage?(link_node) || link_node.imports.size > removed_imports || dsl_parser.contains_object_usage?(link_node.name)
|
37
|
+
next if link_is_used?(link_node, remove_imports)
|
42
38
|
|
43
39
|
editor.remove_link(link_node)
|
44
40
|
removed_links += 1
|
@@ -51,6 +47,16 @@ module RubyLsp
|
|
51
47
|
|
52
48
|
editor.source
|
53
49
|
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def import_is_used?(link_node, link_import)
|
54
|
+
editor.contains_link_import_usage?(link_node, link_import) || dsl_parser.contains_object_usage?(link_import)
|
55
|
+
end
|
56
|
+
|
57
|
+
def link_is_used?(link_node, remove_imports)
|
58
|
+
editor.contains_link_usage?(link_node) || link_node.imports.size > remove_imports.size || dsl_parser.contains_object_usage?(link_node.name)
|
59
|
+
end
|
54
60
|
end
|
55
61
|
end
|
56
62
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative "../utils/ree_lsp_utils"
|
2
2
|
require_relative "../ree_object_finder"
|
3
|
-
require_relative '
|
4
|
-
require_relative 'method_additional_text_edits_creator'
|
3
|
+
require_relative '../completion/completion_items_mapper'
|
5
4
|
|
6
5
|
module RubyLsp
|
7
6
|
module Ree
|
@@ -18,6 +17,7 @@ module RubyLsp
|
|
18
17
|
@node_context = node_context
|
19
18
|
@root_node = @node_context.instance_variable_get(:@nesting_nodes).first
|
20
19
|
@finder = ReeObjectFinder.new(@index)
|
20
|
+
@mapper = RubyLsp::Ree::CompletionItemsMapper.new(@index)
|
21
21
|
end
|
22
22
|
|
23
23
|
def get_ree_receiver(receiver_node)
|
@@ -31,115 +31,30 @@ module RubyLsp
|
|
31
31
|
|
32
32
|
case @finder.object_type(ree_receiver)
|
33
33
|
when :enum
|
34
|
-
get_enum_values_completion_items(ree_receiver, location)
|
34
|
+
get_enum_values_completion_items(ree_receiver, location, node)
|
35
35
|
when :bean, :async_bean
|
36
|
-
get_bean_methods_completion_items(ree_receiver, location)
|
36
|
+
get_bean_methods_completion_items(ree_receiver, location, node)
|
37
37
|
when :dao
|
38
|
-
get_dao_filters_completion_items(ree_receiver, location)
|
38
|
+
get_dao_filters_completion_items(ree_receiver, location, node)
|
39
39
|
else
|
40
40
|
[]
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
def get_bean_methods_completion_items(bean_obj, location)
|
44
|
+
def get_bean_methods_completion_items(bean_obj, location, node)
|
45
45
|
bean_node = RubyLsp::Ree::ParsedDocumentBuilder.build_from_uri(bean_obj.uri, :bean)
|
46
|
-
|
47
|
-
range = Interface::Range.new(
|
48
|
-
start: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
49
|
-
end: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
50
|
-
)
|
51
|
-
|
52
|
-
bean_node.bean_methods.map do |bean_method|
|
53
|
-
signature = bean_method.signatures.first
|
54
|
-
|
55
|
-
label_details = Interface::CompletionItemLabelDetails.new(
|
56
|
-
description: "method",
|
57
|
-
detail: get_detail_string(signature)
|
58
|
-
)
|
59
|
-
|
60
|
-
Interface::CompletionItem.new(
|
61
|
-
label: bean_method.name,
|
62
|
-
label_details: label_details,
|
63
|
-
filter_text: bean_method.name,
|
64
|
-
text_edit: Interface::TextEdit.new(
|
65
|
-
range: range,
|
66
|
-
new_text: get_method_string(bean_method.name, signature)
|
67
|
-
),
|
68
|
-
kind: Constant::CompletionItemKind::METHOD,
|
69
|
-
insert_text_format: Constant::InsertTextFormat::SNIPPET,
|
70
|
-
data: {
|
71
|
-
owner_name: "Object",
|
72
|
-
guessed_type: false,
|
73
|
-
}
|
74
|
-
)
|
75
|
-
end
|
46
|
+
@mapper.map_ree_object_methods(bean_node.bean_methods, location, node, "method")
|
76
47
|
end
|
77
48
|
|
78
|
-
def get_dao_filters_completion_items(dao_obj, location)
|
49
|
+
def get_dao_filters_completion_items(dao_obj, location, node)
|
79
50
|
dao_node = RubyLsp::Ree::ParsedDocumentBuilder.build_from_uri(dao_obj.uri, :dao)
|
80
|
-
|
81
|
-
range = Interface::Range.new(
|
82
|
-
start: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
83
|
-
end: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
84
|
-
)
|
85
|
-
|
86
|
-
dao_node.filters.map do |filter|
|
87
|
-
signature = filter.signatures.first
|
88
|
-
|
89
|
-
label_details = Interface::CompletionItemLabelDetails.new(
|
90
|
-
description: "filter",
|
91
|
-
detail: get_detail_string(signature)
|
92
|
-
)
|
93
|
-
|
94
|
-
Interface::CompletionItem.new(
|
95
|
-
label: filter.name,
|
96
|
-
label_details: label_details,
|
97
|
-
filter_text: filter.name,
|
98
|
-
text_edit: Interface::TextEdit.new(
|
99
|
-
range: range,
|
100
|
-
new_text: get_method_string(filter.name, signature)
|
101
|
-
),
|
102
|
-
kind: Constant::CompletionItemKind::METHOD,
|
103
|
-
insert_text_format: Constant::InsertTextFormat::SNIPPET,
|
104
|
-
data: {
|
105
|
-
owner_name: "Object",
|
106
|
-
guessed_type: false,
|
107
|
-
}
|
108
|
-
)
|
109
|
-
end
|
51
|
+
@mapper.map_ree_object_methods(dao_node.filters, location, node, "filter")
|
110
52
|
end
|
111
53
|
|
112
|
-
def get_enum_values_completion_items(enum_obj, location)
|
54
|
+
def get_enum_values_completion_items(enum_obj, location, node)
|
113
55
|
enum_node = RubyLsp::Ree::ParsedDocumentBuilder.build_from_uri(enum_obj.uri, :enum)
|
114
|
-
|
115
56
|
class_name = enum_node.full_class_name
|
116
|
-
|
117
|
-
label_details = Interface::CompletionItemLabelDetails.new(
|
118
|
-
description: "from: #{class_name}",
|
119
|
-
detail: ''
|
120
|
-
)
|
121
|
-
|
122
|
-
range = Interface::Range.new(
|
123
|
-
start: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
124
|
-
end: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
125
|
-
)
|
126
|
-
|
127
|
-
enum_node.values.map do |val|
|
128
|
-
Interface::CompletionItem.new(
|
129
|
-
label: val.name,
|
130
|
-
label_details: label_details,
|
131
|
-
filter_text: val.name,
|
132
|
-
text_edit: Interface::TextEdit.new(
|
133
|
-
range: range,
|
134
|
-
new_text: val.name
|
135
|
-
),
|
136
|
-
kind: Constant::CompletionItemKind::METHOD,
|
137
|
-
data: {
|
138
|
-
owner_name: "Object",
|
139
|
-
guessed_type: false,
|
140
|
-
}
|
141
|
-
)
|
142
|
-
end
|
57
|
+
@mapper.map_ree_object_methods(enum_node.values, location, node, "from: #{class_name}")
|
143
58
|
end
|
144
59
|
|
145
60
|
def get_class_name_completion_items(node)
|
@@ -150,59 +65,7 @@ module RubyLsp
|
|
150
65
|
|
151
66
|
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@root_node, @uri)
|
152
67
|
|
153
|
-
|
154
|
-
not_imported_consts = []
|
155
|
-
|
156
|
-
class_name_objects.take(CANDIDATES_LIMIT).each do |full_class_name|
|
157
|
-
entries = @index[full_class_name]
|
158
|
-
|
159
|
-
entries.each do |entry|
|
160
|
-
class_name = full_class_name.split('::').last
|
161
|
-
package_name = package_name_from_uri(entry.uri)
|
162
|
-
file_name = File.basename(entry.uri.to_s)
|
163
|
-
entry_comment = entry.comments && entry.comments.size > 0 ? " (#{entry.comments})" : ''
|
164
|
-
|
165
|
-
matched_import = parsed_doc.find_import_for_package(class_name, package_name)
|
166
|
-
|
167
|
-
if matched_import
|
168
|
-
label_details = Interface::CompletionItemLabelDetails.new(
|
169
|
-
description: "imported from: :#{package_name}",
|
170
|
-
detail: entry_comment
|
171
|
-
)
|
172
|
-
|
173
|
-
imported_consts << Interface::CompletionItem.new(
|
174
|
-
label: class_name,
|
175
|
-
label_details: label_details,
|
176
|
-
filter_text: class_name,
|
177
|
-
text_edit: Interface::TextEdit.new(
|
178
|
-
range: range_from_location(node.location),
|
179
|
-
new_text: class_name,
|
180
|
-
),
|
181
|
-
kind: Constant::CompletionItemKind::CLASS,
|
182
|
-
additional_text_edits: []
|
183
|
-
)
|
184
|
-
else
|
185
|
-
label_details = Interface::CompletionItemLabelDetails.new(
|
186
|
-
description: "from: :#{package_name}",
|
187
|
-
detail: entry_comment + " #{file_name}"
|
188
|
-
)
|
189
|
-
|
190
|
-
not_imported_consts << Interface::CompletionItem.new(
|
191
|
-
label: class_name,
|
192
|
-
label_details: label_details,
|
193
|
-
filter_text: class_name,
|
194
|
-
text_edit: Interface::TextEdit.new(
|
195
|
-
range: range_from_location(node.location),
|
196
|
-
new_text: class_name,
|
197
|
-
),
|
198
|
-
kind: Constant::CompletionItemKind::CLASS,
|
199
|
-
additional_text_edits: ConstAdditionalTextEditsCreator.call(parsed_doc, class_name, package_name, entry)
|
200
|
-
)
|
201
|
-
end
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
imported_consts + not_imported_consts
|
68
|
+
@mapper.map_class_name_objects(class_name_objects.take(CANDIDATES_LIMIT), node, parsed_doc)
|
206
69
|
end
|
207
70
|
|
208
71
|
def get_ree_objects_completions_items(node)
|
@@ -212,65 +75,7 @@ module RubyLsp
|
|
212
75
|
|
213
76
|
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@root_node, @uri)
|
214
77
|
|
215
|
-
ree_objects
|
216
|
-
ree_object_name = ree_object.name
|
217
|
-
package_name = package_name_from_uri(ree_object.uri)
|
218
|
-
signature = ree_object.signatures.first
|
219
|
-
ree_type = get_ree_type(ree_object)
|
220
|
-
|
221
|
-
label_details = Interface::CompletionItemLabelDetails.new(
|
222
|
-
description: "#{ree_type}, from: :#{package_name}",
|
223
|
-
detail: get_detail_string(signature)
|
224
|
-
)
|
225
|
-
|
226
|
-
Interface::CompletionItem.new(
|
227
|
-
label: ree_object_name,
|
228
|
-
label_details: label_details,
|
229
|
-
filter_text: ree_object_name,
|
230
|
-
text_edit: Interface::TextEdit.new(
|
231
|
-
range: range_from_location(node.location),
|
232
|
-
new_text: get_method_string(ree_object_name, signature)
|
233
|
-
),
|
234
|
-
kind: Constant::CompletionItemKind::METHOD,
|
235
|
-
insert_text_format: Constant::InsertTextFormat::SNIPPET,
|
236
|
-
data: {
|
237
|
-
owner_name: "Object",
|
238
|
-
guessed_type: false,
|
239
|
-
},
|
240
|
-
additional_text_edits: MethodAdditionalTextEditsCreator.call(parsed_doc, ree_object_name, package_name)
|
241
|
-
)
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
def get_detail_string(signature)
|
246
|
-
return '' unless signature
|
247
|
-
|
248
|
-
"(#{get_parameters_string(signature)})"
|
249
|
-
end
|
250
|
-
|
251
|
-
def get_parameters_string(signature)
|
252
|
-
return '' unless signature
|
253
|
-
|
254
|
-
signature.parameters.map(&:decorated_name).join(', ')
|
255
|
-
end
|
256
|
-
|
257
|
-
def get_method_string(fn_name, signature)
|
258
|
-
return fn_name unless signature
|
259
|
-
|
260
|
-
"#{fn_name}(#{get_parameters_placeholder(signature)})"
|
261
|
-
end
|
262
|
-
|
263
|
-
def get_parameters_placeholder(signature)
|
264
|
-
return '' unless signature
|
265
|
-
|
266
|
-
signature.parameters.to_enum.with_index.map do |signature_param, index|
|
267
|
-
case signature_param
|
268
|
-
when RubyIndexer::Entry::KeywordParameter, RubyIndexer::Entry::OptionalKeywordParameter
|
269
|
-
"#{signature_param.name}: ${#{index+1}:#{signature_param.name}}"
|
270
|
-
else
|
271
|
-
"${#{index+1}:#{signature_param.name}}"
|
272
|
-
end
|
273
|
-
end.join(', ')
|
78
|
+
@mapper.map_ree_objects(ree_objects, node, parsed_doc)
|
274
79
|
end
|
275
80
|
end
|
276
81
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
class RubyLsp::Ree::CallObjectsParser
|
2
|
+
attr_reader :parsed_doc
|
3
|
+
|
4
|
+
class CallObject
|
5
|
+
attr_reader :name, :type, :receiver_name, :method_name
|
6
|
+
|
7
|
+
def initialize(name:, type:, receiver_name: nil)
|
8
|
+
@name = name
|
9
|
+
@type = type
|
10
|
+
@receiver_name = receiver_name
|
11
|
+
@method_name = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_method_name(method_name)
|
15
|
+
@method_name = method_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(parsed_doc)
|
20
|
+
@parsed_doc = parsed_doc
|
21
|
+
end
|
22
|
+
|
23
|
+
def class_call_objects
|
24
|
+
call_objects = []
|
25
|
+
return unless parsed_doc.has_body?
|
26
|
+
|
27
|
+
call_objects += parse_body_call_objects(parsed_doc.class_node.body.body)
|
28
|
+
|
29
|
+
parsed_doc.parse_instance_methods
|
30
|
+
|
31
|
+
parsed_doc.doc_instance_methods.each do |doc_instance_method|
|
32
|
+
call_objects += method_call_objects(doc_instance_method)
|
33
|
+
end
|
34
|
+
|
35
|
+
call_objects
|
36
|
+
end
|
37
|
+
|
38
|
+
def method_call_objects(method_object)
|
39
|
+
method_body = method_object.method_body
|
40
|
+
return [] unless method_body
|
41
|
+
|
42
|
+
call_nodes = parse_body_call_objects(method_body)
|
43
|
+
call_expressions = [] # don't parse call expressions for now parse_body_call_expressions(method_body)
|
44
|
+
|
45
|
+
call_objects = call_nodes + call_expressions
|
46
|
+
|
47
|
+
call_objects.each{ |call_object| call_object.set_method_name(method_object.name) }
|
48
|
+
call_objects
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def parse_body_call_objects(node_body)
|
54
|
+
call_objects = []
|
55
|
+
|
56
|
+
node_body.each do |node|
|
57
|
+
if node.is_a?(Prism::CallNode)
|
58
|
+
receiver = get_first_receiver(node)
|
59
|
+
receiver_name = receiver.respond_to?(:name) ? receiver.name : nil
|
60
|
+
call_objects << CallObject.new(name: node.name, type: :method_call, receiver_name: receiver_name)
|
61
|
+
elsif node.respond_to?(:statements)
|
62
|
+
call_objects += parse_body_call_objects(node.statements.body)
|
63
|
+
elsif node.respond_to?(:block) && node.block && node.block.is_a?(Prism::BlockNode)
|
64
|
+
call_objects += parse_body_call_objects(get_method_body(node.block))
|
65
|
+
elsif node.respond_to?(:value) && node.value
|
66
|
+
call_objects += parse_body_call_objects([node.value])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
call_objects
|
71
|
+
end
|
72
|
+
|
73
|
+
def parse_body_call_expressions(node_body)
|
74
|
+
call_expressions = []
|
75
|
+
|
76
|
+
node_body.each do |node|
|
77
|
+
if node.respond_to?(:block) && node.block && node.block.is_a?(Prism::BlockArgumentNode) && node.block.expression.is_a?(Prism::SymbolNode)
|
78
|
+
call_expressions << CallObject.new(name: node.block.expression.unescaped.to_sym, type: :proc_to_sym)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
call_expressions
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_method_body(node)
|
86
|
+
return unless node.body
|
87
|
+
|
88
|
+
if node.body.is_a?(Prism::BeginNode)
|
89
|
+
node.body.statements.body
|
90
|
+
else
|
91
|
+
node.body.body
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_first_receiver(node)
|
96
|
+
return nil unless node.receiver
|
97
|
+
|
98
|
+
if node.receiver.is_a?(Prism::CallNode) && node.receiver.receiver
|
99
|
+
return get_first_receiver(node.receiver)
|
100
|
+
end
|
101
|
+
|
102
|
+
node.receiver
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class RubyLsp::Ree::LocalVariablesParser
|
2
|
+
attr_reader :parsed_doc, :method_object
|
3
|
+
|
4
|
+
class LocalVariable
|
5
|
+
attr_reader :name
|
6
|
+
|
7
|
+
def initialize(name:)
|
8
|
+
@name = name
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(method_obj)
|
13
|
+
@method_object = method_obj
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_local_variables
|
17
|
+
method_body = method_object.method_body
|
18
|
+
return [] unless method_body
|
19
|
+
|
20
|
+
parse_body_local_variables(method_body)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def parse_body_local_variables(node_body)
|
26
|
+
local_variables = []
|
27
|
+
|
28
|
+
node_body.each do |node|
|
29
|
+
if node.is_a?(Prism::LocalVariableWriteNode)
|
30
|
+
local_variables << LocalVariable.new(name: node.name)
|
31
|
+
elsif node.is_a?(Prism::MultiWriteNode)
|
32
|
+
local_variables += node.lefts.map{ |x| LocalVariable.new(name: x.name) }
|
33
|
+
elsif node.respond_to?(:statements)
|
34
|
+
local_variables += parse_body_local_variables(node.statements.body)
|
35
|
+
elsif node.respond_to?(:block) && node.block && node.block.is_a?(Prism::BlockNode)
|
36
|
+
local_variables += parse_body_local_variables(get_method_body(node.block))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
local_variables
|
41
|
+
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
|
+
end
|
@@ -2,6 +2,8 @@ require_relative 'parsed_base_document'
|
|
2
2
|
require_relative 'parsed_link_node'
|
3
3
|
require_relative 'parsed_method_node'
|
4
4
|
require_relative "../ree_constants"
|
5
|
+
require_relative "body_parsers/call_objects_parser"
|
6
|
+
|
5
7
|
require 'ostruct'
|
6
8
|
|
7
9
|
class RubyLsp::Ree::ParsedClassDocument < RubyLsp::Ree::ParsedBaseDocument
|
@@ -142,6 +144,7 @@ class RubyLsp::Ree::ParsedClassDocument < RubyLsp::Ree::ParsedBaseDocument
|
|
142
144
|
end
|
143
145
|
|
144
146
|
def parse_instance_methods
|
147
|
+
return if @doc_instance_methods
|
145
148
|
@doc_instance_methods = []
|
146
149
|
|
147
150
|
current_contract_node = nil
|
@@ -202,6 +205,14 @@ class RubyLsp::Ree::ParsedClassDocument < RubyLsp::Ree::ParsedBaseDocument
|
|
202
205
|
.map(&:name)
|
203
206
|
end
|
204
207
|
|
208
|
+
def parse_fn_calls
|
209
|
+
RubyLsp::Ree::CallObjectsParser.new(self).class_call_objects.select{ !_1.receiver_name }
|
210
|
+
end
|
211
|
+
|
212
|
+
def parse_bean_calls
|
213
|
+
RubyLsp::Ree::CallObjectsParser.new(self).class_call_objects.select{ _1.receiver_name }
|
214
|
+
end
|
215
|
+
|
205
216
|
def class_name
|
206
217
|
class_node.constant_path.name.to_s
|
207
218
|
end
|
@@ -1,11 +1,28 @@
|
|
1
1
|
require 'prism'
|
2
2
|
|
3
3
|
class RubyLsp::Ree::ParsedLinkNode
|
4
|
-
attr_reader :node, :document_package, :name, :
|
4
|
+
attr_reader :node, :document_package, :name, :import_items
|
5
5
|
|
6
6
|
FROM_ARG_KEY = 'from'
|
7
7
|
IMPORT_ARG_KEY = 'import'
|
8
8
|
|
9
|
+
class ImportItem
|
10
|
+
attr_reader :name, :original_name
|
11
|
+
|
12
|
+
def initialize(name:, original_name: nil)
|
13
|
+
@name = name
|
14
|
+
@original_name = original_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
if @original_name
|
19
|
+
"#{@original_name}.as(#{@name})"
|
20
|
+
else
|
21
|
+
@name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
9
26
|
def initialize(node, document_package = nil)
|
10
27
|
@node = node
|
11
28
|
@document_package = document_package
|
@@ -72,7 +89,11 @@ class RubyLsp::Ree::ParsedLinkNode
|
|
72
89
|
end
|
73
90
|
|
74
91
|
def parse_imports
|
75
|
-
@
|
92
|
+
@import_items ||= get_import_items
|
93
|
+
end
|
94
|
+
|
95
|
+
def imports
|
96
|
+
@import_items.map(&:name)
|
76
97
|
end
|
77
98
|
|
78
99
|
def has_import_section?
|
@@ -116,7 +137,7 @@ class RubyLsp::Ree::ParsedLinkNode
|
|
116
137
|
end
|
117
138
|
end
|
118
139
|
|
119
|
-
def
|
140
|
+
def get_import_items
|
120
141
|
return [] if @node.arguments.arguments.size == 1
|
121
142
|
|
122
143
|
if object_name_type?
|
@@ -136,10 +157,17 @@ class RubyLsp::Ree::ParsedLinkNode
|
|
136
157
|
end
|
137
158
|
|
138
159
|
def parse_object_link_multiple_imports(import_body)
|
139
|
-
if import_body.is_a?(Prism::CallNode)
|
140
|
-
parse_object_link_multiple_imports(import_body.receiver) +
|
160
|
+
if import_body.is_a?(Prism::CallNode) && import_body.name == :&
|
161
|
+
parse_object_link_multiple_imports(import_body.receiver) + parse_object_link_multiple_imports(import_body.arguments.arguments.first)
|
162
|
+
elsif import_body.is_a?(Prism::CallNode) && import_body.name == :as
|
163
|
+
[
|
164
|
+
ImportItem.new(
|
165
|
+
name: import_body.arguments.arguments.first.name.to_s,
|
166
|
+
original_name: import_body.receiver.name.to_s
|
167
|
+
)
|
168
|
+
]
|
141
169
|
else
|
142
|
-
[import_body.name.to_s]
|
170
|
+
[ ImportItem.new(name: import_body.name.to_s) ]
|
143
171
|
end
|
144
172
|
end
|
145
173
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'prism'
|
2
|
+
require_relative "body_parsers/local_variables_parser"
|
2
3
|
|
3
4
|
class RubyLsp::Ree::ParsedMethodNode
|
4
5
|
attr_reader :method_node, :contract_node, :nested_local_methods
|
@@ -24,6 +25,10 @@ class RubyLsp::Ree::ParsedMethodNode
|
|
24
25
|
@method_node.location.end_line - 1
|
25
26
|
end
|
26
27
|
|
28
|
+
def method_body
|
29
|
+
get_method_body(@method_node)
|
30
|
+
end
|
31
|
+
|
27
32
|
def raised_errors_nested
|
28
33
|
return @raised_errors_nested if @raised_errors_nested
|
29
34
|
raised = raised_errors
|
@@ -94,6 +99,10 @@ class RubyLsp::Ree::ParsedMethodNode
|
|
94
99
|
def contract_in_parentheses?
|
95
100
|
@contract_node.opening == '(' && @contract_node.closing == ')'
|
96
101
|
end
|
102
|
+
|
103
|
+
def parse_local_variables
|
104
|
+
RubyLsp::Ree::LocalVariablesParser.new(self).method_local_variables
|
105
|
+
end
|
97
106
|
|
98
107
|
def parse_nested_local_methods(local_methods)
|
99
108
|
unless @method_node.body
|
@@ -111,6 +120,20 @@ class RubyLsp::Ree::ParsedMethodNode
|
|
111
120
|
@nested_local_methods.each{ _1.parse_nested_local_methods(local_methods) }
|
112
121
|
end
|
113
122
|
|
123
|
+
def parse_call_objects
|
124
|
+
method_body = get_method_body(@method_node)
|
125
|
+
return [] unless method_body
|
126
|
+
|
127
|
+
call_nodes = parse_body_call_objects(method_body)
|
128
|
+
call_expressions = parse_body_call_expressions(method_body)
|
129
|
+
|
130
|
+
call_node_names = call_nodes.map(&:name) + call_expressions
|
131
|
+
|
132
|
+
call_node_names
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
114
137
|
def parse_body_call_objects(node_body)
|
115
138
|
call_nodes = []
|
116
139
|
|
@@ -121,6 +144,8 @@ class RubyLsp::Ree::ParsedMethodNode
|
|
121
144
|
call_nodes += parse_body_call_objects(node.statements.body)
|
122
145
|
elsif node.respond_to?(:block) && node.block && node.block.is_a?(Prism::BlockNode)
|
123
146
|
call_nodes += parse_body_call_objects(get_method_body(node.block))
|
147
|
+
elsif node.respond_to?(:value) && node.value
|
148
|
+
call_nodes += parse_body_call_objects([node.value])
|
124
149
|
end
|
125
150
|
end
|
126
151
|
|
@@ -140,6 +165,8 @@ class RubyLsp::Ree::ParsedMethodNode
|
|
140
165
|
end
|
141
166
|
|
142
167
|
def get_method_body(node)
|
168
|
+
return unless node.body
|
169
|
+
|
143
170
|
if node.body.is_a?(Prism::BeginNode)
|
144
171
|
node.body.statements.body
|
145
172
|
else
|
@@ -3,6 +3,7 @@ require_relative 'formatters/missing_error_definitions_formatter'
|
|
3
3
|
require_relative 'formatters/missing_error_contracts_formatter'
|
4
4
|
require_relative 'formatters/missing_error_locales_formatter'
|
5
5
|
require_relative 'formatters/unused_links_formatter'
|
6
|
+
require_relative 'formatters/missing_imports_formatter'
|
6
7
|
|
7
8
|
module RubyLsp
|
8
9
|
module Ree
|
@@ -23,11 +24,12 @@ module RubyLsp
|
|
23
24
|
source = document.source
|
24
25
|
|
25
26
|
formatters = [
|
26
|
-
RubyLsp::Ree::SortLinksFormatter,
|
27
27
|
RubyLsp::Ree::MissingErrorDefinitionsFormatter,
|
28
28
|
RubyLsp::Ree::MissingErrorContractsFormatter,
|
29
29
|
RubyLsp::Ree::MissingErrorLocalesFormatter,
|
30
30
|
RubyLsp::Ree::UnusedLinksFormatter,
|
31
|
+
RubyLsp::Ree::MissingImportsFormatter,
|
32
|
+
RubyLsp::Ree::SortLinksFormatter,
|
31
33
|
].select do |formatter|
|
32
34
|
formatter_name = formatter.name.split('::').last.to_sym
|
33
35
|
@settings[formatter_name] != false
|
@@ -27,8 +27,8 @@ module RubyLsp
|
|
27
27
|
set_empty_lines!(link_node.location.start_line-1, link_node.location.end_line-1)
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
31
|
-
imports_str = link_node.
|
30
|
+
def remove_link_imports(link_node, link_imports)
|
31
|
+
imports_str = link_node.import_items.reject{ link_imports.include?(_1.name) }.map(&:to_s).join(' & ')
|
32
32
|
|
33
33
|
block_start_col = link_node.import_block_open_location.start_column
|
34
34
|
block_line = link_node.import_block_open_location.start_line-1
|
@@ -63,6 +63,36 @@ module RubyLsp
|
|
63
63
|
source_lines[i] = ''
|
64
64
|
end
|
65
65
|
end
|
66
|
+
|
67
|
+
def add_links(parsed_doc, ree_objects, current_package)
|
68
|
+
new_text = ''
|
69
|
+
|
70
|
+
ree_objects.each do |ree_object|
|
71
|
+
object_package = package_name_from_uri(ree_object.uri)
|
72
|
+
|
73
|
+
link_text = if current_package == object_package
|
74
|
+
"\s\slink :#{ree_object.name}"
|
75
|
+
else
|
76
|
+
"\s\slink :#{ree_object.name}, from: :#{object_package}"
|
77
|
+
end
|
78
|
+
|
79
|
+
if parsed_doc.links_container_node
|
80
|
+
link_text = "\s\s" + link_text
|
81
|
+
end
|
82
|
+
|
83
|
+
new_text += "\n" + link_text
|
84
|
+
end
|
85
|
+
|
86
|
+
new_text += "\n"
|
87
|
+
|
88
|
+
if parsed_doc.has_blank_links_container?
|
89
|
+
new_text = "\sdo#{new_text}\s\send\n"
|
90
|
+
end
|
91
|
+
|
92
|
+
line = parsed_doc.links_container_node.location.start_line - 1
|
93
|
+
|
94
|
+
source_lines[line] = source_lines[line].chomp + new_text
|
95
|
+
end
|
66
96
|
end
|
67
97
|
end
|
68
98
|
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.16
|
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-04-
|
11
|
+
date: 2025-04-24 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:
|
@@ -26,20 +26,24 @@ files:
|
|
26
26
|
- README.md
|
27
27
|
- Rakefile
|
28
28
|
- lib/ruby_lsp/ruby_lsp_ree/addon.rb
|
29
|
+
- lib/ruby_lsp/ruby_lsp_ree/completion/completion_items_mapper.rb
|
30
|
+
- lib/ruby_lsp/ruby_lsp_ree/completion/const_additional_text_edits_creator.rb
|
31
|
+
- lib/ruby_lsp/ruby_lsp_ree/completion/method_additional_text_edits_creator.rb
|
29
32
|
- lib/ruby_lsp/ruby_lsp_ree/formatters/base_formatter.rb
|
30
33
|
- lib/ruby_lsp/ruby_lsp_ree/formatters/missing_error_contracts_formatter.rb
|
31
34
|
- lib/ruby_lsp/ruby_lsp_ree/formatters/missing_error_definitions_formatter.rb
|
32
35
|
- lib/ruby_lsp/ruby_lsp_ree/formatters/missing_error_locales_formatter.rb
|
36
|
+
- lib/ruby_lsp/ruby_lsp_ree/formatters/missing_imports_formatter.rb
|
33
37
|
- lib/ruby_lsp/ruby_lsp_ree/formatters/sort_links_formatter.rb
|
34
38
|
- lib/ruby_lsp/ruby_lsp_ree/formatters/unused_links_formatter.rb
|
35
39
|
- lib/ruby_lsp/ruby_lsp_ree/handlers/completion_handler.rb
|
36
|
-
- lib/ruby_lsp/ruby_lsp_ree/handlers/const_additional_text_edits_creator.rb
|
37
40
|
- lib/ruby_lsp/ruby_lsp_ree/handlers/definition_handler.rb
|
38
41
|
- lib/ruby_lsp/ruby_lsp_ree/handlers/hover_handler.rb
|
39
|
-
- lib/ruby_lsp/ruby_lsp_ree/handlers/method_additional_text_edits_creator.rb
|
40
42
|
- lib/ruby_lsp/ruby_lsp_ree/listeners/completion_listener.rb
|
41
43
|
- lib/ruby_lsp/ruby_lsp_ree/listeners/definition_listener.rb
|
42
44
|
- lib/ruby_lsp/ruby_lsp_ree/listeners/hover_listener.rb
|
45
|
+
- lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/call_objects_parser.rb
|
46
|
+
- lib/ruby_lsp/ruby_lsp_ree/parsing/body_parsers/local_variables_parser.rb
|
43
47
|
- lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_base_document.rb
|
44
48
|
- lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_class_document.rb
|
45
49
|
- lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document_builder.rb
|
/data/lib/ruby_lsp/ruby_lsp_ree/{handlers → completion}/const_additional_text_edits_creator.rb
RENAMED
File without changes
|