test: Add Build() method for tests using ast::Builder

This separates out the usage of the built module from the construction of the module.

Previously, we'd happily interleave generator testing with module construction statements. Once the AST / Program is made immutable, this will no longer be possible.

Bug: tint:390
Change-Id: Ib4538228e93ca816f5bb796d024f021116609213
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38360
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/writer/hlsl/generator_impl_member_accessor_test.cc b/src/writer/hlsl/generator_impl_member_accessor_test.cc
index 3121135..e1ade73 100644
--- a/src/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -46,13 +46,17 @@
 
   auto* s = ty.struct_("Str", strct);
   auto* str_var = Var("str", ast::StorageClass::kPrivate, s);
+  mod->AddGlobalVariable(str_var);
+
   auto* expr = MemberAccessor("str", "mem");
 
   td.RegisterVariableForTesting(str_var);
-  gen.register_global(str_var);
-  mod->AddGlobalVariable(str_var);
-
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(str_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "str.mem");
 }
@@ -75,15 +79,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = MemberAccessor("data", "b");
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = MemberAccessor("data", "b");
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load(4))");
 }
@@ -105,18 +112,22 @@
       ast::StructDecorationList{});
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = MemberAccessor("data", "a");
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = MemberAccessor("data", "a");
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asint(data.Load(0))");
 }
+
 TEST_F(HlslGeneratorImplTest_MemberAccessor,
        EmitExpression_MemberAccessor_StorageBuffer_Store_Matrix) {
   // struct Data {
@@ -138,7 +149,9 @@
 
   auto* s = ty.struct_("Data", str);
   auto* b_var = Var("b", ast::StorageClass::kPrivate, ty.mat2x3<f32>());
+  mod->AddGlobalVariable(b_var);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
 
   auto* lhs = MemberAccessor("data", "a");
   auto* rhs = Expr("b");
@@ -147,14 +160,15 @@
 
   td.RegisterVariableForTesting(coord_var);
   td.RegisterVariableForTesting(b_var);
-  gen.register_global(coord_var);
-  gen.register_global(b_var);
-  mod->AddGlobalVariable(coord_var);
-  mod->AddGlobalVariable(b_var);
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+  gen.register_global(b_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(), R"(float3x2 _tint_tmp = b;
 data.Store3(4 + 0, asuint(_tint_tmp[0]));
@@ -183,19 +197,21 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor("data", "a");
   auto* rhs = Construct(ty.mat2x3<f32>(), ast::ExpressionList{});
 
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
-  mod->AddGlobalVariable(coord_var);
-
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(
       result(),
@@ -224,16 +240,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = MemberAccessor("data", "a");
 
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
-  mod->AddGlobalVariable(coord_var);
-
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "asfloat(uint2x3(data.Load2(4 + 0), data.Load2(4 + 8), "
@@ -264,15 +282,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = MemberAccessor("data", "a");
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = MemberAccessor("data", "a");
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "asfloat(uint3x2(data.Load3(4 + 0), data.Load3(4 + 16)))");
@@ -296,15 +317,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = MemberAccessor("data", "a");
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = MemberAccessor("data", "a");
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(),
             "asfloat(uint3x3(data.Load3(0 + 0), data.Load3(0 + 16), "
@@ -329,16 +353,19 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
   auto* expr = IndexAccessor(
       IndexAccessor(MemberAccessor("data", "a"), Expr(2)), Expr(1));
 
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
-  mod->AddGlobalVariable(coord_var);
-
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + (16 * 2) + 16))");
 }
@@ -362,15 +389,18 @@
       ast::StructDecorationList{});
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-  auto* expr = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
+  auto* expr = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
 
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asint(data.Load((4 * 2) + 0))");
 }
@@ -394,16 +424,19 @@
       ast::StructDecorationList{});
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
+  mod->AddGlobalVariable(coord_var);
+  td.RegisterVariableForTesting(coord_var);
+
   auto* expr = IndexAccessor(MemberAccessor("data", "a"),
                              Sub(Add(Expr(2), Expr(4)), Expr(3)));
 
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
-  mod->AddGlobalVariable(coord_var);
-
   ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr)) << td.error();
 
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asint(data.Load((4 * ((2 + 4) - 3)) + 0))");
 }
@@ -426,18 +459,20 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor("data", "b");
   auto* rhs = Expr(2.0f);
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(), R"(data.Store(4, asuint(2.0f));
 )");
@@ -464,18 +499,20 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = IndexAccessor(MemberAccessor("data", "a"), Expr(2));
   auto* rhs = Expr(2);
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign)) << td.error();
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(), R"(data.Store((4 * 2) + 0, asuint(2));
 )");
@@ -499,18 +536,20 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor("data", "a");
   auto* rhs = Expr(2);
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(), R"(data.Store(0, asuint(2));
 )");
@@ -534,16 +573,18 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = MemberAccessor("data", "b");
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load3(16))");
 }
@@ -566,19 +607,21 @@
 
   auto* s = ty.struct_("Data", str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, s);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor("data", "b");
   auto* rhs = vec3<f32>(1.f, 2.f, 3.f);
 
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(),
             R"(data.Store3(16, asuint(float3(1.0f, 2.0f, 3.0f)));
@@ -619,17 +662,19 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr =
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b");
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load3(16 + (32 * 2) + 0))");
 }
@@ -666,18 +711,21 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
 
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = MemberAccessor(
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
       "xy");
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load3(16 + (32 * 2) + 0)).xy");
 }
@@ -717,18 +765,20 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = MemberAccessor(
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
       "g");
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + 16 + (32 * 2) + 0))");
 }
@@ -767,18 +817,20 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* expr = IndexAccessor(
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
       Expr(1));
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(expr));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitExpression(pre, out, expr)) << gen.error();
   EXPECT_EQ(result(), "asfloat(data.Load((4 * 1) + 16 + (32 * 2) + 0))");
 }
@@ -817,12 +869,8 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs =
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b");
@@ -830,7 +878,13 @@
   auto* assign =
       create<ast::AssignmentStatement>(lhs, vec3<f32>(1.f, 2.f, 3.f));
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(),
             R"(data.Store3(16 + (32 * 2) + 0, asuint(float3(1.0f, 2.0f, 3.0f)));
@@ -871,12 +925,8 @@
 
   auto* pre_struct = ty.struct_("Pre", pre_str);
   auto* coord_var = Var("data", ast::StorageClass::kStorage, pre_struct);
-
-  td.RegisterVariableForTesting(coord_var);
-  gen.register_global(coord_var);
   mod->AddGlobalVariable(coord_var);
-
-  ASSERT_TRUE(td.Determine()) << td.error();
+  td.RegisterVariableForTesting(coord_var);
 
   auto* lhs = MemberAccessor(
       MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), Expr(2)), "b"),
@@ -885,7 +935,13 @@
 
   auto* assign = create<ast::AssignmentStatement>(lhs, rhs);
 
+  ASSERT_TRUE(td.Determine()) << td.error();
   ASSERT_TRUE(td.DetermineResultType(assign));
+
+  GeneratorImpl& gen = Build();
+
+  gen.register_global(coord_var);
+
   ASSERT_TRUE(gen.EmitStatement(out, assign)) << gen.error();
   EXPECT_EQ(result(),
             R"(data.Store((4 * 1) + 16 + (32 * 2) + 0, asuint(1.0f));