ruby-lsp 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
@@ -13,7 +13,9 @@ module RubyLsp
13
13
  # end # <-- folding range end
14
14
  # ```
15
15
  class FoldingRanges < BaseRequest
16
- SIMPLE_FOLDABLES = [
16
+ extend T::Sig
17
+
18
+ SIMPLE_FOLDABLES = T.let([
17
19
  SyntaxTree::ArrayLiteral,
18
20
  SyntaxTree::BraceBlock,
19
21
  SyntaxTree::Case,
@@ -30,24 +32,37 @@ module RubyLsp
30
32
  SyntaxTree::Unless,
31
33
  SyntaxTree::Until,
32
34
  SyntaxTree::While,
33
- ].freeze
35
+ ].freeze, T::Array[T.class_of(SyntaxTree::Node)])
34
36
 
35
- NODES_WITH_STATEMENTS = [
37
+ NODES_WITH_STATEMENTS = T.let([
36
38
  SyntaxTree::Else,
37
39
  SyntaxTree::Elsif,
38
40
  SyntaxTree::Ensure,
39
41
  SyntaxTree::In,
40
42
  SyntaxTree::Rescue,
41
43
  SyntaxTree::When,
42
- ].freeze
44
+ ].freeze, T::Array[T.class_of(SyntaxTree::Node)])
45
+
46
+ StatementNode = T.type_alias do
47
+ T.any(
48
+ SyntaxTree::Else,
49
+ SyntaxTree::Elsif,
50
+ SyntaxTree::Ensure,
51
+ SyntaxTree::In,
52
+ SyntaxTree::Rescue,
53
+ SyntaxTree::When,
54
+ )
55
+ end
43
56
 
57
+ sig { params(document: Document).void }
44
58
  def initialize(document)
45
59
  super
46
60
 
47
- @ranges = []
48
- @partial_range = nil
61
+ @ranges = T.let([], T::Array[LanguageServer::Protocol::Interface::FoldingRange])
62
+ @partial_range = T.let(nil, T.nilable(PartialRange))
49
63
  end
50
64
 
65
+ sig { override.returns(T.all(T::Array[LanguageServer::Protocol::Interface::FoldingRange], Object)) }
51
66
  def run
52
67
  visit(@document.tree)
53
68
  emit_partial_range
@@ -56,14 +71,15 @@ module RubyLsp
56
71
 
57
72
  private
58
73
 
74
+ sig { params(node: T.nilable(SyntaxTree::Node)).void }
59
75
  def visit(node)
60
76
  return unless handle_partial_range(node)
61
77
 
62
78
  case node
63
79
  when *SIMPLE_FOLDABLES
64
- add_node_range(node)
80
+ add_node_range(T.must(node))
65
81
  when *NODES_WITH_STATEMENTS
66
- add_statements_range(node, node.statements)
82
+ add_statements_range(T.must(node), T.cast(node, StatementNode).statements)
67
83
  when SyntaxTree::Begin
68
84
  add_statements_range(node, node.bodystmt.statements)
69
85
  when SyntaxTree::Call, SyntaxTree::CommandCall
@@ -80,27 +96,38 @@ module RubyLsp
80
96
  end
81
97
 
82
98
  class PartialRange
83
- attr_reader :kind, :end_line
99
+ extend T::Sig
84
100
 
101
+ sig { returns(String) }
102
+ attr_reader :kind
103
+
104
+ sig { returns(Integer) }
105
+ attr_reader :end_line
106
+
107
+ sig { params(node: SyntaxTree::Node, kind: String).returns(PartialRange) }
85
108
  def self.from(node, kind)
86
109
  new(node.location.start_line - 1, node.location.end_line - 1, kind)
87
110
  end
88
111
 
112
+ sig { params(start_line: Integer, end_line: Integer, kind: String).void }
89
113
  def initialize(start_line, end_line, kind)
90
114
  @start_line = start_line
91
115
  @end_line = end_line
92
116
  @kind = kind
93
117
  end
94
118
 
119
+ sig { params(node: SyntaxTree::Node).returns(PartialRange) }
95
120
  def extend_to(node)
96
121
  @end_line = node.location.end_line - 1
97
122
  self
98
123
  end
99
124
 
125
+ sig { params(node: SyntaxTree::Node).returns(T::Boolean) }
100
126
  def new_section?(node)
101
127
  node.is_a?(SyntaxTree::Comment) && @end_line + 1 != node.location.start_line - 1
102
128
  end
103
129
 
130
+ sig { returns(LanguageServer::Protocol::Interface::FoldingRange) }
104
131
  def to_range
105
132
  LanguageServer::Protocol::Interface::FoldingRange.new(
106
133
  start_line: @start_line,
@@ -110,6 +137,7 @@ module RubyLsp
110
137
  end
111
138
  end
112
139
 
140
+ sig { params(node: T.nilable(SyntaxTree::Node)).returns(T::Boolean) }
113
141
  def handle_partial_range(node)
114
142
  kind = partial_range_kind(node)
115
143
 
@@ -118,18 +146,20 @@ module RubyLsp
118
146
  return true
119
147
  end
120
148
 
149
+ target_node = T.must(node)
121
150
  @partial_range = if @partial_range.nil?
122
- PartialRange.from(node, kind)
123
- elsif @partial_range.kind != kind || @partial_range.new_section?(node)
151
+ PartialRange.from(target_node, kind)
152
+ elsif @partial_range.kind != kind || @partial_range.new_section?(target_node)
124
153
  emit_partial_range
125
- PartialRange.from(node, kind)
154
+ PartialRange.from(target_node, kind)
126
155
  else
127
- @partial_range.extend_to(node)
156
+ @partial_range.extend_to(target_node)
128
157
  end
129
158
 
130
159
  false
131
160
  end
132
161
 
162
+ sig { params(node: T.nilable(SyntaxTree::Node)).returns(T.nilable(String)) }
133
163
  def partial_range_kind(node)
134
164
  case node
135
165
  when SyntaxTree::Comment
@@ -141,6 +171,7 @@ module RubyLsp
141
171
  end
142
172
  end
143
173
 
174
+ sig { void }
144
175
  def emit_partial_range
145
176
  return if @partial_range.nil?
146
177
 
@@ -148,6 +179,7 @@ module RubyLsp
148
179
  @partial_range = nil
149
180
  end
150
181
 
182
+ sig { params(node: T.any(SyntaxTree::Call, SyntaxTree::CommandCall)).void }
151
183
  def add_call_range(node)
152
184
  receiver = T.let(node.receiver, SyntaxTree::Node)
153
185
  loop do
@@ -168,6 +200,7 @@ module RubyLsp
168
200
  visit(node.arguments)
169
201
  end
170
202
 
203
+ sig { params(node: T.any(SyntaxTree::Def, SyntaxTree::Defs)).void }
171
204
  def add_def_range(node)
172
205
  params_location = node.params.location
173
206
 
@@ -180,10 +213,12 @@ module RubyLsp
180
213
  visit(node.bodystmt.statements)
181
214
  end
182
215
 
216
+ sig { params(node: SyntaxTree::Node, statements: SyntaxTree::Statements).void }
183
217
  def add_statements_range(node, statements)
184
218
  add_lines_range(node.location.start_line, statements.location.end_line) unless statements.empty?
185
219
  end
186
220
 
221
+ sig { params(node: SyntaxTree::StringConcat).void }
187
222
  def add_string_concat(node)
188
223
  left = T.let(node.left, SyntaxTree::Node)
189
224
  left = left.left while left.is_a?(SyntaxTree::StringConcat)
@@ -191,14 +226,13 @@ module RubyLsp
191
226
  add_lines_range(left.location.start_line, node.right.location.end_line)
192
227
  end
193
228
 
229
+ sig { params(node: SyntaxTree::Node).void }
194
230
  def add_node_range(node)
195
- add_location_range(node.location)
196
- end
197
-
198
- def add_location_range(location)
231
+ location = node.location
199
232
  add_lines_range(location.start_line, location.end_line)
200
233
  end
201
234
 
235
+ sig { params(start_line: Integer, end_line: Integer).void }
202
236
  def add_lines_range(start_line, end_line)
203
237
  return if start_line >= end_line
204
238
 
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
@@ -15,13 +15,17 @@ module RubyLsp
15
15
  # end
16
16
  # ```
17
17
  class Formatting < RuboCopRequest
18
- RUBOCOP_FLAGS = (COMMON_RUBOCOP_FLAGS + ["--autocorrect"]).freeze
18
+ extend T::Sig
19
19
 
20
+ RUBOCOP_FLAGS = T.let((COMMON_RUBOCOP_FLAGS + ["--auto-correct"]).freeze, T::Array[String])
21
+
22
+ sig { params(uri: String, document: Document).void }
20
23
  def initialize(uri, document)
21
24
  super
22
- @formatted_text = nil
25
+ @formatted_text = T.let(nil, T.nilable(String))
23
26
  end
24
27
 
28
+ sig { override.returns(T.nilable(T.all(T::Array[LanguageServer::Protocol::Interface::TextEdit], Object))) }
25
29
  def run
26
30
  super
27
31
 
@@ -44,6 +48,7 @@ module RubyLsp
44
48
 
45
49
  private
46
50
 
51
+ sig { returns(T::Array[String]) }
47
52
  def rubocop_flags
48
53
  RUBOCOP_FLAGS
49
54
  end
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "rubocop"
@@ -8,23 +8,31 @@ module RubyLsp
8
8
  module Requests
9
9
  # :nodoc:
10
10
  class RuboCopRequest < RuboCop::Runner
11
- COMMON_RUBOCOP_FLAGS = [
11
+ extend T::Sig
12
+ extend T::Helpers
13
+
14
+ abstract!
15
+
16
+ COMMON_RUBOCOP_FLAGS = T.let([
12
17
  "--stderr", # Print any output to stderr so that our stdout does not get polluted
13
18
  "--format",
14
19
  "RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
15
- ].freeze
20
+ ].freeze, T::Array[String])
16
21
 
17
- attr_reader :file, :text
22
+ sig { returns(String) }
23
+ attr_reader :file
18
24
 
19
- def self.run(uri, document)
20
- new(uri, document).run
21
- end
25
+ sig { returns(String) }
26
+ attr_reader :text
22
27
 
28
+ sig { params(uri: String, document: Document).void }
23
29
  def initialize(uri, document)
24
- @file = CGI.unescape(URI.parse(uri).path)
30
+ @file = T.let(CGI.unescape(URI.parse(uri).path), String)
25
31
  @document = document
26
- @text = document.source
32
+ @text = T.let(document.source, String)
27
33
  @uri = uri
34
+ @options = T.let({}, T::Hash[Symbol, T.untyped])
35
+ @diagnostics = T.let([], T::Array[Support::RuboCopDiagnostic])
28
36
 
29
37
  super(
30
38
  ::RuboCop::Options.new.parse(rubocop_flags).first,
@@ -32,6 +40,7 @@ module RubyLsp
32
40
  )
33
41
  end
34
42
 
43
+ sig { overridable.returns(Object) }
35
44
  def run
36
45
  # We communicate with Rubocop via stdin
37
46
  @options[:stdin] = text
@@ -42,6 +51,7 @@ module RubyLsp
42
51
 
43
52
  private
44
53
 
54
+ sig { returns(T::Array[String]) }
45
55
  def rubocop_flags
46
56
  COMMON_RUBOCOP_FLAGS
47
57
  end
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
@@ -17,7 +17,9 @@ module RubyLsp
17
17
  # end
18
18
  # ```
19
19
  class SelectionRanges < BaseRequest
20
- NODES_THAT_CAN_BE_PARENTS = [
20
+ extend T::Sig
21
+
22
+ NODES_THAT_CAN_BE_PARENTS = T.let([
21
23
  SyntaxTree::Assign,
22
24
  SyntaxTree::ArrayLiteral,
23
25
  SyntaxTree::Begin,
@@ -54,15 +56,17 @@ module RubyLsp
54
56
  SyntaxTree::VCall,
55
57
  SyntaxTree::When,
56
58
  SyntaxTree::While,
57
- ].freeze
59
+ ].freeze, T::Array[T.class_of(SyntaxTree::Node)])
58
60
 
61
+ sig { params(document: Document).void }
59
62
  def initialize(document)
60
63
  super(document)
61
64
 
62
- @ranges = []
63
- @stack = []
65
+ @ranges = T.let([], T::Array[Support::SelectionRange])
66
+ @stack = T.let([], T::Array[Support::SelectionRange])
64
67
  end
65
68
 
69
+ sig { override.returns(T.all(T::Array[Support::SelectionRange], Object)) }
66
70
  def run
67
71
  visit(@document.tree)
68
72
  @ranges.reverse!
@@ -70,6 +74,7 @@ module RubyLsp
70
74
 
71
75
  private
72
76
 
77
+ sig { params(node: T.nilable(SyntaxTree::Node)).void }
73
78
  def visit(node)
74
79
  return if node.nil?
75
80
 
@@ -83,6 +88,12 @@ module RubyLsp
83
88
  @stack.pop if NODES_THAT_CAN_BE_PARENTS.include?(node.class)
84
89
  end
85
90
 
91
+ sig do
92
+ params(
93
+ location: SyntaxTree::Location,
94
+ parent: T.nilable(Support::SelectionRange)
95
+ ).returns(Support::SelectionRange)
96
+ end
86
97
  def create_selection_range(location, parent = nil)
87
98
  RubyLsp::Requests::Support::SelectionRange.new(
88
99
  range: LanguageServer::Protocol::Interface::Range.new(
@@ -1,4 +1,4 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
@@ -17,12 +17,15 @@ module RubyLsp
17
17
  # end
18
18
  # ```
19
19
  class SemanticHighlighting < BaseRequest
20
- TOKEN_TYPES = [
20
+ extend T::Sig
21
+
22
+ TOKEN_TYPES = T.let([
21
23
  :variable,
22
24
  :method,
23
- ].freeze
25
+ :namespace,
26
+ ].freeze, T::Array[Symbol])
24
27
 
25
- TOKEN_MODIFIERS = {
28
+ TOKEN_MODIFIERS = T.let({
26
29
  declaration: 0,
27
30
  definition: 1,
28
31
  readonly: 2,
@@ -33,18 +36,32 @@ module RubyLsp
33
36
  modification: 7,
34
37
  documentation: 8,
35
38
  default_library: 9,
36
- }.freeze
39
+ }.freeze, T::Hash[Symbol, Integer])
37
40
 
38
- SemanticToken = Struct.new(:location, :length, :type, :modifier)
41
+ class SemanticToken < T::Struct
42
+ const :location, SyntaxTree::Location
43
+ const :length, Integer
44
+ const :type, Integer
45
+ const :modifier, T::Array[Integer]
46
+ end
39
47
 
48
+ sig { params(document: Document, encoder: T.nilable(Support::SemanticTokenEncoder)).void }
40
49
  def initialize(document, encoder: nil)
41
50
  super(document)
42
51
 
43
52
  @encoder = encoder
44
- @tokens = []
45
- @tree = document.tree
53
+ @tokens = T.let([], T::Array[SemanticToken])
54
+ @tree = T.let(document.tree, SyntaxTree::Node)
46
55
  end
47
56
 
57
+ sig do
58
+ override.returns(
59
+ T.any(
60
+ LanguageServer::Protocol::Interface::SemanticTokens,
61
+ T.all(T::Array[SemanticToken], Object),
62
+ )
63
+ )
64
+ end
48
65
  def run
49
66
  visit(@tree)
50
67
  return @tokens unless @encoder
@@ -52,60 +69,118 @@ module RubyLsp
52
69
  @encoder.encode(@tokens)
53
70
  end
54
71
 
55
- def visit_m_assign(node)
56
- node.target.parts.each do |var_ref|
57
- add_token(var_ref.value.location, :variable)
58
- end
59
- end
60
-
61
- def visit_var_field(node)
62
- case node.value
63
- when SyntaxTree::Ident
64
- add_token(node.value.location, :variable)
65
- end
66
- end
67
-
68
- def visit_var_ref(node)
69
- case node.value
70
- when SyntaxTree::Ident
71
- add_token(node.value.location, :variable)
72
- end
73
- end
74
-
72
+ sig { params(node: SyntaxTree::ARefField).void }
75
73
  def visit_a_ref_field(node)
76
74
  add_token(node.collection.value.location, :variable)
77
75
  end
78
76
 
77
+ sig { params(node: SyntaxTree::Call).void }
79
78
  def visit_call(node)
80
79
  visit(node.receiver)
81
80
  add_token(node.message.location, :method)
82
81
  visit(node.arguments)
83
82
  end
84
83
 
84
+ sig { params(node: SyntaxTree::Command).void }
85
85
  def visit_command(node)
86
86
  add_token(node.message.location, :method)
87
87
  visit(node.arguments)
88
88
  end
89
89
 
90
+ sig { params(node: SyntaxTree::CommandCall).void }
90
91
  def visit_command_call(node)
91
92
  visit(node.receiver)
92
93
  add_token(node.message.location, :method)
93
94
  visit(node.arguments)
94
95
  end
95
96
 
97
+ sig { params(node: SyntaxTree::Const).void }
98
+ def visit_const(node)
99
+ add_token(node.location, :namespace)
100
+ end
101
+
102
+ sig { params(node: SyntaxTree::Def).void }
103
+ def visit_def(node)
104
+ add_token(node.name.location, :method, [:declaration])
105
+ visit(node.params)
106
+ visit(node.bodystmt)
107
+ end
108
+
109
+ sig { params(node: SyntaxTree::DefEndless).void }
110
+ def visit_def_endless(node)
111
+ add_token(node.name.location, :method, [:declaration])
112
+ visit(node.paren)
113
+ visit(node.operator)
114
+ visit(node.statement)
115
+ end
116
+
117
+ sig { params(node: SyntaxTree::Defs).void }
118
+ def visit_defs(node)
119
+ visit(node.target)
120
+ visit(node.operator)
121
+ add_token(node.name.location, :method, [:declaration])
122
+ visit(node.params)
123
+ visit(node.bodystmt)
124
+ end
125
+
126
+ sig { params(node: SyntaxTree::FCall).void }
96
127
  def visit_fcall(node)
97
128
  add_token(node.value.location, :method)
98
129
  visit(node.arguments)
99
130
  end
100
131
 
132
+ sig { params(node: SyntaxTree::Kw).void }
133
+ def visit_kw(node)
134
+ case node.value
135
+ when "self"
136
+ add_token(node.location, :variable, [:default_library])
137
+ end
138
+ end
139
+
140
+ sig { params(node: SyntaxTree::MAssign).void }
141
+ def visit_m_assign(node)
142
+ node.target.parts.each do |var_ref|
143
+ add_token(var_ref.value.location, :variable)
144
+ end
145
+ end
146
+
147
+ sig { params(node: SyntaxTree::VarField).void }
148
+ def visit_var_field(node)
149
+ case node.value
150
+ when SyntaxTree::Ident
151
+ add_token(node.value.location, :variable)
152
+ else
153
+ visit(node.value)
154
+ end
155
+ end
156
+
157
+ sig { params(node: SyntaxTree::VarRef).void }
158
+ def visit_var_ref(node)
159
+ case node.value
160
+ when SyntaxTree::Ident
161
+ add_token(node.value.location, :variable)
162
+ else
163
+ visit(node.value)
164
+ end
165
+ end
166
+
167
+ sig { params(node: SyntaxTree::VCall).void }
101
168
  def visit_vcall(node)
102
169
  add_token(node.value.location, :method)
103
170
  end
104
171
 
172
+ sig { params(location: SyntaxTree::Location, type: Symbol, modifiers: T::Array[Symbol]).void }
105
173
  def add_token(location, type, modifiers = [])
106
174
  length = location.end_char - location.start_char
107
175
  modifiers_indices = modifiers.filter_map { |modifier| TOKEN_MODIFIERS[modifier] }
108
- @tokens.push(SemanticToken.new(location, length, TOKEN_TYPES.index(type), modifiers_indices))
176
+ @tokens.push(
177
+ SemanticToken.new(
178
+ location: location,
179
+ length: length,
180
+ type: T.must(TOKEN_TYPES.index(type)),
181
+ modifier: modifiers_indices
182
+ )
183
+ )
109
184
  end
110
185
  end
111
186
  end
@@ -1,35 +1,45 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
5
5
  module Requests
6
6
  module Support
7
7
  class RuboCopDiagnostic
8
- RUBOCOP_TO_LSP_SEVERITY = {
8
+ extend T::Sig
9
+
10
+ RUBOCOP_TO_LSP_SEVERITY = T.let({
9
11
  convention: LanguageServer::Protocol::Constant::DiagnosticSeverity::INFORMATION,
10
12
  info: LanguageServer::Protocol::Constant::DiagnosticSeverity::INFORMATION,
11
13
  refactor: LanguageServer::Protocol::Constant::DiagnosticSeverity::INFORMATION,
12
14
  warning: LanguageServer::Protocol::Constant::DiagnosticSeverity::WARNING,
13
15
  error: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
14
16
  fatal: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
15
- }.freeze
17
+ }.freeze, T::Hash[Symbol, Integer])
16
18
 
19
+ sig { returns(T::Array[LanguageServer::Protocol::Interface::TextEdit]) }
17
20
  attr_reader :replacements
18
21
 
22
+ sig { params(offense: RuboCop::Cop::Offense, uri: String).void }
19
23
  def initialize(offense, uri)
20
24
  @offense = offense
21
25
  @uri = uri
22
- @replacements = offense.correctable? ? offense_replacements : []
26
+ @replacements = T.let(
27
+ offense.correctable? ? offense_replacements : [],
28
+ T::Array[LanguageServer::Protocol::Interface::TextEdit]
29
+ )
23
30
  end
24
31
 
32
+ sig { returns(T::Boolean) }
25
33
  def correctable?
26
34
  @offense.correctable?
27
35
  end
28
36
 
37
+ sig { params(range: T::Range[Integer]).returns(T::Boolean) }
29
38
  def in_range?(range)
30
39
  range.cover?(@offense.line - 1)
31
40
  end
32
41
 
42
+ sig { returns(LanguageServer::Protocol::Interface::CodeAction) }
33
43
  def to_lsp_code_action
34
44
  LanguageServer::Protocol::Interface::CodeAction.new(
35
45
  title: "Autocorrect #{@offense.cop_name}",
@@ -49,6 +59,7 @@ module RubyLsp
49
59
  )
50
60
  end
51
61
 
62
+ sig { returns(LanguageServer::Protocol::Interface::Diagnostic) }
52
63
  def to_lsp_diagnostic
53
64
  LanguageServer::Protocol::Interface::Diagnostic.new(
54
65
  message: @offense.message,
@@ -70,6 +81,7 @@ module RubyLsp
70
81
 
71
82
  private
72
83
 
84
+ sig { returns(T::Array[LanguageServer::Protocol::Interface::TextEdit]) }
73
85
  def offense_replacements
74
86
  @offense.corrector.as_replacements.map do |range, replacement|
75
87
  LanguageServer::Protocol::Interface::TextEdit.new(
@@ -1,10 +1,13 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
5
5
  module Requests
6
6
  module Support
7
7
  class SelectionRange < LanguageServer::Protocol::Interface::SelectionRange
8
+ extend T::Sig
9
+
10
+ sig { params(position: Document::PositionShape).returns(T::Boolean) }
8
11
  def cover?(position)
9
12
  line_range = (range.start.line..range.end.line)
10
13
  character_range = (range.start.character..range.end.character)
@@ -1,15 +1,23 @@
1
- # typed: true
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
5
5
  module Requests
6
6
  module Support
7
7
  class SemanticTokenEncoder
8
+ extend T::Sig
9
+
10
+ sig { void }
8
11
  def initialize
9
- @current_row = 0
10
- @current_column = 0
12
+ @current_row = T.let(0, Integer)
13
+ @current_column = T.let(0, Integer)
11
14
  end
12
15
 
16
+ sig do
17
+ params(
18
+ tokens: T::Array[SemanticHighlighting::SemanticToken]
19
+ ).returns(LanguageServer::Protocol::Interface::SemanticTokens)
20
+ end
13
21
  def encode(tokens)
14
22
  delta = tokens
15
23
  .sort_by do |token|
@@ -31,6 +39,7 @@ module RubyLsp
31
39
 
32
40
  # For more information on how each number is calculated, read:
33
41
  # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens
42
+ sig { params(token: SemanticHighlighting::SemanticToken).returns(T::Array[Integer]) }
34
43
  def compute_delta(token)
35
44
  row = token.location.start_line - 1
36
45
  column = token.location.start_column
@@ -49,6 +58,7 @@ module RubyLsp
49
58
  # For example, [:default_library] will be encoded as
50
59
  # 0b1000000000, as :default_library is the 10th bit according
51
60
  # to the token modifiers index map.
61
+ sig { params(modifiers: T::Array[Integer]).returns(Integer) }
52
62
  def encode_modifiers(modifiers)
53
63
  modifiers.inject(0) do |encoded_modifiers, modifier|
54
64
  encoded_modifiers | (1 << modifier)