Build language: Support 'not in' operator.

--
MOS_MIGRATED_REVID=93129861
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
index 8ca1e9e..5c7715f 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
@@ -511,6 +511,19 @@
   }
 
   @Test
+  public void testNotInOperator() throws Exception {
+    assertEquals(Boolean.FALSE, eval("'b' not in ['a', 'b']"));
+    assertEquals(Boolean.TRUE, eval("'c' not in ['a', 'b']"));
+    assertEquals(Boolean.FALSE, eval("'b' not in ('a', 'b')"));
+    assertEquals(Boolean.TRUE, eval("'c' not in ('a', 'b')"));
+    assertEquals(Boolean.FALSE, eval("'b' not in {'a' : 1, 'b' : 2}"));
+    assertEquals(Boolean.TRUE, eval("'c' not in {'a' : 1, 'b' : 2}"));
+    assertEquals(Boolean.TRUE, eval("1 not in {'a' : 1, 'b' : 2}"));
+    assertEquals(Boolean.FALSE, eval("'b' not in 'abc'"));
+    assertEquals(Boolean.TRUE, eval("'d' not in 'abc'"));
+  }
+
+  @Test
   public void testInFail() throws Exception {
     checkEvalError("in operator only works on strings if the left operand is also a string",
         "1 in '123'");
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 5f7deb7..613a648 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
@@ -626,7 +626,7 @@
     setFailFast(false);
     List<Statement> statements = parseFileForSkylark(
         "def foo():",
-        "  a = 2 not 4",  // parse error
+        "  a = 2 for 4",  // parse error
         "  b = [3, 4]",
         "",
         "d = 4 ada",  // parse error
@@ -637,7 +637,7 @@
         "");
 
     assertThat(getEventCollector()).hasSize(3);
-    assertContainsEvent("syntax error at 'not': expected newline");
+    assertContainsEvent("syntax error at 'for': expected newline");
     assertContainsEvent("syntax error at 'ada': expected newline");
     assertContainsEvent("syntax error at '+': expected expression");
     assertThat(statements).hasSize(3);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java
index f25c827..edbf550 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/ValidationTests.java
@@ -334,7 +334,7 @@
         "  b = [3, 4]",
         "  if a not b:",
         "    print(a)");
-    assertContainsEvent("syntax error at 'not': expected :");
+    assertContainsEvent("syntax error at 'b': expected in");
     // Parser uses "$error" symbol for error recovery.
     // It should not be used in error messages.
     for (Event event : getEventCollector()) {