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/build/lib/syntax/SkylarkDict.java | |
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/build/lib/syntax/SkylarkDict.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java | 163 |
1 files changed, 163 insertions, 0 deletions
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. * |