ruby-lsp 0.23.11 → 0.26.4
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/README.md +2 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp +10 -4
- data/exe/ruby-lsp-check +0 -4
- data/exe/ruby-lsp-launcher +45 -22
- data/exe/ruby-lsp-test-exec +6 -0
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +82 -116
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +140 -183
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +107 -236
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +188 -285
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +25 -57
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
- data/lib/ruby_indexer/test/class_variables_test.rb +14 -14
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
- data/lib/ruby_indexer/test/configuration_test.rb +49 -9
- data/lib/ruby_indexer/test/constant_test.rb +34 -34
- data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
- data/lib/ruby_indexer/test/index_test.rb +225 -135
- data/lib/ruby_indexer/test/instance_variables_test.rb +61 -37
- data/lib/ruby_indexer/test/method_test.rb +166 -123
- data/lib/ruby_indexer/test/prefix_tree_test.rb +21 -21
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +70 -75
- data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
- data/lib/ruby_indexer/test/test_case.rb +9 -3
- data/lib/ruby_indexer/test/uri_test.rb +15 -2
- data/lib/ruby_lsp/addon.rb +88 -86
- data/lib/ruby_lsp/base_server.rb +79 -65
- data/lib/ruby_lsp/client_capabilities.rb +16 -13
- data/lib/ruby_lsp/document.rb +205 -104
- data/lib/ruby_lsp/erb_document.rb +45 -47
- data/lib/ruby_lsp/global_state.rb +73 -57
- data/lib/ruby_lsp/internal.rb +8 -3
- data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
- data/lib/ruby_lsp/listeners/completion.rb +81 -76
- data/lib/ruby_lsp/listeners/definition.rb +44 -58
- data/lib/ruby_lsp/listeners/document_highlight.rb +149 -151
- data/lib/ruby_lsp/listeners/document_link.rb +94 -82
- data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
- data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
- data/lib/ruby_lsp/listeners/hover.rb +107 -115
- data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
- data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
- data/lib/ruby_lsp/listeners/spec_style.rb +231 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +107 -0
- data/lib/ruby_lsp/listeners/test_style.rb +207 -95
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +10 -11
- data/lib/ruby_lsp/requests/code_action_resolve.rb +65 -61
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +31 -21
- data/lib/ruby_lsp/requests/completion.rb +8 -21
- data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
- data/lib/ruby_lsp/requests/definition.rb +8 -20
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
- data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
- data/lib/ruby_lsp/requests/document_link.rb +6 -17
- data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
- data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
- data/lib/ruby_lsp/requests/formatting.rb +6 -9
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +139 -0
- data/lib/ruby_lsp/requests/hover.rb +12 -25
- data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
- data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
- data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +17 -57
- data/lib/ruby_lsp/requests/rename.rb +27 -51
- data/lib/ruby_lsp/requests/request.rb +13 -25
- data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
- data/lib/ruby_lsp/requests/signature_help.rb +9 -27
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +23 -61
- data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
- data/lib/ruby_lsp/requests/support/package_url.rb +414 -0
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
- data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
- data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
- data/lib/ruby_lsp/requests/workspace_symbol.rb +24 -16
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
- data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
- data/lib/ruby_lsp/response_builders/hover.rb +12 -18
- data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
- data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
- data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
- data/lib/ruby_lsp/ruby_document.rb +32 -98
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
- data/lib/ruby_lsp/server.rb +305 -198
- data/lib/ruby_lsp/setup_bundler.rb +131 -82
- data/lib/ruby_lsp/static_docs.rb +12 -7
- data/lib/ruby_lsp/store.rb +21 -49
- data/lib/ruby_lsp/test_helper.rb +3 -16
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +241 -0
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
- data/lib/ruby_lsp/type_inferrer.rb +13 -14
- data/lib/ruby_lsp/utils.rb +138 -93
- data/static_docs/break.md +103 -0
- metadata +15 -20
- data/lib/ruby_lsp/load_sorbet.rb +0 -62
|
@@ -3,125 +3,247 @@
|
|
|
3
3
|
|
|
4
4
|
module RubyLsp
|
|
5
5
|
module Listeners
|
|
6
|
-
class TestStyle
|
|
7
|
-
|
|
6
|
+
class TestStyle < TestDiscovery
|
|
7
|
+
class << self
|
|
8
|
+
# Resolves the minimal set of commands required to execute the requested tests
|
|
9
|
+
#: (Array[Hash[Symbol, untyped]]) -> Array[String]
|
|
10
|
+
def resolve_test_commands(items)
|
|
11
|
+
# A nested hash of file_path => test_group => { tags: [], examples: [test_example] } to ensure we build the
|
|
12
|
+
# minimum amount of commands needed to execute the requested tests. This is only used for specific examples
|
|
13
|
+
# where we will need more complex regexes to execute it all at the same time
|
|
14
|
+
aggregated_tests = Hash.new do |hash, key|
|
|
15
|
+
hash[key] = Hash.new do |inner_h, inner_k|
|
|
16
|
+
inner_h[inner_k] = { tags: Set.new, examples: [] }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Full files are paths that should be executed as a whole e.g.: an entire test file or directory
|
|
21
|
+
full_files = []
|
|
22
|
+
queue = items.dup
|
|
23
|
+
|
|
24
|
+
until queue.empty?
|
|
25
|
+
item = queue.shift #: as !nil
|
|
26
|
+
tags = Set.new(item[:tags])
|
|
27
|
+
next unless tags.include?("framework:minitest") || tags.include?("framework:test_unit")
|
|
28
|
+
|
|
29
|
+
children = item[:children]
|
|
30
|
+
uri = URI(item[:uri])
|
|
31
|
+
path = uri.full_path
|
|
32
|
+
next unless path
|
|
33
|
+
|
|
34
|
+
if tags.include?("test_dir")
|
|
35
|
+
if children.empty?
|
|
36
|
+
full_files.concat(
|
|
37
|
+
Dir.glob(
|
|
38
|
+
"#{path}/**/{*_test,test_*,*_spec}.rb",
|
|
39
|
+
File::Constants::FNM_EXTGLOB | File::Constants::FNM_PATHNAME,
|
|
40
|
+
).map! { |p| Shellwords.escape(p) },
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
elsif tags.include?("test_file")
|
|
44
|
+
full_files << Shellwords.escape(path) if children.empty?
|
|
45
|
+
elsif tags.include?("test_group")
|
|
46
|
+
# If all of the children of the current test group are other groups, then there's no need to add it to the
|
|
47
|
+
# aggregated examples
|
|
48
|
+
unless children.any? && children.all? { |child| child[:tags].include?("test_group") }
|
|
49
|
+
aggregated_tests[path][item[:id]] = { tags: tags, examples: [] }
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
class_name, method_name = item[:id].split("#")
|
|
53
|
+
aggregated_tests[path][class_name][:examples] << method_name
|
|
54
|
+
aggregated_tests[path][class_name][:tags].merge(tags)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
queue.concat(children) unless children.empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
commands = []
|
|
61
|
+
|
|
62
|
+
aggregated_tests.each do |file_path, groups_and_examples|
|
|
63
|
+
# Separate groups into Minitest and Test Unit. You can have both frameworks in the same file, but you cannot
|
|
64
|
+
# have a group belongs to both at the same time
|
|
65
|
+
minitest_groups, test_unit_groups = groups_and_examples.partition do |_, info|
|
|
66
|
+
info[:tags].include?("framework:minitest")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
if minitest_groups.any?
|
|
70
|
+
commands << handle_minitest_groups(file_path, minitest_groups)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
if test_unit_groups.any?
|
|
74
|
+
commands.concat(handle_test_unit_groups(file_path, test_unit_groups))
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
unless full_files.empty?
|
|
79
|
+
specs, tests = full_files.partition { |path| spec?(path) }
|
|
80
|
+
|
|
81
|
+
commands << "#{COMMAND} -Itest -e \"ARGV.each { |f| require f }\" #{tests.join(" ")}" if tests.any?
|
|
82
|
+
commands << "#{COMMAND} -Ispec -e \"ARGV.each { |f| require f }\" #{specs.join(" ")}" if specs.any?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
commands
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
#: (String) -> bool
|
|
91
|
+
def spec?(path)
|
|
92
|
+
File.fnmatch?("**/spec/**/*_spec.rb", path, File::FNM_PATHNAME | File::FNM_EXTGLOB)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
#: (String, Hash[String, Hash[Symbol, untyped]]) -> String
|
|
96
|
+
def handle_minitest_groups(file_path, groups_and_examples)
|
|
97
|
+
regexes = groups_and_examples.flat_map do |group, info|
|
|
98
|
+
examples = info[:examples].map { |e| Shellwords.escape(e).gsub(/test_\d{4}/, "test_\\d{4}") }
|
|
99
|
+
group_regex = Shellwords.escape(group).gsub(
|
|
100
|
+
Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
|
|
101
|
+
".*",
|
|
102
|
+
)
|
|
103
|
+
if examples.empty?
|
|
104
|
+
"^#{group_regex}(#|::)"
|
|
105
|
+
elsif examples.length == 1
|
|
106
|
+
"^#{group_regex}##{examples[0]}\\$"
|
|
107
|
+
else
|
|
108
|
+
"^#{group_regex}#(#{examples.join("|")})\\$"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
regex = if regexes.length == 1
|
|
113
|
+
regexes[0]
|
|
114
|
+
else
|
|
115
|
+
"(#{regexes.join("|")})"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
load_path = spec?(file_path) ? "-Ispec" : "-Itest"
|
|
119
|
+
"#{COMMAND} #{load_path} #{Shellwords.escape(file_path)} --name \"/#{regex}/\""
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#: (String, Hash[String, Hash[Symbol, untyped]]) -> Array[String]
|
|
123
|
+
def handle_test_unit_groups(file_path, groups_and_examples)
|
|
124
|
+
groups_and_examples.map do |group, info|
|
|
125
|
+
examples = info[:examples]
|
|
126
|
+
group_regex = Shellwords.escape(group).gsub(
|
|
127
|
+
Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
|
|
128
|
+
".*",
|
|
129
|
+
)
|
|
130
|
+
command = +"#{COMMAND} -Itest #{Shellwords.escape(file_path)} --testcase \"/^#{group_regex}\\$/\""
|
|
131
|
+
|
|
132
|
+
unless examples.empty?
|
|
133
|
+
command << if examples.length == 1
|
|
134
|
+
" --name \"/#{examples[0]}\\$/\""
|
|
135
|
+
else
|
|
136
|
+
" --name \"/(#{examples.join("|")})\\$/\""
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
command
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
8
145
|
include Requests::Support::Common
|
|
9
146
|
|
|
147
|
+
MINITEST_REPORTER_PATH = File.expand_path("../test_reporters/minitest_reporter.rb", __dir__) #: String
|
|
148
|
+
TEST_UNIT_REPORTER_PATH = File.expand_path("../test_reporters/test_unit_reporter.rb", __dir__) #: String
|
|
149
|
+
BASE_COMMAND = begin
|
|
150
|
+
Bundler.with_unbundled_env { Bundler.default_lockfile }
|
|
151
|
+
"bundle exec ruby"
|
|
152
|
+
rescue Bundler::GemfileNotFound
|
|
153
|
+
"ruby"
|
|
154
|
+
end #: String
|
|
155
|
+
COMMAND = "#{BASE_COMMAND} -r#{MINITEST_REPORTER_PATH} -r#{TEST_UNIT_REPORTER_PATH}" #: String
|
|
10
156
|
ACCESS_MODIFIERS = [:public, :private, :protected].freeze
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
sig do
|
|
14
|
-
params(
|
|
15
|
-
response_builder: ResponseBuilders::TestCollection,
|
|
16
|
-
global_state: GlobalState,
|
|
17
|
-
dispatcher: Prism::Dispatcher,
|
|
18
|
-
uri: URI::Generic,
|
|
19
|
-
).void
|
|
20
|
-
end
|
|
157
|
+
|
|
158
|
+
#: (ResponseBuilders::TestCollection, GlobalState, Prism::Dispatcher, URI::Generic) -> void
|
|
21
159
|
def initialize(response_builder, global_state, dispatcher, uri)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@
|
|
25
|
-
@
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
self,
|
|
160
|
+
super(response_builder, global_state, uri)
|
|
161
|
+
|
|
162
|
+
@framework = :minitest #: Symbol
|
|
163
|
+
@parent_stack = [@response_builder] #: Array[(Requests::Support::TestItem | ResponseBuilders::TestCollection)?]
|
|
164
|
+
|
|
165
|
+
register_events(
|
|
166
|
+
dispatcher,
|
|
30
167
|
:on_class_node_enter,
|
|
31
|
-
:on_class_node_leave,
|
|
32
|
-
:on_module_node_enter,
|
|
33
|
-
:on_module_node_leave,
|
|
34
168
|
:on_def_node_enter,
|
|
35
169
|
:on_call_node_enter,
|
|
36
170
|
:on_call_node_leave,
|
|
37
171
|
)
|
|
38
172
|
end
|
|
39
173
|
|
|
40
|
-
|
|
41
|
-
def on_class_node_enter(node)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
name ||= name_with_dynamic_reference(node.constant_path)
|
|
174
|
+
#: (Prism::ClassNode node) -> void
|
|
175
|
+
def on_class_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
|
176
|
+
with_test_ancestor_tracking(node) do |name, ancestors|
|
|
177
|
+
@framework = :test_unit if ancestors.include?("Test::Unit::TestCase")
|
|
45
178
|
|
|
46
|
-
|
|
179
|
+
if @framework == :test_unit || non_declarative_minitest?(ancestors, name)
|
|
180
|
+
test_item = Requests::Support::TestItem.new(
|
|
181
|
+
name,
|
|
182
|
+
name,
|
|
183
|
+
@uri,
|
|
184
|
+
range_from_node(node),
|
|
185
|
+
framework: @framework,
|
|
186
|
+
)
|
|
47
187
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
188
|
+
last_test_group.add(test_item)
|
|
189
|
+
@response_builder.add_code_lens(test_item)
|
|
190
|
+
@parent_stack << test_item
|
|
191
|
+
else
|
|
192
|
+
@parent_stack << nil
|
|
193
|
+
end
|
|
54
194
|
end
|
|
55
|
-
|
|
56
|
-
if attached_ancestors.include?("Test::Unit::TestCase") ||
|
|
57
|
-
non_declarative_minitest?(attached_ancestors, fully_qualified_name)
|
|
58
|
-
|
|
59
|
-
@response_builder.add(Requests::Support::TestItem.new(
|
|
60
|
-
fully_qualified_name,
|
|
61
|
-
fully_qualified_name,
|
|
62
|
-
@uri,
|
|
63
|
-
range_from_node(node),
|
|
64
|
-
))
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
@nesting << name
|
|
68
195
|
end
|
|
69
196
|
|
|
70
|
-
|
|
71
|
-
def
|
|
72
|
-
@
|
|
73
|
-
|
|
74
|
-
name = constant_name(node.constant_path)
|
|
75
|
-
name ||= name_with_dynamic_reference(node.constant_path)
|
|
76
|
-
|
|
77
|
-
@nesting << name
|
|
197
|
+
#: (Prism::ClassNode node) -> void
|
|
198
|
+
def on_class_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
|
199
|
+
@parent_stack.pop
|
|
200
|
+
super
|
|
78
201
|
end
|
|
79
202
|
|
|
80
|
-
|
|
81
|
-
def
|
|
82
|
-
@
|
|
83
|
-
|
|
203
|
+
#: (Prism::ModuleNode node) -> void
|
|
204
|
+
def on_module_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
|
205
|
+
@parent_stack << nil
|
|
206
|
+
super
|
|
84
207
|
end
|
|
85
208
|
|
|
86
|
-
|
|
87
|
-
def
|
|
88
|
-
@
|
|
89
|
-
|
|
209
|
+
#: (Prism::ModuleNode node) -> void
|
|
210
|
+
def on_module_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
|
211
|
+
@parent_stack.pop
|
|
212
|
+
super
|
|
90
213
|
end
|
|
91
214
|
|
|
92
|
-
|
|
93
|
-
def on_def_node_enter(node)
|
|
215
|
+
#: (Prism::DefNode node) -> void
|
|
216
|
+
def on_def_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
|
94
217
|
return if @visibility_stack.last != :public
|
|
95
218
|
|
|
96
219
|
name = node.name.to_s
|
|
97
220
|
return unless name.start_with?("test_")
|
|
98
221
|
|
|
99
222
|
current_group_name = RubyIndexer::Index.actual_nesting(@nesting, nil).join("::")
|
|
223
|
+
parent = @parent_stack.last
|
|
224
|
+
return unless parent.is_a?(Requests::Support::TestItem)
|
|
100
225
|
|
|
101
|
-
|
|
102
|
-
# previously pushed and thus we return early and avoid adding items for a framework this listener is not
|
|
103
|
-
# interested in
|
|
104
|
-
test_item = @response_builder[current_group_name]
|
|
105
|
-
return unless test_item
|
|
106
|
-
|
|
107
|
-
test_item.add(Requests::Support::TestItem.new(
|
|
226
|
+
example_item = Requests::Support::TestItem.new(
|
|
108
227
|
"#{current_group_name}##{name}",
|
|
109
228
|
name,
|
|
110
229
|
@uri,
|
|
111
230
|
range_from_node(node),
|
|
112
|
-
|
|
231
|
+
framework: @framework,
|
|
232
|
+
)
|
|
233
|
+
parent.add(example_item)
|
|
234
|
+
@response_builder.add_code_lens(example_item)
|
|
113
235
|
end
|
|
114
236
|
|
|
115
|
-
|
|
116
|
-
def on_call_node_enter(node)
|
|
237
|
+
#: (Prism::CallNode node) -> void
|
|
238
|
+
def on_call_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
|
117
239
|
name = node.name
|
|
118
240
|
return unless ACCESS_MODIFIERS.include?(name)
|
|
119
241
|
|
|
120
242
|
@visibility_stack << name
|
|
121
243
|
end
|
|
122
244
|
|
|
123
|
-
|
|
124
|
-
def on_call_node_leave(node)
|
|
245
|
+
#: (Prism::CallNode node) -> void
|
|
246
|
+
def on_call_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
|
125
247
|
name = node.name
|
|
126
248
|
return unless ACCESS_MODIFIERS.include?(name)
|
|
127
249
|
return unless node.arguments&.arguments
|
|
@@ -131,7 +253,13 @@ module RubyLsp
|
|
|
131
253
|
|
|
132
254
|
private
|
|
133
255
|
|
|
134
|
-
|
|
256
|
+
#: -> (Requests::Support::TestItem | ResponseBuilders::TestCollection)
|
|
257
|
+
def last_test_group
|
|
258
|
+
index = @parent_stack.rindex { |i| i } #: as !nil
|
|
259
|
+
@parent_stack[index] #: as Requests::Support::TestItem | ResponseBuilders::TestCollection
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
#: (Array[String] attached_ancestors, String fully_qualified_name) -> bool
|
|
135
263
|
def non_declarative_minitest?(attached_ancestors, fully_qualified_name)
|
|
136
264
|
return false unless attached_ancestors.include?("Minitest::Test")
|
|
137
265
|
|
|
@@ -143,22 +271,6 @@ module RubyLsp
|
|
|
143
271
|
rescue RubyIndexer::Index::NonExistingNamespaceError
|
|
144
272
|
true
|
|
145
273
|
end
|
|
146
|
-
|
|
147
|
-
sig do
|
|
148
|
-
params(
|
|
149
|
-
node: T.any(
|
|
150
|
-
Prism::ConstantPathNode,
|
|
151
|
-
Prism::ConstantReadNode,
|
|
152
|
-
Prism::ConstantPathTargetNode,
|
|
153
|
-
Prism::CallNode,
|
|
154
|
-
Prism::MissingNode,
|
|
155
|
-
),
|
|
156
|
-
).returns(String)
|
|
157
|
-
end
|
|
158
|
-
def name_with_dynamic_reference(node)
|
|
159
|
-
slice = node.slice
|
|
160
|
-
slice.gsub(/((?<=::)|^)[a-z]\w*/, DYNAMIC_REFERENCE_MARKER)
|
|
161
|
-
end
|
|
162
274
|
end
|
|
163
275
|
end
|
|
164
276
|
end
|
|
@@ -5,36 +5,19 @@ module RubyLsp
|
|
|
5
5
|
# This class allows listeners to access contextual information about a node in the AST, such as its parent,
|
|
6
6
|
# its namespace nesting, and the surrounding CallNode (e.g. a method call).
|
|
7
7
|
class NodeContext
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
sig { returns(T.nilable(Prism::Node)) }
|
|
8
|
+
#: Prism::Node?
|
|
11
9
|
attr_reader :node, :parent
|
|
12
10
|
|
|
13
|
-
|
|
11
|
+
#: Array[String]
|
|
14
12
|
attr_reader :nesting
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
#: Prism::CallNode?
|
|
17
15
|
attr_reader :call_node
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
#: String?
|
|
20
18
|
attr_reader :surrounding_method
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
params(
|
|
24
|
-
node: T.nilable(Prism::Node),
|
|
25
|
-
parent: T.nilable(Prism::Node),
|
|
26
|
-
nesting_nodes: T::Array[T.any(
|
|
27
|
-
Prism::ClassNode,
|
|
28
|
-
Prism::ModuleNode,
|
|
29
|
-
Prism::SingletonClassNode,
|
|
30
|
-
Prism::DefNode,
|
|
31
|
-
Prism::BlockNode,
|
|
32
|
-
Prism::LambdaNode,
|
|
33
|
-
Prism::ProgramNode,
|
|
34
|
-
)],
|
|
35
|
-
call_node: T.nilable(Prism::CallNode),
|
|
36
|
-
).void
|
|
37
|
-
end
|
|
20
|
+
#: (Prism::Node? node, Prism::Node? parent, Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] nesting_nodes, Prism::CallNode? call_node) -> void
|
|
38
21
|
def initialize(node, parent, nesting_nodes, call_node)
|
|
39
22
|
@node = node
|
|
40
23
|
@parent = parent
|
|
@@ -42,16 +25,16 @@ module RubyLsp
|
|
|
42
25
|
@call_node = call_node
|
|
43
26
|
|
|
44
27
|
nesting, surrounding_method = handle_nesting_nodes(nesting_nodes)
|
|
45
|
-
@nesting =
|
|
46
|
-
@surrounding_method =
|
|
28
|
+
@nesting = nesting #: Array[String]
|
|
29
|
+
@surrounding_method = surrounding_method #: String?
|
|
47
30
|
end
|
|
48
31
|
|
|
49
|
-
|
|
32
|
+
#: -> String
|
|
50
33
|
def fully_qualified_name
|
|
51
|
-
@fully_qualified_name ||=
|
|
34
|
+
@fully_qualified_name ||= @nesting.join("::") #: String?
|
|
52
35
|
end
|
|
53
36
|
|
|
54
|
-
|
|
37
|
+
#: -> Array[Symbol]
|
|
55
38
|
def locals_for_scope
|
|
56
39
|
locals = []
|
|
57
40
|
|
|
@@ -69,20 +52,10 @@ module RubyLsp
|
|
|
69
52
|
|
|
70
53
|
private
|
|
71
54
|
|
|
72
|
-
|
|
73
|
-
params(nodes: T::Array[T.any(
|
|
74
|
-
Prism::ClassNode,
|
|
75
|
-
Prism::ModuleNode,
|
|
76
|
-
Prism::SingletonClassNode,
|
|
77
|
-
Prism::DefNode,
|
|
78
|
-
Prism::BlockNode,
|
|
79
|
-
Prism::LambdaNode,
|
|
80
|
-
Prism::ProgramNode,
|
|
81
|
-
)]).returns([T::Array[String], T.nilable(String)])
|
|
82
|
-
end
|
|
55
|
+
#: (Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] nodes) -> [Array[String], String?]
|
|
83
56
|
def handle_nesting_nodes(nodes)
|
|
84
57
|
nesting = []
|
|
85
|
-
surrounding_method =
|
|
58
|
+
surrounding_method = nil #: String?
|
|
86
59
|
|
|
87
60
|
@nesting_nodes.each do |node|
|
|
88
61
|
case node
|
|
@@ -2,19 +2,16 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module RubyLsp
|
|
5
|
+
#: [ParseResultType = Array[RBS::AST::Declarations::Base]]
|
|
5
6
|
class RBSDocument < Document
|
|
6
|
-
|
|
7
|
-
extend T::Generic
|
|
8
|
-
|
|
9
|
-
ParseResultType = type_member { { fixed: T::Array[RBS::AST::Declarations::Base] } }
|
|
10
|
-
|
|
11
|
-
sig { params(source: String, version: Integer, uri: URI::Generic, global_state: GlobalState).void }
|
|
7
|
+
#: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
|
|
12
8
|
def initialize(source:, version:, uri:, global_state:)
|
|
13
|
-
@syntax_error =
|
|
9
|
+
@syntax_error = false #: bool
|
|
14
10
|
super
|
|
15
11
|
end
|
|
16
12
|
|
|
17
|
-
|
|
13
|
+
# @override
|
|
14
|
+
#: -> bool
|
|
18
15
|
def parse!
|
|
19
16
|
return false unless @needs_parsing
|
|
20
17
|
|
|
@@ -29,14 +26,16 @@ module RubyLsp
|
|
|
29
26
|
true
|
|
30
27
|
end
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
# @override
|
|
30
|
+
#: -> bool
|
|
33
31
|
def syntax_error?
|
|
34
32
|
@syntax_error
|
|
35
33
|
end
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
# @override
|
|
36
|
+
#: -> Symbol
|
|
38
37
|
def language_id
|
|
39
|
-
|
|
38
|
+
:rbs
|
|
40
39
|
end
|
|
41
40
|
end
|
|
42
41
|
end
|