blob: 51207e136ab26f451dd91795f30758b400aaf5dc [file] [log] [blame]
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of csslib.visitor;
/**
* The base type for all nodes in a CSS abstract syntax tree.
*/
abstract class TreeNode {
/** The source code this [TreeNode] represents. */
final SourceSpan span;
TreeNode(this.span);
TreeNode clone();
/** Classic double-dispatch visitor for implementing passes. */
visit(VisitorBase visitor);
/** A multiline string showing the node and its children. */
String toDebugString() {
var to = new TreeOutput();
var tp = new _TreePrinter(to, true);
this.visit(tp);
return to.buf.toString();
}
}
/** The base type for expressions. */
abstract class Expression extends TreeNode {
Expression(SourceSpan span) : super(span);
}
/** Simple class to provide a textual dump of trees for debugging. */
class TreeOutput {
int depth = 0;
final StringBuffer buf = new StringBuffer();
VisitorBase printer;
void write(String s) {
for (int i = 0; i < depth; i++) {
buf.write(' ');
}
buf.write(s);
}
void writeln(String s) {
write(s);
buf.write('\n');
}
void heading(String name, [span]) {
write(name);
if (span != null) {
buf.write(' (${span.message('')})');
}
buf.write('\n');
}
String toValue(value) {
if (value == null) return 'null';
else if (value is Identifier) return value.name;
else return value.toString();
}
void writeNode(String label, TreeNode node) {
write('${label}: ');
depth += 1;
if (node != null) node.visit(printer);
else writeln('null');
depth -= 1;
}
void writeValue(String label, value) {
var v = toValue(value);
writeln('${label}: ${v}');
}
void writeNodeList(String label, List<TreeNode> list) {
writeln('${label} [');
if (list != null) {
depth += 1;
for (var node in list) {
if (node != null) {
node.visit(printer);
} else {
writeln('null');
}
}
depth -= 1;
writeln(']');
}
}
String toString() => buf.toString();
}