@@ -32,44 +32,51 @@ Future<void> main(List<String> args) async {
32
32
}
33
33
var corpus = args[0 ] == '--corpus' ;
34
34
var rootPath = corpus ? args[1 ] : args[0 ];
35
- await CompletionCoverageMetrics (rootPath).compute (corpus: corpus);
36
- io.exit (0 );
35
+ var code = await CompletionCoverageMetrics (rootPath).compute (corpus: corpus);
36
+ io.exit (code );
37
37
}
38
38
39
39
/// This is the main metrics computer class for code completions. After the
40
40
/// object is constructed, [computeCompletionMetrics] is executed to do analysis
41
41
/// and print a summary of the metrics gathered from the completion tests.
42
- abstract class AbstractCompletionMetricsComputer {
43
- // TODO(brianwilkerson) Consider merging this class into the single concrete
44
- // subclass.
42
+ class CompletionCoverageMetrics {
45
43
final String _rootPath;
46
44
47
45
String _currentFilePath;
48
46
49
47
ResolvedUnitResult _resolvedUnitResult;
50
48
51
- AbstractCompletionMetricsComputer (this ._rootPath);
49
+ /// The int to be returned from the [compute] call.
50
+ int resultCode;
51
+
52
+ int includedCount = 0 ;
53
+ int notIncludedCount = 0 ;
54
+
55
+ var completionMissedTokenCounter = Counter ('missing completion counter' );
56
+ var completionKindCounter = Counter ('completion kind counter' );
57
+ var completionElementKindCounter = Counter ('completion element kind counter' );
58
+ var mRRComputer = MeanReciprocalRankComputer ();
59
+
60
+ CompletionCoverageMetrics (this ._rootPath);
52
61
53
62
/// The path to the current file.
54
63
String get currentFilePath => _currentFilePath;
55
64
56
65
/// If the concrete class has this getter return true, then when
57
66
/// [forEachExpectedCompletion] is called, the [List] of
58
67
/// [CompletionSuggestion] s will be passed.
59
- bool get doComputeCompletionsFromAnalysisServer;
60
-
61
- /// The current [ResolvedUnitResult] .
62
- ResolvedUnitResult get resolvedUnitResult => _resolvedUnitResult;
68
+ bool get doComputeCompletionsFromAnalysisServer => true ;
63
69
64
70
/// The analysis root path that this CompletionMetrics class will be computed.
65
71
String get rootPath => _rootPath;
66
72
67
- void compute ({bool corpus = false }) async {
73
+ Future <int > compute ({bool corpus = false }) async {
74
+ resultCode = 0 ;
68
75
print ('Analyzing root: \" $_rootPath \" ' );
69
76
70
77
if (! io.Directory (_rootPath).existsSync ()) {
71
78
print ('\t Error: No such directory exists on this machine.\n ' );
72
- return ;
79
+ return 1 ;
73
80
}
74
81
75
82
var roots = _computeRootPaths (_rootPath, corpus);
@@ -85,10 +92,8 @@ abstract class AbstractCompletionMetricsComputer {
85
92
var declarationsTracker = DeclarationsTracker (
86
93
MemoryByteStore (), PhysicalResourceProvider .INSTANCE );
87
94
declarationsTracker.addContext (context);
88
- if (doComputeCompletionsFromAnalysisServer) {
89
- while (declarationsTracker.hasWork) {
90
- declarationsTracker.doWork ();
91
- }
95
+ while (declarationsTracker.hasWork) {
96
+ declarationsTracker.doWork ();
92
97
}
93
98
94
99
// Loop through each file, resolve the file and call
@@ -100,51 +105,102 @@ abstract class AbstractCompletionMetricsComputer {
100
105
_resolvedUnitResult =
101
106
await context.currentSession.getResolvedUnit (filePath);
102
107
103
- var error = getFirstErrorOrNull (resolvedUnitResult );
104
- if (error != null ) {
108
+ var analysisError = getFirstErrorOrNull (_resolvedUnitResult );
109
+ if (analysisError != null ) {
105
110
print ('File $filePath skipped due to errors such as:' );
106
- print (' ${error .toString ()}' );
111
+ print (' ${analysisError .toString ()}' );
107
112
print ('' );
113
+ resultCode = 1 ;
108
114
continue ;
109
115
}
110
116
111
117
// Use the ExpectedCompletionsVisitor to compute the set of expected
112
118
// completions for this CompilationUnit.
113
119
final visitor = ExpectedCompletionsVisitor ();
114
- resolvedUnitResult .unit.accept (visitor);
120
+ _resolvedUnitResult .unit.accept (visitor);
115
121
116
122
for (var expectedCompletion in visitor.expectedCompletions) {
117
- // Call forEachExpectedCompletion, passing in the computed
118
- // suggestions only if doComputeCompletionsFromAnalysisServer is
119
- // true:
120
123
forEachExpectedCompletion (
121
124
expectedCompletion,
122
125
doComputeCompletionsFromAnalysisServer
123
126
? await _computeCompletionSuggestions (
124
- resolvedUnitResult ,
127
+ _resolvedUnitResult ,
125
128
expectedCompletion.offset,
126
129
declarationsTracker)
127
130
: null );
128
131
}
129
132
} catch (e) {
130
133
print ('Exception caught analyzing: $filePath ' );
131
134
print (e.toString ());
135
+ resultCode = 1 ;
132
136
}
133
137
}
134
138
}
135
139
}
136
140
}
137
141
printAndClearComputers ();
142
+ return resultCode;
138
143
}
139
144
140
- /// Overridden by each subclass, this method gathers some set of data from
141
- /// each [ExpectedCompletion] , and each [CompletionSuggestion] list (if
142
- /// [doComputeCompletionsFromAnalysisServer] is set to true.)
143
145
void forEachExpectedCompletion (ExpectedCompletion expectedCompletion,
144
- List <CompletionSuggestion > suggestions);
146
+ List <CompletionSuggestion > suggestions) {
147
+ assert (suggestions != null );
145
148
146
- /// This method is called to print a summary of the data collected.
147
- void printAndClearComputers ();
149
+ var place = placementInSuggestionList (suggestions, expectedCompletion);
150
+
151
+ mRRComputer.addRank (place.rank);
152
+
153
+ if (place.denominator != 0 ) {
154
+ includedCount++ ;
155
+ } else {
156
+ notIncludedCount++ ;
157
+
158
+ completionMissedTokenCounter.count (expectedCompletion.completion);
159
+ completionKindCounter.count (expectedCompletion.kind.toString ());
160
+ completionElementKindCounter
161
+ .count (expectedCompletion.elementKind.toString ());
162
+
163
+ // The format "/file/path/foo.dart:3:4" makes for easier input
164
+ // with the Files dialog in IntelliJ
165
+ print (
166
+ '$currentFilePath :${expectedCompletion .lineNumber }:${expectedCompletion .columnNumber }' );
167
+ print (
168
+ '\t did not include the expected completion: \" ${expectedCompletion .completion }\" , completion kind: ${expectedCompletion .kind .toString ()}, element kind: ${expectedCompletion .elementKind .toString ()}' );
169
+ print ('' );
170
+ }
171
+ }
172
+
173
+ void printAndClearComputers () {
174
+ final totalCompletionCount = includedCount + notIncludedCount;
175
+ final percentIncluded = includedCount / totalCompletionCount;
176
+ final percentNotIncluded = 1 - percentIncluded;
177
+
178
+ completionMissedTokenCounter.printCounterValues ();
179
+ print ('' );
180
+
181
+ completionKindCounter.printCounterValues ();
182
+ print ('' );
183
+
184
+ completionElementKindCounter.printCounterValues ();
185
+ print ('' );
186
+
187
+ mRRComputer.printMean ();
188
+ print ('' );
189
+
190
+ print ('Summary for $_rootPath :' );
191
+ print ('Total number of completion tests = $totalCompletionCount ' );
192
+ print (
193
+ 'Number of successful completions = $includedCount (${printPercentage (percentIncluded )})' );
194
+ print (
195
+ 'Number of unsuccessful completions = $notIncludedCount (${printPercentage (percentNotIncluded )})' );
196
+
197
+ includedCount = 0 ;
198
+ notIncludedCount = 0 ;
199
+ completionMissedTokenCounter.clear ();
200
+ completionKindCounter.clear ();
201
+ completionElementKindCounter.clear ();
202
+ mRRComputer.clear ();
203
+ }
148
204
149
205
Future <List <CompletionSuggestion >> _computeCompletionSuggestions (
150
206
ResolvedUnitResult resolvedUnitResult, int offset,
@@ -225,80 +281,3 @@ abstract class AbstractCompletionMetricsComputer {
225
281
return Place .none ();
226
282
}
227
283
}
228
-
229
- class CompletionCoverageMetrics extends AbstractCompletionMetricsComputer {
230
- int includedCount = 0 ;
231
- int notIncludedCount = 0 ;
232
- var completionMissedTokenCounter = Counter ('missing completion counter' );
233
- var completionKindCounter = Counter ('completion kind counter' );
234
- var completionElementKindCounter = Counter ('completion element kind counter' );
235
- var mRRComputer = MeanReciprocalRankComputer ();
236
-
237
- CompletionCoverageMetrics (String rootPath) : super (rootPath);
238
-
239
- @override
240
- bool get doComputeCompletionsFromAnalysisServer => true ;
241
-
242
- @override
243
- void forEachExpectedCompletion (ExpectedCompletion expectedCompletion,
244
- List <CompletionSuggestion > suggestions) {
245
- assert (suggestions != null );
246
-
247
- var place = AbstractCompletionMetricsComputer .placementInSuggestionList (
248
- suggestions, expectedCompletion);
249
-
250
- mRRComputer.addRank (place.rank);
251
-
252
- if (place.denominator != 0 ) {
253
- includedCount++ ;
254
- } else {
255
- notIncludedCount++ ;
256
-
257
- completionMissedTokenCounter.count (expectedCompletion.completion);
258
- completionKindCounter.count (expectedCompletion.kind.toString ());
259
- completionElementKindCounter
260
- .count (expectedCompletion.elementKind.toString ());
261
-
262
- // The format "/file/path/foo.dart:3:4" makes for easier input
263
- // with the Files dialog in IntelliJ
264
- print (
265
- '$currentFilePath :${expectedCompletion .lineNumber }:${expectedCompletion .columnNumber }' );
266
- print (
267
- '\t did not include the expected completion: \" ${expectedCompletion .completion }\" , completion kind: ${expectedCompletion .kind .toString ()}, element kind: ${expectedCompletion .elementKind .toString ()}' );
268
- print ('' );
269
- }
270
- }
271
-
272
- @override
273
- void printAndClearComputers () {
274
- final totalCompletionCount = includedCount + notIncludedCount;
275
- final percentIncluded = includedCount / totalCompletionCount;
276
- final percentNotIncluded = 1 - percentIncluded;
277
-
278
- completionMissedTokenCounter.printCounterValues ();
279
- print ('' );
280
-
281
- completionKindCounter.printCounterValues ();
282
- print ('' );
283
-
284
- completionElementKindCounter.printCounterValues ();
285
- print ('' );
286
-
287
- mRRComputer.printMean ();
288
- print ('' );
289
-
290
- print ('Summary for $_rootPath :' );
291
- print ('Total number of completion tests = $totalCompletionCount ' );
292
- print (
293
- 'Number of successful completions = $includedCount (${printPercentage (percentIncluded )})' );
294
- print (
295
- 'Number of unsuccessful completions = $notIncludedCount (${printPercentage (percentNotIncluded )})' );
296
-
297
- includedCount = 0 ;
298
- notIncludedCount = 0 ;
299
- completionMissedTokenCounter.clear ();
300
- completionKindCounter.clear ();
301
- completionElementKindCounter.clear ();
302
- mRRComputer.clear ();
303
- }
304
- }
0 commit comments