steep 0.36.0 → 0.37.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/steep.rb +2 -0
- data/lib/steep/ast/types/factory.rb +112 -53
- data/lib/steep/ast/types/proc.rb +32 -20
- data/lib/steep/interface/block.rb +79 -0
- data/lib/steep/interface/function.rb +770 -0
- data/lib/steep/interface/method_type.rb +32 -812
- data/lib/steep/subtyping/check.rb +19 -16
- data/lib/steep/subtyping/variable_occurrence.rb +2 -2
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +76 -50
- data/lib/steep/type_inference/block_params.rb +1 -1
- data/lib/steep/version.rb +1 -1
- data/smoke/tsort/Steepfile +6 -0
- data/smoke/tsort/a.rb +15 -0
- data/steep.gemspec +1 -1
- metadata +10 -6
@@ -1,810 +1,37 @@
|
|
1
1
|
module Steep
|
2
2
|
module Interface
|
3
|
-
class Params
|
4
|
-
attr_reader :required
|
5
|
-
attr_reader :optional
|
6
|
-
attr_reader :rest
|
7
|
-
attr_reader :required_keywords
|
8
|
-
attr_reader :optional_keywords
|
9
|
-
attr_reader :rest_keywords
|
10
|
-
|
11
|
-
def initialize(required:, optional:, rest:, required_keywords:, optional_keywords:, rest_keywords:)
|
12
|
-
@required = required
|
13
|
-
@optional = optional
|
14
|
-
@rest = rest
|
15
|
-
@required_keywords = required_keywords
|
16
|
-
@optional_keywords = optional_keywords
|
17
|
-
@rest_keywords = rest_keywords
|
18
|
-
end
|
19
|
-
|
20
|
-
def update(required: self.required, optional: self.optional, rest: self.rest, required_keywords: self.required_keywords, optional_keywords: self.optional_keywords, rest_keywords: self.rest_keywords)
|
21
|
-
self.class.new(
|
22
|
-
required: required,
|
23
|
-
optional: optional,
|
24
|
-
rest: rest,
|
25
|
-
required_keywords: required_keywords,
|
26
|
-
optional_keywords: optional_keywords,
|
27
|
-
rest_keywords: rest_keywords,
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
RequiredPositional = Struct.new(:type)
|
32
|
-
OptionalPositional = Struct.new(:type)
|
33
|
-
RestPositional = Struct.new(:type)
|
34
|
-
|
35
|
-
def first_param
|
36
|
-
case
|
37
|
-
when !required.empty?
|
38
|
-
RequiredPositional.new(required[0])
|
39
|
-
when !optional.empty?
|
40
|
-
OptionalPositional.new(optional[0])
|
41
|
-
when rest
|
42
|
-
RestPositional.new(rest)
|
43
|
-
else
|
44
|
-
nil
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def with_first_param(param)
|
49
|
-
case param
|
50
|
-
when RequiredPositional
|
51
|
-
update(required: [param.type] + required)
|
52
|
-
when OptionalPositional
|
53
|
-
update(optional: [param.type] + required)
|
54
|
-
when RestPositional
|
55
|
-
update(rest: param.type)
|
56
|
-
else
|
57
|
-
self
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def has_positional?
|
62
|
-
first_param
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.empty
|
66
|
-
self.new(
|
67
|
-
required: [],
|
68
|
-
optional: [],
|
69
|
-
rest: nil,
|
70
|
-
required_keywords: {},
|
71
|
-
optional_keywords: {},
|
72
|
-
rest_keywords: nil
|
73
|
-
)
|
74
|
-
end
|
75
|
-
|
76
|
-
def ==(other)
|
77
|
-
other.is_a?(self.class) &&
|
78
|
-
other.required == required &&
|
79
|
-
other.optional == optional &&
|
80
|
-
other.rest == rest &&
|
81
|
-
other.required_keywords == required_keywords &&
|
82
|
-
other.optional_keywords == optional_keywords &&
|
83
|
-
other.rest_keywords == rest_keywords
|
84
|
-
end
|
85
|
-
|
86
|
-
alias eql? ==
|
87
|
-
|
88
|
-
def hash
|
89
|
-
required.hash ^ optional.hash ^ rest.hash ^ required_keywords.hash ^ optional_keywords.hash ^ rest_keywords.hash
|
90
|
-
end
|
91
|
-
|
92
|
-
def flat_unnamed_params
|
93
|
-
required.map {|p| [:required, p] } + optional.map {|p| [:optional, p] }
|
94
|
-
end
|
95
|
-
|
96
|
-
def flat_keywords
|
97
|
-
required_keywords.merge optional_keywords
|
98
|
-
end
|
99
|
-
|
100
|
-
def has_keywords?
|
101
|
-
!required_keywords.empty? || !optional_keywords.empty? || rest_keywords
|
102
|
-
end
|
103
|
-
|
104
|
-
def without_keywords
|
105
|
-
self.class.new(
|
106
|
-
required: required,
|
107
|
-
optional: optional,
|
108
|
-
rest: rest,
|
109
|
-
required_keywords: {},
|
110
|
-
optional_keywords: {},
|
111
|
-
rest_keywords: nil
|
112
|
-
)
|
113
|
-
end
|
114
|
-
|
115
|
-
def drop_first
|
116
|
-
case
|
117
|
-
when required.any? || optional.any? || rest
|
118
|
-
self.class.new(
|
119
|
-
required: required.any? ? required.drop(1) : [],
|
120
|
-
optional: required.empty? && optional.any? ? optional.drop(1) : optional,
|
121
|
-
rest: required.empty? && optional.empty? ? nil : rest,
|
122
|
-
required_keywords: required_keywords,
|
123
|
-
optional_keywords: optional_keywords,
|
124
|
-
rest_keywords: rest_keywords
|
125
|
-
)
|
126
|
-
when has_keywords?
|
127
|
-
without_keywords
|
128
|
-
else
|
129
|
-
raise "Cannot drop from empty params"
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def each_missing_argument(args)
|
134
|
-
required.size.times do |index|
|
135
|
-
if index >= args.size
|
136
|
-
yield index
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def each_extra_argument(args)
|
142
|
-
return if rest
|
143
|
-
|
144
|
-
if has_keywords?
|
145
|
-
args = args.take(args.count - 1) if args.count > 0
|
146
|
-
end
|
147
|
-
|
148
|
-
args.size.times do |index|
|
149
|
-
if index >= required.count + optional.count
|
150
|
-
yield index
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def each_missing_keyword(args)
|
156
|
-
return unless has_keywords?
|
157
|
-
|
158
|
-
keywords, rest = extract_keywords(args)
|
159
|
-
|
160
|
-
return unless rest.empty?
|
161
|
-
|
162
|
-
required_keywords.each do |keyword, _|
|
163
|
-
yield keyword unless keywords.key?(keyword)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def each_extra_keyword(args)
|
168
|
-
return unless has_keywords?
|
169
|
-
return if rest_keywords
|
170
|
-
|
171
|
-
keywords, rest = extract_keywords(args)
|
172
|
-
|
173
|
-
return unless rest.empty?
|
174
|
-
|
175
|
-
all_keywords = flat_keywords
|
176
|
-
keywords.each do |keyword, _|
|
177
|
-
yield keyword unless all_keywords.key?(keyword)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
def extract_keywords(args)
|
182
|
-
last_arg = args.last
|
183
|
-
|
184
|
-
keywords = {}
|
185
|
-
rest = []
|
186
|
-
|
187
|
-
if last_arg&.type == :hash
|
188
|
-
last_arg.children.each do |element|
|
189
|
-
case element.type
|
190
|
-
when :pair
|
191
|
-
if element.children[0].type == :sym
|
192
|
-
name = element.children[0].children[0]
|
193
|
-
keywords[name] = element.children[1]
|
194
|
-
end
|
195
|
-
when :kwsplat
|
196
|
-
rest << element.children[0]
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
[keywords, rest]
|
202
|
-
end
|
203
|
-
|
204
|
-
def each_type()
|
205
|
-
if block_given?
|
206
|
-
flat_unnamed_params.each do |(_, type)|
|
207
|
-
yield type
|
208
|
-
end
|
209
|
-
flat_keywords.each do |_, type|
|
210
|
-
yield type
|
211
|
-
end
|
212
|
-
rest and yield rest
|
213
|
-
rest_keywords and yield rest_keywords
|
214
|
-
else
|
215
|
-
enum_for :each_type
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
def free_variables()
|
220
|
-
@fvs ||= Set.new.tap do |set|
|
221
|
-
each_type do |type|
|
222
|
-
set.merge(type.free_variables)
|
223
|
-
end
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
def closed?
|
228
|
-
required.all?(&:closed?) && optional.all?(&:closed?) && (!rest || rest.closed?) && required_keywords.values.all?(&:closed?) && optional_keywords.values.all?(&:closed?) && (!rest_keywords || rest_keywords.closed?)
|
229
|
-
end
|
230
|
-
|
231
|
-
def subst(s)
|
232
|
-
return self if s.empty?
|
233
|
-
return self if empty?
|
234
|
-
return self if free_variables.disjoint?(s.domain)
|
235
|
-
|
236
|
-
rs = required.map {|t| t.subst(s) }
|
237
|
-
os = optional.map {|t| t.subst(s) }
|
238
|
-
r = rest&.subst(s)
|
239
|
-
rk = required_keywords.transform_values {|t| t.subst(s) }
|
240
|
-
ok = optional_keywords.transform_values {|t| t.subst(s) }
|
241
|
-
k = rest_keywords&.subst(s)
|
242
|
-
|
243
|
-
if rs == required && os == optional && r == rest && rk == required_keywords && ok == optional_keywords && k == rest_keywords
|
244
|
-
self
|
245
|
-
else
|
246
|
-
self.class.new(
|
247
|
-
required: required.map {|t| t.subst(s) },
|
248
|
-
optional: optional.map {|t| t.subst(s) },
|
249
|
-
rest: rest&.subst(s),
|
250
|
-
required_keywords: required_keywords.transform_values {|t| t.subst(s) },
|
251
|
-
optional_keywords: optional_keywords.transform_values {|t| t.subst(s) },
|
252
|
-
rest_keywords: rest_keywords&.subst(s)
|
253
|
-
)
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
def size
|
258
|
-
required.size + optional.size + (rest ? 1 : 0) + required_keywords.size + optional_keywords.size + (rest_keywords ? 1 : 0)
|
259
|
-
end
|
260
|
-
|
261
|
-
def to_s
|
262
|
-
required = self.required.map {|ty| ty.to_s }
|
263
|
-
optional = self.optional.map {|ty| "?#{ty}" }
|
264
|
-
rest = self.rest ? ["*#{self.rest}"] : []
|
265
|
-
required_keywords = self.required_keywords.map {|name, type| "#{name}: #{type}" }
|
266
|
-
optional_keywords = self.optional_keywords.map {|name, type| "?#{name}: #{type}"}
|
267
|
-
rest_keywords = self.rest_keywords ? ["**#{self.rest_keywords}"] : []
|
268
|
-
"(#{(required + optional + rest + required_keywords + optional_keywords + rest_keywords).join(", ")})"
|
269
|
-
end
|
270
|
-
|
271
|
-
def map_type(&block)
|
272
|
-
self.class.new(
|
273
|
-
required: required.map(&block),
|
274
|
-
optional: optional.map(&block),
|
275
|
-
rest: rest && yield(rest),
|
276
|
-
required_keywords: required_keywords.transform_values(&block),
|
277
|
-
optional_keywords: optional_keywords.transform_values(&block),
|
278
|
-
rest_keywords: rest_keywords && yield(rest_keywords)
|
279
|
-
)
|
280
|
-
end
|
281
|
-
|
282
|
-
def empty?
|
283
|
-
!has_positional? && !has_keywords?
|
284
|
-
end
|
285
|
-
|
286
|
-
# self + params returns a new params for overloading.
|
287
|
-
#
|
288
|
-
def +(other)
|
289
|
-
a = first_param
|
290
|
-
b = other.first_param
|
291
|
-
|
292
|
-
case
|
293
|
-
when a.is_a?(RequiredPositional) && b.is_a?(RequiredPositional)
|
294
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
295
|
-
(self.drop_first + other.drop_first).with_first_param(RequiredPositional.new(type))
|
296
|
-
end
|
297
|
-
when a.is_a?(RequiredPositional) && b.is_a?(OptionalPositional)
|
298
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
299
|
-
(self.drop_first + other.drop_first).with_first_param(OptionalPositional.new(type))
|
300
|
-
end
|
301
|
-
when a.is_a?(RequiredPositional) && b.is_a?(RestPositional)
|
302
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
303
|
-
(self.drop_first + other).with_first_param(OptionalPositional.new(type))
|
304
|
-
end
|
305
|
-
when a.is_a?(RequiredPositional) && b.nil?
|
306
|
-
(self.drop_first + other).with_first_param(OptionalPositional.new(a.type))
|
307
|
-
when a.is_a?(OptionalPositional) && b.is_a?(RequiredPositional)
|
308
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
309
|
-
(self.drop_first + other.drop_first).with_first_param(OptionalPositional.new(type))
|
310
|
-
end
|
311
|
-
when a.is_a?(OptionalPositional) && b.is_a?(OptionalPositional)
|
312
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
313
|
-
(self.drop_first + other.drop_first).with_first_param(OptionalPositional.new(type))
|
314
|
-
end
|
315
|
-
when a.is_a?(OptionalPositional) && b.is_a?(RestPositional)
|
316
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
317
|
-
(self.drop_first + other).with_first_param(OptionalPositional.new(type))
|
318
|
-
end
|
319
|
-
when a.is_a?(OptionalPositional) && b.nil?
|
320
|
-
(self.drop_first + other).with_first_param(OptionalPositional.new(a.type))
|
321
|
-
when a.is_a?(RestPositional) && b.is_a?(RequiredPositional)
|
322
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
323
|
-
(self + other.drop_first).with_first_param(OptionalPositional.new(type))
|
324
|
-
end
|
325
|
-
when a.is_a?(RestPositional) && b.is_a?(OptionalPositional)
|
326
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
327
|
-
(self + other.drop_first).with_first_param(OptionalPositional.new(type))
|
328
|
-
end
|
329
|
-
when a.is_a?(RestPositional) && b.is_a?(RestPositional)
|
330
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
331
|
-
(self.drop_first + other.drop_first).with_first_param(RestPositional.new(type))
|
332
|
-
end
|
333
|
-
when a.is_a?(RestPositional) && b.nil?
|
334
|
-
(self.drop_first + other).with_first_param(RestPositional.new(a.type))
|
335
|
-
when a.nil? && b.is_a?(RequiredPositional)
|
336
|
-
(self + other.drop_first).with_first_param(OptionalPositional.new(b.type))
|
337
|
-
when a.nil? && b.is_a?(OptionalPositional)
|
338
|
-
(self + other.drop_first).with_first_param(OptionalPositional.new(b.type))
|
339
|
-
when a.nil? && b.is_a?(RestPositional)
|
340
|
-
(self + other.drop_first).with_first_param(RestPositional.new(b.type))
|
341
|
-
when a.nil? && b.nil?
|
342
|
-
required_keywords = {}
|
343
|
-
|
344
|
-
(Set.new(self.required_keywords.keys) & Set.new(other.required_keywords.keys)).each do |keyword|
|
345
|
-
required_keywords[keyword] = AST::Types::Union.build(
|
346
|
-
types: [
|
347
|
-
self.required_keywords[keyword],
|
348
|
-
other.required_keywords[keyword]
|
349
|
-
]
|
350
|
-
)
|
351
|
-
end
|
352
|
-
|
353
|
-
optional_keywords = {}
|
354
|
-
self.required_keywords.each do |keyword, t|
|
355
|
-
unless required_keywords.key?(keyword)
|
356
|
-
case
|
357
|
-
when other.optional_keywords.key?(keyword)
|
358
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, other.optional_keywords[keyword]])
|
359
|
-
when other.rest_keywords
|
360
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, other.rest_keywords])
|
361
|
-
else
|
362
|
-
optional_keywords[keyword] = t
|
363
|
-
end
|
364
|
-
end
|
365
|
-
end
|
366
|
-
other.required_keywords.each do |keyword, t|
|
367
|
-
unless required_keywords.key?(keyword)
|
368
|
-
case
|
369
|
-
when self.optional_keywords.key?(keyword)
|
370
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, self.optional_keywords[keyword]])
|
371
|
-
when self.rest_keywords
|
372
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, self.rest_keywords])
|
373
|
-
else
|
374
|
-
optional_keywords[keyword] = t
|
375
|
-
end
|
376
|
-
end
|
377
|
-
end
|
378
|
-
self.optional_keywords.each do |keyword, t|
|
379
|
-
unless optional_keywords.key?(keyword)
|
380
|
-
case
|
381
|
-
when other.optional_keywords.key?(keyword)
|
382
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, other.optional_keywords[keyword]])
|
383
|
-
when other.rest_keywords
|
384
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, other.rest_keywords])
|
385
|
-
else
|
386
|
-
optional_keywords[keyword] = t
|
387
|
-
end
|
388
|
-
end
|
389
|
-
end
|
390
|
-
other.optional_keywords.each do |keyword, t|
|
391
|
-
unless optional_keywords.key?(keyword)
|
392
|
-
case
|
393
|
-
when self.optional_keywords.key?(keyword)
|
394
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, self.optional_keywords[keyword]])
|
395
|
-
when self.rest_keywords
|
396
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, self.rest_keywords])
|
397
|
-
else
|
398
|
-
optional_keywords[keyword] = t
|
399
|
-
end
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
rest = case
|
404
|
-
when self.rest_keywords && other.rest_keywords
|
405
|
-
AST::Types::Union.build(types: [self.rest_keywords, other.rest_keywords])
|
406
|
-
else
|
407
|
-
self.rest_keywords || other.rest_keywords
|
408
|
-
end
|
409
|
-
|
410
|
-
Params.new(
|
411
|
-
required: [],
|
412
|
-
optional: [],
|
413
|
-
rest: nil,
|
414
|
-
required_keywords: required_keywords,
|
415
|
-
optional_keywords: optional_keywords,
|
416
|
-
rest_keywords: rest)
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
# Returns the intersection between self and other.
|
421
|
-
# Returns nil if the intersection cannot be computed.
|
422
|
-
#
|
423
|
-
def &(other)
|
424
|
-
a = first_param
|
425
|
-
b = other.first_param
|
426
|
-
|
427
|
-
case
|
428
|
-
when a.is_a?(RequiredPositional) && b.is_a?(RequiredPositional)
|
429
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
430
|
-
(self.drop_first & other.drop_first)&.with_first_param(RequiredPositional.new(type))
|
431
|
-
end
|
432
|
-
when a.is_a?(RequiredPositional) && b.is_a?(OptionalPositional)
|
433
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
434
|
-
(self.drop_first & other.drop_first)&.with_first_param(RequiredPositional.new(type))
|
435
|
-
end
|
436
|
-
when a.is_a?(RequiredPositional) && b.is_a?(RestPositional)
|
437
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
438
|
-
(self.drop_first & other)&.with_first_param(RequiredPositional.new(type))
|
439
|
-
end
|
440
|
-
when a.is_a?(RequiredPositional) && b.nil?
|
441
|
-
nil
|
442
|
-
when a.is_a?(OptionalPositional) && b.is_a?(RequiredPositional)
|
443
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
444
|
-
(self.drop_first & other.drop_first)&.with_first_param(RequiredPositional.new(type))
|
445
|
-
end
|
446
|
-
when a.is_a?(OptionalPositional) && b.is_a?(OptionalPositional)
|
447
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
448
|
-
(self.drop_first & other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
449
|
-
end
|
450
|
-
when a.is_a?(OptionalPositional) && b.is_a?(RestPositional)
|
451
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
452
|
-
(self.drop_first & other)&.with_first_param(OptionalPositional.new(type))
|
453
|
-
end
|
454
|
-
when a.is_a?(OptionalPositional) && b.nil?
|
455
|
-
self.drop_first & other
|
456
|
-
when a.is_a?(RestPositional) && b.is_a?(RequiredPositional)
|
457
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
458
|
-
(self & other.drop_first)&.with_first_param(RequiredPositional.new(type))
|
459
|
-
end
|
460
|
-
when a.is_a?(RestPositional) && b.is_a?(OptionalPositional)
|
461
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
462
|
-
(self & other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
463
|
-
end
|
464
|
-
when a.is_a?(RestPositional) && b.is_a?(RestPositional)
|
465
|
-
AST::Types::Intersection.build(types: [a.type, b.type]).yield_self do |type|
|
466
|
-
(self.drop_first & other.drop_first)&.with_first_param(RestPositional.new(type))
|
467
|
-
end
|
468
|
-
when a.is_a?(RestPositional) && b.nil?
|
469
|
-
self.drop_first & other
|
470
|
-
when a.nil? && b.is_a?(RequiredPositional)
|
471
|
-
nil
|
472
|
-
when a.nil? && b.is_a?(OptionalPositional)
|
473
|
-
self & other.drop_first
|
474
|
-
when a.nil? && b.is_a?(RestPositional)
|
475
|
-
self & other.drop_first
|
476
|
-
when a.nil? && b.nil?
|
477
|
-
optional_keywords = {}
|
478
|
-
|
479
|
-
(Set.new(self.optional_keywords.keys) & Set.new(other.optional_keywords.keys)).each do |keyword|
|
480
|
-
optional_keywords[keyword] = AST::Types::Intersection.build(
|
481
|
-
types: [
|
482
|
-
self.optional_keywords[keyword],
|
483
|
-
other.optional_keywords[keyword]
|
484
|
-
]
|
485
|
-
)
|
486
|
-
end
|
487
|
-
|
488
|
-
required_keywords = {}
|
489
|
-
self.optional_keywords.each do |keyword, t|
|
490
|
-
unless optional_keywords.key?(keyword)
|
491
|
-
case
|
492
|
-
when other.required_keywords.key?(keyword)
|
493
|
-
required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.required_keywords[keyword]])
|
494
|
-
when other.rest_keywords
|
495
|
-
optional_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.rest_keywords])
|
496
|
-
end
|
497
|
-
end
|
498
|
-
end
|
499
|
-
other.optional_keywords.each do |keyword, t|
|
500
|
-
unless optional_keywords.key?(keyword)
|
501
|
-
case
|
502
|
-
when self.required_keywords.key?(keyword)
|
503
|
-
required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.required_keywords[keyword]])
|
504
|
-
when self.rest_keywords
|
505
|
-
optional_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.rest_keywords])
|
506
|
-
end
|
507
|
-
end
|
508
|
-
end
|
509
|
-
self.required_keywords.each do |keyword, t|
|
510
|
-
unless required_keywords.key?(keyword)
|
511
|
-
case
|
512
|
-
when other.required_keywords.key?(keyword)
|
513
|
-
required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.required_keywords[keyword]])
|
514
|
-
when other.rest_keywords
|
515
|
-
required_keywords[keyword] = AST::Types::Intersection.build(types: [t, other.rest_keywords])
|
516
|
-
else
|
517
|
-
return
|
518
|
-
end
|
519
|
-
end
|
520
|
-
end
|
521
|
-
other.required_keywords.each do |keyword, t|
|
522
|
-
unless required_keywords.key?(keyword)
|
523
|
-
case
|
524
|
-
when self.required_keywords.key?(keyword)
|
525
|
-
required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.required_keywords[keyword]])
|
526
|
-
when self.rest_keywords
|
527
|
-
required_keywords[keyword] = AST::Types::Intersection.build(types: [t, self.rest_keywords])
|
528
|
-
else
|
529
|
-
return
|
530
|
-
end
|
531
|
-
end
|
532
|
-
end
|
533
|
-
|
534
|
-
rest = case
|
535
|
-
when self.rest_keywords && other.rest_keywords
|
536
|
-
AST::Types::Intersection.build(types: [self.rest_keywords, other.rest_keywords])
|
537
|
-
else
|
538
|
-
nil
|
539
|
-
end
|
540
|
-
|
541
|
-
Params.new(
|
542
|
-
required: [],
|
543
|
-
optional: [],
|
544
|
-
rest: nil,
|
545
|
-
required_keywords: required_keywords,
|
546
|
-
optional_keywords: optional_keywords,
|
547
|
-
rest_keywords: rest)
|
548
|
-
end
|
549
|
-
end
|
550
|
-
|
551
|
-
# Returns the union between self and other.
|
552
|
-
#
|
553
|
-
def |(other)
|
554
|
-
a = first_param
|
555
|
-
b = other.first_param
|
556
|
-
|
557
|
-
case
|
558
|
-
when a.is_a?(RequiredPositional) && b.is_a?(RequiredPositional)
|
559
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
560
|
-
(self.drop_first | other.drop_first)&.with_first_param(RequiredPositional.new(type))
|
561
|
-
end
|
562
|
-
when a.is_a?(RequiredPositional) && b.is_a?(OptionalPositional)
|
563
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
564
|
-
(self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
565
|
-
end
|
566
|
-
when a.is_a?(RequiredPositional) && b.is_a?(RestPositional)
|
567
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
568
|
-
(self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
569
|
-
end
|
570
|
-
when a.is_a?(RequiredPositional) && b.nil?
|
571
|
-
self.drop_first&.with_first_param(OptionalPositional.new(a.type))
|
572
|
-
when a.is_a?(OptionalPositional) && b.is_a?(RequiredPositional)
|
573
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
574
|
-
(self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
575
|
-
end
|
576
|
-
when a.is_a?(OptionalPositional) && b.is_a?(OptionalPositional)
|
577
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
578
|
-
(self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
579
|
-
end
|
580
|
-
when a.is_a?(OptionalPositional) && b.is_a?(RestPositional)
|
581
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
582
|
-
(self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
583
|
-
end
|
584
|
-
when a.is_a?(OptionalPositional) && b.nil?
|
585
|
-
(self.drop_first | other)&.with_first_param(a)
|
586
|
-
when a.is_a?(RestPositional) && b.is_a?(RequiredPositional)
|
587
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
588
|
-
(self.drop_first | other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
589
|
-
end
|
590
|
-
when a.is_a?(RestPositional) && b.is_a?(OptionalPositional)
|
591
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
592
|
-
(self | other.drop_first)&.with_first_param(OptionalPositional.new(type))
|
593
|
-
end
|
594
|
-
when a.is_a?(RestPositional) && b.is_a?(RestPositional)
|
595
|
-
AST::Types::Union.build(types: [a.type, b.type]).yield_self do |type|
|
596
|
-
(self.drop_first | other.drop_first)&.with_first_param(RestPositional.new(type))
|
597
|
-
end
|
598
|
-
when a.is_a?(RestPositional) && b.nil?
|
599
|
-
(self.drop_first | other)&.with_first_param(a)
|
600
|
-
when a.nil? && b.is_a?(RequiredPositional)
|
601
|
-
other.drop_first&.with_first_param(OptionalPositional.new(b.type))
|
602
|
-
when a.nil? && b.is_a?(OptionalPositional)
|
603
|
-
(self | other.drop_first)&.with_first_param(b)
|
604
|
-
when a.nil? && b.is_a?(RestPositional)
|
605
|
-
(self | other.drop_first)&.with_first_param(b)
|
606
|
-
when a.nil? && b.nil?
|
607
|
-
required_keywords = {}
|
608
|
-
optional_keywords = {}
|
609
|
-
|
610
|
-
(Set.new(self.required_keywords.keys) & Set.new(other.required_keywords.keys)).each do |keyword|
|
611
|
-
required_keywords[keyword] = AST::Types::Union.build(
|
612
|
-
types: [
|
613
|
-
self.required_keywords[keyword],
|
614
|
-
other.required_keywords[keyword]
|
615
|
-
]
|
616
|
-
)
|
617
|
-
end
|
618
|
-
|
619
|
-
self.optional_keywords.each do |keyword, t|
|
620
|
-
unless optional_keywords.key?(keyword) || required_keywords.key?(keyword)
|
621
|
-
case
|
622
|
-
when s = other.required_keywords[keyword]
|
623
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
|
624
|
-
when s = other.optional_keywords[keyword]
|
625
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
|
626
|
-
when r = other.rest_keywords
|
627
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, r])
|
628
|
-
else
|
629
|
-
optional_keywords[keyword] = t
|
630
|
-
end
|
631
|
-
end
|
632
|
-
end
|
633
|
-
other.optional_keywords.each do |keyword, t|
|
634
|
-
unless optional_keywords.key?(keyword) || required_keywords.key?(keyword)
|
635
|
-
case
|
636
|
-
when s = self.required_keywords[keyword]
|
637
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
|
638
|
-
when s = self.optional_keywords[keyword]
|
639
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
|
640
|
-
when r = self.rest_keywords
|
641
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, r])
|
642
|
-
else
|
643
|
-
optional_keywords[keyword] = t
|
644
|
-
end
|
645
|
-
end
|
646
|
-
end
|
647
|
-
self.required_keywords.each do |keyword, t|
|
648
|
-
unless optional_keywords.key?(keyword) || required_keywords.key?(keyword)
|
649
|
-
case
|
650
|
-
when s = other.optional_keywords[keyword]
|
651
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
|
652
|
-
when r = other.rest_keywords
|
653
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, r])
|
654
|
-
else
|
655
|
-
optional_keywords[keyword] = t
|
656
|
-
end
|
657
|
-
end
|
658
|
-
end
|
659
|
-
other.required_keywords.each do |keyword, t|
|
660
|
-
unless optional_keywords.key?(keyword) || required_keywords.key?(keyword)
|
661
|
-
case
|
662
|
-
when s = self.optional_keywords[keyword]
|
663
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, s])
|
664
|
-
when r = self.rest_keywords
|
665
|
-
optional_keywords[keyword] = AST::Types::Union.build(types: [t, r])
|
666
|
-
else
|
667
|
-
optional_keywords[keyword] = t
|
668
|
-
end
|
669
|
-
end
|
670
|
-
end
|
671
|
-
|
672
|
-
rest = case
|
673
|
-
when self.rest_keywords && other.rest_keywords
|
674
|
-
AST::Types::Union.build(types: [self.rest_keywords, other.rest_keywords])
|
675
|
-
when self.rest_keywords
|
676
|
-
if required_keywords.empty? && optional_keywords.empty?
|
677
|
-
self.rest_keywords
|
678
|
-
end
|
679
|
-
when other.rest_keywords
|
680
|
-
if required_keywords.empty? && optional_keywords.empty?
|
681
|
-
other.rest_keywords
|
682
|
-
end
|
683
|
-
else
|
684
|
-
nil
|
685
|
-
end
|
686
|
-
|
687
|
-
Params.new(
|
688
|
-
required: [],
|
689
|
-
optional: [],
|
690
|
-
rest: nil,
|
691
|
-
required_keywords: required_keywords,
|
692
|
-
optional_keywords: optional_keywords,
|
693
|
-
rest_keywords: rest)
|
694
|
-
end
|
695
|
-
end
|
696
|
-
end
|
697
|
-
|
698
|
-
class Block
|
699
|
-
attr_reader :type
|
700
|
-
attr_reader :optional
|
701
|
-
|
702
|
-
def initialize(type:, optional:)
|
703
|
-
@type = type
|
704
|
-
@optional = optional
|
705
|
-
end
|
706
|
-
|
707
|
-
def optional?
|
708
|
-
@optional
|
709
|
-
end
|
710
|
-
|
711
|
-
def to_optional
|
712
|
-
self.class.new(
|
713
|
-
type: type,
|
714
|
-
optional: true
|
715
|
-
)
|
716
|
-
end
|
717
|
-
|
718
|
-
def ==(other)
|
719
|
-
other.is_a?(self.class) && other.type == type && other.optional == optional
|
720
|
-
end
|
721
|
-
|
722
|
-
alias eql? ==
|
723
|
-
|
724
|
-
def hash
|
725
|
-
type.hash ^ optional.hash
|
726
|
-
end
|
727
|
-
|
728
|
-
def closed?
|
729
|
-
type.closed?
|
730
|
-
end
|
731
|
-
|
732
|
-
def subst(s)
|
733
|
-
ty = type.subst(s)
|
734
|
-
if ty == type
|
735
|
-
self
|
736
|
-
else
|
737
|
-
self.class.new(
|
738
|
-
type: ty,
|
739
|
-
optional: optional
|
740
|
-
)
|
741
|
-
end
|
742
|
-
end
|
743
|
-
|
744
|
-
def free_variables()
|
745
|
-
@fvs ||= type.free_variables
|
746
|
-
end
|
747
|
-
|
748
|
-
def to_s
|
749
|
-
"#{optional? ? "?" : ""}{ #{type.params} -> #{type.return_type} }"
|
750
|
-
end
|
751
|
-
|
752
|
-
def map_type(&block)
|
753
|
-
self.class.new(
|
754
|
-
type: type.map_type(&block),
|
755
|
-
optional: optional
|
756
|
-
)
|
757
|
-
end
|
758
|
-
|
759
|
-
def +(other)
|
760
|
-
optional = self.optional? || other.optional?
|
761
|
-
type = AST::Types::Proc.new(
|
762
|
-
params: self.type.params + other.type.params,
|
763
|
-
return_type: AST::Types::Union.build(types: [self.type.return_type, other.type.return_type])
|
764
|
-
)
|
765
|
-
self.class.new(
|
766
|
-
type: type,
|
767
|
-
optional: optional
|
768
|
-
)
|
769
|
-
end
|
770
|
-
end
|
771
|
-
|
772
3
|
class MethodType
|
773
4
|
attr_reader :type_params
|
774
|
-
attr_reader :
|
5
|
+
attr_reader :type
|
775
6
|
attr_reader :block
|
776
|
-
attr_reader :return_type
|
777
7
|
attr_reader :method_decls
|
778
8
|
|
779
|
-
def initialize(type_params:,
|
9
|
+
def initialize(type_params:, type:, block:, method_decls:)
|
780
10
|
@type_params = type_params
|
781
|
-
@
|
11
|
+
@type = type
|
782
12
|
@block = block
|
783
|
-
@return_type = return_type
|
784
13
|
@method_decls = method_decls
|
785
14
|
end
|
786
15
|
|
787
16
|
def ==(other)
|
788
17
|
other.is_a?(self.class) &&
|
789
18
|
other.type_params == type_params &&
|
790
|
-
other.
|
791
|
-
other.block == block
|
792
|
-
other.return_type == return_type
|
19
|
+
other.type == type &&
|
20
|
+
other.block == block
|
793
21
|
end
|
794
22
|
|
795
23
|
alias eql? ==
|
796
24
|
|
797
25
|
def hash
|
798
|
-
type_params.hash ^
|
26
|
+
type_params.hash ^ type.hash ^ block.hash
|
799
27
|
end
|
800
28
|
|
801
29
|
def free_variables
|
802
30
|
@fvs ||= Set.new.tap do |set|
|
803
|
-
set.merge(
|
31
|
+
set.merge(type.free_variables)
|
804
32
|
if block
|
805
33
|
set.merge(block.free_variables)
|
806
34
|
end
|
807
|
-
set.merge(return_type.free_variables)
|
808
35
|
set.subtract(type_params)
|
809
36
|
end
|
810
37
|
end
|
@@ -817,21 +44,19 @@ module Steep
|
|
817
44
|
|
818
45
|
self.class.new(
|
819
46
|
type_params: type_params,
|
820
|
-
|
47
|
+
type: type.subst(s_),
|
821
48
|
block: block&.subst(s_),
|
822
|
-
return_type: return_type.subst(s_),
|
823
49
|
method_decls: method_decls
|
824
50
|
)
|
825
51
|
end
|
826
52
|
|
827
53
|
def each_type(&block)
|
828
54
|
if block_given?
|
829
|
-
|
55
|
+
type.each_type(&block)
|
830
56
|
self.block&.tap do
|
831
57
|
self.block.type.params.each_type(&block)
|
832
58
|
yield(self.block.type.return_type)
|
833
59
|
end
|
834
|
-
yield(return_type)
|
835
60
|
else
|
836
61
|
enum_for :each_type
|
837
62
|
end
|
@@ -839,23 +64,22 @@ module Steep
|
|
839
64
|
|
840
65
|
def instantiate(s)
|
841
66
|
self.class.new(type_params: [],
|
842
|
-
|
67
|
+
type: type.subst(s),
|
843
68
|
block: block&.subst(s),
|
844
|
-
return_type: return_type.subst(s),
|
845
69
|
method_decls: method_decls)
|
846
70
|
end
|
847
71
|
|
848
|
-
def with(type_params: self.type_params,
|
72
|
+
def with(type_params: self.type_params, type: self.type, block: self.block, method_decls: self.method_decls)
|
849
73
|
self.class.new(type_params: type_params,
|
850
|
-
|
74
|
+
type: type,
|
851
75
|
block: block,
|
852
|
-
return_type: return_type,
|
853
76
|
method_decls: method_decls)
|
854
77
|
end
|
855
78
|
|
856
79
|
def to_s
|
857
80
|
type_params = !self.type_params.empty? ? "[#{self.type_params.map{|x| "#{x}" }.join(", ")}] " : ""
|
858
|
-
params =
|
81
|
+
params = type.params.to_s
|
82
|
+
return_type = type.return_type
|
859
83
|
block = self.block ? " #{self.block}" : ""
|
860
84
|
|
861
85
|
"#{type_params}#{params}#{block} -> #{return_type}"
|
@@ -863,9 +87,8 @@ module Steep
|
|
863
87
|
|
864
88
|
def map_type(&block)
|
865
89
|
self.class.new(type_params: type_params,
|
866
|
-
|
90
|
+
type: type.map_type(&block),
|
867
91
|
block: self.block&.yield_self {|blk| blk.map_type(&block) },
|
868
|
-
return_type: yield(return_type),
|
869
92
|
method_decls: method_decls)
|
870
93
|
end
|
871
94
|
|
@@ -889,11 +112,14 @@ module Steep
|
|
889
112
|
|
890
113
|
self.class.new(
|
891
114
|
type_params: type_params,
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
115
|
+
type: Function.new(
|
116
|
+
params: type.params.subst(s1) + other.type.params.subst(s2),
|
117
|
+
return_type: AST::Types::Union.build(
|
118
|
+
types: [type.return_type.subst(s1), other.type.return_type.subst(s2)]
|
119
|
+
),
|
120
|
+
location: nil
|
896
121
|
),
|
122
|
+
block: block,
|
897
123
|
method_decls: method_decls + other.method_decls
|
898
124
|
)
|
899
125
|
end
|
@@ -921,14 +147,12 @@ module Steep
|
|
921
147
|
type_params = (self_type_params + other_type_params).to_a
|
922
148
|
end
|
923
149
|
|
924
|
-
params = self.params & other.params or return
|
150
|
+
params = self.type.params & other.type.params or return
|
925
151
|
block = case
|
926
152
|
when self.block && other.block
|
927
153
|
block_params = self.block.type.params | other.block.type.params
|
928
154
|
block_return_type = AST::Types::Intersection.build(types: [self.block.type.return_type, other.block.type.return_type])
|
929
|
-
block_type =
|
930
|
-
return_type: block_return_type,
|
931
|
-
location: nil)
|
155
|
+
block_type = Function.new(params: block_params, return_type: block_return_type, location: nil)
|
932
156
|
Block.new(
|
933
157
|
type: block_type,
|
934
158
|
optional: self.block.optional && other.block.optional
|
@@ -942,13 +166,12 @@ module Steep
|
|
942
166
|
else
|
943
167
|
return
|
944
168
|
end
|
945
|
-
return_type = AST::Types::Union.build(types: [self.return_type, other.return_type])
|
169
|
+
return_type = AST::Types::Union.build(types: [self.type.return_type, other.type.return_type])
|
946
170
|
|
947
171
|
MethodType.new(
|
948
|
-
params: params,
|
949
|
-
block: block,
|
950
|
-
return_type: return_type,
|
951
172
|
type_params: type_params,
|
173
|
+
type: Function.new(params: params, return_type: return_type, location: nil),
|
174
|
+
block: block,
|
952
175
|
method_decls: method_decls + other.method_decls
|
953
176
|
)
|
954
177
|
end
|
@@ -972,14 +195,12 @@ module Steep
|
|
972
195
|
type_params = (self_type_params + other_type_params).to_a
|
973
196
|
end
|
974
197
|
|
975
|
-
params = self.params | other.params
|
198
|
+
params = self.type.params | other.type.params
|
976
199
|
block = case
|
977
200
|
when self.block && other.block
|
978
201
|
block_params = self.block.type.params & other.block.type.params or return
|
979
202
|
block_return_type = AST::Types::Union.build(types: [self.block.type.return_type, other.block.type.return_type])
|
980
|
-
block_type =
|
981
|
-
return_type: block_return_type,
|
982
|
-
location: nil)
|
203
|
+
block_type = Function.new(params: block_params, return_type: block_return_type, location: nil)
|
983
204
|
Block.new(
|
984
205
|
type: block_type,
|
985
206
|
optional: self.block.optional || other.block.optional
|
@@ -989,13 +210,12 @@ module Steep
|
|
989
210
|
self.block || other.block
|
990
211
|
end
|
991
212
|
|
992
|
-
return_type = AST::Types::Intersection.build(types: [self.return_type, other.return_type])
|
213
|
+
return_type = AST::Types::Intersection.build(types: [self.type.return_type, other.type.return_type])
|
993
214
|
|
994
215
|
MethodType.new(
|
995
|
-
params: params,
|
996
|
-
block: block,
|
997
|
-
return_type: return_type,
|
998
216
|
type_params: type_params,
|
217
|
+
type: Function.new(params: params, return_type: return_type, location: nil),
|
218
|
+
block: block,
|
999
219
|
method_decls: method_decls + other.method_decls
|
1000
220
|
)
|
1001
221
|
end
|