1 | | // Copyright (c) 2015, 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 | | library dart_style.src.rule.combinator;
|
6 | |
|
7 | | import '../chunk.dart';
|
8 | | import 'rule.dart';
|
9 | |
|
10 | | /// Handles a list of "combinators".
|
11 | | ///
|
12 | | /// A combinator is a keyword followed by a list of nodes used to modify some
|
13 | | /// declaration. It's used for actual hide and show combinators as well as
|
14 | | /// "with" and "implements" clauses in class declarations.
|
15 | | ///
|
16 | | /// Combinators can be split in a few different ways:
|
17 | | ///
|
18 | | /// // All on one line:
|
19 | | /// import 'animals.dart' show Ant hide Cat;
|
20 | | ///
|
21 | | /// // Wrap before each keyword:
|
22 | | /// import 'animals.dart'
|
23 | | /// show Ant, Baboon
|
24 | | /// hide Cat;
|
25 | | ///
|
26 | | /// // Wrap either or both of the name lists:
|
27 | | /// import 'animals.dart'
|
28 | | /// show
|
29 | | /// Ant,
|
30 | | /// Baboon
|
31 | | /// hide Cat;
|
32 | | ///
|
33 | | /// These are not allowed:
|
34 | | ///
|
35 | | /// // Wrap list but not keyword:
|
36 | | /// import 'animals.dart' show
|
37 | | /// Ant,
|
38 | | /// Baboon
|
39 | | /// hide Cat;
|
40 | | ///
|
41 | | /// // Wrap one keyword but not both:
|
42 | | /// import 'animals.dart'
|
43 | | /// show Ant, Baboon hide Cat;
|
44 | | ///
|
45 | | /// This ensures that when any wrapping occurs, the keywords are always at
|
46 | | /// the beginning of the line.
|
47 | | class CombinatorRule extends Rule {
|
48 | | /// The set of chunks before the combinators.
|
49 | | final Set<Chunk> _combinators = new Set();
|
50 | |
|
51 | | /// A list of sets of chunks prior to each name in a combinator.
|
52 | | ///
|
53 | | /// The outer list is a list of combinators (i.e. "hide", "show", etc.). Each
|
54 | | /// inner set is the set of names for that combinator.
|
55 | | final List<Set<Chunk>> _names = [];
|
56 | |
|
57 | 1 | int get numValues {
|
58 | | var count = 2; // No wrapping, or wrap just before each combinator.
|
59 | |
|
60 | 3 | if (_names.length == 2) {
|
61 | 1 | count += 3; // Wrap first set of names, second, or both.
|
62 | | } else {
|
63 | 3 | assert(_names.length == 1);
|
64 | 1 | count++; // Wrap the names.
|
65 | | }
|
66 | |
|
67 | | return count;
|
68 | | }
|
69 | |
|
70 | | /// Adds a new combinator to the list of combinators.
|
71 | | ///
|
72 | | /// This must be called before adding any names.
|
73 | 1 | void addCombinator(Chunk chunk) {
|
74 | 2 | _combinators.add(chunk);
|
75 | 3 | _names.add(new Set());
|
76 | | }
|
77 | |
|
78 | | /// Adds a chunk prior to a name to the current combinator.
|
79 | 1 | void addName(Chunk chunk) {
|
80 | 3 | _names.last.add(chunk);
|
81 | | }
|
82 | |
|
83 | 1 | bool isSplitAtValue(int value, Chunk chunk) {
|
84 | | switch (value) {
|
85 | 1 | case 1:
|
86 | | // Just split at the combinators.
|
87 | 2 | return _combinators.contains(chunk);
|
88 | |
|
89 | 1 | case 2:
|
90 | | // Split at the combinators and the first set of names.
|
91 | 1 | return _isCombinatorSplit(0, chunk);
|
92 | |
|
93 | 1 | case 3:
|
94 | | // If there is two combinators, just split at the combinators and the
|
95 | | // second set of names.
|
96 | 3 | if (_names.length == 2) {
|
97 | | // Two sets of combinators, so just split at the combinators and the
|
98 | | // second set of names.
|
99 | 1 | return _isCombinatorSplit(1, chunk);
|
100 | | }
|
101 | |
|
102 | | // Split everything.
|
103 | | return true;
|
104 | |
|
105 | | default:
|
106 | | return true;
|
107 | | }
|
108 | | }
|
109 | |
|
110 | | /// Returns `true` if [chunk] is for a combinator or a name in the
|
111 | | /// combinator at index [combinator].
|
112 | 1 | bool _isCombinatorSplit(int combinator, Chunk chunk) {
|
113 | 5 | return _combinators.contains(chunk) || _names[combinator].contains(chunk);
|
114 | | }
|
115 | |
|
116 | 0 | String toString() => "Comb${super.toString()}";
|
117 | | }
|