ruby-lsp 0.23.11 → 0.23.12
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-launcher +12 -11
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +52 -77
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +61 -144
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +8 -6
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +73 -182
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +48 -181
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +12 -14
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +21 -44
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +40 -58
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +9 -16
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
- data/lib/ruby_indexer/test/configuration_test.rb +32 -2
- data/lib/ruby_indexer/test/method_test.rb +2 -2
- data/lib/ruby_lsp/addon.rb +32 -67
- data/lib/ruby_lsp/base_server.rb +10 -10
- data/lib/ruby_lsp/client_capabilities.rb +4 -6
- data/lib/ruby_lsp/document.rb +21 -32
- data/lib/ruby_lsp/erb_document.rb +17 -27
- data/lib/ruby_lsp/global_state.rb +30 -32
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +21 -39
- data/lib/ruby_lsp/listeners/completion.rb +34 -53
- data/lib/ruby_lsp/listeners/definition.rb +35 -49
- data/lib/ruby_lsp/listeners/document_highlight.rb +60 -69
- data/lib/ruby_lsp/listeners/document_link.rb +9 -19
- data/lib/ruby_lsp/listeners/document_symbol.rb +34 -48
- data/lib/ruby_lsp/listeners/folding_ranges.rb +31 -38
- data/lib/ruby_lsp/listeners/hover.rb +37 -47
- data/lib/ruby_lsp/listeners/inlay_hints.rb +3 -10
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +29 -35
- data/lib/ruby_lsp/listeners/signature_help.rb +4 -23
- data/lib/ruby_lsp/listeners/spec_style.rb +199 -0
- data/lib/ruby_lsp/listeners/test_style.rb +136 -30
- data/lib/ruby_lsp/node_context.rb +8 -35
- data/lib/ruby_lsp/rbs_document.rb +7 -5
- data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
- data/lib/ruby_lsp/requests/code_actions.rb +5 -14
- data/lib/ruby_lsp/requests/code_lens.rb +4 -13
- data/lib/ruby_lsp/requests/completion.rb +4 -15
- data/lib/ruby_lsp/requests/completion_resolve.rb +4 -4
- data/lib/ruby_lsp/requests/definition.rb +4 -12
- data/lib/ruby_lsp/requests/diagnostics.rb +6 -9
- data/lib/ruby_lsp/requests/discover_tests.rb +15 -3
- data/lib/ruby_lsp/requests/document_highlight.rb +3 -11
- data/lib/ruby_lsp/requests/document_link.rb +4 -13
- data/lib/ruby_lsp/requests/document_symbol.rb +4 -7
- data/lib/ruby_lsp/requests/folding_ranges.rb +4 -7
- data/lib/ruby_lsp/requests/formatting.rb +4 -7
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +87 -0
- data/lib/ruby_lsp/requests/hover.rb +6 -16
- data/lib/ruby_lsp/requests/inlay_hints.rb +4 -13
- data/lib/ruby_lsp/requests/on_type_formatting.rb +17 -24
- data/lib/ruby_lsp/requests/prepare_rename.rb +3 -8
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
- data/lib/ruby_lsp/requests/range_formatting.rb +3 -4
- data/lib/ruby_lsp/requests/references.rb +5 -35
- data/lib/ruby_lsp/requests/rename.rb +9 -35
- data/lib/ruby_lsp/requests/request.rb +5 -17
- data/lib/ruby_lsp/requests/selection_ranges.rb +3 -3
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +6 -23
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +4 -5
- data/lib/ruby_lsp/requests/signature_help.rb +6 -24
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +12 -49
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +12 -14
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +7 -10
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +9 -15
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
- data/lib/ruby_lsp/requests/support/sorbet.rb +1 -7
- data/lib/ruby_lsp/requests/support/source_uri.rb +5 -16
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +7 -10
- data/lib/ruby_lsp/requests/support/test_item.rb +14 -13
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +4 -5
- data/lib/ruby_lsp/requests/workspace_symbol.rb +3 -3
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +4 -4
- data/lib/ruby_lsp/response_builders/document_symbol.rb +8 -11
- data/lib/ruby_lsp/response_builders/hover.rb +5 -5
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +18 -40
- data/lib/ruby_lsp/response_builders/signature_help.rb +4 -5
- data/lib/ruby_lsp/response_builders/test_collection.rb +5 -9
- data/lib/ruby_lsp/ruby_document.rb +15 -40
- data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +106 -0
- data/lib/ruby_lsp/scope.rb +6 -10
- data/lib/ruby_lsp/server.rb +125 -74
- data/lib/ruby_lsp/setup_bundler.rb +22 -15
- data/lib/ruby_lsp/store.rb +12 -28
- data/lib/ruby_lsp/test_helper.rb +3 -12
- data/lib/ruby_lsp/test_reporter.rb +71 -0
- data/lib/ruby_lsp/test_unit_test_runner.rb +96 -0
- data/lib/ruby_lsp/type_inferrer.rb +9 -13
- data/lib/ruby_lsp/utils.rb +27 -65
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b902a160bf7f96c2b65716065887523f5e4d1788e9ba7211a5500513f951d2f
|
4
|
+
data.tar.gz: d2500874ca70ea7aa4df5d1ce2106d16e67143fb5cff87208bdfab36a4b49414
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d7d14c58e08d99a9c4f19d2ccde6171da415093c7ebab744181af7ebc8617eae4ba09a992123542d5a5ba44177457cd23cd8bd0ece1886b17237c7bad73fc2b
|
7
|
+
data.tar.gz: eea9a42eeabe3e8c5ce86210770f76e210b313bd94bc457dcfe99fc7a0913e24443b67e35c4c64e46420e95a47cd2cb0eaa7004fbbb8e9544932a90c63686219
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
[](https://github.com/Shopify/ruby-lsp/actions/workflows/ci.yml)
|
6
6
|
[](https://marketplace.visualstudio.com/items?itemName=Shopify.ruby-lsp)
|
7
|
-
[](https://
|
7
|
+
[](https://shopify.github.io/ruby-lsp/invite)
|
8
8
|
|
9
9
|
# Ruby LSP
|
10
10
|
|
@@ -13,7 +13,7 @@ for Ruby, used to improve rich features in editors. It is a part of a wider goal
|
|
13
13
|
experience to Ruby developers using modern standards for cross-editor features, documentation and debugging.
|
14
14
|
|
15
15
|
Want to discuss Ruby developer experience? Consider joining the public
|
16
|
-
[Ruby DX Slack workspace](https://
|
16
|
+
[Ruby DX Slack workspace](https://shopify.github.io/ruby-lsp/invite).
|
17
17
|
|
18
18
|
## Getting Started
|
19
19
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.23.
|
1
|
+
0.23.12
|
data/exe/ruby-lsp-launcher
CHANGED
@@ -83,19 +83,20 @@ begin
|
|
83
83
|
Bundler.setup
|
84
84
|
$stderr.puts("Composed Bundle set up successfully")
|
85
85
|
end
|
86
|
-
rescue
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
# to telemetry, which is not useful
|
94
|
-
unless install_error && e.is_a?(Bundler::GemNotFound)
|
95
|
-
setup_error = e
|
96
|
-
$stderr.puts("Failed to set up composed Bundle\n#{e.full_message}")
|
86
|
+
rescue Bundler::GemNotFound, Bundler::GitError
|
87
|
+
# Sometimes, we successfully set up the bundle, but users either change their Gemfile or uninstall gems from an
|
88
|
+
# external process. If there's no install error, but the gem is still not found, then we need to attempt to start from
|
89
|
+
# scratch
|
90
|
+
unless install_error || ARGV.include?("--retry")
|
91
|
+
$stderr.puts("Initial bundle compose succeeded, but Bundler.setup failed. Trying to restart from scratch...")
|
92
|
+
exec(Gem.ruby, File.expand_path("ruby-lsp-launcher", __dir__), *ARGV, "--retry")
|
97
93
|
end
|
98
94
|
|
95
|
+
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
96
|
+
rescue StandardError => e
|
97
|
+
setup_error = e
|
98
|
+
$stderr.puts("Failed to set up composed Bundle\n#{e.full_message}")
|
99
|
+
|
99
100
|
# If Bundler.setup fails, we need to restore the original $LOAD_PATH so that we can still require the Ruby LSP server
|
100
101
|
# in degraded mode
|
101
102
|
$LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
|
@@ -63,8 +63,6 @@ module RuboCop
|
|
63
63
|
# end
|
64
64
|
# end
|
65
65
|
class UseRegisterWithHandlerMethod < RuboCop::Cop::Base
|
66
|
-
extend T::Sig
|
67
|
-
|
68
66
|
MSG_MISSING_HANDLER = "Registered to `%{listener}` without a handler defined."
|
69
67
|
MSG_MISSING_LISTENER = "Created a handler without registering the associated `%{listener}` event."
|
70
68
|
|
@@ -93,12 +91,12 @@ module RuboCop
|
|
93
91
|
|
94
92
|
private
|
95
93
|
|
96
|
-
|
94
|
+
#: (Symbol event_name) -> bool
|
97
95
|
def valid_event_name?(event_name)
|
98
96
|
/^on_.*(node_enter|node_leave)$/.match?(event_name)
|
99
97
|
end
|
100
98
|
|
101
|
-
|
99
|
+
#: (Array[RuboCop::AST::SymbolNode] listeners, Array[RuboCop::AST::DefNode] handlers) -> void
|
102
100
|
def add_offense_to_listeners_without_handler(listeners, handlers)
|
103
101
|
return if listeners.none?
|
104
102
|
|
@@ -107,7 +105,7 @@ module RuboCop
|
|
107
105
|
.each { |node| add_offense(node, message: format(MSG_MISSING_HANDLER, listener: node.value)) }
|
108
106
|
end
|
109
107
|
|
110
|
-
|
108
|
+
#: (Array[RuboCop::AST::SymbolNode] listeners, Array[RuboCop::AST::DefNode] handlers) -> void
|
111
109
|
def add_offense_handlers_without_listener(listeners, handlers)
|
112
110
|
return if handlers.none?
|
113
111
|
|
@@ -3,8 +3,6 @@
|
|
3
3
|
|
4
4
|
module RubyIndexer
|
5
5
|
class Configuration
|
6
|
-
extend T::Sig
|
7
|
-
|
8
6
|
CONFIGURATION_SCHEMA = T.let(
|
9
7
|
{
|
10
8
|
"excluded_gems" => Array,
|
@@ -16,13 +14,13 @@ module RubyIndexer
|
|
16
14
|
T::Hash[String, T.untyped],
|
17
15
|
)
|
18
16
|
|
19
|
-
|
17
|
+
#: String
|
20
18
|
attr_writer :workspace_path
|
21
19
|
|
22
|
-
|
20
|
+
#: Encoding
|
23
21
|
attr_accessor :encoding
|
24
22
|
|
25
|
-
|
23
|
+
#: -> void
|
26
24
|
def initialize
|
27
25
|
@workspace_path = T.let(Dir.pwd, String)
|
28
26
|
@encoding = T.let(Encoding::UTF_8, Encoding)
|
@@ -31,11 +29,8 @@ module RubyIndexer
|
|
31
29
|
|
32
30
|
@excluded_patterns = T.let(
|
33
31
|
[
|
34
|
-
|
35
|
-
|
36
|
-
File.join("spec", "**", "*"),
|
37
|
-
File.join("test", "**", "*"),
|
38
|
-
File.join("tmp", "**", "*"),
|
32
|
+
"**/{test,spec}/**/{*_test.rb,test_*.rb,*_spec.rb}",
|
33
|
+
"**/fixtures/**/*",
|
39
34
|
],
|
40
35
|
T::Array[String],
|
41
36
|
)
|
@@ -44,10 +39,13 @@ module RubyIndexer
|
|
44
39
|
if path
|
45
40
|
# Substitute Windows backslashes into forward slashes, which are used in glob patterns
|
46
41
|
glob = path.gsub(/[\\]+/, "/")
|
47
|
-
|
42
|
+
glob.delete_suffix!("/")
|
43
|
+
@excluded_patterns << "#{glob}/**/*.rb"
|
48
44
|
end
|
49
45
|
|
50
|
-
|
46
|
+
# We start the included patterns with only the non excluded directories so that we can avoid paying the price of
|
47
|
+
# traversing large directories that don't include Ruby files like `node_modules`
|
48
|
+
@included_patterns = T.let(["{#{top_level_directories.join(",")}}/**/*.rb", "*.rb"], T::Array[String])
|
51
49
|
@excluded_magic_comments = T.let(
|
52
50
|
[
|
53
51
|
"frozen_string_literal:",
|
@@ -66,22 +64,7 @@ module RubyIndexer
|
|
66
64
|
)
|
67
65
|
end
|
68
66
|
|
69
|
-
|
70
|
-
def merged_excluded_file_pattern
|
71
|
-
# This regex looks for @excluded_patterns that follow the format of "something/**/*", where
|
72
|
-
# "something" is one or more non-"/"
|
73
|
-
#
|
74
|
-
# Returns "/path/to/workspace/{tmp,node_modules}/**/*"
|
75
|
-
@excluded_patterns
|
76
|
-
.filter_map do |pattern|
|
77
|
-
next if File.absolute_path?(pattern)
|
78
|
-
|
79
|
-
pattern.match(%r{\A([^/]+)/\*\*/\*\z})&.captures&.first
|
80
|
-
end
|
81
|
-
.then { |dirs| File.join(@workspace_path, "{#{dirs.join(",")}}/**/*") }
|
82
|
-
end
|
83
|
-
|
84
|
-
sig { returns(T::Array[URI::Generic]) }
|
67
|
+
#: -> Array[URI::Generic]
|
85
68
|
def indexable_uris
|
86
69
|
excluded_gems = @excluded_gems - @included_gems
|
87
70
|
locked_gems = Bundler.locked_gems&.specs
|
@@ -91,51 +74,19 @@ module RubyIndexer
|
|
91
74
|
|
92
75
|
flags = File::FNM_PATHNAME | File::FNM_EXTGLOB
|
93
76
|
|
94
|
-
|
95
|
-
# For example, if "tmp/**/*" is excluded, we don't need to traverse into "tmp" at all. However, if
|
96
|
-
# "vendor/bundle/**/*" is excluded, we will traverse all of "vendor" and `reject!` out all "vendor/bundle" entries
|
97
|
-
# later.
|
98
|
-
excluded_pattern = merged_excluded_file_pattern
|
99
|
-
included_paths = Dir.glob(File.join(@workspace_path, "*/"), flags)
|
100
|
-
.filter_map do |included_path|
|
101
|
-
next if File.fnmatch?(excluded_pattern, included_path, flags)
|
102
|
-
|
103
|
-
relative_path = included_path
|
104
|
-
.delete_prefix(@workspace_path)
|
105
|
-
.tap { |path| path.delete_prefix!("/") }
|
106
|
-
|
107
|
-
[included_path, relative_path]
|
108
|
-
end
|
109
|
-
|
110
|
-
uris = T.let([], T::Array[URI::Generic])
|
111
|
-
|
112
|
-
# Handle top level files separately. The path below is an optimization to prevent descending down directories that
|
113
|
-
# are going to be excluded anyway, so we need to handle top level scripts separately
|
114
|
-
Dir.glob(File.join(@workspace_path, "*.rb"), flags).each do |path|
|
115
|
-
uris << URI::Generic.from_path(path: path)
|
116
|
-
end
|
117
|
-
|
118
|
-
# Add user specified patterns
|
119
|
-
@included_patterns.each do |pattern|
|
77
|
+
uris = @included_patterns.flat_map do |pattern|
|
120
78
|
load_path_entry = T.let(nil, T.nilable(String))
|
121
79
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
# All entries for the same pattern match the same $LOAD_PATH entry. Since searching the $LOAD_PATH for every
|
130
|
-
# entry is expensive, we memoize it until we find a path that doesn't belong to that $LOAD_PATH. This
|
131
|
-
# happens on repositories that define multiple gems, like Rails. All frameworks are defined inside the
|
132
|
-
# current workspace directory, but each one of them belongs to a different $LOAD_PATH entry
|
133
|
-
if load_path_entry.nil? || !path.start_with?(load_path_entry)
|
134
|
-
load_path_entry = $LOAD_PATH.find { |load_path| path.start_with?(load_path) }
|
135
|
-
end
|
136
|
-
|
137
|
-
uris << URI::Generic.from_path(path: path, load_path_entry: load_path_entry)
|
80
|
+
Dir.glob(File.join(@workspace_path, pattern), flags).map! do |path|
|
81
|
+
# All entries for the same pattern match the same $LOAD_PATH entry. Since searching the $LOAD_PATH for every
|
82
|
+
# entry is expensive, we memoize it until we find a path that doesn't belong to that $LOAD_PATH. This happens
|
83
|
+
# on repositories that define multiple gems, like Rails. All frameworks are defined inside the current
|
84
|
+
# workspace directory, but each one of them belongs to a different $LOAD_PATH entry
|
85
|
+
if load_path_entry.nil? || !path.start_with?(load_path_entry)
|
86
|
+
load_path_entry = $LOAD_PATH.find { |load_path| path.start_with?(load_path) }
|
138
87
|
end
|
88
|
+
|
89
|
+
URI::Generic.from_path(path: path, load_path_entry: load_path_entry)
|
139
90
|
end
|
140
91
|
end
|
141
92
|
|
@@ -150,10 +101,12 @@ module RubyIndexer
|
|
150
101
|
end
|
151
102
|
|
152
103
|
# Remove user specified patterns
|
104
|
+
bundle_path = Bundler.settings["path"]&.gsub(/[\\]+/, "/")
|
153
105
|
uris.reject! do |indexable|
|
154
|
-
|
155
|
-
|
156
|
-
|
106
|
+
path = T.must(indexable.full_path)
|
107
|
+
next false if test_files_ignored_from_exclusion?(path, bundle_path)
|
108
|
+
|
109
|
+
excluded_patterns.any? { |pattern| File.fnmatch?(pattern, path, flags) }
|
157
110
|
end
|
158
111
|
|
159
112
|
# Add default gems to the list of files to be indexed
|
@@ -222,12 +175,12 @@ module RubyIndexer
|
|
222
175
|
uris
|
223
176
|
end
|
224
177
|
|
225
|
-
|
178
|
+
#: -> Regexp
|
226
179
|
def magic_comment_regex
|
227
180
|
@magic_comment_regex ||= T.let(/^#\s*#{@excluded_magic_comments.join("|")}/, T.nilable(Regexp))
|
228
181
|
end
|
229
182
|
|
230
|
-
|
183
|
+
#: (Hash[String, untyped] config) -> void
|
231
184
|
def apply_config(config)
|
232
185
|
validate_config!(config)
|
233
186
|
|
@@ -240,7 +193,7 @@ module RubyIndexer
|
|
240
193
|
|
241
194
|
private
|
242
195
|
|
243
|
-
|
196
|
+
#: (Hash[String, untyped] config) -> void
|
244
197
|
def validate_config!(config)
|
245
198
|
errors = config.filter_map do |key, value|
|
246
199
|
type = CONFIGURATION_SCHEMA[key]
|
@@ -255,7 +208,7 @@ module RubyIndexer
|
|
255
208
|
raise ArgumentError, errors.join("\n") if errors.any?
|
256
209
|
end
|
257
210
|
|
258
|
-
|
211
|
+
#: -> Array[String]
|
259
212
|
def initial_excluded_gems
|
260
213
|
excluded, others = Bundler.definition.dependencies.partition do |dependency|
|
261
214
|
dependency.groups == [:development]
|
@@ -305,5 +258,27 @@ module RubyIndexer
|
|
305
258
|
rescue Bundler::GemfileNotFound
|
306
259
|
[]
|
307
260
|
end
|
261
|
+
|
262
|
+
# Checks if the test file is never supposed to be ignored from indexing despite matching exclusion patterns, like
|
263
|
+
# `test_helper.rb` or `test_case.rb`. Also takes into consideration the possibility of finding these files under
|
264
|
+
# fixtures or inside gem source code if the bundle path points to a directory inside the workspace
|
265
|
+
#: (String path, String? bundle_path) -> bool
|
266
|
+
def test_files_ignored_from_exclusion?(path, bundle_path)
|
267
|
+
["test_case.rb", "test_helper.rb"].include?(File.basename(path)) &&
|
268
|
+
!File.fnmatch?("**/fixtures/**/*", path, File::FNM_PATHNAME | File::FNM_EXTGLOB) &&
|
269
|
+
(!bundle_path || !path.start_with?(bundle_path))
|
270
|
+
end
|
271
|
+
|
272
|
+
#: -> Array[String]
|
273
|
+
def top_level_directories
|
274
|
+
excluded_directories = ["tmp", "node_modules", "sorbet"]
|
275
|
+
|
276
|
+
Dir.glob("#{Dir.pwd}/*").filter_map do |path|
|
277
|
+
dir_name = File.basename(path)
|
278
|
+
next unless File.directory?(path) && !excluded_directories.include?(dir_name)
|
279
|
+
|
280
|
+
dir_name
|
281
|
+
end
|
282
|
+
end
|
308
283
|
end
|
309
284
|
end
|