rbi 0.2.3 → 0.3.0

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
@@ -451,11 +446,6 @@ module RBI
451
446
  loc: node_loc(node),
452
447
  comments: node_comments(node),
453
448
  )
454
- else
455
- raise ParseError.new(
456
- "Unexpected token `#{node.message}` before `#{last_node&.string&.strip}`",
457
- node_loc(node),
458
- )
459
449
  end
460
450
  else
461
451
  current_scope << parse_visibility(node.name.to_s, node)
@@ -499,7 +489,7 @@ module RBI
499
489
  private
500
490
 
501
491
  # Collect all the remaining comments within a node
502
- sig { params(node: Prism::Node).void }
492
+ #: (Prism::Node node) -> void
503
493
  def collect_dangling_comments(node)
504
494
  first_line = node.location.start_line
505
495
  last_line = node.location.end_line
@@ -517,7 +507,7 @@ module RBI
517
507
  end
518
508
 
519
509
  # Collect all the remaining comments after visiting the tree
520
- sig { void }
510
+ #: -> void
521
511
  def collect_orphan_comments
522
512
  last_line = T.let(nil, T.nilable(Integer))
523
513
  last_node_end = @tree.nodes.last&.loc&.end_line
@@ -540,19 +530,19 @@ module RBI
540
530
  end
541
531
  end
542
532
 
543
- sig { returns(Tree) }
533
+ #: -> Tree
544
534
  def current_scope
545
535
  T.must(@scopes_stack.last) # Should never be nil since we create a Tree as the root
546
536
  end
547
537
 
548
- sig { returns(T::Array[Sig]) }
538
+ #: -> Array[Sig]
549
539
  def current_sigs
550
540
  sigs = @last_sigs.dup
551
541
  @last_sigs.clear
552
542
  sigs
553
543
  end
554
544
 
555
- sig { params(sigs: T::Array[Sig]).returns(T::Array[Comment]) }
545
+ #: (Array[Sig] sigs) -> Array[Comment]
556
546
  def detach_comments_from_sigs(sigs)
557
547
  comments = T.let([], T::Array[Comment])
558
548
 
@@ -564,7 +554,7 @@ module RBI
564
554
  comments
565
555
  end
566
556
 
567
- sig { params(node: Prism::Node).returns(T::Array[Comment]) }
557
+ #: (Prism::Node node) -> Array[Comment]
568
558
  def node_comments(node)
569
559
  comments = []
570
560
 
@@ -582,12 +572,18 @@ module RBI
582
572
  comments
583
573
  end
584
574
 
585
- sig { params(node: Prism::Comment).returns(Comment) }
575
+ #: (Prism::Comment node) -> Comment
586
576
  def parse_comment(node)
587
- 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
+ if string.start_with?("#:")
580
+ RBSComment.new(string.gsub(/^#: ?/, "").rstrip, loc: loc)
581
+ else
582
+ Comment.new(string.gsub(/^# ?/, "").rstrip, loc: loc)
583
+ end
588
584
  end
589
585
 
590
- sig { params(node: T.nilable(Prism::Node)).returns(T::Array[Arg]) }
586
+ #: (Prism::Node? node) -> Array[Arg]
591
587
  def parse_send_args(node)
592
588
  args = T.let([], T::Array[Arg])
593
589
  return args unless node.is_a?(Prism::ArgumentsNode)
@@ -611,7 +607,7 @@ module RBI
611
607
  args
612
608
  end
613
609
 
614
- sig { params(node: T.nilable(Prism::Node)).returns(T::Array[Param]) }
610
+ #: (Prism::Node? node) -> Array[Param]
615
611
  def parse_params(node)
616
612
  params = []
617
613
  return params unless node.is_a?(Prism::ParametersNode)
@@ -685,7 +681,7 @@ module RBI
685
681
  params
686
682
  end
687
683
 
688
- sig { params(node: Prism::CallNode).returns(Sig) }
684
+ #: (Prism::CallNode node) -> Sig
689
685
  def parse_sig(node)
690
686
  builder = SigBuilder.new(@source, file: @file)
691
687
  builder.current.loc = node_loc(node)
@@ -694,7 +690,7 @@ module RBI
694
690
  builder.current
695
691
  end
696
692
 
697
- sig { params(node: T.any(Prism::ConstantWriteNode, Prism::ConstantPathWriteNode)).returns(T.nilable(Struct)) }
693
+ #: ((Prism::ConstantWriteNode | Prism::ConstantPathWriteNode) node) -> Struct?
698
694
  def parse_struct(node)
699
695
  send = node.value
700
696
  return unless send.is_a?(Prism::CallNode)
@@ -722,8 +718,6 @@ module RBI
722
718
 
723
719
  keyword_init = val == "true" if key == "keyword_init:"
724
720
  end
725
- else
726
- raise ParseError.new("Unexpected node type `#{arg.class}`", node_loc(arg))
727
721
  end
728
722
  end
729
723
  end
@@ -744,7 +738,7 @@ module RBI
744
738
  struct
745
739
  end
746
740
 
747
- sig { params(send: Prism::CallNode).void }
741
+ #: (Prism::CallNode send) -> void
748
742
  def parse_tstruct_field(send)
749
743
  args = send.arguments
750
744
  return unless args.is_a?(Prism::ArgumentsNode)
@@ -781,7 +775,7 @@ module RBI
781
775
  end
782
776
  end
783
777
 
784
- sig { params(name: String, node: Prism::Node).returns(Visibility) }
778
+ #: (String name, Prism::Node node) -> Visibility
785
779
  def parse_visibility(name, node)
786
780
  case name
787
781
  when "public"
@@ -795,7 +789,7 @@ module RBI
795
789
  end
796
790
  end
797
791
 
798
- sig { void }
792
+ #: -> void
799
793
  def separate_header_comments
800
794
  current_scope.nodes.dup.each do |child_node|
801
795
  break unless child_node.is_a?(Comment) || child_node.is_a?(BlankLine)
@@ -805,7 +799,7 @@ module RBI
805
799
  end
806
800
  end
807
801
 
808
- sig { void }
802
+ #: -> void
809
803
  def set_root_tree_loc
810
804
  first_loc = tree.nodes.first&.loc
811
805
  last_loc = tree.nodes.last&.loc
@@ -819,26 +813,25 @@ module RBI
819
813
  )
820
814
  end
821
815
 
822
- sig { params(node: T.nilable(Prism::Node)).returns(T::Boolean) }
816
+ #: (Prism::Node? node) -> bool
823
817
  def type_variable_definition?(node)
824
818
  node.is_a?(Prism::CallNode) && (node.message == "type_member" || node.message == "type_template")
825
819
  end
826
820
  end
827
821
 
828
822
  class SigBuilder < Visitor
829
- extend T::Sig
830
-
831
- sig { returns(Sig) }
823
+ #: Sig
832
824
  attr_reader :current
833
825
 
834
- sig { params(content: String, file: String).void }
826
+ #: (String content, file: String) -> void
835
827
  def initialize(content, file:)
836
828
  super
837
829
 
838
830
  @current = T.let(Sig.new, Sig)
839
831
  end
840
832
 
841
- sig { override.params(node: Prism::CallNode).void }
833
+ # @override
834
+ #: (Prism::CallNode node) -> void
842
835
  def visit_call_node(node)
843
836
  case node.message
844
837
  when "sig"
@@ -899,7 +892,8 @@ module RBI
899
892
  visit(node.block)
900
893
  end
901
894
 
902
- sig { override.params(node: Prism::AssocNode).void }
895
+ # @override
896
+ #: (Prism::AssocNode node) -> void
903
897
  def visit_assoc_node(node)
904
898
  @current.params << SigParam.new(
905
899
  node_string!(node.key).delete_suffix(":"),