steep 1.10.0.pre.3 → 2.0.0

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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +87 -0
  3. data/CLAUDE.md +114 -0
  4. data/README.md +1 -1
  5. data/Rakefile +15 -3
  6. data/Steepfile +13 -13
  7. data/lib/steep/annotation_parser.rb +5 -1
  8. data/lib/steep/annotations_helper.rb +12 -2
  9. data/lib/steep/ast/node/type_application.rb +22 -16
  10. data/lib/steep/ast/node/type_assertion.rb +7 -4
  11. data/lib/steep/ast/types/factory.rb +3 -2
  12. data/lib/steep/cli.rb +246 -2
  13. data/lib/steep/daemon/configuration.rb +19 -0
  14. data/lib/steep/daemon/server.rb +476 -0
  15. data/lib/steep/daemon.rb +201 -0
  16. data/lib/steep/diagnostic/ruby.rb +50 -8
  17. data/lib/steep/diagnostic/signature.rb +31 -8
  18. data/lib/steep/drivers/check.rb +301 -140
  19. data/lib/steep/drivers/print_project.rb +9 -10
  20. data/lib/steep/drivers/query.rb +102 -0
  21. data/lib/steep/drivers/start_server.rb +19 -0
  22. data/lib/steep/drivers/stop_server.rb +20 -0
  23. data/lib/steep/drivers/watch.rb +2 -2
  24. data/lib/steep/index/rbs_index.rb +38 -13
  25. data/lib/steep/index/signature_symbol_provider.rb +24 -3
  26. data/lib/steep/interface/builder.rb +48 -15
  27. data/lib/steep/interface/shape.rb +13 -5
  28. data/lib/steep/locator.rb +377 -0
  29. data/lib/steep/project/dsl.rb +26 -5
  30. data/lib/steep/project/group.rb +8 -2
  31. data/lib/steep/project/target.rb +16 -2
  32. data/lib/steep/project.rb +21 -2
  33. data/lib/steep/server/base_worker.rb +2 -2
  34. data/lib/steep/server/change_buffer.rb +2 -1
  35. data/lib/steep/server/custom_methods.rb +12 -0
  36. data/lib/steep/server/inline_source_change_detector.rb +94 -0
  37. data/lib/steep/server/interaction_worker.rb +51 -74
  38. data/lib/steep/server/lsp_formatter.rb +48 -12
  39. data/lib/steep/server/master.rb +100 -18
  40. data/lib/steep/server/target_group_files.rb +124 -151
  41. data/lib/steep/server/type_check_controller.rb +276 -123
  42. data/lib/steep/server/type_check_worker.rb +104 -3
  43. data/lib/steep/services/completion_provider/rbs.rb +74 -0
  44. data/lib/steep/services/completion_provider/ruby.rb +652 -0
  45. data/lib/steep/services/completion_provider/type_name.rb +243 -0
  46. data/lib/steep/services/completion_provider.rb +39 -662
  47. data/lib/steep/services/content_change.rb +14 -1
  48. data/lib/steep/services/file_loader.rb +4 -2
  49. data/lib/steep/services/goto_service.rb +271 -68
  50. data/lib/steep/services/hover_provider/content.rb +67 -0
  51. data/lib/steep/services/hover_provider/rbs.rb +8 -9
  52. data/lib/steep/services/hover_provider/ruby.rb +123 -64
  53. data/lib/steep/services/hover_provider/singleton_methods.rb +4 -0
  54. data/lib/steep/services/signature_service.rb +129 -54
  55. data/lib/steep/services/type_check_service.rb +72 -27
  56. data/lib/steep/signature/validator.rb +30 -18
  57. data/lib/steep/source/ignore_ranges.rb +14 -4
  58. data/lib/steep/source.rb +16 -2
  59. data/lib/steep/tagged_logging.rb +39 -0
  60. data/lib/steep/type_construction.rb +94 -21
  61. data/lib/steep/type_inference/block_params.rb +7 -7
  62. data/lib/steep/type_inference/context.rb +4 -2
  63. data/lib/steep/type_inference/logic_type_interpreter.rb +21 -3
  64. data/lib/steep/type_inference/method_call.rb +4 -0
  65. data/lib/steep/type_inference/type_env.rb +1 -1
  66. data/lib/steep/typing.rb +0 -2
  67. data/lib/steep/version.rb +1 -1
  68. data/lib/steep.rb +42 -32
  69. data/manual/ruby-diagnostics.md +67 -0
  70. data/sample/Steepfile +1 -0
  71. data/sample/lib/conference.rb +1 -0
  72. data/sample/lib/deprecated.rb +6 -0
  73. data/sample/lib/inline.rb +43 -0
  74. data/sample/sig/generics.rbs +3 -0
  75. data/steep.gemspec +4 -5
  76. metadata +26 -26
  77. data/lib/steep/services/type_name_completion.rb +0 -236
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Steep
4
+ module Drivers
5
+ class StartServer
6
+ attr_reader :stdout
7
+ attr_reader :stderr
8
+
9
+ def initialize(stdout:, stderr:)
10
+ @stdout = stdout
11
+ @stderr = stderr
12
+ end
13
+
14
+ def run
15
+ Daemon.start(stderr: stderr) ? 0 : 1
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Steep
4
+ module Drivers
5
+ class StopServer
6
+ attr_reader :stdout
7
+ attr_reader :stderr
8
+
9
+ def initialize(stdout:, stderr:)
10
+ @stdout = stdout
11
+ @stderr = stderr
12
+ end
13
+
14
+ def run
15
+ Daemon.stop(stderr: stderr)
16
+ 0
17
+ end
18
+ end
19
+ end
20
+ end
@@ -112,7 +112,7 @@ module Steep
112
112
  end
113
113
  end
114
114
 
115
- params = { library_paths: [], signature_paths: [], code_paths: [] } #: Server::CustomMethods::TypeCheck::params
115
+ params = { library_paths: [], inline_paths: [], signature_paths: [], code_paths: [] } #: Server::CustomMethods::TypeCheck::params
116
116
 
117
117
  (modified + added).each do |path|
118
118
  path = Pathname(path)
@@ -132,7 +132,7 @@ module Steep
132
132
  begin
133
133
  stdout.puts Rainbow("👀 Watching directories, Ctrl-C to stop.").bold
134
134
 
135
- params = { library_paths: [], signature_paths: [], code_paths: [] } #: Server::CustomMethods::TypeCheck::params
135
+ params = { library_paths: [], inline_paths: [], signature_paths: [], code_paths: [] } #: Server::CustomMethods::TypeCheck::params
136
136
  file_loader = Services::FileLoader.new(base_dir: project.base_dir)
137
137
  project.targets.each do |target|
138
138
  file_loader.each_path_in_patterns(target.source_pattern, dirs.map(&:to_s)) do |path|
@@ -22,6 +22,12 @@ module Steep
22
22
  declarations << decl
23
23
  when RBS::AST::Declarations::ClassAlias, RBS::AST::Declarations::ModuleAlias
24
24
  declarations << decl
25
+ when RBS::AST::Ruby::Declarations::ClassDecl
26
+ declarations << decl
27
+ when RBS::AST::Ruby::Declarations::ModuleDecl
28
+ declarations << decl
29
+ when RBS::AST::Ruby::Declarations::ClassModuleAliasDecl
30
+ declarations << decl
25
31
  else
26
32
  raise "Unexpected type declaration: #{decl}"
27
33
  end
@@ -47,6 +53,8 @@ module Steep
47
53
  references << ref
48
54
  when RBS::AST::Declarations::ClassAlias, RBS::AST::Declarations::ModuleAlias
49
55
  references << ref
56
+ when RBS::AST::Ruby::Declarations::ClassModuleAliasDecl
57
+ references << ref
50
58
  else
51
59
  raise "Unexpected type reference: #{ref}"
52
60
  end
@@ -74,6 +82,8 @@ module Steep
74
82
  RBS::AST::Members::AttrReader,
75
83
  RBS::AST::Members::AttrAccessor
76
84
  declarations << decl
85
+ when RBS::AST::Ruby::Members::DefMember
86
+ declarations << decl
77
87
  else
78
88
  raise "Unexpected method declaration: #{decl}"
79
89
  end
@@ -93,7 +103,7 @@ module Steep
93
103
 
94
104
  def add_declaration(decl)
95
105
  case decl
96
- when RBS::AST::Declarations::Constant
106
+ when RBS::AST::Declarations::Constant, RBS::AST::Ruby::Declarations::ConstantDecl
97
107
  declarations << decl
98
108
  else
99
109
  raise
@@ -228,6 +238,10 @@ module Steep
228
238
  index.add_method_declaration(method_name, member)
229
239
  end
230
240
 
241
+ when RBS::AST::Ruby::Members::DefMember
242
+ method_name = InstanceMethodName.new(type_name: type_name, method_name: member.name)
243
+ index.add_method_declaration(method_name, member)
244
+
231
245
  when RBS::AST::Members::AttrAccessor, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter
232
246
  type_reference member.type, from: member
233
247
 
@@ -290,28 +304,37 @@ module Steep
290
304
 
291
305
  def env(env)
292
306
  env.class_decls.each do |name, decl|
293
- decl.decls.each do |d|
294
- index.add_type_declaration(name, d.decl)
307
+ decl.each_decl do |decl|
308
+ index.add_type_declaration(name, decl)
295
309
 
296
- case d.decl
310
+ case decl
297
311
  when RBS::AST::Declarations::Class
298
- if super_class = d.decl.super_class
299
- index.add_type_reference(super_class.name, d.decl)
312
+ if super_class = decl.super_class
313
+ index.add_type_reference(super_class.name, decl)
300
314
  super_class.args.each do |type|
301
- type_reference(type, from: d.decl)
315
+ type_reference(type, from: decl)
302
316
  end
303
317
  end
304
318
  when RBS::AST::Declarations::Module
305
- d.decl.self_types.each do |self_type|
306
- index.add_type_reference(self_type.name, d.decl)
319
+ decl.self_types.each do |self_type|
320
+ index.add_type_reference(self_type.name, decl)
307
321
  self_type.args.each do |type|
308
- type_reference(type, from: d.decl)
322
+ type_reference(type, from: decl)
309
323
  end
310
324
  end
311
325
  end
312
326
 
313
- d.decl.members.each do |member|
314
- member(name, member)
327
+ case decl
328
+ when RBS::AST::Declarations::Base
329
+ decl.members.each do |member|
330
+ member(name, member)
331
+ end
332
+ when RBS::AST::Ruby::Declarations::Base
333
+ decl.members.each do |member|
334
+ if member.is_a?(RBS::AST::Ruby::Members::Base)
335
+ member(name, member)
336
+ end
337
+ end
315
338
  end
316
339
  end
317
340
  end
@@ -336,7 +359,9 @@ module Steep
336
359
 
337
360
  env.constant_decls.each do |name, decl|
338
361
  index.add_constant_declaration(name, decl.decl)
339
- type_reference decl.decl.type, from: decl.decl
362
+ if decl.decl.is_a?(RBS::AST::Declarations::Constant)
363
+ type_reference decl.decl.type, from: decl.decl
364
+ end
340
365
  end
341
366
 
342
367
  env.global_decls.each do |name, decl|
@@ -73,6 +73,13 @@ module Steep
73
73
  kind: LSP::Constant::SymbolKind::CLASS,
74
74
  container_name: container_name
75
75
  )
76
+ when RBS::AST::Ruby::Declarations::ClassDecl
77
+ symbols << SymbolInformation.new(
78
+ name: name,
79
+ location: location,
80
+ kind: LSP::Constant::SymbolKind::CLASS,
81
+ container_name: container_name
82
+ )
76
83
  when RBS::AST::Declarations::Module
77
84
  symbols << SymbolInformation.new(
78
85
  name: name,
@@ -80,6 +87,13 @@ module Steep
80
87
  kind: LSP::Constant::SymbolKind::MODULE,
81
88
  container_name: container_name
82
89
  )
90
+ when RBS::AST::Ruby::Declarations::ModuleDecl
91
+ symbols << SymbolInformation.new(
92
+ name: name,
93
+ location: location,
94
+ kind: LSP::Constant::SymbolKind::MODULE,
95
+ container_name: container_name
96
+ )
83
97
  when RBS::AST::Declarations::Interface
84
98
  symbols << SymbolInformation.new(
85
99
  name: name,
@@ -144,18 +158,25 @@ module Steep
144
158
  container_name: container_name
145
159
  )
146
160
  end
161
+ when RBS::AST::Ruby::Members::DefMember
162
+ symbols << SymbolInformation.new(
163
+ name: name,
164
+ location: location,
165
+ kind: LSP::Constant::SymbolKind::METHOD,
166
+ container_name: container_name
167
+ )
147
168
  end
148
169
  end
149
170
  when RBSIndex::ConstantEntry
150
171
  next unless SignatureSymbolProvider.test_const_name(query, entry.const_name)
151
172
 
152
173
  entry.declarations.each do |decl|
153
- next unless decl.location
154
- next unless assigned?(target, Pathname(decl.location.buffer.name))
174
+ loc = decl.location or next
175
+ next unless assigned?(target, Pathname(loc.buffer.name))
155
176
 
156
177
  symbols << SymbolInformation.new(
157
178
  name: entry.const_name.name.to_s,
158
- location: decl.location,
179
+ location: loc,
159
180
  kind: LSP::Constant::SymbolKind::CONSTANT,
160
181
  container_name: entry.const_name.namespace.relative!.to_s.delete_suffix("::")
161
182
  )
@@ -82,7 +82,7 @@ module Steep
82
82
  end
83
83
 
84
84
  def fetch_cache(cache, key)
85
- if cache.key?(key)
85
+ if cache.key?(key) # steep:ignore ArgumentTypeMismatch
86
86
  return cache.fetch(key)
87
87
  end
88
88
 
@@ -239,8 +239,8 @@ module Steep
239
239
  vars =
240
240
  case type
241
241
  when AST::Types::Name::Instance
242
- entry = factory.env.normalized_module_class_entry(type.name) or raise
243
- entry.primary.decl.type_params.map { _1.name }
242
+ entry = factory.env.module_class_entry(type.name, normalized: true) or raise
243
+ entry.primary_decl.type_params.map { _1.name }
244
244
  when AST::Types::Name::Interface
245
245
  entry = factory.env.interface_decls.fetch(type.name)
246
246
  entry.decl.type_params.map { _1.name }
@@ -408,20 +408,34 @@ module Steep
408
408
  def method_name_for(type_def, name)
409
409
  type_name = type_def.implemented_in || type_def.defined_in
410
410
 
411
- if name == :new && type_def.member.is_a?(RBS::AST::Members::MethodDefinition) && type_def.member.name == :initialize
412
- return SingletonMethodName.new(type_name: type_name, method_name: name)
411
+ if name == :new
412
+ case type_def.member
413
+ when RBS::AST::Members::MethodDefinition
414
+ if type_def.member.name == :initialize
415
+ return SingletonMethodName.new(type_name: type_name, method_name: name)
416
+ end
417
+ when RBS::AST::Ruby::Members::DefMember
418
+ if type_def.member.name == :initialize
419
+ return SingletonMethodName.new(type_name: type_name, method_name: name)
420
+ end
421
+ end
413
422
  end
414
423
 
415
- case type_def.member.kind
416
- when :instance
417
- InstanceMethodName.new(type_name: type_name, method_name: name)
418
- when :singleton
419
- SingletonMethodName.new(type_name: type_name, method_name: name)
420
- when :singleton_instance
421
- # Assume it a instance method, because `module_function` methods are typically defined with `def`
424
+ case type_def.member
425
+ when RBS::AST::Members::Base
426
+ case type_def.member.kind
427
+ when :instance
428
+ InstanceMethodName.new(type_name: type_name, method_name: name)
429
+ when :singleton
430
+ SingletonMethodName.new(type_name: type_name, method_name: name)
431
+ when :singleton_instance
432
+ # Assume it a instance method, because `module_function` methods are typically defined with `def`
433
+ InstanceMethodName.new(type_name: type_name, method_name: name)
434
+ else
435
+ raise
436
+ end
437
+ when RBS::AST::Ruby::Members::DefMember, RBS::AST::Ruby::Members::AttributeMember
422
438
  InstanceMethodName.new(type_name: type_name, method_name: name)
423
- else
424
- raise
425
439
  end
426
440
  end
427
441
 
@@ -779,7 +793,8 @@ module Steep
779
793
  return_type: AST::Types::Logic::ArgIsReceiver.instance()
780
794
  )
781
795
  )
782
- when RBS::BuiltinNames::Object.name,
796
+ when RBS::BuiltinNames::BasicObject.name,
797
+ RBS::BuiltinNames::Object.name,
783
798
  RBS::BuiltinNames::Kernel.name,
784
799
  RBS::BuiltinNames::String.name,
785
800
  RBS::BuiltinNames::Integer.name,
@@ -794,6 +809,24 @@ module Steep
794
809
  )
795
810
  )
796
811
  end
812
+ when :==
813
+ case defined_in
814
+ when RBS::BuiltinNames::BasicObject.name,
815
+ RBS::BuiltinNames::Object.name,
816
+ RBS::BuiltinNames::Kernel.name,
817
+ RBS::BuiltinNames::String.name,
818
+ RBS::BuiltinNames::Integer.name,
819
+ RBS::BuiltinNames::Symbol.name,
820
+ RBS::BuiltinNames::TrueClass.name,
821
+ RBS::BuiltinNames::FalseClass.name,
822
+ RBS::TypeName.parse("::NilClass")
823
+ # For ==, we use ReceiverIsArg to narrow the receiver based on the argument
824
+ return method_type.with(
825
+ type: method_type.type.with(
826
+ return_type: AST::Types::Logic::ReceiverIsArg.instance()
827
+ )
828
+ )
829
+ end
797
830
  when :<, :<=
798
831
  case defined_in
799
832
  when RBS::BuiltinNames::Module.name
@@ -32,14 +32,22 @@ module Steep
32
32
  method_defs.map do |defn|
33
33
  type_name = defn.implemented_in || defn.defined_in
34
34
 
35
- if name == :new && defn.member.is_a?(RBS::AST::Members::MethodDefinition) && defn.member.name == :initialize
35
+ case
36
+ when name == :new && defn.member.is_a?(RBS::AST::Members::MethodDefinition) && defn.member.name == :initialize
37
+ method_name = SingletonMethodName.new(type_name: type_name, method_name: name)
38
+ when name == :new && defn.member.is_a?(RBS::AST::Ruby::Members::DefMember) && defn.member.name == :initialize
36
39
  method_name = SingletonMethodName.new(type_name: type_name, method_name: name)
37
40
  else
38
41
  method_name =
39
- if defn.member.kind == :singleton
40
- SingletonMethodName.new(type_name: defn.defined_in, method_name: name)
41
- else
42
- # Call the `self?` method an instance method, because the definition is done with instance method definition, not with singleton method
42
+ case defn.member
43
+ when RBS::AST::Members::Base
44
+ if defn.member.kind == :singleton
45
+ SingletonMethodName.new(type_name: defn.defined_in, method_name: name)
46
+ else
47
+ # Call the `self?` method an instance method, because the definition is done with instance method definition, not with singleton method
48
+ InstanceMethodName.new(type_name: defn.defined_in, method_name: name)
49
+ end
50
+ when RBS::AST::Ruby::Members::DefMember, RBS::AST::Ruby::Members::AttributeMember
43
51
  InstanceMethodName.new(type_name: defn.defined_in, method_name: name)
44
52
  end
45
53
  end