Supported "in" operator for all SkylarkIndexable objects.

--
MOS_MIGRATED_REVID=135483694
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
index 107e64b..cbe5056 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/AbstractConfiguredTarget.java
@@ -150,6 +150,24 @@
   }
 
   @Override
+  public boolean containsKey(Object key, Location loc) throws EvalException {
+    if (!(key instanceof SkylarkClassObjectConstructor)) {
+      throw new EvalException(loc, String.format(
+          "Type Target only supports querying by object constructors, got %s instead",
+          EvalUtils.getDataTypeName(key)));
+    }
+    SkylarkClassObjectConstructor constructor = (SkylarkClassObjectConstructor) key;
+    SkylarkProviders provider = getProvider(SkylarkProviders.class);
+    if (provider != null) {
+      Object declaredProvider = provider.getDeclaredProvider(constructor.getKey());
+      if (declaredProvider != null) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @Override
   public String errorMessage(String name) {
     return null;
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
index 347c728..1c6eebd 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/AliasConfiguredTarget.java
@@ -96,6 +96,11 @@
   }
 
   @Override
+  public boolean containsKey(Object key, Location loc) throws EvalException {
+    return actual != null && actual.containsKey(key, loc);
+  }
+
+  @Override
   public Target getTarget() {
     return actual == null ? null : actual.getTarget();
   }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
index 131ee54..15989ec 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
@@ -95,17 +95,8 @@
    * <p>Publicly accessible for reflection and compiled Skylark code.
    */
   public static boolean in(Object lval, Object rval, Location location) throws EvalException {
-    if (rval instanceof SkylarkList) {
-      for (Object obj : (SkylarkList) rval) {
-        if (obj.equals(lval)) {
-          return true;
-        }
-      }
-      return false;
-    } else if (rval instanceof SkylarkDict) {
-      return ((SkylarkDict<?, ?>) rval).containsKey(lval);
-    } else if (rval instanceof SkylarkNestedSet) {
-      return ((SkylarkNestedSet) rval).expandedSet().contains(lval);
+    if (rval instanceof SkylarkQueryable) {
+      return ((SkylarkQueryable) rval).containsKey(lval, location);
     } else if (rval instanceof String) {
       if (lval instanceof String) {
         return ((String) rval).contains((String) lval);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java
index 49f6c58..fc5e9cf 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java
@@ -223,6 +223,11 @@
     return this.get(key);
   }
 
+  @Override
+  public final boolean containsKey(Object key, Location loc) throws EvalException {
+    return this.containsKey(key);
+  }
+
   public static <K, V> SkylarkDict<K, V> plus(
       SkylarkDict<? extends K, ? extends V> left,
       SkylarkDict<? extends K, ? extends V> right,
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkIndexable.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkIndexable.java
index 18293f4..b33fb45 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkIndexable.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkIndexable.java
@@ -17,9 +17,9 @@
 import com.google.devtools.build.lib.events.Location;
 
 /**
- * Skylark values that support index access, i.e. object[key]
+ * Skylark values that support index access, i.e. `object[key]`
  */
-public interface SkylarkIndexable {
+public interface SkylarkIndexable extends SkylarkQueryable {
 
   /**
    * Returns the value associated with the given key.
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
index 81cad2f..1c1c52b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
@@ -136,6 +136,16 @@
     return list.get(index);
   }
 
+  @Override
+  public final boolean containsKey(Object key, Location loc) throws EvalException {
+    for (Object obj : this) {
+      if (obj.equals(key)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   /**
    * Retrieve a sublist from a SkylarkList.
    * @param start start value
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java
index 2a64d79..1657955 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java
@@ -78,7 +78,7 @@
       + "nested sets."
 )
 @Immutable
-public final class SkylarkNestedSet implements Iterable<Object>, SkylarkValue {
+public final class SkylarkNestedSet implements Iterable<Object>, SkylarkValue, SkylarkQueryable {
 
   private final SkylarkType contentType;
   @Nullable private final List<Object> items;
@@ -272,4 +272,9 @@
     }
     Printer.append(buffer, ")");
   }
+
+  @Override
+  public final boolean containsKey(Object key, Location loc) throws EvalException {
+    return (this.expandedSet().contains(key));
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkQueryable.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkQueryable.java
new file mode 100644
index 0000000..b278168
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkQueryable.java
@@ -0,0 +1,29 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.syntax;
+
+import com.google.devtools.build.lib.events.Location;
+
+/**
+ * Skylark values that support querying by other objects, i.e. `foo in object`.
+ * Semantics of the operation may differ, i.e. dicts check for keys and lists for values.
+ */
+public interface SkylarkQueryable {
+
+  /**
+   * Returns whether the key is in the object.
+   */
+  boolean containsKey(Object key, Location loc) throws EvalException;
+}