rbs-inline 0.3.0 → 0.5.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -7
  3. data/Rakefile +12 -0
  4. data/lib/rbs/inline/annotation_parser/tokenizer.rb +361 -0
  5. data/lib/rbs/inline/annotation_parser.rb +548 -326
  6. data/lib/rbs/inline/ast/annotations.rb +446 -136
  7. data/lib/rbs/inline/ast/comment_lines.rb +32 -18
  8. data/lib/rbs/inline/ast/declarations.rb +67 -28
  9. data/lib/rbs/inline/ast/members.rb +137 -140
  10. data/lib/rbs/inline/ast/tree.rb +104 -5
  11. data/lib/rbs/inline/cli.rb +12 -12
  12. data/lib/rbs/inline/node_utils.rb +4 -0
  13. data/lib/rbs/inline/parser.rb +140 -59
  14. data/lib/rbs/inline/version.rb +1 -1
  15. data/lib/rbs/inline/writer.rb +243 -94
  16. data/lib/rbs/inline.rb +4 -0
  17. data/rbs_collection.lock.yaml +3 -7
  18. data/rbs_collection.yaml +2 -0
  19. data/sig/generated/rbs/inline/annotation_parser/tokenizer.rbs +221 -0
  20. data/sig/generated/rbs/inline/annotation_parser.rbs +148 -92
  21. data/sig/generated/rbs/inline/ast/annotations.rbs +142 -36
  22. data/sig/generated/rbs/inline/ast/comment_lines.rbs +35 -0
  23. data/sig/generated/rbs/inline/ast/declarations.rbs +29 -10
  24. data/sig/generated/rbs/inline/ast/members.rbs +33 -24
  25. data/sig/generated/rbs/inline/ast/tree.rbs +132 -0
  26. data/sig/generated/rbs/inline/cli.rbs +3 -3
  27. data/sig/generated/rbs/inline/node_utils.rbs +11 -0
  28. data/sig/generated/rbs/inline/parser.rbs +38 -18
  29. data/sig/generated/rbs/inline/version.rbs +7 -0
  30. data/sig/generated/rbs/inline/writer.rbs +104 -0
  31. data/sig/generated/rbs/inline.rbs +7 -0
  32. metadata +14 -14
  33. data/sig/rbs/inline/annotation_parser.rbs +0 -0
  34. data/sig/rbs/inline/ast/comment_lines.rbs +0 -27
  35. data/sig/rbs/inline/ast/tree.rbs +0 -98
  36. data/sig/rbs/inline/node_utils.rbs +0 -7
  37. data/sig/rbs/inline/writer.rbs +0 -27
  38. data/sig/rbs/inline.rbs +0 -41
  39. data/yard-samples/hello.rb +0 -6
  40. data/yard-samples/sample1.rb +0 -26
@@ -4,15 +4,22 @@ module RBS
4
4
  module Inline
5
5
  module AST
6
6
  module Members
7
+ # @rbs!
8
+ # type ruby = RubyDef | RubyAlias | RubyMixin | RubyAttr | RubyPublic | RubyPrivate
9
+ #
10
+ # type rbs = RBSIvar | RBSEmbedded
11
+ #
12
+ # type t = ruby | rbs
13
+
7
14
  class Base
8
- attr_reader :location #:: Prism::Location
15
+ attr_reader :location #: Prism::Location
9
16
 
10
17
  # @rbs location: Prism::Location
11
- def initialize(location) #:: void
18
+ def initialize(location) #: void
12
19
  @location = location
13
20
  end
14
21
 
15
- def start_line #:: Integer
22
+ def start_line #: Integer
16
23
  location.start_line
17
24
  end
18
25
  end
@@ -21,8 +28,8 @@ module RBS
21
28
  end
22
29
 
23
30
  class RubyDef < RubyBase
24
- attr_reader :node #:: Prism::DefNode
25
- attr_reader :comments #:: AnnotationParser::ParsingResult?
31
+ attr_reader :node #: Prism::DefNode
32
+ attr_reader :comments #: AnnotationParser::ParsingResult?
26
33
 
27
34
  # The visibility directly attached to the `def` node
28
35
  #
@@ -32,15 +39,17 @@ module RBS
32
39
  # def foo() end # <= nil
33
40
  # private def foo() end # <= :private
34
41
  # ```
35
- attr_reader :visibility #:: RBS::AST::Members::visibility?
42
+ attr_reader :visibility #: RBS::AST::Members::visibility?
36
43
 
37
- attr_reader :assertion #:: Annotations::Assertion?
44
+ # Assertion given at the end of the method name
45
+ #
46
+ attr_reader :assertion #: Annotations::TypeAssertion?
38
47
 
39
48
  # @rbs node: Prism::DefNode
40
49
  # @rbs comments: AnnotationParser::ParsingResult?
41
50
  # @rbs visibility: RBS::AST::Members::visibility?
42
- # @rbs assertion: Annotations::Assertion?
43
- def initialize(node, comments, visibility, assertion) #:: void
51
+ # @rbs assertion: Annotations::TypeAssertion?
52
+ def initialize(node, comments, visibility, assertion) #: void
44
53
  @node = node
45
54
  @comments = comments
46
55
  @visibility = visibility
@@ -50,60 +59,53 @@ module RBS
50
59
  end
51
60
 
52
61
  # Returns the name of the method
53
- def method_name #:: Symbol
62
+ def method_name #: Symbol
54
63
  node.name
55
64
  end
56
65
 
57
- def method_type_annotations #:: Array[Annotations::Assertion]
58
- if comments
59
- comments.annotations.select do |annotation|
60
- annotation.is_a?(Annotations::Assertion) && annotation.type.is_a?(MethodType)
61
- end #: Array[Annotations::Assertion]
62
- else
63
- []
64
- end
65
- end
66
-
67
- # Returns the `kind` of the method definition
66
+ # Returns `nil` if no `@rbs METHOD-TYPE` or `#:` annotation is given
68
67
  #
69
- # [FIXME] It only supports `self` receiver.
70
- #
71
- # ```rb
72
- # def self.foo = () # :singleton
73
- # def object.foo = () # Not supported (returns :instance)
74
- # ```
68
+ # Returns an empty array if only `...` method type is given.
75
69
  #
76
- def method_kind #:: RBS::AST::Members::MethodDefinition::kind
77
- # FIXME: really hacky implementation
78
- case node.receiver
79
- when Prism::SelfNode
80
- :singleton
81
- when nil
82
- :instance
83
- else
84
- :instance
70
+ def annotated_method_types #: Array[MethodType]?
71
+ if comments
72
+ method_type_annotations = comments.each_annotation.select do |annotation|
73
+ annotation.is_a?(Annotations::MethodTypeAssertion) || annotation.is_a?(Annotations::Method) || annotation.is_a?(Annotations::Dot3Assertion)
74
+ end
75
+
76
+ return nil if method_type_annotations.empty?
77
+
78
+ method_type_annotations.each_with_object([]) do |annotation, method_types| #$ Array[MethodType]
79
+ case annotation
80
+ when Annotations::MethodTypeAssertion
81
+ method_types << annotation.method_type
82
+ when Annotations::Method
83
+ annotation.each_method_type do
84
+ method_types << _1
85
+ end
86
+ end
87
+ end
85
88
  end
86
89
  end
87
90
 
88
- def return_type #:: Types::t?
91
+ def return_type #: Types::t?
89
92
  if assertion
90
- if assertion.type?
91
- return assertion.type?
92
- end
93
+ return assertion.type
93
94
  end
95
+
94
96
  if comments
95
- annot = comments.annotations.find {|annot| annot.is_a?(Annotations::ReturnType ) } #: Annotations::ReturnType?
97
+ annot = comments.each_annotation.find {|annot| annot.is_a?(Annotations::ReturnType ) } #: Annotations::ReturnType?
96
98
  if annot
97
99
  annot.type
98
100
  end
99
101
  end
100
102
  end
101
103
 
102
- def var_type_hash #:: Hash[Symbol, Types::t?]
104
+ def var_type_hash #: Hash[Symbol, Types::t?]
103
105
  types = {} #: Hash[Symbol, Types::t?]
104
106
 
105
107
  if comments
106
- comments.annotations.each do |annotation|
108
+ comments.each_annotation.each do |annotation|
107
109
  if annotation.is_a?(Annotations::VarType)
108
110
  name = annotation.name
109
111
  type = annotation.type
@@ -118,11 +120,42 @@ module RBS
118
120
  types
119
121
  end
120
122
 
121
- def method_overloads #:: Array[RBS::AST::Members::MethodDefinition::Overload]
122
- if !(annots = method_type_annotations).empty?
123
- annots.map do
124
- method_type = _1.type #: MethodType
123
+ def splat_param_type_annotation #: Annotations::SplatParamType?
124
+ if comments
125
+ comments.each_annotation.find do |annotation|
126
+ annotation.is_a?(Annotations::SplatParamType)
127
+ end #: Annotations::SplatParamType?
128
+ end
129
+ end
125
130
 
131
+ def double_splat_param_type_annotation #: Annotations::DoubleSplatParamType?
132
+ if comments
133
+ comments.each_annotation.find do |annotation|
134
+ annotation.is_a?(Annotations::DoubleSplatParamType)
135
+ end #: Annotations::DoubleSplatParamType?
136
+ end
137
+ end
138
+
139
+ def overloading? #: bool
140
+ if comments
141
+ comments.each_annotation do |annotation|
142
+ if annotation.is_a?(Annotations::Method)
143
+ return true if annotation.overloading
144
+ end
145
+ if annotation.is_a?(Annotations::Dot3Assertion)
146
+ return true
147
+ end
148
+ end
149
+ false
150
+ else
151
+ false
152
+ end
153
+ end
154
+
155
+ def method_overloads #: Array[RBS::AST::Members::MethodDefinition::Overload]
156
+ case
157
+ when method_types = annotated_method_types
158
+ method_types.map do |method_type|
126
159
  RBS::AST::Members::MethodDefinition::Overload.new(
127
160
  method_type: method_type,
128
161
  annotations: []
@@ -160,22 +193,15 @@ module RBS
160
193
  end
161
194
 
162
195
  if (rest = node.parameters.rest).is_a?(Prism::RestParameterNode)
163
- rest_type =
164
- if rest.name
165
- var_type_hash[rest.name]
166
- end
167
-
168
- if rest_type
169
- if rest_type.is_a?(Types::ClassInstance)
170
- if rest_type.name.name == :Array && rest_type.name.namespace.empty?
171
- rest_type = rest_type.args[0]
172
- end
173
- end
196
+ splat_param_type = splat_param_type_annotation
197
+
198
+ if splat_param_type && splat_param_type.type
199
+ splat_type = splat_param_type.type
174
200
  end
175
201
 
176
202
  rest_positionals = Types::Function::Param.new(
177
203
  name: rest.name,
178
- type: rest_type || Types::Bases::Any.new(location: nil),
204
+ type: splat_type || Types::Bases::Any.new(location: nil),
179
205
  location: nil
180
206
  )
181
207
  end
@@ -199,60 +225,31 @@ module RBS
199
225
  end
200
226
 
201
227
  if (kw_rest = node.parameters.keyword_rest).is_a?(Prism::KeywordRestParameterNode)
202
- rest_type =
203
- if kw_rest.name
204
- var_type_hash[kw_rest.name]
205
- end
206
-
207
- if rest_type
208
- if rest_type.is_a?(Types::ClassInstance)
209
- if rest_type.name.name == :Hash && rest_type.name.namespace.empty?
210
- rest_type = rest_type.args[1]
211
- end
212
- end
228
+ double_splat_param_type = double_splat_param_type_annotation
229
+
230
+ if double_splat_param_type && double_splat_param_type.type
231
+ double_splat_type = double_splat_param_type.type
213
232
  end
214
233
 
215
234
  rest_keywords = Types::Function::Param.new(
216
235
  name: kw_rest.name,
217
- type: rest_type || Types::Bases::Any.new(location: nil),
236
+ type: double_splat_type || Types::Bases::Any.new(location: nil),
218
237
  location: nil)
219
238
  end
220
239
 
221
240
  if node.parameters.block
222
- if (block_name = node.parameters.block.name) && (var_type = var_type_hash[block_name])
223
- if var_type.is_a?(Types::Optional)
224
- optional = true
225
- var_type = var_type.type
226
- else
227
- optional = false
228
- end
229
-
230
- if var_type.is_a?(Types::Proc)
231
- block = Types::Block.new(type: var_type.type, self_type: var_type.self_type, required: !optional)
232
- end
233
- else
234
- block = Types::Block.new(
235
- type: Types::UntypedFunction.new(return_type: Types::Bases::Any.new(location: nil)),
236
- required: false,
237
- self_type: nil
238
- )
239
- end
240
- end
241
- end
242
-
243
- if annotation = yields_annotation
244
- case annotation.block_type
245
- when Types::Block
246
- block = annotation.block_type
247
- else
248
241
  block = Types::Block.new(
249
242
  type: Types::UntypedFunction.new(return_type: Types::Bases::Any.new(location: nil)),
250
- required: !annotation.optional,
243
+ required: false,
251
244
  self_type: nil
252
245
  )
253
246
  end
254
247
  end
255
248
 
249
+ if type = block_type_annotation&.type
250
+ block = type
251
+ end
252
+
256
253
  [
257
254
  RBS::AST::Members::MethodDefinition::Overload.new(
258
255
  method_type: RBS::MethodType.new(
@@ -276,9 +273,9 @@ module RBS
276
273
  end
277
274
  end
278
275
 
279
- def method_annotations #:: Array[RBS::AST::Annotation]
276
+ def method_annotations #: Array[RBS::AST::Annotation]
280
277
  if comments
281
- comments.annotations.flat_map do |annotation|
278
+ comments.each_annotation.flat_map do |annotation|
282
279
  if annotation.is_a?(AST::Annotations::RBSAnnotation)
283
280
  annotation.contents.map do |string|
284
281
  RBS::AST::Annotation.new(
@@ -295,44 +292,45 @@ module RBS
295
292
  end
296
293
  end
297
294
 
298
- def override_annotation #:: AST::Annotations::Override?
295
+ # Returns the `@rbs override` annotation
296
+ def override_annotation #: AST::Annotations::Override?
299
297
  if comments
300
- comments.annotations.find do |annotation|
298
+ comments.each_annotation.find do |annotation|
301
299
  annotation.is_a?(AST::Annotations::Override)
302
300
  end #: AST::Annotations::Override?
303
301
  end
304
302
  end
305
303
 
306
- def yields_annotation #:: AST::Annotations::Yields?
304
+ def block_type_annotation #: AST::Annotations::BlockType?
307
305
  if comments
308
- comments.annotations.find do |annotation|
309
- annotation.is_a?(AST::Annotations::Yields)
310
- end #: AST::Annotations::Yields?
306
+ comments.each_annotation.find do |annotation|
307
+ annotation.is_a?(AST::Annotations::BlockType)
308
+ end #: AST::Annotations::BlockType?
311
309
  end
312
310
  end
313
311
  end
314
312
 
315
313
  class RubyAlias < RubyBase
316
- attr_reader :node #:: Prism::AliasMethodNode
317
- attr_reader :comments #:: AnnotationParser::ParsingResult?
314
+ attr_reader :node #: Prism::AliasMethodNode
315
+ attr_reader :comments #: AnnotationParser::ParsingResult?
318
316
 
319
317
  # @rbs node: Prism::AliasMethodNode
320
318
  # @rbs comments: AnnotationParser::ParsingResult?
321
- def initialize(node, comments)
319
+ def initialize(node, comments) #: void
322
320
  @node = node
323
321
  @comments = comments
324
322
 
325
323
  super(node.location)
326
324
  end
327
325
 
328
- # @rbs returns Symbol -- the name of *old* method
326
+ # @rbs return: Symbol -- the name of *old* method
329
327
  def old_name
330
328
  raise unless node.old_name.is_a?(Prism::SymbolNode)
331
329
  value = node.old_name.value or raise
332
330
  value.to_sym
333
331
  end
334
332
 
335
- # @rbs returns Symbol -- the name of *new* method
333
+ # @rbs return: Symbol -- the name of *new* method
336
334
  def new_name
337
335
  raise unless node.new_name.is_a?(Prism::SymbolNode)
338
336
  value = node.new_name.value or raise
@@ -341,19 +339,21 @@ module RBS
341
339
  end
342
340
 
343
341
  class RubyMixin < RubyBase
342
+ include Declarations::ConstantUtil
343
+
344
344
  # CallNode that calls `include`, `prepend`, and `extend` method
345
- attr_reader :node #:: Prism::CallNode
345
+ attr_reader :node #: Prism::CallNode
346
346
 
347
347
  # Comments attached to the call node
348
- attr_reader :comments #:: AnnotationParser::ParsingResult?
348
+ attr_reader :comments #: AnnotationParser::ParsingResult?
349
349
 
350
350
  # Possible following type application annotation
351
- attr_reader :application #:: Annotations::Application?
351
+ attr_reader :application #: Annotations::Application?
352
352
 
353
353
  # @rbs node: Prism::CallNode
354
354
  # @rbs comments: AnnotationParser::ParsingResult?
355
355
  # @rbs application: Annotations::Application?
356
- # @rbs returns void
356
+ # @rbs return: void
357
357
  def initialize(node, comments, application)
358
358
  super(node.location)
359
359
 
@@ -362,7 +362,7 @@ module RBS
362
362
  @application = application
363
363
  end
364
364
 
365
- # @rbs returns ::RBS::AST::Members::Include
365
+ # @rbs return: ::RBS::AST::Members::Include
366
366
  # | ::RBS::AST::Members::Extend
367
367
  # | ::RBS::AST::Members::Prepend
368
368
  # | nil
@@ -371,11 +371,8 @@ module RBS
371
371
  return unless node.arguments.arguments.size == 1
372
372
 
373
373
  arg = node.arguments.arguments[0] || raise
374
- if arg.is_a?(Prism::ConstantReadNode)
375
- type_name = RBS::TypeName.new(name: arg.name, namespace: RBS::Namespace.empty)
376
- else
377
- raise
378
- end
374
+ type_name = type_name(arg)
375
+ return unless type_name
379
376
 
380
377
  args = [] #: Array[Types::t]
381
378
  if application
@@ -414,14 +411,14 @@ module RBS
414
411
  end
415
412
 
416
413
  class RubyAttr < RubyBase
417
- attr_reader :node #:: Prism::CallNode
418
- attr_reader :comments #:: AnnotationParser::ParsingResult?
419
- attr_reader :assertion #:: Annotations::Assertion?
414
+ attr_reader :node #: Prism::CallNode
415
+ attr_reader :comments #: AnnotationParser::ParsingResult?
416
+ attr_reader :assertion #: Annotations::TypeAssertion?
420
417
 
421
418
  # @rbs node: Prism::CallNode
422
419
  # @rbs comments: AnnotationParser::ParsingResult?
423
- # @rbs assertion: Annotations::Assertion?
424
- # @rbs returns void
420
+ # @rbs assertion: Annotations::TypeAssertion?
421
+ # @rbs return: void
425
422
  def initialize(node, comments, assertion)
426
423
  super(node.location)
427
424
 
@@ -433,7 +430,7 @@ module RBS
433
430
  # @rbs return Array[RBS::AST::Members::AttrReader | RBS::AST::Members::AttrWriter | RBS::AST::Members::AttrAccessor]?
434
431
  def rbs
435
432
  if comments
436
- comment = RBS::AST::Comment.new(string: comments.content, location: nil)
433
+ comment = RBS::AST::Comment.new(string: comments.content(trim: true), location: nil)
437
434
  end
438
435
 
439
436
  klass =
@@ -478,7 +475,7 @@ module RBS
478
475
  #
479
476
  # Returns `untyped` when not annotated.
480
477
  #
481
- def attribute_type #:: Types::t
478
+ def attribute_type #: Types::t
482
479
  type = assertion&.type
483
480
  raise if type.is_a?(MethodType)
484
481
 
@@ -489,10 +486,10 @@ module RBS
489
486
  # `private` call without arguments
490
487
  #
491
488
  class RubyPrivate < RubyBase
492
- attr_reader :node #:: Prism::CallNode
489
+ attr_reader :node #: Prism::CallNode
493
490
 
494
491
  # @rbs node: Prism::CallNode
495
- def initialize(node) #:: void
492
+ def initialize(node) #: void
496
493
  super(node.location)
497
494
  @node = node
498
495
  end
@@ -501,10 +498,10 @@ module RBS
501
498
  # `public` call without arguments
502
499
  #
503
500
  class RubyPublic < RubyBase
504
- attr_reader :node #:: Prism::CallNode
501
+ attr_reader :node #: Prism::CallNode
505
502
 
506
503
  # @rbs node: Prism::CallNode
507
- def initialize(node) #:: void
504
+ def initialize(node) #: void
508
505
  super(node.location)
509
506
  @node = node
510
507
  end
@@ -514,20 +511,20 @@ module RBS
514
511
  end
515
512
 
516
513
  class RBSIvar < RBSBase
517
- attr_reader :annotation #:: Annotations::IvarType
514
+ attr_reader :annotation #: Annotations::IvarType
518
515
 
519
- attr_reader :comment #:: AnnotationParser::ParsingResult
516
+ attr_reader :comment #: AnnotationParser::ParsingResult
520
517
 
521
518
  # @rbs comment: AnnotationParser::ParsingResult
522
519
  # @rbs annotation: Annotations::IvarType
523
- def initialize(comment, annotation) #:: void
520
+ def initialize(comment, annotation) #: void
524
521
  @comment = comment
525
522
  @annotation = annotation
526
523
 
527
524
  super(comment.comments[0].location)
528
525
  end
529
526
 
530
- def rbs #:: RBS::AST::Members::InstanceVariable | RBS::AST::Members::ClassInstanceVariable | nil
527
+ def rbs #: RBS::AST::Members::InstanceVariable | RBS::AST::Members::ClassInstanceVariable | nil
531
528
  if annotation.type
532
529
  if annotation.comment
533
530
  string = annotation.comment.delete_prefix("--").lstrip
@@ -554,13 +551,13 @@ module RBS
554
551
  end
555
552
 
556
553
  class RBSEmbedded < RBSBase
557
- attr_reader :annotation #:: Annotations::Embedded
554
+ attr_reader :annotation #: Annotations::Embedded
558
555
 
559
- attr_reader :comment #:: AnnotationParser::ParsingResult
556
+ attr_reader :comment #: AnnotationParser::ParsingResult
560
557
 
561
558
  # @rbs comment: AnnotationParser::ParsingResult
562
559
  # @rbs annotation: Annotations::Embedded
563
- def initialize(comment, annotation) #:: void
560
+ def initialize(comment, annotation) #: void
564
561
  @comment = comment
565
562
  @annotation = annotation
566
563
 
@@ -571,7 +568,7 @@ module RBS
571
568
  #
572
569
  # Returns `RBS::ParsingError` when the `content` has syntax error.
573
570
  #
574
- def members #:: Array[RBS::AST::Members::t | RBS::AST::Declarations::t] | RBS::ParsingError
571
+ def members #: Array[RBS::AST::Members::t | RBS::AST::Declarations::t] | RBS::ParsingError
575
572
  source = <<~RBS
576
573
  module EmbeddedModuleTest
577
574
  #{annotation.content}