steep 1.4.0.dev.1 → 1.4.0.dev.3

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -2
  3. data/Gemfile +2 -2
  4. data/Gemfile.lock +13 -15
  5. data/Gemfile.steep +1 -2
  6. data/Gemfile.steep.lock +20 -18
  7. data/README.md +7 -1
  8. data/Steepfile +16 -3
  9. data/bin/rbs +0 -1
  10. data/guides/README.md +5 -0
  11. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +143 -0
  12. data/guides/src/getting-started/getting-started.md +164 -0
  13. data/guides/src/nil-optional/nil-optional.md +195 -0
  14. data/lib/steep/annotation_parser.rb +40 -20
  15. data/lib/steep/ast/types/factory.rb +56 -10
  16. data/lib/steep/ast/types/name.rb +10 -0
  17. data/lib/steep/diagnostic/ruby.rb +80 -5
  18. data/lib/steep/diagnostic/signature.rb +40 -0
  19. data/lib/steep/drivers/check.rb +4 -4
  20. data/lib/steep/index/rbs_index.rb +12 -3
  21. data/lib/steep/index/signature_symbol_provider.rb +1 -1
  22. data/lib/steep/interface/block.rb +10 -0
  23. data/lib/steep/module_helper.rb +13 -11
  24. data/lib/steep/path_helper.rb +4 -0
  25. data/lib/steep/project/target.rb +1 -3
  26. data/lib/steep/server/interaction_worker.rb +102 -72
  27. data/lib/steep/server/lsp_formatter.rb +14 -5
  28. data/lib/steep/services/completion_provider.rb +10 -12
  29. data/lib/steep/services/goto_service.rb +15 -14
  30. data/lib/steep/services/hover_provider/rbs.rb +29 -9
  31. data/lib/steep/services/hover_provider/ruby.rb +16 -10
  32. data/lib/steep/services/signature_service.rb +36 -39
  33. data/lib/steep/services/type_name_completion.rb +157 -0
  34. data/lib/steep/signature/validator.rb +28 -6
  35. data/lib/steep/source.rb +1 -0
  36. data/lib/steep/subtyping/check.rb +1 -1
  37. data/lib/steep/type_construction.rb +414 -239
  38. data/lib/steep/type_inference/block_params.rb +13 -0
  39. data/lib/steep/type_inference/constant_env.rb +7 -3
  40. data/lib/steep/type_inference/context.rb +3 -3
  41. data/lib/steep/type_inference/method_params.rb +42 -16
  42. data/lib/steep/type_inference/send_args.rb +79 -50
  43. data/lib/steep/type_inference/type_env.rb +7 -1
  44. data/lib/steep/version.rb +1 -1
  45. data/lib/steep.rb +1 -0
  46. data/rbs_collection.steep.lock.yaml +9 -41
  47. data/rbs_collection.steep.yaml +11 -8
  48. data/sample/lib/conference.rb +22 -0
  49. data/sample/sig/conference.rbs +28 -0
  50. data/sig/shims/language-server_protocol.rbs +12 -0
  51. data/sig/shims/parser/nodes.rbs +37 -0
  52. data/sig/shims/parser.rbs +1 -0
  53. data/sig/shims/string.rbs +4 -0
  54. data/sig/steep/annotation_parser.rbs +3 -2
  55. data/sig/steep/ast/annotation/collection.rbs +1 -1
  56. data/sig/steep/ast/types/factory.rbs +12 -8
  57. data/sig/steep/ast/types/name.rbs +4 -0
  58. data/sig/steep/diagnostic/lsp_formatter.rbs +1 -1
  59. data/sig/steep/diagnostic/ruby.rbs +38 -2
  60. data/sig/steep/diagnostic/signature.rbs +18 -14
  61. data/sig/steep/drivers/check.rbs +1 -1
  62. data/sig/steep/drivers/checkfile.rbs +1 -1
  63. data/sig/steep/drivers/diagnostic_printer.rbs +1 -1
  64. data/sig/steep/drivers/watch.rbs +1 -1
  65. data/sig/steep/index/rbs_index.rbs +6 -2
  66. data/sig/steep/index/signature_symbol_provider.rbs +1 -1
  67. data/sig/steep/interface/block.rbs +2 -0
  68. data/sig/steep/interface/builder.rbs +5 -3
  69. data/sig/steep/interface/method_type.rbs +5 -3
  70. data/sig/steep/module_helper.rbs +9 -0
  71. data/sig/steep/path_helper.rbs +3 -1
  72. data/sig/steep/project/target.rbs +7 -7
  73. data/sig/steep/server/base_worker.rbs +1 -1
  74. data/sig/steep/server/interaction_worker.rbs +46 -17
  75. data/sig/steep/server/lsp_formatter.rbs +4 -2
  76. data/sig/steep/server/master.rbs +1 -1
  77. data/sig/steep/server/type_check_worker.rbs +7 -5
  78. data/sig/steep/server/worker_process.rbs +6 -4
  79. data/sig/steep/services/completion_provider.rbs +8 -0
  80. data/sig/steep/services/hover_provider/rbs.rbs +6 -4
  81. data/sig/steep/services/hover_provider/ruby.rbs +8 -4
  82. data/sig/steep/services/signature_service.rbs +27 -3
  83. data/sig/steep/services/type_name_completion.rbs +122 -0
  84. data/sig/steep/signature/validator.rbs +9 -5
  85. data/sig/steep/type_construction.rbs +100 -31
  86. data/sig/steep/type_inference/block_params.rbs +4 -0
  87. data/sig/steep/type_inference/constant_env.rbs +2 -0
  88. data/sig/steep/type_inference/context.rbs +70 -22
  89. data/sig/steep/type_inference/method_params.rbs +43 -24
  90. data/sig/steep/type_inference/multiple_assignment.rbs +1 -1
  91. data/sig/steep/type_inference/send_args.rbs +13 -3
  92. data/sig/steep/typing.rbs +7 -2
  93. data/smoke/diagnostics/test_expectations.yml +1 -0
  94. data/smoke/regexp/a.rb +2 -2
  95. data/steep.gemspec +0 -1
  96. metadata +11 -17
@@ -69,6 +69,16 @@ module Steep
69
69
  )
70
70
  end
71
71
 
72
+ def to_proc_type
73
+ proc = AST::Types::Proc.new(type: type, self_type: self_type, block: nil)
74
+
75
+ if optional?
76
+ AST::Types::Union.build(types: [proc, AST::Builtin.nil_type])
77
+ else
78
+ proc
79
+ end
80
+ end
81
+
72
82
  def +(other)
73
83
  optional = self.optional? || other.optional?
74
84
  type = Function.new(
@@ -1,21 +1,23 @@
1
1
  module Steep
2
2
  module ModuleHelper
3
3
  def module_name_from_node(parent_node, constant_name)
4
- namespace = namespace_from_node(parent_node) or return
5
- name = constant_name
6
- RBS::TypeName.new(name: name, namespace: namespace)
4
+ if namespace = namespace_from_node(parent_node)
5
+ RBS::TypeName.new(name: constant_name, namespace: namespace)
6
+ end
7
7
  end
8
8
 
9
9
  def namespace_from_node(node)
10
- case node&.type
11
- when nil
12
- RBS::Namespace.empty
13
- when :cbase
14
- RBS::Namespace.root
15
- when :const
16
- namespace_from_node(node.children[0])&.yield_self do |parent|
17
- parent.append(node.children[1])
10
+ if node
11
+ case node.type
12
+ when :cbase
13
+ RBS::Namespace.root
14
+ when :const
15
+ if parent = namespace_from_node(node.children[0])
16
+ parent.append(node.children[1])
17
+ end
18
18
  end
19
+ else
20
+ RBS::Namespace.empty
19
21
  end
20
22
  end
21
23
  end
@@ -11,6 +11,10 @@ module Steep
11
11
  end
12
12
  end
13
13
 
14
+ def to_pathname!(uri, dosish: Gem.win_platform?)
15
+ to_pathname(uri, dosish: dosish) or raise "Cannot translate a URI to pathname: #{uri}"
16
+ end
17
+
14
18
  def to_uri(path, dosish: Gem.win_platform?)
15
19
  str_path = path.to_s
16
20
  if dosish
@@ -14,9 +14,6 @@ module Steep
14
14
  @source_pattern = source_pattern
15
15
  @signature_pattern = signature_pattern
16
16
  @code_diagnostics_config = code_diagnostics_config
17
-
18
- @source_files = {}
19
- @signature_files = {}
20
17
  end
21
18
 
22
19
  def possible_source_file?(path)
@@ -55,6 +52,7 @@ module Steep
55
52
 
56
53
  options.libraries.each do |lib|
57
54
  name, version = lib.split(/:/, 2)
55
+ name or raise
58
56
  loader.add(library: name, version: version)
59
57
  end
60
58
  loader.add_collection(options.collection_lock) if options.collection_lock
@@ -3,9 +3,9 @@ module Steep
3
3
  class InteractionWorker < BaseWorker
4
4
  include ChangeBuffer
5
5
 
6
- ApplyChangeJob = Class.new()
7
- HoverJob = Struct.new(:id, :path, :line, :column, keyword_init: true)
8
- CompletionJob = Struct.new(:id, :path, :line, :column, :trigger, keyword_init: true)
6
+ ApplyChangeJob = _ = Class.new()
7
+ HoverJob = _ = Struct.new(:id, :path, :line, :column, keyword_init: true)
8
+ CompletionJob = _ = Struct.new(:id, :path, :line, :column, :trigger, keyword_init: true)
9
9
 
10
10
  LSP = LanguageServer::Protocol
11
11
 
@@ -53,7 +53,7 @@ module Steep
53
53
  when "textDocument/hover"
54
54
  id = request[:id]
55
55
 
56
- path = project.relative_path(Steep::PathHelper.to_pathname(request[:params][:textDocument][:uri]))
56
+ path = project.relative_path(Steep::PathHelper.to_pathname!(request[:params][:textDocument][:uri]))
57
57
  line = request[:params][:position][:line]+1
58
58
  column = request[:params][:position][:character]
59
59
 
@@ -63,7 +63,8 @@ module Steep
63
63
  id = request[:id]
64
64
 
65
65
  params = request[:params]
66
- path = project.relative_path(Steep::PathHelper.to_pathname(params[:textDocument][:uri]))
66
+
67
+ path = project.relative_path(Steep::PathHelper.to_pathname!(params[:textDocument][:uri]))
67
68
  line, column = params[:position].yield_self {|hash| [hash[:line]+1, hash[:character]] }
68
69
  trigger = params.dig(:context, :triggerCharacter)
69
70
 
@@ -104,6 +105,7 @@ module Steep
104
105
  Steep.logger.tagged("#response_to_completion") do
105
106
  Steep.measure "Generating response" do
106
107
  Steep.logger.info "path: #{job.path}, line: #{job.line}, column: #{job.column}, trigger: #{job.trigger}"
108
+
107
109
  case
108
110
  when target = project.target_for_source_path(job.path)
109
111
  file = service.source_files[job.path] or return
@@ -127,53 +129,78 @@ module Steep
127
129
  items: completion_items
128
130
  )
129
131
  when (targets = project.targets_for_path(job.path)).is_a?(Array)
130
- target = targets[0] or return
131
- sig_service = service.signature_services[target.name]
132
+ target = targets[0] or raise
133
+ sig_service = service.signature_services[target.name] or raise
132
134
  relative_path = job.path
133
- buffer = RBS::Buffer.new(name: relative_path, content: sig_service.files[relative_path].content)
134
- pos = buffer.loc_to_pos([job.line, job.column])
135
- prefix = buffer.content[0...pos].reverse[/\A[\w\d]*/].reverse
135
+
136
+ context = nil #: RBS::Resolver::context
136
137
 
137
138
  case sig_service.status
138
139
  when Steep::Services::SignatureService::SyntaxErrorStatus, Steep::Services::SignatureService::AncestorErrorStatus
139
- return
140
- end
141
-
142
- decls = sig_service.files[relative_path].decls
143
- locator = RBS::Locator.new(decls: decls)
144
-
145
- _hd, tail = locator.find2(line: job.line, column: job.column)
146
140
 
147
- namespace = []
148
- tail.each do |t|
149
- case t
150
- when RBS::AST::Declarations::Module, RBS::AST::Declarations::Class
151
- namespace << t.name.to_namespace
141
+ if buffer = sig_service.latest_env.buffers.find {|buf| Pathname(buf.name) == Pathname(relative_path) }
142
+ dirs = sig_service.latest_env.signatures[buffer][0]
143
+ else
144
+ dirs = [] #: Array[RBS::AST::Directives::t]
145
+ end
146
+ else
147
+ signature = sig_service.files[relative_path].signature
148
+ signature.is_a?(Array) or raise
149
+ buffer, dirs, decls = signature
150
+
151
+ locator = RBS::Locator.new(buffer: buffer, dirs: dirs, decls: decls)
152
+
153
+ _hd, tail = locator.find2(line: job.line, column: job.column)
154
+ tail ||= []
155
+
156
+ tail.reverse_each do |t|
157
+ case t
158
+ when RBS::AST::Declarations::Module, RBS::AST::Declarations::Class
159
+ if (last_type_name = context&.[](1)).is_a?(RBS::TypeName)
160
+ context = [context, last_type_name + t.name]
161
+ else
162
+ context = [context, t.name.absolute!]
163
+ end
164
+ end
152
165
  end
153
166
  end
154
- context = []
155
167
 
156
- namespace.each do |ns|
157
- context.map! { |n| ns + n }
158
- context << ns
168
+ buffer = RBS::Buffer.new(name: relative_path, content: sig_service.files[relative_path].content)
169
+ prefix = Services::TypeNameCompletion::Prefix.parse(buffer, line: job.line, column: job.column)
170
+
171
+ completion = Services::TypeNameCompletion.new(env: sig_service.latest_env, context: context, dirs: dirs)
172
+ type_names = completion.find_type_names(prefix)
173
+ prefix_size = prefix ? prefix.size : 0
174
+
175
+ completion_items = type_names.map {|type_name|
176
+ absolute_name, relative_name = completion.resolve_name_in_context(type_name)
177
+
178
+ format_completion_item_for_rbs(sig_service, absolute_name, job, relative_name.to_s, prefix_size)
179
+ }
180
+
181
+ ["untyped", "void", "bool", "class", "module", "instance", "nil"].each do |name|
182
+ completion_items << LanguageServer::Protocol::Interface::CompletionItem.new(
183
+ label: name,
184
+ detail: "(builtin type)",
185
+ text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
186
+ range: LanguageServer::Protocol::Interface::Range.new(
187
+ start: LanguageServer::Protocol::Interface::Position.new(
188
+ line: job.line - 1,
189
+ character: job.column - prefix_size
190
+ ),
191
+ end: LanguageServer::Protocol::Interface::Position.new(
192
+ line: job.line - 1,
193
+ character: job.column
194
+ )
195
+ ),
196
+ new_text: name
197
+ ),
198
+ kind: LSP::Constant::CompletionItemKind::KEYWORD,
199
+ filter_text: name,
200
+ sort_text: "zz__#{name}"
201
+ )
159
202
  end
160
203
 
161
- context.map!(&:absolute!)
162
-
163
- class_items = sig_service.latest_env.class_decls.keys.map { |type_name|
164
- format_completion_item_for_rbs(sig_service, type_name, context, job, prefix)
165
- }.compact
166
-
167
- alias_items = sig_service.latest_env.alias_decls.keys.map { |type_name|
168
- format_completion_item_for_rbs(sig_service, type_name, context, job, prefix)
169
- }.compact
170
-
171
- interface_items = sig_service.latest_env.interface_decls.keys.map {|type_name|
172
- format_completion_item_for_rbs(sig_service, type_name, context, job, prefix)
173
- }.compact
174
-
175
- completion_items = class_items + alias_items + interface_items
176
-
177
204
  LSP::Interface::CompletionList.new(
178
205
  is_incomplete: false,
179
206
  items: completion_items
@@ -183,11 +210,11 @@ module Steep
183
210
  end
184
211
  end
185
212
 
186
- def format_completion_item_for_rbs(sig_service, type_name, context, job, prefix)
213
+ def format_completion_item_for_rbs(sig_service, type_name, job, complete_text, prefix_size)
187
214
  range = LanguageServer::Protocol::Interface::Range.new(
188
215
  start: LanguageServer::Protocol::Interface::Position.new(
189
216
  line: job.line - 1,
190
- character: job.column - prefix.size
217
+ character: job.column - prefix_size
191
218
  ),
192
219
  end: LanguageServer::Protocol::Interface::Position.new(
193
220
  line: job.line - 1,
@@ -195,50 +222,64 @@ module Steep
195
222
  )
196
223
  )
197
224
 
198
- name = relative_name_in_context(type_name, context).to_s
199
-
200
- return unless name.start_with?(prefix)
201
-
202
225
  case type_name.kind
203
226
  when :class
204
- class_decl = sig_service.latest_env.class_decls[type_name]&.decls[0]&.decl or raise
227
+ env = sig_service.latest_env #: RBS::Environment
228
+ class_entry = env.module_class_entry(type_name) or raise
229
+
230
+ comment =
231
+ case class_entry
232
+ when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
233
+ class_entry.decls.flat_map {|decl| [decl.decl.comment] }.first
234
+ when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
235
+ class_entry.decl.comment
236
+ end
205
237
 
206
238
  LanguageServer::Protocol::Interface::CompletionItem.new(
207
- label: "#{name}",
208
- documentation: format_comment(class_decl.comment),
239
+ label: complete_text,
240
+ detail: type_name.to_s,
241
+ documentation: format_comment(comment),
209
242
  text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
210
243
  range: range,
211
- new_text: name
244
+ new_text: complete_text
212
245
  ),
213
246
  kind: LSP::Constant::CompletionItemKind::CLASS,
214
- insert_text_format: LSP::Constant::InsertTextFormat::SNIPPET
215
-
247
+ insert_text_format: LSP::Constant::InsertTextFormat::SNIPPET,
248
+ sort_text: complete_text,
249
+ filter_text: complete_text
216
250
  )
217
251
  when :alias
218
- alias_decl = sig_service.latest_env.alias_decls[type_name]&.decl or raise
252
+ alias_decl = sig_service.latest_env.type_alias_decls[type_name]&.decl or raise
253
+
219
254
  LanguageServer::Protocol::Interface::CompletionItem.new(
220
- label: "#{name}",
255
+ label: complete_text,
256
+ detail: type_name.to_s,
221
257
  text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
222
258
  range: range,
223
- new_text: name
259
+ new_text: complete_text
224
260
  ),
225
261
  documentation: format_comment(alias_decl.comment),
226
262
  # https://github.com/microsoft/vscode-languageserver-node/blob/6d78fc4d25719b231aba64a721a606f58b9e0a5f/client/src/common/client.ts#L624-L650
227
263
  kind: LSP::Constant::CompletionItemKind::FIELD,
228
- insert_text_format: LSP::Constant::InsertTextFormat::SNIPPET
264
+ insert_text_format: LSP::Constant::InsertTextFormat::SNIPPET,
265
+ sort_text: complete_text,
266
+ filter_text: complete_text
229
267
  )
230
268
  when :interface
231
269
  interface_decl = sig_service.latest_env.interface_decls[type_name]&.decl or raise
232
270
 
233
271
  LanguageServer::Protocol::Interface::CompletionItem.new(
234
- label: "#{name}",
272
+ label: complete_text,
273
+ detail: type_name.to_s,
235
274
  text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
236
275
  range: range,
237
- new_text: name
276
+ new_text: complete_text
238
277
  ),
239
278
  documentation: format_comment(interface_decl.comment),
240
279
  kind: LanguageServer::Protocol::Constant::CompletionItemKind::INTERFACE,
241
- insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET
280
+ insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET,
281
+ sort_text: complete_text,
282
+ filter_text: complete_text
242
283
  )
243
284
  end
244
285
  end
@@ -400,17 +441,6 @@ module Steep
400
441
 
401
442
  params.join(", ")
402
443
  end
403
-
404
- def relative_name_in_context(type_name, context)
405
- context.each do |namespace|
406
- if (type_name.to_s == namespace.to_type_name.to_s || type_name.namespace.to_s == "::")
407
- return RBS::TypeName.new(namespace: RBS::Namespace.empty, name: type_name.name)
408
- elsif type_name.to_s.start_with?(namespace.to_s)
409
- return TypeName(type_name.to_s.sub(namespace.to_type_name.to_s, '')).relative!
410
- end
411
- end
412
- type_name
413
- end
414
444
  end
415
445
  end
416
446
  end
@@ -110,19 +110,24 @@ EOM
110
110
  end
111
111
  when HoverProvider::Ruby::ConstantContent
112
112
  CommentBuilder.build do |builder|
113
- if decl = content.class_or_module?
113
+ case
114
+ when decl = content.class_decl
114
115
  builder << <<EOM
115
116
  ```rbs
116
117
  #{declaration_summary(decl.primary.decl)}
117
118
  ```
118
119
  EOM
119
- end
120
-
121
- if content.constant?
120
+ when decl = content.constant_decl
122
121
  builder << <<EOM
123
122
  ```rbs
124
123
  #{content.full_name}: #{content.type}
125
124
  ```
125
+ EOM
126
+ when decl = content.class_alias
127
+ builder << <<EOM
128
+ ```rbs
129
+ #{decl.is_a?(::RBS::Environment::ClassAliasEntry) ? "class" : "module"} #{decl.decl.new_name} = #{decl.decl.old_name}
130
+ ```
126
131
  EOM
127
132
  end
128
133
 
@@ -245,10 +250,14 @@ EOM
245
250
  " : #{decl.self_types.map {|s| name_and_args(s.name, s.args) }.join(", ")}"
246
251
  end
247
252
  "module #{name_and_params(decl.name, decl.type_params)}#{self_type}"
248
- when RBS::AST::Declarations::Alias
253
+ when RBS::AST::Declarations::TypeAlias
249
254
  "type #{decl.name} = #{decl.type}"
250
255
  when RBS::AST::Declarations::Interface
251
256
  "interface #{name_and_params(decl.name, decl.type_params)}"
257
+ when RBS::AST::Declarations::ClassAlias
258
+ "class #{decl.new_name} = #{decl.old_name}"
259
+ when RBS::AST::Declarations::ModuleAlias
260
+ "module #{decl.new_name} = #{decl.old_name}"
252
261
  end
253
262
  end
254
263
  end
@@ -16,25 +16,23 @@ module Steep
16
16
  # @implements ConstantItem
17
17
 
18
18
  def class?
19
- if decl = env.class_decls[full_name]
20
- decl.primary.decl.is_a?(RBS::AST::Declarations::Class)
21
- end
19
+ env.class_entry(full_name) ? true : false
22
20
  end
23
21
 
24
22
  def module?
25
- if decl = env.class_decls[full_name]
26
- decl.primary.decl.is_a?(RBS::AST::Declarations::Module)
27
- end
23
+ env.module_entry(full_name) ? true : false
28
24
  end
29
25
 
30
26
  def comments
31
- case
32
- when decl = env.class_decls[full_name]
33
- decl.decls.filter_map {|d| d.decl.comment }
34
- when comment = env.constant_decls[full_name]&.decl&.comment
35
- [comment]
27
+ case entry = env.constant_entry(full_name)
28
+ when RBS::Environment::ConstantEntry
29
+ [entry.decl.comment].compact
30
+ when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
31
+ entry.decls.filter_map {|d| d.decl.comment }
32
+ when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
33
+ [entry.decl.comment].compact
36
34
  else
37
- []
35
+ raise
38
36
  end
39
37
  end
40
38
  end
@@ -151,15 +151,15 @@ module Steep
151
151
  end
152
152
  end
153
153
  end
154
- when target_names = type_check.signature_file?(path)
154
+ when target_names = type_check.signature_file?(path) #: Array[Symbol]
155
155
  target_names.each do |target_name|
156
- signature_service = type_check.signature_services[target_name]
157
- decls = signature_service.latest_env.declarations.select do |decl|
158
- buffer_path = Pathname(decl.location.buffer.name)
159
- buffer_path == relative_path || buffer_path == path
160
- end
156
+ signature_service = type_check.signature_services[target_name] #: SignatureService
157
+
158
+ env = signature_service.latest_env
159
+ buffer = env.buffers.find {|buf| buf.name.to_s == relative_path.to_s } or raise
160
+ (dirs, decls = env.signatures[buffer]) or raise
161
161
 
162
- locator = RBS::Locator.new(decls: decls)
162
+ locator = RBS::Locator.new(buffer: buffer, dirs: dirs, decls: decls)
163
163
  last, nodes = locator.find2(line: line, column: column)
164
164
  case nodes[0]
165
165
  when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module
@@ -222,16 +222,17 @@ module Steep
222
222
 
223
223
  def constant_definition_in_rbs(name, locations:)
224
224
  type_check.signature_services.each_value do |signature|
225
- env = signature.latest_env
225
+ env = signature.latest_env #: RBS::Environment
226
226
 
227
- if entry = env.class_decls[name]
227
+ case entry = env.constant_entry(name)
228
+ when RBS::Environment::ConstantEntry
229
+ locations << entry.decl.location&.[](:name)
230
+ when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
228
231
  entry.decls.each do |d|
229
- locations << d.decl.location[:name]
232
+ locations << d.decl.location&.[](:name)
230
233
  end
231
- end
232
-
233
- if entry = env.constant_decls[name]
234
- locations << entry.decl.location[:name]
234
+ when RBS::Environment::ClassAliasEntry, RBS::Environment::ModuleAliasEntry
235
+ locations << entry.decl.location&.[](:new_name)
235
236
  end
236
237
  end
237
238
 
@@ -19,18 +19,17 @@ module Steep
19
19
  def content_for(target:, path:, line:, column:)
20
20
  service = self.service.signature_services[target.name]
21
21
 
22
- _, decls = service.latest_env.buffers_decls.find do |buffer, _|
23
- Pathname(buffer.name) == path
24
- end
25
-
26
- return if decls.nil?
22
+ env = service.latest_env
23
+ buffer = env.buffers.find {|buf| buf.name.to_s == path.to_s } or return
24
+ (dirs, decls = env.signatures[buffer]) or raise
27
25
 
28
- loc_key, path = ::RBS::Locator.new(decls: decls).find2(line: line, column: column) || return
26
+ locator = ::RBS::Locator.new(buffer: buffer, dirs: dirs, decls: decls)
27
+ loc_key, path = locator.find2(line: line, column: column) || return
29
28
  head, *_tail = path
30
29
 
31
30
  case head
32
31
  when ::RBS::Types::Alias
33
- alias_decl = service.latest_env.alias_decls[head.name]&.decl or raise
32
+ alias_decl = service.latest_env.type_alias_decls[head.name]&.decl or raise
34
33
 
35
34
  TypeAliasContent.new(
36
35
  location: head.location || raise,
@@ -38,9 +37,16 @@ module Steep
38
37
  )
39
38
  when ::RBS::Types::ClassInstance, ::RBS::Types::ClassSingleton
40
39
  if loc_key == :name
41
- env = service.latest_env
42
- class_decl = env.class_decls[head.name]&.decls&.[](0)&.decl or raise
43
40
  location = head.location&.[](:name) or raise
41
+
42
+ class_entry = service.latest_env.module_class_entry(head.name) or raise
43
+ case class_entry
44
+ when ::RBS::Environment::ClassEntry, ::RBS::Environment::ModuleEntry
45
+ class_decl = class_entry.primary.decl
46
+ when ::RBS::Environment::ClassAliasEntry, ::RBS::Environment::ModuleAliasEntry
47
+ class_decl = class_entry.decl
48
+ end
49
+
44
50
  ClassContent.new(
45
51
  location: location,
46
52
  decl: class_decl
@@ -55,6 +61,20 @@ module Steep
55
61
  location: location,
56
62
  decl: interface_decl
57
63
  )
64
+ when ::RBS::AST::Declarations::ClassAlias, ::RBS::AST::Declarations::ModuleAlias
65
+ if loc_key == :old_name
66
+ location = head.location&.[](:old_name) or raise
67
+
68
+ class_entry = service.latest_env.module_class_entry(head.old_name) or raise
69
+ case class_entry
70
+ when ::RBS::Environment::ClassEntry, ::RBS::Environment::ModuleEntry
71
+ class_decl = class_entry.primary.decl
72
+ when ::RBS::Environment::ClassAliasEntry, ::RBS::Environment::ModuleAliasEntry
73
+ class_decl = class_entry.decl
74
+ end
75
+
76
+ ClassContent.new(location: location, decl: class_decl)
77
+ end
58
78
  end
59
79
  end
60
80
  end
@@ -14,6 +14,8 @@ module Steep
14
14
  case
15
15
  when decl = class_decl
16
16
  decl.decls.map {|d| d.decl.comment }
17
+ when decl = class_alias
18
+ [decl.decl.comment]
17
19
  when decl = constant_decl
18
20
  [decl.decl.comment]
19
21
  else
@@ -22,27 +24,31 @@ module Steep
22
24
  end
23
25
 
24
26
  def class_decl
25
- if (decl = decl()).is_a?(::RBS::Environment::MultiEntry)
27
+ case decl
28
+ when ::RBS::Environment::ClassEntry, ::RBS::Environment::ModuleEntry
26
29
  decl
27
30
  end
28
31
  end
29
32
 
30
- def constant_decl
31
- if (decl = decl()).is_a?(::RBS::Environment::SingleEntry)
33
+ def class_alias
34
+ case decl
35
+ when ::RBS::Environment::ClassAliasEntry, ::RBS::Environment::ModuleAliasEntry
32
36
  decl
33
37
  end
34
38
  end
35
39
 
36
- def constant?
37
- if decl.is_a?(::RBS::Environment::SingleEntry)
40
+ def constant_decl
41
+ if decl.is_a?(::RBS::Environment::ConstantEntry)
38
42
  decl
39
43
  end
40
44
  end
41
45
 
46
+ def constant?
47
+ constant_decl ? true : false
48
+ end
49
+
42
50
  def class_or_module?
43
- if decl.is_a?(::RBS::Environment::MultiEntry)
44
- decl
45
- end
51
+ (class_decl || class_alias) ? true : false
46
52
  end
47
53
  end
48
54
 
@@ -169,13 +175,13 @@ module Steep
169
175
  const_name = typing.source_index.reference(constant_node: node)
170
176
 
171
177
  if const_name
172
- decl = context.env.class_decls[const_name] || context.env.constant_decls[const_name]
178
+ entry = context.env.constant_entry(const_name) or return
173
179
 
174
180
  return ConstantContent.new(
175
181
  location: node.location.name,
176
182
  full_name: const_name,
177
183
  type: type,
178
- decl: decl
184
+ decl: entry
179
185
  )
180
186
  end
181
187
  when :assertion