steep 0.1.0.pre2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +1 -1
  3. data/README.md +146 -33
  4. data/bin/smoke_runner.rb +43 -10
  5. data/lib/steep/ast/annotation/collection.rb +93 -0
  6. data/lib/steep/ast/annotation.rb +131 -0
  7. data/lib/steep/ast/buffer.rb +47 -0
  8. data/lib/steep/ast/location.rb +82 -0
  9. data/lib/steep/ast/method_type.rb +116 -0
  10. data/lib/steep/ast/signature/class.rb +33 -0
  11. data/lib/steep/ast/signature/const.rb +17 -0
  12. data/lib/steep/ast/signature/env.rb +123 -0
  13. data/lib/steep/ast/signature/extension.rb +21 -0
  14. data/lib/steep/ast/signature/gvar.rb +17 -0
  15. data/lib/steep/ast/signature/interface.rb +31 -0
  16. data/lib/steep/ast/signature/members.rb +71 -0
  17. data/lib/steep/ast/signature/module.rb +21 -0
  18. data/lib/steep/ast/type_params.rb +13 -0
  19. data/lib/steep/ast/types/any.rb +39 -0
  20. data/lib/steep/ast/types/bot.rb +39 -0
  21. data/lib/steep/ast/types/class.rb +35 -0
  22. data/lib/steep/ast/types/helper.rb +21 -0
  23. data/lib/steep/ast/types/instance.rb +39 -0
  24. data/lib/steep/ast/types/intersection.rb +74 -0
  25. data/lib/steep/ast/types/name.rb +124 -0
  26. data/lib/steep/ast/types/self.rb +39 -0
  27. data/lib/steep/ast/types/top.rb +39 -0
  28. data/lib/steep/ast/types/union.rb +74 -0
  29. data/lib/steep/ast/types/var.rb +57 -0
  30. data/lib/steep/ast/types/void.rb +35 -0
  31. data/lib/steep/cli.rb +28 -1
  32. data/lib/steep/drivers/annotations.rb +32 -0
  33. data/lib/steep/drivers/check.rb +53 -77
  34. data/lib/steep/drivers/scaffold.rb +303 -0
  35. data/lib/steep/drivers/utils/each_signature.rb +66 -0
  36. data/lib/steep/drivers/utils/validator.rb +115 -0
  37. data/lib/steep/drivers/validate.rb +39 -0
  38. data/lib/steep/errors.rb +291 -19
  39. data/lib/steep/interface/abstract.rb +44 -0
  40. data/lib/steep/interface/builder.rb +470 -0
  41. data/lib/steep/interface/instantiated.rb +126 -0
  42. data/lib/steep/interface/ivar_chain.rb +26 -0
  43. data/lib/steep/interface/method.rb +60 -0
  44. data/lib/steep/{interface.rb → interface/method_type.rb} +111 -100
  45. data/lib/steep/interface/substitution.rb +65 -0
  46. data/lib/steep/module_name.rb +116 -0
  47. data/lib/steep/parser.rb +1314 -814
  48. data/lib/steep/parser.y +536 -175
  49. data/lib/steep/source.rb +220 -25
  50. data/lib/steep/subtyping/check.rb +673 -0
  51. data/lib/steep/subtyping/constraints.rb +275 -0
  52. data/lib/steep/subtyping/relation.rb +41 -0
  53. data/lib/steep/subtyping/result.rb +126 -0
  54. data/lib/steep/subtyping/trace.rb +48 -0
  55. data/lib/steep/subtyping/variable_occurrence.rb +49 -0
  56. data/lib/steep/subtyping/variable_variance.rb +69 -0
  57. data/lib/steep/type_construction.rb +1630 -524
  58. data/lib/steep/type_inference/block_params.rb +100 -0
  59. data/lib/steep/type_inference/constant_env.rb +55 -0
  60. data/lib/steep/type_inference/send_args.rb +222 -0
  61. data/lib/steep/type_inference/type_env.rb +226 -0
  62. data/lib/steep/type_name.rb +27 -7
  63. data/lib/steep/typing.rb +4 -0
  64. data/lib/steep/version.rb +1 -1
  65. data/lib/steep.rb +71 -16
  66. data/smoke/and/a.rb +4 -2
  67. data/smoke/array/a.rb +4 -5
  68. data/smoke/array/b.rb +4 -4
  69. data/smoke/block/a.rb +2 -2
  70. data/smoke/block/a.rbi +2 -0
  71. data/smoke/block/b.rb +15 -0
  72. data/smoke/case/a.rb +3 -3
  73. data/smoke/class/a.rb +3 -3
  74. data/smoke/class/b.rb +0 -2
  75. data/smoke/class/d.rb +2 -2
  76. data/smoke/class/e.rb +1 -1
  77. data/smoke/class/f.rb +2 -2
  78. data/smoke/class/g.rb +8 -0
  79. data/smoke/const/a.rb +3 -3
  80. data/smoke/dstr/a.rb +1 -1
  81. data/smoke/ensure/a.rb +22 -0
  82. data/smoke/enumerator/a.rb +6 -6
  83. data/smoke/enumerator/b.rb +22 -0
  84. data/smoke/extension/a.rb +2 -2
  85. data/smoke/extension/b.rb +3 -3
  86. data/smoke/extension/c.rb +1 -1
  87. data/smoke/hello/hello.rb +2 -2
  88. data/smoke/if/a.rb +4 -2
  89. data/smoke/kwbegin/a.rb +8 -0
  90. data/smoke/literal/a.rb +5 -5
  91. data/smoke/method/a.rb +5 -5
  92. data/smoke/method/a.rbi +4 -0
  93. data/smoke/method/b.rb +29 -0
  94. data/smoke/module/a.rb +3 -3
  95. data/smoke/module/a.rbi +9 -0
  96. data/smoke/module/b.rb +2 -2
  97. data/smoke/module/c.rb +1 -1
  98. data/smoke/module/d.rb +5 -0
  99. data/smoke/module/e.rb +13 -0
  100. data/smoke/module/f.rb +13 -0
  101. data/smoke/rescue/a.rb +62 -0
  102. data/smoke/super/a.rb +2 -2
  103. data/smoke/type_case/a.rb +35 -0
  104. data/smoke/yield/a.rb +2 -2
  105. data/stdlib/builtin.rbi +463 -24
  106. data/steep.gemspec +3 -2
  107. metadata +91 -29
  108. data/lib/steep/annotation.rb +0 -223
  109. data/lib/steep/signature/class.rb +0 -450
  110. data/lib/steep/signature/extension.rb +0 -51
  111. data/lib/steep/signature/interface.rb +0 -49
  112. data/lib/steep/types/any.rb +0 -31
  113. data/lib/steep/types/class.rb +0 -27
  114. data/lib/steep/types/instance.rb +0 -27
  115. data/lib/steep/types/merge.rb +0 -32
  116. data/lib/steep/types/name.rb +0 -57
  117. data/lib/steep/types/union.rb +0 -42
  118. data/lib/steep/types/var.rb +0 -38
  119. data/lib/steep/types.rb +0 -4
@@ -1,450 +0,0 @@
1
- module Steep
2
- module Signature
3
- module Members
4
- class InstanceMethod
5
- # @implements Steep__SignatureMember__Method
6
-
7
- # @dynamic name
8
- attr_reader :name
9
- # @dynamic types
10
- attr_reader :types
11
-
12
- attr_reader :constructor
13
-
14
- def initialize(name:, types:, constructor:)
15
- @name = name
16
- @types = types
17
- @constructor = constructor
18
- end
19
-
20
- def ==(other)
21
- other.is_a?(self.class) && other.name == name && other.types == types && other.constructor == constructor
22
- end
23
- end
24
-
25
- class ModuleMethod
26
- # @implements Steep__SignatureMember__Method
27
-
28
- # @dynamic name
29
- attr_reader :name
30
- # @dynamic types
31
- attr_reader :types
32
- attr_reader :constructor
33
-
34
- def initialize(name:, types:, constructor:)
35
- @name = name
36
- @types = types
37
- @constructor = constructor
38
- end
39
-
40
- def ==(other)
41
- other.is_a?(self.class) && other.name == name && other.types == types && other.constructor == constructor
42
- end
43
- end
44
-
45
- class ModuleInstanceMethod
46
- # @implements Steep__SignatureMember__Method
47
-
48
- # @dynamic name
49
- attr_reader :name
50
- # @dynamic types
51
- attr_reader :types
52
- attr_reader :constructor
53
-
54
- def initialize(name:, types:, constructor:)
55
- @name = name
56
- @types = types
57
- @constructor = constructor
58
- end
59
-
60
- def ==(other)
61
- other.is_a?(self.class) && other.name == name && other.types == types && other.constructor == constructor
62
- end
63
- end
64
-
65
- class Include
66
- # @implements Steep__SignatureMember__Include
67
-
68
- # @dynamic name
69
- attr_reader :name
70
-
71
- def initialize(name:)
72
- @name = name
73
- end
74
-
75
- def ==(other)
76
- other.is_a?(Include) && other.name == name
77
- end
78
- end
79
-
80
- class Extend
81
- # @implements Steep__SignatureMember__Extend
82
-
83
- # @dynamic name
84
- attr_reader :name
85
-
86
- def initialize(name:)
87
- @name = name
88
- end
89
-
90
- def ==(other)
91
- other.is_a?(Extend) && other.name == name
92
- end
93
- end
94
- end
95
-
96
- module WithMethods
97
- # @implements Steep__Signature__WithMethods
98
-
99
- def instance_methods(assignability:, klass:, instance:, params:)
100
- methods = super
101
-
102
- hash = type_application_hash(params)
103
-
104
- members.each do |member|
105
- case member
106
- when Members::Include
107
- # @type var include_member: Steep__SignatureMember__Include
108
- include_member = member
109
- module_signature = assignability.lookup_included_signature(include_member.name)
110
- merge_methods(methods, module_signature.instance_methods(assignability: assignability,
111
- klass: klass,
112
- instance: instance,
113
- params: module_signature.type_application_hash(include_member.name.params)))
114
-
115
- end
116
- end
117
-
118
- members.each do |member|
119
- case member
120
- when Members::InstanceMethod, Members::ModuleInstanceMethod
121
- # @type var method_member: Steep__SignatureMember__Method
122
- method_member = member
123
- method_types = method_member.types.map {|type| type.substitute(klass: klass, instance: instance, params: hash) }
124
-
125
- attributes = [].tap do |attrs|
126
- attrs.push(:constructor) if method_member.constructor
127
- end
128
-
129
- merge_methods(methods,
130
- method_member.name => Steep::Interface::Method.new(types: method_types,
131
- super_method: nil,
132
- attributes: attributes))
133
- end
134
- end
135
-
136
- extensions = assignability.lookup_extensions(name)
137
- extensions.each do |extension|
138
- extension_methods = extension.instance_methods(assignability: assignability, klass: klass, instance: instance, params: [])
139
- merge_methods(methods, extension_methods)
140
- end
141
-
142
- methods
143
- end
144
-
145
- def module_methods(assignability:, klass:, instance:, params:, constructor:)
146
- methods = super
147
-
148
- members.each do |member|
149
- case member
150
- when Members::Include
151
- module_signature = assignability.lookup_included_signature(member.name)
152
- merge_methods(methods, module_signature.module_methods(assignability: assignability,
153
- klass: klass,
154
- instance: instance,
155
- params: module_signature.type_application_hash(member.name.params),
156
- constructor: constructor))
157
- when Members::Extend
158
- module_signature = assignability.lookup_included_signature(member.name)
159
- merge_methods(methods, module_signature.instance_methods(assignability: assignability,
160
- klass: klass,
161
- instance: instance,
162
- params: module_signature.type_application_hash(member.name.params)))
163
- end
164
- end
165
-
166
- members.each do |member|
167
- case member
168
- when Members::ModuleInstanceMethod, Members::ModuleMethod
169
- # @type var method_member: Steep__SignatureMember__Method
170
- method_member = member
171
- method_types = method_member.types.map {|type| type.substitute(klass: klass, instance: instance, params: {}) }
172
- merge_methods(methods,
173
- method_member.name => Steep::Interface::Method.new(types: method_types,
174
- super_method: nil,
175
- attributes: []))
176
- end
177
- end
178
-
179
- if is_class? && constructor
180
- instance_methods = instance_methods(assignability: assignability, klass: klass, instance: instance, params: params)
181
- new_method = if instance_methods[:initialize]
182
- types = instance_methods[:initialize].types.map do |method_type|
183
- method_type.updated(return_type: instance)
184
- end
185
- Steep::Interface::Method.new(types: types, super_method: nil, attributes: [])
186
- else
187
- Steep::Interface::Method.new(types: [Steep::Interface::MethodType.new(type_params: [],
188
- params: Steep::Interface::Params.empty,
189
- block: nil,
190
- return_type: instance)],
191
- super_method: nil,
192
- attributes: [])
193
- end
194
- methods[:new] = new_method
195
- end
196
-
197
- methods
198
- end
199
-
200
- def merge_methods(methods, hash)
201
- hash.each_key do |name|
202
- new_method = hash[name]
203
- old_method = methods[name]
204
- attributes = (new_method.attributes + (old_method&.attributes || [])).sort.uniq
205
-
206
- methods[name] = Steep::Interface::Method.new(types: new_method.types,
207
- super_method: old_method,
208
- attributes: attributes)
209
- end
210
- end
211
- end
212
-
213
- module WithMembers
214
- # @implements Steep__Signature__WithMembers
215
- def each_type
216
- if block_given?
217
- members.each do |member|
218
- case member
219
- when Members::InstanceMethod, Members::ModuleMethod, Members::ModuleInstanceMethod
220
- # @type var method_member: Steep__SignatureMember__Method
221
- method_member = member
222
- method_member.types.each do |method_type|
223
- method_type.params.each_type do |type|
224
- yield type
225
- end
226
- yield method_type.return_type
227
- if method_type.block
228
- method_type.block.params.each_type do |type|
229
- yield type
230
- end
231
- yield method_type.block.return_type
232
- end
233
- end
234
- when Members::Include, Members::Extend
235
- # @type var mixin_member: _Steep__SignatureMember__Mixin
236
- mixin_member = member
237
- yield mixin_member.name
238
- else
239
- raise "Unknown member: #{member.class.inspect}"
240
- end
241
- end
242
- else
243
- enum_for :each_type
244
- end
245
- end
246
-
247
- def validate_mixins(assignability, interface)
248
- members.each do |member|
249
- if member.is_a?(Members::Include)
250
- module_signature = assignability.lookup_included_signature(member.name)
251
-
252
- if module_signature.self_type
253
- self_type = module_signature.self_type.substitute(klass: Types::Name.module(name: name),
254
- instance: Types::Name.instance(name: name),
255
- params: {})
256
- self_interface = assignability.resolve_interface(self_type.name, member.name.params)
257
-
258
- unless assignability.test_interface(interface, self_interface, [])
259
- assignability.errors << Errors::InvalidSelfType.new(signature: self, member: member)
260
- end
261
- end
262
- end
263
- end
264
- end
265
- end
266
-
267
- module WithParams
268
- # @implements Steep__Signature__WithParams
269
-
270
- def type_application_hash(args)
271
- Hash[params.zip(args)]
272
- end
273
- end
274
-
275
- class Module
276
- # @implements Steep__Signature__Module
277
-
278
- # @dynamic name
279
- attr_reader :name
280
- # @dynamic params
281
- attr_reader :params
282
- # @dynamic members
283
- attr_reader :members
284
- # @dynamic self_type
285
- attr_reader :self_type
286
-
287
- prepend WithMethods
288
- include WithMembers
289
- include WithParams
290
-
291
- def initialize(name:, params:, members:, self_type:)
292
- @name = name
293
- @members = members
294
- @params = params
295
- @self_type = self_type
296
- end
297
-
298
- def ==(other)
299
- other.is_a?(Module) && other.name == name && other.params == params && other.members == members && other.self_type == self_type
300
- end
301
-
302
- def instance_methods(assignability:, klass:, instance:, params:)
303
- {}
304
- end
305
-
306
- def module_methods(assignability:, klass:, instance:, params:, constructor:)
307
- {}
308
- end
309
-
310
- def each_type
311
- if block_given?
312
- yield self_type if self_type
313
- super do |type|
314
- yield type
315
- end
316
- else
317
- enum_for :each_type
318
- end
319
- end
320
-
321
- def validate(assignability)
322
- each_type do |type|
323
- assignability.validate_type_presence self, type
324
- end
325
-
326
- interface = assignability.resolve_interface(TypeName::Instance.new(name: name),
327
- params.map {|x| Types::Var.new(name: x) })
328
-
329
- validate_mixins(assignability, interface)
330
-
331
- # FIXME: There is no check for initializer compatibility
332
- if interface.methods.values.any? {|method| method.attributes.include?(:constructor) }
333
- assignability.errors << Signature::Errors::ConstructorNoCheck.new(signature: self)
334
- end
335
- end
336
-
337
- def is_class?
338
- false
339
- end
340
- end
341
-
342
- class Class
343
- # @implements Steep__Signature__Class
344
-
345
- # @dynamic name
346
- attr_reader :name
347
- # @dynamic params
348
- attr_reader :params
349
- # @dynamic members
350
- attr_reader :members
351
- # @dynamic super_class
352
- attr_reader :super_class
353
-
354
- prepend WithMethods
355
- include WithMembers
356
- include WithParams
357
-
358
- def initialize(name:, params:, members:, super_class:)
359
- @name = name
360
- @members = members
361
- @params = params
362
- @super_class = super_class
363
- end
364
-
365
- def ==(other)
366
- other.is_a?(Class) && other.name == name && other.params == params && other.members == members && other.super_class == super_class
367
- end
368
-
369
- def instance_methods(assignability:, klass:, instance:, params:)
370
- if self.name == :BasicObject
371
- {}
372
- else
373
- super_class = self.super_class || Types::Name.instance(name: :Object)
374
- signature = assignability.lookup_super_class_signature(super_class)
375
-
376
- hash = type_application_hash(params)
377
- super_class_params = super_class.params.map do |type|
378
- type.substitute(klass: klass, instance: instance, params: hash)
379
- end
380
-
381
- signature.instance_methods(assignability: assignability, klass: klass, instance: instance, params: super_class_params)
382
- end
383
- end
384
-
385
- def module_methods(assignability:, klass:, instance:, params:, constructor:)
386
- signature = assignability.lookup_class_signature(Types::Name.instance(name: :Class))
387
- class_methods = signature.instance_methods(assignability: assignability,
388
- klass: klass,
389
- instance: instance,
390
- params: [instance])
391
- if self.name == :BasicObject
392
- class_methods
393
- else
394
- super_class = self.super_class || Types::Name.instance(name: :Object)
395
- signature = assignability.lookup_super_class_signature(super_class)
396
-
397
- hash = type_application_hash(params)
398
- super_class_params = super_class.params.map do |type|
399
- type.substitute(klass: klass, instance: instance, params: hash)
400
- end
401
-
402
- class_methods.merge!(signature.module_methods(assignability: assignability,
403
- klass: klass,
404
- instance: instance,
405
- params: super_class_params,
406
- constructor: constructor))
407
- end
408
- end
409
-
410
- def each_type
411
- if block_given?
412
- yield super_class if super_class
413
- super do |type|
414
- yield type
415
- end
416
- else
417
- enum_for :each_type
418
- end
419
- end
420
-
421
- def validate(assignability)
422
- each_type do |type|
423
- assignability.validate_type_presence self, type
424
- end
425
-
426
- interface = assignability.resolve_interface(TypeName::Instance.new(name: name),
427
- params.map {|x| Types::Var.new(name: x) },
428
- constructor: true)
429
-
430
- interface.methods.each_key do |method_name|
431
- method = interface.methods[method_name]
432
- if method.super_method
433
- assignability.validate_method_compatibility(self, method_name, method)
434
- end
435
- end
436
-
437
- validate_mixins(assignability, interface)
438
-
439
- # FIXME: There is no check for initializer compatibility
440
- if interface.methods.values.any? {|method| method.attributes.include?(:constructor) }
441
- assignability.errors << Signature::Errors::ConstructorNoCheck.new(signature: self)
442
- end
443
- end
444
-
445
- def is_class?
446
- true
447
- end
448
- end
449
- end
450
- end
@@ -1,51 +0,0 @@
1
- module Steep
2
- module Signature
3
- class Extension
4
- # @implements Steep__Signature__Extension
5
-
6
- def initialize(module_name:, extension_name:, members:)
7
- @module_name = module_name
8
- @extension_name = extension_name
9
- @members = members
10
- end
11
-
12
- def module_name; @module_name; end
13
- def extension_name; @extension_name; end
14
- def members; @members; end
15
-
16
- def ==(other)
17
- # @type var other_: Steep__Signature__Extension
18
- other_ = other
19
- other.is_a?(self.class) &&
20
- other_.module_name == module_name &&
21
- other_.extension_name == extension_name &&
22
- other_.members == members
23
- end
24
-
25
- def name
26
- :"#{module_name} (#{extension_name})"
27
- end
28
-
29
- include WithMembers
30
- prepend WithMethods
31
-
32
- def validate(assignability)
33
- each_type do |type|
34
- assignability.validate_type_presence self, type
35
- end
36
- end
37
-
38
- def instance_methods(assignability:, klass:, instance:, params:)
39
- {}
40
- end
41
-
42
- def module_methods(assignability:, klass:, instance:, params:)
43
- {}
44
- end
45
-
46
- def type_application_hash(args)
47
- {}
48
- end
49
- end
50
- end
51
- end
@@ -1,49 +0,0 @@
1
- module Steep
2
- module Signature
3
- class Interface
4
- # @implements Steep__Signature__Interface
5
- # @type const Hash: Hash.class
6
- # @type const Interface: Steep__Signature__Interface.class
7
- # @type const Steep::Interface: Steep__Interface.class
8
- # @type const Steep::Interface::Method: Steep__Method.class
9
-
10
- # @dynamic name
11
- attr_reader :name
12
- # @dynamic params
13
- attr_reader :params
14
- # @dynamic methods
15
- attr_reader :methods
16
-
17
- def initialize(name:, params:, methods:)
18
- @name = name
19
- @params = params
20
- @methods = methods
21
- end
22
-
23
- def ==(other)
24
- # @type var other_: Steep__Signature__Interface
25
- other_ = other
26
- other_.is_a?(Interface) && other_.name == name && other_.params == params && other_.methods == methods
27
- end
28
-
29
- def to_interface(klass:, instance:, params:)
30
- raise "Invalid type application: expected: #{self.params.size}, actual: #{params.size}" if params.size != self.params.size
31
-
32
- # @type var map: Hash<Symbol, Steep__Type>
33
- map = Hash[self.params.zip(params)]
34
- Steep::Interface.new(name: name,
35
- params: params,
36
- methods: methods.transform_values {|method|
37
- types = method.map {|method_type|
38
- method_type.substitute(klass: klass, instance: instance, params: map)
39
- }
40
- Steep::Interface::Method.new(types: types, super_method: nil, attributes: [])
41
- })
42
- end
43
-
44
- def validate(assignability)
45
-
46
- end
47
- end
48
- end
49
- end
@@ -1,31 +0,0 @@
1
- module Steep
2
- module Types
3
- class Any
4
- # @implements Steep__Types__Any
5
-
6
- def ==(other)
7
- other.is_a?(Any)
8
- end
9
-
10
- def hash
11
- self.class.hash
12
- end
13
-
14
- def eql?(other)
15
- other == self
16
- end
17
-
18
- def closed?
19
- true
20
- end
21
-
22
- def substitute(klass:, instance:, params:)
23
- self
24
- end
25
-
26
- def to_s
27
- "any"
28
- end
29
- end
30
- end
31
- end
@@ -1,27 +0,0 @@
1
- module Steep
2
- module Types
3
- class Class
4
- # @implements Steep__Types__Class
5
-
6
- def ==(other)
7
- other.is_a?(Class)
8
- end
9
-
10
- def hash
11
- self.class.hash
12
- end
13
-
14
- def eql?(other)
15
- self == other
16
- end
17
-
18
- def closed?
19
- false
20
- end
21
-
22
- def substitute(klass:, instance:, params:)
23
- klass
24
- end
25
- end
26
- end
27
- end
@@ -1,27 +0,0 @@
1
- module Steep
2
- module Types
3
- class Instance
4
- # @implements Steep__Types__Instance
5
-
6
- def ==(other)
7
- other.is_a?(Instance)
8
- end
9
-
10
- def eql?(other)
11
- self == other
12
- end
13
-
14
- def hash
15
- self.class.hash
16
- end
17
-
18
- def closed?
19
- false
20
- end
21
-
22
- def substitute(klass:, instance:, params:)
23
- instance
24
- end
25
- end
26
- end
27
- end
@@ -1,32 +0,0 @@
1
- module Steep
2
- module Types
3
- class Merge
4
- # @implements Steep__Types__Merge
5
-
6
- # @dynamic types
7
- attr_reader :types
8
-
9
- def initialize(types:)
10
- @types = types
11
- end
12
-
13
- def ==(other)
14
- # @type var other_: Steep__Types__Merge
15
- other_ = other
16
- other_.is_a?(self.class) && other_.types == types
17
- end
18
-
19
- def hash
20
- self.class.hash ^ types.hash
21
- end
22
-
23
- def eql?(other)
24
- other == self
25
- end
26
-
27
- def to_s
28
- types.join(" + ")
29
- end
30
- end
31
- end
32
- end