Files
sdk/utils/css/tree.dart
T
terry@google.com 91dd628bd8 More changes for CSS to run under VM.
Need unique name for library collision with template parser.

Few more changes to work under VM.

More changes for lang.dart seperation.

Seperation from lang.dart (tokenizer can't access private fields of base class in another library).  This was allowed in frog but not in the VM.  VM is right so need to sever dependency.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com//9695048

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@5544 260f80e4-7a28-3924-810f-c04153c831b5
2012-03-15 21:19:54 +00:00

1280 lines
34 KiB
Dart

// Copyright (c) 2011, 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.
// Generated by scripts/tree_gen.py.
/////////////////////////////////////////////////////////////////////////
// CSS specific types:
/////////////////////////////////////////////////////////////////////////
class Identifier extends ASTNode {
String name;
Identifier(this.name, SourceSpan span): super(span);
visit(TreeVisitor visitor) => visitor.visitIdentifier(this);
String toString() => name;
}
class Wildcard extends ASTNode {
Wildcard(SourceSpan span): super(span);
visit(TreeVisitor visitor) => visitor.visitWildcard(this);
String toString() => '*';
}
// /* .... */
class CssComment extends ASTNode {
String comment;
CssComment(this.comment, SourceSpan span): super(span);
visit(TreeVisitor visitor) => visitor.visitCssComment(this);
String toString() => '/* ${comment} */';
}
// CDO/CDC (Comment Definition Open <!-- and Comment Definition Close -->).
class CommentDefinition extends CssComment {
CommentDefinition(String comment, SourceSpan span): super(comment, span);
visit(TreeVisitor visitor) => visitor.visitCommentDefinition(this);
String toString() => '<!-- ${comment} -->';
}
class SelectorGroup extends ASTNode {
List<Selector> _selectors;
SelectorGroup(this._selectors, SourceSpan span): super(span);
List<Selector> get selectors() => _selectors;
visit(TreeVisitor visitor) => visitor.visitSelectorGroup(this);
String toString() {
StringBuffer buff = new StringBuffer();
int idx = 0;
for (final selector in _selectors) {
if (idx++ > 0) {
buff.add(', ');
}
buff.add(selector.toString());
}
return buff.toString();
}
/** A multiline string showing the node and its children. */
String toDebugString() {
var to = new TreeOutput();
var tp = new TreePrinter(to);
this.visit(tp);
return to.buf.toString();
}
}
class Selector extends ASTNode {
List<SimpleSelectorSequence> _simpleSelectorSequences;
Selector(this._simpleSelectorSequences, SourceSpan span) : super(span);
List<SimpleSelectorSequence> get simpleSelectorSequences() =>
_simpleSelectorSequences;
add(SimpleSelectorSequence seq) => _simpleSelectorSequences.add(seq);
List<SimpleSelectorSequence> get simpleSelectorSquences() =>
_simpleSelectorSequences;
int get length() => _simpleSelectorSequences.length;
String toString() {
StringBuffer buff = new StringBuffer();
for (final simpleSelectorSequence in _simpleSelectorSequences) {
buff.add(simpleSelectorSequence.toString());
}
return buff.toString();
}
visit(TreeVisitor visitor) => visitor.visitSelector(this);
}
class SimpleSelectorSequence extends ASTNode {
int _combinator; // +, >, ~, NONE
SimpleSelector _selector;
SimpleSelectorSequence(this._selector, SourceSpan span,
[this._combinator = TokenKind.COMBINATOR_NONE]) : super(span);
get simpleSelector() => _selector;
bool isCombinatorNone() => _combinator == TokenKind.COMBINATOR_NONE;
bool isCombinatorPlus() => _combinator == TokenKind.COMBINATOR_PLUS;
bool isCombinatorGreater() => _combinator == TokenKind.COMBINATOR_GREATER;
bool isCombinatorTilde() => _combinator == TokenKind.COMBINATOR_TILDE;
bool isCombinatorDescendant() =>
_combinator == TokenKind.COMBINATOR_DESCENDANT;
String _combinatorToString() =>
isCombinatorDescendant() ? ' ' :
isCombinatorPlus() ? '+' :
isCombinatorGreater() ? '>' :
isCombinatorTilde() ? '~' : '';
visit(TreeVisitor visitor) => visitor.visitSimpleSelectorSequence(this);
String toString() => _combinatorToString() + _selector.toString();
}
/* All other selectors (element, #id, .class, attribute, pseudo, negation,
* namespace, *) are derived from this selector.
*/
class SimpleSelector extends ASTNode {
var _name;
SimpleSelector(this._name, SourceSpan span) : super(span);
// Name can be an Identifier or WildCard we'll return either the name or '*'.
String get name() => isWildcard() ? '*' : _name.name;
bool isWildcard() => _name is Wildcard;
visit(TreeVisitor visitor) => visitor.visitSimpleSelector(this);
String toString() => name;
}
// element name
class ElementSelector extends SimpleSelector {
ElementSelector(var name, SourceSpan span) : super(name, span);
visit(TreeVisitor visitor) => visitor.visitElementSelector(this);
String toString() => "$name";
/** A multiline string showing the node and its children. */
String toDebugString() {
var to = new TreeOutput();
var tp = new TreePrinter(to);
this.visit(tp);
return to.buf.toString();
}
}
// namespace|element
class NamespaceSelector extends SimpleSelector {
var _namespace; // null, Wildcard or Identifier
NamespaceSelector(this._namespace, var name, SourceSpan span) :
super(name, span);
String get namespace() => _namespace is Wildcard ? '*' : _namespace.name;
bool isNamespaceWildcard() => _namespace is Wildcard;
SimpleSelector get nameAsSimpleSelector() => _name;
visit(TreeVisitor visitor) => visitor.visitNamespaceSelector(this);
String toString() => "$namespace|${nameAsSimpleSelector.name}";
}
// [attr op value]
class AttributeSelector extends SimpleSelector {
int _op;
var _value;
AttributeSelector(Identifier name, this._op, this._value,
SourceSpan span) : super(name, span);
String matchOperator() {
switch (_op) {
case TokenKind.EQUALS:
return '=';
case TokenKind.INCLUDES:
return '~=';
case TokenKind.DASH_MATCH:
return '|=';
case TokenKind.PREFIX_MATCH:
return '^=';
case TokenKind.SUFFIX_MATCH:
return '\$=';
case TokenKind.SUBSTRING_MATCH:
return '*=';
}
}
// Return the TokenKind for operator used by visitAttributeSelector.
String matchOperatorAsTokenString() {
switch (_op) {
case TokenKind.EQUALS:
return 'EQUALS';
case TokenKind.INCLUDES:
return 'INCLUDES';
case TokenKind.DASH_MATCH:
return 'DASH_MATCH';
case TokenKind.PREFIX_MATCH:
return 'PREFIX_MATCH';
case TokenKind.SUFFIX_MATCH:
return 'SUFFIX_MATCH';
case TokenKind.SUBSTRING_MATCH:
return 'SUBSTRING_MATCH';
}
}
String valueToString() {
if (_value is Identifier) {
return _value.name;
} else {
return '"${_value}"';
}
}
visit(TreeVisitor visitor) => visitor.visitAttributeSelector(this);
String toString() => "[${name} ${matchOperator()} ${valueToString()}]";
}
// #id
class IdSelector extends SimpleSelector {
IdSelector(Identifier name, SourceSpan span) : super(name, span);
visit(TreeVisitor visitor) => visitor.visitIdSelector(this);
String toString() => "#$name";
}
// .class
class ClassSelector extends SimpleSelector {
ClassSelector(Identifier name, SourceSpan span) : super(name, span);
visit(TreeVisitor visitor) => visitor.visitClassSelector(this);
String toString() => ".$name";
}
// :pseudoClass
class PseudoClassSelector extends SimpleSelector {
PseudoClassSelector(Identifier name, SourceSpan span) :
super(name, span);
visit(TreeVisitor visitor) => visitor.visitPseudoClassSelector(this);
String toString() => ":$name";
}
// ::pseudoElement
class PseudoElementSelector extends SimpleSelector {
PseudoElementSelector(Identifier name, SourceSpan span) :
super(name, span);
visit(TreeVisitor visitor) => visitor.visitPseudoElementSelector(this);
String toString() => "::$name";
}
// TODO(terry): Implement
// NOT
class NotSelector extends SimpleSelector {
NotSelector(String name, SourceSpan span) : super(name, span);
visit(TreeVisitor visitor) => visitor.visitNotSelector(this);
}
class Stylesheet extends ASTNode {
// Contains charset, ruleset, directives (media, page, etc.)
List<ASTNode> _topLevels;
Stylesheet(this._topLevels, SourceSpan span) : super(span) {
for (final node in _topLevels) {
assert(node is TopLevelProduction || node is Directive);
}
}
visit(TreeVisitor visitor) => visitor.visitStylesheet(this);
List<ASTNode> get topLevels() => _topLevels;
String toString() {
StringBuffer buff = new StringBuffer();
for (final topLevel in _topLevels) {
buff.add(topLevel.toString());
}
return buff.toString();
}
/** A multiline string showing the node and its children. */
String toDebugString() {
var to = new TreeOutput();
var tp = new TreePrinter(to);
this.visit(tp);
return to.buf.toString();
}
}
class TopLevelProduction extends ASTNode {
TopLevelProduction(SourceSpan span) : super(span);
visit(TreeVisitor visitor) => visitor.visitTopLevelProduction(this);
String toString() => "TopLevelProduction";
}
class RuleSet extends TopLevelProduction {
SelectorGroup _selectorGroup;
DeclarationGroup _declarationGroup;
RuleSet(this._selectorGroup, this._declarationGroup, SourceSpan span) :
super(span);
SelectorGroup get selectorGroup() => _selectorGroup;
DeclarationGroup get declarationGroup() => _declarationGroup;
visit(TreeVisitor visitor) => visitor.visitRuleSet(this);
String toString() =>
"\n${_selectorGroup.toString()} {\n" +
"${_declarationGroup.toString()}}\n";
}
class Directive extends ASTNode {
Directive(SourceSpan span) : super(span);
String toString() => "Directive";
bool get isBuiltIn() => true; // Known CSS directive?
bool get isExtension() => false; // SCSS extension?
visit(TreeVisitor visitor) => visitor.visitDirective(this);
}
class ImportDirective extends Directive {
String _import;
List<String> _media;
ImportDirective(this._import, this._media, SourceSpan span) :
super(span);
visit(TreeVisitor visitor) => visitor.visitImportDirective(this);
String toString() {
StringBuffer buff = new StringBuffer();
buff.add('@import url(${_import})');
int idx = 0;
for (final medium in _media) {
buff.add(idx++ == 0 ? ' $medium' : ',$medium');
}
buff.add('\n');
return buff.toString();
}
}
class MediaDirective extends Directive {
List<String> _media;
RuleSet _ruleset;
MediaDirective(this._media, this._ruleset, SourceSpan span) :
super(span);
visit(TreeVisitor visitor) => visitor.visitMediaDirective(this);
String toString() {
StringBuffer buff = new StringBuffer();
buff.add('@media');
int idx = 0;
for (var medium in _media) {
buff.add(idx++ == 0 ? ' $medium' : ',$medium');
}
buff.add(' {\n');
buff.add(_ruleset.toString());
buff.add('\n\}\n');
return buff.toString();
}
}
class PageDirective extends Directive {
String _pseudoPage;
DeclarationGroup _decls;
PageDirective(this._pseudoPage, this._decls, SourceSpan span) :
super(span);
visit(TreeVisitor visitor) => visitor.visitPageDirective(this);
// @page : pseudoPage {
// decls
// }
String toString() {
StringBuffer buff = new StringBuffer();
buff.add('@page ');
if (_pseudoPage != null) {
buff.add(': ${_pseudoPage} ');
}
buff.add('{\n${_decls.toString()}\n}\n');
return buff.toString();
}
}
class KeyFrameDirective extends Directive {
var _name;
List<KeyFrameBlock> _blocks;
KeyFrameDirective(this._name, SourceSpan span) :
_blocks = [], super(span);
add(KeyFrameBlock block) {
_blocks.add(block);
}
String get name() => _name;
visit(TreeVisitor visitor) => visitor.visitKeyFrameDirective(this);
String toString() {
StringBuffer buff = new StringBuffer();
buff.add('@-webkit-keyframes ${_name} {\n');
for (final block in _blocks) {
buff.add(block.toString());
}
buff.add('}\n');
return buff.toString();
}
}
class KeyFrameBlock extends Expression {
Expressions _blockSelectors;
DeclarationGroup _declarations;
KeyFrameBlock(this._blockSelectors, this._declarations, SourceSpan span):
super(span);
visit(TreeVisitor visitor) => visitor.visitKeyFrameBlock(this);
String toString() {
StringBuffer buff = new StringBuffer();
buff.add(' ${_blockSelectors.toString()} {\n');
buff.add(_declarations.toString());
buff.add(' }\n');
return buff.toString();
}
}
// TODO(terry): TBD
class FontFaceDirective extends Directive {
List<Declaration> _declarations;
FontFaceDirective(this._declarations, SourceSpan span) : super(span);
visit(TreeVisitor visitor) => visitor.visitFontFaceDirective(this);
String toString() {
return "TO BE DONE";
}
}
class IncludeDirective extends Directive {
String _include;
Stylesheet _stylesheet;
IncludeDirective(this._include, this._stylesheet, SourceSpan span) :
super(span);
visit(TreeVisitor visitor) => visitor.visitIncludeDirective(this);
bool get isBuiltIn() => false;
bool get isExtension() => true;
Stylesheet get styleSheet() => _stylesheet;
String toString() {
StringBuffer buff = new StringBuffer();
buff.add('/****** @include ${_include} ******/\n');
buff.add(_stylesheet != null ? _stylesheet.toString() : '// <EMPTY>');
buff.add('/****** End of ${_include} ******/\n\n');
return buff.toString();
}
}
class StyletDirective extends Directive {
String _dartClassName;
List<RuleSet> _rulesets;
StyletDirective(this._dartClassName, this._rulesets, SourceSpan span) :
super(span);
bool get isBuiltIn() => false;
bool get isExtension() => true;
String get dartClassName() => _dartClassName;
List<RuleSet> get rulesets() => _rulesets;
visit(TreeVisitor visitor) => visitor.visitStyletDirective(this);
// TODO(terry): Output Dart class
String toString() => '/* @stylet export as ${_dartClassName} */\n';
}
class Declaration extends ASTNode {
Identifier _property;
Expression _expression;
bool _important;
Declaration(this._property, this._expression, SourceSpan span) :
_important = false, super(span);
String get property() => _property.name;
Expression get expression() => _expression;
bool get important() => _important;
set important(bool value) => _important = value;
String importantAsString() => _important ? ' !important' : '';
visit(TreeVisitor visitor) => visitor.visitDeclaration(this);
String toString() =>
"${_property.name}: ${_expression.toString()}${importantAsString()}";
}
class DeclarationGroup extends ASTNode {
List<Declaration> _declarations;
DeclarationGroup(this._declarations, SourceSpan span) : super(span);
List<Declaration> get declarations() => _declarations;
visit(TreeVisitor visitor) => visitor.visitDeclarationGroup(this);
String toString() {
StringBuffer buff = new StringBuffer();
int idx = 0;
for (final declaration in _declarations) {
buff.add(" ${declaration.toString()};\n");
}
return buff.toString();
}
}
class OperatorSlash extends Expression {
OperatorSlash(SourceSpan span) : super(span);
visit(TreeVisitor visitor) => visitor.visitOperatorSlash(this);
String toString() => ' /';
}
class OperatorComma extends Expression {
OperatorComma(SourceSpan span) : super(span);
visit(TreeVisitor visitor) => visitor.visitOperatorComma(this);
String toString() => ',';
}
class LiteralTerm extends Expression {
var _value;
String _text;
LiteralTerm(this._value, this._text, SourceSpan span) : super(span);
get value() => _value;
String get text() => _text;
visit(TreeVisitor visitor) => visitor.visitLiteralTerm(this);
String toString() => _text;
}
class NumberTerm extends LiteralTerm {
NumberTerm(var value, String t, SourceSpan span) : super(value, t, span);
visit(TreeVisitor visitor) => visitor.visitNumberTerm(this);
}
class UnitTerm extends LiteralTerm {
int _unit;
UnitTerm(var value, String t, SourceSpan span, this._unit) :
super(value, t, span);
int get unit() => _unit;
visit(TreeVisitor visitor) => visitor.visitUnitTerm(this);
String toString() => '${text}${unitToString()}';
String unitToString() => TokenKind.unitToString(_unit);
}
class LengthTerm extends UnitTerm {
LengthTerm(var value, String t, SourceSpan span,
[int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
assert(this._unit == TokenKind.UNIT_LENGTH_PX ||
this._unit == TokenKind.UNIT_LENGTH_CM ||
this._unit == TokenKind.UNIT_LENGTH_MM ||
this._unit == TokenKind.UNIT_LENGTH_IN ||
this._unit == TokenKind.UNIT_LENGTH_PT ||
this._unit == TokenKind.UNIT_LENGTH_PC);
}
visit(TreeVisitor visitor) => visitor.visitLengthTerm(this);
}
class PercentageTerm extends LiteralTerm {
PercentageTerm(var value, String t, SourceSpan span) :
super(value, t, span);
visit(TreeVisitor visitor) => visitor.visitPercentageTerm(this);
String toString() => '${text}%';
}
class EmTerm extends LiteralTerm {
EmTerm(var value, String t, SourceSpan span) :
super(value, t, span);
visit(TreeVisitor visitor) => visitor.visitEmTerm(this);
String toString() => '${text}em';
}
class ExTerm extends LiteralTerm {
ExTerm(var value, String t, SourceSpan span) :
super(value, t, span);
visit(TreeVisitor visitor) => visitor.visitExTerm(this);
String toString() => '${text}ex';
}
class AngleTerm extends UnitTerm {
AngleTerm(var value, String t, SourceSpan span,
[int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
assert(this._unit == TokenKind.UNIT_ANGLE_DEG ||
this._unit == TokenKind.UNIT_ANGLE_RAD ||
this._unit == TokenKind.UNIT_ANGLE_GRAD);
}
visit(TreeVisitor visitor) => visitor.visitAngleTerm(this);
}
class TimeTerm extends UnitTerm {
TimeTerm(var value, String t, SourceSpan span,
[int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
assert(this._unit == TokenKind.UNIT_ANGLE_DEG ||
this._unit == TokenKind.UNIT_TIME_MS ||
this._unit == TokenKind.UNIT_TIME_S);
}
visit(TreeVisitor visitor) => visitor.visitTimeTerm(this);
}
class FreqTerm extends UnitTerm {
FreqTerm(var value, String t, SourceSpan span,
[int unit = TokenKind.UNIT_LENGTH_PX]) : super(value, t, span, unit) {
assert(_unit == TokenKind.UNIT_FREQ_HZ || _unit == TokenKind.UNIT_FREQ_KHZ);
}
visit(TreeVisitor visitor) => visitor.visitFreqTerm(this);
}
class FractionTerm extends LiteralTerm {
FractionTerm(var value, String t, SourceSpan span) :
super(value, t, span);
visit(TreeVisitor visitor) => visitor.visitFractionTerm(this);
String toString() => '${text}fr';
}
class UriTerm extends LiteralTerm {
UriTerm(String value, SourceSpan span) : super(value, value, span);
visit(TreeVisitor visitor) => visitor.visitUriTerm(this);
String toString() => 'url(${text})';
}
class HexColorTerm extends LiteralTerm {
HexColorTerm(var value, String t, SourceSpan span) :
super(value, t, span);
visit(TreeVisitor visitor) => visitor.visitHexColorTerm(this);
String toString() => '#${text}';
}
class FunctionTerm extends LiteralTerm {
Expressions _params;
FunctionTerm(var value, String t, this._params, SourceSpan span)
: super(value, t, span);
visit(TreeVisitor visitor) => visitor.visitFunctionTerm(this);
String toString() {
// TODO(terry): Optimize rgb to a hexcolor.
StringBuffer buff = new StringBuffer();
buff.add('${text}(');
buff.add(_params.toString());
buff.add(')');
return buff.toString();
}
}
class GroupTerm extends Expression {
List<LiteralTerm> _terms;
GroupTerm(SourceSpan span) : _terms = [], super(span);
add(LiteralTerm term) {
_terms.add(term);
}
visit(TreeVisitor visitor) => visitor.visitGroupTerm(this);
String toString() {
StringBuffer buff = new StringBuffer();
buff.add('(');
int idx = 0;
for (final term in _terms) {
if (idx++ > 0) {
buff.add(' ');
}
buff.add(term.toString());
}
buff.add(')');
return buff.toString();
}
}
class ItemTerm extends NumberTerm {
ItemTerm(var value, String t, SourceSpan span) : super(value, t, span);
visit(TreeVisitor visitor) => visitor.visitItemTerm(this);
String toString() => '[${text}]';
}
class Expressions extends Expression {
List<Expression> _expressions;
Expressions(SourceSpan span): super(span), _expressions = [];
add(Expression expression) {
_expressions.add(expression);
}
List<Expression> get expressions() => _expressions;
visit(TreeVisitor visitor) => visitor.visitExpressions(this);
String toString() {
StringBuffer buff = new StringBuffer();
int idx = 0;
for (final expression in _expressions) {
// Add space seperator between terms without an operator.
// TODO(terry): Should have a BinaryExpression to solve this problem.
if (idx > 0 &&
!(expression is OperatorComma || expression is OperatorSlash)) {
buff.add(' ');
}
buff.add(expression.toString());
idx++;
}
return buff.toString();
}
}
class BinaryExpression extends Expression {
Token op;
Expression x;
Expression y;
BinaryExpression(this.op, this.x, this.y, SourceSpan span): super(span);
visit(TreeVisitor visitor) => visitor.visitBinaryExpression(this);
}
class UnaryExpression extends Expression {
Token op;
Expression self;
UnaryExpression(this.op, this.self, SourceSpan span): super(span);
visit(TreeVisitor visitor) => visitor.visitUnaryExpression(this);
}
interface TreeVisitor {
void visitCssComment(CssComment node);
void visitCommentDefinition(CommentDefinition node);
void visitStylesheet(Stylesheet node);
void visitTopLevelProduction(TopLevelProduction node);
void visitDirective(Directive node);
void visitMediaDirective(MediaDirective node);
void visitPageDirective(PageDirective node);
void visitImportDirective(ImportDirective node);
void visitKeyFrameDirective(KeyFrameDirective node);
void visitKeyFrameBlock(KeyFrameBlock node);
void visitFontFaceDirective(FontFaceDirective node);
void visitIncludeDirective(IncludeDirective node);
void visitStyletDirective(StyletDirective node);
void visitRuleSet(RuleSet node);
void visitDeclarationGroup(DeclarationGroup node);
void visitDeclaration(Declaration node);
void visitSelectorGroup(SelectorGroup node);
void visitSelector(Selector node);
void visitSimpleSelectorSequence(SimpleSelectorSequence node);
void visitSimpleSelector(SimpleSelector node);
void visitElementSelector(ElementSelector node);
void visitNamespaceSelector(NamespaceSelector node);
void visitAttributeSelector(AttributeSelector node);
void visitIdSelector(IdSelector node);
void visitClassSelector(ClassSelector node);
void visitPseudoClassSelector(PseudoClassSelector node);
void visitPseudoElementSelector(PseudoElementSelector node);
void visitNotSelector(NotSelector node);
void visitLiteralTerm(LiteralTerm node);
void visitHexColorTerm(HexColorTerm node);
void visitNumberTerm(NumberTerm node);
void visitUnitTerm(UnitTerm node);
void visitLengthTerm(LengthTerm node);
void visitPercentageTerm(PercentageTerm node);
void visitEmTerm(EmTerm node);
void visitExTerm(ExTerm node);
void visitAngleTerm(AngleTerm node);
void visitTimeTerm(TimeTerm node);
void visitFreqTerm(FreqTerm node);
void visitFractionTerm(FractionTerm node);
void visitUriTerm(UriTerm node);
void visitFunctionTerm(FunctionTerm node);
void visitGroupTerm(GroupTerm node);
void visitItemTerm(ItemTerm node);
void visitOperatorSlash(OperatorSlash node);
void visitOperatorComma(OperatorComma node);
void visitExpressions(Expressions node);
void visitBinaryExpression(BinaryExpression node);
void visitUnaryExpression(UnaryExpression node);
void visitIdentifier(Identifier node);
void visitWildcard(Wildcard node);
// TODO(terry): Defined for ../tree.dart.
void visitTypeReference(TypeReference node);
}
class TreePrinter implements TreeVisitor {
var output;
TreePrinter(this.output) { output.printer = this; }
void visitStylesheet(Stylesheet node) {
output.heading('Stylesheet', node.span);
output.depth++;
output.writeNodeList('productions', node._topLevels);
output.depth--;
}
void visitTopLevelProduction(TopLevelProduction node) {
output.heading('TopLevelProduction', node.span);
}
void visitDirective(Directive node) {
output.heading('Directive', node.span);
}
void visitCssComment(CssComment node) {
output.heading('Comment', node.span);
output.depth++;
output.writeValue('comment value', node.comment);
output.depth--;
}
void visitCommentDefinition(CommentDefinition node) {
output.heading('CommentDefinition (CDO/CDC)', node.span);
output.depth++;
output.writeValue('comment value', node.comment);
output.depth--;
}
void visitMediaDirective(MediaDirective node) {
output.heading('MediaDirective', node.span);
output.depth++;
output.writeNodeList('media', node._media);
visitRuleSet(node._ruleset);
output.depth--;
}
void visitPageDirective(PageDirective node) {
output.heading('PageDirective', node.span);
output.depth++;
output.writeValue('pseudo page', node._pseudoPage);
visitDeclarationGroup(node._decls);
output.depth;
}
void visitImportDirective(ImportDirective node) {
output.heading('ImportDirective', node.span);
output.depth++;
output.writeValue('import', node._import);
output.writeNodeList('media', node._media);
output.depth--;
}
void visitKeyFrameDirective(KeyFrameDirective node) {
output.heading('KeyFrameDirective', node.span);
output.depth++;
output.writeValue('name', node._name);
output.writeNodeList('blocks', node._blocks);
output.depth--;
}
void visitKeyFrameBlock(KeyFrameBlock node) {
output.heading('KeyFrameBlock', node.span);
output.depth++;
visitExpressions(node._blockSelectors);
visitDeclarationGroup(node._declarations);
output.depth--;
}
void visitFontFaceDirective(FontFaceDirective node) {
// TODO(terry): To Be Implemented
}
void visitIncludeDirective(IncludeDirective node) {
output.heading('IncludeDirective', node.span);
output.writeValue('include', node._include);
output.depth++;
if (node._stylesheet != null) {
visitStylesheet(node._stylesheet);
} else {
output.writeValue('StyleSheet', '<EMPTY>');
}
output.depth--;
}
void visitStyletDirective(StyletDirective node) {
output.heading('StyletDirective', node.span);
output.writeValue('dartClassName', node._dartClassName);
output.depth++;
output.writeNodeList('rulesets', node._rulesets);
output.depth--;
}
void visitRuleSet(RuleSet node) {
output.heading('Ruleset', node.span);
output.depth++;
visitSelectorGroup(node._selectorGroup);
visitDeclarationGroup(node._declarationGroup);
output.depth--;
}
void visitDeclarationGroup(DeclarationGroup node) {
output.heading('DeclarationGroup', node.span);
output.depth++;
output.writeNodeList('declarations', node._declarations);
output.depth--;
}
void visitDeclaration(Declaration node) {
output.heading('Declaration', node.span);
output.depth++;
output.write('property');
visitIdentifier(node._property);
output.writeNode('expression', node._expression);
if (node.important) {
output.writeValue('!important', 'true');
}
output.depth--;
}
void visitSelectorGroup(SelectorGroup node) {
output.heading('Selector Group', node.span);
output.depth++;
output.writeNodeList('selectors', node.selectors);
output.depth--;
}
void visitSelector(Selector node) {
output.heading('Selector', node.span);
output.depth++;
output.writeNodeList('simpleSelectorsSequences',
node._simpleSelectorSequences);
output.depth--;
}
void visitSimpleSelectorSequence(SimpleSelectorSequence node) {
output.heading('SimpleSelectorSequence', node.span);
output.depth++;
if (node.isCombinatorNone()) {
output.writeValue('combinator', "NONE");
} else if (node.isCombinatorDescendant()) {
output.writeValue('combinator', "descendant");
} else if (node.isCombinatorPlus()) {
output.writeValue('combinator', "+");
} else if (node.isCombinatorGreater()) {
output.writeValue('combinator', ">");
} else if (node.isCombinatorTilde()) {
output.writeValue('combinator', "~");
} else {
output.writeValue('combinator', "ERROR UNKNOWN");
}
var selector = node._selector;
if (selector is NamespaceSelector) {
visitNamespaceSelector(selector);
} else if (selector is ElementSelector) {
visitElementSelector(selector);
} else if (selector is IdSelector) {
visitIdSelector(selector);
} else if (selector is ClassSelector) {
visitClassSelector(selector);
} else if (selector is PseudoClassSelector) {
visitPseudoClassSelector(selector);
} else if (selector is PseudoElementSelector) {
visitPseudoElementSelector(selector);
} else if (selector is NotSelector) {
visitNotSelector(selector);
} else if (selector is AttributeSelector) {
visitAttributeSelector(selector);
} else {
output.heading('SimpleSelector', selector.span);
output.depth++;
visitSimpleSelector(selector);
output.depth--;
}
output.depth--;
}
void visitSimpleSelector(SimpleSelector node) {
visitIdentifier(node._name);
}
void visitNamespaceSelector(NamespaceSelector node) {
output.heading('Namespace Selector', node.span);
output.depth++;
var namespace = node._namespace;
if (namespace is Identifier) {
visitIdentifier(namespace);
} else if (namespace is Wildcard) {
visitWildcard(namespace);
} else {
output.writeln("NULL");
}
visitSimpleSelector(node.nameAsSimpleSelector);
output.depth--;
}
void visitElementSelector(ElementSelector node) {
output.heading('Element Selector', node.span);
output.depth++;
visitSimpleSelector(node);
output.depth--;
}
void visitAttributeSelector(AttributeSelector node) {
output.heading('AttributeSelector', node.span);
output.depth++;
visitSimpleSelector(node);
String tokenStr = node.matchOperatorAsTokenString();
output.writeValue('operator', '${node.matchOperator()} (${tokenStr})');
output.writeValue('value', node.valueToString());
output.depth--;
}
void visitIdSelector(IdSelector node) {
output.heading('Id Selector', node.span);
output.depth++;
visitSimpleSelector(node);
output.depth--;
}
void visitClassSelector(ClassSelector node) {
output.heading('Class Selector', node.span);
output.depth++;
visitSimpleSelector(node);
output.depth--;
}
void visitPseudoClassSelector(PseudoClassSelector node) {
output.heading('Pseudo Class Selector', node.span);
output.depth++;
visitSimpleSelector(node);
output.depth--;
}
void visitPseudoElementSelector(PseudoElementSelector node) {
output.heading('Pseudo Element Selector', node.span);
output.depth++;
visitSimpleSelector(node);
output.depth--;
}
void visitNotSelector(NotSelector node) {
visitSimpleSelector(node);
output.depth++;
output.heading('Not Selector', node.span);
output.depth--;
}
void visitLiteralTerm(LiteralTerm node) {
output.heading('LiteralTerm', node.span);
output.depth++;
output.writeValue('value', node.text);
output.depth--;
}
void visitHexColorTerm(HexColorTerm node) {
output.heading('HexColorTerm', node.span);
output.depth++;
output.writeValue('hex value', node.text);
output.writeValue('decimal value', node.value);
output.depth--;
}
void visitNumberTerm(NumberTerm node) {
output.heading('NumberTerm', node.span);
output.depth++;
output.writeValue('value', node.text);
output.depth--;
}
void visitUnitTerm(UnitTerm node) {
String unitValue;
output.depth++;
output.writeValue('value', node.text);
output.writeValue('unit', node.unitToString());
output.depth--;
}
void visitLengthTerm(LengthTerm node) {
output.heading('LengthTerm', node.span);
visitUnitTerm(node);
}
void visitPercentageTerm(PercentageTerm node) {
output.heading('PercentageTerm', node.span);
output.depth++;
visitLiteralTerm(node);
output.depth--;
}
void visitEmTerm(EmTerm node) {
output.heading('EmTerm', node.span);
output.depth++;
visitLiteralTerm(node);
output.depth--;
}
void visitExTerm(ExTerm node) {
output.heading('ExTerm', node.span);
output.depth++;
visitLiteralTerm(node);
output.depth--;
}
void visitAngleTerm(AngleTerm node) {
output.heading('AngleTerm', node.span);
visitUnitTerm(node);
}
void visitTimeTerm(TimeTerm node) {
output.heading('TimeTerm', node.span);
visitUnitTerm(node);
}
void visitFreqTerm(FreqTerm node) {
output.heading('FreqTerm', node.span);
visitUnitTerm(node);
}
void visitFractionTerm(FractionTerm node) {
output.heading('FractionTerm', node.span);
output.depth++;
visitLiteralTerm(node);
output.depth--;
}
void visitUriTerm(UriTerm node) {
output.heading('UriTerm', node.span);
output.depth++;
visitLiteralTerm(node);
output.depth--;
}
void visitFunctionTerm(FunctionTerm node) {
output.heading('FunctionTerm', node.span);
output.depth++;
visitLiteralTerm(node);
visitExpressions(node._params);
output.depth--;
}
void visitGroupTerm(GroupTerm node) {
output.heading('GroupTerm', node.span);
output.depth++;
output.writeNodeList('grouped terms', node._terms);
output.depth--;
}
void visitItemTerm(ItemTerm node) {
output.heading('ItemTerm', node.span);
visitNumberTerm(node);
}
void visitOperatorSlash(OperatorSlash node) {
output.heading('OperatorSlash', node.span);
}
void visitOperatorComma(OperatorComma node) {
output.heading('OperatorComma', node.span);
}
void visitExpressions(Expressions node) {
output.heading('Expressions', node.span);
output.depth++;
output.writeNodeList('expressions', node._expressions);
output.depth--;
}
void visitBinaryExpression(BinaryExpression node) {
output.heading('BinaryExpression', node.span);
// TODO(terry): TBD
}
void visitUnaryExpression(UnaryExpression node) {
output.heading('UnaryExpression', node.span);
// TODO(terry): TBD
}
void visitIdentifier(Identifier node) {
output.heading('Identifier(' + output.toValue(node.name) + ")", node.span);
}
void visitWildcard(Wildcard node) {
output.heading('Wildcard(*)', node.span);
}
// TODO(terry): Defined for frog/tree.dart.
void visitTypeReference(TypeReference node) {
output.heading('Unimplemented');
}
}