steep 1.2.1 → 1.3.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/Gemfile.lock +4 -4
  4. data/Gemfile.steep +1 -1
  5. data/Gemfile.steep.lock +13 -3
  6. data/Steepfile +0 -1
  7. data/lib/steep/annotation_parser.rb +34 -28
  8. data/lib/steep/ast/annotation.rb +16 -5
  9. data/lib/steep/ast/node/type_application.rb +74 -0
  10. data/lib/steep/ast/node/type_assertion.rb +56 -0
  11. data/lib/steep/ast/types/factory.rb +5 -1
  12. data/lib/steep/diagnostic/helper.rb +2 -1
  13. data/lib/steep/diagnostic/lsp_formatter.rb +3 -1
  14. data/lib/steep/diagnostic/ruby.rb +70 -5
  15. data/lib/steep/diagnostic/signature.rb +21 -8
  16. data/lib/steep/drivers/check.rb +1 -1
  17. data/lib/steep/drivers/checkfile.rb +1 -1
  18. data/lib/steep/drivers/langserver.rb +2 -2
  19. data/lib/steep/drivers/stats.rb +1 -1
  20. data/lib/steep/drivers/watch.rb +1 -1
  21. data/lib/steep/drivers/worker.rb +0 -1
  22. data/lib/steep/server/lsp_formatter.rb +13 -3
  23. data/lib/steep/server/master.rb +4 -1
  24. data/lib/steep/server/worker_process.rb +86 -14
  25. data/lib/steep/services/hover_provider/rbs.rb +7 -7
  26. data/lib/steep/services/hover_provider/ruby.rb +19 -4
  27. data/lib/steep/services/signature_service.rb +7 -4
  28. data/lib/steep/signature/validator.rb +36 -13
  29. data/lib/steep/source.rb +189 -71
  30. data/lib/steep/type_construction.rb +232 -126
  31. data/lib/steep/type_inference/logic_type_interpreter.rb +3 -1
  32. data/lib/steep/version.rb +1 -1
  33. data/lib/steep.rb +2 -0
  34. data/rbs_collection.steep.lock.yaml +27 -10
  35. data/rbs_collection.steep.yaml +0 -1
  36. data/sig/shims/exception.rbs +4 -0
  37. data/sig/shims/parser/comment.rbs +33 -0
  38. data/sig/shims/parser.rbs +30 -2
  39. data/sig/steep/annotation_parser.rbs +59 -0
  40. data/sig/steep/ast/annotation.rbs +21 -26
  41. data/sig/steep/ast/node/type_application.rbs +31 -0
  42. data/sig/steep/ast/node/type_assertion.rbs +26 -0
  43. data/sig/steep/ast/types/factory.rbs +0 -2
  44. data/sig/steep/diagnostic/helper.rbs +9 -3
  45. data/sig/steep/diagnostic/lsp_formatter.rbs +12 -8
  46. data/sig/steep/diagnostic/ruby.rbs +62 -8
  47. data/sig/steep/diagnostic/signature.rbs +118 -85
  48. data/sig/steep/drivers/worker.rbs +11 -13
  49. data/sig/steep/range_extension.rbs +7 -0
  50. data/sig/steep/server/lsp_formatter.rbs +14 -7
  51. data/sig/steep/server/worker_process.rbs +74 -12
  52. data/sig/steep/services/hover_provider/rbs.rbs +27 -7
  53. data/sig/steep/services/hover_provider/ruby.rbs +18 -4
  54. data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
  55. data/sig/steep/signature/validator.rbs +76 -0
  56. data/sig/steep/source.rbs +54 -30
  57. data/sig/steep/type_construction.rbs +85 -27
  58. data/sig/steep/type_inference/method_call.rbs +1 -1
  59. data/smoke/diagnostics-rbs/inherit-module.rbs +2 -0
  60. data/smoke/diagnostics-rbs/test_expectations.yml +12 -0
  61. data/steep.gemspec +1 -1
  62. metadata +16 -6
@@ -11,9 +11,7 @@ module Steep
11
11
  end
12
12
 
13
13
  def header_line
14
- StringIO.new.tap do |io|
15
- puts io
16
- end.string
14
+ raise
17
15
  end
18
16
 
19
17
  def detail_lines
@@ -25,7 +23,9 @@ module Steep
25
23
  end
26
24
 
27
25
  def path
28
- location.buffer.name
26
+ if location
27
+ Pathname(location.buffer.name)
28
+ end
29
29
  end
30
30
  end
31
31
 
@@ -166,7 +166,6 @@ module Steep
166
166
  class RecursiveAlias < Base
167
167
  attr_reader :class_name
168
168
  attr_reader :names
169
- attr_reader :location
170
169
 
171
170
  def initialize(class_name:, names:, location:)
172
171
  super(location: location)
@@ -284,7 +283,6 @@ module Steep
284
283
 
285
284
  class InstanceVariableTypeError < Base
286
285
  attr_reader :name
287
- attr_reader :variable
288
286
  attr_reader :var_type
289
287
  attr_reader :parent_type
290
288
 
@@ -318,7 +316,7 @@ module Steep
318
316
  private
319
317
 
320
318
  def mixin_name
321
- case member
319
+ case mem = member
322
320
  when RBS::AST::Members::Prepend
323
321
  "prepend"
324
322
  when RBS::AST::Members::Include
@@ -329,6 +327,19 @@ module Steep
329
327
  end
330
328
  end
331
329
 
330
+ class InheritModuleError < Base
331
+ attr_reader :super_class
332
+
333
+ def initialize(super_class)
334
+ super(location: super_class.location)
335
+ @super_class = super_class
336
+ end
337
+
338
+ def header_line
339
+ "Cannot inherit from a module `#{super_class.name}`"
340
+ end
341
+ end
342
+
332
343
  class UnexpectedError < Base
333
344
  attr_reader :message
334
345
 
@@ -427,7 +438,7 @@ module Steep
427
438
  Diagnostic::Signature::RecursiveAlias.new(
428
439
  class_name: error.type.name,
429
440
  names: error.defs.map(&:name),
430
- location: error.defs[0].original.location
441
+ location: error.defs[0].original&.location
431
442
  )
432
443
  when RBS::RecursiveAncestorError
433
444
  Diagnostic::Signature::RecursiveAncestor.new(
@@ -462,6 +473,8 @@ module Steep
462
473
  nonregular_type: factory.type(error.diagnostic.nonregular_type),
463
474
  location: error.location
464
475
  )
476
+ when RBS::InheritModuleError
477
+ Diagnostic::Signature::InheritModuleError.new(error.super_decl)
465
478
  else
466
479
  raise error
467
480
  end
@@ -36,7 +36,7 @@ module Steep
36
36
  server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
37
37
  server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
38
38
 
39
- typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(
39
+ typecheck_workers = Server::WorkerProcess.start_typecheck_workers(
40
40
  steepfile: project.steepfile_path,
41
41
  args: command_line_patterns,
42
42
  delay_shutdown: true,
@@ -101,7 +101,7 @@ module Steep
101
101
 
102
102
  Steep.logger.info { "Starting #{count} workers for #{files.size} files..." }
103
103
 
104
- typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(
104
+ typecheck_workers = Server::WorkerProcess.start_typecheck_workers(
105
105
  steepfile: project.steepfile_path,
106
106
  args: [],
107
107
  delay_shutdown: true,
@@ -35,8 +35,8 @@ module Steep
35
35
  def run
36
36
  @project = load_config()
37
37
 
38
- interaction_worker = Server::WorkerProcess.spawn_worker(:interaction, name: "interaction", steepfile: project.steepfile_path, steep_command: jobs_option.steep_command_value)
39
- typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: [], steep_command: jobs_option.steep_command_value, count: jobs_option.jobs_count_value)
38
+ interaction_worker = Server::WorkerProcess.start_worker(:interaction, name: "interaction", steepfile: project.steepfile_path, steep_command: jobs_option.steep_command_value)
39
+ typecheck_workers = Server::WorkerProcess.start_typecheck_workers(steepfile: project.steepfile_path, args: [], steep_command: jobs_option.steep_command_value, count: jobs_option.jobs_count_value)
40
40
 
41
41
  master = Server::Master.new(
42
42
  project: project,
@@ -126,7 +126,7 @@ module Steep
126
126
  server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
127
127
  server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
128
128
 
129
- typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(
129
+ typecheck_workers = Server::WorkerProcess.start_typecheck_workers(
130
130
  steepfile: project.steepfile_path,
131
131
  delay_shutdown: true,
132
132
  args: command_line_patterns,
@@ -42,7 +42,7 @@ module Steep
42
42
  server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
43
43
  server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
44
44
 
45
- typecheck_workers = Server::WorkerProcess.spawn_typecheck_workers(steepfile: project.steepfile_path, args: dirs.map(&:to_s), steep_command: jobs_option.steep_command_value, count: jobs_option.jobs_count_value)
45
+ typecheck_workers = Server::WorkerProcess.start_typecheck_workers(steepfile: project.steepfile_path, args: dirs.map(&:to_s), steep_command: jobs_option.steep_command_value, count: jobs_option.jobs_count_value)
46
46
 
47
47
  master = Server::Master.new(
48
48
  project: project,
@@ -3,7 +3,6 @@ module Steep
3
3
  class Worker
4
4
  attr_reader :stdout, :stderr, :stdin
5
5
 
6
- attr_accessor :steepfile_path
7
6
  attr_accessor :worker_type
8
7
  attr_accessor :worker_name
9
8
  attr_accessor :delay_shutdown
@@ -17,6 +17,8 @@ module Steep
17
17
  def to_s
18
18
  unless @array.empty?
19
19
  @array.join("\n\n----\n\n")
20
+ else
21
+ ""
20
22
  end
21
23
  end
22
24
 
@@ -83,7 +85,7 @@ module Steep
83
85
  #{decl.method_type}
84
86
  ```
85
87
 
86
- #{decl.method_def.comment.string.gsub(/\A([ \t]*\n)+/, "")}
88
+ #{comment.string.gsub(/\A([ \t]*\n)+/, "")}
87
89
  EOM
88
90
  end
89
91
  end
@@ -108,10 +110,10 @@ EOM
108
110
  end
109
111
  when HoverProvider::Ruby::ConstantContent
110
112
  CommentBuilder.build do |builder|
111
- if content.class_or_module?
113
+ if decl = content.class_or_module?
112
114
  builder << <<EOM
113
115
  ```rbs
114
- #{declaration_summary(content.decl.primary.decl)}
116
+ #{declaration_summary(decl.primary.decl)}
115
117
  ```
116
118
  EOM
117
119
  end
@@ -141,6 +143,14 @@ EOM
141
143
  builder << comment.string
142
144
  end
143
145
  end
146
+ when HoverProvider::Ruby::TypeAssertionContent
147
+ CommentBuilder.build do |builder|
148
+ builder << <<-EOM
149
+ `#{content.asserted_type.to_s}`
150
+
151
+ ↑ Converted from `#{content.original_type.to_s}`
152
+ EOM
153
+ end
144
154
  when HoverProvider::RBS::ClassContent
145
155
  CommentBuilder.build do |builder|
146
156
  builder << <<EOM
@@ -796,7 +796,10 @@ module Steep
796
796
 
797
797
  Steep.logger.info "Sending $/typecheck/start notifications"
798
798
  typecheck_workers.each do |worker|
799
- assignment = Services::PathAssignment.new(max_index: typecheck_workers.size, index: worker.index)
799
+ assignment = Services::PathAssignment.new(
800
+ max_index: typecheck_workers.size,
801
+ index: worker.index || raise
802
+ )
800
803
 
801
804
  job_queue << SendMessageJob.to_worker(
802
805
  worker,
@@ -18,48 +18,120 @@ module Steep
18
18
  @index = index
19
19
  end
20
20
 
21
- def self.spawn_worker(type, name:, steepfile:, steep_command: "steep", options: [], delay_shutdown: false, index: nil)
21
+ def self.start_worker(type, name:, steepfile:, steep_command: "steep", index: nil, delay_shutdown: false, patterns: [])
22
+ begin
23
+ fork_worker(
24
+ type,
25
+ name: name,
26
+ steepfile: steepfile,
27
+ index: index,
28
+ delay_shutdown: delay_shutdown,
29
+ patterns: patterns
30
+ )
31
+ rescue NotImplementedError
32
+ spawn_worker(
33
+ type,
34
+ name: name,
35
+ steepfile: steepfile,
36
+ steep_command: steep_command,
37
+ index: index,
38
+ delay_shutdown: delay_shutdown,
39
+ patterns: patterns
40
+ )
41
+ end
42
+ end
43
+
44
+ def self.fork_worker(type, name:, steepfile:, index:, delay_shutdown:, patterns:)
45
+ stdin_in, stdin_out = IO.pipe
46
+ stdout_in, stdout_out = IO.pipe
47
+
48
+ worker = Drivers::Worker.new(stdout: stdout_out, stdin: stdin_in, stderr: STDERR)
49
+
50
+ worker.steepfile = steepfile
51
+ worker.worker_type = type
52
+ worker.worker_name = name
53
+ worker.delay_shutdown = delay_shutdown
54
+ if (max, this = index)
55
+ worker.max_index = max
56
+ worker.index = this
57
+ end
58
+ worker.commandline_args = patterns
59
+
60
+ pid = fork do
61
+ worker.run()
62
+ end
63
+
64
+ pid or raise
65
+
66
+ writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin_out)
67
+ reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdout_in)
68
+
69
+ # @type var wait_thread: Thread & _ProcessWaitThread
70
+ wait_thread = _ = Thread.new { Process.waitpid(pid) }
71
+ wait_thread.define_singleton_method(:pid) { pid }
72
+
73
+ stdin_in.close
74
+ stdout_out.close
75
+
76
+ new(
77
+ reader: reader,
78
+ writer: writer,
79
+ stderr: STDERR,
80
+ wait_thread: wait_thread,
81
+ name: name,
82
+ index: index&.[](1)
83
+ )
84
+ end
85
+
86
+ def self.spawn_worker(type, name:, steepfile:, steep_command:, index:, delay_shutdown:, patterns:)
22
87
  args = ["--name=#{name}", "--steepfile=#{steepfile}"]
23
88
  args << (%w(debug info warn error fatal unknown)[Steep.logger.level].yield_self {|log_level| "--log-level=#{log_level}" })
89
+
24
90
  if Steep.log_output.is_a?(String)
25
91
  args << "--log-output=#{Steep.log_output}"
26
92
  end
93
+
94
+ if (max, this = index)
95
+ args << "--max-index=#{max}"
96
+ args << "--index=#{this}"
97
+ end
98
+
99
+ if delay_shutdown
100
+ args << "--delay-shutdown"
101
+ end
102
+
27
103
  command = case type
28
104
  when :interaction
29
- [steep_command, "worker", "--interaction", *args, *options]
105
+ [steep_command, "worker", "--interaction", *args, *patterns]
30
106
  when :typecheck
31
- [steep_command, "worker", "--typecheck", *args, *options]
107
+ [steep_command, "worker", "--typecheck", *args, *patterns]
32
108
  else
33
109
  raise "Unknown type: #{type}"
34
110
  end
35
111
 
36
- if delay_shutdown
37
- command << "--delay-shutdown"
38
- end
39
-
40
112
  stdin, stdout, thread = if Gem.win_platform?
41
- Open3.popen2(*command, new_pgroup: true)
113
+ __skip__ = Open3.popen2(*command, new_pgroup: true)
42
114
  else
43
- Open3.popen2(*command, pgroup: true)
115
+ __skip__ = Open3.popen2(*command, pgroup: true)
44
116
  end
45
117
  stderr = nil
46
118
 
47
119
  writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin)
48
120
  reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdout)
49
121
 
50
- new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread, name: name, index: index)
122
+ new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread, name: name, index: index&.[](1))
51
123
  end
52
124
 
53
- def self.spawn_typecheck_workers(steepfile:, args:, steep_command: "steep", count: [Etc.nprocessors - 1, 1].max, delay_shutdown: false)
125
+ def self.start_typecheck_workers(steepfile:, args:, steep_command: "steep", count: [Etc.nprocessors - 1, 1].max, delay_shutdown: false)
54
126
  count.times.map do |i|
55
- spawn_worker(
127
+ start_worker(
56
128
  :typecheck,
57
129
  name: "typecheck@#{i}",
58
130
  steepfile: steepfile,
59
131
  steep_command: steep_command,
60
- options: ["--max-index=#{count}", "--index=#{i}", *args],
132
+ index: [count, i],
133
+ patterns: args,
61
134
  delay_shutdown: delay_shutdown,
62
- index: i
63
135
  )
64
136
  end
65
137
  end
@@ -2,9 +2,9 @@ module Steep
2
2
  module Services
3
3
  module HoverProvider
4
4
  class RBS
5
- TypeAliasContent = Struct.new(:location, :decl, keyword_init: true)
6
- ClassContent = Struct.new(:location, :decl, keyword_init: true)
7
- InterfaceContent = Struct.new(:location, :decl, keyword_init: true)
5
+ TypeAliasContent = _ = Struct.new(:location, :decl, keyword_init: true)
6
+ ClassContent = _ = Struct.new(:location, :decl, keyword_init: true)
7
+ InterfaceContent = _ = Struct.new(:location, :decl, keyword_init: true)
8
8
 
9
9
  attr_reader :service
10
10
 
@@ -33,14 +33,14 @@ module Steep
33
33
  alias_decl = service.latest_env.alias_decls[head.name]&.decl or raise
34
34
 
35
35
  TypeAliasContent.new(
36
- location: head.location,
36
+ location: head.location || raise,
37
37
  decl: alias_decl
38
38
  )
39
39
  when ::RBS::Types::ClassInstance, ::RBS::Types::ClassSingleton
40
40
  if loc_key == :name
41
41
  env = service.latest_env
42
- class_decl = env.class_decls[head.name]&.decls[0]&.decl or raise
43
- location = head.location[:name]
42
+ class_decl = env.class_decls[head.name]&.decls&.[](0)&.decl or raise
43
+ location = head.location&.[](:name) or raise
44
44
  ClassContent.new(
45
45
  location: location,
46
46
  decl: class_decl
@@ -49,7 +49,7 @@ module Steep
49
49
  when ::RBS::Types::Interface
50
50
  env = service.latest_env
51
51
  interface_decl = env.interface_decls[head.name]&.decl or raise
52
- location = head.location[:name]
52
+ location = head.location&.[](:name) or raise
53
53
 
54
54
  InterfaceContent.new(
55
55
  location: location,
@@ -4,6 +4,7 @@ module Steep
4
4
  class Ruby
5
5
  TypeContent = _ = Struct.new(:node, :type, :location, keyword_init: true)
6
6
  VariableContent = _ = Struct.new(:node, :name, :type, :location, keyword_init: true)
7
+ TypeAssertionContent = _ = Struct.new(:node, :original_type, :asserted_type, :location, keyword_init: true)
7
8
  MethodCallContent = _ = Struct.new(:node, :method_call, :location, keyword_init: true)
8
9
  DefinitionContent = _ = Struct.new(:node, :method_name, :method_type, :definition, :location, keyword_init: true)
9
10
  ConstantContent = _ = Struct.new(:location, :full_name, :type, :decl, keyword_init: true) do
@@ -33,11 +34,15 @@ module Steep
33
34
  end
34
35
 
35
36
  def constant?
36
- decl.is_a?(::RBS::Environment::SingleEntry)
37
+ if decl.is_a?(::RBS::Environment::SingleEntry)
38
+ decl
39
+ end
37
40
  end
38
41
 
39
42
  def class_or_module?
40
- decl.is_a?(::RBS::Environment::MultiEntry)
43
+ if decl.is_a?(::RBS::Environment::MultiEntry)
44
+ decl
45
+ end
41
46
  end
42
47
  end
43
48
 
@@ -78,8 +83,9 @@ module Steep
78
83
  end
79
84
 
80
85
  def method_name_from_method(context, builder:)
81
- defined_in = context.method.defined_in
82
- method_name = context.name
86
+ context.method or raise
87
+ defined_in = context.method.defined_in or raise
88
+ method_name = context.name or raise
83
89
 
84
90
  case
85
91
  when defined_in.class?
@@ -171,6 +177,15 @@ module Steep
171
177
  decl: decl
172
178
  )
173
179
  end
180
+ when :assertion
181
+ original_node, _ = node.children
182
+
183
+ original_type = typing.type_of(node: original_node)
184
+ asserted_type = typing.type_of(node: node)
185
+
186
+ if original_type != asserted_type
187
+ return TypeAssertionContent.new(node: node, original_type: original_type, asserted_type: asserted_type, location: node.location.expression)
188
+ end
174
189
  end
175
190
 
176
191
  TypeContent.new(
@@ -174,7 +174,7 @@ module Steep
174
174
  file.decls
175
175
  else
176
176
  # factory is not used here because the error is a syntax error.
177
- Diagnostic::Signature.from_rbs_error(file.decls, factory: nil)
177
+ Diagnostic::Signature.from_rbs_error(file.decls, factory: _ = nil)
178
178
  end
179
179
  diagnostics << diagnostic
180
180
  end
@@ -214,6 +214,7 @@ module Steep
214
214
 
215
215
  def update_env(updated_files, paths:)
216
216
  Steep.logger.tagged "#update_env" do
217
+ # @type var errors: Array[RBS::BaseError]
217
218
  errors = []
218
219
  new_decls = Set[].compare_by_identity
219
220
 
@@ -230,7 +231,9 @@ module Steep
230
231
  updated_files.each_value do |content|
231
232
  case decls = content.decls
232
233
  when RBS::BaseError
233
- errors << content.decls
234
+ errors << decls
235
+ when Diagnostic::Signature::UnexpectedError
236
+ return [decls]
234
237
  else
235
238
  begin
236
239
  decls.each do |decl|
@@ -255,7 +258,7 @@ module Steep
255
258
  unless errors.empty?
256
259
  return errors.map {|error|
257
260
  # Factory will not be used because of the possible error types.
258
- Diagnostic::Signature.from_rbs_error(error, factory: nil)
261
+ Diagnostic::Signature.from_rbs_error(error, factory: _ = nil)
259
262
  }
260
263
  end
261
264
 
@@ -277,7 +280,7 @@ module Steep
277
280
 
278
281
  unless errors.empty?
279
282
  # Builder won't be used.
280
- factory = AST::Types::Factory.new(builder: nil)
283
+ factory = AST::Types::Factory.new(builder: _ = nil)
281
284
  return errors.map {|error| Diagnostic::Signature.from_rbs_error(error, factory: factory) }
282
285
  end
283
286
 
@@ -20,7 +20,7 @@ module Steep
20
20
  end
21
21
 
22
22
  def each_error(&block)
23
- if block_given?
23
+ if block
24
24
  @errors.each(&block)
25
25
  else
26
26
  enum_for :each_error
@@ -64,6 +64,8 @@ module Steep
64
64
  )
65
65
 
66
66
  type_params.zip(type_args).each do |param, arg|
67
+ arg or raise
68
+
67
69
  if param.upper_bound
68
70
  upper_bound_type = factory.type(param.upper_bound).subst(subst)
69
71
  arg_type = factory.type(arg)
@@ -121,7 +123,7 @@ module Steep
121
123
 
122
124
  if name && type_params && type_args
123
125
  if !type_params.empty? && !type_args.empty?
124
- validate_type_application_constraints(type.name, type_params, type_args, location: type.location)
126
+ validate_type_application_constraints(name, type_params, type_args, location: type.location)
125
127
  end
126
128
  end
127
129
 
@@ -156,19 +158,21 @@ module Steep
156
158
  end
157
159
 
158
160
  def mixin_constraints(definition, mixin_ancestors, immediate_self_types:)
161
+ # @type var relations: Array[[Subtyping::Relation[AST::Types::t], RBS::Definition::Ancestor::Instance]]
159
162
  relations = []
160
163
 
161
164
  self_type = checker.factory.type(definition.self_type)
162
165
  if immediate_self_types && !immediate_self_types.empty?
163
- self_type = AST::Types::Intersection.build(
164
- types: immediate_self_types.map {|st| ancestor_to_type(st) }.push(self_type),
165
- location: nil
166
- )
166
+ # @type var sts: Array[AST::Types::t]
167
+ sts = immediate_self_types.map {|st| ancestor_to_type(st) }
168
+ self_type = AST::Types::Intersection.build(types: sts.push(self_type), location: nil)
167
169
  end
168
170
 
169
171
  mixin_ancestors.each do |ancestor|
170
172
  args = ancestor.args.map {|type| checker.factory.type(type) }
171
173
  ancestor_ancestors = builder.ancestor_builder.one_instance_ancestors(ancestor.name)
174
+ ancestor_ancestors.self_types or raise
175
+ ancestor_ancestors.params or raise
172
176
  self_constraints = ancestor_ancestors.self_types.map do |self_ancestor|
173
177
  s = Interface::Substitution.build(ancestor_ancestors.params, args)
174
178
  ancestor_to_type(self_ancestor).subst(s)
@@ -263,7 +267,7 @@ module Steep
263
267
  end
264
268
 
265
269
  ancestors = builder.ancestor_builder.one_instance_ancestors(name)
266
- mixin_constraints(definition, ancestors.included_modules, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
270
+ mixin_constraints(definition, ancestors.included_modules || raise, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
267
271
  checker.check(
268
272
  relation,
269
273
  self_type: AST::Types::Self.new,
@@ -271,6 +275,8 @@ module Steep
271
275
  class_type: AST::Types::Class.new,
272
276
  constraints: Subtyping::Constraints.empty
273
277
  ).else do
278
+ raise if ancestor.source.is_a?(Symbol)
279
+
274
280
  @errors << Diagnostic::Signature::ModuleSelfTypeError.new(
275
281
  name: name,
276
282
  location: ancestor.source&.location || raise,
@@ -292,6 +298,14 @@ module Steep
292
298
  end
293
299
 
294
300
  builder.build_singleton(name).tap do |definition|
301
+ entry =
302
+ case definition.entry
303
+ when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
304
+ definition.entry
305
+ else
306
+ raise
307
+ end
308
+
295
309
  definition.instance_variables.each do |name, var|
296
310
  if parent = var.parent_variable
297
311
  var_type = checker.factory.type(var.type)
@@ -327,7 +341,7 @@ module Steep
327
341
  definition.class_variables.each do |name, var|
328
342
  if var.declared_in == definition.type_name
329
343
  if (parent = var.parent_variable) && var.declared_in != parent.declared_in
330
- class_var = definition.entry.decls.flat_map {|decl| decl.decl.members }.find do |member|
344
+ class_var = entry.decls.flat_map {|decl| decl.decl.members }.find do |member|
331
345
  member.is_a?(RBS::AST::Members::ClassVariable) && member.name == name
332
346
  end
333
347
 
@@ -336,7 +350,7 @@ module Steep
336
350
  class_name: definition.type_name,
337
351
  other_class_name: parent.declared_in,
338
352
  variable_name: name,
339
- location: class_var.location[:name]
353
+ location: class_var.location&.[](:name)
340
354
  )
341
355
  end
342
356
  end
@@ -344,6 +358,7 @@ module Steep
344
358
  end
345
359
 
346
360
  ancestors = builder.ancestor_builder.one_singleton_ancestors(name)
361
+ ancestors.extended_modules or raise
347
362
  mixin_constraints(definition, ancestors.extended_modules, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
348
363
  checker.check(
349
364
  relation,
@@ -352,6 +367,8 @@ module Steep
352
367
  class_type: AST::Types::Class.new,
353
368
  constraints: Subtyping::Constraints.empty
354
369
  ).else do
370
+ raise if ancestor.source.is_a?(Symbol)
371
+
355
372
  @errors << Diagnostic::Signature::ModuleSelfTypeError.new(
356
373
  name: name,
357
374
  location: ancestor.source&.location || raise,
@@ -381,19 +398,23 @@ module Steep
381
398
  builder.build_instance(ancestor.name)
382
399
  when ancestor.name.interface?
383
400
  builder.build_interface(ancestor.name)
401
+ else
402
+ raise
384
403
  end
385
404
 
386
405
  location =
387
- if ancestor.source == :super
406
+ case ancestor.source
407
+ when :super
388
408
  primary_decl = env.class_decls[name].primary.decl
409
+ primary_decl.is_a?(RBS::AST::Declarations::Class) or raise
389
410
  if super_class = primary_decl.super_class
390
411
  super_class.location
391
412
  else
392
413
  # Implicit super class (Object): this can be skipped in fact...
393
- primary_decl.location[:name]
414
+ primary_decl.location&.aref(:name)
394
415
  end
395
416
  else
396
- ancestor.source.location
417
+ ancestor.source&.location
397
418
  end
398
419
 
399
420
  validate_type_application_constraints(
@@ -423,12 +444,14 @@ module Steep
423
444
  case ancestor
424
445
  when RBS::Definition::Ancestor::Instance
425
446
  # Interface ancestor cannot be other than Interface
447
+ ancestor.source.is_a?(Symbol) and raise
448
+
426
449
  defn = builder.build_interface(ancestor.name)
427
450
  validate_type_application_constraints(
428
451
  ancestor.name,
429
452
  defn.type_params_decl,
430
453
  ancestor.args,
431
- location: ancestor.source.location || raise
454
+ location: ancestor.source&.location || raise
432
455
  )
433
456
  end
434
457
  end