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

Sign up to get free protection for your applications and to get access to all the features.
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