ruby-lsp 0.23.11 → 0.23.13
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_language_server_aliases.rb +1 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +81 -115
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +117 -166
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +88 -200
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +56 -192
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +14 -16
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +42 -60
- 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 +42 -3
- data/lib/ruby_indexer/test/method_test.rb +28 -2
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
- data/lib/ruby_lsp/addon.rb +44 -71
- data/lib/ruby_lsp/base_server.rb +29 -32
- data/lib/ruby_lsp/client_capabilities.rb +10 -12
- data/lib/ruby_lsp/document.rb +34 -45
- data/lib/ruby_lsp/erb_document.rb +24 -36
- data/lib/ruby_lsp/global_state.rb +51 -56
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +81 -88
- data/lib/ruby_lsp/listeners/completion.rb +36 -55
- data/lib/ruby_lsp/listeners/definition.rb +37 -51
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +43 -62
- data/lib/ruby_lsp/listeners/document_symbol.rb +35 -49
- data/lib/ruby_lsp/listeners/folding_ranges.rb +32 -39
- data/lib/ruby_lsp/listeners/hover.rb +81 -100
- data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +42 -51
- data/lib/ruby_lsp/listeners/signature_help.rb +6 -25
- data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
- data/lib/ruby_lsp/listeners/test_style.rb +160 -88
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +8 -6
- data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +6 -17
- data/lib/ruby_lsp/requests/completion.rb +7 -20
- data/lib/ruby_lsp/requests/completion_resolve.rb +5 -5
- data/lib/ruby_lsp/requests/definition.rb +8 -17
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +18 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
- 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 +87 -0
- data/lib/ruby_lsp/requests/hover.rb +8 -18
- data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
- data/lib/ruby_lsp/requests/on_type_formatting.rb +28 -38
- data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +6 -36
- data/lib/ruby_lsp/requests/rename.rb +11 -37
- data/lib/ruby_lsp/requests/request.rb +7 -19
- data/lib/ruby_lsp/requests/selection_ranges.rb +5 -5
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +12 -31
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +5 -6
- data/lib/ruby_lsp/requests/signature_help.rb +8 -26
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +13 -50
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +9 -12
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
- 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 +16 -30
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +10 -14
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +5 -5
- data/lib/ruby_lsp/response_builders/document_symbol.rb +10 -16
- data/lib/ruby_lsp/response_builders/hover.rb +10 -13
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +59 -87
- data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
- data/lib/ruby_lsp/response_builders/test_collection.rb +6 -10
- data/lib/ruby_lsp/ruby_document.rb +22 -60
- data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +109 -0
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/server.rb +133 -74
- data/lib/ruby_lsp/setup_bundler.rb +58 -57
- data/lib/ruby_lsp/static_docs.rb +4 -7
- data/lib/ruby_lsp/store.rb +21 -40
- data/lib/ruby_lsp/test_helper.rb +3 -12
- data/lib/ruby_lsp/test_reporter.rb +207 -0
- data/lib/ruby_lsp/test_unit_test_runner.rb +98 -0
- data/lib/ruby_lsp/type_inferrer.rb +9 -13
- data/lib/ruby_lsp/utils.rb +37 -81
- metadata +9 -3
@@ -6,43 +6,29 @@ require "uri/file"
|
|
6
6
|
module URI
|
7
7
|
# Must be kept in sync with the one in Tapioca
|
8
8
|
class Source < URI::File
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
:path,
|
17
|
-
:line_number,
|
18
|
-
].freeze,
|
19
|
-
T::Array[Symbol],
|
20
|
-
)
|
9
|
+
COMPONENT = [
|
10
|
+
:scheme,
|
11
|
+
:gem_name,
|
12
|
+
:gem_version,
|
13
|
+
:path,
|
14
|
+
:line_number,
|
15
|
+
].freeze #: Array[Symbol]
|
21
16
|
|
22
17
|
# `uri` for Ruby 3.4 switched the default parser from RFC2396 to RFC3986. The new parser emits a deprecation
|
23
18
|
# warning on a few methods and delegates them to RFC2396, namely `extract`/`make_regexp`/`escape`/`unescape`.
|
24
19
|
# On earlier versions of the uri gem, the RFC2396_PARSER constant doesn't exist, so it needs some special
|
25
20
|
# handling to select a parser that doesn't emit deprecations. While it was backported to Ruby 3.1, users may
|
26
21
|
# have the uri gem in their own bundle and thus not use a compatible version.
|
27
|
-
PARSER =
|
22
|
+
PARSER = const_defined?(:RFC2396_PARSER) ? RFC2396_PARSER : DEFAULT_PARSER #: RFC2396_Parser
|
28
23
|
|
29
24
|
T.unsafe(self).alias_method(:gem_name, :host)
|
30
25
|
T.unsafe(self).alias_method(:line_number, :fragment)
|
31
26
|
|
32
|
-
|
27
|
+
#: String?
|
33
28
|
attr_reader :gem_version
|
34
29
|
|
35
30
|
class << self
|
36
|
-
|
37
|
-
|
38
|
-
sig do
|
39
|
-
params(
|
40
|
-
gem_name: String,
|
41
|
-
gem_version: T.nilable(String),
|
42
|
-
path: String,
|
43
|
-
line_number: T.nilable(String),
|
44
|
-
).returns(URI::Source)
|
45
|
-
end
|
31
|
+
#: (gem_name: String, gem_version: String?, path: String, line_number: String?) -> URI::Source
|
46
32
|
def build(gem_name:, gem_version:, path:, line_number:)
|
47
33
|
super(
|
48
34
|
{
|
@@ -55,17 +41,17 @@ module URI
|
|
55
41
|
end
|
56
42
|
end
|
57
43
|
|
58
|
-
|
44
|
+
#: (String? v) -> void
|
59
45
|
def set_path(v) # rubocop:disable Naming/AccessorMethodName
|
60
46
|
return if v.nil?
|
61
47
|
|
62
48
|
gem_version, path = v.delete_prefix("/").split("/", 2)
|
63
49
|
|
64
|
-
@gem_version =
|
65
|
-
@path =
|
50
|
+
@gem_version = gem_version #: String?
|
51
|
+
@path = path #: String?
|
66
52
|
end
|
67
53
|
|
68
|
-
|
54
|
+
#: (String? v) -> bool
|
69
55
|
def check_host(v)
|
70
56
|
return true unless v
|
71
57
|
|
@@ -77,7 +63,7 @@ module URI
|
|
77
63
|
true
|
78
64
|
end
|
79
65
|
|
80
|
-
|
66
|
+
#: -> String
|
81
67
|
def to_s
|
82
68
|
"source://#{gem_name}/#{gem_version}#{path}##{line_number}"
|
83
69
|
end
|
@@ -85,7 +71,7 @@ module URI
|
|
85
71
|
if URI.respond_to?(:register_scheme)
|
86
72
|
URI.register_scheme("SOURCE", self)
|
87
73
|
else
|
88
|
-
@@schemes =
|
74
|
+
@@schemes = @@schemes # rubocop:disable Style/ClassVars #: Hash[String, untyped]
|
89
75
|
@@schemes["SOURCE"] = self
|
90
76
|
end
|
91
77
|
end
|
@@ -13,23 +13,19 @@ module RubyLsp
|
|
13
13
|
module Support
|
14
14
|
# :nodoc:
|
15
15
|
class SyntaxTreeFormatter
|
16
|
-
extend T::Sig
|
17
16
|
include Support::Formatter
|
18
17
|
|
19
|
-
|
18
|
+
#: -> void
|
20
19
|
def initialize
|
21
|
-
@options =
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
opts
|
27
|
-
end,
|
28
|
-
SyntaxTree::CLI::Options,
|
29
|
-
)
|
20
|
+
@options = begin
|
21
|
+
opts = SyntaxTree::CLI::Options.new
|
22
|
+
opts.parse(SyntaxTree::CLI::ConfigFile.new.arguments)
|
23
|
+
opts
|
24
|
+
end #: SyntaxTree::CLI::Options
|
30
25
|
end
|
31
26
|
|
32
|
-
|
27
|
+
# @override
|
28
|
+
#: (URI::Generic uri, RubyDocument document) -> String?
|
33
29
|
def run_formatting(uri, document)
|
34
30
|
path = uri.to_standardized_path
|
35
31
|
return if path && @options.ignore_files.any? { |pattern| File.fnmatch?("*/#{pattern}", path) }
|
@@ -37,7 +33,8 @@ module RubyLsp
|
|
37
33
|
SyntaxTree.format(document.source, @options.print_width, options: @options.formatter_options)
|
38
34
|
end
|
39
35
|
|
40
|
-
|
36
|
+
# @override
|
37
|
+
#: (URI::Generic uri, String source, Integer base_indentation) -> String?
|
41
38
|
def run_range_formatting(uri, source, base_indentation)
|
42
39
|
path = uri.to_standardized_path
|
43
40
|
return if path && @options.ignore_files.any? { |pattern| File.fnmatch?("*/#{pattern}", path) }
|
@@ -45,12 +42,8 @@ module RubyLsp
|
|
45
42
|
SyntaxTree.format(source, @options.print_width, base_indentation, options: @options.formatter_options)
|
46
43
|
end
|
47
44
|
|
48
|
-
|
49
|
-
|
50
|
-
uri: URI::Generic,
|
51
|
-
document: RubyDocument,
|
52
|
-
).returns(T.nilable(T::Array[Interface::Diagnostic]))
|
53
|
-
end
|
45
|
+
# @override
|
46
|
+
#: (URI::Generic uri, RubyDocument document) -> Array[Interface::Diagnostic]?
|
54
47
|
def run_diagnostic(uri, document)
|
55
48
|
nil
|
56
49
|
end
|
@@ -10,46 +10,42 @@ module RubyLsp
|
|
10
10
|
# Note: this test item object can only represent test groups or examples discovered inside files. It cannot be
|
11
11
|
# used to represent test files, directories or workspaces
|
12
12
|
class TestItem
|
13
|
-
|
14
|
-
|
15
|
-
sig { returns(String) }
|
13
|
+
#: String
|
16
14
|
attr_reader :id, :label
|
17
15
|
|
18
|
-
|
19
|
-
def initialize(id, label, uri, range)
|
16
|
+
#: (String id, String label, URI::Generic uri, Interface::Range range, Symbol framework) -> void
|
17
|
+
def initialize(id, label, uri, range, framework:)
|
20
18
|
@id = id
|
21
19
|
@label = label
|
22
20
|
@uri = uri
|
23
21
|
@range = range
|
24
|
-
@
|
22
|
+
@tags = ["framework:#{framework}"] #: Array[String]
|
23
|
+
@children = {} #: Hash[String, TestItem]
|
25
24
|
end
|
26
25
|
|
27
|
-
|
26
|
+
#: (TestItem item) -> void
|
28
27
|
def add(item)
|
29
|
-
if @children.key?(item.id)
|
30
|
-
raise ResponseBuilders::TestCollection::DuplicateIdError, "TestItem ID is already in use"
|
31
|
-
end
|
32
|
-
|
33
28
|
@children[item.id] = item
|
34
29
|
end
|
35
30
|
|
36
|
-
|
31
|
+
#: (String id) -> TestItem?
|
37
32
|
def [](id)
|
38
33
|
@children[id]
|
39
34
|
end
|
40
35
|
|
41
|
-
|
36
|
+
#: -> Array[TestItem]
|
42
37
|
def children
|
43
38
|
@children.values
|
44
39
|
end
|
45
40
|
|
46
|
-
|
41
|
+
#: -> Hash[Symbol, untyped]
|
47
42
|
def to_hash
|
48
43
|
{
|
49
44
|
id: @id,
|
50
45
|
label: @label,
|
51
46
|
uri: @uri,
|
52
47
|
range: @range,
|
48
|
+
tags: @tags,
|
53
49
|
children: children.map(&:to_hash),
|
54
50
|
}
|
55
51
|
end
|
@@ -7,11 +7,9 @@ module RubyLsp
|
|
7
7
|
# request](https://microsoft.github.io/language-server-protocol/specification#typeHierarchy_supertypes)
|
8
8
|
# displays the list of ancestors (supertypes) for the selected type.
|
9
9
|
class TypeHierarchySupertypes < Request
|
10
|
-
extend T::Sig
|
11
|
-
|
12
10
|
include Support::Common
|
13
11
|
|
14
|
-
|
12
|
+
#: (RubyIndexer::Index index, Hash[Symbol, untyped] item) -> void
|
15
13
|
def initialize(index, item)
|
16
14
|
super()
|
17
15
|
|
@@ -19,12 +17,13 @@ module RubyLsp
|
|
19
17
|
@item = item
|
20
18
|
end
|
21
19
|
|
22
|
-
|
20
|
+
# @override
|
21
|
+
#: -> Array[Interface::TypeHierarchyItem]?
|
23
22
|
def perform
|
24
23
|
name = @item[:name]
|
25
24
|
entries = @index[name]
|
26
25
|
|
27
|
-
parents =
|
26
|
+
parents = Set.new #: Set[RubyIndexer::Entry::Namespace]
|
28
27
|
return unless entries&.any?
|
29
28
|
|
30
29
|
entries.each do |entry|
|
@@ -60,7 +59,7 @@ module RubyLsp
|
|
60
59
|
|
61
60
|
private
|
62
61
|
|
63
|
-
|
62
|
+
#: (RubyIndexer::Entry entry) -> Interface::TypeHierarchyItem
|
64
63
|
def hierarchy_item(entry)
|
65
64
|
Interface::TypeHierarchyItem.new(
|
66
65
|
name: entry.name,
|
@@ -7,18 +7,18 @@ module RubyLsp
|
|
7
7
|
# request allows fuzzy searching declarations in the entire project. On VS Code, use CTRL/CMD + T to search for
|
8
8
|
# symbols.
|
9
9
|
class WorkspaceSymbol < Request
|
10
|
-
extend T::Sig
|
11
10
|
include Support::Common
|
12
11
|
|
13
|
-
|
12
|
+
#: (GlobalState global_state, String? query) -> void
|
14
13
|
def initialize(global_state, query)
|
15
14
|
super()
|
16
15
|
@global_state = global_state
|
17
16
|
@query = query
|
18
|
-
@index =
|
17
|
+
@index = global_state.index #: RubyIndexer::Index
|
19
18
|
end
|
20
19
|
|
21
|
-
|
20
|
+
# @override
|
21
|
+
#: -> Array[Interface::WorkspaceSymbol]
|
22
22
|
def perform
|
23
23
|
@index.fuzzy_search(@query).filter_map do |entry|
|
24
24
|
uri = entry.uri
|
@@ -4,23 +4,23 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
6
|
class CollectionResponseBuilder < ResponseBuilder
|
7
|
-
extend T::Sig
|
8
7
|
extend T::Generic
|
9
8
|
|
10
9
|
ResponseType = type_member { { upper: Object } }
|
11
10
|
|
12
|
-
|
11
|
+
#: -> void
|
13
12
|
def initialize
|
14
13
|
super
|
15
|
-
@items =
|
14
|
+
@items = [] #: Array[ResponseType]
|
16
15
|
end
|
17
16
|
|
18
|
-
|
17
|
+
#: (ResponseType item) -> void
|
19
18
|
def <<(item)
|
20
19
|
@items << item
|
21
20
|
end
|
22
21
|
|
23
|
-
|
22
|
+
# @override
|
23
|
+
#: -> Array[ResponseType]
|
24
24
|
def response
|
25
25
|
@items
|
26
26
|
end
|
@@ -4,51 +4,45 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
6
|
class DocumentSymbol < ResponseBuilder
|
7
|
-
extend T::Sig
|
8
|
-
|
9
7
|
ResponseType = type_member { { fixed: T::Array[Interface::DocumentSymbol] } }
|
10
8
|
|
11
9
|
class SymbolHierarchyRoot
|
12
|
-
|
13
|
-
|
14
|
-
sig { returns(T::Array[Interface::DocumentSymbol]) }
|
10
|
+
#: Array[Interface::DocumentSymbol]
|
15
11
|
attr_reader :children
|
16
12
|
|
17
|
-
|
13
|
+
#: -> void
|
18
14
|
def initialize
|
19
|
-
@children =
|
15
|
+
@children = [] #: Array[Interface::DocumentSymbol]
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
23
|
-
|
19
|
+
#: -> void
|
24
20
|
def initialize
|
25
21
|
super
|
26
|
-
@stack =
|
27
|
-
[SymbolHierarchyRoot.new],
|
28
|
-
T::Array[T.any(SymbolHierarchyRoot, Interface::DocumentSymbol)],
|
29
|
-
)
|
22
|
+
@stack = [SymbolHierarchyRoot.new] #: Array[(SymbolHierarchyRoot | Interface::DocumentSymbol)]
|
30
23
|
end
|
31
24
|
|
32
|
-
|
25
|
+
#: (Interface::DocumentSymbol symbol) -> void
|
33
26
|
def push(symbol)
|
34
27
|
@stack << symbol
|
35
28
|
end
|
36
29
|
|
37
30
|
alias_method(:<<, :push)
|
38
31
|
|
39
|
-
|
32
|
+
#: -> Interface::DocumentSymbol?
|
40
33
|
def pop
|
41
34
|
if @stack.size > 1
|
42
35
|
T.cast(@stack.pop, Interface::DocumentSymbol)
|
43
36
|
end
|
44
37
|
end
|
45
38
|
|
46
|
-
|
39
|
+
#: -> (SymbolHierarchyRoot | Interface::DocumentSymbol)
|
47
40
|
def last
|
48
41
|
T.must(@stack.last)
|
49
42
|
end
|
50
43
|
|
51
|
-
|
44
|
+
# @override
|
45
|
+
#: -> Array[Interface::DocumentSymbol]
|
52
46
|
def response
|
53
47
|
T.must(@stack.first).children
|
54
48
|
end
|
@@ -4,26 +4,22 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
6
|
class Hover < ResponseBuilder
|
7
|
-
extend T::Sig
|
8
7
|
extend T::Generic
|
9
8
|
|
10
9
|
ResponseType = type_member { { fixed: String } }
|
11
10
|
|
12
|
-
|
11
|
+
#: -> void
|
13
12
|
def initialize
|
14
13
|
super
|
15
14
|
|
16
|
-
@response =
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
},
|
22
|
-
T::Hash[Symbol, String],
|
23
|
-
)
|
15
|
+
@response = {
|
16
|
+
title: +"",
|
17
|
+
links: +"",
|
18
|
+
documentation: +"",
|
19
|
+
} #: Hash[Symbol, String]
|
24
20
|
end
|
25
21
|
|
26
|
-
|
22
|
+
#: (String content, category: Symbol) -> void
|
27
23
|
def push(content, category:)
|
28
24
|
hover_content = @response[category]
|
29
25
|
if hover_content
|
@@ -31,12 +27,13 @@ module RubyLsp
|
|
31
27
|
end
|
32
28
|
end
|
33
29
|
|
34
|
-
|
30
|
+
#: -> bool
|
35
31
|
def empty?
|
36
32
|
@response.values.all?(&:empty?)
|
37
33
|
end
|
38
34
|
|
39
|
-
|
35
|
+
# @override
|
36
|
+
#: -> ResponseType
|
40
37
|
def response
|
41
38
|
result = T.must(@response[:title])
|
42
39
|
result << "\n" << @response[:links] if @response[:links]
|
@@ -6,68 +6,55 @@ module RubyLsp
|
|
6
6
|
class SemanticHighlighting < ResponseBuilder
|
7
7
|
class UndefinedTokenType < StandardError; end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
abstract: 5,
|
48
|
-
async: 6,
|
49
|
-
modification: 7,
|
50
|
-
documentation: 8,
|
51
|
-
default_library: 9,
|
52
|
-
}.freeze,
|
53
|
-
T::Hash[Symbol, Integer],
|
54
|
-
)
|
9
|
+
TOKEN_TYPES = {
|
10
|
+
namespace: 0,
|
11
|
+
type: 1,
|
12
|
+
class: 2,
|
13
|
+
enum: 3,
|
14
|
+
interface: 4,
|
15
|
+
struct: 5,
|
16
|
+
typeParameter: 6,
|
17
|
+
parameter: 7,
|
18
|
+
variable: 8,
|
19
|
+
property: 9,
|
20
|
+
enumMember: 10,
|
21
|
+
event: 11,
|
22
|
+
function: 12,
|
23
|
+
method: 13,
|
24
|
+
macro: 14,
|
25
|
+
keyword: 15,
|
26
|
+
modifier: 16,
|
27
|
+
comment: 17,
|
28
|
+
string: 18,
|
29
|
+
number: 19,
|
30
|
+
regexp: 20,
|
31
|
+
operator: 21,
|
32
|
+
decorator: 22,
|
33
|
+
}.freeze #: Hash[Symbol, Integer]
|
34
|
+
|
35
|
+
TOKEN_MODIFIERS = {
|
36
|
+
declaration: 0,
|
37
|
+
definition: 1,
|
38
|
+
readonly: 2,
|
39
|
+
static: 3,
|
40
|
+
deprecated: 4,
|
41
|
+
abstract: 5,
|
42
|
+
async: 6,
|
43
|
+
modification: 7,
|
44
|
+
documentation: 8,
|
45
|
+
default_library: 9,
|
46
|
+
}.freeze #: Hash[Symbol, Integer]
|
55
47
|
|
56
48
|
ResponseType = type_member { { fixed: Interface::SemanticTokens } }
|
57
49
|
|
58
|
-
|
59
|
-
params(code_units_cache: T.any(
|
60
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
61
|
-
Prism::CodeUnitsCache,
|
62
|
-
)).void
|
63
|
-
end
|
50
|
+
#: ((^(Integer arg0) -> Integer | Prism::CodeUnitsCache) code_units_cache) -> void
|
64
51
|
def initialize(code_units_cache)
|
65
52
|
super()
|
66
53
|
@code_units_cache = code_units_cache
|
67
|
-
@stack =
|
54
|
+
@stack = [] #: Array[SemanticToken]
|
68
55
|
end
|
69
56
|
|
70
|
-
|
57
|
+
#: (Prism::Location location, Symbol type, ?Array[Symbol] modifiers) -> void
|
71
58
|
def add_token(location, type, modifiers = [])
|
72
59
|
end_code_unit = location.cached_end_code_units_offset(@code_units_cache)
|
73
60
|
length = end_code_unit - location.cached_start_code_units_offset(@code_units_cache)
|
@@ -83,7 +70,7 @@ module RubyLsp
|
|
83
70
|
)
|
84
71
|
end
|
85
72
|
|
86
|
-
|
73
|
+
#: (Prism::Location location) -> bool
|
87
74
|
def last_token_matches?(location)
|
88
75
|
token = @stack.last
|
89
76
|
return false unless token
|
@@ -92,43 +79,34 @@ module RubyLsp
|
|
92
79
|
token.start_code_unit_column == location.cached_start_code_units_column(@code_units_cache)
|
93
80
|
end
|
94
81
|
|
95
|
-
|
82
|
+
#: -> SemanticToken?
|
96
83
|
def last
|
97
84
|
@stack.last
|
98
85
|
end
|
99
86
|
|
100
|
-
|
87
|
+
# @override
|
88
|
+
#: -> Array[SemanticToken]
|
101
89
|
def response
|
102
90
|
@stack
|
103
91
|
end
|
104
92
|
|
105
93
|
class SemanticToken
|
106
|
-
|
107
|
-
|
108
|
-
sig { returns(Integer) }
|
94
|
+
#: Integer
|
109
95
|
attr_reader :start_line
|
110
96
|
|
111
|
-
|
97
|
+
#: Integer
|
112
98
|
attr_reader :start_code_unit_column
|
113
99
|
|
114
|
-
|
100
|
+
#: Integer
|
115
101
|
attr_reader :length
|
116
102
|
|
117
|
-
|
103
|
+
#: Integer
|
118
104
|
attr_reader :type
|
119
105
|
|
120
|
-
|
106
|
+
#: Array[Integer]
|
121
107
|
attr_reader :modifier
|
122
108
|
|
123
|
-
|
124
|
-
params(
|
125
|
-
start_line: Integer,
|
126
|
-
start_code_unit_column: Integer,
|
127
|
-
length: Integer,
|
128
|
-
type: Integer,
|
129
|
-
modifier: T::Array[Integer],
|
130
|
-
).void
|
131
|
-
end
|
109
|
+
#: (start_line: Integer, start_code_unit_column: Integer, length: Integer, type: Integer, modifier: Array[Integer]) -> void
|
132
110
|
def initialize(start_line:, start_code_unit_column:, length:, type:, modifier:)
|
133
111
|
@start_line = start_line
|
134
112
|
@start_code_unit_column = start_code_unit_column
|
@@ -137,7 +115,7 @@ module RubyLsp
|
|
137
115
|
@modifier = modifier
|
138
116
|
end
|
139
117
|
|
140
|
-
|
118
|
+
#: (Symbol type_symbol) -> void
|
141
119
|
def replace_type(type_symbol)
|
142
120
|
type_int = TOKEN_TYPES[type_symbol]
|
143
121
|
raise UndefinedTokenType, "Undefined token type: #{type_symbol}" unless type_int
|
@@ -145,7 +123,7 @@ module RubyLsp
|
|
145
123
|
@type = type_int
|
146
124
|
end
|
147
125
|
|
148
|
-
|
126
|
+
#: (Array[Symbol] modifier_symbols) -> void
|
149
127
|
def replace_modifier(modifier_symbols)
|
150
128
|
@modifier = modifier_symbols.filter_map do |modifier_symbol|
|
151
129
|
modifier_index = TOKEN_MODIFIERS[modifier_symbol]
|
@@ -157,19 +135,13 @@ module RubyLsp
|
|
157
135
|
end
|
158
136
|
|
159
137
|
class SemanticTokenEncoder
|
160
|
-
|
161
|
-
|
162
|
-
sig { void }
|
138
|
+
#: -> void
|
163
139
|
def initialize
|
164
|
-
@current_row =
|
165
|
-
@current_column =
|
140
|
+
@current_row = 0 #: Integer
|
141
|
+
@current_column = 0 #: Integer
|
166
142
|
end
|
167
143
|
|
168
|
-
|
169
|
-
params(
|
170
|
-
tokens: T::Array[SemanticToken],
|
171
|
-
).returns(T::Array[Integer])
|
172
|
-
end
|
144
|
+
#: (Array[SemanticToken] tokens) -> Array[Integer]
|
173
145
|
def encode(tokens)
|
174
146
|
sorted_tokens = tokens.sort_by.with_index do |token, index|
|
175
147
|
# Enumerable#sort_by is not deterministic when the compared values are equal.
|
@@ -194,7 +166,7 @@ module RubyLsp
|
|
194
166
|
|
195
167
|
# For more information on how each number is calculated, read:
|
196
168
|
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens
|
197
|
-
|
169
|
+
#: (SemanticToken token) -> Array[Integer]
|
198
170
|
def compute_delta(token)
|
199
171
|
row = token.start_line - 1
|
200
172
|
column = token.start_code_unit_column
|
@@ -216,7 +188,7 @@ module RubyLsp
|
|
216
188
|
# For example, [:default_library] will be encoded as
|
217
189
|
# 0b1000000000, as :default_library is the 10th bit according
|
218
190
|
# to the token modifiers index map.
|
219
|
-
|
191
|
+
#: (Array[Integer] modifiers) -> Integer
|
220
192
|
def encode_modifiers(modifiers)
|
221
193
|
modifiers.inject(0) do |encoded_modifiers, modifier|
|
222
194
|
encoded_modifiers | (1 << modifier)
|