steep 1.10.0 → 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 +84 -1
  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
@@ -1,205 +1,178 @@
1
1
  module Steep
2
2
  module Server
3
3
  class TargetGroupFiles
4
- attr_reader :project
5
-
6
- attr_reader :source_paths, :signature_paths
7
-
8
- attr_reader :library_paths
9
-
10
- def initialize(project)
11
- @project = project
12
- @source_paths = {}
13
- @signature_paths = {}
14
- @library_paths = {}
15
- end
4
+ class PathEnumerator
5
+ def initialize
6
+ @paths = {}
7
+ end
16
8
 
17
- def add_path(path)
18
- if target_group = project.group_for_signature_path(path)
19
- signature_paths[path] = target_group
20
- return true
9
+ def empty?
10
+ @paths.empty?
21
11
  end
22
- if target_group = project.group_for_source_path(path)
23
- source_paths[path] = target_group
24
- return true
12
+
13
+ def paths
14
+ @paths.keys
25
15
  end
26
16
 
27
- false
28
- end
17
+ def registered_path?(path)
18
+ @paths.key?(path)
19
+ end
29
20
 
30
- def add_library_path(target, *paths)
31
- (library_paths[target.name] ||= Set[]).merge(paths)
32
- end
21
+ def []=(path, target_group)
22
+ @paths[path] = target_group
23
+ end
33
24
 
34
- def each_library_path(target, &block)
35
- if block
36
- library_paths.fetch(target.name).each(&block)
37
- else
38
- enum_for(_ = __method__, target)
25
+ def [](path)
26
+ @paths[path]
39
27
  end
40
- end
41
28
 
42
- def library_path?(path)
43
- library_paths.each_value.any? { _1.include?(path) }
44
- end
29
+ def each(&block)
30
+ if block
31
+ @paths.each do |path, target_group|
32
+ target = target_of(target_group)
33
+ group = group_of(target_group)
45
34
 
46
- def signature_path_target(path)
47
- case target_group = signature_paths.fetch(path, nil)
48
- when Project::Target
49
- target_group
50
- when Project::Group
51
- target_group.target
35
+ yield [path, target, group]
36
+ end
37
+ else
38
+ enum_for(_ = __method__)
39
+ end
52
40
  end
53
- end
54
41
 
55
- def source_path_target(path)
56
- case target_group = source_paths.fetch(path, nil)
57
- when Project::Target
58
- target_group
59
- when Project::Group
60
- target_group.target
42
+ def target(path)
43
+ if target_group = @paths.fetch(path, nil)
44
+ target_of(target_group)
45
+ end
61
46
  end
62
- end
63
47
 
64
- def target_group_for_source_path(path)
65
- ret = source_paths.fetch(path, nil)
66
- case ret
67
- when Project::Group
68
- [ret.target, ret]
69
- when Project::Target
70
- [ret, nil]
71
- end
72
- end
48
+ def target_group(path)
49
+ if target_group = @paths.fetch(path, nil)
50
+ target = target_of(target_group)
51
+ group = group_of(target_group)
73
52
 
74
- def target_group_for_signature_path(path)
75
- ret = signature_paths.fetch(path, nil)
76
- case ret
77
- when Project::Group
78
- [ret.target, ret]
79
- when Project::Target
80
- [ret, nil]
53
+ [target, group]
54
+ end
81
55
  end
82
- end
83
56
 
84
- def each_group_signature_path(target, no_group = false, &block)
85
- if block
86
- signature_paths.each_key do |path|
87
- t, g = target_group_for_signature_path(path)
88
-
89
- if target.is_a?(Project::Target)
90
- if no_group
91
- yield path if t == target && g == nil
92
- else
93
- yield path if t == target
94
- end
95
- else
96
- yield path if g == target
57
+ def each_project_path(except: nil, &block)
58
+ if block
59
+ @paths.each_key do |path|
60
+ target, group = target_group(path) || raise
61
+
62
+ next if target == except
63
+
64
+ yield [path, target, group, group || target]
97
65
  end
66
+ else
67
+ enum_for(_ = __method__, except: except)
98
68
  end
99
- else
100
- enum_for(_ = __method__, target, no_group)
101
69
  end
102
- end
103
70
 
104
- def each_target_signature_path(target, group, &block)
105
- raise unless group.target == target if group
71
+ def each_target_path(target, except: nil, &block)
72
+ if block
73
+ @paths.each_key do |path|
74
+ t, g = target_group(path) || raise
106
75
 
107
- if block
108
- signature_paths.each_key do |path|
109
- t, g = target_group_for_signature_path(path)
76
+ if except
77
+ next if g == except
78
+ end
110
79
 
111
- next unless target == t
112
- next if group && group == g
80
+ next unless t == target
113
81
 
114
- yield path
82
+ yield [path, t, g, g || t]
83
+ end
84
+ else
85
+ enum_for(_ = __method__, target, except: except)
115
86
  end
116
- else
117
- enum_for(_ = __method__, target, group)
118
87
  end
119
- end
120
88
 
121
- def each_project_signature_path(target, &block)
122
- if block
123
- signature_paths.each do |path, target_group|
124
- t =
125
- case target_group
126
- when Project::Target
127
- target_group
128
- when Project::Group
129
- target_group.target
89
+ def each_group_path(target_group, include_sub_groups: false, &block)
90
+ if block
91
+ if include_sub_groups
92
+ target_group.is_a?(Project::Target) or raise "target_group must be a target if `include_sub_groups:` is given. (#{target_group.name})"
93
+ each_target_path(target_group, &block)
94
+ else
95
+ @paths.each do |path, tg|
96
+ if tg == target_group
97
+ t, g = target_group(path) || raise
98
+ yield [path, t, g, g || t]
99
+ end
130
100
  end
131
-
132
- if target
133
- next if t.unreferenced
134
- next if t == target
135
101
  end
102
+ else
103
+ enum_for(_ = __method__, target_group, include_sub_groups: include_sub_groups)
104
+ end
105
+ end
136
106
 
137
- yield path
107
+ def target_of(target_group)
108
+ case target_group
109
+ when Project::Target
110
+ target_group
111
+ when Project::Group
112
+ target_group.target
138
113
  end
139
- else
140
- enum_for(_ = __method__, target)
141
114
  end
142
- end
143
115
 
144
- def each_group_source_path(target, no_group = false, &block)
145
- if block
146
- source_paths.each_key do |path|
147
- t, g = target_group_for_source_path(path)
148
-
149
- if target.is_a?(Project::Target)
150
- if no_group
151
- yield path if t == target && g == nil
152
- else
153
- yield path if t == target
154
- end
155
- else
156
- yield path if g == target
157
- end
116
+ def group_of(target_group)
117
+ case target_group
118
+ when Project::Group
119
+ target_group
158
120
  end
159
- else
160
- enum_for(_ = __method__, target, no_group)
161
121
  end
162
122
  end
163
123
 
164
- def each_target_source_path(target, group, &block)
165
- raise unless group.target == target if group
124
+ attr_reader :project
166
125
 
167
- if block
168
- source_paths.each_key do |path|
169
- t, g = target_group_for_source_path(path)
126
+ attr_reader :source_paths, :signature_paths, :inline_paths
170
127
 
171
- next unless target == t
172
- next if group && group == g
128
+ attr_reader :library_paths
173
129
 
174
- yield path
175
- end
176
- else
177
- enum_for(_ = __method__, target, group)
130
+ def initialize(project)
131
+ @project = project
132
+ @source_paths = PathEnumerator.new
133
+ @signature_paths = PathEnumerator.new
134
+ @inline_paths = PathEnumerator.new
135
+ @library_paths = {}
136
+ end
137
+
138
+ def add_path(path)
139
+ if target_group = project.group_for_signature_path(path)
140
+ signature_paths[path] = target_group
141
+ return true
178
142
  end
143
+ if target_group = project.group_for_inline_source_path(path)
144
+ inline_paths[path] = target_group
145
+ return true
146
+ end
147
+ if target_group = project.group_for_source_path(path)
148
+ source_paths[path] = target_group
149
+ return true
150
+ end
151
+
152
+ false
179
153
  end
180
154
 
181
- def each_project_source_path(target, &block)
182
- if block
183
- source_paths.each do |path, target_group|
184
- t =
185
- case target_group
186
- when Project::Target
187
- target_group
188
- when Project::Group
189
- target_group.target
190
- end
155
+ def registered_path?(path)
156
+ source_paths.registered_path?(path) ||
157
+ signature_paths.registered_path?(path) ||
158
+ inline_paths.registered_path?(path)
159
+ end
191
160
 
192
- if target
193
- next if t.unreferenced
194
- next if t == target
195
- end
161
+ def add_library_path(target, *paths)
162
+ (library_paths[target.name] ||= Set[]).merge(paths)
163
+ end
196
164
 
197
- yield path
198
- end
165
+ def each_library_path(target, &block)
166
+ if block
167
+ library_paths.fetch(target.name).each(&block)
199
168
  else
200
169
  enum_for(_ = __method__, target)
201
170
  end
202
171
  end
172
+
173
+ def library_path?(path)
174
+ library_paths.each_value.any? { _1.include?(path) }
175
+ end
203
176
  end
204
177
  end
205
178
  end