Index: pkg/compiler/lib/src/util/indentation.dart |
diff --git a/pkg/compiler/lib/src/util/indentation.dart b/pkg/compiler/lib/src/util/indentation.dart |
index 6206bd6793926b5d07f71b7973ec6d0fe4f056dc..ddbeafa7f11027e991e0688adaff1a2d00498712 100644 |
--- a/pkg/compiler/lib/src/util/indentation.dart |
+++ b/pkg/compiler/lib/src/util/indentation.dart |
@@ -51,3 +51,96 @@ class Indentation { |
return result; |
} |
} |
+ |
+abstract class Tagging<N> implements Indentation { |
+ |
+ StringBuffer sb = new StringBuffer(); |
+ Link<String> tagStack = const Link<String>(); |
+ |
+ void pushTag(String tag) { |
+ tagStack = tagStack.prepend(tag); |
+ indentMore(); |
+ } |
+ |
+ String popTag() { |
+ assert(!tagStack.isEmpty); |
+ String tag = tagStack.head; |
+ tagStack = tagStack.tail; |
+ indentLess(); |
+ return tag; |
+ } |
+ |
+ /** |
+ * Adds given string to result string. |
+ */ |
+ void add(String string) { |
+ sb.write(string); |
+ } |
+ |
+ /// Adds default parameters for [node] into [params]. |
+ void addDefaultParameters(N node, Map params) {} |
+ |
+ /** |
+ * Adds given node type to result string. |
+ * The method "opens" the node, meaning that all output after calling |
+ * this method and before calling closeNode() will represent contents |
+ * of given node. |
+ */ |
+ void openNode(N node, String type, [Map params]) { |
+ if (params == null) params = new Map(); |
+ addCurrentIndent(); |
+ sb.write("<"); |
+ addDefaultParameters(node, params); |
+ addTypeWithParams(type, params); |
+ sb.write(">\n"); |
+ pushTag(type); |
+ } |
+ |
+ /** |
+ * Adds given node to result string. |
+ */ |
+ void openAndCloseNode(N node, String type, [Map params]) { |
+ if (params == null) params = {}; |
+ addCurrentIndent(); |
+ sb.write("<"); |
+ addDefaultParameters(node, params); |
+ addTypeWithParams(type, params); |
+ sb.write("/>\n"); |
+ } |
+ |
+ /** |
+ * Closes current node type. |
+ */ |
+ void closeNode() { |
+ String tag = popTag(); |
+ addCurrentIndent(); |
+ sb.write("</"); |
+ addTypeWithParams(tag); |
+ sb.write(">\n"); |
+ } |
+ |
+ void addTypeWithParams(String type, [Map params]) { |
+ if (params == null) params = new Map(); |
+ sb.write("${type}"); |
+ params.forEach((k, v) { |
+ String value; |
+ if (v != null) { |
+ String str = valueToString(v); |
+ value = str |
+ .replaceAll("<", "<") |
+ .replaceAll(">", ">") |
+ .replaceAll('"', "'"); |
+ } else { |
+ value = "[null]"; |
+ } |
+ sb.write(' $k="$value"'); |
+ }); |
+ } |
+ |
+ void addCurrentIndent() { |
+ sb.write(indentation); |
+ } |
+ |
+ /// Converts a parameter value into a string. |
+ String valueToString(var value) => value; |
+} |