Skip to content

Commit 2e9ef02

Browse files
alpaca-tcmame
authored andcommitted
Support rest arguments
- Initialized rest arguments in method definitions as array. - Updated method call to add edges to array types. Further improvements may be possible.
1 parent dbb3fe5 commit 2e9ef02

5 files changed

Lines changed: 35 additions & 20 deletions

File tree

lib/typeprof/core/ast/method.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ def install0(genv)
220220
rest_keywords = @rest_keywords ? @body.lenv.new_var(@rest_keywords, self) : nil
221221
block = @block ? @body.lenv.new_var(@block, self) : nil
222222

223+
if rest_positionals
224+
@changes.add_edge(genv, Source.new(genv.gen_ary_type(Vertex.new(self))), rest_positionals)
225+
end
226+
223227
@opt_positional_defaults.zip(opt_positionals) do |expr, vtx|
224228
@changes.add_edge(genv, expr.install(genv), vtx)
225229
end

lib/typeprof/core/graph/box.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,11 @@ def pass_arguments(changes, genv, a_args)
485485

486486
if @f_args.rest_positionals
487487
rest_vtxs.each do |vtx|
488-
changes.add_edge(genv, vtx, @f_args.rest_positionals)
488+
@f_args.rest_positionals.each_type do |ty|
489+
if ty.is_a?(Type::Instance) && ty.mod == genv.mod_ary && ty.args[0]
490+
changes.add_edge(genv, vtx, ty.args[0])
491+
end
492+
end
489493
end
490494
end
491495
else
@@ -519,9 +523,12 @@ def pass_arguments(changes, genv, a_args)
519523

520524
if start_rest < end_rest
521525
if @f_args.rest_positionals
522-
f_arg = @f_args.rest_positionals
523526
(start_rest..end_rest-1).each do |i|
524-
changes.add_edge(genv, a_args.positionals[i], f_arg)
527+
@f_args.rest_positionals.each_type do |ty|
528+
if ty.is_a?(Type::Instance) && ty.mod == genv.mod_ary && ty.args[0]
529+
changes.add_edge(genv, a_args.positionals[i], ty.args[0])
530+
end
531+
end
525532
end
526533
end
527534
end
@@ -569,7 +576,7 @@ def show(output_parameter_names)
569576
args << ("?" + Type.strip_parens(f_vtx.show))
570577
end
571578
if @f_args.rest_positionals
572-
args << ("*" + Type.strip_parens(@f_args.rest_positionals.show))
579+
args << ("*" + Type.strip_array(Type.strip_parens(@f_args.rest_positionals.show)))
573580
end
574581
@f_args.post_positionals.each do |var|
575582
args << Type.strip_parens(var.show)

lib/typeprof/core/type.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ def self.strip_parens(s)
1111
s.start_with?("(") && s.end_with?(")") ? s[1..-2] || raise : s
1212
end
1313

14+
def self.strip_array(s)
15+
s.start_with?("Array[") && s.end_with?("]") ? s[6..-2] || raise : s
16+
end
17+
1418
def self.default_param_map(genv, ty)
1519
ty = ty.base_type(genv)
1620
instance_ty = ty.is_a?(Type::Instance) ? ty : Type::Instance.new(genv, ty.mod, []) # TODO: type params

scenario/known-issues/splat-arg.rb

Lines changed: 0 additions & 16 deletions
This file was deleted.

scenario/method/splat-arg.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## update
2+
class Foo
3+
def rest(*args)
4+
args
5+
end
6+
7+
def call_rest_method
8+
rest(1)
9+
end
10+
end
11+
12+
## assert
13+
class Foo
14+
def rest: (*Integer) -> Array[Integer]
15+
def call_rest_method: -> Array[Integer]
16+
end

0 commit comments

Comments
 (0)