steep 1.2.0 → 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 +23 -2
  3. data/Gemfile.lock +14 -4
  4. data/Gemfile.steep +2 -2
  5. data/Gemfile.steep.lock +17 -5
  6. data/Steepfile +7 -9
  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 +31 -5
  32. data/lib/steep/version.rb +1 -1
  33. data/lib/steep.rb +2 -0
  34. data/rbs_collection.steep.lock.yaml +52 -11
  35. data/rbs_collection.steep.yaml +1 -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 +6 -1
  62. metadata +86 -6
@@ -773,6 +773,65 @@ module Steep
773
773
  end
774
774
  end
775
775
 
776
+ class FalseAssertion < Base
777
+ attr_reader :node, :assertion_type, :node_type
778
+
779
+ def initialize(node:, assertion_type:, node_type:)
780
+ super(node: node)
781
+ @assertion_type = assertion_type
782
+ @node_type = node_type
783
+ end
784
+
785
+ def header_line
786
+ "Assertion cannot hold: no relationship between infered type (`#{node_type.to_s}`) and asserted type (`#{assertion_type.to_s}`)"
787
+ end
788
+ end
789
+
790
+ class UnexpectedTypeArgument < Base
791
+ attr_reader :type_arg, :method_type
792
+
793
+ def initialize(type_arg:, method_type:)
794
+ super(node: nil, location: type_arg.location)
795
+ @type_arg = type_arg
796
+ @method_type = method_type
797
+ end
798
+
799
+ def header_line
800
+ "Unexpected type arg is given to method type `#{method_type.to_s}`"
801
+ end
802
+ end
803
+
804
+ class InsufficientTypeArgument < Base
805
+ attr_reader :type_args, :method_type
806
+
807
+ def initialize(node:, type_args:, method_type:)
808
+ super(node: node)
809
+ @type_args = type_args
810
+ @method_type = method_type
811
+ end
812
+
813
+ def header_line
814
+ "Requires #{method_type.type_params.size} types, but #{type_args.size} given: `#{method_type.to_s}`"
815
+ end
816
+ end
817
+
818
+ class TypeArgumentMismatchError < Base
819
+ attr_reader :type_argument, :type_parameter, :result
820
+
821
+ def initialize(type_arg:, type_param:, result:)
822
+ super(node: nil, location: type_arg.location)
823
+ @type_argument = type_arg
824
+ @type_parameter = type_param
825
+ @result = result
826
+ end
827
+
828
+ include ResultPrinter
829
+
830
+ def header_line
831
+ "Cannot pass a type `#{type_argument}` as a type parameter `#{type_parameter.to_s}`"
832
+ end
833
+ end
834
+
776
835
  ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
777
836
  if klass < Base
778
837
  array << klass
@@ -781,24 +840,29 @@ module Steep
781
840
 
782
841
  def self.all_error
783
842
  @all_error ||= ALL.each.with_object({}) do |klass, hash|
843
+ # @type var hash: Hash[singleton(Base), LSPFormatter::severity]
784
844
  hash[klass] = LSPFormatter::ERROR
785
845
  end.freeze
786
846
  end
787
847
 
788
848
  def self.default
789
- @default ||= all_error.merge(
849
+ @default ||= _ = all_error.merge(
790
850
  {
791
851
  ImplicitBreakValueMismatch => :warning,
792
852
  FallbackAny => :information,
793
853
  ElseOnExhaustiveCase => :warning,
794
854
  UnknownConstant => :warning,
795
- MethodDefinitionMissing => :information
855
+ MethodDefinitionMissing => :information,
856
+ FalseAssertion => :information,
857
+ UnexpectedTypeArgument => :information,
858
+ InsufficientTypeArgument => :information,
859
+ UnexpectedTypeArgument => :information
796
860
  }
797
861
  ).freeze
798
862
  end
799
863
 
800
864
  def self.strict
801
- @strict ||= all_error.merge(
865
+ @strict ||= _ = all_error.merge(
802
866
  {
803
867
  NoMethod => nil,
804
868
  ImplicitBreakValueMismatch => nil,
@@ -811,7 +875,7 @@ module Steep
811
875
  end
812
876
 
813
877
  def self.lenient
814
- @lenient ||= all_error.merge(
878
+ @lenient ||= _ = all_error.merge(
815
879
  {
816
880
  NoMethod => nil,
817
881
  ImplicitBreakValueMismatch => nil,
@@ -819,7 +883,8 @@ module Steep
819
883
  ElseOnExhaustiveCase => nil,
820
884
  UnknownConstant => nil,
821
885
  MethodDefinitionMissing => nil,
822
- UnexpectedJump => nil
886
+ UnexpectedJump => nil,
887
+ FalseAssertion => :hint
823
888
  }
824
889
  ).freeze
825
890
  end
@@ -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