OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of csslib.parser; | 5 part of csslib.parser; |
6 | 6 |
7 | 7 |
8 // TODO(terry): Add optimizing phase to remove duplicated selectors in the same | 8 // TODO(terry): Add optimizing phase to remove duplicated selectors in the same |
9 // selector group (e.g., .btn, .btn { color: red; }). Also, look | 9 // selector group (e.g., .btn, .btn { color: red; }). Also, look |
10 // at simplifying selectors expressions too (much harder). | 10 // at simplifying selectors expressions too (much harder). |
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
566 index++; | 566 index++; |
567 } | 567 } |
568 return -1; | 568 return -1; |
569 } | 569 } |
570 | 570 |
571 /** | 571 /** |
572 * Stamp out a mixin with the defined args substituted with the user's | 572 * Stamp out a mixin with the defined args substituted with the user's |
573 * parameters. | 573 * parameters. |
574 */ | 574 */ |
575 class CallMixin extends Visitor { | 575 class CallMixin extends Visitor { |
576 var mixinDef; | 576 final MixinDefinition mixinDef; |
577 List _definedArgs; | 577 List _definedArgs; |
578 Expressions _currExpressions; | 578 Expressions _currExpressions; |
579 int _currIndex = -1; | 579 int _currIndex = -1; |
580 | 580 |
581 final varUsages = new Map<String, Map<Expressions, Set<int>>>(); | 581 final varUsages = new Map<String, Map<Expressions, Set<int>>>(); |
582 | 582 |
583 /** Only var defs with more than one expression (comma separated). */ | 583 /** Only var defs with more than one expression (comma separated). */ |
584 final Map<String, VarDefinition> varDefs; | 584 final Map<String, VarDefinition> varDefs; |
585 | 585 |
586 CallMixin(this.mixinDef, [this.varDefs]) { | 586 CallMixin(this.mixinDef, [this.varDefs]) { |
587 if (mixinDef is MixinRulesetDirective) { | 587 if (mixinDef is MixinRulesetDirective) { |
588 visitMixinRulesetDirective(mixinDef); | 588 visitMixinRulesetDirective(mixinDef); |
589 } else { | 589 } else { |
590 visitMixinDeclarationDirective(mixinDef); | 590 visitMixinDeclarationDirective(mixinDef); |
591 } | 591 } |
592 } | 592 } |
593 | 593 |
594 /** | 594 /** |
595 * Given a mixin's defined arguments return a cloned mixin defintion that has | 595 * Given a mixin's defined arguments return a cloned mixin defintion that has |
596 * replaced all defined arguments with user's supplied VarUsages. | 596 * replaced all defined arguments with user's supplied VarUsages. |
597 */ | 597 */ |
598 transform(List<TreeNode> callArgs) { | 598 MixinDefinition transform(List<TreeNode> callArgs) { |
599 // TODO(terry): Handle default arguments and varArgs. | 599 // TODO(terry): Handle default arguments and varArgs. |
600 // Transform mixin with callArgs. | 600 // Transform mixin with callArgs. |
601 var index = 0; | 601 var index = 0; |
602 for (var index = 0; index < _definedArgs.length; index++) { | 602 for (var index = 0; index < _definedArgs.length; index++) { |
603 var definedArg = _definedArgs[index]; | 603 var definedArg = _definedArgs[index]; |
604 VarDefinition varDef; | 604 VarDefinition varDef; |
605 if (definedArg is VarDefinition) { | 605 if (definedArg is VarDefinition) { |
606 varDef = definedArg; | 606 varDef = definedArg; |
607 } else if (definedArg is VarDefinitionDirective) { | 607 } else if (definedArg is VarDefinitionDirective) { |
608 VarDefinitionDirective varDirective = definedArg; | 608 VarDefinitionDirective varDirective = definedArg; |
609 varDef = varDirective.def; | 609 varDef = varDirective.def; |
610 } | 610 } |
611 var callArg = callArgs[index]; | 611 var callArg = callArgs[index]; |
612 | 612 |
613 // Is callArg a var definition with multi-args (expressions > 1). | 613 // Is callArg a var definition with multi-args (expressions > 1). |
614 var defArgs = _varDefsAsCallArgs(callArg); | 614 var defArgs = _varDefsAsCallArgs(callArg); |
615 if (defArgs.isNotEmpty) { | 615 if (defArgs.isNotEmpty) { |
616 // Replace call args with the var def parameters. | 616 // Replace call args with the var def parameters. |
617 callArgs.insertAll(index, defArgs); | 617 callArgs.insertAll(index, defArgs); |
618 callArgs.removeAt(index + defArgs.length); | 618 callArgs.removeAt(index + defArgs.length); |
619 callArg = callArgs[index]; | 619 callArg = callArgs[index]; |
620 } | 620 } |
621 | 621 |
622 var expressions = varUsages[varDef.definedName]; | 622 var expressions = varUsages[varDef.definedName]; |
623 var expressionsLength = expressions.length; | |
624 expressions.forEach((k, v) { | 623 expressions.forEach((k, v) { |
625 for (var usagesIndex in v) { | 624 for (var usagesIndex in v) { |
626 k.expressions.replaceRange(usagesIndex, usagesIndex + 1, callArg); | 625 k.expressions.replaceRange(usagesIndex, usagesIndex + 1, callArg); |
627 } | 626 } |
628 }); | 627 }); |
629 } | 628 } |
630 | 629 |
631 // Clone the mixin | 630 // Clone the mixin |
632 return mixinDef.clone(); | 631 return mixinDef.clone(); |
633 } | 632 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 | 716 |
718 DeclarationIncludes(this._messages, List<StyleSheet> styleSheets) { | 717 DeclarationIncludes(this._messages, List<StyleSheet> styleSheets) { |
719 for (var styleSheet in styleSheets) { | 718 for (var styleSheet in styleSheets) { |
720 visitTree(styleSheet); | 719 visitTree(styleSheet); |
721 } | 720 } |
722 } | 721 } |
723 | 722 |
724 bool _allIncludes(rulesets) => | 723 bool _allIncludes(rulesets) => |
725 rulesets.every((rule) => rule is IncludeDirective || rule is NoOp); | 724 rulesets.every((rule) => rule is IncludeDirective || rule is NoOp); |
726 | 725 |
727 CallMixin _createCallDeclMixin(mixinDef) { | 726 CallMixin _createCallDeclMixin(MixinDefinition mixinDef) { |
728 callMap.putIfAbsent(mixinDef.name, () => | 727 callMap.putIfAbsent(mixinDef.name, () => |
729 callMap[mixinDef.name] = new CallMixin(mixinDef, varDefs)); | 728 callMap[mixinDef.name] = new CallMixin(mixinDef, varDefs)); |
730 return callMap[mixinDef.name]; | 729 return callMap[mixinDef.name]; |
731 } | 730 } |
732 | 731 |
733 void visitStyleSheet(StyleSheet ss) { | 732 void visitStyleSheet(StyleSheet ss) { |
734 _styleSheet = ss; | 733 _styleSheet = ss; |
735 super.visitStyleSheet(ss); | 734 super.visitStyleSheet(ss); |
736 _styleSheet = null; | 735 _styleSheet = null; |
737 } | 736 } |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 } | 960 } |
962 } | 961 } |
963 | 962 |
964 // TODO(terry): Need to handle merging selector sequences | 963 // TODO(terry): Need to handle merging selector sequences |
965 // TODO(terry): Need to handle @extend-Only selectors. | 964 // TODO(terry): Need to handle @extend-Only selectors. |
966 // TODO(terry): Need to handle !optional glag. | 965 // TODO(terry): Need to handle !optional glag. |
967 /** | 966 /** |
968 * Changes any selector that matches @extend. | 967 * Changes any selector that matches @extend. |
969 */ | 968 */ |
970 class InheritExtends extends Visitor { | 969 class InheritExtends extends Visitor { |
971 Messages _messages; | 970 final Messages _messages; |
972 AllExtends _allExtends; | 971 final AllExtends _allExtends; |
973 | 972 |
974 InheritExtends(this._messages, this._allExtends); | 973 InheritExtends(this._messages, this._allExtends); |
975 | 974 |
976 void visitSelectorGroup(SelectorGroup node) { | 975 void visitSelectorGroup(SelectorGroup node) { |
977 for (var selectorsIndex = 0; selectorsIndex < node.selectors.length; | 976 for (var selectorsIndex = 0; selectorsIndex < node.selectors.length; |
978 selectorsIndex++) { | 977 selectorsIndex++) { |
979 var selectors = node.selectors[selectorsIndex]; | 978 var selectors = node.selectors[selectorsIndex]; |
980 var isLastNone = false; | 979 var isLastNone = false; |
981 var selectorName = ""; | 980 var selectorName = ""; |
982 for (var index = 0; index < selectors.simpleSelectorSequences.length; | 981 for (var index = 0; index < selectors.simpleSelectorSequences.length; |
(...skipping 26 matching lines...) Expand all Loading... |
1009 isLastNone = false; | 1008 isLastNone = false; |
1010 } | 1009 } |
1011 } else { | 1010 } else { |
1012 isLastNone = simpleSeq.isCombinatorNone; | 1011 isLastNone = simpleSeq.isCombinatorNone; |
1013 } | 1012 } |
1014 } | 1013 } |
1015 } | 1014 } |
1016 super.visitSelectorGroup(node); | 1015 super.visitSelectorGroup(node); |
1017 } | 1016 } |
1018 } | 1017 } |
OLD | NEW |