Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions spec/compiler/normalize/array_literal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,25 @@ describe "Normalize: array literal" do
__temp_3
CRYSTAL
end

# TODO: add md5 to the rest of the variables
it "normalizes with filename" do
assert_expand_named "Foo{x, *y}", <<-CRYSTAL, filename: "foo.cr"
__temp_1 = x
__temp_2 = y
__temp_3 = Foo.new
__temp_3 << __temp_1
__temp_2.each do |__temp_cd6ae5dd_1| __temp_3 << __temp_cd6ae5dd_1 end
__temp_3
CRYSTAL

assert_expand_named "Foo{x, *y}", <<-CRYSTAL, filename: "bar.cr"
__temp_1 = x
__temp_2 = y
__temp_3 = Foo.new
__temp_3 << __temp_1
__temp_2.each do |__temp_fbcf3d84_1| __temp_3 << __temp_fbcf3d84_1 end
__temp_3
CRYSTAL
end
end
50 changes: 50 additions & 0 deletions spec/compiler/normalize/def_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -251,5 +251,55 @@ module Crystal
end
end
end

it "normalizes with filename" do
a_def = parse("def foo(*args, **options); args + options; end", filename: "foo.cr").as(Def)
other_def = a_def.expand_default_arguments(Program.new, 2, ["x", "y"])
other_def.to_s.should eq <<-CRYSTAL
def foo:x:y(__temp_cd6ae5dd_1, __temp_cd6ae5dd_2, x __temp_cd6ae5dd_3, y __temp_cd6ae5dd_4)
args = {__temp_cd6ae5dd_1, __temp_cd6ae5dd_2}
options = {x: __temp_cd6ae5dd_3, y: __temp_cd6ae5dd_4}
args + options
end
CRYSTAL

a_def = parse("def foo(*args, **options); args + options; end", filename: "bar.cr").as(Def)
other_def = a_def.expand_default_arguments(Program.new, 2, ["x", "y"])
other_def.to_s.should eq <<-CRYSTAL
def foo:x:y(__temp_fbcf3d84_1, __temp_fbcf3d84_2, x __temp_fbcf3d84_3, y __temp_fbcf3d84_4)
args = {__temp_fbcf3d84_1, __temp_fbcf3d84_2}
options = {x: __temp_fbcf3d84_3, y: __temp_fbcf3d84_4}
args + options
end
CRYSTAL
end

it "normalizes `.new` with filename" do
a_def = parse("def new(y, **options); end", filename: "foo.cr").as(Def)
other_def = a_def.expand_new_default_arguments(Program.new, 0, ["x", "y", "z"])
other_def.to_s.should eq <<-CRYSTAL
def new:x:y:z(x __temp_cd6ae5dd_1, y __temp_cd6ae5dd_2, z __temp_cd6ae5dd_3)
_ = allocate
_.initialize(x: __temp_cd6ae5dd_1, y: __temp_cd6ae5dd_2, z: __temp_cd6ae5dd_3)
if _.responds_to?(:finalize)
::GC.add_finalizer(_)
end
_
end
CRYSTAL

a_def = parse("def new(y, **options); end", filename: "bar.cr").as(Def)
other_def = a_def.expand_new_default_arguments(Program.new, 0, ["x", "y", "z"])
other_def.to_s.should eq <<-CRYSTAL
def new:x:y:z(x __temp_fbcf3d84_1, y __temp_fbcf3d84_2, z __temp_fbcf3d84_3)
_ = allocate
_.initialize(x: __temp_fbcf3d84_1, y: __temp_fbcf3d84_2, z: __temp_fbcf3d84_3)
if _.responds_to?(:finalize)
::GC.add_finalizer(_)
end
_
end
CRYSTAL
end
end
end
17 changes: 17 additions & 0 deletions spec/compiler/semantic/splat_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -808,4 +808,21 @@ describe "Semantic: splat" do
a_def.location.should eq Location.new("", line_number: 2, column_number: 3)
a_def.body.location.should eq Location.new("", line_number: 3, column_number: 5)
end

it "normalizes with filename" do
result = semantic <<-CRYSTAL
def foo(x, y)
end

#<loc:"foo.cr",1,1>foo(*{1, 2})
#<loc:"bar.cr",1,1>foo(*{3, 4})
CRYSTAL

result.node.to_s.should end_with <<-CRYSTAL
__temp_cd6ae5dd_1 = {1, 2}
foo(__temp_cd6ae5dd_1[0], __temp_cd6ae5dd_1[1])
__temp_fbcf3d84_1 = {3, 4}
foo(__temp_fbcf3d84_1[0], __temp_fbcf3d84_1[1])\n
CRYSTAL
end
end
4 changes: 2 additions & 2 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ def assert_expand_third(from : String, to, *, flags = nil, file = __FILE__, line
assert_expand node, to, flags: flags, file: file, line: line
end

def assert_expand_named(from : String, to, *, generic = nil, flags = nil, file = __FILE__, line = __LINE__)
def assert_expand_named(from : String, to, *, generic = nil, flags = nil, filename = nil, file = __FILE__, line = __LINE__)
program = new_program
program.flags.concat(flags.split) if flags
from_nodes = Parser.parse(from)
from_nodes = parse(from, filename: filename)
generic_type = generic.path if generic
case from_nodes
when ArrayLiteral
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/crystal/semantic/default_arguments.cr
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Crystal::Def
splat_size = 0 if splat_size < 0

splat_size.times do |index|
splat_name = program.new_temp_var_name
splat_name = program.new_temp_var_name(self)
splat_names << splat_name

splat_arg = Arg.new(splat_name)
Expand All @@ -88,7 +88,7 @@ class Crystal::Def
str << ':'
str << named_arg

temp_name = program.new_temp_var_name
temp_name = program.new_temp_var_name(self)
named_args_temp_names << temp_name

# If a named argument matches an argument's external name, use the internal name
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/literal_expander.cr
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ module Crystal
node.elements.each_with_index do |elem, i|
temp_var = elem_temp_vars.try &.[i]
if elem.is_a?(Splat)
yield_var = new_temp_var
yield_var = new_temp_var(elem)
each_body = Call.new(ary_var.clone, "<<", yield_var.clone).at(node)
each_block = Block.new(args: [yield_var], body: each_body).at(node)
exps << Call.new((temp_var || elem.exp).clone, "each", block: each_block).at(node)
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/main_visitor.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,7 @@ module Crystal
next
end

temp_var = @program.new_temp_var.at(arg)
temp_var = @program.new_temp_var(arg).at(arg)
assign = Assign.new(temp_var, exp).at(arg)
exps << assign
case arg
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/semantic/new.cr
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ module Crystal

# When **opts is expanded for named arguments, we must use internal
# names that won't clash with local variables defined in the method.
temp_name = instance_type.program.new_temp_var_name
temp_name = instance_type.program.new_temp_var_name(self)
def_arg = Arg.new(temp_name, external_name: named_arg)

if matching_arg = args.find { |arg| arg.external_name == named_arg }
Expand Down