* Implements DAP `stepInTargets` request. * * @todo location information is patched in until ratification of * https://github.com/microsoft/debug-adapter-protocol/issues/274
(frameId: number)
| 821 | * https://github.com/microsoft/debug-adapter-protocol/issues/274 |
| 822 | */ |
| 823 | public async getStepInTargets(frameId: number): Promise< |
| 824 | (Dap.StepInTarget & { |
| 825 | line?: number; |
| 826 | column?: number; |
| 827 | endLine?: number; |
| 828 | endColumn?: number; |
| 829 | })[] |
| 830 | > { |
| 831 | const pausedDetails = this._pausedDetails; |
| 832 | if (!pausedDetails) { |
| 833 | return []; |
| 834 | } |
| 835 | |
| 836 | const frame = pausedDetails.stackTrace.frames.find(f => f.frameId === frameId); |
| 837 | if (!(frame instanceof StackFrame)) { |
| 838 | return []; |
| 839 | } |
| 840 | |
| 841 | const pausedLocation = await frame.uiLocation(); |
| 842 | if (!pausedLocation) { |
| 843 | return []; |
| 844 | } |
| 845 | |
| 846 | const rawPausedLocation = pausedDetails.event.callFrames[0].location; |
| 847 | const [locations, content] = await Promise.all([ |
| 848 | this._breakpointManager |
| 849 | .getBreakpointLocations( |
| 850 | this, |
| 851 | pausedLocation.source, |
| 852 | new Base1Position(pausedLocation.lineNumber, 1), |
| 853 | new Base1Position(pausedLocation.lineNumber + 1, 1), |
| 854 | ) |
| 855 | .then(l => |
| 856 | // remove the currently-paused location |
| 857 | l.filter( |
| 858 | l => |
| 859 | l.breakLocation.lineNumber !== rawPausedLocation.lineNumber |
| 860 | || l.breakLocation.columnNumber !== rawPausedLocation.columnNumber, |
| 861 | ) |
| 862 | ), |
| 863 | pausedLocation.source.content(), |
| 864 | ]); |
| 865 | |
| 866 | // V8's breakpoint locations are placed directly before the function to |
| 867 | // be called, which is perfect, e.g `this.*greet()`. However, once mapped, |
| 868 | // many tools will make the entire `this.greet(` a single range, which |
| 869 | // means default behavior of reading the next word will not give a good |
| 870 | // location. Instead, look over the source content manually to build ranges. |
| 871 | |
| 872 | const idStart = pausedDetails.stepInTargets?.length || 0; |
| 873 | pausedDetails.stepInTargets = pausedDetails.stepInTargets?.concat(locations) || locations; |
| 874 | |
| 875 | const lines = content && new PositionToOffset(content); |
| 876 | |
| 877 | return locations |
| 878 | .map((location, i) => { |
| 879 | const preferred = location.uiLocations.find(l => l.source === pausedLocation.source); |
| 880 | if (!preferred) { |
no test coverage detected