@@ -7,16 +7,15 @@ import 'package:analyzer/dart/ast/ast.dart';
7
7
import 'package:analyzer/dart/ast/visitor.dart' ;
8
8
import 'package:analyzer/src/generated/source.dart' ;
9
9
10
- // TODO(devoncarew): We should look into not creating any labels until there's
11
- // at least 2 levels of nesting.
12
-
13
10
/**
14
11
* A computer for [CompilationUnit] closing labels.
15
12
*/
16
13
class DartUnitClosingLabelsComputer {
17
14
final LineInfo _lineInfo;
18
15
final CompilationUnit _unit;
19
16
final List <ClosingLabel > _closingLabels = [];
17
+ final Set <ClosingLabel > hasNestingSet = new Set ();
18
+ final Set <ClosingLabel > isSingleLineSet = new Set ();
20
19
21
20
DartUnitClosingLabelsComputer (this ._lineInfo, this ._unit);
22
21
@@ -25,7 +24,20 @@ class DartUnitClosingLabelsComputer {
25
24
*/
26
25
List <ClosingLabel > compute () {
27
26
_unit.accept (new _DartUnitClosingLabelsComputerVisitor (this ));
28
- return _closingLabels;
27
+
28
+ return _closingLabels.where ((ClosingLabel label) {
29
+ // Filter labels that don't have some nesting.
30
+ // Filter labels that start and end on the same line.
31
+ return hasNestingSet.contains (label) && ! isSingleLineSet.contains (label);
32
+ }).toList ();
33
+ }
34
+
35
+ void setHasNesting (ClosingLabel label) {
36
+ hasNestingSet.add (label);
37
+ }
38
+
39
+ void setSingleLine (ClosingLabel label) {
40
+ isSingleLineSet.add (label);
29
41
}
30
42
}
31
43
@@ -37,36 +49,53 @@ class _DartUnitClosingLabelsComputerVisitor
37
49
final DartUnitClosingLabelsComputer computer;
38
50
39
51
int interpolatedStringsEntered = 0 ;
52
+ List <ClosingLabel > labelStack = [];
40
53
41
54
_DartUnitClosingLabelsComputerVisitor (this .computer);
42
55
43
56
@override
44
57
Object visitInstanceCreationExpression (InstanceCreationExpression node) {
58
+ ClosingLabel label;
59
+
45
60
if (node.argumentList != null ) {
46
- var label = node.constructorName.type.name.name;
61
+ String labelText = node.constructorName.type.name.name;
47
62
if (node.constructorName.name != null ) {
48
- label += ".${node .constructorName .name .name }" ;
63
+ labelText += ".${node .constructorName .name .name }" ;
49
64
}
50
65
// We override the node used for doing line calculations because otherwise
51
66
// constructors that split over multiple lines (but have parens on same
52
67
// line) would incorrectly get labels, because node.start on an instance
53
68
// creation expression starts at the start of the expression.
54
- _addLabel (node, label , checkLinesUsing: node.argumentList);
69
+ label = _addLabel (node, labelText , checkLinesUsing: node.argumentList);
55
70
}
56
71
57
- return super .visitInstanceCreationExpression (node);
72
+ if (label != null ) _pushLabel (label);
73
+
74
+ try {
75
+ return super .visitInstanceCreationExpression (node);
76
+ } finally {
77
+ if (label != null ) _popLabel ();
78
+ }
58
79
}
59
80
60
81
@override
61
82
Object visitListLiteral (ListLiteral node) {
62
83
final NodeList <TypeAnnotation > args = node.typeArguments? .arguments;
63
84
final String typeName = args != null ? args[0 ]? .toString () : null ;
64
85
86
+ ClosingLabel label;
87
+
65
88
if (typeName != null ) {
66
- _addLabel (node, "<$typeName >[]" );
89
+ label = _addLabel (node, "<$typeName >[]" );
67
90
}
68
91
69
- return super .visitListLiteral (node);
92
+ if (label != null ) _pushLabel (label);
93
+
94
+ try {
95
+ return super .visitListLiteral (node);
96
+ } finally {
97
+ if (label != null ) _popLabel ();
98
+ }
70
99
}
71
100
72
101
@override
@@ -79,10 +108,11 @@ class _DartUnitClosingLabelsComputerVisitor
79
108
}
80
109
}
81
110
82
- void _addLabel (AstNode node, String label, {AstNode checkLinesUsing}) {
111
+ ClosingLabel _addLabel (AstNode node, String label,
112
+ {AstNode checkLinesUsing}) {
83
113
// Never add labels if we're inside strings.
84
114
if (interpolatedStringsEntered > 0 ) {
85
- return ;
115
+ return null ;
86
116
}
87
117
88
118
checkLinesUsing = checkLinesUsing ?? node;
@@ -92,14 +122,32 @@ class _DartUnitClosingLabelsComputerVisitor
92
122
final LineInfo_Location end =
93
123
computer._lineInfo.getLocation (checkLinesUsing.end - 1 );
94
124
125
+ final ClosingLabel closingLabel =
126
+ new ClosingLabel (node.offset, node.length, label);
127
+
95
128
int spannedLines = end.lineNumber - start.lineNumber;
96
129
if (spannedLines < 1 ) {
97
- return ;
130
+ computer. setSingleLine (closingLabel) ;
98
131
}
99
132
100
- final ClosingLabel closingLabel =
101
- new ClosingLabel (node.offset, node.length, label);
133
+ ClosingLabel parent = _currentLabel;
134
+ if (parent != null ) {
135
+ computer.setHasNesting (parent);
136
+ computer.setHasNesting (closingLabel);
137
+ }
102
138
103
139
computer._closingLabels.add (closingLabel);
140
+
141
+ return closingLabel;
142
+ }
143
+
144
+ void _pushLabel (ClosingLabel label) {
145
+ labelStack.add (label);
146
+ }
147
+
148
+ ClosingLabel get _currentLabel => labelStack.isEmpty ? null : labelStack.last;
149
+
150
+ void _popLabel () {
151
+ labelStack.removeLast ();
104
152
}
105
153
}
0 commit comments