From 13ef26d0817a429bf214d3dc4c5551e616e403fe Mon Sep 17 00:00:00 2001 From: Francois-Rene Rideau Date: Wed, 17 Jun 2015 15:43:46 +0000 Subject: Skylark: write labels readably Write a label as Label("//x:x") instead of merely "//x:x", so it can be read and evaluated back, as per the Python convention. However, the OutputFormatter for BUILD files still needs to output "//x:x". -- MOS_MIGRATED_REVID=96209979 --- .../build/lib/query2/output/OutputFormatter.java | 43 +++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java') diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java index 26432465d4..baade5a1ce 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.PackageSerializer; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Target; +import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.EvalUtils; import com.google.devtools.build.lib.syntax.Label; import com.google.devtools.build.lib.syntax.Printer; @@ -289,6 +290,46 @@ public abstract class OutputFormatter implements Serializable { return "build"; } + // We only need to be able to output the types allowed in an attribute: + // int, string, label, string_list, label_list, bool, output, output_list, string_dict, license, + // where most of those things are actually printed as strings and list of strings. + private static void outputValue(PrintStream out, Object value) { + if (value instanceof Integer || value instanceof Boolean || value == Environment.NONE) { + Printer.write(out, value); + } else if (value instanceof String) { + Printer.writeString(out, (String) value, '"'); + } else if (value instanceof Label) { + outputValue(out, value.toString()); + } else if (value instanceof List) { + out.print("["); + outputList(out, (List) value); + out.print("]"); + } else if (value instanceof Map) { + Map dict = (Map) value; + out.print("{"); + outputList(out, dict.entrySet()); + out.print("}"); + } else if (value instanceof Map.Entry) { + Map.Entry entry = (Map.Entry) value; + outputValue(out, entry.getKey()); + out.print(": "); + outputValue(out, entry.getValue()); + } else { + throw new RuntimeException("invalid value " + Printer.repr(value)); + } + } + + private static void outputList(PrintStream out, Iterable list) { + boolean first = true; + for (Object v : list) { + if (!first) { + out.print(", "); + first = false; + } + outputValue(out, v); + } + } + private void outputRule(Rule rule, PrintStream out) { out.printf("# %s%n", rule.getLocation()); out.printf("%s(%n", rule.getRuleClass()); @@ -310,7 +351,7 @@ public abstract class OutputFormatter implements Serializable { // Display it as a list (and not as a tuple). Attributes can never be tuples. value = new ArrayList<>((List) value); } - Printer.write(out, value); + outputValue(out, value); out.println(","); } out.printf(")\n%n"); -- cgit v1.2.3