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 |