rbs 0.17.0 → 0.20.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.
@@ -20,7 +20,7 @@ class RBS::Parser
20
20
  nonassoc kARROW
21
21
  preclow
22
22
 
23
- expect 2
23
+ expect 5
24
24
 
25
25
  rule
26
26
 
@@ -202,57 +202,67 @@ rule
202
202
  | alias_member
203
203
  | signature
204
204
 
205
+ attribute_kind:
206
+ { result = :instance }
207
+ | kSELF kDOT { result = :singleton }
208
+
205
209
  attribute_member:
206
- annotations kATTRREADER keyword type {
207
- location = val[1].location + val[3].location
208
- result = Members::AttrReader.new(name: val[2].value,
210
+ annotations kATTRREADER attribute_kind keyword type {
211
+ location = val[1].location + val[4].location
212
+ result = Members::AttrReader.new(name: val[3].value,
209
213
  ivar_name: nil,
210
- type: val[3],
214
+ type: val[4],
215
+ kind: val[2],
211
216
  annotations: val[0],
212
217
  location: location,
213
218
  comment: leading_comment(val[0].first&.location || location))
214
219
  }
215
- | annotations kATTRREADER method_name attr_var_opt kCOLON type {
216
- location = val[1].location + val[5].location
217
- result = Members::AttrReader.new(name: val[2].value.to_sym,
218
- ivar_name: val[3],
219
- type: val[5],
220
+ | annotations kATTRREADER attribute_kind method_name attr_var_opt kCOLON type {
221
+ location = val[1].location + val[6].location
222
+ result = Members::AttrReader.new(name: val[3].value.to_sym,
223
+ ivar_name: val[4],
224
+ type: val[6],
225
+ kind: val[2],
220
226
  annotations: val[0],
221
227
  location: location,
222
228
  comment: leading_comment(val[0].first&.location || location))
223
229
  }
224
- | annotations kATTRWRITER keyword type {
225
- location = val[1].location + val[3].location
226
- result = Members::AttrWriter.new(name: val[2].value,
230
+ | annotations kATTRWRITER attribute_kind keyword type {
231
+ location = val[1].location + val[4].location
232
+ result = Members::AttrWriter.new(name: val[3].value,
227
233
  ivar_name: nil,
228
- type: val[3],
234
+ kind: val[2],
235
+ type: val[4],
229
236
  annotations: val[0],
230
237
  location: location,
231
238
  comment: leading_comment(val[0].first&.location || location))
232
239
  }
233
- | annotations kATTRWRITER method_name attr_var_opt kCOLON type {
234
- location = val[1].location + val[5].location
235
- result = Members::AttrWriter.new(name: val[2].value.to_sym,
236
- ivar_name: val[3],
237
- type: val[5],
240
+ | annotations kATTRWRITER attribute_kind method_name attr_var_opt kCOLON type {
241
+ location = val[1].location + val[6].location
242
+ result = Members::AttrWriter.new(name: val[3].value.to_sym,
243
+ ivar_name: val[4],
244
+ kind: val[2],
245
+ type: val[6],
238
246
  annotations: val[0],
239
247
  location: location,
240
248
  comment: leading_comment(val[0].first&.location || location))
241
249
  }
242
- | annotations kATTRACCESSOR keyword type {
243
- location = val[1].location + val[3].location
244
- result = Members::AttrAccessor.new(name: val[2].value,
250
+ | annotations kATTRACCESSOR attribute_kind keyword type {
251
+ location = val[1].location + val[4].location
252
+ result = Members::AttrAccessor.new(name: val[3].value,
245
253
  ivar_name: nil,
246
- type: val[3],
254
+ kind: val[2],
255
+ type: val[4],
247
256
  annotations: val[0],
248
257
  location: location,
249
258
  comment: leading_comment(val[0].first&.location || location))
250
259
  }
251
- | annotations kATTRACCESSOR method_name attr_var_opt kCOLON type {
252
- location = val[1].location + val[5].location
253
- result = Members::AttrAccessor.new(name: val[2].value.to_sym,
254
- ivar_name: val[3],
255
- type: val[5],
260
+ | annotations kATTRACCESSOR attribute_kind method_name attr_var_opt kCOLON type {
261
+ location = val[1].location + val[6].location
262
+ result = Members::AttrAccessor.new(name: val[3].value.to_sym,
263
+ ivar_name: val[4],
264
+ kind: val[2],
265
+ type: val[6],
256
266
  annotations: val[0],
257
267
  location: location,
258
268
  comment: leading_comment(val[0].first&.location || location))
@@ -474,26 +484,13 @@ rule
474
484
  }
475
485
 
476
486
  method_type:
477
- start_merged_scope type_params params_opt block_opt kARROW simple_type {
487
+ start_merged_scope type_params proc_type {
478
488
  reset_variable_scope
479
489
 
480
- location = (val[1] || val[2] || val[3] || val[4]).location + val[5].location
490
+ location = (val[1] || val[2]).location + val[2].location
481
491
  type_params = val[1]&.value || []
482
492
 
483
- params = val[2]&.value || empty_params_result
484
-
485
- type = Types::Function.new(
486
- required_positionals: params[0],
487
- optional_positionals: params[1],
488
- rest_positionals: params[2],
489
- trailing_positionals: params[3],
490
- required_keywords: params[4],
491
- optional_keywords: params[5],
492
- rest_keywords: params[6],
493
- return_type: val[5]
494
- )
495
-
496
- block = val[3]&.value
493
+ type, block = val[2].value
497
494
 
498
495
  result = MethodType.new(type_params: type_params,
499
496
  type: type,
@@ -507,14 +504,13 @@ rule
507
504
  result = LocatedValue.new(value: val[1], location: val[0].location + val[2].location)
508
505
  }
509
506
 
510
- block_opt:
511
- { result = nil }
512
- | kLBRACE function_type kRBRACE {
513
- block = MethodType::Block.new(type: val[1].value, required: true)
507
+ block:
508
+ kLBRACE simple_function_type kRBRACE {
509
+ block = Types::Block.new(type: val[1].value, required: true)
514
510
  result = LocatedValue.new(value: block, location: val[0].location + val[2].location)
515
511
  }
516
- | kQUESTION kLBRACE function_type kRBRACE {
517
- block = MethodType::Block.new(type: val[2].value, required: false)
512
+ | kQUESTION kLBRACE simple_function_type kRBRACE {
513
+ block = Types::Block.new(type: val[2].value, required: false)
518
514
  result = LocatedValue.new(value: block, location: val[0].location + val[3].location)
519
515
  }
520
516
 
@@ -797,8 +793,9 @@ rule
797
793
  result = Types::ClassSingleton.new(name: val[2].value,
798
794
  location: val[0].location + val[3].location)
799
795
  }
800
- | kHAT function_type {
801
- result = Types::Proc.new(type: val[1].value, location: val[0].location + val[1].location)
796
+ | kHAT proc_type {
797
+ type, block = val[1].value
798
+ result = Types::Proc.new(type: type, block: block, location: val[0].location + val[1].location)
802
799
  }
803
800
  | simple_type kQUESTION {
804
801
  result = Types::Optional.new(type: val[0], location: val[0].location + val[1].location)
@@ -851,7 +848,32 @@ rule
851
848
 
852
849
  keyword: tLKEYWORD | tUKEYWORD | tLKEYWORD_Q_E | tUKEYWORD_Q_E
853
850
 
854
- function_type:
851
+ proc_type:
852
+ params_opt block kARROW simple_type {
853
+ location = (val[0] || val[1] || val[2]).location + val[3].location
854
+
855
+ params = val[0]&.value || [[], [], nil, [], {}, {}, nil]
856
+
857
+ type = Types::Function.new(
858
+ required_positionals: params[0],
859
+ optional_positionals: params[1],
860
+ rest_positionals: params[2],
861
+ trailing_positionals: params[3],
862
+ required_keywords: params[4],
863
+ optional_keywords: params[5],
864
+ rest_keywords: params[6],
865
+ return_type: val[3]
866
+ )
867
+
868
+ block = val[1].value
869
+
870
+ result = LocatedValue.new(value: [type, block], location: location)
871
+ }
872
+ | simple_function_type {
873
+ result = LocatedValue.new(value: [val[0].value, nil], location: val[0].location)
874
+ }
875
+
876
+ simple_function_type:
855
877
  kLPAREN params kRPAREN kARROW simple_type {
856
878
  location = val[0].location + val[4].location
857
879
  type = Types::Function.new(
@@ -883,7 +905,7 @@ rule
883
905
  result = LocatedValue.new(value: type, location: location)
884
906
  }
885
907
 
886
- params:
908
+ params:
887
909
  required_positional kCOMMA params {
888
910
  result = val[2]
889
911
  result[0].unshift(val[0])
@@ -1294,6 +1316,10 @@ ANNOTATION_RE = Regexp.union(/%a\{.*?\}/,
1294
1316
  /%a\(.*?\)/,
1295
1317
  /%a\<.*?\>/,
1296
1318
  /%a\|.*?\|/)
1319
+
1320
+ escape_sequences = %w[a b e f n r s t v "].map { |l| "\\\\#{l}" }
1321
+ DBL_QUOTE_STR_ESCAPE_SEQUENCES_RE = /(#{escape_sequences.join("|")})/
1322
+
1297
1323
  def next_token
1298
1324
  if @type
1299
1325
  type = @type
@@ -1373,7 +1399,21 @@ def next_token
1373
1399
  when input.scan(/[a-z_]\w*\b/)
1374
1400
  new_token(:tLIDENT)
1375
1401
  when input.scan(/"(\\"|[^"])*"/)
1376
- s = input.matched.yield_self {|s| s[1, s.length - 2] }.gsub(/\\"/, '"')
1402
+ s = input.matched.yield_self {|s| s[1, s.length - 2] }
1403
+ .gsub(DBL_QUOTE_STR_ESCAPE_SEQUENCES_RE) do |match|
1404
+ case match
1405
+ when '\\a' then "\a"
1406
+ when '\\b' then "\b"
1407
+ when '\\e' then "\e"
1408
+ when '\\f' then "\f"
1409
+ when '\\n' then "\n"
1410
+ when '\\r' then "\r"
1411
+ when '\\s' then "\s"
1412
+ when '\\t' then "\t"
1413
+ when '\\v' then "\v"
1414
+ when '\\"' then '"'
1415
+ end
1416
+ end
1377
1417
  new_token(:tSTRING, s)
1378
1418
  when input.scan(/'(\\'|[^'])*'/)
1379
1419
  s = input.matched.yield_self {|s| s[1, s.length - 2] }.gsub(/\\'/, "'")
@@ -1,6 +1,30 @@
1
1
  module RBS
2
2
  module Prototype
3
3
  class RB
4
+ Context = Struct.new(:module_function, :singleton, :namespace, keyword_init: true) do
5
+ def self.initial(namespace: Namespace.root)
6
+ self.new(module_function: false, singleton: false, namespace: namespace)
7
+ end
8
+
9
+ def method_kind
10
+ if singleton
11
+ :singleton
12
+ elsif module_function
13
+ :singleton_instance
14
+ else
15
+ :instance
16
+ end
17
+ end
18
+
19
+ def attribute_kind
20
+ if singleton
21
+ :singleton
22
+ else
23
+ :instance
24
+ end
25
+ end
26
+ end
27
+
4
28
  attr_reader :source_decls
5
29
  attr_reader :toplevel_members
6
30
 
@@ -52,10 +76,10 @@ module RBS
52
76
  end
53
77
  end
54
78
 
55
- process RubyVM::AbstractSyntaxTree.parse(string), decls: source_decls, comments: comments, singleton: false
79
+ process RubyVM::AbstractSyntaxTree.parse(string), decls: source_decls, comments: comments, context: Context.initial
56
80
  end
57
81
 
58
- def process(node, decls:, comments:, singleton:)
82
+ def process(node, decls:, comments:, context:)
59
83
  case node.type
60
84
  when :CLASS
61
85
  class_name, super_class, *class_body = node.children
@@ -71,9 +95,11 @@ module RBS
71
95
 
72
96
  decls.push kls
73
97
 
98
+ new_ctx = Context.initial(namespace: context.namespace + kls.name.to_namespace)
74
99
  each_node class_body do |child|
75
- process child, decls: kls.members, comments: comments, singleton: false
100
+ process child, decls: kls.members, comments: comments, context: new_ctx
76
101
  end
102
+ remove_unnecessary_accessibility_methods! kls.members
77
103
 
78
104
  when :MODULE
79
105
  module_name, *module_body = node.children
@@ -90,9 +116,11 @@ module RBS
90
116
 
91
117
  decls.push mod
92
118
 
119
+ new_ctx = Context.initial(namespace: context.namespace + mod.name.to_namespace)
93
120
  each_node module_body do |child|
94
- process child, decls: mod.members, comments: comments, singleton: false
121
+ process child, decls: mod.members, comments: comments, context: new_ctx
95
122
  end
123
+ remove_unnecessary_accessibility_methods! mod.members
96
124
 
97
125
  when :SCLASS
98
126
  this, body = node.children
@@ -101,14 +129,13 @@ module RBS
101
129
  RBS.logger.warn "`class <<` syntax with not-self may be compiled to incorrect code: #{this}"
102
130
  end
103
131
 
104
- each_child(body) do |child|
105
- process child, decls: decls, comments: comments, singleton: true
106
- end
132
+ ctx = Context.initial.tap { |ctx| ctx.singleton = true }
133
+ process_children(body, decls: decls, comments: comments, context: ctx)
107
134
 
108
135
  when :DEFN, :DEFS
109
136
  if node.type == :DEFN
110
137
  def_name, def_body = node.children
111
- kind = singleton ? :singleton : :instance
138
+ kind = context.method_kind
112
139
  else
113
140
  _, def_name, def_body = node.children
114
141
  kind = :singleton
@@ -140,14 +167,14 @@ module RBS
140
167
  member = AST::Members::Alias.new(
141
168
  new_name: new_name,
142
169
  old_name: old_name,
143
- kind: singleton ? :singleton : :instance,
170
+ kind: context.singleton ? :singleton : :instance,
144
171
  annotations: [],
145
172
  location: nil,
146
173
  comment: comments[node.first_lineno - 1],
147
174
  )
148
175
  decls.push member unless decls.include?(member)
149
176
 
150
- when :FCALL
177
+ when :FCALL, :VCALL
151
178
  # Inside method definition cannot reach here.
152
179
  args = node.children[1]&.children || []
153
180
 
@@ -166,7 +193,7 @@ module RBS
166
193
  end
167
194
  when :extend
168
195
  args.each do |arg|
169
- if (name = const_to_name(arg))
196
+ if (name = const_to_name(arg, context: context))
170
197
  decls << AST::Members::Extend.new(
171
198
  name: name,
172
199
  args: [],
@@ -183,6 +210,7 @@ module RBS
183
210
  name: name,
184
211
  ivar_name: nil,
185
212
  type: Types::Bases::Any.new(location: nil),
213
+ kind: context.attribute_kind,
186
214
  location: nil,
187
215
  comment: comments[node.first_lineno - 1],
188
216
  annotations: []
@@ -196,6 +224,7 @@ module RBS
196
224
  name: name,
197
225
  ivar_name: nil,
198
226
  type: Types::Bases::Any.new(location: nil),
227
+ kind: context.attribute_kind,
199
228
  location: nil,
200
229
  comment: comments[node.first_lineno - 1],
201
230
  annotations: []
@@ -209,6 +238,7 @@ module RBS
209
238
  name: name,
210
239
  ivar_name: nil,
211
240
  type: Types::Bases::Any.new(location: nil),
241
+ kind: context.attribute_kind,
212
242
  location: nil,
213
243
  comment: comments[node.first_lineno - 1],
214
244
  annotations: []
@@ -220,16 +250,61 @@ module RBS
220
250
  decls << AST::Members::Alias.new(
221
251
  new_name: new_name,
222
252
  old_name: old_name,
223
- kind: singleton ? :singleton : :instance,
253
+ kind: context.singleton ? :singleton : :instance,
224
254
  annotations: [],
225
255
  location: nil,
226
256
  comment: comments[node.first_lineno - 1],
227
257
  )
228
258
  end
259
+ when :module_function
260
+ if args.empty?
261
+ context.module_function = true
262
+ else
263
+ module_func_context = context.dup.tap { |ctx| ctx.module_function = true }
264
+ args.each do |arg|
265
+ if arg && (name = literal_to_symbol(arg))
266
+ if i = find_def_index_by_name(decls, name)
267
+ decls[i] = decls[i].update(kind: :singleton_instance)
268
+ end
269
+ elsif arg
270
+ process arg, decls: decls, comments: comments, context: module_func_context
271
+ end
272
+ end
273
+ end
274
+ when :public, :private
275
+ accessibility = __send__(node.children[0])
276
+ if args.empty?
277
+ decls << accessibility
278
+ else
279
+ args.each do |arg|
280
+ if arg && (name = literal_to_symbol(arg))
281
+ if i = find_def_index_by_name(decls, name)
282
+ current = current_accessibility(decls, i)
283
+ if current != accessibility
284
+ decls.insert(i + 1, current)
285
+ decls.insert(i, accessibility)
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ # For `private def foo` syntax
292
+ current = current_accessibility(decls)
293
+ decls << accessibility
294
+ process_children(node, decls: decls, comments: comments, context: context)
295
+ decls << current
296
+ end
297
+ else
298
+ process_children(node, decls: decls, comments: comments, context: context)
229
299
  end
230
300
 
231
- each_child node do |child|
232
- process child, decls: decls, comments: comments, singleton: singleton
301
+ when :ITER
302
+ method_name = node.children.first.children.first
303
+ case method_name
304
+ when :refine
305
+ # ignore
306
+ else
307
+ process_children(node, decls: decls, comments: comments, context: context)
233
308
  end
234
309
 
235
310
  when :CDECL
@@ -248,13 +323,17 @@ module RBS
248
323
  )
249
324
 
250
325
  else
251
- each_child node do |child|
252
- process child, decls: decls, comments: comments, singleton: singleton
253
- end
326
+ process_children(node, decls: decls, comments: comments, context: context)
254
327
  end
255
328
  end
256
329
 
257
- def const_to_name(node)
330
+ def process_children(node, decls:, comments:, context:)
331
+ each_child node do |child|
332
+ process child, decls: decls, comments: comments, context: context
333
+ end
334
+ end
335
+
336
+ def const_to_name(node, context: nil)
258
337
  case node&.type
259
338
  when :CONST
260
339
  TypeName.new(name: node.children[0], namespace: Namespace.empty)
@@ -268,6 +347,8 @@ module RBS
268
347
  TypeName.new(name: node.children[1], namespace: namespace)
269
348
  when :COLON3
270
349
  TypeName.new(name: node.children[0], namespace: Namespace.root)
350
+ when :SELF
351
+ context&.then { |c| c.namespace.to_type_name }
271
352
  end
272
353
  end
273
354
 
@@ -479,7 +560,7 @@ module RBS
479
560
  method_block = nil
480
561
 
481
562
  if block
482
- method_block = MethodType::Block.new(
563
+ method_block = Types::Block.new(
483
564
  required: true,
484
565
  type: Types::Function.empty(untyped)
485
566
  )
@@ -487,7 +568,7 @@ module RBS
487
568
 
488
569
  if body_node
489
570
  if (yields = any_node?(body_node) {|n| n.type == :YIELD })
490
- method_block = MethodType::Block.new(
571
+ method_block = Types::Block.new(
491
572
  required: true,
492
573
  type: Types::Function.empty(untyped)
493
574
  )
@@ -586,6 +667,59 @@ module RBS
586
667
  def untyped
587
668
  @untyped ||= Types::Bases::Any.new(location: nil)
588
669
  end
670
+
671
+ def private
672
+ @private ||= AST::Members::Private.new(location: nil)
673
+ end
674
+
675
+ def public
676
+ @public ||= AST::Members::Public.new(location: nil)
677
+ end
678
+
679
+ def current_accessibility(decls, index = decls.size)
680
+ idx = decls.slice(0, index).rindex { |decl| decl == private || decl == public }
681
+ (idx && decls[idx]) || public
682
+ end
683
+
684
+ def remove_unnecessary_accessibility_methods!(decls)
685
+ current = public
686
+ idx = 0
687
+
688
+ loop do
689
+ decl = decls[idx] or break
690
+ if current == decl
691
+ decls.delete_at(idx)
692
+ next
693
+ end
694
+
695
+ if 0 < idx && is_accessibility?(decls[idx - 1]) && is_accessibility?(decl)
696
+ decls.delete_at(idx - 1)
697
+ idx -= 1
698
+ current = current_accessibility(decls, idx)
699
+ next
700
+ end
701
+
702
+ current = decl if is_accessibility?(decl)
703
+ idx += 1
704
+ end
705
+
706
+ decls.pop while decls.last && is_accessibility?(decls.last)
707
+ end
708
+
709
+ def is_accessibility?(decl)
710
+ decl == public || decl == private
711
+ end
712
+
713
+ def find_def_index_by_name(decls, name)
714
+ decls.find_index do |decl|
715
+ case decl
716
+ when AST::Members::MethodDefinition, AST::Members::AttrReader
717
+ decl.name == name
718
+ when AST::Members::AttrWriter
719
+ decl.name == :"#{name}="
720
+ end
721
+ end
722
+ end
589
723
  end
590
724
  end
591
725
  end