| // 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'); |
| } |
| } |