rbs 0.17.0 → 0.20.1

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