rbs-inline 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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}