source-maps.js (3863B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ 4 5 import { 6 debuggerToSourceMapLocation, 7 sourceMapToDebuggerLocation, 8 } from "./location"; 9 import { waitForSourceToBeRegisteredInStore } from "../client/firefox/create"; 10 11 /** 12 * For any location, return the matching generated location. 13 * If this is already a generated location, returns the same location. 14 * 15 * In additional to `SourceMapLoader.getGeneratedLocation`, 16 * this asserts that the related source is still registered in the reducer current state. 17 * 18 * @param {object} location 19 * @param {object} thunkArgs 20 * Redux action thunk arguments 21 * @param {object} 22 * The matching generated location. 23 */ 24 export async function getGeneratedLocation(location, thunkArgs) { 25 if (!location.source.isOriginal) { 26 return location; 27 } 28 29 const { sourceMapLoader, getState } = thunkArgs; 30 const generatedLocation = await sourceMapLoader.getGeneratedLocation( 31 debuggerToSourceMapLocation(location) 32 ); 33 if (!generatedLocation) { 34 return location; 35 } 36 37 return sourceMapToDebuggerLocation(getState(), generatedLocation); 38 } 39 40 /** 41 * For any location, return the matching original location. 42 * If this is already an original location, returns the same location. 43 * 44 * In additional to `SourceMapLoader.getOriginalLocation`, 45 * this automatically fetches the original source object in order to build 46 * the original location object. 47 * 48 * @param {object} location 49 * @param {object} thunkArgs 50 * Redux action thunk arguments 51 * @param {object} options 52 * @param {boolean} options.waitForSource 53 * Default to false. If true is passed, this function will 54 * ensure waiting, possibly asynchronously for the related original source 55 * to be registered in the redux store. 56 * @param {boolean} options.looseSearch 57 * Default to false. If true, this won't query an exact mapping, 58 * but will also lookup for a loose match at the first column and next lines. 59 * 60 * @param {object} 61 * The matching original location. 62 */ 63 export async function getOriginalLocation( 64 location, 65 thunkArgs, 66 { waitForSource = false, looseSearch = false } = {} 67 ) { 68 if (location.source.isOriginal) { 69 return location; 70 } 71 const { getState, sourceMapLoader } = thunkArgs; 72 const originalLocation = await sourceMapLoader.getOriginalLocation( 73 debuggerToSourceMapLocation(location), 74 { looseSearch } 75 ); 76 if (!originalLocation) { 77 return location; 78 } 79 80 // When we are mapping frames while being paused, 81 // the original source may not be registered yet in the reducer. 82 if (waitForSource) { 83 await waitForSourceToBeRegisteredInStore(originalLocation.sourceId); 84 } 85 86 return sourceMapToDebuggerLocation(getState(), originalLocation); 87 } 88 89 export async function getMappedLocation(location, thunkArgs) { 90 if (location.source.isOriginal) { 91 const generatedLocation = await getGeneratedLocation(location, thunkArgs); 92 return { location, generatedLocation }; 93 } 94 95 const generatedLocation = location; 96 const originalLocation = await getOriginalLocation( 97 generatedLocation, 98 thunkArgs 99 ); 100 101 return { location: originalLocation, generatedLocation }; 102 } 103 104 /** 105 * Gets the "mapped location". 106 * 107 * If the passed location is on a generated source, it gets the 108 * related location in the original source. 109 * If the passed location is on an original source, it gets the 110 * related location in the generated source. 111 */ 112 export async function getRelatedMapLocation(location, thunkArgs) { 113 if (!location.source) { 114 return location; 115 } 116 117 if (location.source.isOriginal) { 118 return getGeneratedLocation(location, thunkArgs); 119 } 120 121 return getOriginalLocation(location, thunkArgs); 122 }