Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d1affb7

Browse files
liamappelbeCommit Bot
authored andcommitted
[vm] Remove async function deduping in source_report
As of https://dart-review.googlesource.com/c/sdk/+/247603 we no longer see 2 copies of the function, so now this deduping check entirely skips those functions. Fixes: https://github.com/dart-lang/coverage/issues/392 Bug: https://github.com/dart-lang/coverage/issues/392 Change-Id: I7157eec2ad53b3bcff346e4837bec26169b94e5b TEST=Added coverage_async_test.dart Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248460 Commit-Queue: Liam Appelbe <liama@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
1 parent 08d6d8f commit d1affb7

File tree

2 files changed

+127
-5
lines changed

2 files changed

+127
-5
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright (c) 2022, 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+
import 'dart:developer';
6+
7+
import 'package:test/test.dart';
8+
import 'package:vm_service/vm_service.dart';
9+
10+
import 'common/service_test_common.dart';
11+
import 'common/test_helper.dart';
12+
13+
Future<int> asyncFunction() async {
14+
await Future.delayed(const Duration(milliseconds: 1));
15+
return 123;
16+
}
17+
18+
Stream<int> asyncGenerator() async* {
19+
await Future.delayed(const Duration(milliseconds: 1));
20+
yield 456;
21+
}
22+
23+
Iterable<int> syncGenerator() sync* {
24+
yield 789;
25+
}
26+
27+
Future<void> wrapperFunction() async {
28+
print(await asyncFunction());
29+
await for (final value in asyncGenerator()) {
30+
print(value);
31+
}
32+
for (final value in syncGenerator()) {
33+
print(value);
34+
}
35+
}
36+
37+
Future<void> testFunction() async {
38+
debugger();
39+
await wrapperFunction();
40+
debugger();
41+
}
42+
43+
bool allRangesCompiled(coverage) {
44+
for (int i = 0; i < coverage['ranges'].length; i++) {
45+
if (!coverage['ranges'][i]['compiled']) {
46+
return false;
47+
}
48+
}
49+
return true;
50+
}
51+
52+
IsolateTest coverageTest(Map<String, dynamic> expectedRange) {
53+
return (VmService service, IsolateRef isolateRef) async {
54+
final isolateId = isolateRef.id!;
55+
final isolate = await service.getIsolate(isolateId);
56+
final stack = await service.getStack(isolateId);
57+
58+
// Make sure we are in the right place.
59+
expect(stack.frames!.length, greaterThanOrEqualTo(1));
60+
expect(stack.frames![0].function!.name, 'testFunction');
61+
62+
final root =
63+
await service.getObject(isolateId, isolate.rootLib!.id!) as Library;
64+
FuncRef funcRef =
65+
root.functions!.singleWhere((f) => f.name == 'wrapperFunction');
66+
Func func = await service.getObject(isolateId, funcRef.id!) as Func;
67+
final location = func.location!;
68+
69+
final report = await service.getSourceReport(
70+
isolateId,
71+
[SourceReportKind.kCoverage],
72+
scriptId: location.script!.id,
73+
tokenPos: location.tokenPos,
74+
endTokenPos: location.endTokenPos,
75+
forceCompile: true,
76+
reportLines: true,
77+
);
78+
expect(report.ranges!.length, 1);
79+
expect(report.ranges![0].toJson(), expectedRange);
80+
expect(report.scripts!.length, 1);
81+
expect(
82+
report.scripts![0].uri,
83+
endsWith('coverage_async_test.dart'),
84+
);
85+
};
86+
}
87+
88+
var tests = <IsolateTest>[
89+
hasStoppedAtBreakpoint,
90+
coverageTest(
91+
{
92+
'scriptIndex': 0,
93+
'startPos': 674,
94+
'endPos': 878,
95+
'compiled': true,
96+
'coverage': {
97+
'hits': [],
98+
'misses': [27, 28, 28, 29, 29, 29, 30, 32, 32, 33]
99+
}
100+
},
101+
),
102+
resumeIsolate,
103+
hasStoppedAtBreakpoint,
104+
coverageTest(
105+
{
106+
'scriptIndex': 0,
107+
'startPos': 674,
108+
'endPos': 878,
109+
'compiled': true,
110+
'coverage': {
111+
'hits': [27, 28, 28, 29, 29, 29, 30, 32, 32, 33],
112+
'misses': []
113+
}
114+
},
115+
),
116+
];
117+
118+
main([args = const <String>[]]) => runIsolateTests(
119+
args,
120+
tests,
121+
'coverage_async_test.dart',
122+
testeeConcurrent: testFunction,
123+
);

runtime/vm/source_report.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -553,11 +553,10 @@ void SourceReport::VisitFunction(JSONArray* jsarr, const Function& func) {
553553
}
554554
ASSERT(!code.IsNull());
555555

556-
// We skip compiled async functions. Once an async function has
557-
// been compiled, there is another function with the same range which
558-
// actually contains the user code.
559-
if (!func.IsAsyncFunction() && !func.IsAsyncGenerator() &&
560-
!func.IsSyncGenerator()) {
556+
// We skip compiled sync generators. Once a sync generator has been compiled,
557+
// there is another function with the same range which actually contains the
558+
// user code.
559+
if (!func.IsSyncGenerator()) {
561560
JSONObject range(jsarr);
562561
range.AddProperty("scriptIndex", script_index);
563562
range.AddProperty("startPos", begin_pos);

0 commit comments

Comments
 (0)