istanbuljs / istanbuljs

monorepo containing the various nuts and bolts that facilitate istanbul.js test instrumentation
https://istanbul.js.org/
1.02k stars 236 forks source link

Class fields instrumentation breaks name inferences #782

Open NotWearingPants opened 6 months ago

NotWearingPants commented 6 months ago

Very similar to #59 (which is fixed).

This code behaves different when instrumented:

class Foo {
    field1 = function() {};
    ['field' + 2] = class {};
    static ['field' + 3] = function() {};
    static field4 = class {};
}
console.log(new Foo().field1);
console.log(new Foo().field2);
console.log(Foo.field3);
console.log(Foo.field4);

Normally it prints:

[Function: field1]
[class field2]
[Function: field3]
[class field4]

After instrumentation it prints:

[Function (anonymous)]
[class (anonymous)]
[Function (anonymous)]
[class (anonymous)]

The instrumented code contains:

class Foo {
    field1 = (cov_1m4qtsm9gj().s[0]++, function() { cov_1m4qtsm9gj().f[0]++; });
    ["field" + 2] = (cov_1m4qtsm9gj().s[1]++, class {});
    static ["field" + 3] = (cov_1m4qtsm9gj().s[2]++, function() { cov_1m4qtsm9gj().f[1]++; });
    static field4 = (cov_1m4qtsm9gj().s[3]++, class {});
}
cov_1m4qtsm9gj().s[4]++; console.log(new Foo().field1);
cov_1m4qtsm9gj().s[5]++; console.log(new Foo().field2);
cov_1m4qtsm9gj().s[6]++; console.log(Foo.field3);
cov_1m4qtsm9gj().s[7]++; console.log(Foo.field4);

so the function and class expressions can't infer their names.


Unlike #59 it's not clear where to hoist the counter to, maybe to a temp field above?

class Foo {
    _cov_0 = cov_1m4qtsm9gj().s[0]++; // <--
    field1 = function() { cov_1m4qtsm9gj().f[0]++; };
    _cov_1 = cov_1m4qtsm9gj().s[1]++; // <--
    ["field" + 2] = class {};
    static _cov_2 = cov_1m4qtsm9gj().s[2]++; // <--
    static ["field" + 3] = function() { cov_1m4qtsm9gj().f[1]++; };
    static _cov_3 = cov_1m4qtsm9gj().s[3]++; // <--
    static field4 = class {};
}

What do you think?