[hlsl-writer] Support pre stream in if/else statements.

This CL updates the if and else statement support to output the pre
streams in the proper places.

Bug: tint:192
Change-Id: If217de7f838fc033823987e20ba7efc5cd6108ff
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/27781
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 01cfe59..a2b15ea 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -949,40 +949,53 @@
   if (!EmitExpression(pre, cond, stmt->condition())) {
     return false;
   }
-  out << pre.str();
-  out << "if (" << cond.str() << ") ";
-  if (!EmitBlock(out, stmt->body())) {
+
+  std::ostringstream if_out;
+  if_out << "if (" << cond.str() << ") ";
+  if (!EmitBlock(if_out, stmt->body())) {
     return false;
   }
 
-  // TODO(dsinclair): The else pre strings need to mix with the if pre
-  // strings correctly.
   for (const auto& e : stmt->else_statements()) {
-    if (!EmitElse(out, e.get())) {
+    if (e->HasCondition()) {
+      if_out << " else {" << std::endl;
+
+      increment_indent();
+
+      std::ostringstream else_pre;
+      std::ostringstream else_cond_out;
+      if (!EmitExpression(else_pre, else_cond_out, e->condition())) {
+        return false;
+      }
+      if_out << else_pre.str();
+
+      make_indent(if_out);
+      if_out << "if (" << else_cond_out.str() << ") ";
+    } else {
+      if_out << " else ";
+    }
+
+    if (!EmitBlock(if_out, e->body())) {
       return false;
     }
   }
-  out << std::endl;
+  if_out << std::endl;
 
+  for (const auto& e : stmt->else_statements()) {
+    if (!e->HasCondition()) {
+      continue;
+    }
+
+    decrement_indent();
+    make_indent(if_out);
+    if_out << "}" << std::endl;
+  }
+
+  out << pre.str();
+  out << if_out.str();
   return true;
 }
 
-bool GeneratorImpl::EmitElse(std::ostream& out, ast::ElseStatement* stmt) {
-  // TODO(dsinclair): This has to work with the if pre string ....
-  std::ostringstream pre;
-  if (stmt->HasCondition()) {
-    out << " else if (";
-    if (!EmitExpression(pre, out, stmt->condition())) {
-      return false;
-    }
-    out << ") ";
-  } else {
-    out << " else ";
-  }
-
-  return EmitBlock(out, stmt->body());
-}
-
 bool GeneratorImpl::has_referenced_in_var_needing_struct(ast::Function* func) {
   for (auto data : func->referenced_location_variables()) {
     auto* var = data.first;
diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h
index d4f9126..3963781 100644
--- a/src/writer/hlsl/generator_impl.h
+++ b/src/writer/hlsl/generator_impl.h
@@ -164,11 +164,6 @@
   /// @param stmt the statement to emit
   /// @returns true if the statement was emitted successfully
   bool EmitContinue(std::ostream& out, ast::ContinueStatement* stmt);
-  /// Handles generating an else statement
-  /// @param out the output stream
-  /// @param stmt the statement to emit
-  /// @returns true if the statement was emitted
-  bool EmitElse(std::ostream& out, ast::ElseStatement* stmt);
   /// Handles generate an Expression
   /// @param pre the preamble for the expression stream
   /// @param out the output of the expression stream
diff --git a/src/writer/hlsl/generator_impl_if_test.cc b/src/writer/hlsl/generator_impl_if_test.cc
index df2a7d6..aa2c07a 100644
--- a/src/writer/hlsl/generator_impl_if_test.cc
+++ b/src/writer/hlsl/generator_impl_if_test.cc
@@ -62,8 +62,10 @@
   ASSERT_TRUE(gen().EmitStatement(out(), &i)) << gen().error();
   EXPECT_EQ(result(), R"(  if (cond) {
     return;
-  } else if (else_cond) {
-    return;
+  } else {
+    if (else_cond) {
+      return;
+    }
   }
 )");
 }
@@ -119,10 +121,12 @@
   ASSERT_TRUE(gen().EmitStatement(out(), &i)) << gen().error();
   EXPECT_EQ(result(), R"(  if (cond) {
     return;
-  } else if (else_cond) {
-    return;
   } else {
-    return;
+    if (else_cond) {
+      return;
+    } else {
+      return;
+    }
   }
 )");
 }