Add Ninja escape '$' parsing tests

Closes #10942.

PiperOrigin-RevId: 300243386
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/lexer/NinjaLexerStep.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/lexer/NinjaLexerStep.java
index 1dbec92..b1569e6 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/lexer/NinjaLexerStep.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/ninja/lexer/NinjaLexerStep.java
@@ -211,6 +211,7 @@
   }
 
   public boolean tryReadEscapedLiteral() {
+    Preconditions.checkState('$' == fragment.byteAt(position));
     if (checkForward(1, '$', ':', ' ')) {
       // Escaped literal.
       end = position + 2;
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaParserStepTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaParserStepTest.java
index 46363b6..8cf88c6 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaParserStepTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/ninja/NinjaParserStepTest.java
@@ -179,6 +179,38 @@
   }
 
   @Test
+  public void testNinjaRuleWithDollarSign() throws Exception {
+    NinjaParserStep parser =
+        createParser(
+            "rule testRule  \n"
+                + "  command = something && $\n"
+                + "    something_else\n"
+                + "  description = Test $\n"
+                + "    rule");
+    NinjaRule ninjaRule = parser.parseNinjaRule();
+    assertThat(ninjaRule.getVariables().get(NinjaRuleVariable.COMMAND).getRawText())
+        .isEqualTo("something && $\n    something_else");
+    assertThat(ninjaRule.getVariables().get(NinjaRuleVariable.DESCRIPTION).getRawText())
+        .isEqualTo("Test $\n    rule");
+  }
+
+  @Test
+  public void testNinjaRuleWithStickyDollarSign() throws Exception {
+    NinjaParserStep parser =
+        createParser(
+            "rule testRule  \n"
+                + "  command = something &&$\n"
+                + "    something_else\n"
+                + "  description = Test$\n"
+                + "    rule");
+    NinjaRule ninjaRule = parser.parseNinjaRule();
+    assertThat(ninjaRule.getVariables().get(NinjaRuleVariable.COMMAND).getRawText())
+        .isEqualTo("something &&$\n    something_else");
+    assertThat(ninjaRule.getVariables().get(NinjaRuleVariable.DESCRIPTION).getRawText())
+        .isEqualTo("Test$\n    rule");
+  }
+
+  @Test
   public void testVariableWithoutValue() throws Exception {
     NinjaParserStep parser =
         createParser(
@@ -348,6 +380,20 @@
   }
 
   @Test
+  public void testNinjaTargetsPathWithEscapedNewline() throws Exception {
+    NinjaTarget target =
+        parseNinjaTarget(
+            "build $\n" + "  output : $\n" + "  command input$\n" + "  with$\n" + "  newline");
+    assertThat(target.getRuleName()).isEqualTo("command");
+    assertThat(target.getOutputs()).containsExactly(PathFragment.create("output"));
+    assertThat(target.getUsualInputs())
+        .containsExactly(
+            PathFragment.create("input"),
+            PathFragment.create("with"),
+            PathFragment.create("newline"));
+  }
+
+  @Test
   public void testNinjaTargetWithScope() throws Exception {
     NinjaTarget target = parseNinjaTarget("build output : command input\n  pool = abc\n");
     assertThat(target.getRuleName()).isEqualTo("command");