Convert IRGenerator::convertDo to DoStatement::Make.

We currently don't have any optimizations for do-statements so the
primary benefit is moving code out of IRGenerator.

Change-Id: Ibc4d1ecd87ebef572e742dfdb15821cf4ac0f047
Bug: skia:11342
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376179
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 37fb4c1..99b3743 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -90,6 +90,7 @@
   "$_src/sksl/ir/SkSLConstructor.h",
   "$_src/sksl/ir/SkSLContinueStatement.h",
   "$_src/sksl/ir/SkSLDiscardStatement.h",
+  "$_src/sksl/ir/SkSLDoStatement.cpp",
   "$_src/sksl/ir/SkSLDoStatement.h",
   "$_src/sksl/ir/SkSLEnum.h",
   "$_src/sksl/ir/SkSLExpression.h",
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index d0ecf78..35caf01 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -634,23 +634,6 @@
                                    fSymbolTable);
 }
 
-std::unique_ptr<Statement> IRGenerator::convertDo(std::unique_ptr<Statement> stmt,
-                                                  std::unique_ptr<Expression> test) {
-    if (this->strictES2Mode()) {
-        this->errorReporter().error(stmt->fOffset, "do-while loops are not supported");
-        return nullptr;
-    }
-
-    test = this->coerce(std::move(test), *fContext.fTypes.fBool);
-    if (!test) {
-        return nullptr;
-    }
-    if (this->detectVarDeclarationWithoutScope(*stmt)) {
-        return nullptr;
-    }
-    return std::make_unique<DoStatement>(stmt->fOffset, std::move(stmt), std::move(test));
-}
-
 std::unique_ptr<Statement> IRGenerator::convertDo(const ASTNode& d) {
     SkASSERT(d.fKind == ASTNode::Kind::kDo);
     auto iter = d.begin();
@@ -662,7 +645,10 @@
     if (!test) {
         return nullptr;
     }
-    return this->convertDo(std::move(statement), std::move(test));
+    if (this->detectVarDeclarationWithoutScope(*statement)) {
+        return nullptr;
+    }
+    return DoStatement::Make(fContext, std::move(statement), std::move(test));
 }
 
 std::unique_ptr<Statement> IRGenerator::convertSwitch(const ASTNode& s) {
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index 8a18349..ce1c6b3 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -194,8 +194,6 @@
     std::unique_ptr<Statement> convertBreak(const ASTNode& b);
     std::unique_ptr<Statement> convertContinue(const ASTNode& c);
     std::unique_ptr<Statement> convertDiscard(const ASTNode& d);
-    std::unique_ptr<Statement> convertDo(std::unique_ptr<Statement> stmt,
-                                         std::unique_ptr<Expression> test);
     std::unique_ptr<Statement> convertDo(const ASTNode& d);
     std::unique_ptr<Statement> convertSwitch(const ASTNode& s);
     std::unique_ptr<Expression> convertBinaryExpression(const ASTNode& expression);
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 098185f..7899ca4 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -450,7 +450,7 @@
 
         case Statement::Kind::kDo: {
             const DoStatement& d = statement.as<DoStatement>();
-            return std::make_unique<DoStatement>(offset, stmt(d.statement()), expr(d.test()));
+            return DoStatement::Make(*fContext, stmt(d.statement()), expr(d.test()));
         }
         case Statement::Kind::kExpression: {
             const ExpressionStatement& e = statement.as<ExpressionStatement>();
@@ -473,6 +473,7 @@
         case Statement::Kind::kInlineMarker:
         case Statement::Kind::kNop:
             return statement.clone();
+
         case Statement::Kind::kReturn: {
             const ReturnStatement& r = statement.as<ReturnStatement>();
             if (!r.expression()) {
diff --git a/src/sksl/SkSLRehydrator.cpp b/src/sksl/SkSLRehydrator.cpp
index 781827c..95d9f5d 100644
--- a/src/sksl/SkSLRehydrator.cpp
+++ b/src/sksl/SkSLRehydrator.cpp
@@ -363,8 +363,7 @@
         case Rehydrator::kDo_Command: {
             std::unique_ptr<Statement> stmt = this->statement();
             std::unique_ptr<Expression> expr = this->expression();
-            return std::unique_ptr<Statement>(new DoStatement(-1, std::move(stmt),
-                                                              std::move(expr)));
+            return DoStatement::Make(fContext, std::move(stmt), std::move(expr));
         }
         case Rehydrator::kExpressionStatement_Command: {
             std::unique_ptr<Expression> expr = this->expression();
diff --git a/src/sksl/dsl/DSLCore.cpp b/src/sksl/dsl/DSLCore.cpp
index 7b98cb2..069bc87 100644
--- a/src/sksl/dsl/DSLCore.cpp
+++ b/src/sksl/dsl/DSLCore.cpp
@@ -88,7 +88,7 @@
     }
 
     static DSLPossibleStatement Do(DSLStatement stmt, DSLExpression test) {
-        return DSLWriter::IRGenerator().convertDo(stmt.release(), test.release());
+        return DoStatement::Make(DSLWriter::Context(), stmt.release(), test.release());
     }
 
     static DSLPossibleStatement For(DSLStatement initializer, DSLExpression test,
diff --git a/src/sksl/ir/SkSLDoStatement.cpp b/src/sksl/ir/SkSLDoStatement.cpp
new file mode 100644
index 0000000..cf92764
--- /dev/null
+++ b/src/sksl/ir/SkSLDoStatement.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/sksl/SkSLContext.h"
+#include "src/sksl/SkSLProgramSettings.h"
+#include "src/sksl/ir/SkSLDoStatement.h"
+
+namespace SkSL {
+
+std::unique_ptr<Statement> DoStatement::Make(const Context& context,
+                                             std::unique_ptr<Statement> stmt,
+                                             std::unique_ptr<Expression> test) {
+    if (context.fConfig->strictES2Mode()) {
+        context.fErrors.error(stmt->fOffset, "do-while loops are not supported");
+        return nullptr;
+    }
+    test = context.fTypes.fBool->coerceExpression(std::move(test), context);
+    if (!test) {
+        return nullptr;
+    }
+    return std::make_unique<DoStatement>(stmt->fOffset, std::move(stmt), std::move(test));
+}
+
+std::unique_ptr<Statement> DoStatement::clone() const {
+    return std::make_unique<DoStatement>(fOffset, this->statement()->clone(),
+                                         this->test()->clone());
+}
+
+String DoStatement::description() const {
+    return "do " + this->statement()->description() +
+           " while (" + this->test()->description() + ");";
+}
+
+}  // namespace SkSL
+
diff --git a/src/sksl/ir/SkSLDoStatement.h b/src/sksl/ir/SkSLDoStatement.h
index 231abba..0c22165 100644
--- a/src/sksl/ir/SkSLDoStatement.h
+++ b/src/sksl/ir/SkSLDoStatement.h
@@ -20,12 +20,16 @@
 public:
     static constexpr Kind kStatementKind = Kind::kDo;
 
-    DoStatement(int offset, std::unique_ptr<Statement> statement,
-                std::unique_ptr<Expression> test)
+    DoStatement(int offset, std::unique_ptr<Statement> statement, std::unique_ptr<Expression> test)
         : INHERITED(offset, kStatementKind)
         , fStatement(std::move(statement))
         , fTest(std::move(test)) {}
 
+    // Creates an SkSL do loop.
+    static std::unique_ptr<Statement> Make(const Context& context,
+                                           std::unique_ptr<Statement> stmt,
+                                           std::unique_ptr<Expression> test);
+
     std::unique_ptr<Statement>& statement() {
         return fStatement;
     }
@@ -42,15 +46,9 @@
         return fTest;
     }
 
-    std::unique_ptr<Statement> clone() const override {
-        return std::unique_ptr<Statement>(new DoStatement(fOffset, this->statement()->clone(),
-                                                          this->test()->clone()));
-    }
+    std::unique_ptr<Statement> clone() const override;
 
-    String description() const override {
-        return "do " + this->statement()->description() + " while (" + this->test()->description() +
-               ");";
-    }
+    String description() const override;
 
 private:
     std::unique_ptr<Statement> fStatement;