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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +87 -0
- data/CLAUDE.md +114 -0
- data/README.md +1 -1
- data/Rakefile +15 -3
- data/Steepfile +13 -13
- data/lib/steep/annotation_parser.rb +5 -1
- data/lib/steep/annotations_helper.rb +12 -2
- data/lib/steep/ast/node/type_application.rb +22 -16
- data/lib/steep/ast/node/type_assertion.rb +7 -4
- data/lib/steep/ast/types/factory.rb +3 -2
- data/lib/steep/cli.rb +246 -2
- data/lib/steep/daemon/configuration.rb +19 -0
- data/lib/steep/daemon/server.rb +476 -0
- data/lib/steep/daemon.rb +201 -0
- data/lib/steep/diagnostic/ruby.rb +50 -8
- data/lib/steep/diagnostic/signature.rb +31 -8
- data/lib/steep/drivers/check.rb +301 -140
- data/lib/steep/drivers/print_project.rb +9 -10
- data/lib/steep/drivers/query.rb +102 -0
- data/lib/steep/drivers/start_server.rb +19 -0
- data/lib/steep/drivers/stop_server.rb +20 -0
- data/lib/steep/drivers/watch.rb +2 -2
- data/lib/steep/index/rbs_index.rb +38 -13
- data/lib/steep/index/signature_symbol_provider.rb +24 -3
- data/lib/steep/interface/builder.rb +48 -15
- data/lib/steep/interface/shape.rb +13 -5
- data/lib/steep/locator.rb +377 -0
- data/lib/steep/project/dsl.rb +26 -5
- data/lib/steep/project/group.rb +8 -2
- data/lib/steep/project/target.rb +16 -2
- data/lib/steep/project.rb +21 -2
- data/lib/steep/server/base_worker.rb +2 -2
- data/lib/steep/server/change_buffer.rb +2 -1
- data/lib/steep/server/custom_methods.rb +12 -0
- data/lib/steep/server/inline_source_change_detector.rb +94 -0
- data/lib/steep/server/interaction_worker.rb +51 -74
- data/lib/steep/server/lsp_formatter.rb +48 -12
- data/lib/steep/server/master.rb +100 -18
- data/lib/steep/server/target_group_files.rb +124 -151
- data/lib/steep/server/type_check_controller.rb +276 -123
- data/lib/steep/server/type_check_worker.rb +104 -3
- data/lib/steep/services/completion_provider/rbs.rb +74 -0
- data/lib/steep/services/completion_provider/ruby.rb +652 -0
- data/lib/steep/services/completion_provider/type_name.rb +243 -0
- data/lib/steep/services/completion_provider.rb +39 -662
- data/lib/steep/services/content_change.rb +14 -1
- data/lib/steep/services/file_loader.rb +4 -2
- data/lib/steep/services/goto_service.rb +271 -68
- data/lib/steep/services/hover_provider/content.rb +67 -0
- data/lib/steep/services/hover_provider/rbs.rb +8 -9
- data/lib/steep/services/hover_provider/ruby.rb +123 -64
- data/lib/steep/services/hover_provider/singleton_methods.rb +4 -0
- data/lib/steep/services/signature_service.rb +129 -54
- data/lib/steep/services/type_check_service.rb +72 -27
- data/lib/steep/signature/validator.rb +30 -18
- data/lib/steep/source/ignore_ranges.rb +14 -4
- data/lib/steep/source.rb +16 -2
- data/lib/steep/tagged_logging.rb +39 -0
- data/lib/steep/type_construction.rb +94 -21
- data/lib/steep/type_inference/block_params.rb +7 -7
- data/lib/steep/type_inference/context.rb +4 -2
- data/lib/steep/type_inference/logic_type_interpreter.rb +21 -3
- data/lib/steep/type_inference/method_call.rb +4 -0
- data/lib/steep/type_inference/type_env.rb +1 -1
- data/lib/steep/typing.rb +0 -2
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +42 -32
- data/manual/ruby-diagnostics.md +67 -0
- data/sample/Steepfile +1 -0
- data/sample/lib/conference.rb +1 -0
- data/sample/lib/deprecated.rb +6 -0
- data/sample/lib/inline.rb +43 -0
- data/sample/sig/generics.rbs +3 -0
- data/steep.gemspec +4 -5
- metadata +26 -26
- 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
|
data/lib/steep/drivers/watch.rb
CHANGED
|
@@ -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.
|
|
294
|
-
index.add_type_declaration(name,
|
|
307
|
+
decl.each_decl do |decl|
|
|
308
|
+
index.add_type_declaration(name, decl)
|
|
295
309
|
|
|
296
|
-
case
|
|
310
|
+
case decl
|
|
297
311
|
when RBS::AST::Declarations::Class
|
|
298
|
-
if super_class =
|
|
299
|
-
index.add_type_reference(super_class.name,
|
|
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:
|
|
315
|
+
type_reference(type, from: decl)
|
|
302
316
|
end
|
|
303
317
|
end
|
|
304
318
|
when RBS::AST::Declarations::Module
|
|
305
|
-
|
|
306
|
-
index.add_type_reference(self_type.name,
|
|
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:
|
|
322
|
+
type_reference(type, from: decl)
|
|
309
323
|
end
|
|
310
324
|
end
|
|
311
325
|
end
|
|
312
326
|
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
|
|
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
|
-
|
|
154
|
-
next unless assigned?(target, Pathname(
|
|
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:
|
|
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.
|
|
243
|
-
entry.
|
|
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
|
|
412
|
-
|
|
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
|
|
416
|
-
when
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
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::
|
|
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
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|