rbi 0.2.4 → 0.3.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.
data/lib/rbi/parser.rb CHANGED
@@ -5,12 +5,10 @@ require "prism"
5
5
 
6
6
  module RBI
7
7
  class ParseError < Error
8
- extend T::Sig
9
-
10
- sig { returns(Loc) }
8
+ #: Loc
11
9
  attr_reader :location
12
10
 
13
- sig { params(message: String, location: Loc).void }
11
+ #: (String message, Loc location) -> void
14
12
  def initialize(message, location)
15
13
  super(message)
16
14
  @location = location
@@ -18,19 +16,17 @@ module RBI
18
16
  end
19
17
 
20
18
  class UnexpectedParserError < Error
21
- extend T::Sig
22
-
23
- sig { returns(Loc) }
19
+ #: Loc
24
20
  attr_reader :last_location
25
21
 
26
- sig { params(parent_exception: Exception, last_location: Loc).void }
22
+ #: (Exception parent_exception, Loc last_location) -> void
27
23
  def initialize(parent_exception, last_location)
28
24
  super(parent_exception)
29
25
  set_backtrace(parent_exception.backtrace)
30
26
  @last_location = last_location
31
27
  end
32
28
 
33
- sig { params(io: T.any(IO, StringIO)).void }
29
+ #: (?io: (IO | StringIO)) -> void
34
30
  def print_debug(io: $stderr)
35
31
  io.puts ""
36
32
  io.puts "##################################"
@@ -51,47 +47,43 @@ module RBI
51
47
  end
52
48
 
53
49
  class Parser
54
- extend T::Sig
55
-
56
50
  class << self
57
- extend T::Sig
58
-
59
- sig { params(string: String).returns(Tree) }
51
+ #: (String string) -> Tree
60
52
  def parse_string(string)
61
53
  Parser.new.parse_string(string)
62
54
  end
63
55
 
64
- sig { params(path: String).returns(Tree) }
56
+ #: (String path) -> Tree
65
57
  def parse_file(path)
66
58
  Parser.new.parse_file(path)
67
59
  end
68
60
 
69
- sig { params(paths: T::Array[String]).returns(T::Array[Tree]) }
61
+ #: (Array[String] paths) -> Array[Tree]
70
62
  def parse_files(paths)
71
63
  parser = Parser.new
72
64
  paths.map { |path| parser.parse_file(path) }
73
65
  end
74
66
 
75
- sig { params(strings: T::Array[String]).returns(T::Array[Tree]) }
67
+ #: (Array[String] strings) -> Array[Tree]
76
68
  def parse_strings(strings)
77
69
  parser = Parser.new
78
70
  strings.map { |string| parser.parse_string(string) }
79
71
  end
80
72
  end
81
73
 
82
- sig { params(string: String).returns(Tree) }
74
+ #: (String string) -> Tree
83
75
  def parse_string(string)
84
76
  parse(string, file: "-")
85
77
  end
86
78
 
87
- sig { params(path: String).returns(Tree) }
79
+ #: (String path) -> Tree
88
80
  def parse_file(path)
89
81
  parse(::File.read(path), file: path)
90
82
  end
91
83
 
92
84
  private
93
85
 
94
- sig { params(source: String, file: String).returns(Tree) }
86
+ #: (String source, file: String) -> Tree
95
87
  def parse(source, file:)
96
88
  result = Prism.parse(source)
97
89
  unless result.success?
@@ -120,9 +112,7 @@ module RBI
120
112
  end
121
113
 
122
114
  class Visitor < Prism::Visitor
123
- extend T::Sig
124
-
125
- sig { params(source: String, file: String).void }
115
+ #: (String source, file: String) -> void
126
116
  def initialize(source, file:)
127
117
  super()
128
118
 
@@ -132,34 +122,32 @@ module RBI
132
122
 
133
123
  private
134
124
 
135
- sig { params(node: Prism::Node).returns(Loc) }
125
+ #: (Prism::Node node) -> Loc
136
126
  def node_loc(node)
137
127
  Loc.from_prism(@file, node.location)
138
128
  end
139
129
 
140
- sig { params(node: T.nilable(Prism::Node)).returns(T.nilable(String)) }
130
+ #: (Prism::Node? node) -> String?
141
131
  def node_string(node)
142
132
  return unless node
143
133
 
144
134
  node.slice
145
135
  end
146
136
 
147
- sig { params(node: Prism::Node).returns(String) }
137
+ #: (Prism::Node node) -> String
148
138
  def node_string!(node)
149
139
  T.must(node_string(node))
150
140
  end
151
141
  end
152
142
 
153
143
  class TreeBuilder < Visitor
154
- extend T::Sig
155
-
156
- sig { returns(Tree) }
144
+ #: Tree
157
145
  attr_reader :tree
158
146
 
159
- sig { returns(T.nilable(Prism::Node)) }
147
+ #: Prism::Node?
160
148
  attr_reader :last_node
161
149
 
162
- sig { params(source: String, comments: T::Array[Prism::Comment], file: String).void }
150
+ #: (String source, comments: Array[Prism::Comment], file: String) -> void
163
151
  def initialize(source, comments:, file:)
164
152
  super(source, file: file)
165
153
 
@@ -171,7 +159,8 @@ module RBI
171
159
  @last_sigs = T.let([], T::Array[RBI::Sig])
172
160
  end
173
161
 
174
- sig { override.params(node: Prism::ClassNode).void }
162
+ # @override
163
+ #: (Prism::ClassNode node) -> void
175
164
  def visit_class_node(node)
176
165
  @last_node = node
177
166
  superclass_name = node_string(node.superclass)
@@ -206,21 +195,23 @@ module RBI
206
195
  @last_node = nil
207
196
  end
208
197
 
209
- sig { override.params(node: Prism::ConstantWriteNode).void }
198
+ # @override
199
+ #: (Prism::ConstantWriteNode node) -> void
210
200
  def visit_constant_write_node(node)
211
201
  @last_node = node
212
202
  visit_constant_assign(node)
213
203
  @last_node = nil
214
204
  end
215
205
 
216
- sig { override.params(node: Prism::ConstantPathWriteNode).void }
206
+ # @override
207
+ #: (Prism::ConstantPathWriteNode node) -> void
217
208
  def visit_constant_path_write_node(node)
218
209
  @last_node = node
219
210
  visit_constant_assign(node)
220
211
  @last_node = nil
221
212
  end
222
213
 
223
- sig { params(node: T.any(Prism::ConstantWriteNode, Prism::ConstantPathWriteNode)).void }
214
+ #: ((Prism::ConstantWriteNode | Prism::ConstantPathWriteNode) node) -> void
224
215
  def visit_constant_assign(node)
225
216
  struct = parse_struct(node)
226
217
 
@@ -253,7 +244,8 @@ module RBI
253
244
  end
254
245
  end
255
246
 
256
- sig { override.params(node: Prism::DefNode).void }
247
+ # @override
248
+ #: (Prism::DefNode node) -> void
257
249
  def visit_def_node(node)
258
250
  @last_node = node
259
251
 
@@ -274,7 +266,8 @@ module RBI
274
266
  @last_node = nil
275
267
  end
276
268
 
277
- sig { override.params(node: Prism::ModuleNode).void }
269
+ # @override
270
+ #: (Prism::ModuleNode node) -> void
278
271
  def visit_module_node(node)
279
272
  @last_node = node
280
273
  scope = Module.new(
@@ -292,7 +285,8 @@ module RBI
292
285
  @last_node = nil
293
286
  end
294
287
 
295
- sig { override.params(node: Prism::ProgramNode).void }
288
+ # @override
289
+ #: (Prism::ProgramNode node) -> void
296
290
  def visit_program_node(node)
297
291
  @last_node = node
298
292
  super
@@ -303,7 +297,8 @@ module RBI
303
297
  @last_node = nil
304
298
  end
305
299
 
306
- sig { override.params(node: Prism::SingletonClassNode).void }
300
+ # @override
301
+ #: (Prism::SingletonClassNode node) -> void
307
302
  def visit_singleton_class_node(node)
308
303
  @last_node = node
309
304
  scope = SingletonClass.new(
@@ -320,7 +315,7 @@ module RBI
320
315
  @last_node = nil
321
316
  end
322
317
 
323
- sig { params(node: Prism::CallNode).void }
318
+ #: (Prism::CallNode node) -> void
324
319
  def visit_call_node(node)
325
320
  @last_node = node
326
321
  message = node.name.to_s
@@ -494,7 +489,7 @@ module RBI
494
489
  private
495
490
 
496
491
  # Collect all the remaining comments within a node
497
- sig { params(node: Prism::Node).void }
492
+ #: (Prism::Node node) -> void
498
493
  def collect_dangling_comments(node)
499
494
  first_line = node.location.start_line
500
495
  last_line = node.location.end_line
@@ -512,7 +507,7 @@ module RBI
512
507
  end
513
508
 
514
509
  # Collect all the remaining comments after visiting the tree
515
- sig { void }
510
+ #: -> void
516
511
  def collect_orphan_comments
517
512
  last_line = T.let(nil, T.nilable(Integer))
518
513
  last_node_end = @tree.nodes.last&.loc&.end_line
@@ -535,19 +530,19 @@ module RBI
535
530
  end
536
531
  end
537
532
 
538
- sig { returns(Tree) }
533
+ #: -> Tree
539
534
  def current_scope
540
535
  T.must(@scopes_stack.last) # Should never be nil since we create a Tree as the root
541
536
  end
542
537
 
543
- sig { returns(T::Array[Sig]) }
538
+ #: -> Array[Sig]
544
539
  def current_sigs
545
540
  sigs = @last_sigs.dup
546
541
  @last_sigs.clear
547
542
  sigs
548
543
  end
549
544
 
550
- sig { params(sigs: T::Array[Sig]).returns(T::Array[Comment]) }
545
+ #: (Array[Sig] sigs) -> Array[Comment]
551
546
  def detach_comments_from_sigs(sigs)
552
547
  comments = T.let([], T::Array[Comment])
553
548
 
@@ -559,7 +554,7 @@ module RBI
559
554
  comments
560
555
  end
561
556
 
562
- sig { params(node: Prism::Node).returns(T::Array[Comment]) }
557
+ #: (Prism::Node node) -> Array[Comment]
563
558
  def node_comments(node)
564
559
  comments = []
565
560
 
@@ -577,12 +572,20 @@ module RBI
577
572
  comments
578
573
  end
579
574
 
580
- sig { params(node: Prism::Comment).returns(Comment) }
575
+ #: (Prism::Comment node) -> Comment
581
576
  def parse_comment(node)
582
- Comment.new(node.location.slice.gsub(/^# ?/, "").rstrip, loc: Loc.from_prism(@file, node.location))
577
+ loc = Loc.from_prism(@file, node.location)
578
+ string = node.location.slice
579
+ # We also ignore RDoc directives such as `:nodoc:`
580
+ # See https://ruby.github.io/rdoc/RDoc/MarkupReference.html#class-RDoc::MarkupReference-label-Directives
581
+ if string.start_with?("#:") && !(string =~ /^#:[a-z_]+:/)
582
+ RBSComment.new(string.gsub(/^#: ?/, "").rstrip, loc: loc)
583
+ else
584
+ Comment.new(string.gsub(/^# ?/, "").rstrip, loc: loc)
585
+ end
583
586
  end
584
587
 
585
- sig { params(node: T.nilable(Prism::Node)).returns(T::Array[Arg]) }
588
+ #: (Prism::Node? node) -> Array[Arg]
586
589
  def parse_send_args(node)
587
590
  args = T.let([], T::Array[Arg])
588
591
  return args unless node.is_a?(Prism::ArgumentsNode)
@@ -606,7 +609,7 @@ module RBI
606
609
  args
607
610
  end
608
611
 
609
- sig { params(node: T.nilable(Prism::Node)).returns(T::Array[Param]) }
612
+ #: (Prism::Node? node) -> Array[Param]
610
613
  def parse_params(node)
611
614
  params = []
612
615
  return params unless node.is_a?(Prism::ParametersNode)
@@ -680,7 +683,7 @@ module RBI
680
683
  params
681
684
  end
682
685
 
683
- sig { params(node: Prism::CallNode).returns(Sig) }
686
+ #: (Prism::CallNode node) -> Sig
684
687
  def parse_sig(node)
685
688
  builder = SigBuilder.new(@source, file: @file)
686
689
  builder.current.loc = node_loc(node)
@@ -689,7 +692,7 @@ module RBI
689
692
  builder.current
690
693
  end
691
694
 
692
- sig { params(node: T.any(Prism::ConstantWriteNode, Prism::ConstantPathWriteNode)).returns(T.nilable(Struct)) }
695
+ #: ((Prism::ConstantWriteNode | Prism::ConstantPathWriteNode) node) -> Struct?
693
696
  def parse_struct(node)
694
697
  send = node.value
695
698
  return unless send.is_a?(Prism::CallNode)
@@ -737,7 +740,7 @@ module RBI
737
740
  struct
738
741
  end
739
742
 
740
- sig { params(send: Prism::CallNode).void }
743
+ #: (Prism::CallNode send) -> void
741
744
  def parse_tstruct_field(send)
742
745
  args = send.arguments
743
746
  return unless args.is_a?(Prism::ArgumentsNode)
@@ -774,7 +777,7 @@ module RBI
774
777
  end
775
778
  end
776
779
 
777
- sig { params(name: String, node: Prism::Node).returns(Visibility) }
780
+ #: (String name, Prism::Node node) -> Visibility
778
781
  def parse_visibility(name, node)
779
782
  case name
780
783
  when "public"
@@ -788,7 +791,7 @@ module RBI
788
791
  end
789
792
  end
790
793
 
791
- sig { void }
794
+ #: -> void
792
795
  def separate_header_comments
793
796
  current_scope.nodes.dup.each do |child_node|
794
797
  break unless child_node.is_a?(Comment) || child_node.is_a?(BlankLine)
@@ -798,7 +801,7 @@ module RBI
798
801
  end
799
802
  end
800
803
 
801
- sig { void }
804
+ #: -> void
802
805
  def set_root_tree_loc
803
806
  first_loc = tree.nodes.first&.loc
804
807
  last_loc = tree.nodes.last&.loc
@@ -812,26 +815,25 @@ module RBI
812
815
  )
813
816
  end
814
817
 
815
- sig { params(node: T.nilable(Prism::Node)).returns(T::Boolean) }
818
+ #: (Prism::Node? node) -> bool
816
819
  def type_variable_definition?(node)
817
820
  node.is_a?(Prism::CallNode) && (node.message == "type_member" || node.message == "type_template")
818
821
  end
819
822
  end
820
823
 
821
824
  class SigBuilder < Visitor
822
- extend T::Sig
823
-
824
- sig { returns(Sig) }
825
+ #: Sig
825
826
  attr_reader :current
826
827
 
827
- sig { params(content: String, file: String).void }
828
+ #: (String content, file: String) -> void
828
829
  def initialize(content, file:)
829
830
  super
830
831
 
831
832
  @current = T.let(Sig.new, Sig)
832
833
  end
833
834
 
834
- sig { override.params(node: Prism::CallNode).void }
835
+ # @override
836
+ #: (Prism::CallNode node) -> void
835
837
  def visit_call_node(node)
836
838
  case node.message
837
839
  when "sig"
@@ -892,7 +894,8 @@ module RBI
892
894
  visit(node.block)
893
895
  end
894
896
 
895
- sig { override.params(node: Prism::AssocNode).void }
897
+ # @override
898
+ #: (Prism::AssocNode node) -> void
896
899
  def visit_assoc_node(node)
897
900
  @current.params << SigParam.new(
898
901
  node_string!(node.key).delete_suffix(":"),