steep 1.2.0 → 1.3.0.pre.1

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 (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