[vm] Remove redirecting factories from source coverage report

Redirecting factories are never hit in source coverage report because
front-end replaces calls to redirecting factories with calls to their
targets. This change excludes redirecting factories from source
coverage reports.

TEST=vm/cc/SourceReport_Regress95008_RedirectingFactory
Fixes https://github.com/flutter/flutter/issues/95008

Change-Id: I0f6af291f7ee0c042521c92063092f990426b995
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/223600
Reviewed-by: Liam Appelbe <liama@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov 2021-12-13 19:47:04 +00:00 committed by Commit Bot
parent 498d976e1e
commit d950043abd
4 changed files with 58 additions and 2 deletions

View file

@ -1952,6 +1952,7 @@ void KernelLoader::LoadProcedure(const Library& library,
}
function.set_kernel_offset(procedure_offset);
function.set_is_extension_member(is_extension_member);
function.set_is_redirecting_factory(procedure_helper.IsRedirectingFactory());
if ((library.is_dart_scheme() &&
H.IsPrivate(procedure_helper.canonical_name_)) ||
(function.is_static() && (library.ptr() == Library::InternalLibrary()))) {

View file

@ -3800,7 +3800,8 @@ class Function : public Object {
V(PolymorphicTarget, is_polymorphic_target) \
V(HasPragma, has_pragma) \
V(IsSynthetic, is_synthetic) \
V(IsExtensionMember, is_extension_member)
V(IsExtensionMember, is_extension_member) \
V(IsRedirectingFactory, is_redirecting_factory)
// Bit that is updated after function is constructed, has to be updated in
// concurrent-safe manner.
#define FOR_EACH_FUNCTION_VOLATILE_KIND_BIT(V) V(Inlinable, is_inlinable)

View file

@ -105,7 +105,7 @@ bool SourceReport::ShouldSkipFunction(const Function& func) {
return true;
}
if (func.is_abstract() || func.IsImplicitConstructor() ||
func.is_synthetic()) {
func.is_synthetic() || func.is_redirecting_factory()) {
return true;
}
if (func.IsNonImplicitClosureFunction() &&

View file

@ -1065,6 +1065,60 @@ ISOLATE_UNIT_TEST_CASE(SourceReport_Coverage_IssueCov341_LateFinalVars) {
buffer);
}
ISOLATE_UNIT_TEST_CASE(SourceReport_Regress95008_RedirectingFactory) {
// WARNING: This MUST be big enough for the serialised JSON string.
const int kBufferSize = 1024;
char buffer[kBufferSize];
const char* kScript = R"(
class A {
A();
factory A.foo(int i) = B; // LINE_A
}
class B extends A {
int i;
B(this.i); // LINE_B
}
main() {
A.foo(42);
}
)";
Library& lib = Library::Handle();
lib ^= ExecuteScript(kScript);
ASSERT(!lib.IsNull());
const Script& script =
Script::Handle(lib.LookupScript(String::Handle(String::New("test-lib"))));
SourceReport report(SourceReport::kCoverage);
JSONStream js;
report.PrintJSON(&js, script);
const char* json_str = js.ToCString();
ASSERT(strlen(json_str) < kBufferSize);
ElideJSONSubstring("classes", json_str, buffer);
ElideJSONSubstring("libraries", buffer, buffer);
EXPECT_STREQ(
"{\"type\":\"SourceReport\",\"ranges\":["
// A()
"{\"scriptIndex\":0,\"startPos\":13,\"endPos\":16,\"compiled\":true,"
"\"coverage\":{\"hits\":[13],\"misses\":[]}},"
// B()
"{\"scriptIndex\":0,\"startPos\":90,\"endPos\":99,\"compiled\":true,"
"\"coverage\":{\"hits\":[90],\"misses\":[]}},"
// main
"{\"scriptIndex\":0,\"startPos\":114,\"endPos\":136,\"compiled\":true,"
"\"coverage\":{\"hits\":[114,127],\"misses\":[]}}],"
// Only one script in the script table.
"\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
"\"uri\":\"file:\\/\\/\\/test-lib\",\"_kind\":\"kernel\"}]}",
buffer);
}
#endif // !PRODUCT
} // namespace dart