SkSL DSL break / continue / discard

Change-Id: Ifa5fa8bd80ffc48408f133f96951f8a74d572751
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/366959
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/tests/SkSLDSLTest.cpp b/tests/SkSLDSLTest.cpp
index 2330a14..ded346f 100644
--- a/tests/SkSLDSLTest.cpp
+++ b/tests/SkSLDSLTest.cpp
@@ -898,6 +898,46 @@
     REPORTER_ASSERT(r, whitespace_insensitive_compare(y, "{ int a = 1; int b = 2; (a = b); }"));
 }
 
+DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLBreak, r, ctxInfo) {
+    AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
+    Var i(kInt, "i");
+    DSLFunction(kVoid, "success").define(
+        For(Declare(i, 0), i < 10, ++i, Block(
+            If(i > 5, Break())
+        ))
+    );
+    REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
+    REPORTER_ASSERT(r, whitespace_insensitive_compare(*DSLWriter::ProgramElements()[0],
+            "void success() { for (int i = 0; (i < 10); ++i) { if ((i > 5)) break; } }"));
+
+    {
+        ExpectError error(r, "error: break statement must be inside a loop or switch\n");
+        DSLFunction(kVoid, "fail").define(
+            Break()
+        );
+    }
+}
+
+DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLContinue, r, ctxInfo) {
+    AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
+    Var i(kInt, "i");
+    DSLFunction(kVoid, "success").define(
+        For(Declare(i, 0), i < 10, ++i, Block(
+            If(i < 5, Continue())
+        ))
+    );
+    REPORTER_ASSERT(r, DSLWriter::ProgramElements().size() == 1);
+    REPORTER_ASSERT(r, whitespace_insensitive_compare(*DSLWriter::ProgramElements()[0],
+            "void success() { for (int i = 0; (i < 10); ++i) { if ((i < 5)) continue; } }"));
+
+    {
+        ExpectError error(r, "error: continue statement must be inside a loop\n");
+        DSLFunction(kVoid, "fail").define(
+            Continue()
+        );
+    }
+}
+
 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDeclare, r, ctxInfo) {
     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
     Var a(kHalf4, "a"), b(kHalf4, "b");
@@ -913,6 +953,12 @@
     }
 }
 
+DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDiscard, r, ctxInfo) {
+    AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
+    Statement x = If(Sqrt(1) > 0, Discard());
+    REPORTER_ASSERT(r, whitespace_insensitive_compare(x, "if ((sqrt(1.0) > 0.0)) discard;"));
+}
+
 DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLDo, r, ctxInfo) {
     AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
     Statement x = Do(Block(), true);