diff options
author | 2018-03-30 13:55:52 -0700 | |
---|---|---|
committer | 2018-03-30 13:58:22 -0700 | |
commit | 7a5761ca0b745c2a4085468d1262093164bcc1ad (patch) | |
tree | b2e87a4f27b22ed749c39d24e0e4f9fa5f395865 /src/main/java/com/google/devtools | |
parent | 7f475d738320933ef4a0e25b0653eabb49a53b88 (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')
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; + } } /** |