steep 1.9.3 → 1.10.0.dev.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02b4d30c83adaf9c3784371edd9f014f772273cec3ea72e9befeb3d882a897c6
4
- data.tar.gz: 1146ee79d9b908d96f3079de416ba2d10b43e8b2a32ee440d4a2b7519a29558c
3
+ metadata.gz: c16f09c4999f414317b991d4c36ed5a5b51a2bf785d4f865ab9d698890050205
4
+ data.tar.gz: f0a34b2b9c27703a87375e19a33055bed47ae3cc1ac8dae4fc846a931e054223
5
5
  SHA512:
6
- metadata.gz: 23ab3d323a5395ab7fe9ac37c98c657c780a949637ff4126ea2b0c320f27031fba615239eeaeaa028409cbf9b22dc1016c4299c31a545b387bec61785321a3fa
7
- data.tar.gz: 6e94877bc417d187f49f7f8dc105058835785146ad4172d7d98751e790ea05b42f191db588a516fb0151949f68664a16c5ddb2a6220915613cc98f1be824ab0f
6
+ metadata.gz: 24d081be36d7b8bd33ffe5786db94ff5e8a1b505c7dfa72e4076b3c7612d78e6c5978bebba991d792e9fc4b97bb0da3f004db308eade2b6ed6e63075ce3f9d9f
7
+ data.tar.gz: 68069586284621fac6acbc1f279a3b866b26dcba5436334f16abb6db3466c2917a549c0f2b48bfc205eab74ee3d865124ab1a87f7b02403bb2a8b39d2c67a938
data/Steepfile CHANGED
@@ -13,7 +13,6 @@ if (source = rbs_dep&.source).is_a?(Bundler::Source::Path)
13
13
  end
14
14
  else
15
15
  FileUtils.rm_f(tmp_rbs_dir)
16
- library "rbs"
17
16
  end
18
17
 
19
18
  target :app do
@@ -64,5 +63,9 @@ target :bin do
64
63
  check "bin/generate-diagnostics-docs.rb"
65
64
  signature "tmp/rbs-inline/bin"
66
65
 
67
- library "rbs"
66
+ if tmp_rbs_dir.directory?
67
+ signature tmp_rbs_dir.to_s
68
+ else
69
+ library "rbs"
70
+ end
68
71
  end
@@ -0,0 +1,18 @@
1
+ module Steep
2
+ module AnnotationsHelper
3
+ module_function
4
+
5
+ def deprecated_annotation?(annotations)
6
+ annotations.reverse_each do |annotation|
7
+ if match = annotation.string.match(/deprecated(:\s*(?<message>.+))?/)
8
+ return [annotation, match[:message]]
9
+ end
10
+ if match = annotation.string.match(/steep:deprecated(:\s*(?<message>.+))?/)
11
+ return [annotation, match[:message]]
12
+ end
13
+ end
14
+
15
+ nil
16
+ end
17
+ end
18
+ end
@@ -93,15 +93,14 @@ module Steep
93
93
  def self.parse(comment, buffer)
94
94
  return unless comment.inline?
95
95
 
96
- comment_location = RBS::Location.new(buffer, comment.loc.expression.begin_pos, comment.loc.expression.end_pos)
96
+ begin_pos = buffer.loc_to_pos([comment.loc.line, comment.loc.column])
97
+ end_pos = buffer.loc_to_pos([comment.loc.last_line, comment.loc.last_column])
98
+ comment_location = RBS::Location.new(buffer, begin_pos, end_pos)
97
99
  scanner = BufferScanner.new(comment_location)
98
100
 
99
101
  scanner.scan(/#/)
100
102
  scanner.skip(/\s*/)
101
103
 
102
- begin_pos = comment.location.expression.begin_pos
103
- end_pos = comment.location.expression.end_pos
104
-
105
104
  case
106
105
  when loc = scanner.scan(/steep:ignore:start\b/)
107
106
  scanner.skip(/\s*/)
data/lib/steep/cli.rb CHANGED
@@ -24,12 +24,13 @@ module Steep
24
24
  opts.banner = <<~USAGE
25
25
  Usage: steep [options]
26
26
 
27
- available commands: #{CLI.available_commands.join(', ')}
27
+ Available commands:
28
+ #{CLI.available_commands.join(', ')}
28
29
 
29
30
  Options:
30
31
  USAGE
31
32
 
32
- opts.on("--version") do
33
+ opts.on("--version", "Print Steep version") do
33
34
  process_version
34
35
  exit 0
35
36
  end
@@ -60,6 +61,10 @@ module Steep
60
61
  __send__(:"process_#{command}")
61
62
  end
62
63
 
64
+ def handle_steepfile_option(opts, command)
65
+ opts.on("--steepfile=PATH", "Specify path to Steepfile") {|path| command.steepfile = Pathname(path) }
66
+ end
67
+
63
68
  def handle_logging_options(opts)
64
69
  opts.on("--log-level=LEVEL", "Specify log level: debug, info, warn, error, fatal") do |level|
65
70
  Steep.logger.level = level
@@ -101,10 +106,16 @@ module Steep
101
106
  def process_init
102
107
  Drivers::Init.new(stdout: stdout, stderr: stderr).tap do |command|
103
108
  OptionParser.new do |opts|
104
- opts.banner = "Usage: steep init [options]"
109
+ opts.banner = <<BANNER
110
+ Usage: steep init [options]
111
+
112
+ Description:
113
+ Generates a Steepfile at specified path.
105
114
 
106
- opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
107
- opts.on("--force") { command.force_write = true }
115
+ Options:
116
+ BANNER
117
+ handle_steepfile_option(opts, command)
118
+ opts.on("--force", "Overwrite the Steepfile if it already exists") { command.force_write = true }
108
119
 
109
120
  handle_logging_options opts
110
121
  end.parse!(argv)
@@ -114,9 +125,19 @@ module Steep
114
125
  def process_check
115
126
  Drivers::Check.new(stdout: stdout, stderr: stderr).tap do |command|
116
127
  OptionParser.new do |opts|
117
- opts.banner = "Usage: steep check [options] [sources]"
128
+ opts.banner = <<BANNER
129
+ Usage: steep check [options] [paths]
130
+
131
+ Description:
132
+ Type check the program.
133
+
134
+ If paths are specified, it type checks and validates the files at the given path.
135
+ Otherwise, it type checks and validates all files in the project or the groups if specified.
136
+
137
+ Options:
138
+ BANNER
118
139
 
119
- opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
140
+ handle_steepfile_option(opts, command)
120
141
  opts.on("--with-expectations[=PATH]", "Type check with expectations saved in PATH (or steep_expectations.yml)") do |path|
121
142
  command.with_expectations_path = Pathname(path || "steep_expectations.yml")
122
143
  end
@@ -172,16 +193,23 @@ module Steep
172
193
 
173
194
  setup_jobs_for_ci(command.jobs_option)
174
195
 
175
- command.command_line_patterns.push *argv
196
+ command.command_line_patterns.push(*argv)
176
197
  end.run
177
198
  end
178
199
 
179
200
  def process_checkfile
180
201
  Drivers::Checkfile.new(stdout: stdout, stderr: stderr).tap do |command|
181
202
  OptionParser.new do |opts|
182
- opts.banner = "Usage: steep checkfile [options] [files]"
203
+ opts.banner = <<BANNER
204
+ Usage: steep checkfile [options] [files]
183
205
 
184
- opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
206
+ Description:
207
+ Deprecated: Use `steep check` instead.
208
+
209
+ Options:
210
+ BANNER
211
+
212
+ handle_steepfile_option(opts, command)
185
213
  opts.on("--all-rbs", "Type check all RBS files") { command.all_rbs = true }
186
214
  opts.on("--all-ruby", "Type check all Ruby files") { command.all_ruby = true }
187
215
  opts.on("--stdin", "Read files to type check from stdin") do
@@ -197,16 +225,23 @@ module Steep
197
225
 
198
226
  setup_jobs_for_ci(command.jobs_option)
199
227
 
200
- command.command_line_args.push *argv
228
+ command.command_line_args.push(*argv)
201
229
  end.run
202
230
  end
203
231
 
204
232
  def process_stats
205
233
  Drivers::Stats.new(stdout: stdout, stderr: stderr).tap do |command|
206
234
  OptionParser.new do |opts|
207
- opts.banner = "Usage: steep stats [options] [sources]"
235
+ opts.banner = <<BANNER
236
+ Usage: steep stats [options] [sources]
237
+
238
+ Description:
239
+ Displays statistics about the typing of method calls.
208
240
 
209
- opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
241
+ Options:
242
+ BANNER
243
+
244
+ handle_steepfile_option(opts, command)
210
245
  opts.on("--format=FORMAT", "Specify output format: csv, table") {|format| command.format = format }
211
246
  handle_jobs_option command.jobs_option, opts
212
247
  handle_logging_options opts
@@ -214,7 +249,7 @@ module Steep
214
249
 
215
250
  setup_jobs_for_ci(command.jobs_option)
216
251
 
217
- command.command_line_patterns.push *argv
252
+ command.command_line_patterns.push(*argv)
218
253
  end.run
219
254
  end
220
255
 
@@ -226,19 +261,33 @@ module Steep
226
261
  def process_annotations
227
262
  Drivers::Annotations.new(stdout: stdout, stderr: stderr).tap do |command|
228
263
  OptionParser.new do |opts|
229
- opts.banner = "Usage: steep annotations [options] [sources]"
264
+ opts.banner = <<BANNER
265
+ Usage: steep annotations [options] [sources]
266
+
267
+ Description:
268
+ Prints the type annotations in the Ruby code.
269
+
270
+ Options:
271
+ BANNER
230
272
  handle_logging_options opts
231
273
  end.parse!(argv)
232
274
 
233
- command.command_line_patterns.push *argv
275
+ command.command_line_patterns.push(*argv)
234
276
  end.run
235
277
  end
236
278
 
237
279
  def process_project
238
280
  Drivers::PrintProject.new(stdout: stdout, stderr: stderr).tap do |command|
239
281
  OptionParser.new do |opts|
240
- opts.banner = "Usage: steep project [options]"
241
- opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
282
+ opts.banner = <<BANNER
283
+ Usage: steep project [options]
284
+
285
+ Description:
286
+ Prints the project configuration.
287
+
288
+ Options:
289
+ BANNER
290
+ handle_steepfile_option(opts, command)
242
291
  opts.on("--[no-]print-files", "Print files") {|v|
243
292
  command.print_files = v ? true : false
244
293
  }
@@ -250,7 +299,15 @@ module Steep
250
299
  def process_watch
251
300
  Drivers::Watch.new(stdout: stdout, stderr: stderr).tap do |command|
252
301
  OptionParser.new do |opts|
253
- opts.banner = "Usage: steep watch [options] [dirs]"
302
+ opts.banner = <<BANNER
303
+ Usage: steep watch [options] [dirs]
304
+
305
+ Description:
306
+ Monitors file changes and automatically type checks updated files.
307
+ Using LSP is recommended for better performance and more features.
308
+
309
+ Options:
310
+ BANNER
254
311
  opts.on("--severity-level=LEVEL", /^error|warning|information|hint$/, "Specify the minimum diagnostic severity to be recognized as an error (defaults: warning): error, warning, information, or hint") do |level|
255
312
  # @type var level: String
256
313
  command.severity_level = _ = level.to_sym
@@ -269,7 +326,16 @@ module Steep
269
326
  def process_langserver
270
327
  Drivers::Langserver.new(stdout: stdout, stderr: stderr, stdin: stdin).tap do |command|
271
328
  OptionParser.new do |opts|
272
- opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
329
+ opts.banner = <<BANNER
330
+ Usage: steep langserver [options]
331
+
332
+ Description:
333
+ Starts language server, which is assumed to be invoked from language client.
334
+
335
+ Options:
336
+ BANNER
337
+ handle_steepfile_option(opts, command)
338
+ opts.on("--refork") { command.refork = true }
273
339
  handle_jobs_option command.jobs_option, opts
274
340
  handle_logging_options opts
275
341
  end.parse!(argv)
@@ -300,8 +366,8 @@ module Steep
300
366
  opts.banner = <<BANNER
301
367
  Usage: steep binstub [options]
302
368
 
303
- Generate a binstub to execute Steep with setting up Bundler and rbenv/rvm.
304
- Use the executable for LSP integration setup.
369
+ Description:
370
+ Generate a binstub which set up ruby executables and bundlers.
305
371
 
306
372
  Options:
307
373
  BANNER
@@ -372,6 +438,15 @@ TEMPLATE
372
438
  end
373
439
 
374
440
  def process_version
441
+ OptionParser.new do |opts|
442
+ opts.banner = <<BANNER
443
+ Usage: steep version [options]
444
+
445
+ Description:
446
+ Prints Steep version.
447
+ BANNER
448
+ end.parse!(argv)
449
+
375
450
  stdout.puts Steep::VERSION
376
451
  0
377
452
  end
@@ -384,7 +459,7 @@ TEMPLATE
384
459
 
385
460
  opts.on("--interaction") { command.worker_type = :interaction }
386
461
  opts.on("--typecheck") { command.worker_type = :typecheck }
387
- opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
462
+ handle_steepfile_option(opts, command)
388
463
  opts.on("--name=NAME") {|name| command.worker_name = name }
389
464
  opts.on("--delay-shutdown") { command.delay_shutdown = true }
390
465
  opts.on("--max-index=COUNT") {|count| command.max_index = Integer(count) }
@@ -49,13 +49,24 @@ module Steep
49
49
  } #: LSP::Interface::CodeDescription::json
50
50
  end
51
51
 
52
- {
52
+ tags = [] #: Array[LSP::Constant::DiagnosticTag::t]
53
+
54
+ case diagnostic
55
+ when Ruby::DeprecatedReference
56
+ tags << LSP::Constant::DiagnosticTag::DEPRECATED
57
+ end
58
+
59
+ json = {
53
60
  message: diagnostic.full_message,
54
61
  code: diagnostic.diagnostic_code,
55
62
  severity: severity,
56
63
  range: range,
57
- codeDescription: description
58
- }
64
+ codeDescription: description,
65
+ } #: LSP::Interface::Diagnostic::json
66
+
67
+ json[:tags] = tags unless tags.empty?
68
+
69
+ json
59
70
  end
60
71
  end
61
72
 
@@ -977,6 +977,72 @@ module Steep
977
977
  end
978
978
  end
979
979
 
980
+ class UndeclaredMethodDefinition < Base
981
+ attr_reader :method_name, :type_name
982
+
983
+ def initialize(method_name:, type_name:, node:)
984
+ @method_name = method_name
985
+ @type_name = type_name
986
+ super(node: node, location: (_ = node.loc).name)
987
+ end
988
+
989
+ def header_line
990
+ name =
991
+ case node.type
992
+ when :def
993
+ "#{type_name}##{method_name}"
994
+ when :defs
995
+ "#{type_name}.#{method_name}"
996
+ else
997
+ raise
998
+ end
999
+ "Method `#{name}` is not declared in RBS"
1000
+ end
1001
+ end
1002
+
1003
+ class MethodDefinitionInUndeclaredModule < Base
1004
+ attr_reader :method_name
1005
+
1006
+ def initialize(method_name:, node:)
1007
+ @method_name = method_name
1008
+ super(node: node, location: (_ = node.loc).name)
1009
+ end
1010
+
1011
+ def header_line
1012
+ "Method `#{method_name}` is defined in undeclared module"
1013
+ end
1014
+ end
1015
+
1016
+ class DeprecatedReference < Base
1017
+ attr_reader :message
1018
+
1019
+ def initialize(node:, location:, message:)
1020
+ super(node: node, location: location)
1021
+ @message = message
1022
+ end
1023
+
1024
+ def header_line
1025
+ header =
1026
+ case node&.type
1027
+ when :send, :csend, :block, :numblock
1028
+ "The method is deprecated"
1029
+ when :const, :casgn
1030
+ "The constant is deprecated"
1031
+ when :gvar, :gvasgn
1032
+ "The global variable is deprecated"
1033
+ else
1034
+ raise "Unexpected node: #{node}"
1035
+ end
1036
+
1037
+ if message
1038
+ header = +header
1039
+ header.concat(": ", message)
1040
+ end
1041
+
1042
+ header
1043
+ end
1044
+ end
1045
+
980
1046
  ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
981
1047
  if klass < Base
982
1048
  array << klass
@@ -997,6 +1063,7 @@ module Steep
997
1063
  BlockBodyTypeMismatch => :warning,
998
1064
  BlockTypeMismatch => :warning,
999
1065
  BreakTypeMismatch => :hint,
1066
+ DeprecatedReference => :warning,
1000
1067
  DifferentMethodParameterKind => :hint,
1001
1068
  FallbackAny => :hint,
1002
1069
  FalseAssertion => :hint,
@@ -1010,6 +1077,7 @@ module Steep
1010
1077
  InvalidIgnoreComment => :warning,
1011
1078
  MethodArityMismatch => :error,
1012
1079
  MethodBodyTypeMismatch => :error,
1080
+ MethodDefinitionInUndeclaredModule => :information,
1013
1081
  MethodDefinitionMissing => nil,
1014
1082
  MethodParameterMismatch => :error,
1015
1083
  MethodReturnTypeAnnotationMismatch => :hint,
@@ -1026,6 +1094,7 @@ module Steep
1026
1094
  SyntaxError => :information,
1027
1095
  TypeArgumentMismatchError => :hint,
1028
1096
  UnannotatedEmptyCollection => :warning,
1097
+ UndeclaredMethodDefinition => :warning,
1029
1098
  UnexpectedBlockGiven => :warning,
1030
1099
  UnexpectedDynamicMethod => :hint,
1031
1100
  UnexpectedError => :hint,
@@ -1057,6 +1126,7 @@ module Steep
1057
1126
  BlockBodyTypeMismatch => :error,
1058
1127
  BlockTypeMismatch => :error,
1059
1128
  BreakTypeMismatch => :error,
1129
+ DeprecatedReference => :warning,
1060
1130
  DifferentMethodParameterKind => :error,
1061
1131
  FallbackAny => :warning,
1062
1132
  FalseAssertion => :error,
@@ -1070,6 +1140,7 @@ module Steep
1070
1140
  InvalidIgnoreComment => :warning,
1071
1141
  MethodArityMismatch => :error,
1072
1142
  MethodBodyTypeMismatch => :error,
1143
+ MethodDefinitionInUndeclaredModule => :warning,
1073
1144
  MethodDefinitionMissing => :hint,
1074
1145
  MethodParameterMismatch => :error,
1075
1146
  MethodReturnTypeAnnotationMismatch => :error,
@@ -1086,6 +1157,7 @@ module Steep
1086
1157
  SyntaxError => :information,
1087
1158
  TypeArgumentMismatchError => :error,
1088
1159
  UnannotatedEmptyCollection => :error,
1160
+ UndeclaredMethodDefinition => :warning,
1089
1161
  UnexpectedBlockGiven => :error,
1090
1162
  UnexpectedDynamicMethod => :information,
1091
1163
  UnexpectedError => :information,
@@ -1117,6 +1189,7 @@ module Steep
1117
1189
  BlockBodyTypeMismatch => :information,
1118
1190
  BlockTypeMismatch => :information,
1119
1191
  BreakTypeMismatch => :hint,
1192
+ DeprecatedReference => :warning,
1120
1193
  DifferentMethodParameterKind => nil,
1121
1194
  FallbackAny => nil,
1122
1195
  FalseAssertion => nil,
@@ -1130,6 +1203,7 @@ module Steep
1130
1203
  InvalidIgnoreComment => :warning,
1131
1204
  MethodArityMismatch => :information,
1132
1205
  MethodBodyTypeMismatch => :warning,
1206
+ MethodDefinitionInUndeclaredModule => :hint,
1133
1207
  MethodDefinitionMissing => nil,
1134
1208
  MethodParameterMismatch => :warning,
1135
1209
  MethodReturnTypeAnnotationMismatch => nil,
@@ -1146,6 +1220,7 @@ module Steep
1146
1220
  SyntaxError => :information,
1147
1221
  TypeArgumentMismatchError => nil,
1148
1222
  UnannotatedEmptyCollection => :hint,
1223
+ UndeclaredMethodDefinition => :information,
1149
1224
  UnexpectedBlockGiven => :hint,
1150
1225
  UnexpectedDynamicMethod => nil,
1151
1226
  UnexpectedError => :hint,
@@ -8,6 +8,7 @@ module Steep
8
8
  attr_reader :type_check_queue
9
9
  attr_reader :type_check_thread
10
10
  attr_reader :jobs_option
11
+ attr_accessor :refork
11
12
 
12
13
  include Utils::DriverHelper
13
14
 
@@ -18,6 +19,7 @@ module Steep
18
19
  @write_mutex = Mutex.new
19
20
  @type_check_queue = Queue.new
20
21
  @jobs_option = Utils::JobsOption.new(jobs_count_modifier: -1)
22
+ @refork = false
21
23
  end
22
24
 
23
25
  def writer
@@ -43,7 +45,8 @@ module Steep
43
45
  reader: reader,
44
46
  writer: writer,
45
47
  interaction_worker: interaction_worker,
46
- typecheck_workers: typecheck_workers
48
+ typecheck_workers: typecheck_workers,
49
+ refork: refork,
47
50
  )
48
51
  master.typecheck_automatically = true
49
52
 
@@ -9,6 +9,7 @@ module Steep
9
9
  attr_accessor :max_index
10
10
  attr_accessor :index
11
11
  attr_accessor :commandline_args
12
+ attr_accessor :io_socket
12
13
 
13
14
  include Utils::DriverHelper
14
15
 
@@ -32,6 +33,7 @@ module Steep
32
33
  Server::TypeCheckWorker.new(project: project,
33
34
  reader: reader,
34
35
  writer: writer,
36
+ io_socket:,
35
37
  assignment: assignment,
36
38
  commandline_args: commandline_args)
37
39
  when :interaction
@@ -283,7 +283,7 @@ module Steep
283
283
  method_type = factory.method_type(type_def.type)
284
284
  method_type = replace_primitive_method(method_name, type_def, method_type)
285
285
  method_type = replace_kernel_class(method_name, type_def, method_type) { AST::Builtin::Class.instance_type }
286
- method_type = add_implicitly_returns_nil(type_def.annotations, method_type)
286
+ method_type = add_implicitly_returns_nil(type_def.each_annotation, method_type)
287
287
  Shape::MethodOverload.new(method_type, [type_def])
288
288
  end
289
289
 
@@ -317,7 +317,7 @@ module Steep
317
317
  if type_name.class?
318
318
  method_type = replace_kernel_class(method_name, type_def, method_type) { AST::Types::Name::Singleton.new(name: type_name) }
319
319
  end
320
- method_type = add_implicitly_returns_nil(type_def.annotations, method_type)
320
+ method_type = add_implicitly_returns_nil(type_def.each_annotation, method_type)
321
321
  Shape::MethodOverload.new(method_type, [type_def])
322
322
  end
323
323
 
@@ -72,6 +72,18 @@ module Steep
72
72
  { id: id, result: result }
73
73
  end
74
74
  end
75
+
76
+ module Refork
77
+ METHOD = "$/steep/refork"
78
+
79
+ def self.request(id, params)
80
+ { method: METHOD, id: id, params: params }
81
+ end
82
+
83
+ def self.response(id, result)
84
+ { id: id, result: result }
85
+ end
86
+ end
75
87
  end
76
88
  end
77
89
  end
@@ -355,6 +355,11 @@ module Steep
355
355
 
356
356
  detail = LSPFormatter.declaration_summary(item.decl)
357
357
 
358
+ tags = [] #: Array[LSP::Constant::CompletionItemTag::t]
359
+ if item.deprecated?
360
+ tags << LSP::Constant::CompletionItemTag::DEPRECATED
361
+ end
362
+
358
363
  LSP::Interface::CompletionItem.new(
359
364
  label: item.identifier.to_s,
360
365
  kind: kind,
@@ -363,15 +368,22 @@ module Steep
363
368
  text_edit: LSP::Interface::TextEdit.new(
364
369
  range: range,
365
370
  new_text: item.identifier.to_s
366
- )
371
+ ),
372
+ tags: tags
367
373
  )
368
374
  when Services::CompletionProvider::SimpleMethodNameItem
375
+ tags = [] #: Array[LSP::Constant::CompletionItemTag::t]
376
+ if item.deprecated
377
+ tags << LSP::Constant::CompletionItemTag::DEPRECATED
378
+ end
379
+
369
380
  LSP::Interface::CompletionItem.new(
370
381
  label: item.identifier.to_s,
371
382
  kind: LSP::Constant::CompletionItemKind::FUNCTION,
372
383
  label_details: LSP::Interface::CompletionItemLabelDetails.new(description: item.method_name.relative.to_s),
373
384
  insert_text: item.identifier.to_s,
374
- documentation: LSPFormatter.markup_content { LSPFormatter.format_completion_docs(item) }
385
+ documentation: LSPFormatter.markup_content { LSPFormatter.format_completion_docs(item) },
386
+ tags: tags
375
387
  )
376
388
  when Services::CompletionProvider::ComplexMethodNameItem
377
389
  method_names = item.method_names.map(&:relative).uniq