OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 part of csslib.visitor; |
| 6 |
| 7 // TODO(terry): Enable class for debug only; when conditional imports enabled. |
| 8 |
| 9 /** Helper function to dump the CSS AST. */ |
| 10 String treeToDebugString(StyleSheet styleSheet, [bool useSpan = false]) { |
| 11 var to = new TreeOutput(); |
| 12 new _TreePrinter(to, useSpan)..visitTree(styleSheet); |
| 13 return to.toString(); |
| 14 } |
| 15 |
| 16 /** Tree dump for debug output of the CSS AST. */ |
| 17 class _TreePrinter extends Visitor { |
| 18 final TreeOutput output; |
| 19 final bool useSpan; |
| 20 _TreePrinter(this.output, this.useSpan) { |
| 21 output.printer = this; |
| 22 } |
| 23 |
| 24 void visitTree(StyleSheet tree) => visitStylesheet(tree); |
| 25 |
| 26 void heading(String heading, node) { |
| 27 if (useSpan) { |
| 28 output.heading(heading, node.span); |
| 29 } else { |
| 30 output.heading(heading); |
| 31 } |
| 32 } |
| 33 |
| 34 void visitStylesheet(StyleSheet node) { |
| 35 heading('Stylesheet', node); |
| 36 output.depth++; |
| 37 super.visitStyleSheet(node); |
| 38 output.depth--; |
| 39 } |
| 40 |
| 41 void visitTopLevelProduction(TopLevelProduction node) { |
| 42 heading('TopLevelProduction', node); |
| 43 } |
| 44 |
| 45 void visitDirective(Directive node) { |
| 46 heading('Directive', node); |
| 47 } |
| 48 |
| 49 void visitCssComment(CssComment node) { |
| 50 heading('Comment', node); |
| 51 output.depth++; |
| 52 output.writeValue('comment value', node.comment); |
| 53 output.depth--; |
| 54 } |
| 55 |
| 56 void visitCommentDefinition(CommentDefinition node) { |
| 57 heading('CommentDefinition (CDO/CDC)', node); |
| 58 output.depth++; |
| 59 output.writeValue('comment value', node.comment); |
| 60 output.depth--; |
| 61 } |
| 62 |
| 63 void visitMediaExpression(MediaExpression node) { |
| 64 heading('MediaExpression', node); |
| 65 output.writeValue('feature', node.mediaFeature); |
| 66 if (node.andOperator) output.writeValue('AND operator', ''); |
| 67 visitExpressions(node.exprs); |
| 68 } |
| 69 |
| 70 void visitMediaQueries(MediaQuery query) { |
| 71 output.heading('MediaQueries'); |
| 72 output.writeValue('unary', query.unary); |
| 73 output.writeValue('media type', query.mediaType); |
| 74 output.writeNodeList('media expressions', query.expressions); |
| 75 } |
| 76 |
| 77 void visitMediaDirective(MediaDirective node) { |
| 78 heading('MediaDirective', node); |
| 79 output.depth++; |
| 80 output.writeNodeList('media queries', node.mediaQueries); |
| 81 output.writeNodeList('rule sets', node.rulesets); |
| 82 super.visitMediaDirective(node); |
| 83 output.depth--; |
| 84 } |
| 85 |
| 86 void visitPageDirective(PageDirective node) { |
| 87 heading('PageDirective', node); |
| 88 output.depth++; |
| 89 output.writeValue('pseudo page', node._pseudoPage); |
| 90 super.visitPageDirective(node); |
| 91 output.depth; |
| 92 } |
| 93 |
| 94 void visitCharsetDirective(CharsetDirective node) { |
| 95 heading('Charset Directive', node); |
| 96 output.writeValue('charset encoding', node.charEncoding); |
| 97 } |
| 98 |
| 99 void visitImportDirective(ImportDirective node) { |
| 100 heading('ImportDirective', node); |
| 101 output.depth++; |
| 102 output.writeValue('import', node.import); |
| 103 super.visitImportDirective(node); |
| 104 output.writeNodeList('media', node.mediaQueries); |
| 105 output.depth--; |
| 106 } |
| 107 |
| 108 void visitContentDirective(ContentDirective node) { |
| 109 print("ContentDirective not implemented"); |
| 110 } |
| 111 |
| 112 void visitKeyFrameDirective(KeyFrameDirective node) { |
| 113 heading('KeyFrameDirective', node); |
| 114 output.depth++; |
| 115 output.writeValue('keyframe', node.keyFrameName); |
| 116 output.writeValue('name', node.name); |
| 117 output.writeNodeList('blocks', node._blocks); |
| 118 output.depth--; |
| 119 } |
| 120 |
| 121 void visitKeyFrameBlock(KeyFrameBlock node) { |
| 122 heading('KeyFrameBlock', node); |
| 123 output.depth++; |
| 124 super.visitKeyFrameBlock(node); |
| 125 output.depth--; |
| 126 } |
| 127 |
| 128 void visitFontFaceDirective(FontFaceDirective node) { |
| 129 // TODO(terry): To Be Implemented |
| 130 } |
| 131 |
| 132 void visitStyletDirective(StyletDirective node) { |
| 133 heading('StyletDirective', node); |
| 134 output.writeValue('dartClassName', node.dartClassName); |
| 135 output.depth++; |
| 136 output.writeNodeList('rulesets', node.rulesets); |
| 137 output.depth--; |
| 138 } |
| 139 |
| 140 void visitNamespaceDirective(NamespaceDirective node) { |
| 141 heading('NamespaceDirective', node); |
| 142 output.depth++; |
| 143 output.writeValue('prefix', node._prefix); |
| 144 output.writeValue('uri', node._uri); |
| 145 output.depth--; |
| 146 } |
| 147 |
| 148 void visitVarDefinitionDirective(VarDefinitionDirective node) { |
| 149 heading('Less variable definition', node); |
| 150 output.depth++; |
| 151 visitVarDefinition(node.def); |
| 152 output.depth--; |
| 153 } |
| 154 |
| 155 void visitMixinRulesetDirective(MixinRulesetDirective node) { |
| 156 heading('Mixin top-level ${node.name}', node); |
| 157 output.writeNodeList('parameters', node.definedArgs); |
| 158 output.depth++; |
| 159 _visitNodeList(node.rulesets); |
| 160 output.depth--; |
| 161 } |
| 162 |
| 163 void visitMixinDeclarationDirective(MixinDeclarationDirective node) { |
| 164 heading('Mixin declaration ${node.name}', node); |
| 165 output.writeNodeList('parameters', node.definedArgs); |
| 166 output.depth++; |
| 167 visitDeclarationGroup(node.declarations); |
| 168 output.depth--; |
| 169 } |
| 170 |
| 171 /** |
| 172 * Added optional newLine for handling @include at top-level vs/ inside of |
| 173 * a declaration group. |
| 174 */ |
| 175 void visitIncludeDirective(IncludeDirective node) { |
| 176 heading('IncludeDirective ${node.name}', node); |
| 177 var flattened = node.args.expand((e) => e).toList(); |
| 178 output.writeNodeList('parameters', flattened); |
| 179 } |
| 180 |
| 181 void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) { |
| 182 heading('IncludeMixinAtDeclaration ${node.include.name}', node); |
| 183 output.depth++; |
| 184 visitIncludeDirective(node.include); |
| 185 output.depth--; |
| 186 } |
| 187 |
| 188 void visitExtendDeclaration(ExtendDeclaration node) { |
| 189 heading('ExtendDeclaration', node); |
| 190 output.depth++; |
| 191 _visitNodeList(node.selectors); |
| 192 output.depth--; |
| 193 } |
| 194 |
| 195 void visitRuleSet(RuleSet node) { |
| 196 heading('Ruleset', node); |
| 197 output.depth++; |
| 198 super.visitRuleSet(node); |
| 199 output.depth--; |
| 200 } |
| 201 |
| 202 void visitDeclarationGroup(DeclarationGroup node) { |
| 203 heading('DeclarationGroup', node); |
| 204 output.depth++; |
| 205 output.writeNodeList('declarations', node.declarations); |
| 206 output.depth--; |
| 207 } |
| 208 |
| 209 void visitMarginGroup(MarginGroup node) { |
| 210 heading('MarginGroup', node); |
| 211 output.depth++; |
| 212 output.writeValue('@directive', node.margin_sym); |
| 213 output.writeNodeList('declarations', node.declarations); |
| 214 output.depth--; |
| 215 } |
| 216 |
| 217 void visitDeclaration(Declaration node) { |
| 218 heading('Declaration', node); |
| 219 output.depth++; |
| 220 if (node.isIE7) output.write('IE7 property'); |
| 221 output.write('property'); |
| 222 super.visitDeclaration(node); |
| 223 output.writeNode('expression', node._expression); |
| 224 if (node.important) { |
| 225 output.writeValue('!important', 'true'); |
| 226 } |
| 227 output.depth--; |
| 228 } |
| 229 |
| 230 void visitVarDefinition(VarDefinition node) { |
| 231 heading('Var', node); |
| 232 output.depth++; |
| 233 output.write('defintion'); |
| 234 super.visitVarDefinition(node); |
| 235 output.writeNode('expression', node._expression); |
| 236 output.depth--; |
| 237 } |
| 238 |
| 239 void visitSelectorGroup(SelectorGroup node) { |
| 240 heading('Selector Group', node); |
| 241 output.depth++; |
| 242 output.writeNodeList('selectors', node.selectors); |
| 243 output.depth--; |
| 244 } |
| 245 |
| 246 void visitSelector(Selector node) { |
| 247 heading('Selector', node); |
| 248 output.depth++; |
| 249 output.writeNodeList( |
| 250 'simpleSelectorsSequences', node.simpleSelectorSequences); |
| 251 output.depth--; |
| 252 } |
| 253 |
| 254 void visitSimpleSelectorSequence(SimpleSelectorSequence node) { |
| 255 heading('SimpleSelectorSequence', node); |
| 256 output.depth++; |
| 257 if (node.isCombinatorNone) { |
| 258 output.writeValue('combinator', "NONE"); |
| 259 } else if (node.isCombinatorDescendant) { |
| 260 output.writeValue('combinator', "descendant"); |
| 261 } else if (node.isCombinatorPlus) { |
| 262 output.writeValue('combinator', "+"); |
| 263 } else if (node.isCombinatorGreater) { |
| 264 output.writeValue('combinator', ">"); |
| 265 } else if (node.isCombinatorTilde) { |
| 266 output.writeValue('combinator', "~"); |
| 267 } else { |
| 268 output.writeValue('combinator', "ERROR UNKNOWN"); |
| 269 } |
| 270 |
| 271 super.visitSimpleSelectorSequence(node); |
| 272 |
| 273 output.depth--; |
| 274 } |
| 275 |
| 276 void visitNamespaceSelector(NamespaceSelector node) { |
| 277 heading('Namespace Selector', node); |
| 278 output.depth++; |
| 279 |
| 280 super.visitNamespaceSelector(node); |
| 281 |
| 282 visitSimpleSelector(node.nameAsSimpleSelector); |
| 283 output.depth--; |
| 284 } |
| 285 |
| 286 void visitElementSelector(ElementSelector node) { |
| 287 heading('Element Selector', node); |
| 288 output.depth++; |
| 289 super.visitElementSelector(node); |
| 290 output.depth--; |
| 291 } |
| 292 |
| 293 void visitAttributeSelector(AttributeSelector node) { |
| 294 heading('AttributeSelector', node); |
| 295 output.depth++; |
| 296 super.visitAttributeSelector(node); |
| 297 String tokenStr = node.matchOperatorAsTokenString(); |
| 298 output.writeValue('operator', '${node.matchOperator()} (${tokenStr})'); |
| 299 output.writeValue('value', node.valueToString()); |
| 300 output.depth--; |
| 301 } |
| 302 |
| 303 void visitIdSelector(IdSelector node) { |
| 304 heading('Id Selector', node); |
| 305 output.depth++; |
| 306 super.visitIdSelector(node); |
| 307 output.depth--; |
| 308 } |
| 309 |
| 310 void visitClassSelector(ClassSelector node) { |
| 311 heading('Class Selector', node); |
| 312 output.depth++; |
| 313 super.visitClassSelector(node); |
| 314 output.depth--; |
| 315 } |
| 316 |
| 317 void visitPseudoClassSelector(PseudoClassSelector node) { |
| 318 heading('Pseudo Class Selector', node); |
| 319 output.depth++; |
| 320 super.visitPseudoClassSelector(node); |
| 321 output.depth--; |
| 322 } |
| 323 |
| 324 void visitPseudoElementSelector(PseudoElementSelector node) { |
| 325 heading('Pseudo Element Selector', node); |
| 326 output.depth++; |
| 327 super.visitPseudoElementSelector(node); |
| 328 output.depth--; |
| 329 } |
| 330 |
| 331 void visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) { |
| 332 heading('Pseudo Class Function Selector', node); |
| 333 output.depth++; |
| 334 visitSelectorExpression(node.expression); |
| 335 super.visitPseudoClassFunctionSelector(node); |
| 336 output.depth--; |
| 337 } |
| 338 |
| 339 void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) { |
| 340 heading('Pseudo Element Function Selector', node); |
| 341 output.depth++; |
| 342 visitSelectorExpression(node.expression); |
| 343 super.visitPseudoElementFunctionSelector(node); |
| 344 output.depth--; |
| 345 } |
| 346 |
| 347 void visitSelectorExpression(SelectorExpression node) { |
| 348 heading('Selector Expression', node); |
| 349 output.depth++; |
| 350 output.writeNodeList('expressions', node.expressions); |
| 351 output.depth--; |
| 352 } |
| 353 |
| 354 void visitNegationSelector(NegationSelector node) { |
| 355 super.visitNegationSelector(node); |
| 356 output.depth++; |
| 357 heading('Negation Selector', node); |
| 358 output.writeNode('Negation arg', node.negationArg); |
| 359 output.depth--; |
| 360 } |
| 361 |
| 362 void visitUnicodeRangeTerm(UnicodeRangeTerm node) { |
| 363 heading('UnicodeRangeTerm', node); |
| 364 output.depth++; |
| 365 output.writeValue('1st value', node.first); |
| 366 output.writeValue('2nd value', node.second); |
| 367 output.depth--; |
| 368 } |
| 369 |
| 370 void visitLiteralTerm(LiteralTerm node) { |
| 371 heading('LiteralTerm', node); |
| 372 output.depth++; |
| 373 output.writeValue('value', node.text); |
| 374 output.depth--; |
| 375 } |
| 376 |
| 377 void visitHexColorTerm(HexColorTerm node) { |
| 378 heading('HexColorTerm', node); |
| 379 output.depth++; |
| 380 output.writeValue('hex value', node.text); |
| 381 output.writeValue('decimal value', node.value); |
| 382 output.depth--; |
| 383 } |
| 384 |
| 385 void visitNumberTerm(NumberTerm node) { |
| 386 heading('NumberTerm', node); |
| 387 output.depth++; |
| 388 output.writeValue('value', node.text); |
| 389 output.depth--; |
| 390 } |
| 391 |
| 392 void visitUnitTerm(UnitTerm node) { |
| 393 output.depth++; |
| 394 output.writeValue('value', node.text); |
| 395 output.writeValue('unit', node.unitToString()); |
| 396 output.depth--; |
| 397 } |
| 398 |
| 399 void visitLengthTerm(LengthTerm node) { |
| 400 heading('LengthTerm', node); |
| 401 super.visitLengthTerm(node); |
| 402 } |
| 403 |
| 404 void visitPercentageTerm(PercentageTerm node) { |
| 405 heading('PercentageTerm', node); |
| 406 output.depth++; |
| 407 super.visitPercentageTerm(node); |
| 408 output.depth--; |
| 409 } |
| 410 |
| 411 void visitEmTerm(EmTerm node) { |
| 412 heading('EmTerm', node); |
| 413 output.depth++; |
| 414 super.visitEmTerm(node); |
| 415 output.depth--; |
| 416 } |
| 417 |
| 418 void visitExTerm(ExTerm node) { |
| 419 heading('ExTerm', node); |
| 420 output.depth++; |
| 421 super.visitExTerm(node); |
| 422 output.depth--; |
| 423 } |
| 424 |
| 425 void visitAngleTerm(AngleTerm node) { |
| 426 heading('AngleTerm', node); |
| 427 super.visitAngleTerm(node); |
| 428 } |
| 429 |
| 430 void visitTimeTerm(TimeTerm node) { |
| 431 heading('TimeTerm', node); |
| 432 super.visitTimeTerm(node); |
| 433 } |
| 434 |
| 435 void visitFreqTerm(FreqTerm node) { |
| 436 heading('FreqTerm', node); |
| 437 super.visitFreqTerm(node); |
| 438 } |
| 439 |
| 440 void visitFractionTerm(FractionTerm node) { |
| 441 heading('FractionTerm', node); |
| 442 output.depth++; |
| 443 super.visitFractionTerm(node); |
| 444 output.depth--; |
| 445 } |
| 446 |
| 447 void visitUriTerm(UriTerm node) { |
| 448 heading('UriTerm', node); |
| 449 output.depth++; |
| 450 super.visitUriTerm(node); |
| 451 output.depth--; |
| 452 } |
| 453 |
| 454 void visitFunctionTerm(FunctionTerm node) { |
| 455 heading('FunctionTerm', node); |
| 456 output.depth++; |
| 457 super.visitFunctionTerm(node); |
| 458 output.depth--; |
| 459 } |
| 460 |
| 461 void visitGroupTerm(GroupTerm node) { |
| 462 heading('GroupTerm', node); |
| 463 output.depth++; |
| 464 output.writeNodeList('grouped terms', node._terms); |
| 465 output.depth--; |
| 466 } |
| 467 |
| 468 void visitItemTerm(ItemTerm node) { |
| 469 heading('ItemTerm', node); |
| 470 super.visitItemTerm(node); |
| 471 } |
| 472 |
| 473 void visitIE8Term(IE8Term node) { |
| 474 heading('IE8Term', node); |
| 475 visitLiteralTerm(node); |
| 476 } |
| 477 |
| 478 void visitOperatorSlash(OperatorSlash node) { |
| 479 heading('OperatorSlash', node); |
| 480 } |
| 481 |
| 482 void visitOperatorComma(OperatorComma node) { |
| 483 heading('OperatorComma', node); |
| 484 } |
| 485 |
| 486 void visitOperatorPlus(OperatorPlus node) { |
| 487 heading('OperatorPlus', node); |
| 488 } |
| 489 |
| 490 void visitOperatorMinus(OperatorMinus node) { |
| 491 heading('OperatorMinus', node); |
| 492 } |
| 493 |
| 494 void visitVarUsage(VarUsage node) { |
| 495 heading('Var', node); |
| 496 output.depth++; |
| 497 output.write('usage ${node.name}'); |
| 498 output.writeNodeList('default values', node.defaultValues); |
| 499 output.depth--; |
| 500 } |
| 501 |
| 502 void visitExpressions(Expressions node) { |
| 503 heading('Expressions', node); |
| 504 output.depth++; |
| 505 output.writeNodeList('expressions', node.expressions); |
| 506 output.depth--; |
| 507 } |
| 508 |
| 509 void visitBinaryExpression(BinaryExpression node) { |
| 510 heading('BinaryExpression', node); |
| 511 // TODO(terry): TBD |
| 512 } |
| 513 |
| 514 void visitUnaryExpression(UnaryExpression node) { |
| 515 heading('UnaryExpression', node); |
| 516 // TODO(terry): TBD |
| 517 } |
| 518 |
| 519 void visitIdentifier(Identifier node) { |
| 520 heading('Identifier(${output.toValue(node.name)})', node); |
| 521 } |
| 522 |
| 523 void visitWildcard(Wildcard node) { |
| 524 heading('Wildcard(*)', node); |
| 525 } |
| 526 |
| 527 void visitDartStyleExpression(DartStyleExpression node) { |
| 528 heading('DartStyleExpression', node); |
| 529 } |
| 530 |
| 531 void visitFontExpression(FontExpression node) { |
| 532 heading('Dart Style FontExpression', node); |
| 533 } |
| 534 |
| 535 void visitBoxExpression(BoxExpression node) { |
| 536 heading('Dart Style BoxExpression', node); |
| 537 } |
| 538 |
| 539 void visitMarginExpression(MarginExpression node) { |
| 540 heading('Dart Style MarginExpression', node); |
| 541 } |
| 542 |
| 543 void visitBorderExpression(BorderExpression node) { |
| 544 heading('Dart Style BorderExpression', node); |
| 545 } |
| 546 |
| 547 void visitHeightExpression(HeightExpression node) { |
| 548 heading('Dart Style HeightExpression', node); |
| 549 } |
| 550 |
| 551 void visitPaddingExpression(PaddingExpression node) { |
| 552 heading('Dart Style PaddingExpression', node); |
| 553 } |
| 554 |
| 555 void visitWidthExpression(WidthExpression node) { |
| 556 heading('Dart Style WidthExpression', node); |
| 557 } |
| 558 } |
OLD | NEW |