steep 0.33.0 → 0.38.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 +28 -0
- data/lib/steep.rb +9 -0
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/factory.rb +167 -102
- data/lib/steep/ast/types/logic.rb +20 -1
- data/lib/steep/ast/types/proc.rb +32 -20
- data/lib/steep/cli.rb +15 -2
- data/lib/steep/drivers/print_project.rb +11 -0
- data/lib/steep/drivers/stats.rb +85 -0
- data/lib/steep/drivers/vendor.rb +1 -20
- data/lib/steep/errors.rb +38 -15
- data/lib/steep/index/rbs_index.rb +334 -0
- data/lib/steep/index/signature_symbol_provider.rb +154 -0
- data/lib/steep/index/source_index.rb +100 -0
- data/lib/steep/interface/block.rb +79 -0
- data/lib/steep/interface/function.rb +770 -0
- data/lib/steep/interface/method_type.rb +41 -832
- data/lib/steep/method_name.rb +28 -0
- data/lib/steep/project/completion_provider.rb +24 -15
- data/lib/steep/project/dsl.rb +13 -17
- data/lib/steep/project/options.rb +4 -4
- data/lib/steep/project/source_file.rb +2 -1
- data/lib/steep/project/target.rb +19 -10
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/server/master.rb +5 -1
- data/lib/steep/server/signature_worker.rb +63 -6
- data/lib/steep/subtyping/check.rb +70 -32
- data/lib/steep/subtyping/variable_occurrence.rb +4 -2
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +780 -495
- data/lib/steep/type_inference/block_params.rb +1 -1
- data/lib/steep/type_inference/constant_env.rb +5 -1
- data/lib/steep/type_inference/context.rb +7 -3
- data/lib/steep/type_inference/local_variable_type_env.rb +10 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +3 -0
- data/lib/steep/type_inference/method_call.rb +116 -0
- data/lib/steep/typing.rb +46 -10
- data/lib/steep/version.rb +1 -1
- data/smoke/regression/range.rb +5 -0
- data/smoke/tsort/Steepfile +6 -0
- data/smoke/tsort/a.rb +15 -0
- data/steep.gemspec +1 -1
- metadata +17 -6
@@ -1,814 +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 :
|
777
|
-
attr_reader :location
|
778
|
-
attr_reader :method_def
|
7
|
+
attr_reader :method_decls
|
779
8
|
|
780
|
-
def initialize(type_params:,
|
9
|
+
def initialize(type_params:, type:, block:, method_decls:)
|
781
10
|
@type_params = type_params
|
782
|
-
@
|
11
|
+
@type = type
|
783
12
|
@block = block
|
784
|
-
@
|
785
|
-
@location = location
|
786
|
-
@method_def = method_def
|
13
|
+
@method_decls = method_decls
|
787
14
|
end
|
788
15
|
|
789
16
|
def ==(other)
|
790
17
|
other.is_a?(self.class) &&
|
791
18
|
other.type_params == type_params &&
|
792
|
-
other.
|
793
|
-
other.block == block
|
794
|
-
other.return_type == return_type &&
|
795
|
-
(!other.method_def || !method_def || other.method_def == method_def) &&
|
796
|
-
(!other.location || !location || other.location == location)
|
19
|
+
other.type == type &&
|
20
|
+
other.block == block
|
797
21
|
end
|
798
22
|
|
799
23
|
alias eql? ==
|
800
24
|
|
801
25
|
def hash
|
802
|
-
type_params.hash ^
|
26
|
+
type_params.hash ^ type.hash ^ block.hash
|
803
27
|
end
|
804
28
|
|
805
29
|
def free_variables
|
806
30
|
@fvs ||= Set.new.tap do |set|
|
807
|
-
set.merge(
|
31
|
+
set.merge(type.free_variables)
|
808
32
|
if block
|
809
33
|
set.merge(block.free_variables)
|
810
34
|
end
|
811
|
-
set.merge(return_type.free_variables)
|
812
35
|
set.subtract(type_params)
|
813
36
|
end
|
814
37
|
end
|
@@ -821,22 +44,19 @@ module Steep
|
|
821
44
|
|
822
45
|
self.class.new(
|
823
46
|
type_params: type_params,
|
824
|
-
|
47
|
+
type: type.subst(s_),
|
825
48
|
block: block&.subst(s_),
|
826
|
-
|
827
|
-
method_def: method_def,
|
828
|
-
location: location
|
49
|
+
method_decls: method_decls
|
829
50
|
)
|
830
51
|
end
|
831
52
|
|
832
53
|
def each_type(&block)
|
833
54
|
if block_given?
|
834
|
-
|
55
|
+
type.each_type(&block)
|
835
56
|
self.block&.tap do
|
836
57
|
self.block.type.params.each_type(&block)
|
837
58
|
yield(self.block.type.return_type)
|
838
59
|
end
|
839
|
-
yield(return_type)
|
840
60
|
else
|
841
61
|
enum_for :each_type
|
842
62
|
end
|
@@ -844,25 +64,22 @@ module Steep
|
|
844
64
|
|
845
65
|
def instantiate(s)
|
846
66
|
self.class.new(type_params: [],
|
847
|
-
|
67
|
+
type: type.subst(s),
|
848
68
|
block: block&.subst(s),
|
849
|
-
|
850
|
-
location: location,
|
851
|
-
method_def: method_def)
|
69
|
+
method_decls: method_decls)
|
852
70
|
end
|
853
71
|
|
854
|
-
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)
|
855
73
|
self.class.new(type_params: type_params,
|
856
|
-
|
74
|
+
type: type,
|
857
75
|
block: block,
|
858
|
-
|
859
|
-
method_def: method_def,
|
860
|
-
location: location)
|
76
|
+
method_decls: method_decls)
|
861
77
|
end
|
862
78
|
|
863
79
|
def to_s
|
864
80
|
type_params = !self.type_params.empty? ? "[#{self.type_params.map{|x| "#{x}" }.join(", ")}] " : ""
|
865
|
-
params =
|
81
|
+
params = type.params.to_s
|
82
|
+
return_type = type.return_type
|
866
83
|
block = self.block ? " #{self.block}" : ""
|
867
84
|
|
868
85
|
"#{type_params}#{params}#{block} -> #{return_type}"
|
@@ -870,11 +87,9 @@ module Steep
|
|
870
87
|
|
871
88
|
def map_type(&block)
|
872
89
|
self.class.new(type_params: type_params,
|
873
|
-
|
90
|
+
type: type.map_type(&block),
|
874
91
|
block: self.block&.yield_self {|blk| blk.map_type(&block) },
|
875
|
-
|
876
|
-
location: location,
|
877
|
-
method_def: method_def)
|
92
|
+
method_decls: method_decls)
|
878
93
|
end
|
879
94
|
|
880
95
|
# Returns a new method type which can be used for the method implementation type of both `self` and `other`.
|
@@ -897,13 +112,15 @@ module Steep
|
|
897
112
|
|
898
113
|
self.class.new(
|
899
114
|
type_params: type_params,
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
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
|
904
121
|
),
|
905
|
-
|
906
|
-
|
122
|
+
block: block,
|
123
|
+
method_decls: method_decls + other.method_decls
|
907
124
|
)
|
908
125
|
end
|
909
126
|
|
@@ -930,14 +147,12 @@ module Steep
|
|
930
147
|
type_params = (self_type_params + other_type_params).to_a
|
931
148
|
end
|
932
149
|
|
933
|
-
params = self.params & other.params or return
|
150
|
+
params = self.type.params & other.type.params or return
|
934
151
|
block = case
|
935
152
|
when self.block && other.block
|
936
153
|
block_params = self.block.type.params | other.block.type.params
|
937
154
|
block_return_type = AST::Types::Intersection.build(types: [self.block.type.return_type, other.block.type.return_type])
|
938
|
-
block_type =
|
939
|
-
return_type: block_return_type,
|
940
|
-
location: nil)
|
155
|
+
block_type = Function.new(params: block_params, return_type: block_return_type, location: nil)
|
941
156
|
Block.new(
|
942
157
|
type: block_type,
|
943
158
|
optional: self.block.optional && other.block.optional
|
@@ -951,15 +166,13 @@ module Steep
|
|
951
166
|
else
|
952
167
|
return
|
953
168
|
end
|
954
|
-
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])
|
955
170
|
|
956
171
|
MethodType.new(
|
957
|
-
params: params,
|
958
|
-
block: block,
|
959
|
-
return_type: return_type,
|
960
172
|
type_params: type_params,
|
961
|
-
|
962
|
-
|
173
|
+
type: Function.new(params: params, return_type: return_type, location: nil),
|
174
|
+
block: block,
|
175
|
+
method_decls: method_decls + other.method_decls
|
963
176
|
)
|
964
177
|
end
|
965
178
|
|
@@ -982,14 +195,12 @@ module Steep
|
|
982
195
|
type_params = (self_type_params + other_type_params).to_a
|
983
196
|
end
|
984
197
|
|
985
|
-
params = self.params | other.params
|
198
|
+
params = self.type.params | other.type.params
|
986
199
|
block = case
|
987
200
|
when self.block && other.block
|
988
201
|
block_params = self.block.type.params & other.block.type.params or return
|
989
202
|
block_return_type = AST::Types::Union.build(types: [self.block.type.return_type, other.block.type.return_type])
|
990
|
-
block_type =
|
991
|
-
return_type: block_return_type,
|
992
|
-
location: nil)
|
203
|
+
block_type = Function.new(params: block_params, return_type: block_return_type, location: nil)
|
993
204
|
Block.new(
|
994
205
|
type: block_type,
|
995
206
|
optional: self.block.optional || other.block.optional
|
@@ -999,15 +210,13 @@ module Steep
|
|
999
210
|
self.block || other.block
|
1000
211
|
end
|
1001
212
|
|
1002
|
-
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])
|
1003
214
|
|
1004
215
|
MethodType.new(
|
1005
|
-
params: params,
|
1006
|
-
block: block,
|
1007
|
-
return_type: return_type,
|
1008
216
|
type_params: type_params,
|
1009
|
-
|
1010
|
-
|
217
|
+
type: Function.new(params: params, return_type: return_type, location: nil),
|
218
|
+
block: block,
|
219
|
+
method_decls: method_decls + other.method_decls
|
1011
220
|
)
|
1012
221
|
end
|
1013
222
|
end
|