Skip to content

Commit

Permalink
Hoist complex element expressions outside container literals (#12366)
Browse files Browse the repository at this point in the history
  • Loading branch information
HertzDevil authored Sep 5, 2022
1 parent a4c44b7 commit d642d4f
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 117 deletions.
45 changes: 45 additions & 0 deletions spec/compiler/normalize/array_literal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,49 @@ describe "Normalize: array literal" do
__temp_1
CR
end

it "hoists complex element expressions" do
assert_expand "[[1]]", <<-CR
__temp_1 = [1]
__temp_2 = ::Array(typeof(__temp_1)).unsafe_build(1)
__temp_3 = __temp_2.to_unsafe
__temp_3[0] = __temp_1
__temp_2
CR
end

it "hoists complex element expressions, with splat" do
assert_expand "[*[1]]", <<-CR
__temp_1 = [1]
__temp_2 = ::Array(typeof(::Enumerable.element_type(__temp_1))).new(0)
__temp_2.concat(__temp_1)
__temp_2
CR
end

it "hoists complex element expressions, array-like" do
assert_expand_named "Foo{[1], *[2]}", <<-CR
__temp_1 = [1]
__temp_2 = [2]
__temp_3 = Foo.new
__temp_3 << __temp_1
__temp_2.each do |__temp_4|
__temp_3 << __temp_4
end
__temp_3
CR
end

it "hoists complex element expressions, array-like generic" do
assert_expand_named "Foo{[1], *[2]}", <<-CR, generic: "Foo"
__temp_1 = [1]
__temp_2 = [2]
__temp_3 = Foo(typeof(__temp_1, ::Enumerable.element_type(__temp_2))).new
__temp_3 << __temp_1
__temp_2.each do |__temp_4|
__temp_3 << __temp_4
end
__temp_3
CR
end
end
47 changes: 45 additions & 2 deletions spec/compiler/normalize/hash_literal_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,53 @@ describe "Normalize: hash literal" do
end

it "normalizes non-empty with of" do
assert_expand "{1 => 2, 3 => 4} of Int => Float", "__temp_1 = ::Hash(Int, Float).new\n__temp_1[1] = 2\n__temp_1[3] = 4\n__temp_1"
assert_expand "{1 => 2, 3 => 4} of Int => Float", <<-CR
__temp_1 = ::Hash(Int, Float).new
__temp_1[1] = 2
__temp_1[3] = 4
__temp_1
CR
end

it "normalizes non-empty without of" do
assert_expand "{1 => 2, 3 => 4}", "__temp_1 = ::Hash(typeof(1, 3), typeof(2, 4)).new\n__temp_1[1] = 2\n__temp_1[3] = 4\n__temp_1"
assert_expand "{1 => 2, 3 => 4}", <<-CR
__temp_1 = ::Hash(typeof(1, 3), typeof(2, 4)).new
__temp_1[1] = 2
__temp_1[3] = 4
__temp_1
CR
end

it "hoists complex element expressions" do
assert_expand "{[1] => 2, 3 => [4]}", <<-CR
__temp_1 = [1]
__temp_2 = [4]
__temp_3 = ::Hash(typeof(__temp_1, 3), typeof(2, __temp_2)).new
__temp_3[__temp_1] = 2
__temp_3[3] = __temp_2
__temp_3
CR
end

it "hoists complex element expressions, hash-like" do
assert_expand_named "Foo{[1] => 2, 3 => [4]}", <<-CR
__temp_1 = [1]
__temp_2 = [4]
__temp_3 = Foo.new
__temp_3[__temp_1] = 2
__temp_3[3] = __temp_2
__temp_3
CR
end

it "hoists complex element expressions, hash-like generic" do
assert_expand_named "Foo{[1] => 2, 3 => [4]}", <<-CR, generic: "Foo"
__temp_1 = [1]
__temp_2 = [4]
__temp_3 = Foo(typeof(__temp_1, 3), typeof(2, __temp_2)).new
__temp_3[__temp_1] = 2
__temp_3[3] = __temp_2
__temp_3
CR
end
end
16 changes: 16 additions & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ 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__)
program = new_program
program.flags.concat(flags.split) if flags
from_nodes = Parser.parse(from)
generic_type = generic.path if generic
case from_nodes
when ArrayLiteral
to_nodes = LiteralExpander.new(program).expand_named(from_nodes, generic_type)
when HashLiteral
to_nodes = LiteralExpander.new(program).expand_named(from_nodes, generic_type)
else
fail "Expected: ArrayLiteral | HashLiteral, got: #{from_nodes.class}", file: file, line: line
end
to_nodes.to_s.strip.should eq(to.strip), file: file, line: line
end

def assert_error(str, message = nil, *, inject_primitives = false, flags = nil, file = __FILE__, line = __LINE__)
expect_raises TypeException, message, file, line do
semantic str, inject_primitives: inject_primitives, flags: flags
Expand Down
Loading

0 comments on commit d642d4f

Please sign in to comment.