blob: 08160e452945a18d07f897879febb5a3f3eb2ea8 [file] [log] [blame]
// 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.write(', ');
}
buff.write(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.write(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.write(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.write('@import url(${_import})');
int idx = 0;
for (final medium in _media) {
buff.write(idx++ == 0 ? ' $medium' : ',$medium');
}
buff.write('\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.write('@media');
int idx = 0;
for (var medium in _media) {
buff.write(idx++ == 0 ? ' $medium' : ',$medium');
}
buff.write(' {\n');
buff.write(_ruleset.toString());
buff.write('\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.write('@page ');
if (_pseudoPage != null) {
buff.write(': ${_pseudoPage} ');
}
buff.write('{\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.write('@-webkit-keyframes ${_name} {\n');
for (final block in _blocks) {
buff.write(block.toString());
}
buff.write('}\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.write(' ${_blockSelectors.toString()} {\n');
buff.write(_declarations.toString());
buff.write(' }\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.write('/****** @include ${_include} ******/\n');
buff.write(_stylesheet != null ? _stylesheet.toString() : '// <EMPTY>');
buff.write('/****** 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.write(" ${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.write('${text}(');
buff.write(_params.toString());
buff.write(')');
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.write('(');
int idx = 0;
for (final term in _terms) {
if (idx++ > 0) {
buff.write(' ');
}
buff.write(term.toString());
}
buff.write(')');
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.write(' ');
}
buff.write(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);
}
abstract class 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');
}
}