Merge "Use list comprehensions in Starlark"
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 93b6779..3e490dd 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -694,6 +694,31 @@
formatString := `
# This file is generated by soong_build. Do not edit.
+# a drop-in replacement for json.encode(), not available in cquery environment
+# TODO(cparsons): bring json module in and remove this function
+def json_encode(input):
+ # Avoiding recursion by limiting
+ # - a dict to contain anything except a dict
+ # - a list to contain only primitives
+ def encode_primitive(p):
+ t = type(p)
+ if t == "string" or t == "int":
+ return repr(p)
+ fail("unsupported value '%%s' of type '%%s'" %% (p, type(p)))
+
+ def encode_list(list):
+ return "[%%s]" %% ", ".join([encode_primitive(item) for item in list])
+
+ def encode_list_or_primitive(v):
+ return encode_list(v) if type(v) == "list" else encode_primitive(v)
+
+ if type(input) == "dict":
+ # TODO(juu): the result is read line by line so can't use '\n' yet
+ kv_pairs = [("%%s: %%s" %% (encode_primitive(k), encode_list_or_primitive(v))) for (k, v) in input.items()]
+ return "{ %%s }" %% ", ".join(kv_pairs)
+ else:
+ return encode_list_or_primitive(input)
+
# Label Map Section
%s
@@ -727,15 +752,6 @@
fail("expected platform name of the form 'android_<arch>' or 'linux_<arch>', but was " + str(platforms))
return "UNKNOWN"
-def json_for_file(key, file):
- return '"' + key + '":"' + file.path + '"'
-
-def json_for_files(key, files):
- return '"' + key + '":[' + ",".join(['"' + f.path + '"' for f in files]) + ']'
-
-def json_for_labels(key, ll):
- return '"' + key + '":[' + ",".join(['"' + str(x) + '"' for x in ll]) + ']'
-
def format(target):
id_string = str(target.label) + "|" + get_arch(target)
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 5cee6ac..cf8e9f7 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -235,14 +235,14 @@
// - The function body should not be indented outside of its own scope.
func (g getApexInfoType) StarlarkFunctionBody() string {
return `info = providers(target)["//build/bazel/rules/apex:apex.bzl%ApexInfo"]
-return "{%s}" % ",".join([
- json_for_file("signed_output", info.signed_output),
- json_for_file("unsigned_output", info.unsigned_output),
- json_for_labels("provides_native_libs", info.provides_native_libs),
- json_for_labels("requires_native_libs", info.requires_native_libs),
- json_for_files("bundle_key_pair", info.bundle_key_pair),
- json_for_files("container_key_pair", info.container_key_pair)
- ])`
+return json_encode({
+ "signed_output": info.signed_output.path,
+ "unsigned_output": info.unsigned_output.path,
+ "provides_native_libs": [str(lib) for lib in info.provides_native_libs],
+ "requires_native_libs": [str(lib) for lib in info.requires_native_libs],
+ "bundle_key_pair": [f.path for f in info.bundle_key_pair],
+ "container_key_pair": [f.path for f in info.container_key_pair]
+})`
}
type ApexCqueryInfo struct {
@@ -259,7 +259,9 @@
// Starlark given in StarlarkFunctionBody.
func (g getApexInfoType) ParseResult(rawString string) ApexCqueryInfo {
var info ApexCqueryInfo
- if err := json.Unmarshal([]byte(rawString), &info); err != nil {
+ decoder := json.NewDecoder(strings.NewReader(rawString))
+ decoder.DisallowUnknownFields() //useful to detect typos, e.g. in unit tests
+ if err := decoder.Decode(&info); err != nil {
panic(fmt.Errorf("cannot parse cquery result '%s': %s", rawString, err))
}
return info
diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go
index 34248ce..46eb0b6 100644
--- a/bazel/cquery/request_type_test.go
+++ b/bazel/cquery/request_type_test.go
@@ -161,7 +161,7 @@
actualOutput, err := GetCcInfo.ParseResult(tc.input)
if (err == nil && tc.expectedErrorMessage != "") ||
(err != nil && err.Error() != tc.expectedErrorMessage) {
- t.Errorf("%q:\nexpected Error %s\n, got %s", tc.description, tc.expectedErrorMessage, err)
+ t.Errorf("%q:\n%12s: %q\n%12s: %q", tc.description, "expect Error", tc.expectedErrorMessage, "but got", err)
} else if err == nil && !reflect.DeepEqual(tc.expectedOutput, actualOutput) {
t.Errorf("%q:\n expected %#v\n!= actual %#v", tc.description, tc.expectedOutput, actualOutput)
}