aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
authorGravatar cparsons <cparsons@google.com>2018-03-30 13:55:52 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-03-30 13:58:22 -0700
commit7a5761ca0b745c2a4085468d1262093164bcc1ad (patch)
treeb2e87a4f27b22ed749c39d24e0e4f9fa5f395865 /src/main/java/com/google/devtools
parent7f475d738320933ef4a0e25b0653eabb49a53b88 (diff)
Migrate SkylarkDict and MutableList methods to use @SkylarkCallable instead of @SkylarkSignature.
RELNOTES: None. PiperOrigin-RevId: 191112273
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java370
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java163
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java121
3 files changed, 284 insertions, 370 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index 0597ebf1c9..6e563424c3 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -37,7 +37,6 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.TreeSet;
@@ -1204,375 +1203,6 @@ public class MethodLibrary {
};
@SkylarkSignature(
- name = "append",
- objectType = MutableList.class,
- returnType = Runtime.NoneType.class,
- doc = "Adds an item to the end of the list.",
- parameters = {
- @Param(name = "self", type = MutableList.class, doc = "This list."),
- @Param(name = "item", type = Object.class, doc = "Item to add at the end.")
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction append =
- new BuiltinFunction("append") {
- public Runtime.NoneType invoke(
- MutableList<Object> self, Object item, Location loc, Environment env)
- throws EvalException {
- self.add(item, loc, env.mutability());
- return Runtime.NONE;
- }
- };
-
- @SkylarkSignature(
- name = "insert",
- objectType = MutableList.class,
- returnType = Runtime.NoneType.class,
- doc = "Inserts an item at a given position.",
- parameters = {
- @Param(name = "self", type = MutableList.class, doc = "This list."),
- @Param(name = "index", type = Integer.class, doc = "The index of the given position."),
- @Param(name = "item", type = Object.class, doc = "The item.")
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction insert =
- new BuiltinFunction("insert") {
- public Runtime.NoneType invoke(
- MutableList<Object> self, Integer index, Object item, Location loc, Environment env)
- throws EvalException {
- self.add(EvalUtils.clampRangeEndpoint(index, self.size()), item, loc, env.mutability());
- return Runtime.NONE;
- }
- };
-
- @SkylarkSignature(
- name = "extend",
- objectType = MutableList.class,
- returnType = Runtime.NoneType.class,
- doc = "Adds all items to the end of the list.",
- parameters = {
- @Param(name = "self", type = MutableList.class, doc = "This list."),
- @Param(name = "items", type = SkylarkList.class, doc = "Items to add at the end.")
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction extend =
- new BuiltinFunction("extend") {
- public Runtime.NoneType invoke(
- MutableList<Object> self, SkylarkList<Object> items, Location loc, Environment env)
- throws EvalException {
- self.addAll(items, loc, env.mutability());
- return Runtime.NONE;
- }
- };
-
- @SkylarkSignature(
- name = "index",
- objectType = MutableList.class,
- returnType = Integer.class,
- doc =
- "Returns the index in the list of the first item whose value is x. "
- + "It is an error if there is no such item.",
- parameters = {
- @Param(name = "self", type = MutableList.class, doc = "This list."),
- @Param(name = "x", type = Object.class, doc = "The object to search.")
- },
- useLocation = true
- )
- private static final BuiltinFunction listIndex =
- new BuiltinFunction("index") {
- public Integer invoke(MutableList<?> self, Object x, Location loc) throws EvalException {
- int i = 0;
- for (Object obj : self) {
- if (obj.equals(x)) {
- return i;
- }
- i++;
- }
- throw new EvalException(loc, Printer.format("item %r not found in list", x));
- }
- };
-
- @SkylarkSignature(
- name = "remove",
- objectType = MutableList.class,
- returnType = Runtime.NoneType.class,
- doc =
- "Removes the first item from the list whose value is x. "
- + "It is an error if there is no such item.",
- parameters = {
- @Param(name = "self", type = MutableList.class, doc = "This list."),
- @Param(name = "x", type = Object.class, doc = "The object to remove.")
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction listRemove =
- new BuiltinFunction("remove") {
- public Runtime.NoneType invoke(MutableList<?> self, Object x, Location loc, Environment env)
- throws EvalException {
- for (int i = 0; i < self.size(); i++) {
- if (self.get(i).equals(x)) {
- self.remove(i, loc, env.mutability());
- return Runtime.NONE;
- }
- }
- throw new EvalException(loc, Printer.format("item %r not found in list", x));
- }
- };
-
- @SkylarkSignature(
- name = "pop",
- objectType = MutableList.class,
- returnType = Object.class,
- doc =
- "Removes the item at the given position in the list, and returns it. "
- + "If no <code>index</code> is specified, "
- + "it removes and returns the last item in the list.",
- parameters = {
- @Param(name = "self", type = MutableList.class, doc = "This list."),
- @Param(
- name = "i",
- type = Integer.class,
- noneable = true,
- defaultValue = "None",
- doc = "The index of the item."
- )
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction listPop =
- new BuiltinFunction("pop") {
- public Object invoke(MutableList<?> self, Object i, Location loc, Environment env)
- throws EvalException {
- int arg = i == Runtime.NONE ? -1 : (Integer) i;
- int index = EvalUtils.getSequenceIndex(arg, self.size(), loc);
- Object result = self.get(index);
- self.remove(index, loc, env.mutability());
- return result;
- }
- };
-
- @SkylarkSignature(
- name = "pop",
- objectType = SkylarkDict.class,
- returnType = Object.class,
- doc =
- "Removes a <code>key</code> from the dict, and returns the associated value. "
- + "If entry with that key was found, return the specified <code>default</code> value;"
- + "if no default value was specified, fail instead.",
- parameters = {
- @Param(name = "self", type = SkylarkDict.class, doc = "This dict."),
- @Param(name = "key", type = Object.class, doc = "The key."),
- @Param(name = "default", type = Object.class, defaultValue = "unbound",
- doc = "a default value if the key is absent."),
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction dictPop =
- new BuiltinFunction("pop") {
- public Object invoke(SkylarkDict<Object, Object> self, Object key, Object defaultValue,
- Location loc, Environment env)
- throws EvalException {
- Object value = self.get(key);
- if (value != null) {
- self.remove(key, loc, env.mutability());
- return value;
- }
- if (defaultValue != Runtime.UNBOUND) {
- return defaultValue;
- }
- throw new EvalException(loc, Printer.format("KeyError: %r", key));
- }
- };
-
- @SkylarkSignature(
- name = "popitem",
- objectType = SkylarkDict.class,
- returnType = Tuple.class,
- doc =
- "Remove and return an arbitrary <code>(key, value)</code> pair from the dictionary. "
- + "<code>popitem()</code> is useful to destructively iterate over a dictionary, "
- + "as often used in set algorithms. "
- + "If the dictionary is empty, calling <code>popitem()</code> fails. "
- + "It is deterministic which pair is returned.",
- parameters = {
- @Param(name = "self", type = SkylarkDict.class, doc = "This dict.")
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction dictPopItem =
- new BuiltinFunction("popitem") {
- public Tuple<Object> invoke(SkylarkDict<Object, Object> self,
- Location loc, Environment env)
- throws EvalException {
- if (self.isEmpty()) {
- throw new EvalException(loc, "popitem(): dictionary is empty");
- }
- Object key = self.keySet().iterator().next();
- Object value = self.get(key);
- self.remove(key, loc, env.mutability());
- return Tuple.of(key, value);
- }
- };
-
- @SkylarkSignature(
- name = "clear",
- objectType = SkylarkDict.class,
- returnType = Runtime.NoneType.class,
- doc = "Remove all items from the dictionary.",
- parameters = {
- @Param(name = "self", type = SkylarkDict.class, doc = "This dict.")
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction dictClear =
- new BuiltinFunction("clear") {
- public Runtime.NoneType invoke(SkylarkDict<Object, Object> self,
- Location loc, Environment env)
- throws EvalException {
- self.clear(loc, env.mutability());
- return Runtime.NONE;
- }
- };
-
- @SkylarkSignature(
- name = "setdefault",
- objectType = SkylarkDict.class,
- returnType = Object.class,
- doc =
- "If <code>key</code> is in the dictionary, return its value. "
- + "If not, insert key with a value of <code>default</code> "
- + "and return <code>default</code>. "
- + "<code>default</code> defaults to <code>None</code>.",
- parameters = {
- @Param(name = "self", type = SkylarkDict.class, doc = "This dict."),
- @Param(name = "key", type = Object.class, doc = "The key."),
- @Param(
- name = "default",
- type = Object.class,
- defaultValue = "None",
- doc = "a default value if the key is absent."
- ),
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction dictSetDefault =
- new BuiltinFunction("setdefault") {
- public Object invoke(
- SkylarkDict<Object, Object> self,
- Object key,
- Object defaultValue,
- Location loc,
- Environment env)
- throws EvalException {
- Object value = self.get(key);
- if (value != null) {
- return value;
- }
- self.put(key, defaultValue, loc, env);
- return defaultValue;
- }
- };
-
- @SkylarkSignature(
- name = "update",
- objectType = SkylarkDict.class,
- returnType = Runtime.NoneType.class,
- doc = "Update the dictionary with the key/value pairs from other, overwriting existing keys.",
- parameters = {
- @Param(name = "self", type = SkylarkDict.class, doc = "This dict."),
- @Param(name = "other", type = SkylarkDict.class, doc = "The values to add."),
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction dictUpdate =
- new BuiltinFunction("update") {
- public Runtime.NoneType invoke(
- SkylarkDict<Object, Object> self,
- SkylarkDict<Object, Object> other,
- Location loc,
- Environment env)
- throws EvalException {
- self.putAll(other, loc, env.mutability());
- return Runtime.NONE;
- }
- };
-
- @SkylarkSignature(
- name = "values",
- objectType = SkylarkDict.class,
- returnType = MutableList.class,
- doc =
- "Returns the list of values:"
- + "<pre class=\"language-python\">"
- + "{2: \"a\", 4: \"b\", 1: \"c\"}.values() == [\"a\", \"b\", \"c\"]</pre>\n",
- parameters = {@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
- useEnvironment = true
- )
- private static final BuiltinFunction values =
- new BuiltinFunction("values") {
- public MutableList<?> invoke(SkylarkDict<?, ?> self, Environment env) throws EvalException {
- return MutableList.copyOf(env, self.values());
- }
- };
-
- @SkylarkSignature(
- name = "items",
- objectType = SkylarkDict.class,
- returnType = MutableList.class,
- doc =
- "Returns the list of key-value tuples:"
- + "<pre class=\"language-python\">"
- + "{2: \"a\", 4: \"b\", 1: \"c\"}.items() == [(2, \"a\"), (4, \"b\"), (1, \"c\")]"
- + "</pre>\n",
- parameters = {@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
- useEnvironment = true
- )
- private static final BuiltinFunction items =
- new BuiltinFunction("items") {
- public MutableList<?> invoke(SkylarkDict<?, ?> self, Environment env) throws EvalException {
- ArrayList<Object> list = Lists.newArrayListWithCapacity(self.size());
- for (Map.Entry<?, ?> entries : self.entrySet()) {
- list.add(Tuple.of(entries.getKey(), entries.getValue()));
- }
- return MutableList.wrapUnsafe(env, list);
- }
- };
-
- @SkylarkSignature(name = "keys", objectType = SkylarkDict.class,
- returnType = MutableList.class,
- doc = "Returns the list of keys:"
- + "<pre class=\"language-python\">{2: \"a\", 4: \"b\", 1: \"c\"}.keys() == [2, 4, 1]"
- + "</pre>\n",
- parameters = {
- @Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
- useEnvironment = true)
- private static final BuiltinFunction keys = new BuiltinFunction("keys") {
- // Skylark will only call this on a dict; and
- // allowed keys are all Comparable... if not mutually, it's OK to get a runtime exception.
- @SuppressWarnings("unchecked")
- public MutableList<?> invoke(SkylarkDict<?, ?> self,
- Environment env) throws EvalException {
- ArrayList<Object> list = Lists.newArrayListWithCapacity(self.size());
- for (Map.Entry<?, ?> entries : self.entrySet()) {
- list.add(entries.getKey());
- }
- return MutableList.wrapUnsafe(env, list);
- }
- };
-
- @SkylarkSignature(
name = "tuple",
returnType = Tuple.class,
doc =
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 db656328fd..1cb04977f1 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
@@ -15,13 +15,17 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Lists;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
+import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkMutable.MutableMap;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -90,6 +94,152 @@ public final class SkylarkDict<K, V> extends MutableMap<K, V>
return defaultValue;
}
+ @SkylarkCallable(
+ name = "pop",
+ doc =
+ "Removes a <code>key</code> from the dict, and returns the associated value. "
+ + "If entry with that key was found, return the specified <code>default</code> value;"
+ + "if no default value was specified, fail instead.",
+ parameters = {
+ @Param(name = "key", type = Object.class, doc = "The key."),
+ @Param(name = "default", type = Object.class, defaultValue = "unbound", named = true,
+ noneable = true, doc = "a default value if the key is absent."),
+ },
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Object pop(Object key, Object defaultValue,
+ Location loc, Environment env)
+ throws EvalException {
+ Object value = get(key);
+ if (value != null) {
+ remove(key, loc, env.mutability());
+ return value;
+ }
+ if (defaultValue != Runtime.UNBOUND) {
+ return defaultValue;
+ }
+ throw new EvalException(loc, Printer.format("KeyError: %r", key));
+ }
+
+ @SkylarkCallable(
+ name = "popitem",
+ doc =
+ "Remove and return an arbitrary <code>(key, value)</code> pair from the dictionary. "
+ + "<code>popitem()</code> is useful to destructively iterate over a dictionary, "
+ + "as often used in set algorithms. "
+ + "If the dictionary is empty, calling <code>popitem()</code> fails. "
+ + "It is deterministic which pair is returned.",
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Tuple<Object> popitem(Location loc, Environment env)
+ throws EvalException {
+ if (isEmpty()) {
+ throw new EvalException(loc, "popitem(): dictionary is empty");
+ }
+ Object key = keySet().iterator().next();
+ Object value = get(key);
+ remove(key, loc, env.mutability());
+ return Tuple.of(key, value);
+ }
+
+ @SkylarkCallable(
+ name = "setdefault",
+ doc =
+ "If <code>key</code> is in the dictionary, return its value. "
+ + "If not, insert key with a value of <code>default</code> "
+ + "and return <code>default</code>. "
+ + "<code>default</code> defaults to <code>None</code>.",
+ parameters = {
+ @Param(name = "key", type = Object.class, doc = "The key."),
+ @Param(
+ name = "default",
+ type = Object.class,
+ defaultValue = "None",
+ named = true,
+ noneable = true,
+ doc = "a default value if the key is absent."
+ ),
+ },
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Object setdefault(
+ K key,
+ V defaultValue,
+ Location loc,
+ Environment env)
+ throws EvalException {
+ Object value = get(key);
+ if (value != null) {
+ return value;
+ }
+ put(key, defaultValue, loc, env);
+ return defaultValue;
+ }
+
+ @SkylarkCallable(
+ name = "update",
+ doc = "Update the dictionary with the key/value pairs from other, overwriting existing keys.",
+ parameters = {
+ @Param(name = "other", type = SkylarkDict.class, doc = "The values to add."),
+ },
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Runtime.NoneType update(
+ SkylarkDict<K, V> other,
+ Location loc,
+ Environment env)
+ throws EvalException {
+ putAll(other, loc, env.mutability());
+ return Runtime.NONE;
+ }
+
+ @SkylarkCallable(
+ name = "values",
+ doc =
+ "Returns the list of values:"
+ + "<pre class=\"language-python\">"
+ + "{2: \"a\", 4: \"b\", 1: \"c\"}.values() == [\"a\", \"b\", \"c\"]</pre>\n",
+ useEnvironment = true
+ )
+ public MutableList<?> invoke(Environment env) throws EvalException {
+ return MutableList.copyOf(env, values());
+ }
+
+ @SkylarkCallable(
+ name = "items",
+ doc =
+ "Returns the list of key-value tuples:"
+ + "<pre class=\"language-python\">"
+ + "{2: \"a\", 4: \"b\", 1: \"c\"}.items() == [(2, \"a\"), (4, \"b\"), (1, \"c\")]"
+ + "</pre>\n",
+ useEnvironment = true
+ )
+ public MutableList<?> items(Environment env) throws EvalException {
+ ArrayList<Object> list = Lists.newArrayListWithCapacity(size());
+ for (Map.Entry<?, ?> entries : entrySet()) {
+ list.add(Tuple.of(entries.getKey(), entries.getValue()));
+ }
+ return MutableList.wrapUnsafe(env, list);
+ }
+
+ @SkylarkCallable(name = "keys",
+ doc = "Returns the list of keys:"
+ + "<pre class=\"language-python\">{2: \"a\", 4: \"b\", 1: \"c\"}.keys() == [2, 4, 1]"
+ + "</pre>\n",
+ useEnvironment = true
+ )
+ public MutableList<?> keys(Environment env) throws EvalException {
+ ArrayList<Object> list = Lists.newArrayListWithCapacity(size());
+ for (Map.Entry<?, ?> entries : entrySet()) {
+ list.add(entries.getKey());
+ }
+ return MutableList.wrapUnsafe(env, list);
+ }
+
private static final SkylarkDict<?, ?> EMPTY = withMutability(Mutability.IMMUTABLE);
/** Returns an immutable empty dict. */
@@ -221,6 +371,19 @@ public final class SkylarkDict<K, V> extends MutableMap<K, V>
return contents.remove(key);
}
+ @SkylarkCallable(
+ name = "clear",
+ doc = "Remove all items from the dictionary.",
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Runtime.NoneType clear(
+ Location loc, Environment env)
+ throws EvalException {
+ clear(loc, env.mutability());
+ return Runtime.NONE;
+ }
+
/**
* Clears the dict.
*
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 55ae33d4d2..ebe9cf52bf 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
@@ -19,6 +19,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkinterface.Param;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
@@ -475,6 +477,28 @@ public abstract class SkylarkList<E> extends BaseMutableList<E>
contents.remove(index);
}
+ @SkylarkCallable(
+ name = "remove",
+ doc =
+ "Removes the first item from the list whose value is x. "
+ + "It is an error if there is no such item.",
+ parameters = {
+ @Param(name = "x", type = Object.class, doc = "The object to remove.")
+ },
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Runtime.NoneType remove(Object x, Location loc, Environment env)
+ throws EvalException {
+ for (int i = 0; i < size(); i++) {
+ if (get(i).equals(x)) {
+ remove(i, loc, env.mutability());
+ return Runtime.NONE;
+ }
+ }
+ throw new EvalException(loc, Printer.format("item %r not found in list", x));
+ }
+
/**
* Sets the position at the given index to contain the given value. The index must already have
* been validated to be in range.
@@ -488,6 +512,103 @@ public abstract class SkylarkList<E> extends BaseMutableList<E>
checkMutable(loc, mutability);
contents.set(index, value);
}
+
+ @SkylarkCallable(
+ name = "append",
+ doc = "Adds an item to the end of the list.",
+ parameters = {
+ @Param(name = "item", type = Object.class, doc = "Item to add at the end.")
+ },
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Runtime.NoneType append(
+ E item, Location loc, Environment env)
+ throws EvalException {
+ add(item, loc, env.mutability());
+ return Runtime.NONE;
+ }
+
+ @SkylarkCallable(
+ name = "insert",
+ doc = "Inserts an item at a given position.",
+ parameters = {
+ @Param(name = "index", type = Integer.class, doc = "The index of the given position."),
+ @Param(name = "item", type = Object.class, doc = "The item.")
+ },
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Runtime.NoneType insert(
+ Integer index, E item, Location loc, Environment env)
+ throws EvalException {
+ add(EvalUtils.clampRangeEndpoint(index, size()), item, loc, env.mutability());
+ return Runtime.NONE;
+ }
+
+ @SkylarkCallable(
+ name = "extend",
+ doc = "Adds all items to the end of the list.",
+ parameters = {
+ @Param(name = "items", type = SkylarkList.class, doc = "Items to add at the end.")
+ },
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Runtime.NoneType extend(
+ SkylarkList<E> items, Location loc, Environment env)
+ throws EvalException {
+ addAll(items, loc, env.mutability());
+ return Runtime.NONE;
+ }
+
+ @SkylarkCallable(
+ name = "index",
+ doc =
+ "Returns the index in the list of the first item whose value is x. "
+ + "It is an error if there is no such item.",
+ parameters = {
+ @Param(name = "x", type = Object.class, doc = "The object to search.")
+ },
+ useLocation = true
+ )
+ public Integer index(Object x, Location loc) throws EvalException {
+ int i = 0;
+ for (Object obj : this) {
+ if (obj.equals(x)) {
+ return i;
+ }
+ i++;
+ }
+ throw new EvalException(loc, Printer.format("item %r not found in list", x));
+ }
+
+ @SkylarkCallable(
+ name = "pop",
+ doc =
+ "Removes the item at the given position in the list, and returns it. "
+ + "If no <code>index</code> is specified, "
+ + "it removes and returns the last item in the list.",
+ parameters = {
+ @Param(
+ name = "i",
+ type = Integer.class,
+ noneable = true,
+ defaultValue = "None",
+ doc = "The index of the item."
+ )
+ },
+ useLocation = true,
+ useEnvironment = true
+ )
+ public Object pop(Object i, Location loc, Environment env)
+ throws EvalException {
+ int arg = i == Runtime.NONE ? -1 : (Integer) i;
+ int index = EvalUtils.getSequenceIndex(arg, size(), loc);
+ Object result = get(index);
+ remove(index, loc, env.mutability());
+ return result;
+ }
}
/**