Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function definition after the return statement #66

Closed
eight04 opened this issue Feb 18, 2019 · 14 comments
Closed

Function definition after the return statement #66

eight04 opened this issue Feb 18, 2019 · 14 comments
Labels

Comments

@eight04
Copy link

eight04 commented Feb 18, 2019

  • Version: v11.10.0
  • Platform: Windows 7 x64
  1. Create foo.js:
    function test(foo = "foo") {
      return {bar};
      
      function bar() {
        console.log("test");
      }
    }
    
    test().bar();
  2. Run c8 --reporter html node foo.js
  3. Line 3, 4 are marked as uncovered:
    image

It works fine if test has no default argument:
image

c8 v3.4.0

@eight04
Copy link
Author

eight04 commented Apr 18, 2019

This bug also applies to async function without default arguments:

async function test(foo) {
  return {bar};
  
  function bar() {
    console.log("test");
  }
}

test().then(r => r.bar());

image

@bcoe
Copy link
Owner

bcoe commented May 1, 2019

@eight04 could you please try with Node@12.0, or a never version of 11; I believe this issue has been addressed upstream.

@eight04
Copy link
Author

eight04 commented May 2, 2019

I can still reproduce this issue with Node@12.1.0 + c8@4.0.0.

@bcoe
Copy link
Owner

bcoe commented May 2, 2019

@schuay ping, this looks like it might trace back to some oddities in V8.

@schuay
Copy link

schuay commented May 6, 2019

Are microtasks run to completion before reporting coverage? I tried this locally in d8 and indeed just running the script does not show coverage for bar. But after flushing microtasks with %PerformMicrotaskCheckpoint(); (pass --allow-natives-syntax) the counts show up correctly.

I'm not familiar with how coverage is collected in node. Do you collect after completing all microtasks?

@bcoe
Copy link
Owner

bcoe commented May 6, 2019

@schuay interesting; it sounds like we might need to change our implementation in Node.js to force micro tasks to complete (CC: @joyeecheung).

@bcoe
Copy link
Owner

bcoe commented Oct 24, 2019

@schuay coming back to some old issues, this still seems to have issues in Node 13:

%PerformMicrotaskCheckpoint();
function test(foo = "foo") {
  return {bar};
  
  function bar() {
    console.log("test");
  }
}

test().bar();
----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |       80 |       75 |      100 |       80 |                   |
 foo.js   |       80 |       75 |      100 |       80 |               4,5 |
----------|----------|----------|----------|----------|-------------------|

@joyeecheung
Copy link

joyeecheung commented Oct 24, 2019

I think the question is whether we actually want to flush the microtasks at exit - in the case of e.g. uncaught excetions, this might not be desirable (because that may trigger more exceptions/rejections that are treated as exceptions by us). However we should be able to flush them at least when we are on the normal exit path.

@bcoe
Copy link
Owner

bcoe commented Oct 24, 2019

@joyeecheung I tried, on Jakob's suggestion, enabling natives syntax, and calling %PerformMicrotaskCheckpoint(); in the test script, and it's worth noting it didn't seem to do the trick.

@joyeecheung, I was thinking for some of these issues I'll perhaps open a tracking issue in V8, okay if I loop you in? or can you suggest someone else?

@joyeecheung
Copy link

joyeecheung commented Oct 24, 2019

Indeed, I tried this ad-hoc fix on Node.js master and it did not seem to work

diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc
index b5f63b2b41..8e760063a1 100644
--- a/src/inspector_profiler.cc
+++ b/src/inspector_profiler.cc
@@ -369,6 +369,7 @@ void EndStartedProfilers(Environment* env) {
   if (connection != nullptr && !connection->ending()) {
     Debug(
         env, DebugCategory::INSPECTOR_PROFILER, "Ending coverage collection\n");
+    env->isolate()->RunMicrotasks();
     connection->End();
   }
 }

okay if I loop you in?

Sure!

@schuay
Copy link

schuay commented Oct 28, 2019

I tried, on Jakob's suggestion, enabling natives syntax, and calling %PerformMicrotaskCheckpoint(); in the test script, and it's worth noting it didn't seem to do the trick.

As shown in comment #66 (comment)? I think you would need to call %PerformMicrotaskCheckpoint(); at the end of the script, not the beginning.

Anyways, there are no promises or asyncs in your most recent example, so likely no connection to microtasks. (Note another example above did use async functions.)

@sigurdschneider
Copy link

We've altered coverage reporting to not report whitespace as uncovered in this case: https://bugs.chromium.org/p/v8/issues/detail?id=9952

Thanks for finding this issue und posting a repro!

@schuay
Copy link

schuay commented Nov 7, 2019

I just want to point out that there is probably some issue in c8 causing the line containing function bar() { to be reported as uncovered, even though V8 correctly reports the leading two spaces as uncovered and the bar, starting at the function keyword, as covered.

The fix Sigurd mentioned above is slightly orthogonal since it just fixes our 'report-trailling-whitespace-and-comments-after-return' optimization for functions with default-value-args.

@bcoe please double-check why c8 is reporting lines 4 and 5 as uncovered.

bcoe added a commit to bcoe/node-1 that referenced this issue Nov 30, 2019
Original commit message:

    [coverage] Fix coverage with default arguments

    In the presence of default arguments, the body of the function gets
    wrapped into another block. This caused our trailing-range-after-return
    optimization to not apply, because the wrapper block had no source
    range assigned. This CL correctly assignes a source range to that block,
    which allows already present code to handle it correctly.

    Note that this is not a real coverage bug; we've just been reporting
    whitespace as uncovered. We're fixing it for consistency.

    Originally reported on github.com/bcoe/c8/issues/66

    Bug: v8:9952
    Change-Id: Iab3905f558eb99126e0dad8072d03d0a312fdcd3
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1903430
    Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Reviewed-by: Jakob Gruber <jgruber@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#64836}

Refs: v8/v8@0dfd9ea
bcoe added a commit to nodejs/node that referenced this issue Nov 30, 2019
Original commit message:

    [coverage] Fix coverage with default arguments

    In the presence of default arguments, the body of the function gets
    wrapped into another block. This caused our trailing-range-after-return
    optimization to not apply, because the wrapper block had no source
    range assigned. This CL correctly assignes a source range to that block,
    which allows already present code to handle it correctly.

    Note that this is not a real coverage bug; we've just been reporting
    whitespace as uncovered. We're fixing it for consistency.

    Originally reported on github.com/bcoe/c8/issues/66

    Bug: v8:9952
    Change-Id: Iab3905f558eb99126e0dad8072d03d0a312fdcd3
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1903430
    Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Reviewed-by: Jakob Gruber <jgruber@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#64836}

Refs: v8/v8@0dfd9ea

PR-URL: #30713
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@bcoe
Copy link
Owner

bcoe commented Nov 30, 2019

The upstream V8 fixes have been landed in Node.js, and I have confirmed that this addresses this issue 👍

@schuay I've opened a tracking issue for the hiccup with v8-to-istanbul (I think you're right that this is an actual issue).

@sigurdschneider thanks for this fix! this addresses a pretty nasty bug.

@bcoe bcoe closed this as completed Nov 30, 2019
targos pushed a commit to nodejs/node that referenced this issue Dec 1, 2019
Original commit message:

    [coverage] Fix coverage with default arguments

    In the presence of default arguments, the body of the function gets
    wrapped into another block. This caused our trailing-range-after-return
    optimization to not apply, because the wrapper block had no source
    range assigned. This CL correctly assignes a source range to that block,
    which allows already present code to handle it correctly.

    Note that this is not a real coverage bug; we've just been reporting
    whitespace as uncovered. We're fixing it for consistency.

    Originally reported on github.com/bcoe/c8/issues/66

    Bug: v8:9952
    Change-Id: Iab3905f558eb99126e0dad8072d03d0a312fdcd3
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1903430
    Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Reviewed-by: Jakob Gruber <jgruber@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#64836}

Refs: v8/v8@0dfd9ea

PR-URL: #30713
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
bcoe added a commit to bcoe/node-1 that referenced this issue Jan 19, 2020
Original commit message:

    [coverage] Fix coverage with default arguments

    In the presence of default arguments, the body of the function gets
    wrapped into another block. This caused our trailing-range-after-return
    optimization to not apply, because the wrapper block had no source
    range assigned. This CL correctly assignes a source range to that block,
    which allows already present code to handle it correctly.

    Note that this is not a real coverage bug; we've just been reporting
    whitespace as uncovered. We're fixing it for consistency.

    Originally reported on github.com/bcoe/c8/issues/66

    Bug: v8:9952
    Change-Id: Iab3905f558eb99126e0dad8072d03d0a312fdcd3
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1903430
    Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Reviewed-by: Jakob Gruber <jgruber@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#64836}

Refs: v8/v8@0dfd9ea

PR-URL: nodejs#30713
Backport-PR-URL: nodejs#31412
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
MylesBorins pushed a commit to nodejs/node that referenced this issue Jan 30, 2020
Original commit message:

    [coverage] Fix coverage with default arguments

    In the presence of default arguments, the body of the function gets
    wrapped into another block. This caused our trailing-range-after-return
    optimization to not apply, because the wrapper block had no source
    range assigned. This CL correctly assignes a source range to that block,
    which allows already present code to handle it correctly.

    Note that this is not a real coverage bug; we've just been reporting
    whitespace as uncovered. We're fixing it for consistency.

    Originally reported on github.com/bcoe/c8/issues/66

    Bug: v8:9952
    Change-Id: Iab3905f558eb99126e0dad8072d03d0a312fdcd3
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1903430
    Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Reviewed-by: Jakob Gruber <jgruber@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#64836}

Refs: v8/v8@0dfd9ea

Backport-PR-URL: #31412
PR-URL: #30713
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
BethGriggs pushed a commit to nodejs/node that referenced this issue Feb 6, 2020
Original commit message:

    [coverage] Fix coverage with default arguments

    In the presence of default arguments, the body of the function gets
    wrapped into another block. This caused our trailing-range-after-return
    optimization to not apply, because the wrapper block had no source
    range assigned. This CL correctly assignes a source range to that block,
    which allows already present code to handle it correctly.

    Note that this is not a real coverage bug; we've just been reporting
    whitespace as uncovered. We're fixing it for consistency.

    Originally reported on github.com/bcoe/c8/issues/66

    Bug: v8:9952
    Change-Id: Iab3905f558eb99126e0dad8072d03d0a312fdcd3
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1903430
    Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Reviewed-by: Jakob Gruber <jgruber@chromium.org>
    Cr-Commit-Position: refs/heads/master@{#64836}

Refs: v8/v8@0dfd9ea

Backport-PR-URL: #31412
PR-URL: #30713
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants