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

Step Into (F11) steps into transpiled JavaScript when debugging TypeScript that uses async/await #4798

Closed
jpierson opened this issue Mar 30, 2016 · 21 comments
Assignees
Labels
debug Debug viewlet, configurations, breakpoints, adapter issues feature-request Request for new features or functionality
Milestone

Comments

@jpierson
Copy link

  • VSCode Version: 0.10.11
  • OS Version: Windows 10
  • Node Version: 4.2.2
  • TypeScirpt Version:

Steps to Reproduce:

  1. Set a break point on a line of TypeScript code in an async function that uses the await keyword on the Promise result of another async function. Example: const result = await callMyApi().
  2. Start debugging in VS Code by selecting a related launch profile in a TypScript project. See my example snippet below.
  3. Run necessary code so that the debugger is stopped on the breakpoint from step 1.
  4. Press F11 to step into the callMyApi function.

Expected Result:
The .ts TypeScript file where callMyApi implementation exists should be opened and the debugger should be stopped on the first line of that function.

Actual Result:
The .js transpiled JavaScript file is opened and the debugger is stopped on the first line of the that file.

/// launch.json snippet
{
    "name": "Test",
    "type": "node",
    "request": "launch",
    "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
    "stopOnEntry": false,
    "args": [
        "./bin/test/my.test.js"
    ],
    "cwd": "${workspaceRoot}",
    "runtimeExecutable": null,
    "runtimeArgs": [
        "--lazy",
        "--harmony", "--harmony_modules","--harmony_destructuring"
    ],
    "env": {
        "NODE_ENV": "development"
    },
    "externalConsole": false,
    "sourceMaps": true,
    "outDir": "${workspaceRoot}/bin"
}
// tsconfig.json compiler options snippet
{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "sourceMap": true,
        "allowJs": true,
        "outDir": "bin"
    }
   // excludes ...
}
@isidorn isidorn added the debug Debug viewlet, configurations, breakpoints, adapter issues label Mar 31, 2016
@weinand
Copy link
Contributor

weinand commented Mar 31, 2016

@jpierson this basically a problem of the generated source map and the fact that VS Code does not (yet) tries to be smart. Here is my example:

async function longRunning() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(42);
        }, 3000);
    });
}

async function main() {
    const result = await longRunning();
    console.log(`the answer to everything: ${result}`);
}

main();

As you can see in this visualization of the generated source map, the __awaiter function has no mapping to the TypeScript source. That's the reason why VS Code shows the generated code. I think this is a good strategy because now you can clearly see that you need to do another two F11s to step into the longRunning function.

On the other hand if the source map would have a mapping for __awaiter you would end up in some strange place in the TypeScript source and you would not know how to proceed.

So the current behaviour isn't optimal but it is not buggy either. I've added a 'feature request' label.

I'm planning to make node-debug smarter by detecting the __awaiter function and automatically issuing 'step into' requests.

@weinand weinand added the feature-request Request for new features or functionality label Mar 31, 2016
@weinand weinand added this to the Backlog milestone Mar 31, 2016
weinand added a commit to microsoft/vscode-node-debug that referenced this issue Apr 1, 2016
@weinand
Copy link
Contributor

weinand commented Apr 1, 2016

I've added experimental support for automatically skipping code that has a source map but where the mapping does not exist and would end up in the generated code. This can be enabled in the launch config by setting an attribute smartStep to true.

@jpierson @felixfbecker please let me know if you think this is useful.

@felixfbecker
Copy link
Contributor

@weinand If I understand you correctly, this is more an issue with TypeScript's/Babel's source map generation?

I have tried out the tool with your example, but compiled with the gulpfile from my debug adapter: link
You have to scroll down to the TS source because I do two-step compilation with TS+Babel. The await may not be colored, but I hover over it, it highlights the corresponding yield statement in the generator.

I think though that transpilation that adds additional function calls is quite common and if you can somehow detect and ignore those that would be a great feature. As a user, when I land in the compiled source, it is not clear to me that I have to do a step over to get to the TS again.

I tried to test the new feature by running vsce package in the repo and installing the package, but I get countless ENOENT errors like cannot read package.json or locale files, what am I doing wrong? Do I have to recompile VS Code?

@weinand
Copy link
Contributor

weinand commented Apr 1, 2016

@felixfbecker I've fixed the dependencies in vscode-node-debug and after removing node_modules and doing an npm install the vsce package created a vsix that works with the insiders release. There is no need to rebuild VS Code.

@weinand
Copy link
Contributor

weinand commented Apr 1, 2016

@felixfbecker my experimental "smart step" feature should be independent from what transpiler tools are used to generate JavaScript and source maps. The feature should just hide generated code by auto stepping through it. If you enable the feature you can see on the console how many "step in" commands were issued.

@felixfbecker
Copy link
Contributor

@weinand I am still hitting the source files. Ran git pull, rm -re -fo node_modules, npm i, gulp build, vsce package and installed it

@weinand
Copy link
Contributor

weinand commented Apr 1, 2016

@felixfbecker how it should look like: https://dl.dropboxusercontent.com/u/2433608/2016-04-01%2014-23-27.mp4 (before/after)

@felixfbecker
Copy link
Contributor

@weinand No idea why it's not working, can you send me your vsix?

@weinand
Copy link
Contributor

weinand commented Apr 1, 2016

@felixfbecker here is my sample project:
async.zip
and here the vsix:
node-debug-0.10.12.vsix.zip (double zipped...)

@felixfbecker
Copy link
Contributor

I meant the extension file as apparently I can't get it to compile and install correctly

@weinand
Copy link
Contributor

weinand commented Apr 1, 2016

@felixfbecker I'd like to know what problems you are seeing when trying to build vscode-node-debug? Is this on Windows? I just tried it there and for me it works.

@weinand
Copy link
Contributor

weinand commented Apr 1, 2016

@felixfbecker when looking at your sourec map I get the impression that the double mapping might be the issue. I'll have to try my code on the result of your way of transpiling TypScript...
With your source map it could be that the mapping process always succeeds even if the result of the mapping is again generated JavaScript (and not TypeScript). That's actually an interesting test case for the feature.

@felixfbecker
Copy link
Contributor

@weinand I think my Insiders build might be broken, getting all kinds of ENOENT and null pointer excs. Don't have time to investigate further right now. But +1 for the feature.

@egamma egamma mentioned this issue Apr 4, 2016
68 tasks
@weinand weinand modified the milestones: April 2016, Backlog Apr 5, 2016
@weinand
Copy link
Contributor

weinand commented Apr 6, 2016

I've add experimental support for this. You can enable this feature by adding an attribute smartStep with a value of true to your launch config.

@weinand weinand closed this as completed Apr 6, 2016
weinand added a commit to microsoft/vscode-node-debug that referenced this issue Apr 6, 2016
@Spown
Copy link

Spown commented May 9, 2016

I recon this smartStep option only works with TypeScript? Can we (pure js users) has this option also? For stepping only into project files and jumping over 'uninteresting code' like node_modules/**? Particularly #3215

@weinand
Copy link
Contributor

weinand commented May 10, 2016

@Spown feature request #6245 covers your suggestion.

@amcdnl
Copy link

amcdnl commented Jul 15, 2016

@weinand Is smartStep supposed to cover the issue of the debugger jumping as illistrated here: mozilla/source-map#221

I'm running TypeScript 2.0 & VSCode Insiders and having the jumping issue; although it does fix the step into issue.

Demo can be seen here: https://github.com/swimlane/node-microservice-demo/tree/master/petstore by running Launch, set a breakpoint here: https://github.com/swimlane/node-microservice-demo/blob/master/petstore/src/controllers/PetStoreController.ts#L28 and then hit localhost:8080/pets in your browser and step into that function.

@weinand
Copy link
Contributor

weinand commented Jul 15, 2016

@amcdnl basically yes. But I didn't try it with the examples from mozilla/source-map#221 (because I'm not using Babel).
The 'smartstep' approach is trivial: the debug adapter automatically executes additional 'step' requests if it had stopped in JavaScript that is not covered by the source map. This does not always eliminate the 'jumping around' completely, but it avoids showing the generated code.

@amcdnl
Copy link

amcdnl commented Jul 15, 2016

@weinand

But I didn't try it with the examples from mozilla/source-map#221 (because I'm not using Babel).

Yup, I was just posting that for reference as this happens in both situations. My current use case that I posted is TypeScript.

This does not always eliminate the 'jumping around' completely, but it avoids showing the generated code.

Well a step ( pun haha ) in the right direction, do you know if there is an issue tracking the jumping somewhere?

@weinand
Copy link
Contributor

weinand commented Jul 15, 2016

@amcdnl please create a new issue.

@amcdnl
Copy link

amcdnl commented Jul 15, 2016

@weinand done. Thanks for feedback.

@vscodebot vscodebot bot locked and limited conversation to collaborators Nov 18, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
debug Debug viewlet, configurations, breakpoints, adapter issues feature-request Request for new features or functionality
Projects
None yet
Development

No branches or pull requests

6 participants