ruby-lsp-ree 0.1.1 → 0.1.3
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/.ruby-version +1 -0
- data/CHANGELOG.md +22 -4
- data/Gemfile +6 -0
- data/Gemfile.lock +38 -2
- data/Rakefile +5 -1
- data/lib/ruby_lsp/ruby_lsp_ree/addon.rb +11 -7
- data/lib/ruby_lsp/ruby_lsp_ree/{completion_utils.rb → handlers/completion_handler.rb} +135 -28
- data/lib/ruby_lsp/ruby_lsp_ree/listeners/completion_listener.rb +49 -0
- data/lib/ruby_lsp/ruby_lsp_ree/listeners/definition_listener.rb +137 -0
- data/lib/ruby_lsp/ruby_lsp_ree/listeners/hover_listener.rb +65 -0
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document.rb +61 -14
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_document_builder.rb +24 -1
- data/lib/ruby_lsp/ruby_lsp_ree/parsing/parsed_link_node.rb +31 -3
- data/lib/ruby_lsp/ruby_lsp_ree/ree_formatter.rb +14 -16
- data/lib/ruby_lsp/ruby_lsp_ree/ree_indexing_enhancement.rb +5 -5
- data/lib/ruby_lsp/ruby_lsp_ree/ree_object_finder.rb +67 -8
- data/lib/ruby_lsp/ruby_lsp_ree/{ree_lsp_utils.rb → utils/ree_lsp_utils.rb} +19 -6
- data/lib/ruby_lsp_ree/version.rb +3 -5
- data/ruby-lsp-ree.gemspec +1 -1
- metadata +9 -7
- data/lib/ruby_lsp/ruby_lsp_ree/completion.rb +0 -90
- data/lib/ruby_lsp/ruby_lsp_ree/definition.rb +0 -83
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8eb134e8d6b0ac3bf5321789ed6617ea1347ee096b1e642f953885b398524030
|
4
|
+
data.tar.gz: 460f2cc171155affbafe236535604b116d0af15bbcf14c3925470a8ff3616211
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf49632399253b97f3b3df77ae7767008141900552461de8bca6b7395ac0d48fa4dbc5a353d2245f50147d7d119059b3f4d5a3f55aa41ae4fd11521d58b7930d
|
7
|
+
data.tar.gz: 0f392c77bbe2bdee9e9f613bc856c1d93b9bb9a2c87a93078017388fb253b27325d244ba289b36c24ff7e71e9f72b4f9c11abb663a7a2f675b5a9661aae29554
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.3.0
|
data/CHANGELOG.md
CHANGED
@@ -1,8 +1,20 @@
|
|
1
|
-
## [
|
1
|
+
## [0.1.3] - 2025-02-21
|
2
2
|
|
3
|
-
|
3
|
+
- improved Go To Definition for ree object methods and imported constants
|
4
|
+
- support for :mapper objects
|
5
|
+
- support for :aggregate objects
|
6
|
+
- improved autocompletion for imported constants
|
7
|
+
- basic hover information for ree objects
|
4
8
|
|
5
|
-
-
|
9
|
+
## [0.1.2] - 2025-02-14
|
10
|
+
|
11
|
+
- support for :bean objects
|
12
|
+
- Go To Definition for imported constants
|
13
|
+
- use current (not saved) version of the document in autocomplete
|
14
|
+
- use current (not saved) version of the document in definition
|
15
|
+
- increase autocomplete list limits (affects short functions)
|
16
|
+
- improved const autocomplete
|
17
|
+
- improved ree errors handling
|
6
18
|
|
7
19
|
## [0.1.1] - 2025-02-10
|
8
20
|
|
@@ -19,4 +31,10 @@
|
|
19
31
|
- Add Link for ree actions
|
20
32
|
- sort links in ree actions
|
21
33
|
- autocomplete for ree dao
|
22
|
-
- autocomplete for dao filters
|
34
|
+
- autocomplete for dao filters
|
35
|
+
|
36
|
+
## [0.1.0] - 2025-01-31
|
37
|
+
|
38
|
+
- Initial release
|
39
|
+
|
40
|
+
## [Unreleased]
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,19 +1,55 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-lsp-ree (0.1.
|
4
|
+
ruby-lsp-ree (0.1.3)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
diff-lcs (1.6.0)
|
10
|
+
language_server-protocol (3.17.0.4)
|
11
|
+
logger (1.6.6)
|
12
|
+
prism (1.3.0)
|
9
13
|
rake (13.2.1)
|
14
|
+
rbs (3.8.1)
|
15
|
+
logger
|
16
|
+
rspec (3.13.0)
|
17
|
+
rspec-core (~> 3.13.0)
|
18
|
+
rspec-expectations (~> 3.13.0)
|
19
|
+
rspec-mocks (~> 3.13.0)
|
20
|
+
rspec-core (3.13.3)
|
21
|
+
rspec-support (~> 3.13.0)
|
22
|
+
rspec-expectations (3.13.3)
|
23
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
+
rspec-support (~> 3.13.0)
|
25
|
+
rspec-mocks (3.13.2)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.13.0)
|
28
|
+
rspec-support (3.13.2)
|
29
|
+
ruby-lsp (0.23.11)
|
30
|
+
language_server-protocol (~> 3.17.0)
|
31
|
+
prism (>= 1.2, < 2.0)
|
32
|
+
rbs (>= 3, < 4)
|
33
|
+
sorbet-runtime (>= 0.5.10782)
|
34
|
+
sorbet (0.5.11835)
|
35
|
+
sorbet-static (= 0.5.11835)
|
36
|
+
sorbet-runtime (0.5.11835)
|
37
|
+
sorbet-static (0.5.11835-universal-darwin)
|
38
|
+
sorbet-static (0.5.11835-x86_64-linux)
|
39
|
+
sorbet-static-and-runtime (0.5.11835)
|
40
|
+
sorbet (= 0.5.11835)
|
41
|
+
sorbet-runtime (= 0.5.11835)
|
10
42
|
|
11
43
|
PLATFORMS
|
44
|
+
x86_64-darwin-23
|
12
45
|
x86_64-linux
|
13
46
|
|
14
47
|
DEPENDENCIES
|
15
48
|
rake (~> 13.0)
|
49
|
+
rspec
|
50
|
+
ruby-lsp
|
16
51
|
ruby-lsp-ree!
|
52
|
+
sorbet-static-and-runtime
|
17
53
|
|
18
54
|
BUNDLED WITH
|
19
|
-
2.
|
55
|
+
2.6.3
|
data/Rakefile
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require "ruby_lsp/addon"
|
2
|
-
require_relative "
|
3
|
-
require_relative "
|
2
|
+
require_relative "listeners/definition_listener"
|
3
|
+
require_relative "listeners/completion_listener"
|
4
|
+
require_relative "listeners/hover_listener"
|
4
5
|
require_relative "ree_indexing_enhancement"
|
5
|
-
require_relative "ree_lsp_utils"
|
6
|
+
require_relative "utils/ree_lsp_utils"
|
6
7
|
require_relative "ree_formatter"
|
7
8
|
require_relative "parsing/parsed_document_builder"
|
8
9
|
|
@@ -25,14 +26,17 @@ module RubyLsp
|
|
25
26
|
|
26
27
|
def create_definition_listener(response_builder, uri, node_context, dispatcher)
|
27
28
|
index = @global_state.index
|
28
|
-
RubyLsp::Ree::
|
29
|
+
RubyLsp::Ree::DefinitionListener.new(response_builder, node_context, index, dispatcher, uri)
|
29
30
|
end
|
30
31
|
|
31
32
|
def create_completion_listener(response_builder, node_context, dispatcher, uri)
|
32
|
-
$stderr.puts("create_completion_listener")
|
33
|
-
|
34
33
|
index = @global_state.index
|
35
|
-
RubyLsp::Ree::
|
34
|
+
RubyLsp::Ree::CompletionListener.new(response_builder, node_context, index, dispatcher, uri)
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_hover_listener(response_builder, node_context, dispatcher)
|
38
|
+
index = @global_state.index
|
39
|
+
RubyLsp::Ree::HoverListener.new(response_builder, node_context, index, dispatcher)
|
36
40
|
end
|
37
41
|
end
|
38
42
|
end
|
@@ -1,11 +1,77 @@
|
|
1
|
-
require_relative "ree_lsp_utils"
|
1
|
+
require_relative "../utils/ree_lsp_utils"
|
2
|
+
require_relative "../ree_object_finder"
|
2
3
|
|
3
4
|
module RubyLsp
|
4
5
|
module Ree
|
5
|
-
|
6
|
+
class CompletionHandler
|
6
7
|
include Requests::Support::Common
|
7
8
|
include RubyLsp::Ree::ReeLspUtils
|
8
9
|
|
10
|
+
RECEIVER_OBJECT_TYPES = [:enum, :dao, :bean]
|
11
|
+
CANDIDATES_LIMIT = 100
|
12
|
+
|
13
|
+
def initialize(index, uri, node_context)
|
14
|
+
@index = index
|
15
|
+
@uri = uri
|
16
|
+
@node_context = node_context
|
17
|
+
@finder = ReeObjectFinder.new(@index)
|
18
|
+
end
|
19
|
+
|
20
|
+
def get_ree_receiver(receiver_node)
|
21
|
+
return if !receiver_node || !receiver_node.is_a?(Prism::CallNode)
|
22
|
+
|
23
|
+
@finder.find_objects_by_types(receiver_node.name.to_s, RECEIVER_OBJECT_TYPES).first
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_ree_object_methods_completions_items(ree_receiver, receiver_node, node)
|
27
|
+
location = receiver_node.location
|
28
|
+
|
29
|
+
case @finder.object_type(ree_receiver)
|
30
|
+
when :enum
|
31
|
+
get_enum_values_completion_items(ree_receiver, location)
|
32
|
+
when :bean
|
33
|
+
get_bean_methods_completion_items(ree_receiver, location)
|
34
|
+
when :dao
|
35
|
+
get_dao_filters_completion_items(ree_receiver, location)
|
36
|
+
else
|
37
|
+
[]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_bean_methods_completion_items(bean_obj, location)
|
42
|
+
bean_node = RubyLsp::Ree::ParsedDocumentBuilder.build_from_uri(bean_obj.uri, :bean)
|
43
|
+
|
44
|
+
range = Interface::Range.new(
|
45
|
+
start: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
46
|
+
end: Interface::Position.new(line: location.start_line - 1, character: location.end_column + 1),
|
47
|
+
)
|
48
|
+
|
49
|
+
bean_node.bean_methods.map do |bean_method|
|
50
|
+
signature = bean_method.signatures.first
|
51
|
+
|
52
|
+
label_details = Interface::CompletionItemLabelDetails.new(
|
53
|
+
description: "method",
|
54
|
+
detail: get_detail_string(signature)
|
55
|
+
)
|
56
|
+
|
57
|
+
Interface::CompletionItem.new(
|
58
|
+
label: bean_method.name,
|
59
|
+
label_details: label_details,
|
60
|
+
filter_text: bean_method.name,
|
61
|
+
text_edit: Interface::TextEdit.new(
|
62
|
+
range: range,
|
63
|
+
new_text: get_method_string(bean_method.name, signature)
|
64
|
+
),
|
65
|
+
kind: Constant::CompletionItemKind::METHOD,
|
66
|
+
insert_text_format: Constant::InsertTextFormat::SNIPPET,
|
67
|
+
data: {
|
68
|
+
owner_name: "Object",
|
69
|
+
guessed_type: false,
|
70
|
+
}
|
71
|
+
)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
9
75
|
def get_dao_filters_completion_items(dao_obj, location)
|
10
76
|
dao_node = RubyLsp::Ree::ParsedDocumentBuilder.build_from_uri(dao_obj.uri, :dao)
|
11
77
|
|
@@ -73,33 +139,75 @@ module RubyLsp
|
|
73
139
|
end
|
74
140
|
end
|
75
141
|
|
76
|
-
def get_class_name_completion_items(
|
77
|
-
|
78
|
-
|
79
|
-
|
142
|
+
def get_class_name_completion_items(node)
|
143
|
+
node_name = node.name.to_s
|
144
|
+
class_name_objects = @finder.search_class_objects(node_name)
|
145
|
+
|
146
|
+
return [] if class_name_objects.size == 0
|
147
|
+
|
148
|
+
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@node_context.parent, @uri)
|
149
|
+
|
150
|
+
imported_consts = []
|
151
|
+
not_imported_consts = []
|
152
|
+
|
153
|
+
class_name_objects.take(CANDIDATES_LIMIT).each do |full_class_name|
|
154
|
+
entries = @index[full_class_name]
|
155
|
+
|
156
|
+
entries.each do |entry|
|
157
|
+
class_name = full_class_name.split('::').last
|
158
|
+
package_name = package_name_from_uri(entry.uri)
|
159
|
+
file_name = File.basename(entry.uri.to_s)
|
160
|
+
|
161
|
+
matched_import = parsed_doc.find_import_for_package(class_name, package_name)
|
162
|
+
|
163
|
+
if matched_import
|
164
|
+
label_details = Interface::CompletionItemLabelDetails.new(
|
165
|
+
description: "imported from: :#{package_name}",
|
166
|
+
detail: ""
|
167
|
+
)
|
168
|
+
|
169
|
+
imported_consts << Interface::CompletionItem.new(
|
170
|
+
label: class_name,
|
171
|
+
label_details: label_details,
|
172
|
+
filter_text: class_name,
|
173
|
+
text_edit: Interface::TextEdit.new(
|
174
|
+
range: range_from_location(node.location),
|
175
|
+
new_text: class_name,
|
176
|
+
),
|
177
|
+
kind: Constant::CompletionItemKind::CLASS,
|
178
|
+
additional_text_edits: []
|
179
|
+
)
|
180
|
+
else
|
181
|
+
label_details = Interface::CompletionItemLabelDetails.new(
|
182
|
+
description: "from: :#{package_name}",
|
183
|
+
detail: " #{file_name}"
|
184
|
+
)
|
185
|
+
|
186
|
+
not_imported_consts << Interface::CompletionItem.new(
|
187
|
+
label: class_name,
|
188
|
+
label_details: label_details,
|
189
|
+
filter_text: class_name,
|
190
|
+
text_edit: Interface::TextEdit.new(
|
191
|
+
range: range_from_location(node.location),
|
192
|
+
new_text: class_name,
|
193
|
+
),
|
194
|
+
kind: Constant::CompletionItemKind::CLASS,
|
195
|
+
additional_text_edits: get_additional_text_edits_for_constant(parsed_doc, class_name, package_name, entry)
|
196
|
+
)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
80
200
|
|
81
|
-
|
201
|
+
imported_consts + not_imported_consts
|
202
|
+
end
|
82
203
|
|
83
|
-
|
84
|
-
|
85
|
-
detail: ""
|
86
|
-
)
|
204
|
+
def get_ree_objects_completions_items(node)
|
205
|
+
ree_objects = @finder.search_objects(node.name.to_s, CANDIDATES_LIMIT)
|
87
206
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
filter_text: class_name,
|
92
|
-
text_edit: Interface::TextEdit.new(
|
93
|
-
range: range_from_location(node.location),
|
94
|
-
new_text: class_name,
|
95
|
-
),
|
96
|
-
kind: Constant::CompletionItemKind::CLASS,
|
97
|
-
additional_text_edits: get_additional_text_edits_for_constant(parsed_doc, class_name, package_name, entry)
|
98
|
-
)
|
99
|
-
end
|
100
|
-
end
|
207
|
+
return [] if ree_objects.size == 0
|
208
|
+
|
209
|
+
parsed_doc = RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@node_context.parent, @uri)
|
101
210
|
|
102
|
-
def get_ree_objects_completions_items(ree_objects, parsed_doc, node)
|
103
211
|
ree_objects.map do |ree_object|
|
104
212
|
ree_object_name = ree_object.name
|
105
213
|
package_name = package_name_from_uri(ree_object.uri)
|
@@ -163,7 +271,6 @@ module RubyLsp
|
|
163
271
|
|
164
272
|
def get_additional_text_edits_for_constant(parsed_doc, class_name, package_name, entry)
|
165
273
|
if parsed_doc.includes_linked_constant?(class_name)
|
166
|
-
$stderr.puts("links already include #{class_name}")
|
167
274
|
return []
|
168
275
|
end
|
169
276
|
|
@@ -173,7 +280,7 @@ module RubyLsp
|
|
173
280
|
fn_name = File.basename(entry_uri, ".*")
|
174
281
|
"\s\slink :#{fn_name}, import: -> { #{class_name} }"
|
175
282
|
else
|
176
|
-
path =
|
283
|
+
path = path_from_package_folder(entry_uri)
|
177
284
|
"\s\slink \"#{path}\", import: -> { #{class_name} }"
|
178
285
|
end
|
179
286
|
|
@@ -200,7 +307,6 @@ module RubyLsp
|
|
200
307
|
|
201
308
|
def get_additional_text_edits_for_method(parsed_doc, fn_name, package_name)
|
202
309
|
if parsed_doc.includes_linked_object?(fn_name)
|
203
|
-
$stderr.puts("links already include #{fn_name}")
|
204
310
|
return []
|
205
311
|
end
|
206
312
|
|
@@ -221,6 +327,7 @@ module RubyLsp
|
|
221
327
|
end
|
222
328
|
|
223
329
|
range = get_range_for_fn_insert(parsed_doc, link_text)
|
330
|
+
return unless range
|
224
331
|
|
225
332
|
[
|
226
333
|
Interface::TextEdit.new(
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require_relative "../handlers/completion_handler"
|
2
|
+
|
3
|
+
module RubyLsp
|
4
|
+
module Ree
|
5
|
+
class CompletionListener
|
6
|
+
include Requests::Support::Common
|
7
|
+
|
8
|
+
CHARS_COUNT = 1
|
9
|
+
|
10
|
+
def initialize(response_builder, node_context, index, dispatcher, uri)
|
11
|
+
@response_builder = response_builder
|
12
|
+
@handler = RubyLsp::Ree::CompletionHandler.new(index, uri, node_context)
|
13
|
+
|
14
|
+
dispatcher.register(self, :on_call_node_enter)
|
15
|
+
dispatcher.register(self, :on_constant_read_node_enter)
|
16
|
+
end
|
17
|
+
|
18
|
+
def on_constant_read_node_enter(node)
|
19
|
+
node_name = node.name.to_s
|
20
|
+
return if node_name.size < CHARS_COUNT
|
21
|
+
|
22
|
+
completion_items = @handler.get_class_name_completion_items(node)
|
23
|
+
put_items_into_response(completion_items)
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_call_node_enter(node)
|
27
|
+
completion_items = []
|
28
|
+
ree_receiver = @handler.get_ree_receiver(node.receiver)
|
29
|
+
|
30
|
+
if ree_receiver
|
31
|
+
completion_items = @handler.get_ree_object_methods_completions_items(ree_receiver, node.receiver, node)
|
32
|
+
else
|
33
|
+
return if node.receiver
|
34
|
+
return if node.name.to_s.size < CHARS_COUNT
|
35
|
+
|
36
|
+
completion_items = @handler.get_ree_objects_completions_items(node)
|
37
|
+
end
|
38
|
+
|
39
|
+
put_items_into_response(completion_items)
|
40
|
+
end
|
41
|
+
|
42
|
+
def put_items_into_response(items)
|
43
|
+
items.each do |item|
|
44
|
+
@response_builder << item
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require_relative "../utils/ree_lsp_utils"
|
2
|
+
require_relative "../parsing/parsed_link_node"
|
3
|
+
require_relative "../parsing/parsed_document_builder"
|
4
|
+
require_relative "../ree_object_finder"
|
5
|
+
|
6
|
+
module RubyLsp
|
7
|
+
module Ree
|
8
|
+
class DefinitionListener
|
9
|
+
include Requests::Support::Common
|
10
|
+
include RubyLsp::Ree::ReeLspUtils
|
11
|
+
|
12
|
+
def initialize(response_builder, node_context, index, dispatcher, uri)
|
13
|
+
@response_builder = response_builder
|
14
|
+
@node_context = node_context
|
15
|
+
@nesting = node_context.nesting
|
16
|
+
@index = index
|
17
|
+
@uri = uri
|
18
|
+
|
19
|
+
dispatcher.register(self, :on_call_node_enter, :on_symbol_node_enter, :on_string_node_enter, :on_constant_read_node_enter)
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_constant_read_node_enter(node)
|
23
|
+
link_nodes = if @node_context.parent.is_a?(Prism::CallNode) && @node_context.parent.name == :link
|
24
|
+
# inside link node
|
25
|
+
link_node = RubyLsp::Ree::ParsedLinkNode.new(@node_context.parent)
|
26
|
+
link_node.parse_imports
|
27
|
+
[link_node]
|
28
|
+
else
|
29
|
+
parsed_doc = if @node_context.parent.is_a?(Prism::CallNode)
|
30
|
+
RubyLsp::Ree::ParsedDocumentBuilder.build_from_uri(@uri)
|
31
|
+
else
|
32
|
+
RubyLsp::Ree::ParsedDocumentBuilder.build_from_ast(@node_context.parent, @uri)
|
33
|
+
end
|
34
|
+
|
35
|
+
parsed_doc.link_nodes
|
36
|
+
end
|
37
|
+
|
38
|
+
link_nodes.each do |link_node|
|
39
|
+
if link_node.imports.include?(node.name.to_s)
|
40
|
+
uri = ''
|
41
|
+
if link_node.file_path_type?
|
42
|
+
path = find_local_file_path(link_node.name)
|
43
|
+
next unless path
|
44
|
+
|
45
|
+
uri = File.join(Dir.pwd, path)
|
46
|
+
else
|
47
|
+
package_name = link_node.link_package_name || package_name_from_uri(@uri)
|
48
|
+
|
49
|
+
method_candidates = @index[link_node.name]
|
50
|
+
next if !method_candidates || method_candidates.size == 0
|
51
|
+
|
52
|
+
method = method_candidates.detect{ package_name_from_uri(_1.uri) == package_name }
|
53
|
+
next unless method
|
54
|
+
|
55
|
+
uri = method.uri.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
@response_builder << Interface::Location.new(
|
59
|
+
uri: uri,
|
60
|
+
range: Interface::Range.new(
|
61
|
+
start: Interface::Position.new(line: 0, character: 0),
|
62
|
+
end: Interface::Position.new(line: 0, character: 0),
|
63
|
+
),
|
64
|
+
)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def on_call_node_enter(node)
|
70
|
+
message = node.message
|
71
|
+
return unless message
|
72
|
+
|
73
|
+
definition_uri = nil
|
74
|
+
|
75
|
+
if node.receiver
|
76
|
+
# ruby lsp handles such cases itself
|
77
|
+
return
|
78
|
+
else
|
79
|
+
definition_item = ReeObjectFinder.new(@index).find_object(message)
|
80
|
+
definition_uri = definition_item.uri.to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
return unless definition_uri
|
84
|
+
|
85
|
+
@response_builder << Interface::Location.new(
|
86
|
+
uri: definition_uri,
|
87
|
+
range: Interface::Range.new(
|
88
|
+
start: Interface::Position.new(line: 0, character: 0),
|
89
|
+
end: Interface::Position.new(line: 0, character: 0),
|
90
|
+
),
|
91
|
+
)
|
92
|
+
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
def on_symbol_node_enter(node)
|
97
|
+
parent_node = @node_context.parent
|
98
|
+
return unless parent_node.name == :link
|
99
|
+
|
100
|
+
link_node = RubyLsp::Ree::ParsedLinkNode.new(parent_node, package_name_from_uri(@uri))
|
101
|
+
package_name = link_node.link_package_name
|
102
|
+
|
103
|
+
method_candidates = @index[node.unescaped]
|
104
|
+
return if !method_candidates || method_candidates.size == 0
|
105
|
+
|
106
|
+
method = method_candidates.detect{ package_name_from_uri(_1.uri) == package_name }
|
107
|
+
return unless method
|
108
|
+
|
109
|
+
@response_builder << Interface::Location.new(
|
110
|
+
uri: method.uri.to_s,
|
111
|
+
range: Interface::Range.new(
|
112
|
+
start: Interface::Position.new(line: 0, character: 0),
|
113
|
+
end: Interface::Position.new(line: 0, character: 0),
|
114
|
+
),
|
115
|
+
)
|
116
|
+
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
|
120
|
+
def on_string_node_enter(node)
|
121
|
+
local_path = find_local_file_path(node.unescaped)
|
122
|
+
|
123
|
+
if local_path
|
124
|
+
@response_builder << Interface::Location.new(
|
125
|
+
uri: File.join(Dir.pwd, local_path),
|
126
|
+
range: Interface::Range.new(
|
127
|
+
start: Interface::Position.new(line: 0, character: 0),
|
128
|
+
end: Interface::Position.new(line: 0, character: 0),
|
129
|
+
),
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require_relative "../ree_object_finder"
|
2
|
+
require_relative "../parsing/parsed_document_builder"
|
3
|
+
require_relative "../parsing/parsed_link_node"
|
4
|
+
require_relative "../utils/ree_lsp_utils"
|
5
|
+
|
6
|
+
module RubyLsp
|
7
|
+
module Ree
|
8
|
+
class HoverListener
|
9
|
+
include RubyLsp::Ree::ReeLspUtils
|
10
|
+
|
11
|
+
def initialize(response_builder, node_context, index, dispatcher)
|
12
|
+
@response_builder = response_builder
|
13
|
+
@node_context = node_context
|
14
|
+
@finder = ReeObjectFinder.new(index)
|
15
|
+
|
16
|
+
dispatcher.register(self, :on_call_node_enter)
|
17
|
+
dispatcher.register(self, :on_constant_read_node_enter)
|
18
|
+
end
|
19
|
+
|
20
|
+
def on_constant_read_node_enter(node)
|
21
|
+
# ree_object = @finder.search_classes(node.name.to_s).first
|
22
|
+
|
23
|
+
# $stderr.puts("ree_object #{ree_object.inspect}")
|
24
|
+
|
25
|
+
# return unless ree_object
|
26
|
+
|
27
|
+
# $stderr.puts("ree_object comm #{ree_object.comments.to_s}")
|
28
|
+
|
29
|
+
# @response_builder.push(ree_object.comments.to_s, category: :documentation)
|
30
|
+
end
|
31
|
+
|
32
|
+
def on_call_node_enter(node)
|
33
|
+
ree_object = @finder.find_object(node.name.to_s)
|
34
|
+
|
35
|
+
return unless ree_object
|
36
|
+
|
37
|
+
documentation = <<~DOC
|
38
|
+
Ree object, type: :#{@finder.object_type(ree_object)}
|
39
|
+
|
40
|
+
usage: #{node.name.to_s}#{get_detail_string(ree_object)}
|
41
|
+
|
42
|
+
package: #{package_name_from_uri(ree_object.uri)}
|
43
|
+
|
44
|
+
file: #{path_from_package_folder(ree_object.uri)}
|
45
|
+
DOC
|
46
|
+
|
47
|
+
$stderr.puts(documentation)
|
48
|
+
|
49
|
+
@response_builder.push(documentation, category: :documentation)
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_detail_string(ree_object)
|
53
|
+
return '' if ree_object.signatures.size == 0
|
54
|
+
|
55
|
+
"(#{get_parameters_string(ree_object.signatures.first)})"
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_parameters_string(signature)
|
59
|
+
return '' unless signature
|
60
|
+
|
61
|
+
signature.parameters.map(&:decorated_name).join(', ')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|