rbs 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +28 -0
  3. data/.gitignore +12 -0
  4. data/.rubocop.yml +15 -0
  5. data/BSDL +22 -0
  6. data/CHANGELOG.md +9 -0
  7. data/COPYING +56 -0
  8. data/Gemfile +6 -0
  9. data/README.md +93 -0
  10. data/Rakefile +142 -0
  11. data/bin/annotate-with-rdoc +157 -0
  12. data/bin/console +14 -0
  13. data/bin/query-rdoc +103 -0
  14. data/bin/setup +10 -0
  15. data/bin/sort +89 -0
  16. data/bin/test_runner.rb +16 -0
  17. data/docs/CONTRIBUTING.md +97 -0
  18. data/docs/sigs.md +148 -0
  19. data/docs/stdlib.md +152 -0
  20. data/docs/syntax.md +528 -0
  21. data/exe/rbs +7 -0
  22. data/lib/rbs.rb +64 -0
  23. data/lib/rbs/ast/annotation.rb +27 -0
  24. data/lib/rbs/ast/comment.rb +27 -0
  25. data/lib/rbs/ast/declarations.rb +395 -0
  26. data/lib/rbs/ast/members.rb +362 -0
  27. data/lib/rbs/buffer.rb +50 -0
  28. data/lib/rbs/builtin_names.rb +55 -0
  29. data/lib/rbs/cli.rb +558 -0
  30. data/lib/rbs/constant.rb +26 -0
  31. data/lib/rbs/constant_table.rb +150 -0
  32. data/lib/rbs/definition.rb +170 -0
  33. data/lib/rbs/definition_builder.rb +919 -0
  34. data/lib/rbs/environment.rb +281 -0
  35. data/lib/rbs/environment_loader.rb +136 -0
  36. data/lib/rbs/environment_walker.rb +124 -0
  37. data/lib/rbs/errors.rb +187 -0
  38. data/lib/rbs/location.rb +102 -0
  39. data/lib/rbs/method_type.rb +123 -0
  40. data/lib/rbs/namespace.rb +91 -0
  41. data/lib/rbs/parser.y +1344 -0
  42. data/lib/rbs/prototype/rb.rb +553 -0
  43. data/lib/rbs/prototype/rbi.rb +587 -0
  44. data/lib/rbs/prototype/runtime.rb +381 -0
  45. data/lib/rbs/substitution.rb +46 -0
  46. data/lib/rbs/test.rb +26 -0
  47. data/lib/rbs/test/errors.rb +61 -0
  48. data/lib/rbs/test/hook.rb +294 -0
  49. data/lib/rbs/test/setup.rb +58 -0
  50. data/lib/rbs/test/spy.rb +325 -0
  51. data/lib/rbs/test/test_helper.rb +183 -0
  52. data/lib/rbs/test/type_check.rb +254 -0
  53. data/lib/rbs/type_name.rb +70 -0
  54. data/lib/rbs/types.rb +936 -0
  55. data/lib/rbs/variance_calculator.rb +138 -0
  56. data/lib/rbs/vendorer.rb +47 -0
  57. data/lib/rbs/version.rb +3 -0
  58. data/lib/rbs/writer.rb +269 -0
  59. data/lib/ruby/signature.rb +7 -0
  60. data/rbs.gemspec +46 -0
  61. data/stdlib/abbrev/abbrev.rbs +60 -0
  62. data/stdlib/base64/base64.rbs +71 -0
  63. data/stdlib/benchmark/benchmark.rbs +372 -0
  64. data/stdlib/builtin/array.rbs +1997 -0
  65. data/stdlib/builtin/basic_object.rbs +280 -0
  66. data/stdlib/builtin/binding.rbs +177 -0
  67. data/stdlib/builtin/builtin.rbs +45 -0
  68. data/stdlib/builtin/class.rbs +145 -0
  69. data/stdlib/builtin/comparable.rbs +116 -0
  70. data/stdlib/builtin/complex.rbs +400 -0
  71. data/stdlib/builtin/constants.rbs +37 -0
  72. data/stdlib/builtin/data.rbs +5 -0
  73. data/stdlib/builtin/deprecated.rbs +2 -0
  74. data/stdlib/builtin/dir.rbs +413 -0
  75. data/stdlib/builtin/encoding.rbs +607 -0
  76. data/stdlib/builtin/enumerable.rbs +404 -0
  77. data/stdlib/builtin/enumerator.rbs +260 -0
  78. data/stdlib/builtin/errno.rbs +781 -0
  79. data/stdlib/builtin/errors.rbs +582 -0
  80. data/stdlib/builtin/exception.rbs +194 -0
  81. data/stdlib/builtin/false_class.rbs +40 -0
  82. data/stdlib/builtin/fiber.rbs +68 -0
  83. data/stdlib/builtin/fiber_error.rbs +12 -0
  84. data/stdlib/builtin/file.rbs +1076 -0
  85. data/stdlib/builtin/file_test.rbs +59 -0
  86. data/stdlib/builtin/float.rbs +696 -0
  87. data/stdlib/builtin/gc.rbs +243 -0
  88. data/stdlib/builtin/hash.rbs +1029 -0
  89. data/stdlib/builtin/integer.rbs +707 -0
  90. data/stdlib/builtin/io.rbs +683 -0
  91. data/stdlib/builtin/kernel.rbs +576 -0
  92. data/stdlib/builtin/marshal.rbs +161 -0
  93. data/stdlib/builtin/match_data.rbs +271 -0
  94. data/stdlib/builtin/math.rbs +369 -0
  95. data/stdlib/builtin/method.rbs +185 -0
  96. data/stdlib/builtin/module.rbs +1104 -0
  97. data/stdlib/builtin/nil_class.rbs +82 -0
  98. data/stdlib/builtin/numeric.rbs +409 -0
  99. data/stdlib/builtin/object.rbs +824 -0
  100. data/stdlib/builtin/proc.rbs +429 -0
  101. data/stdlib/builtin/process.rbs +1227 -0
  102. data/stdlib/builtin/random.rbs +267 -0
  103. data/stdlib/builtin/range.rbs +226 -0
  104. data/stdlib/builtin/rational.rbs +424 -0
  105. data/stdlib/builtin/rb_config.rbs +57 -0
  106. data/stdlib/builtin/regexp.rbs +1083 -0
  107. data/stdlib/builtin/ruby_vm.rbs +14 -0
  108. data/stdlib/builtin/signal.rbs +55 -0
  109. data/stdlib/builtin/string.rbs +1901 -0
  110. data/stdlib/builtin/string_io.rbs +284 -0
  111. data/stdlib/builtin/struct.rbs +40 -0
  112. data/stdlib/builtin/symbol.rbs +228 -0
  113. data/stdlib/builtin/thread.rbs +1108 -0
  114. data/stdlib/builtin/thread_group.rbs +23 -0
  115. data/stdlib/builtin/time.rbs +1047 -0
  116. data/stdlib/builtin/trace_point.rbs +290 -0
  117. data/stdlib/builtin/true_class.rbs +46 -0
  118. data/stdlib/builtin/unbound_method.rbs +153 -0
  119. data/stdlib/builtin/warning.rbs +17 -0
  120. data/stdlib/coverage/coverage.rbs +62 -0
  121. data/stdlib/csv/csv.rbs +773 -0
  122. data/stdlib/erb/erb.rbs +392 -0
  123. data/stdlib/find/find.rbs +40 -0
  124. data/stdlib/ipaddr/ipaddr.rbs +247 -0
  125. data/stdlib/json/json.rbs +335 -0
  126. data/stdlib/pathname/pathname.rbs +1093 -0
  127. data/stdlib/prime/integer-extension.rbs +23 -0
  128. data/stdlib/prime/prime.rbs +188 -0
  129. data/stdlib/securerandom/securerandom.rbs +9 -0
  130. data/stdlib/set/set.rbs +301 -0
  131. data/stdlib/tmpdir/tmpdir.rbs +53 -0
  132. metadata +292 -0
@@ -0,0 +1,936 @@
1
+ module RBS
2
+ module Types
3
+ module NoFreeVariables
4
+ def free_variables(set = Set.new)
5
+ set
6
+ end
7
+ end
8
+
9
+ module NoSubst
10
+ def sub(s)
11
+ self
12
+ end
13
+ end
14
+
15
+ module EmptyEachType
16
+ def each_type
17
+ if block_given?
18
+ # nop
19
+ else
20
+ enum_for :each_type
21
+ end
22
+ end
23
+ end
24
+
25
+ module Bases
26
+ class Base
27
+ attr_reader :location
28
+
29
+ def initialize(location:)
30
+ @location = location
31
+ end
32
+
33
+ def ==(other)
34
+ other.is_a?(self.class)
35
+ end
36
+
37
+ def hash
38
+ self.class.hash
39
+ end
40
+
41
+ alias eql? ==
42
+
43
+ include NoFreeVariables
44
+ include NoSubst
45
+ include EmptyEachType
46
+
47
+ def to_json(*a)
48
+ klass = to_s.to_sym
49
+ { class: klass, location: location }.to_json(*a)
50
+ end
51
+
52
+ def to_s(level = 0)
53
+ case self
54
+ when Types::Bases::Bool
55
+ 'bool'
56
+ when Types::Bases::Void
57
+ 'void'
58
+ when Types::Bases::Any
59
+ 'untyped'
60
+ when Types::Bases::Nil
61
+ 'nil'
62
+ when Types::Bases::Top
63
+ 'top'
64
+ when Types::Bases::Bottom
65
+ 'bot'
66
+ when Types::Bases::Self
67
+ 'self'
68
+ when Types::Bases::Instance
69
+ 'instance'
70
+ when Types::Bases::Class
71
+ 'class'
72
+ else
73
+ raise "Unexpected base type: #{type.inspect}"
74
+ end
75
+ end
76
+ end
77
+
78
+ class Bool < Base; end
79
+ class Void < Base; end
80
+ class Any < Base; end
81
+ class Nil < Base; end
82
+ class Top < Base; end
83
+ class Bottom < Base; end
84
+ class Self < Base; end
85
+ class Instance < Base; end
86
+ class Class < Base; end
87
+ end
88
+
89
+ class Variable
90
+ attr_reader :name
91
+ attr_reader :location
92
+
93
+ def initialize(name:, location:)
94
+ @name = name
95
+ @location = location
96
+ end
97
+
98
+ def ==(other)
99
+ other.is_a?(Variable) && other.name == name
100
+ end
101
+
102
+ alias eql? ==
103
+
104
+ def hash
105
+ self.class.hash ^ name.hash
106
+ end
107
+
108
+ def free_variables(set = Set.new)
109
+ set.tap do
110
+ set << name
111
+ end
112
+ end
113
+
114
+ def to_json(*a)
115
+ { class: :variable, name: name, location: location }.to_json(*a)
116
+ end
117
+
118
+ def sub(s)
119
+ s.apply(self)
120
+ end
121
+
122
+ def self.build(v)
123
+ case v
124
+ when Symbol
125
+ new(name: v, location: nil)
126
+ when Array
127
+ v.map {|x| new(name: x, location: nil) }
128
+ else
129
+ raise
130
+ end
131
+ end
132
+
133
+ @@count = 0
134
+ def self.fresh(v = :T)
135
+ @@count = @@count + 1
136
+ new(name: :"#{v}@#{@@count}", location: nil)
137
+ end
138
+
139
+ def to_s(level = 0)
140
+ name.to_s
141
+ end
142
+
143
+ include EmptyEachType
144
+ end
145
+
146
+ class ClassSingleton
147
+ attr_reader :name
148
+ attr_reader :location
149
+
150
+ def initialize(name:, location:)
151
+ @name = name
152
+ @location = location
153
+ end
154
+
155
+ def ==(other)
156
+ other.is_a?(ClassSingleton) && other.name == name
157
+ end
158
+
159
+ alias eql? ==
160
+
161
+ def hash
162
+ self.class.hash ^ name.hash
163
+ end
164
+
165
+ include NoFreeVariables
166
+ include NoSubst
167
+
168
+ def to_json(*a)
169
+ { class: :class_singleton, name: name, location: location }.to_json(*a)
170
+ end
171
+
172
+ def to_s(level = 0)
173
+ "singleton(#{name})"
174
+ end
175
+
176
+ include EmptyEachType
177
+ end
178
+
179
+ module Application
180
+ attr_reader :name
181
+ attr_reader :args
182
+
183
+ def ==(other)
184
+ other.is_a?(self.class) && other.name == name && other.args == args
185
+ end
186
+
187
+ alias eql? ==
188
+
189
+ def hash
190
+ self.class.hash ^ name.hash ^ args.hash
191
+ end
192
+
193
+ def free_variables(set = Set.new)
194
+ set.tap do
195
+ args.each do |arg|
196
+ arg.free_variables(set)
197
+ end
198
+ end
199
+ end
200
+
201
+ def to_s(level = 0)
202
+ if args.empty?
203
+ name.to_s
204
+ else
205
+ "#{name}[#{args.join(", ")}]"
206
+ end
207
+ end
208
+
209
+ def each_type(&block)
210
+ if block_given?
211
+ args.each(&block)
212
+ else
213
+ enum_for :each_type
214
+ end
215
+ end
216
+ end
217
+
218
+ class Interface
219
+ attr_reader :location
220
+
221
+ include Application
222
+
223
+ def initialize(name:, args:, location:)
224
+ @name = name
225
+ @args = args
226
+ @location = location
227
+ end
228
+
229
+ def to_json(*a)
230
+ { class: :interface, name: name, args: args, location: location }.to_json(*a)
231
+ end
232
+
233
+ def sub(s)
234
+ self.class.new(name: name,
235
+ args: args.map {|ty| ty.sub(s) },
236
+ location: location)
237
+ end
238
+ end
239
+
240
+ class ClassInstance
241
+ attr_reader :location
242
+
243
+ include Application
244
+
245
+ def initialize(name:, args:, location:)
246
+ @name = name
247
+ @args = args
248
+ @location = location
249
+ end
250
+
251
+ def to_json(*a)
252
+ { class: :class_instance, name: name, args: args, location: location }.to_json(*a)
253
+ end
254
+
255
+ def sub(s)
256
+ self.class.new(name: name,
257
+ args: args.map {|ty| ty.sub(s) },
258
+ location: location)
259
+ end
260
+ end
261
+
262
+ class Alias
263
+ attr_reader :location
264
+ attr_reader :name
265
+
266
+ def initialize(name:, location:)
267
+ @name = name
268
+ @location = location
269
+ end
270
+
271
+ def ==(other)
272
+ other.is_a?(Alias) && other.name == name
273
+ end
274
+
275
+ alias eql? ==
276
+
277
+ def hash
278
+ self.class.hash ^ name.hash
279
+ end
280
+
281
+ include NoFreeVariables
282
+ include NoSubst
283
+
284
+ def to_json(*a)
285
+ { class: :alias, name: name, location: location }.to_json(*a)
286
+ end
287
+
288
+ def to_s(level = 0)
289
+ name.to_s
290
+ end
291
+
292
+ include EmptyEachType
293
+ end
294
+
295
+ class Tuple
296
+ attr_reader :types
297
+ attr_reader :location
298
+
299
+ def initialize(types:, location:)
300
+ @types = types
301
+ @location = location
302
+ end
303
+
304
+ def ==(other)
305
+ other.is_a?(Tuple) && other.types == types
306
+ end
307
+
308
+ alias eql? ==
309
+
310
+ def hash
311
+ self.class.hash ^ types.hash
312
+ end
313
+
314
+ def free_variables(set = Set.new)
315
+ set.tap do
316
+ types.each do |type|
317
+ type.free_variables set
318
+ end
319
+ end
320
+ end
321
+
322
+ def to_json(*a)
323
+ { class: :tuple, types: types, location: location }.to_json(*a)
324
+ end
325
+
326
+ def sub(s)
327
+ self.class.new(types: types.map {|ty| ty.sub(s) },
328
+ location: location)
329
+ end
330
+
331
+ def to_s(level = 0)
332
+ if types.empty?
333
+ "[ ]"
334
+ else
335
+ "[ #{types.join(", ")} ]"
336
+ end
337
+ end
338
+
339
+ def each_type(&block)
340
+ if block_given?
341
+ types.each(&block)
342
+ else
343
+ enum_for :each_type
344
+ end
345
+ end
346
+ end
347
+
348
+ class Record
349
+ attr_reader :fields
350
+ attr_reader :location
351
+
352
+ def initialize(fields:, location:)
353
+ @fields = fields
354
+ @location = location
355
+ end
356
+
357
+ def ==(other)
358
+ other.is_a?(Record) && other.fields == fields
359
+ end
360
+
361
+ alias eql? ==
362
+
363
+ def hash
364
+ self.class.hash ^ fields.hash
365
+ end
366
+
367
+ def free_variables(set = Set.new)
368
+ set.tap do
369
+ fields.each_value do |type|
370
+ type.free_variables set
371
+ end
372
+ end
373
+ end
374
+
375
+ def to_json(*a)
376
+ { class: :record, fields: fields, location: location }.to_json(*a)
377
+ end
378
+
379
+ def sub(s)
380
+ self.class.new(fields: fields.transform_values {|ty| ty.sub(s) },
381
+ location: location)
382
+ end
383
+
384
+ def to_s(level = 0)
385
+ return "{ }" if self.fields.empty?
386
+
387
+ fields = self.fields.map do |key, type|
388
+ if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/) && !key.match?(Parser::KEYWORDS_RE)
389
+ "#{key}: #{type}"
390
+ else
391
+ "#{key.inspect} => #{type}"
392
+ end
393
+ end
394
+ "{ #{fields.join(", ")} }"
395
+ end
396
+
397
+ def each_type(&block)
398
+ if block_given?
399
+ fields.each_value(&block)
400
+ else
401
+ enum_for :each_type
402
+ end
403
+ end
404
+ end
405
+
406
+ class Optional
407
+ attr_reader :type
408
+ attr_reader :location
409
+
410
+ def initialize(type:, location:)
411
+ @type = type
412
+ @location = location
413
+ end
414
+
415
+ def ==(other)
416
+ other.is_a?(Optional) && other.type == type
417
+ end
418
+
419
+ alias eql? ==
420
+
421
+ def hash
422
+ self.class.hash ^ type.hash
423
+ end
424
+
425
+ def free_variables(set = Set.new)
426
+ type.free_variables(set)
427
+ end
428
+
429
+ def to_json(*a)
430
+ { class: :optional, type: type, location: location }.to_json(*a)
431
+ end
432
+
433
+ def sub(s)
434
+ self.class.new(type: type.sub(s), location: location)
435
+ end
436
+
437
+ def to_s(level = 0)
438
+ if type.is_a?(RBS::Types::Literal) && type.literal.is_a?(Symbol)
439
+ "#{type.to_s(1)} ?"
440
+ else
441
+ "#{type.to_s(1)}?"
442
+ end
443
+ end
444
+
445
+ def each_type
446
+ if block_given?
447
+ yield type
448
+ else
449
+ enum_for :each_type
450
+ end
451
+ end
452
+ end
453
+
454
+ class Union
455
+ attr_reader :types
456
+ attr_reader :location
457
+
458
+ def initialize(types:, location:)
459
+ @types = types
460
+ @location = location
461
+ end
462
+
463
+ def ==(other)
464
+ other.is_a?(Union) && other.types == types
465
+ end
466
+
467
+ alias eql? ==
468
+
469
+ def hash
470
+ self.class.hash ^ types.hash
471
+ end
472
+
473
+ def free_variables(set = Set.new)
474
+ set.tap do
475
+ types.each do |type|
476
+ type.free_variables set
477
+ end
478
+ end
479
+ end
480
+
481
+ def to_json(*a)
482
+ { class: :union, types: types, location: location }.to_json(*a)
483
+ end
484
+
485
+ def sub(s)
486
+ self.class.new(types: types.map {|ty| ty.sub(s) },
487
+ location: location)
488
+ end
489
+
490
+ def to_s(level = 0)
491
+ if level > 0
492
+ "(#{types.join(" | ")})"
493
+ else
494
+ types.join(" | ")
495
+ end
496
+ end
497
+
498
+ def each_type(&block)
499
+ if block_given?
500
+ types.each(&block)
501
+ else
502
+ enum_for :each_type
503
+ end
504
+ end
505
+
506
+ def map_type(&block)
507
+ if block_given?
508
+ Union.new(types: types.map(&block), location: location)
509
+ else
510
+ enum_for :map_type
511
+ end
512
+ end
513
+ end
514
+
515
+ class Intersection
516
+ attr_reader :types
517
+ attr_reader :location
518
+
519
+ def initialize(types:, location:)
520
+ @types = types
521
+ @location = location
522
+ end
523
+
524
+ def ==(other)
525
+ other.is_a?(Intersection) && other.types == types
526
+ end
527
+
528
+ alias eql? ==
529
+
530
+ def hash
531
+ self.class.hash ^ types.hash
532
+ end
533
+
534
+ def free_variables(set = Set.new)
535
+ set.tap do
536
+ types.each do |type|
537
+ type.free_variables set
538
+ end
539
+ end
540
+ end
541
+
542
+ def to_json(*a)
543
+ { class: :intersection, types: types, location: location }.to_json(*a)
544
+ end
545
+
546
+ def sub(s)
547
+ self.class.new(types: types.map {|ty| ty.sub(s) },
548
+ location: location)
549
+ end
550
+
551
+ def to_s(level = 0)
552
+ strs = types.map {|ty| ty.to_s(2) }
553
+ if level > 0
554
+ "(#{strs.join(" & ")})"
555
+ else
556
+ strs.join(" & ")
557
+ end
558
+ end
559
+
560
+ def each_type(&block)
561
+ if block_given?
562
+ types.each(&block)
563
+ else
564
+ enum_for :each_type
565
+ end
566
+ end
567
+
568
+ def map_type(&block)
569
+ if block_given?
570
+ Intersection.new(types: types.map(&block), location: location)
571
+ else
572
+ enum_for :map_type
573
+ end
574
+ end
575
+ end
576
+
577
+ class Function
578
+ class Param
579
+ attr_reader :type
580
+ attr_reader :name
581
+
582
+ def initialize(type:, name:)
583
+ @type = type
584
+ @name = name
585
+ end
586
+
587
+ def ==(other)
588
+ other.is_a?(Param) && other.type == type && other.name == name
589
+ end
590
+
591
+ alias eql? ==
592
+
593
+ def hash
594
+ self.class.hash ^ type.hash ^ name.hash
595
+ end
596
+
597
+ def map_type
598
+ if block_given?
599
+ Param.new(name: name, type: yield(type))
600
+ else
601
+ enum_for :map_type
602
+ end
603
+ end
604
+
605
+ def to_json(*a)
606
+ { type: type, name: name }.to_json(*a)
607
+ end
608
+
609
+ def to_s
610
+ if name
611
+ if /\A#{Parser::KEYWORDS_RE}\z/.match?(name)
612
+ "#{type} `#{name}`"
613
+ else
614
+ "#{type} #{name}"
615
+ end
616
+ else
617
+ "#{type}"
618
+ end
619
+ end
620
+ end
621
+
622
+ attr_reader :required_positionals
623
+ attr_reader :optional_positionals
624
+ attr_reader :rest_positionals
625
+ attr_reader :trailing_positionals
626
+ attr_reader :required_keywords
627
+ attr_reader :optional_keywords
628
+ attr_reader :rest_keywords
629
+ attr_reader :return_type
630
+
631
+ def initialize(required_positionals:, optional_positionals:, rest_positionals:, trailing_positionals:, required_keywords:, optional_keywords:, rest_keywords:, return_type:)
632
+ @return_type = return_type
633
+ @required_positionals = required_positionals
634
+ @optional_positionals = optional_positionals
635
+ @rest_positionals = rest_positionals
636
+ @trailing_positionals = trailing_positionals
637
+ @required_keywords = required_keywords
638
+ @optional_keywords = optional_keywords
639
+ @rest_keywords = rest_keywords
640
+ end
641
+
642
+ def ==(other)
643
+ other.is_a?(Function) &&
644
+ other.required_positionals == required_positionals &&
645
+ other.optional_positionals == optional_positionals &&
646
+ other.rest_positionals == rest_positionals &&
647
+ other.trailing_positionals == trailing_positionals &&
648
+ other.required_keywords == required_keywords &&
649
+ other.optional_keywords == optional_keywords &&
650
+ other.rest_keywords == rest_keywords &&
651
+ return_type == return_type
652
+ end
653
+
654
+ alias eql? ==
655
+
656
+ def hash
657
+ self.class.hash ^
658
+ required_positionals.hash ^
659
+ optional_positionals.hash ^
660
+ rest_positionals.hash ^
661
+ trailing_positionals.hash ^
662
+ required_keywords.hash ^
663
+ optional_keywords.hash ^
664
+ rest_keywords.hash ^
665
+ return_type.hash
666
+ end
667
+
668
+ def free_variables(set = Set.new)
669
+ set.tap do
670
+ required_positionals.each do |param|
671
+ param.type.free_variables(set)
672
+ end
673
+ optional_positionals.each do |param|
674
+ param.type.free_variables(set)
675
+ end
676
+ rest_positionals&.yield_self do |param|
677
+ param.type.free_variables(set)
678
+ end
679
+ trailing_positionals.each do |param|
680
+ param.type.free_variables(set)
681
+ end
682
+ required_keywords.each_value do |param|
683
+ param.type.free_variables(set)
684
+ end
685
+ optional_keywords.each_value do |param|
686
+ param.type.free_variables(set)
687
+ end
688
+ rest_keywords&.yield_self do |param|
689
+ param.type.free_variables(set)
690
+ end
691
+
692
+ return_type.free_variables(set)
693
+ end
694
+ end
695
+
696
+ def map_type(&block)
697
+ if block_given?
698
+ Function.new(
699
+ required_positionals: required_positionals.map {|param| param.map_type(&block) },
700
+ optional_positionals: optional_positionals.map {|param| param.map_type(&block) },
701
+ rest_positionals: rest_positionals&.yield_self {|param| param.map_type(&block) },
702
+ trailing_positionals: trailing_positionals.map {|param| param.map_type(&block) },
703
+ required_keywords: required_keywords.transform_values {|param| param.map_type(&block) },
704
+ optional_keywords: optional_keywords.transform_values {|param| param.map_type(&block) },
705
+ rest_keywords: rest_keywords&.yield_self {|param| param.map_type(&block) },
706
+ return_type: yield(return_type)
707
+ )
708
+ else
709
+ enum_for :map_type
710
+ end
711
+ end
712
+
713
+ def each_type
714
+ if block_given?
715
+ required_positionals.each {|param| yield param.type }
716
+ optional_positionals.each {|param| yield param.type }
717
+ rest_positionals&.yield_self {|param| yield param.type }
718
+ trailing_positionals.each {|param| yield param.type }
719
+ required_keywords.each_value {|param| yield param.type }
720
+ optional_keywords.each_value {|param| yield param.type }
721
+ rest_keywords&.yield_self {|param| yield param.type }
722
+ yield(return_type)
723
+ else
724
+ enum_for :each_type
725
+ end
726
+ end
727
+
728
+ def each_param(&block)
729
+ if block_given?
730
+ required_positionals.each(&block)
731
+ optional_positionals.each(&block)
732
+ rest_positionals&.yield_self(&block)
733
+ trailing_positionals.each(&block)
734
+ required_keywords.each_value(&block)
735
+ optional_keywords.each_value(&block)
736
+ rest_keywords&.yield_self(&block)
737
+ else
738
+ enum_for :each_param
739
+ end
740
+ end
741
+
742
+ def to_json(*a)
743
+ {
744
+ required_positionals: required_positionals,
745
+ optional_positionals: optional_positionals,
746
+ rest_positionals: rest_positionals,
747
+ trailing_positionals: trailing_positionals,
748
+ required_keywords: required_keywords,
749
+ optional_keywords: optional_keywords,
750
+ rest_keywords: rest_keywords,
751
+ return_type: return_type
752
+ }.to_json(*a)
753
+ end
754
+
755
+ def sub(s)
756
+ map_type {|ty| ty.sub(s) }
757
+ end
758
+
759
+ def self.empty(return_type)
760
+ Function.new(
761
+ required_positionals: [],
762
+ optional_positionals: [],
763
+ rest_positionals: nil,
764
+ trailing_positionals: [],
765
+ required_keywords: {},
766
+ optional_keywords: {},
767
+ rest_keywords: nil,
768
+ return_type: return_type
769
+ )
770
+ end
771
+
772
+ def with_return_type(type)
773
+ Function.new(
774
+ required_positionals: required_positionals,
775
+ optional_positionals: optional_positionals,
776
+ rest_positionals: rest_positionals,
777
+ trailing_positionals: trailing_positionals,
778
+ required_keywords: required_keywords,
779
+ optional_keywords: optional_keywords,
780
+ rest_keywords: rest_keywords,
781
+ return_type: type
782
+ )
783
+ end
784
+
785
+ def update(required_positionals: self.required_positionals, optional_positionals: self.optional_positionals, rest_positionals: self.rest_positionals, trailing_positionals: self.trailing_positionals,
786
+ required_keywords: self.required_keywords, optional_keywords: self.optional_keywords, rest_keywords: self.rest_keywords, return_type: self.return_type)
787
+ Function.new(
788
+ required_positionals: required_positionals,
789
+ optional_positionals: optional_positionals,
790
+ rest_positionals: rest_positionals,
791
+ trailing_positionals: trailing_positionals,
792
+ required_keywords: required_keywords,
793
+ optional_keywords: optional_keywords,
794
+ rest_keywords: rest_keywords,
795
+ return_type: return_type
796
+ )
797
+ end
798
+
799
+ def empty?
800
+ required_positionals.empty? &&
801
+ optional_positionals.empty? &&
802
+ !rest_positionals &&
803
+ trailing_positionals.empty? &&
804
+ required_keywords.empty? &&
805
+ optional_keywords.empty? &&
806
+ !rest_keywords
807
+ end
808
+
809
+ def param_to_s
810
+ params = []
811
+ params.push(*required_positionals.map(&:to_s))
812
+ params.push(*optional_positionals.map {|p| "?#{p}"})
813
+ params.push("*#{rest_positionals}") if rest_positionals
814
+ params.push(*trailing_positionals.map(&:to_s))
815
+ params.push(*required_keywords.map {|name, param| "#{name}: #{param}" })
816
+ params.push(*optional_keywords.map {|name, param| "?#{name}: #{param}" })
817
+ params.push("**#{rest_keywords}") if rest_keywords
818
+
819
+ params.join(", ")
820
+ end
821
+
822
+ def return_to_s
823
+ return_type.to_s(1)
824
+ end
825
+
826
+ def drop_head
827
+ case
828
+ when !required_positionals.empty?
829
+ [
830
+ required_positionals[0],
831
+ update(required_positionals: required_positionals.drop(1))
832
+ ]
833
+ when !optional_positionals.empty?
834
+ [
835
+ optional_positionals[0],
836
+ update(optional_positionals: optional_positionals.drop(1))
837
+ ]
838
+ else
839
+ raise "Cannot #drop_head"
840
+ end
841
+ end
842
+
843
+ def drop_tail
844
+ case
845
+ when !trailing_positionals.empty?
846
+ [
847
+ trailing_positionals.last,
848
+ update(trailing_positionals: trailing_positionals.take(trailing_positionals.size - 1))
849
+ ]
850
+ else
851
+ raise "Cannot #drop_tail"
852
+ end
853
+ end
854
+
855
+ def has_keyword?
856
+ !required_keywords.empty? || !optional_keywords.empty? || rest_keywords
857
+ end
858
+ end
859
+
860
+ class Proc
861
+ attr_reader :type
862
+ attr_reader :location
863
+
864
+ def initialize(location:, type:)
865
+ @type = type
866
+ @location = location
867
+ end
868
+
869
+ def ==(other)
870
+ other.is_a?(Proc) && other.type == type
871
+ end
872
+
873
+ alias eql? ==
874
+
875
+ def hash
876
+ self.class.hash ^ type.hash
877
+ end
878
+
879
+ def free_variables(set)
880
+ type.free_variables(set)
881
+ end
882
+
883
+ def to_json(*a)
884
+ { class: :proc, type: type, location: location }.to_json(*a)
885
+ end
886
+
887
+ def sub(s)
888
+ self.class.new(type: type.sub(s), location: location)
889
+ end
890
+
891
+ def to_s(level = 0)
892
+ "^(#{type.param_to_s}) -> #{type.return_to_s}".lstrip
893
+ end
894
+
895
+ def each_type(&block)
896
+ if block_given?
897
+ type.each_type(&block)
898
+ else
899
+ enum_for :each_type
900
+ end
901
+ end
902
+ end
903
+
904
+ class Literal
905
+ attr_reader :literal
906
+ attr_reader :location
907
+
908
+ def initialize(literal:, location:)
909
+ @literal = literal
910
+ @location = location
911
+ end
912
+
913
+ def ==(other)
914
+ other.is_a?(Literal) && other.literal == literal
915
+ end
916
+
917
+ alias eql? ==
918
+
919
+ def hash
920
+ self.class.hash ^ literal.hash
921
+ end
922
+
923
+ include NoFreeVariables
924
+ include NoSubst
925
+ include EmptyEachType
926
+
927
+ def to_json(*a)
928
+ { class: :literal, literal: literal.inspect, location: location }.to_json(*a)
929
+ end
930
+
931
+ def to_s(level = 0)
932
+ literal.inspect
933
+ end
934
+ end
935
+ end
936
+ end