aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
authorGravatar Florian Weikert <fwe@google.com>2015-09-25 11:59:40 +0000
committerGravatar Han-Wen Nienhuys <hanwen@google.com>2015-09-25 14:41:38 +0000
commit1c07e325fd073cb1d801098507e658f160750df3 (patch)
tree8032d21a4509dffc5486b3f482df2a3d223b1a2b /src/main/java/com
parent1249c9a9aec28d9964ac8d72f3685d24d02828dc (diff)
Implemented copy constructor for Skylark dictionaries: new_dict = dict(old_dict)
-- MOS_MIGRATED_REVID=103932279
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java63
1 files changed, 39 insertions, 24 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 2afcbc3017..cb3372430c 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
@@ -32,8 +32,8 @@ import com.google.devtools.build.lib.syntax.Type.ConversionException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -1186,37 +1186,52 @@ public class MethodLibrary {
+ "will overwrite values from the positional argument if a key appears multiple times. "
+ "Dictionaries are always sorted by their keys",
optionalPositionals = {
- @Param(name = "args", type = Iterable.class, defaultValue = "[]",
+ @Param(name = "args", type = Object.class, defaultValue = "[]",
doc =
- "List of entries. Entries must be tuples or lists with exactly "
- + "two elements: key, value"),
+ "Either a dictionary or a list of entries. Entries must be tuples or lists with "
+ + "exactly two elements: key, value"),
},
extraKeywords = {@Param(name = "kwargs", doc = "Dictionary of additional entries.")},
useLocation = true)
private static final BuiltinFunction dict = new BuiltinFunction("dict") {
@SuppressWarnings("unused")
- public Map<Object, Object> invoke(Iterable<Object> args, Map<Object, Object> kwargs,
- Location loc) throws EvalException, ConversionException {
+ public Map<Object, Object> invoke(Object args, Map<Object, Object> kwargs, Location loc)
+ throws EvalException {
+ Map<Object, Object> result =
+ (args instanceof Map<?, ?>)
+ ? new LinkedHashMap<>((Map<?, ?>) args) : getMapFromArgs(args, loc);
+ result.putAll(kwargs);
+ return result;
+ }
+
+ private Map<Object, Object> getMapFromArgs(Object args, Location loc) throws EvalException {
+ Map<Object, Object> result = new LinkedHashMap<>();
+ int pos = 0;
+ for (Object element : Type.OBJECT_LIST.convert(args, "parameter args in dict()")) {
+ List<Object> pair = convertToPair(element, pos, loc);
+ result.put(pair.get(0), pair.get(1));
+ ++pos;
+ }
+ return result;
+ }
+
+ private List<Object> convertToPair(Object element, int pos, Location loc)
+ throws EvalException {
try {
- Map<Object, Object> result = new HashMap<>();
- List<Object> list = Type.OBJECT_LIST.convert(args, "dict(args)");
-
- for (Object tuple : list) {
- List<Object> mapping = Type.OBJECT_LIST.convert(tuple, "dict(args)");
- int numElements = mapping.size();
-
- if (numElements != 2) {
- throw new EvalException(
- location,
- String.format(
- "Tuple has length %d, but exactly two elements are required", numElements));
- }
- result.put(mapping.get(0), mapping.get(1));
+ List<Object> tuple = Type.OBJECT_LIST.convert(element, "");
+ int numElements = tuple.size();
+ if (numElements != 2) {
+ throw new EvalException(
+ location,
+ String.format("Sequence #%d has length %d, but exactly two elements are required",
+ pos, numElements));
}
- result.putAll(kwargs);
- return result;
- } catch (IllegalArgumentException | ClassCastException | NullPointerException ex) {
- throw new EvalException(loc, ex);
+ return tuple;
+ } catch (ConversionException e) {
+ throw new EvalException(
+ loc,
+ String.format(
+ "Cannot convert dictionary update sequence element #%d to a sequence", pos));
}
}
};