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) { output.printer = this; } | |
21 | |
22 void visitTree(StyleSheet tree) => visitStylesheet(tree); | |
23 | |
24 void heading(String heading, node) { | |
25 if (useSpan) { | |
26 output.heading(heading, node.span); | |
27 } else { | |
28 output.heading(heading); | |
29 } | |
30 } | |
31 | |
32 void visitStylesheet(StyleSheet node) { | |
33 heading('Stylesheet', node); | |
34 output.depth++; | |
35 super.visitStyleSheet(node); | |
36 output.depth--; | |
37 } | |
38 | |
39 void visitTopLevelProduction(TopLevelProduction node) { | |
40 heading('TopLevelProduction', node); | |
41 } | |
42 | |
43 void visitDirective(Directive node) { | |
44 heading('Directive', node); | |
45 } | |
46 | |
47 void visitCssComment(CssComment node) { | |
48 heading('Comment', node); | |
49 output.depth++; | |
50 output.writeValue('comment value', node.comment); | |
51 output.depth--; | |
52 } | |
53 | |
54 void visitCommentDefinition(CommentDefinition node) { | |
55 heading('CommentDefinition (CDO/CDC)', node); | |
56 output.depth++; | |
57 output.writeValue('comment value', node.comment); | |
58 output.depth--; | |
59 } | |
60 | |
61 void visitMediaExpression(MediaExpression node) { | |
62 heading('MediaExpression', node); | |
63 output.writeValue('feature', node.mediaFeature); | |
64 if (node.andOperator) output.writeValue('AND operator', ''); | |
65 visitExpressions(node.exprs); | |
66 } | |
67 | |
68 void visitMediaQueries(MediaQuery query) { | |
69 output.heading('MediaQueries'); | |
70 output.writeValue('unary', query.unary); | |
71 output.writeValue('media type', query.mediaType); | |
72 output.writeNodeList('media expressions', query.expressions); | |
73 } | |
74 | |
75 void visitMediaDirective(MediaDirective node) { | |
76 heading('MediaDirective', node); | |
77 output.depth++; | |
78 output.writeNodeList('media queries', node.mediaQueries); | |
79 output.writeNodeList('rule sets', node.rulesets); | |
80 super.visitMediaDirective(node); | |
81 output.depth--; | |
82 } | |
83 | |
84 void visitPageDirective(PageDirective node) { | |
85 heading('PageDirective', node); | |
86 output.depth++; | |
87 output.writeValue('pseudo page', node._pseudoPage); | |
88 super.visitPageDirective(node); | |
89 output.depth; | |
90 } | |
91 | |
92 void visitCharsetDirective(CharsetDirective node) { | |
93 heading('Charset Directive', node); | |
94 output.writeValue('charset encoding', node.charEncoding); | |
95 } | |
96 | |
97 void visitImportDirective(ImportDirective node) { | |
98 heading('ImportDirective', node); | |
99 output.depth++; | |
100 output.writeValue('import', node.import); | |
101 super.visitImportDirective(node); | |
102 output.writeNodeList('media', node.mediaQueries); | |
103 output.depth--; | |
104 } | |
105 | |
106 void visitContentDirective(ContentDirective node) { | |
107 print("ContentDirective not implemented"); | |
108 } | |
109 | |
110 void visitKeyFrameDirective(KeyFrameDirective node) { | |
111 heading('KeyFrameDirective', node); | |
112 output.depth++; | |
113 output.writeValue('keyframe', node.keyFrameName); | |
114 output.writeValue('name', node.name); | |
115 output.writeNodeList('blocks', node._blocks); | |
116 output.depth--; | |
117 } | |
118 | |
119 void visitKeyFrameBlock(KeyFrameBlock node) { | |
120 heading('KeyFrameBlock', node); | |
121 output.depth++; | |
122 super.visitKeyFrameBlock(node); | |
123 output.depth--; | |
124 } | |
125 | |
126 void visitFontFaceDirective(FontFaceDirective node) { | |
127 // TODO(terry): To Be Implemented | |
128 } | |
129 | |
130 void visitStyletDirective(StyletDirective node) { | |
131 heading('StyletDirective', node); | |
132 output.writeValue('dartClassName', node.dartClassName); | |
133 output.depth++; | |
134 output.writeNodeList('rulesets', node.rulesets); | |
135 output.depth--; | |
136 } | |
137 | |
138 void visitNamespaceDirective(NamespaceDirective node) { | |
139 heading('NamespaceDirective', node); | |
140 output.depth++; | |
141 output.writeValue('prefix', node._prefix); | |
142 output.writeValue('uri', node._uri); | |
143 output.depth--; | |
144 } | |
145 | |
146 void visitVarDefinitionDirective(VarDefinitionDirective node) { | |
147 heading('Less variable definition', node); | |
148 output.depth++; | |
149 visitVarDefinition(node.def); | |
150 output.depth--; | |
151 } | |
152 | |
153 void visitMixinRulesetDirective(MixinRulesetDirective node) { | |
154 heading('Mixin top-level ${node.name}', node); | |
155 output.writeNodeList('parameters', node.definedArgs); | |
156 output.depth++; | |
157 _visitNodeList(node.rulesets); | |
158 output.depth--; | |
159 } | |
160 | |
161 void visitMixinDeclarationDirective(MixinDeclarationDirective node) { | |
162 heading('Mixin declaration ${node.name}', node); | |
163 output.writeNodeList('parameters', node.definedArgs); | |
164 output.depth++; | |
165 visitDeclarationGroup(node.declarations); | |
166 output.depth--; | |
167 } | |
168 | |
169 /** | |
170 * Added optional newLine for handling @include at top-level vs/ inside of | |
171 * a declaration group. | |
172 */ | |
173 void visitIncludeDirective(IncludeDirective node) { | |
174 heading('IncludeDirective ${node.name}', node); | |
175 var flattened = node.args.expand((e) => e).toList(); | |
176 output.writeNodeList('parameters', flattened); | |
177 } | |
178 | |
179 void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) { | |
180 heading('IncludeMixinAtDeclaration ${node.include.name}', node); | |
181 output.depth++; | |
182 visitIncludeDirective(node.include); | |
183 output.depth--; | |
184 } | |
185 | |
186 void visitExtendDeclaration(ExtendDeclaration node) { | |
187 heading('ExtendDeclaration', node); | |
188 output.depth++; | |
189 _visitNodeList(node.selectors); | |
190 output.depth--; | |
191 } | |
192 | |
193 void visitRuleSet(RuleSet node) { | |
194 heading('Ruleset', node); | |
195 output.depth++; | |
196 super.visitRuleSet(node); | |
197 output.depth--; | |
198 } | |
199 | |
200 void visitDeclarationGroup(DeclarationGroup node) { | |
201 heading('DeclarationGroup', node); | |
202 output.depth++; | |
203 output.writeNodeList('declarations', node.declarations); | |
204 output.depth--; | |
205 } | |
206 | |
207 void visitMarginGroup(MarginGroup node) { | |
208 heading('MarginGroup', node); | |
209 output.depth++; | |
210 output.writeValue('@directive', node.margin_sym); | |
211 output.writeNodeList('declarations', node.declarations); | |
212 output.depth--; | |
213 } | |
214 | |
215 void visitDeclaration(Declaration node) { | |
216 heading('Declaration', node); | |
217 output.depth++; | |
218 if (node.isIE7) output.write('IE7 property'); | |
219 output.write('property'); | |
220 super.visitDeclaration(node); | |
221 output.writeNode('expression', node._expression); | |
222 if (node.important) { | |
223 output.writeValue('!important', 'true'); | |
224 } | |
225 output.depth--; | |
226 } | |
227 | |
228 void visitVarDefinition(VarDefinition node) { | |
229 heading('Var', node); | |
230 output.depth++; | |
231 output.write('defintion'); | |
232 super.visitVarDefinition(node); | |
233 output.writeNode('expression', node._expression); | |
234 output.depth--; | |
235 } | |
236 | |
237 void visitSelectorGroup(SelectorGroup node) { | |
238 heading('Selector Group', node); | |
239 output.depth++; | |
240 output.writeNodeList('selectors', node.selectors); | |
241 output.depth--; | |
242 } | |
243 | |
244 void visitSelector(Selector node) { | |
245 heading('Selector', node); | |
246 output.depth++; | |
247 output.writeNodeList('simpleSelectorsSequences', | |
248 node.simpleSelectorSequences); | |
249 output.depth--; | |
250 } | |
251 | |
252 void visitSimpleSelectorSequence(SimpleSelectorSequence node) { | |
253 heading('SimpleSelectorSequence', node); | |
254 output.depth++; | |
255 if (node.isCombinatorNone) { | |
256 output.writeValue('combinator', "NONE"); | |
257 } else if (node.isCombinatorDescendant) { | |
258 output.writeValue('combinator', "descendant"); | |
259 } else if (node.isCombinatorPlus) { | |
260 output.writeValue('combinator', "+"); | |
261 } else if (node.isCombinatorGreater) { | |
262 output.writeValue('combinator', ">"); | |
263 } else if (node.isCombinatorTilde) { | |
264 output.writeValue('combinator', "~"); | |
265 } else { | |
266 output.writeValue('combinator', "ERROR UNKNOWN"); | |
267 } | |
268 | |
269 super.visitSimpleSelectorSequence(node); | |
270 | |
271 output.depth--; | |
272 } | |
273 | |
274 void visitNamespaceSelector(NamespaceSelector node) { | |
275 heading('Namespace Selector', node); | |
276 output.depth++; | |
277 | |
278 super.visitNamespaceSelector(node); | |
279 | |
280 visitSimpleSelector(node.nameAsSimpleSelector); | |
281 output.depth--; | |
282 } | |
283 | |
284 void visitElementSelector(ElementSelector node) { | |
285 heading('Element Selector', node); | |
286 output.depth++; | |
287 super.visitElementSelector(node); | |
288 output.depth--; | |
289 } | |
290 | |
291 void visitAttributeSelector(AttributeSelector node) { | |
292 heading('AttributeSelector', node); | |
293 output.depth++; | |
294 super.visitAttributeSelector(node); | |
295 String tokenStr = node.matchOperatorAsTokenString(); | |
296 output.writeValue('operator', '${node.matchOperator()} (${tokenStr})'); | |
297 output.writeValue('value', node.valueToString()); | |
298 output.depth--; | |
299 } | |
300 | |
301 void visitIdSelector(IdSelector node) { | |
302 heading('Id Selector', node); | |
303 output.depth++; | |
304 super.visitIdSelector(node); | |
305 output.depth--; | |
306 } | |
307 | |
308 void visitClassSelector(ClassSelector node) { | |
309 heading('Class Selector', node); | |
310 output.depth++; | |
311 super.visitClassSelector(node); | |
312 output.depth--; | |
313 } | |
314 | |
315 void visitPseudoClassSelector(PseudoClassSelector node) { | |
316 heading('Pseudo Class Selector', node); | |
317 output.depth++; | |
318 super.visitPseudoClassSelector(node); | |
319 output.depth--; | |
320 } | |
321 | |
322 void visitPseudoElementSelector(PseudoElementSelector node) { | |
323 heading('Pseudo Element Selector', node); | |
324 output.depth++; | |
325 super.visitPseudoElementSelector(node); | |
326 output.depth--; | |
327 } | |
328 | |
329 void visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) { | |
330 heading('Pseudo Class Function Selector', node); | |
331 output.depth++; | |
332 visitSelectorExpression(node.expression); | |
333 super.visitPseudoClassFunctionSelector(node); | |
334 output.depth--; | |
335 } | |
336 | |
337 void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) { | |
338 heading('Pseudo Element Function Selector', node); | |
339 output.depth++; | |
340 visitSelectorExpression(node.expression); | |
341 super.visitPseudoElementFunctionSelector(node); | |
342 output.depth--; | |
343 } | |
344 | |
345 void visitSelectorExpression(SelectorExpression node) { | |
346 heading('Selector Expression', node); | |
347 output.depth++; | |
348 output.writeNodeList('expressions', node.expressions); | |
349 output.depth--; | |
350 } | |
351 | |
352 void visitNegationSelector(NegationSelector node) { | |
353 super.visitNegationSelector(node); | |
354 output.depth++; | |
355 heading('Negation Selector', node); | |
356 output.writeNode('Negation arg', node.negationArg); | |
357 output.depth--; | |
358 } | |
359 | |
360 void visitUnicodeRangeTerm(UnicodeRangeTerm node) { | |
361 heading('UnicodeRangeTerm', node); | |
362 output.depth++; | |
363 output.writeValue('1st value', node.first); | |
364 output.writeValue('2nd value', node.second); | |
365 output.depth--; | |
366 } | |
367 | |
368 void visitLiteralTerm(LiteralTerm node) { | |
369 heading('LiteralTerm', node); | |
370 output.depth++; | |
371 output.writeValue('value', node.text); | |
372 output.depth--; | |
373 } | |
374 | |
375 void visitHexColorTerm(HexColorTerm node) { | |
376 heading('HexColorTerm', node); | |
377 output.depth++; | |
378 output.writeValue('hex value', node.text); | |
379 output.writeValue('decimal value', node.value); | |
380 output.depth--; | |
381 } | |
382 | |
383 void visitNumberTerm(NumberTerm node) { | |
384 heading('NumberTerm', node); | |
385 output.depth++; | |
386 output.writeValue('value', node.text); | |
387 output.depth--; | |
388 } | |
389 | |
390 void visitUnitTerm(UnitTerm node) { | |
391 String unitValue; | |
392 | |
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 |