@@ -178,11 +178,8 @@ Future<Map<String, dynamic>> _getAllCoverage(
178
178
continue ;
179
179
}
180
180
for (final script in scripts.scripts! ) {
181
- final uri = Uri .parse (script.uri! );
182
- if (uri.scheme != 'package' ) continue ;
183
- final scope = uri.path.split ('/' ).first;
184
181
// Skip scripts which should not be included in the report.
185
- if (! scopedOutput.contains (scope )) continue ;
182
+ if (! scopedOutput.includesScript (script.uri )) continue ;
186
183
late final SourceReport scriptReport;
187
184
try {
188
185
scriptReport = await service.getSourceReport (
@@ -203,7 +200,8 @@ Future<Map<String, dynamic>> _getAllCoverage(
203
200
includeDart,
204
201
functionCoverage,
205
202
reportLines,
206
- coverableLineCache);
203
+ coverableLineCache,
204
+ scopedOutput);
207
205
allCoverage.addAll (coverage);
208
206
}
209
207
} else {
@@ -229,7 +227,8 @@ Future<Map<String, dynamic>> _getAllCoverage(
229
227
includeDart,
230
228
functionCoverage,
231
229
reportLines,
232
- coverableLineCache);
230
+ coverableLineCache,
231
+ scopedOutput);
233
232
allCoverage.addAll (coverage);
234
233
}
235
234
}
@@ -312,7 +311,8 @@ Future<List<Map<String, dynamic>>> _processSourceReport(
312
311
bool includeDart,
313
312
bool functionCoverage,
314
313
bool reportLines,
315
- Map <String , Set <int >>? coverableLineCache) async {
314
+ Map <String , Set <int >>? coverableLineCache,
315
+ Set <String > scopedOutput) async {
316
316
final hitMaps = < Uri , HitMap > {};
317
317
final scripts = < ScriptRef , Script > {};
318
318
final libraries = < LibraryRef > {};
@@ -362,8 +362,14 @@ Future<List<Map<String, dynamic>>> _processSourceReport(
362
362
363
363
for (var range in report.ranges! ) {
364
364
final scriptRef = report.scripts! [range.scriptIndex! ];
365
- final scriptUriString = scriptRef.uri! ;
366
- final scriptUri = Uri .parse (scriptUriString);
365
+ final scriptUriString = scriptRef.uri;
366
+ if (! scopedOutput.includesScript (scriptUriString)) {
367
+ // Sometimes a range's script can be different to the function's script
368
+ // (eg mixins), so we have to re-check the scope filter.
369
+ // See https://github.com/dart-lang/coverage/issues/495
370
+ continue ;
371
+ }
372
+ final scriptUri = Uri .parse (scriptUriString! );
367
373
368
374
// If we have a coverableLineCache, use it in the same way we use
369
375
// SourceReportCoverage.misses: to add zeros to the coverage result for all
@@ -497,3 +503,19 @@ class StdoutLog extends Log {
497
503
@override
498
504
void severe (String message) => print (message);
499
505
}
506
+
507
+ extension _ScopedOutput on Set <String > {
508
+ bool includesScript (String ? scriptUriString) {
509
+ if (scriptUriString == null ) return false ;
510
+
511
+ // If the set is empty, it means the user didn't specify a --scope-output
512
+ // flag, so allow everything.
513
+ if (isEmpty) return true ;
514
+
515
+ final scriptUri = Uri .parse (scriptUriString);
516
+ if (scriptUri.scheme != 'package' ) return false ;
517
+
518
+ final scope = scriptUri.pathSegments.first;
519
+ return contains (scope);
520
+ }
521
+ }
0 commit comments