Parser: Add the 'pass' keyword

--
MOS_MIGRATED_REVID=88857682
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java b/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java
index b49fb1e..7531b84 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Lexer.java
@@ -456,6 +456,7 @@
     keywordMap.put("in", TokenKind.IN);
     keywordMap.put("not", TokenKind.NOT);
     keywordMap.put("or", TokenKind.OR);
+    keywordMap.put("pass", TokenKind.PASS);
     keywordMap.put("return", TokenKind.RETURN);
     keywordMap.put("try", TokenKind.TRY);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
index 6a856f6..9805e45 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Parser.java
@@ -1016,16 +1016,27 @@
     parseStatement(list, true);
   }
 
+  // small_stmt | 'pass'
+  private void parseSmallStatementOrPass(List<Statement> list) {
+    if (token.kind == TokenKind.PASS) {
+      // Skip the token, don't add it to the list.
+      // It has no existence in the AST.
+      expect(TokenKind.PASS);
+    } else {
+      list.add(parseSmallStatement());
+    }
+  }
+
   // simple_stmt ::= small_stmt (';' small_stmt)* ';'? NEWLINE
   private void parseSimpleStatement(List<Statement> list) {
-    list.add(parseSmallStatement());
+    parseSmallStatementOrPass(list);
 
     while (token.kind == TokenKind.SEMI) {
       nextToken();
       if (token.kind == TokenKind.NEWLINE) {
         break;
       }
-      list.add(parseSmallStatement());
+      parseSmallStatementOrPass(list);
     }
     expect(TokenKind.NEWLINE);
     // This is a safe place to recover: There is a new line at top-level
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/TokenKind.java b/src/main/java/com/google/devtools/build/lib/syntax/TokenKind.java
index 889fa66..e7e92b4 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/TokenKind.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/TokenKind.java
@@ -56,6 +56,7 @@
   NOT_EQUALS("!="),
   OR("or"),
   OUTDENT("outdent"),
+  PASS("pass"),
   PERCENT("%"),
   PLUS("+"),
   PLUS_EQUALS("+="),
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
index b6741c4..f97282e 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ParserTest.java
@@ -778,6 +778,23 @@
   }
 
   @Test
+  public void testPass() throws Exception {
+    List<Statement> statements = parseFileForSkylark("pass\n");
+    assertThat(statements).isEmpty();
+  }
+
+  @Test
+  public void testForPass() throws Exception {
+    List<Statement> statements = parseFileForSkylark(
+        "def foo():\n"
+      + "  pass\n");
+
+    assertThat(statements).hasSize(1);
+    FunctionDefStatement stmt = (FunctionDefStatement) statements.get(0);
+    assertThat(stmt.getStatements()).isEmpty();
+  }
+
+  @Test
   public void testSkipIfBlockFail() throws Exception {
     // Do not parse 'if' blocks, when parsePython is not set
     syntaxEvents.setFailFast(false);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index 65996d8..0b48c68 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -174,6 +174,18 @@
   }
 
   @Test
+  public void testIfPass() throws Exception {
+    exec(parseFileForSkylark(
+        "def foo():\n"
+        + "  a = 1\n"
+        + "  x = True\n"
+        + "  if x: pass\n"
+        + "  return a\n"
+        + "a = foo()"), env);
+    assertEquals(1, env.lookup("a"));
+  }
+
+  @Test
   public void testNestedIf() throws Exception {
     executeNestedIf(0, 0, env);
     assertEquals(0, env.lookup("x"));