зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 5 changesets (bug 1541633) for devtools failures on browser_dbg-sourcemapped-breakpoint-console.js.
Backed out changeset 35fe7c48b49a (bug 1541633) Backed out changeset 59019ae6bf3f (bug 1541633) Backed out changeset 44ea34f63223 (bug 1541633) Backed out changeset a8378192e3b6 (bug 1541633) Backed out changeset de895ee6de42 (bug 1541633) --HG-- extra : rebase_source : 9b3e5b34867298d1a5ffad2ade538c24ff045c1c
This commit is contained in:
Родитель
df6c33c509
Коммит
5086a1bd98
|
@ -19,4 +19,3 @@
|
|||
[options]
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIgnore
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe
|
||||
module.name_mapper='^debugger-html$' -> '<PROJECT_ROOT>/src/types.js'
|
||||
|
|
|
@ -6775,9 +6775,7 @@ WorkerDispatcher.prototype = {
|
|||
const [, resolve, reject] = items[i];
|
||||
|
||||
if (resultData.error) {
|
||||
const err = new Error(resultData.message);
|
||||
err.metadata = resultData.metadata;
|
||||
reject(err);
|
||||
reject(resultData.error);
|
||||
} else {
|
||||
resolve(resultData.response);
|
||||
}
|
||||
|
@ -6810,14 +6808,22 @@ function workerHandler(publicInterface) {
|
|||
if (response instanceof Promise) {
|
||||
return response.then(val => ({
|
||||
response: val
|
||||
}), err => asErrorMessage(err));
|
||||
}), // Error can't be sent via postMessage, so be sure to
|
||||
// convert to string.
|
||||
err => ({
|
||||
error: err.toString()
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
response
|
||||
};
|
||||
} catch (error) {
|
||||
return asErrorMessage(error);
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: error.toString()
|
||||
};
|
||||
}
|
||||
})).then(results => {
|
||||
self.postMessage({
|
||||
|
@ -6828,24 +6834,6 @@ function workerHandler(publicInterface) {
|
|||
};
|
||||
}
|
||||
|
||||
function asErrorMessage(error) {
|
||||
if (typeof error === "object" && error && "message" in error) {
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: true,
|
||||
message: error.message,
|
||||
metadata: error.metadata
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
error: true,
|
||||
message: error == null ? error : error.toString(),
|
||||
metadata: undefined
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WorkerDispatcher,
|
||||
workerHandler
|
||||
|
|
|
@ -613,9 +613,7 @@ WorkerDispatcher.prototype = {
|
|||
const [, resolve, reject] = items[i];
|
||||
|
||||
if (resultData.error) {
|
||||
const err = new Error(resultData.message);
|
||||
err.metadata = resultData.metadata;
|
||||
reject(err);
|
||||
reject(resultData.error);
|
||||
} else {
|
||||
resolve(resultData.response);
|
||||
}
|
||||
|
@ -648,14 +646,22 @@ function workerHandler(publicInterface) {
|
|||
if (response instanceof Promise) {
|
||||
return response.then(val => ({
|
||||
response: val
|
||||
}), err => asErrorMessage(err));
|
||||
}), // Error can't be sent via postMessage, so be sure to
|
||||
// convert to string.
|
||||
err => ({
|
||||
error: err.toString()
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
response
|
||||
};
|
||||
} catch (error) {
|
||||
return asErrorMessage(error);
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: error.toString()
|
||||
};
|
||||
}
|
||||
})).then(results => {
|
||||
self.postMessage({
|
||||
|
@ -666,24 +672,6 @@ function workerHandler(publicInterface) {
|
|||
};
|
||||
}
|
||||
|
||||
function asErrorMessage(error) {
|
||||
if (typeof error === "object" && error && "message" in error) {
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: true,
|
||||
message: error.message,
|
||||
metadata: error.metadata
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
error: true,
|
||||
message: error == null ? error : error.toString(),
|
||||
metadata: undefined
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WorkerDispatcher,
|
||||
workerHandler
|
||||
|
|
|
@ -275,9 +275,7 @@ WorkerDispatcher.prototype = {
|
|||
const [, resolve, reject] = items[i];
|
||||
|
||||
if (resultData.error) {
|
||||
const err = new Error(resultData.message);
|
||||
err.metadata = resultData.metadata;
|
||||
reject(err);
|
||||
reject(resultData.error);
|
||||
} else {
|
||||
resolve(resultData.response);
|
||||
}
|
||||
|
@ -310,14 +308,22 @@ function workerHandler(publicInterface) {
|
|||
if (response instanceof Promise) {
|
||||
return response.then(val => ({
|
||||
response: val
|
||||
}), err => asErrorMessage(err));
|
||||
}), // Error can't be sent via postMessage, so be sure to
|
||||
// convert to string.
|
||||
err => ({
|
||||
error: err.toString()
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
response
|
||||
};
|
||||
} catch (error) {
|
||||
return asErrorMessage(error);
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: error.toString()
|
||||
};
|
||||
}
|
||||
})).then(results => {
|
||||
self.postMessage({
|
||||
|
@ -328,24 +334,6 @@ function workerHandler(publicInterface) {
|
|||
};
|
||||
}
|
||||
|
||||
function asErrorMessage(error) {
|
||||
if (typeof error === "object" && error && "message" in error) {
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: true,
|
||||
message: error.message,
|
||||
metadata: error.metadata
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
error: true,
|
||||
message: error == null ? error : error.toString(),
|
||||
metadata: undefined
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WorkerDispatcher,
|
||||
workerHandler
|
||||
|
|
|
@ -1489,9 +1489,7 @@ WorkerDispatcher.prototype = {
|
|||
const [, resolve, reject] = items[i];
|
||||
|
||||
if (resultData.error) {
|
||||
const err = new Error(resultData.message);
|
||||
err.metadata = resultData.metadata;
|
||||
reject(err);
|
||||
reject(resultData.error);
|
||||
} else {
|
||||
resolve(resultData.response);
|
||||
}
|
||||
|
@ -1524,14 +1522,22 @@ function workerHandler(publicInterface) {
|
|||
if (response instanceof Promise) {
|
||||
return response.then(val => ({
|
||||
response: val
|
||||
}), err => asErrorMessage(err));
|
||||
}), // Error can't be sent via postMessage, so be sure to
|
||||
// convert to string.
|
||||
err => ({
|
||||
error: err.toString()
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
response
|
||||
};
|
||||
} catch (error) {
|
||||
return asErrorMessage(error);
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: error.toString()
|
||||
};
|
||||
}
|
||||
})).then(results => {
|
||||
self.postMessage({
|
||||
|
@ -1542,24 +1548,6 @@ function workerHandler(publicInterface) {
|
|||
};
|
||||
}
|
||||
|
||||
function asErrorMessage(error) {
|
||||
if (typeof error === "object" && error && "message" in error) {
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: true,
|
||||
message: error.message,
|
||||
metadata: error.metadata
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
error: true,
|
||||
message: error == null ? error : error.toString(),
|
||||
metadata: undefined
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WorkerDispatcher,
|
||||
workerHandler
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// @flow
|
||||
|
||||
declare module "debugger-html" {
|
||||
/**
|
||||
* Breakpoint ID
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type BreakpointId = string;
|
||||
|
||||
/**
|
||||
* Source ID
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type SourceId = string;
|
||||
|
||||
/**
|
||||
* Actor ID
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type ActorId = string;
|
||||
|
||||
/**
|
||||
* Source File Location
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type SourceLocation = {|
|
||||
sourceId: SourceId,
|
||||
line: number,
|
||||
column?: number,
|
||||
sourceUrl?: string
|
||||
|};
|
||||
|
||||
/**
|
||||
* Breakpoint
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type Breakpoint = {
|
||||
id: BreakpointId,
|
||||
location: SourceLocation,
|
||||
loading: boolean,
|
||||
disabled: boolean,
|
||||
text: string,
|
||||
condition: ?string
|
||||
};
|
||||
|
||||
/**
|
||||
* Breakpoint Result is the return from an add/modify Breakpoint request
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type BreakpointResult = {
|
||||
id: ActorId,
|
||||
actualLocation: SourceLocation
|
||||
};
|
||||
|
||||
/**
|
||||
* Source
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type Source = {
|
||||
id: SourceId,
|
||||
url?: string,
|
||||
sourceMapURL?: string,
|
||||
isWasm: boolean,
|
||||
text?: string,
|
||||
contentType?: string
|
||||
};
|
||||
|
||||
/**
|
||||
* Frame ID
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type FrameId = string;
|
||||
|
||||
/**
|
||||
* Frame
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type Frame = {
|
||||
id: FrameId,
|
||||
displayName: string,
|
||||
location: SourceLocation,
|
||||
source?: Source,
|
||||
scope: Scope,
|
||||
// FIXME Define this type more clearly
|
||||
this: Object
|
||||
};
|
||||
|
||||
/**
|
||||
* Original Frame
|
||||
*
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type OriginalFrame = {
|
||||
displayName: string,
|
||||
location?: SourceLocation,
|
||||
thread?: string
|
||||
};
|
||||
|
||||
/**
|
||||
* why
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type Why = {
|
||||
type: string
|
||||
};
|
||||
|
||||
/**
|
||||
* Why is the Debugger Paused?
|
||||
* This is the generic state handling the reason the debugger is paused.
|
||||
* Reasons are usually related to "breakpoint" or "debuggerStatement"
|
||||
* and should eventually be specified here as an enum. For now we will
|
||||
* just offer it as a string.
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type WhyPaused = {
|
||||
type: string
|
||||
};
|
||||
|
||||
declare type LoadedObject = {
|
||||
objectId: string,
|
||||
parentId: string,
|
||||
name: string,
|
||||
value: any
|
||||
};
|
||||
|
||||
/**
|
||||
* Pause
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type Pause = {
|
||||
frames: Frame[],
|
||||
why: Why,
|
||||
getIn: (string[]) => any,
|
||||
loadedObjects?: LoadedObject[]
|
||||
};
|
||||
/**
|
||||
* Expression
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type Expression = {
|
||||
id: number,
|
||||
input: string
|
||||
};
|
||||
|
||||
/**
|
||||
* Grip
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type Grip = {
|
||||
actor: string,
|
||||
class: string,
|
||||
extensible: boolean,
|
||||
frozen: boolean,
|
||||
isGlobal: boolean,
|
||||
ownPropertyLength: number,
|
||||
preview: {
|
||||
kind: string,
|
||||
url: string
|
||||
},
|
||||
sealed: boolean,
|
||||
type: string
|
||||
};
|
||||
|
||||
/**
|
||||
* SourceText
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type SourceText = {
|
||||
id: string,
|
||||
text: string,
|
||||
contentType: string
|
||||
};
|
||||
|
||||
/**
|
||||
* SourceScope
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type SourceScope = {
|
||||
type: string,
|
||||
start: SourceLocation,
|
||||
end: SourceLocation,
|
||||
bindings: {
|
||||
[name: string]: SourceLocation[]
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* MappedScopeBindings
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type MappedScopeBindings = {
|
||||
type: string,
|
||||
bindings: {
|
||||
[originalName: string]: string
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Script
|
||||
* This describes scripts which are sent to the debug server to be eval'd
|
||||
* @memberof types
|
||||
* @static
|
||||
* FIXME: This needs a real type definition
|
||||
*/
|
||||
declare type Script = any;
|
||||
|
||||
declare type SyntheticScope = {
|
||||
type: string,
|
||||
bindingsNames: string[]
|
||||
};
|
||||
|
||||
/**
|
||||
* Scope
|
||||
* @memberof types
|
||||
* @static
|
||||
*/
|
||||
declare type Scope = {
|
||||
actor: ActorId,
|
||||
parent: Scope,
|
||||
bindings: {
|
||||
// FIXME Define these types more clearly
|
||||
arguments: Array<Object>,
|
||||
variables: Object
|
||||
},
|
||||
function: {
|
||||
actor: ActorId,
|
||||
class: string,
|
||||
displayName: string,
|
||||
location: SourceLocation,
|
||||
// FIXME Define this type more clearly
|
||||
parameterNames: Array<Object>
|
||||
},
|
||||
syntheticScopes?: {
|
||||
scopes: SyntheticScope[],
|
||||
groupIndex: number,
|
||||
groupLength: number
|
||||
},
|
||||
type: string
|
||||
};
|
||||
}
|
|
@ -12,9 +12,11 @@ import type {
|
|||
OriginalFrame,
|
||||
Range,
|
||||
SourceLocation,
|
||||
Source,
|
||||
SourceId,
|
||||
} from "../../../src/types";
|
||||
import type { SourceMapInput, LocationOptions } from "./source-map";
|
||||
import type { SourceMapConsumer } from "source-map";
|
||||
import type { LocationOptions } from "./source-map";
|
||||
|
||||
export const dispatcher = new WorkerDispatcher();
|
||||
|
||||
|
@ -37,39 +39,44 @@ export const setAssetRootURL = async (assetRoot: string): Promise<void> =>
|
|||
dispatcher.invoke("setAssetRootURL", assetRoot);
|
||||
|
||||
export const getOriginalURLs = async (
|
||||
generatedSource: SourceMapInput
|
||||
): Promise<?Array<{| id: SourceId, url: string |}>> =>
|
||||
generatedSource: Source
|
||||
): Promise<SourceMapConsumer> =>
|
||||
dispatcher.invoke("getOriginalURLs", generatedSource);
|
||||
|
||||
export const hasOriginalURL = async (url: string): Promise<boolean> =>
|
||||
dispatcher.invoke("hasOriginalURL", url);
|
||||
|
||||
export const getOriginalRanges = async (
|
||||
sourceId: SourceId
|
||||
sourceId: SourceId,
|
||||
url: string
|
||||
): Promise<
|
||||
Array<{
|
||||
line: number,
|
||||
columnStart: number,
|
||||
columnEnd: number,
|
||||
}>
|
||||
> => dispatcher.invoke("getOriginalRanges", sourceId);
|
||||
> => dispatcher.invoke("getOriginalRanges", sourceId, url);
|
||||
export const getGeneratedRanges = async (
|
||||
location: SourceLocation
|
||||
location: SourceLocation,
|
||||
originalSource: Source
|
||||
): Promise<
|
||||
Array<{
|
||||
line: number,
|
||||
columnStart: number,
|
||||
columnEnd: number,
|
||||
}>
|
||||
> => _getGeneratedRanges(location);
|
||||
> => _getGeneratedRanges(location, originalSource);
|
||||
|
||||
export const getGeneratedLocation = async (
|
||||
location: SourceLocation
|
||||
): Promise<SourceLocation> => _getGeneratedLocation(location);
|
||||
location: SourceLocation,
|
||||
originalSource: Source
|
||||
): Promise<SourceLocation> => _getGeneratedLocation(location, originalSource);
|
||||
|
||||
export const getAllGeneratedLocations = async (
|
||||
location: SourceLocation
|
||||
): Promise<Array<SourceLocation>> => _getAllGeneratedLocations(location);
|
||||
location: SourceLocation,
|
||||
originalSource: Source
|
||||
): Promise<Array<SourceLocation>> =>
|
||||
_getAllGeneratedLocations(location, originalSource);
|
||||
|
||||
export const getOriginalLocation = async (
|
||||
location: SourceLocation,
|
||||
|
@ -77,32 +84,36 @@ export const getOriginalLocation = async (
|
|||
): Promise<SourceLocation> => _getOriginalLocation(location, options);
|
||||
|
||||
export const getOriginalLocations = async (
|
||||
sourceId: SourceId,
|
||||
locations: SourceLocation[],
|
||||
options: LocationOptions = {}
|
||||
): Promise<SourceLocation[]> =>
|
||||
dispatcher.invoke("getOriginalLocations", locations, options);
|
||||
dispatcher.invoke("getOriginalLocations", sourceId, locations, options);
|
||||
|
||||
export const getGeneratedRangesForOriginal = async (
|
||||
sourceId: SourceId,
|
||||
url: string,
|
||||
mergeUnmappedRegions?: boolean
|
||||
): Promise<Range[]> =>
|
||||
dispatcher.invoke(
|
||||
"getGeneratedRangesForOriginal",
|
||||
sourceId,
|
||||
url,
|
||||
mergeUnmappedRegions
|
||||
);
|
||||
|
||||
export const getFileGeneratedRange = async (
|
||||
originalSourceId: SourceId
|
||||
): Promise<Range> =>
|
||||
dispatcher.invoke("getFileGeneratedRange", originalSourceId);
|
||||
originalSource: Source
|
||||
): Promise<Range> => dispatcher.invoke("getFileGeneratedRange", originalSource);
|
||||
|
||||
export const getLocationScopes = dispatcher.task("getLocationScopes");
|
||||
|
||||
export const getOriginalSourceText = async (
|
||||
originalSourceId: SourceId
|
||||
originalSource: Source
|
||||
): Promise<?{
|
||||
text: string,
|
||||
contentType: string,
|
||||
}> => dispatcher.invoke("getOriginalSourceText", originalSourceId);
|
||||
}> => dispatcher.invoke("getOriginalSourceText", originalSource);
|
||||
|
||||
export const applySourceMap = async (
|
||||
generatedId: string,
|
||||
|
@ -115,6 +126,10 @@ export const applySourceMap = async (
|
|||
export const clearSourceMaps = async (): Promise<void> =>
|
||||
dispatcher.invoke("clearSourceMaps");
|
||||
|
||||
export const hasMappedSource = async (
|
||||
location: SourceLocation
|
||||
): Promise<boolean> => dispatcher.invoke("hasMappedSource", location);
|
||||
|
||||
export const getOriginalStackFrames = async (
|
||||
generatedLocation: SourceLocation
|
||||
): Promise<?Array<OriginalFrame>> =>
|
||||
|
|
|
@ -21,7 +21,6 @@ const {
|
|||
} = require("./utils/fetchSourceMap");
|
||||
const {
|
||||
getSourceMap,
|
||||
getSourceMapWithMetadata,
|
||||
setSourceMap,
|
||||
clearSourceMaps: clearSourceMapsRequests,
|
||||
} = require("./utils/sourceMapRequests");
|
||||
|
@ -34,7 +33,7 @@ const {
|
|||
} = require("./utils");
|
||||
const { clearWasmXScopes } = require("devtools-wasm-dwarf");
|
||||
|
||||
import type { SourceLocation, SourceId } from "debugger-html";
|
||||
import type { SourceLocation, Source, SourceId } from "debugger-html";
|
||||
|
||||
type Range = {
|
||||
start: {
|
||||
|
@ -46,32 +45,24 @@ type Range = {
|
|||
column: number,
|
||||
},
|
||||
};
|
||||
export type SourceMapInput = {|
|
||||
id: SourceId,
|
||||
url: string,
|
||||
sourceMapURL: string,
|
||||
isWasm: boolean,
|
||||
|};
|
||||
|
||||
export type LocationOptions = {
|
||||
search?: "LEAST_UPPER_BOUND" | "GREATEST_LOWER_BOUND",
|
||||
};
|
||||
|
||||
async function getOriginalURLs(
|
||||
generatedSource: SourceMapInput
|
||||
): Promise<?Array<{| id: SourceId, url: string |}>> {
|
||||
await fetchSourceMap(generatedSource);
|
||||
|
||||
const data = await getSourceMapWithMetadata(generatedSource.id);
|
||||
|
||||
return data ? data.sources : null;
|
||||
generatedSource: Source
|
||||
): Promise<SourceMapConsumer> {
|
||||
const map = await fetchSourceMap(generatedSource);
|
||||
return map && map.sources;
|
||||
}
|
||||
|
||||
const COMPUTED_SPANS = new WeakSet();
|
||||
|
||||
const SOURCE_MAPPINGS = new WeakMap();
|
||||
async function getOriginalRanges(
|
||||
sourceId: SourceId
|
||||
sourceId: SourceId,
|
||||
url: string
|
||||
): Promise<
|
||||
Array<{
|
||||
line: number,
|
||||
|
@ -84,12 +75,10 @@ async function getOriginalRanges(
|
|||
}
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(sourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
if (!data) {
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
if (!map) {
|
||||
return [];
|
||||
}
|
||||
const { map } = data;
|
||||
const url = data.urlsById.get(sourceId);
|
||||
|
||||
let mappings = SOURCE_MAPPINGS.get(map);
|
||||
if (!mappings) {
|
||||
|
@ -139,7 +128,8 @@ async function getOriginalRanges(
|
|||
* are mapped from the original range containing the location.
|
||||
*/
|
||||
async function getGeneratedRanges(
|
||||
location: SourceLocation
|
||||
location: SourceLocation,
|
||||
originalSource: Source
|
||||
): Promise<
|
||||
Array<{
|
||||
line: number,
|
||||
|
@ -152,11 +142,10 @@ async function getGeneratedRanges(
|
|||
}
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(location.sourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
if (!data) {
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
if (!map) {
|
||||
return [];
|
||||
}
|
||||
const { urlsById, map } = data;
|
||||
|
||||
if (!COMPUTED_SPANS.has(map)) {
|
||||
COMPUTED_SPANS.add(map);
|
||||
|
@ -170,7 +159,7 @@ async function getGeneratedRanges(
|
|||
// exact original location, making any bias value unnecessary, and then
|
||||
// use that location for the call to 'allGeneratedPositionsFor'.
|
||||
const genPos = map.generatedPositionFor({
|
||||
source: urlsById.get(location.sourceId),
|
||||
source: originalSource.url,
|
||||
line: location.line,
|
||||
column: location.column == null ? 0 : location.column,
|
||||
bias: SourceMapConsumer.GREATEST_LOWER_BOUND,
|
||||
|
@ -199,21 +188,21 @@ async function getGeneratedRanges(
|
|||
}
|
||||
|
||||
async function getGeneratedLocation(
|
||||
location: SourceLocation
|
||||
location: SourceLocation,
|
||||
originalSource: Source
|
||||
): Promise<SourceLocation> {
|
||||
if (!isOriginalId(location.sourceId)) {
|
||||
return location;
|
||||
}
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(location.sourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
if (!data) {
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
if (!map) {
|
||||
return location;
|
||||
}
|
||||
const { urlsById, map } = data;
|
||||
|
||||
const positions = map.allGeneratedPositionsFor({
|
||||
source: urlsById.get(location.sourceId),
|
||||
source: originalSource.url,
|
||||
line: location.line,
|
||||
column: location.column == null ? 0 : location.column,
|
||||
});
|
||||
|
@ -231,7 +220,7 @@ async function getGeneratedLocation(
|
|||
|
||||
if (!match) {
|
||||
match = map.generatedPositionFor({
|
||||
source: urlsById.get(location.sourceId),
|
||||
source: originalSource.url,
|
||||
line: location.line,
|
||||
column: location.column == null ? 0 : location.column,
|
||||
bias: SourceMapConsumer.LEAST_UPPER_BOUND,
|
||||
|
@ -246,21 +235,21 @@ async function getGeneratedLocation(
|
|||
}
|
||||
|
||||
async function getAllGeneratedLocations(
|
||||
location: SourceLocation
|
||||
location: SourceLocation,
|
||||
originalSource: Source
|
||||
): Promise<Array<SourceLocation>> {
|
||||
if (!isOriginalId(location.sourceId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(location.sourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
if (!data) {
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
if (!map) {
|
||||
return [];
|
||||
}
|
||||
const { urlsById, map } = data;
|
||||
|
||||
const positions = map.allGeneratedPositionsFor({
|
||||
source: urlsById.get(location.sourceId),
|
||||
source: originalSource.url,
|
||||
line: location.line,
|
||||
column: location.column == null ? 0 : location.column,
|
||||
});
|
||||
|
@ -273,24 +262,22 @@ async function getAllGeneratedLocations(
|
|||
}
|
||||
|
||||
async function getOriginalLocations(
|
||||
sourceId: string,
|
||||
locations: SourceLocation[],
|
||||
options: LocationOptions = {}
|
||||
): Promise<SourceLocation[]> {
|
||||
const maps = {};
|
||||
|
||||
const results = [];
|
||||
for (const location of locations) {
|
||||
let map = maps[location.sourceId];
|
||||
if (map === undefined) {
|
||||
map = await getSourceMap(location.sourceId);
|
||||
maps[location.sourceId] = map || null;
|
||||
}
|
||||
|
||||
results.push(
|
||||
map ? getOriginalLocationSync(map, location, options) : location
|
||||
);
|
||||
if (locations.some(location => location.sourceId != sourceId)) {
|
||||
throw new Error("Generated locations must belong to the same source");
|
||||
}
|
||||
return results;
|
||||
|
||||
const map = await getSourceMap(sourceId);
|
||||
if (!map) {
|
||||
return locations;
|
||||
}
|
||||
|
||||
return locations.map(location =>
|
||||
getOriginalLocationSync(map, location, options)
|
||||
);
|
||||
}
|
||||
|
||||
function getOriginalLocationSync(
|
||||
|
@ -353,42 +340,28 @@ async function getOriginalLocation(
|
|||
}
|
||||
|
||||
async function getOriginalSourceText(
|
||||
originalSourceId: SourceId
|
||||
originalSource: Source
|
||||
): Promise<?{
|
||||
text: string,
|
||||
contentType: string,
|
||||
}> {
|
||||
assert(isOriginalId(originalSourceId), "Source is not an original source");
|
||||
assert(isOriginalId(originalSource.id), "Source is not an original source");
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(originalSourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
if (!data) {
|
||||
const generatedSourceId = originalToGeneratedId(originalSource.id);
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
if (!map) {
|
||||
return null;
|
||||
}
|
||||
const { urlsById, map } = data;
|
||||
|
||||
const url = urlsById.get(originalSourceId);
|
||||
let text = map.sourceContentFor(url);
|
||||
let text = map.sourceContentFor(originalSource.url);
|
||||
if (!text) {
|
||||
try {
|
||||
const response = await networkRequest(url, {
|
||||
loadFromCache: false,
|
||||
});
|
||||
text = response.content;
|
||||
} catch (err) {
|
||||
// Wrapper logic renders a notification about the specific URL that
|
||||
// failed to load, so we include it in the error metadata.
|
||||
err.metadata = {
|
||||
...err.metadata,
|
||||
url,
|
||||
};
|
||||
throw err;
|
||||
}
|
||||
text = (await networkRequest(originalSource.url, { loadFromCache: false }))
|
||||
.content;
|
||||
}
|
||||
|
||||
return {
|
||||
text,
|
||||
contentType: getContentType(url || ""),
|
||||
contentType: getContentType(originalSource.url || ""),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -407,17 +380,17 @@ async function getOriginalSourceText(
|
|||
const GENERATED_MAPPINGS = new WeakMap();
|
||||
async function getGeneratedRangesForOriginal(
|
||||
sourceId: SourceId,
|
||||
url: string,
|
||||
mergeUnmappedRegions: boolean = false
|
||||
): Promise<Range[]> {
|
||||
assert(isOriginalId(sourceId), "Source is not an original source");
|
||||
|
||||
const data = await getSourceMapWithMetadata(originalToGeneratedId(sourceId));
|
||||
const map = await getSourceMap(originalToGeneratedId(sourceId));
|
||||
|
||||
// NOTE: this is only needed for Flow
|
||||
if (!data) {
|
||||
if (!map) {
|
||||
return [];
|
||||
}
|
||||
const { urlsById, map } = data;
|
||||
const url = urlsById.get(sourceId);
|
||||
|
||||
if (!COMPUTED_SPANS.has(map)) {
|
||||
COMPUTED_SPANS.add(map);
|
||||
|
@ -535,27 +508,24 @@ function wrappedMappingPosition(pos: {
|
|||
}
|
||||
|
||||
async function getFileGeneratedRange(
|
||||
originalSourceId: SourceId
|
||||
originalSource: Source
|
||||
): Promise<?{ start: any, end: any }> {
|
||||
assert(isOriginalId(originalSourceId), "Source is not an original source");
|
||||
assert(isOriginalId(originalSource.id), "Source is not an original source");
|
||||
|
||||
const data = await getSourceMapWithMetadata(
|
||||
originalToGeneratedId(originalSourceId)
|
||||
);
|
||||
if (!data) {
|
||||
const map = await getSourceMap(originalToGeneratedId(originalSource.id));
|
||||
if (!map) {
|
||||
return;
|
||||
}
|
||||
const { urlsById, map } = data;
|
||||
|
||||
const start = map.generatedPositionFor({
|
||||
source: urlsById.get(originalSourceId),
|
||||
source: originalSource.url,
|
||||
line: 1,
|
||||
column: 0,
|
||||
bias: SourceMapConsumer.LEAST_UPPER_BOUND,
|
||||
});
|
||||
|
||||
const end = map.generatedPositionFor({
|
||||
source: urlsById.get(originalSourceId),
|
||||
source: originalSource.url,
|
||||
line: Number.MAX_SAFE_INTEGER,
|
||||
column: Number.MAX_SAFE_INTEGER,
|
||||
bias: SourceMapConsumer.GREATEST_LOWER_BOUND,
|
||||
|
@ -567,6 +537,15 @@ async function getFileGeneratedRange(
|
|||
};
|
||||
}
|
||||
|
||||
async function hasMappedSource(location: SourceLocation): Promise<boolean> {
|
||||
if (isOriginalId(location.sourceId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const loc = await getOriginalLocation(location);
|
||||
return loc.sourceId !== location.sourceId;
|
||||
}
|
||||
|
||||
function applySourceMap(
|
||||
generatedId: string,
|
||||
url: string,
|
||||
|
@ -601,4 +580,5 @@ module.exports = {
|
|||
getFileGeneratedRange,
|
||||
applySourceMap,
|
||||
clearSourceMaps,
|
||||
hasMappedSource,
|
||||
};
|
||||
|
|
|
@ -23,7 +23,7 @@ function getMap(_path) {
|
|||
return fs.readFileSync(mapPath, "utf8");
|
||||
}
|
||||
|
||||
async function setupBundleFixtureAndData(name) {
|
||||
async function setupBundleFixture(name) {
|
||||
const source = {
|
||||
id: `${name}.js`,
|
||||
sourceMapURL: `${name}.js.map`,
|
||||
|
@ -37,16 +37,10 @@ async function setupBundleFixtureAndData(name) {
|
|||
|
||||
return getOriginalURLs(source);
|
||||
}
|
||||
async function setupBundleFixture(name) {
|
||||
const data = await setupBundleFixtureAndData(name);
|
||||
|
||||
return data.map(item => item.url);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
formatLocations,
|
||||
formatLocation,
|
||||
setupBundleFixture,
|
||||
setupBundleFixtureAndData,
|
||||
getMap,
|
||||
};
|
||||
|
|
|
@ -7,12 +7,13 @@ const networkRequest = require("devtools-utils/src/network-request");
|
|||
|
||||
const {
|
||||
getOriginalURLs,
|
||||
hasMappedSource,
|
||||
getOriginalLocation,
|
||||
getGeneratedRangesForOriginal,
|
||||
clearSourceMaps,
|
||||
} = require("../source-map");
|
||||
|
||||
const { setupBundleFixture, setupBundleFixtureAndData } = require("./helpers");
|
||||
const { setupBundleFixture } = require("./helpers");
|
||||
|
||||
describe("source maps", () => {
|
||||
beforeEach(() => {
|
||||
|
@ -53,9 +54,12 @@ describe("source maps", () => {
|
|||
|
||||
describe("getGeneratedRangesForOriginal", () => {
|
||||
test("the overall generated ranges on the source", async () => {
|
||||
const data = await setupBundleFixtureAndData("intermingled-sources");
|
||||
const urls = await setupBundleFixture("intermingled-sources");
|
||||
|
||||
const ranges = await getGeneratedRangesForOriginal(data[0].id);
|
||||
const ranges = await getGeneratedRangesForOriginal(
|
||||
"intermingled-sources.js/originalSource-01",
|
||||
urls[0]
|
||||
);
|
||||
|
||||
expect(ranges).toEqual([
|
||||
{
|
||||
|
@ -112,9 +116,13 @@ describe("source maps", () => {
|
|||
});
|
||||
|
||||
test("the merged generated ranges on the source", async () => {
|
||||
const data = await setupBundleFixtureAndData("intermingled-sources");
|
||||
const urls = await setupBundleFixture("intermingled-sources");
|
||||
|
||||
const ranges = await getGeneratedRangesForOriginal(data[0].id, true);
|
||||
const ranges = await getGeneratedRangesForOriginal(
|
||||
"intermingled-sources.js/originalSource-01",
|
||||
urls[0],
|
||||
true
|
||||
);
|
||||
|
||||
expect(ranges).toEqual([
|
||||
{
|
||||
|
@ -131,6 +139,27 @@ describe("source maps", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("hasMappedSource", () => {
|
||||
test("has original location", async () => {
|
||||
await setupBundleFixture("bundle");
|
||||
const location = {
|
||||
sourceId: "bundle.js",
|
||||
line: 49,
|
||||
};
|
||||
const isMapped = await hasMappedSource(location);
|
||||
expect(isMapped).toBe(true);
|
||||
});
|
||||
|
||||
test("does not have original location", async () => {
|
||||
const location = {
|
||||
sourceId: "bundle.js",
|
||||
line: 94,
|
||||
};
|
||||
const isMapped = await hasMappedSource(location);
|
||||
expect(isMapped).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Error handling", () => {
|
||||
test("missing map", async () => {
|
||||
const source = {
|
||||
|
|
|
@ -110,12 +110,7 @@ describe("wasm source maps", () => {
|
|||
const { getOriginalURLs, getOriginalLocation } = require("../source-map");
|
||||
|
||||
const urls = await getOriginalURLs(source);
|
||||
expect(urls).toEqual([
|
||||
{
|
||||
id: "min.js/originalSource-2133f6ef6d6c464acad221082f398cf0",
|
||||
url: "http://example.com/whatever/one.js",
|
||||
},
|
||||
]);
|
||||
expect(urls).toEqual(["http://example.com/whatever/one.js"]);
|
||||
|
||||
const { line, column } = await getOriginalLocation({
|
||||
sourceId: source.id,
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
// @flow
|
||||
|
||||
import type { SourceMapInput } from "../source-map";
|
||||
|
||||
const { networkRequest } = require("devtools-utils");
|
||||
const { getSourceMap, setSourceMap } = require("./sourceMapRequests");
|
||||
const { WasmRemap } = require("./wasmRemap");
|
||||
|
@ -13,6 +11,8 @@ const { SourceMapConsumer } = require("source-map");
|
|||
const { convertToJSON } = require("devtools-wasm-dwarf");
|
||||
const { createConsumer } = require("./createConsumer");
|
||||
|
||||
import type { Source } from "debugger-html";
|
||||
|
||||
// URLs which have been seen in a completed source map request.
|
||||
const originalURLs = new Set();
|
||||
|
||||
|
@ -24,7 +24,7 @@ function hasOriginalURL(url: string): boolean {
|
|||
return originalURLs.has(url);
|
||||
}
|
||||
|
||||
function _resolveSourceMapURL(source: SourceMapInput) {
|
||||
function _resolveSourceMapURL(source: Source) {
|
||||
const { url = "", sourceMapURL = "" } = source;
|
||||
|
||||
if (!url) {
|
||||
|
@ -45,9 +45,7 @@ function _resolveSourceMapURL(source: SourceMapInput) {
|
|||
return { sourceMapURL: resolvedString, baseURL };
|
||||
}
|
||||
|
||||
async function _resolveAndFetch(
|
||||
generatedSource: SourceMapInput
|
||||
): SourceMapConsumer {
|
||||
async function _resolveAndFetch(generatedSource: Source): SourceMapConsumer {
|
||||
// Fetch the sourcemap over the network and create it.
|
||||
const { sourceMapURL, baseURL } = _resolveSourceMapURL(generatedSource);
|
||||
|
||||
|
@ -75,7 +73,7 @@ async function _resolveAndFetch(
|
|||
return map;
|
||||
}
|
||||
|
||||
function fetchSourceMap(generatedSource: SourceMapInput): SourceMapConsumer {
|
||||
function fetchSourceMap(generatedSource: Source): SourceMapConsumer {
|
||||
const existingRequest = getSourceMap(generatedSource.id);
|
||||
|
||||
// If it has already been requested, return the request. Make sure
|
||||
|
|
|
@ -2,58 +2,22 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
const { generatedToOriginalId } = require(".");
|
||||
|
||||
const sourceMapRequests = new Map();
|
||||
|
||||
function clearSourceMaps() {
|
||||
sourceMapRequests.clear();
|
||||
}
|
||||
|
||||
function getSourceMapWithMetadata(
|
||||
generatedSourceId: string
|
||||
): ?Promise<?{
|
||||
map: SourceMapConsumer,
|
||||
urlsById: Map<SourceId, url>,
|
||||
sources: Array<{ id: SourceId, url: string }>,
|
||||
}> {
|
||||
function getSourceMap(generatedSourceId: string): ?Promise<SourceMapConsumer> {
|
||||
return sourceMapRequests.get(generatedSourceId);
|
||||
}
|
||||
|
||||
function getSourceMap(generatedSourceId: string): ?Promise<?SourceMapConsumer> {
|
||||
const request = getSourceMapWithMetadata(generatedSourceId);
|
||||
if (!request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return request.then(result => (result ? result.map : null));
|
||||
}
|
||||
|
||||
function setSourceMap(generatedId: string, request) {
|
||||
sourceMapRequests.set(
|
||||
generatedId,
|
||||
request.then(map => {
|
||||
if (!map || !map.sources) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const urlsById = new Map();
|
||||
const sources = [];
|
||||
|
||||
for (const url of map.sources) {
|
||||
const id = generatedToOriginalId(generatedId, url);
|
||||
|
||||
urlsById.set(id, url);
|
||||
sources.push({ id, url });
|
||||
}
|
||||
return { map, urlsById, sources };
|
||||
})
|
||||
);
|
||||
function setSourceMap(generatedId, request) {
|
||||
sourceMapRequests.set(generatedId, request);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
clearSourceMaps,
|
||||
getSourceMapWithMetadata,
|
||||
getSourceMap,
|
||||
setSourceMap,
|
||||
};
|
||||
|
|
|
@ -15,6 +15,7 @@ const {
|
|||
getOriginalSourceText,
|
||||
getGeneratedRangesForOriginal,
|
||||
getFileGeneratedRange,
|
||||
hasMappedSource,
|
||||
clearSourceMaps,
|
||||
applySourceMap,
|
||||
} = require("./source-map");
|
||||
|
@ -42,6 +43,7 @@ self.onmessage = workerHandler({
|
|||
getOriginalStackFrames,
|
||||
getGeneratedRangesForOriginal,
|
||||
getFileGeneratedRange,
|
||||
hasMappedSource,
|
||||
applySourceMap,
|
||||
clearSourceMaps,
|
||||
});
|
||||
|
|
|
@ -114,9 +114,7 @@ describe("worker utils", () => {
|
|||
id: 53,
|
||||
results: [
|
||||
{
|
||||
error: true,
|
||||
message: "failed",
|
||||
metadata: undefined,
|
||||
error: "Error: failed",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -83,9 +83,7 @@ WorkerDispatcher.prototype = {
|
|||
const [, resolve, reject] = items[i];
|
||||
|
||||
if (resultData.error) {
|
||||
const err = new Error(resultData.message);
|
||||
(err: any).metadata = resultData.metadata;
|
||||
reject(err);
|
||||
reject(resultData.error);
|
||||
} else {
|
||||
resolve(resultData.response);
|
||||
}
|
||||
|
@ -114,12 +112,16 @@ function workerHandler(publicInterface: Object) {
|
|||
if (response instanceof Promise) {
|
||||
return response.then(
|
||||
val => ({ response: val }),
|
||||
err => asErrorMessage(err)
|
||||
// Error can't be sent via postMessage, so be sure to
|
||||
// convert to string.
|
||||
err => ({ error: err.toString() })
|
||||
);
|
||||
}
|
||||
return { response };
|
||||
} catch (error) {
|
||||
return asErrorMessage(error);
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return { error: error.toString() };
|
||||
}
|
||||
})
|
||||
).then(results => {
|
||||
|
@ -128,24 +130,6 @@ function workerHandler(publicInterface: Object) {
|
|||
};
|
||||
}
|
||||
|
||||
function asErrorMessage(error) {
|
||||
if (typeof error === "object" && error && "message" in error) {
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: true,
|
||||
message: error.message,
|
||||
metadata: error.metadata,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
error: true,
|
||||
message: error == null ? error : error.toString(),
|
||||
metadata: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WorkerDispatcher,
|
||||
workerHandler,
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// @flow
|
||||
|
||||
const { convertToJSON } = require("./src/convertToJSON");
|
||||
const { setAssetRootURL } = require("./src/wasmAsset");
|
||||
const { getWasmXScopes, clearWasmXScopes } = require("./src/wasmXScopes");
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
// @flow
|
||||
|
||||
/* eslint camelcase: 0*/
|
||||
|
||||
|
|
|
@ -43,7 +43,10 @@ async function mapLocations(
|
|||
return [];
|
||||
}
|
||||
|
||||
const { sourceId } = generatedLocations[0];
|
||||
|
||||
const originalLocations = await sourceMaps.getOriginalLocations(
|
||||
sourceId,
|
||||
generatedLocations
|
||||
);
|
||||
|
||||
|
@ -117,6 +120,7 @@ async function _setBreakpointPositions(cx, sourceId, line, thunkArgs) {
|
|||
// https://github.com/facebook/flow/issues/5294
|
||||
const ranges: Range[] = await sourceMaps.getGeneratedRangesForOriginal(
|
||||
sourceId,
|
||||
generatedSource.url,
|
||||
true
|
||||
);
|
||||
const generatedSourceId = originalToGeneratedId(sourceId);
|
||||
|
|
|
@ -44,6 +44,7 @@ Array [
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "/examples/a",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://localhost:8000/examples/a",
|
||||
},
|
||||
},
|
||||
|
@ -126,6 +127,7 @@ Array [
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "/examples/a",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://localhost:8000/examples/a",
|
||||
},
|
||||
},
|
||||
|
|
|
@ -36,7 +36,7 @@ export function toggleBlackBox(cx: Context, source: Source) {
|
|||
|
||||
let sourceId, range;
|
||||
if (features.originalBlackbox && isOriginalId(source.id)) {
|
||||
range = await sourceMaps.getFileGeneratedRange(source.id);
|
||||
range = await sourceMaps.getFileGeneratedRange(source);
|
||||
sourceId = originalToGeneratedId(source.id);
|
||||
} else {
|
||||
sourceId = source.id;
|
||||
|
|
|
@ -63,7 +63,7 @@ async function loadSource(
|
|||
}
|
||||
|
||||
if (isOriginal(source)) {
|
||||
const result = await sourceMaps.getOriginalSourceText(source.id);
|
||||
const result = await sourceMaps.getOriginalSourceText(source);
|
||||
if (!result) {
|
||||
// The way we currently try to load and select a pending
|
||||
// selected location, it is possible that we will try to fetch the
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* @module actions/sources
|
||||
*/
|
||||
|
||||
import { generatedToOriginalId } from "devtools-source-map";
|
||||
import { flatten } from "lodash";
|
||||
|
||||
import {
|
||||
|
@ -25,6 +26,7 @@ import { selectLocation, setBreakableLines } from "../sources";
|
|||
import {
|
||||
getRawSourceURL,
|
||||
isPrettyURL,
|
||||
isOriginal,
|
||||
isUrlExtension,
|
||||
isInlineScript,
|
||||
} from "../../utils/source";
|
||||
|
@ -33,7 +35,6 @@ import {
|
|||
getSource,
|
||||
getSourceFromId,
|
||||
hasSourceActor,
|
||||
getSourceByActorId,
|
||||
getPendingSelectedLocation,
|
||||
getPendingBreakpointsForSource,
|
||||
getContext,
|
||||
|
@ -46,6 +47,7 @@ import { validateNavigateContext, ContextError } from "../../utils/context";
|
|||
|
||||
import type {
|
||||
Source,
|
||||
SourceId,
|
||||
Context,
|
||||
OriginalSourceData,
|
||||
GeneratedSourceData,
|
||||
|
@ -53,17 +55,15 @@ import type {
|
|||
} from "../../types";
|
||||
import type { Action, ThunkArgs } from "../types";
|
||||
|
||||
function loadSourceMaps(cx: Context, sources: SourceActor[]) {
|
||||
function loadSourceMaps(cx: Context, sources: Source[]) {
|
||||
return async function({
|
||||
dispatch,
|
||||
sourceMaps,
|
||||
}: ThunkArgs): Promise<?(Promise<Source>[])> {
|
||||
try {
|
||||
const sourceList = await Promise.all(
|
||||
sources.map(async sourceActor => {
|
||||
const originalSources = await dispatch(
|
||||
loadSourceMap(cx, sourceActor)
|
||||
);
|
||||
sources.map(async ({ id }) => {
|
||||
const originalSources = await dispatch(loadSourceMap(cx, id));
|
||||
sourceQueue.queueSources(
|
||||
originalSources.map(data => ({
|
||||
type: "original",
|
||||
|
@ -76,6 +76,13 @@ function loadSourceMaps(cx: Context, sources: SourceActor[]) {
|
|||
|
||||
await sourceQueue.flush();
|
||||
|
||||
// We would like to sync breakpoints after we are done
|
||||
// loading source maps as sometimes generated and original
|
||||
// files share the same paths.
|
||||
for (const source of sources) {
|
||||
dispatch(checkPendingBreakpoints(cx, source.id));
|
||||
}
|
||||
|
||||
return flatten(sourceList);
|
||||
} catch (error) {
|
||||
if (!(error instanceof ContextError)) {
|
||||
|
@ -89,61 +96,58 @@ function loadSourceMaps(cx: Context, sources: SourceActor[]) {
|
|||
* @memberof actions/sources
|
||||
* @static
|
||||
*/
|
||||
function loadSourceMap(cx: Context, sourceActor: SourceActor) {
|
||||
function loadSourceMap(cx: Context, sourceId: SourceId) {
|
||||
return async function({
|
||||
dispatch,
|
||||
getState,
|
||||
sourceMaps,
|
||||
}: ThunkArgs): Promise<OriginalSourceData[]> {
|
||||
if (!prefs.clientSourceMapsEnabled || !sourceActor.sourceMapURL) {
|
||||
}: ThunkArgs): Promise<Source[]> {
|
||||
const source = getSource(getState(), sourceId);
|
||||
|
||||
if (
|
||||
!prefs.clientSourceMapsEnabled ||
|
||||
!source ||
|
||||
isOriginal(source) ||
|
||||
!source.sourceMapURL
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let data = null;
|
||||
let urls = null;
|
||||
try {
|
||||
// Unable to correctly type the result of a spread on a union type.
|
||||
// See https://github.com/facebook/flow/pull/7298
|
||||
let url = sourceActor.url || "";
|
||||
if (!sourceActor.url && typeof sourceActor.introductionUrl === "string") {
|
||||
const urlInfo: Source = { ...(source: any) };
|
||||
if (!urlInfo.url && typeof urlInfo.introductionUrl === "string") {
|
||||
// If the source was dynamically generated (via eval, dynamically
|
||||
// created script elements, and so forth), it won't have a URL, so that
|
||||
// it is not collapsed into other sources from the same place. The
|
||||
// introduction URL will include the point it was constructed at,
|
||||
// however, so use that for resolving any source maps in the source.
|
||||
url = sourceActor.introductionUrl;
|
||||
}
|
||||
|
||||
// Ignore sourceMapURL on scripts that are part of HTML files, since
|
||||
// we currently treat sourcemaps as Source-wide, not SourceActor-specific.
|
||||
const source = getSourceByActorId(getState(), sourceActor.id);
|
||||
if (source) {
|
||||
data = await sourceMaps.getOriginalURLs({
|
||||
// Using source ID here is historical and eventually we'll want to
|
||||
// switch to all of this being per-source-actor.
|
||||
id: source.id,
|
||||
url,
|
||||
sourceMapURL: sourceActor.sourceMapURL || "",
|
||||
isWasm: sourceActor.introductionType === "wasm",
|
||||
});
|
||||
(urlInfo: any).url = urlInfo.introductionUrl;
|
||||
}
|
||||
urls = await sourceMaps.getOriginalURLs(urlInfo);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (!urls) {
|
||||
// If this source doesn't have a sourcemap, enable it for pretty printing
|
||||
dispatch(
|
||||
({
|
||||
type: "CLEAR_SOURCE_ACTOR_MAP_URL",
|
||||
type: "CLEAR_SOURCE_MAP_URL",
|
||||
cx,
|
||||
id: sourceActor.id,
|
||||
sourceId,
|
||||
}: Action)
|
||||
);
|
||||
return [];
|
||||
}
|
||||
|
||||
validateNavigateContext(getState(), cx);
|
||||
return data;
|
||||
return urls.map(url => ({
|
||||
id: generatedToOriginalId(source.id, url),
|
||||
url,
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -268,10 +272,6 @@ export function newOriginalSources(sourceInfo: Array<OriginalSourceData>) {
|
|||
|
||||
await dispatch(checkNewSources(cx, sources));
|
||||
|
||||
for (const source of sources) {
|
||||
dispatch(checkPendingBreakpoints(cx, source.id));
|
||||
}
|
||||
|
||||
return sources;
|
||||
};
|
||||
}
|
||||
|
@ -298,18 +298,19 @@ export function newGeneratedSources(sourceInfo: Array<GeneratedSourceData>) {
|
|||
const newId = id || makeSourceId(source);
|
||||
|
||||
if (!getSource(getState(), newId) && !newSourcesObj[newId]) {
|
||||
newSourcesObj[newId] = {
|
||||
newSourcesObj[newId] = ({
|
||||
id: newId,
|
||||
url: source.url,
|
||||
relativeUrl: source.url,
|
||||
isPrettyPrinted: false,
|
||||
extensionName: source.extensionName,
|
||||
sourceMapURL: source.sourceMapURL,
|
||||
introductionUrl: source.introductionUrl,
|
||||
introductionType: source.introductionType,
|
||||
isBlackBoxed: false,
|
||||
isWasm: !!supportsWasm && source.introductionType === "wasm",
|
||||
isExtension: (source.url && isUrlExtension(source.url)) || false,
|
||||
};
|
||||
}: any);
|
||||
}
|
||||
|
||||
const actorId = stringToSourceActorId(source.actor);
|
||||
|
@ -355,17 +356,6 @@ export function newGeneratedSources(sourceInfo: Array<GeneratedSourceData>) {
|
|||
}
|
||||
await dispatch(checkNewSources(cx, newSources));
|
||||
|
||||
(async () => {
|
||||
await dispatch(loadSourceMaps(cx, newSourceActors));
|
||||
|
||||
// We would like to sync breakpoints after we are done
|
||||
// loading source maps as sometimes generated and original
|
||||
// files share the same paths.
|
||||
for (const source of newSources) {
|
||||
dispatch(checkPendingBreakpoints(cx, source.id));
|
||||
}
|
||||
})();
|
||||
|
||||
return resultIds.map(id => getSourceFromId(getState(), id));
|
||||
};
|
||||
}
|
||||
|
@ -383,6 +373,7 @@ function checkNewSources(cx, sources: Source[]) {
|
|||
}
|
||||
|
||||
dispatch(restoreBlackBoxedSources(cx, sources));
|
||||
dispatch(loadSourceMaps(cx, sources));
|
||||
|
||||
return sources;
|
||||
};
|
||||
|
|
|
@ -16,12 +16,13 @@ import { getSourcesForTabs } from "../../reducers/tabs";
|
|||
import { setSymbols } from "./symbols";
|
||||
import { setInScopeLines } from "../ast";
|
||||
import { closeActiveSearch, updateActiveFileSearch } from "../ui";
|
||||
import { isFulfilled } from "../../utils/async-value";
|
||||
import { togglePrettyPrint } from "./prettyPrint";
|
||||
import { addTab, closeTab } from "../tabs";
|
||||
import { loadSourceText } from "./loadSourceText";
|
||||
|
||||
import { prefs } from "../../utils/prefs";
|
||||
import { isMinified } from "../../utils/source";
|
||||
import { shouldPrettyPrint, isMinified } from "../../utils/source";
|
||||
import { createLocation } from "../../utils/location";
|
||||
import { mapLocation } from "../../utils/source-maps";
|
||||
|
||||
|
@ -32,7 +33,6 @@ import {
|
|||
getActiveSearch,
|
||||
getSelectedLocation,
|
||||
getSelectedSource,
|
||||
canPrettyPrintSource,
|
||||
} from "../../selectors";
|
||||
|
||||
import type {
|
||||
|
@ -169,12 +169,19 @@ export function selectLocation(
|
|||
return;
|
||||
}
|
||||
const sourceWithContent = getSourceWithContent(getState(), source.id);
|
||||
const sourceContent =
|
||||
sourceWithContent.content && isFulfilled(sourceWithContent.content)
|
||||
? sourceWithContent.content.value
|
||||
: null;
|
||||
|
||||
if (
|
||||
keepContext &&
|
||||
prefs.autoPrettyPrint &&
|
||||
!getPrettySource(getState(), loadedSource.id) &&
|
||||
canPrettyPrintSource(getState(), loadedSource.id) &&
|
||||
shouldPrettyPrint(
|
||||
loadedSource,
|
||||
sourceContent || { type: "text", value: "", contentType: undefined }
|
||||
) &&
|
||||
isMinified(sourceWithContent)
|
||||
) {
|
||||
await dispatch(togglePrettyPrint(cx, loadedSource.id));
|
||||
|
|
|
@ -69,7 +69,7 @@ describe("loadSourceText", () => {
|
|||
getGeneratedRangesForOriginal: async () => [
|
||||
{ start: { line: 1, column: 0 }, end: { line: 1, column: 1 } },
|
||||
],
|
||||
getOriginalLocations: async items =>
|
||||
getOriginalLocations: async (sourceId, items) =>
|
||||
items.map(item => ({
|
||||
...item,
|
||||
sourceId:
|
||||
|
|
|
@ -19,7 +19,6 @@ const {
|
|||
getSourceByURL,
|
||||
} = selectors;
|
||||
import sourceQueue from "../../../utils/source-queue";
|
||||
import { generatedToOriginalId } from "devtools-source-map";
|
||||
|
||||
import { mockCommandClient } from "../../tests/helpers/mockCommandClient";
|
||||
|
||||
|
@ -64,12 +63,7 @@ describe("sources - new sources", () => {
|
|||
mockCommandClient,
|
||||
{},
|
||||
{
|
||||
getOriginalURLs: async source => [
|
||||
{
|
||||
id: generatedToOriginalId(source.id, "magic.js"),
|
||||
url: "magic.js",
|
||||
},
|
||||
],
|
||||
getOriginalURLs: async () => ["magic.js"],
|
||||
getOriginalLocations: async items => items,
|
||||
}
|
||||
);
|
||||
|
@ -130,13 +124,8 @@ describe("sources - new sources", () => {
|
|||
// simulate a hang loading foo.js.map
|
||||
return new Promise(_ => {});
|
||||
}
|
||||
const url = source.id.replace(".js", ".cljs");
|
||||
return [
|
||||
{
|
||||
id: generatedToOriginalId(source.id, url),
|
||||
url: url,
|
||||
},
|
||||
];
|
||||
|
||||
return [source.id.replace(".js", ".cljs")];
|
||||
},
|
||||
getOriginalLocations: async items => items,
|
||||
getGeneratedLocation: location => location,
|
||||
|
|
|
@ -31,7 +31,7 @@ const mockCommandClient = {
|
|||
};
|
||||
|
||||
const sourceMaps = {
|
||||
getOriginalSourceText: async id => ({
|
||||
getOriginalSourceText: async ({ id }) => ({
|
||||
id,
|
||||
text: sourceTexts[id],
|
||||
contentType: "text/javascript",
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
} from "./helpers/breakpoints.js";
|
||||
|
||||
import { mockCommandClient } from "./helpers/mockCommandClient";
|
||||
|
||||
import { asyncStore } from "../../utils/prefs";
|
||||
|
||||
function loadInitialState(opts = {}) {
|
||||
|
@ -56,15 +57,15 @@ function mockClient(bpPos = {}) {
|
|||
function mockSourceMaps() {
|
||||
return {
|
||||
...sourceMaps,
|
||||
getOriginalSourceText: async id => ({
|
||||
id,
|
||||
getOriginalSourceText: async source => ({
|
||||
id: source.id,
|
||||
text: "",
|
||||
contentType: "text/javascript",
|
||||
}),
|
||||
getGeneratedRangesForOriginal: async () => [
|
||||
{ start: { line: 0, column: 0 }, end: { line: 10, column: 10 } },
|
||||
],
|
||||
getOriginalLocations: async items => items,
|
||||
getOriginalLocations: async (sourceId, items) => items,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -375,27 +376,18 @@ describe("adding sources", () => {
|
|||
it("corresponding breakpoints are added to the original source", async () => {
|
||||
const sourceURL = makeSourceURL("bar.js");
|
||||
const store = createStore(mockClient({ "5": [2] }), loadInitialState(), {
|
||||
getOriginalURLs: async source => [
|
||||
{
|
||||
id: sourceMaps.generatedToOriginalId(source.id, sourceURL),
|
||||
url: sourceURL,
|
||||
},
|
||||
],
|
||||
getOriginalSourceText: async () => ({ text: "" }),
|
||||
getGeneratedLocation: async location => ({
|
||||
getOriginalURLs: async () => [sourceURL],
|
||||
getOriginalSourceText: async () => ({ source: "" }),
|
||||
getGeneratedLocation: async (location, _source) => ({
|
||||
line: location.line,
|
||||
column: location.column,
|
||||
sourceId: location.sourceId,
|
||||
sourceId: _source.id,
|
||||
}),
|
||||
getOriginalLocation: async location => location,
|
||||
getGeneratedRangesForOriginal: async () => [
|
||||
{ start: { line: 0, column: 0 }, end: { line: 10, column: 10 } },
|
||||
],
|
||||
getOriginalLocations: async items =>
|
||||
items.map(item => ({
|
||||
...item,
|
||||
sourceId: sourceMaps.generatedToOriginalId(item.sourceId, sourceURL),
|
||||
})),
|
||||
getOriginalLocations: async (sourceId, items) => items,
|
||||
});
|
||||
|
||||
const { getState, dispatch } = store;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
// @flow
|
||||
|
||||
import type { Source, SourceLocation, Context } from "../../types";
|
||||
import type { SourceId, Source, SourceLocation, Context } from "../../types";
|
||||
import type { PromiseAction } from "../utils/middleware/promise";
|
||||
import type { SourceBase } from "../../reducers/sources";
|
||||
|
||||
|
@ -32,6 +32,11 @@ export type SourceAction =
|
|||
+cx: Context,
|
||||
+sources: Array<SourceBase>,
|
||||
|}
|
||||
| {|
|
||||
+type: "CLEAR_SOURCE_MAP_URL",
|
||||
+cx: Context,
|
||||
+sourceId: SourceId,
|
||||
|}
|
||||
| {|
|
||||
+type: "SET_SELECTED_LOCATION",
|
||||
+cx: Context,
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
// @flow
|
||||
|
||||
import type { Context } from "../../types";
|
||||
import { type PromiseAction } from "../utils/middleware/promise";
|
||||
import type {
|
||||
SourceActorId,
|
||||
|
@ -19,11 +18,6 @@ export type SourceActorsRemoveAction = {|
|
|||
type: "REMOVE_SOURCE_ACTORS",
|
||||
items: Array<SourceActor>,
|
||||
|};
|
||||
export type SourceActorClearMapAction = {|
|
||||
+type: "CLEAR_SOURCE_ACTOR_MAP_URL",
|
||||
+cx: Context,
|
||||
+id: SourceActorId,
|
||||
|};
|
||||
|
||||
export type SourceActorBreakpointColumnsAction = PromiseAction<
|
||||
{|
|
||||
|
@ -46,5 +40,4 @@ export type SourceActorAction =
|
|||
| SourceActorsInsertAction
|
||||
| SourceActorsRemoveAction
|
||||
| SourceActorBreakpointColumnsAction
|
||||
| SourceActorBreakableLinesAction
|
||||
| SourceActorClearMapAction;
|
||||
| SourceActorBreakableLinesAction;
|
||||
|
|
|
@ -7,16 +7,13 @@
|
|||
import { Component } from "react";
|
||||
import { connect } from "../../utils/connect";
|
||||
import { showMenu } from "devtools-contextmenu";
|
||||
import { isOriginalId } from "devtools-source-map";
|
||||
|
||||
import { getSourceLocationFromMouseEvent } from "../../utils/editor";
|
||||
import { isPretty } from "../../utils/source";
|
||||
import {
|
||||
getPrettySource,
|
||||
getIsPaused,
|
||||
getCurrentThread,
|
||||
getThreadContext,
|
||||
isSourceWithMap,
|
||||
} from "../../selectors";
|
||||
|
||||
import { editorMenuItems, editorItemActions } from "./menus/editor";
|
||||
|
@ -31,7 +28,7 @@ type Props = {
|
|||
editorActions: EditorItemActions,
|
||||
clearContextMenu: () => void,
|
||||
editor: SourceEditor,
|
||||
hasMappedLocation: boolean,
|
||||
hasPrettySource: boolean,
|
||||
isPaused: boolean,
|
||||
selectedSource: SourceWithContent,
|
||||
};
|
||||
|
@ -52,7 +49,7 @@ class EditorMenu extends Component<Props> {
|
|||
editor,
|
||||
selectedSource,
|
||||
editorActions,
|
||||
hasMappedLocation,
|
||||
hasPrettySource,
|
||||
isPaused,
|
||||
contextMenu: event,
|
||||
} = props;
|
||||
|
@ -70,7 +67,7 @@ class EditorMenu extends Component<Props> {
|
|||
cx,
|
||||
editorActions,
|
||||
selectedSource,
|
||||
hasMappedLocation,
|
||||
hasPrettySource,
|
||||
location,
|
||||
isPaused,
|
||||
selectionText: editor.codeMirror.getSelection().trim(),
|
||||
|
@ -87,11 +84,7 @@ class EditorMenu extends Component<Props> {
|
|||
const mapStateToProps = (state, props) => ({
|
||||
cx: getThreadContext(state),
|
||||
isPaused: getIsPaused(state, getCurrentThread(state)),
|
||||
hasMappedLocation:
|
||||
(isOriginalId(props.selectedSource.id) ||
|
||||
isSourceWithMap(state, props.selectedSource.id) ||
|
||||
isPretty(props.selectedSource)) &&
|
||||
!getPrettySource(state, props.selectedSource.id),
|
||||
hasPrettySource: !!getPrettySource(state, props.selectedSource.id),
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
|
|
|
@ -14,16 +14,15 @@ import {
|
|||
getContext,
|
||||
} from "../../selectors";
|
||||
|
||||
import { isFulfilled } from "../../utils/async-value";
|
||||
import {
|
||||
isPretty,
|
||||
getFilename,
|
||||
isOriginal,
|
||||
shouldBlackbox,
|
||||
} from "../../utils/source";
|
||||
import {
|
||||
getGeneratedSource,
|
||||
canPrettyPrintSource,
|
||||
} from "../../reducers/sources";
|
||||
import { getGeneratedSource } from "../../reducers/sources";
|
||||
import { shouldShowPrettyPrint } from "../../utils/editor";
|
||||
|
||||
import { PaneToggleButton } from "../shared/Button";
|
||||
import AccessibleImage from "../shared/AccessibleImage";
|
||||
|
@ -43,7 +42,6 @@ type Props = {
|
|||
mappedSource: Source,
|
||||
endPanelCollapsed: boolean,
|
||||
horizontal: boolean,
|
||||
canPrettyPrint: boolean,
|
||||
togglePrettyPrint: typeof actions.togglePrettyPrint,
|
||||
toggleBlackBox: typeof actions.toggleBlackBox,
|
||||
jumpToMappedLocation: typeof actions.jumpToMappedLocation,
|
||||
|
@ -86,12 +84,7 @@ class SourceFooter extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
prettyPrintButton() {
|
||||
const {
|
||||
cx,
|
||||
selectedSource,
|
||||
canPrettyPrint,
|
||||
togglePrettyPrint,
|
||||
} = this.props;
|
||||
const { cx, selectedSource, togglePrettyPrint } = this.props;
|
||||
|
||||
if (!selectedSource) {
|
||||
return;
|
||||
|
@ -105,7 +98,16 @@ class SourceFooter extends PureComponent<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
if (!canPrettyPrint) {
|
||||
const sourceContent =
|
||||
selectedSource.content && isFulfilled(selectedSource.content)
|
||||
? selectedSource.content.value
|
||||
: null;
|
||||
if (
|
||||
!shouldShowPrettyPrint(
|
||||
selectedSource,
|
||||
sourceContent || { type: "text", value: "", contentType: undefined }
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -278,9 +280,6 @@ const mapStateToProps = state => {
|
|||
selectedSource ? selectedSource.id : null
|
||||
),
|
||||
endPanelCollapsed: getPaneCollapse(state, "end"),
|
||||
canPrettyPrint: selectedSource
|
||||
? canPrettyPrintSource(state, selectedSource.id)
|
||||
: false,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import { isOriginalId } from "devtools-source-map";
|
|||
|
||||
import { copyToTheClipboard } from "../../../utils/clipboard";
|
||||
import {
|
||||
isPretty,
|
||||
getRawSourceURL,
|
||||
getFilename,
|
||||
shouldBlackbox,
|
||||
|
@ -28,6 +29,10 @@ import type {
|
|||
ThreadContext,
|
||||
} from "../../../types";
|
||||
|
||||
function isMapped(selectedSource) {
|
||||
return isOriginalId(selectedSource.id) || !!selectedSource.sourceMapURL;
|
||||
}
|
||||
|
||||
export const continueToHereItem = (
|
||||
cx: ThreadContext,
|
||||
location: SourceLocation,
|
||||
|
@ -83,7 +88,7 @@ const jumpToMappedLocationItem = (
|
|||
cx: Context,
|
||||
selectedSource: Source,
|
||||
location: SourceLocation,
|
||||
hasMappedLocation: boolean,
|
||||
hasPrettySource: boolean,
|
||||
editorActions: EditorItemActions
|
||||
) => ({
|
||||
id: "node-menu-jump",
|
||||
|
@ -94,7 +99,8 @@ const jumpToMappedLocationItem = (
|
|||
: L10N.getStr("original")
|
||||
),
|
||||
accesskey: L10N.getStr("editor.jumpToMappedLocation1.accesskey"),
|
||||
disabled: !hasMappedLocation,
|
||||
disabled:
|
||||
(!isMapped(selectedSource) && !isPretty(selectedSource)) || hasPrettySource,
|
||||
click: () => editorActions.jumpToMappedLocation(cx, location),
|
||||
});
|
||||
|
||||
|
@ -165,7 +171,7 @@ export function editorMenuItems({
|
|||
selectedSource,
|
||||
location,
|
||||
selectionText,
|
||||
hasMappedLocation,
|
||||
hasPrettySource,
|
||||
isTextSelected,
|
||||
isPaused,
|
||||
}: {
|
||||
|
@ -174,7 +180,7 @@ export function editorMenuItems({
|
|||
selectedSource: SourceWithContent,
|
||||
location: SourceLocation,
|
||||
selectionText: string,
|
||||
hasMappedLocation: boolean,
|
||||
hasPrettySource: boolean,
|
||||
isTextSelected: boolean,
|
||||
isPaused: boolean,
|
||||
}) {
|
||||
|
@ -190,7 +196,7 @@ export function editorMenuItems({
|
|||
cx,
|
||||
selectedSource,
|
||||
location,
|
||||
hasMappedLocation,
|
||||
hasPrettySource,
|
||||
editorActions
|
||||
),
|
||||
continueToHereItem(cx, location, isPaused, editorActions),
|
||||
|
|
|
@ -83,7 +83,8 @@ describe("SourcesTree", () => {
|
|||
const newSource = createMockSource(
|
||||
"server1.conn13.child1/43",
|
||||
"http://mdn.com/four.js",
|
||||
true
|
||||
true,
|
||||
""
|
||||
);
|
||||
|
||||
const newThreadSources = {
|
||||
|
@ -148,7 +149,8 @@ describe("SourcesTree", () => {
|
|||
"server1.conn13.child1/41": createMockSource(
|
||||
"server1.conn13.child1/41",
|
||||
"http://mdn.com/three.js",
|
||||
true
|
||||
true,
|
||||
""
|
||||
),
|
||||
},
|
||||
};
|
||||
|
@ -175,7 +177,8 @@ describe("SourcesTree", () => {
|
|||
const newSource = createMockSource(
|
||||
"server1.conn13.child1/43",
|
||||
"http://mdn.com/four.js",
|
||||
true
|
||||
true,
|
||||
""
|
||||
);
|
||||
|
||||
const newThreadSources = {
|
||||
|
@ -224,7 +227,8 @@ describe("SourcesTree", () => {
|
|||
const mockSource = createMockSource(
|
||||
"server1.conn13.child1/41",
|
||||
"http://mdn.com/three.js",
|
||||
false
|
||||
false,
|
||||
null
|
||||
);
|
||||
await component.setProps({
|
||||
...props,
|
||||
|
@ -359,26 +363,32 @@ function generateDefaults(overrides: Object) {
|
|||
"server1.conn13.child1/39": createMockSource(
|
||||
"server1.conn13.child1/39",
|
||||
"http://mdn.com/one.js",
|
||||
false
|
||||
false,
|
||||
null
|
||||
),
|
||||
"server1.conn13.child1/40": createMockSource(
|
||||
"server1.conn13.child1/40",
|
||||
"http://mdn.com/two.js",
|
||||
false
|
||||
false,
|
||||
null
|
||||
),
|
||||
"server1.conn13.child1/41": createMockSource(
|
||||
"server1.conn13.child1/41",
|
||||
"http://mdn.com/three.js",
|
||||
false
|
||||
false,
|
||||
null
|
||||
),
|
||||
"server1.conn13.child1/42/originalSource-sha": createMockSource(
|
||||
"server1.conn13.child1/42/originalSource-sha",
|
||||
"http://mdn.com/four.js",
|
||||
false
|
||||
false,
|
||||
null
|
||||
),
|
||||
"server1.conn13.child1/42": createMockSource(
|
||||
"server1.conn13.child1/42",
|
||||
"http://mdn.com/four.js"
|
||||
"http://mdn.com/four.js",
|
||||
false,
|
||||
"data:application/json?charset=utf?dsffewrsf"
|
||||
),
|
||||
},
|
||||
};
|
||||
|
@ -420,10 +430,11 @@ function render(overrides = {}) {
|
|||
return { component, props, defaultState, instance };
|
||||
}
|
||||
|
||||
function createMockSource(id, url, isBlackBoxed = false) {
|
||||
function createMockSource(id, url, isBlackBoxed = false, sourceMapURL = null) {
|
||||
return {
|
||||
...makeMockSource(url, id),
|
||||
isBlackBoxed,
|
||||
sourceMapURL,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/three.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/three.js",
|
||||
},
|
||||
"name": "three.js",
|
||||
|
@ -163,6 +164,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/four.js",
|
||||
"sourceMapURL": "data:application/json?charset=utf?dsffewrsf",
|
||||
"url": "http://mdn.com/four.js",
|
||||
},
|
||||
"name": "four.js",
|
||||
|
@ -180,6 +182,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/four.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/four.js",
|
||||
},
|
||||
"name": "four.js",
|
||||
|
@ -197,6 +200,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/one.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/one.js",
|
||||
},
|
||||
"name": "one.js",
|
||||
|
@ -214,6 +218,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/three.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/three.js",
|
||||
},
|
||||
"name": "three.js",
|
||||
|
@ -231,6 +236,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/two.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/two.js",
|
||||
},
|
||||
"name": "two.js",
|
||||
|
@ -257,6 +263,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/four.js",
|
||||
"sourceMapURL": "data:application/json?charset=utf?dsffewrsf",
|
||||
"url": "http://mdn.com/four.js",
|
||||
},
|
||||
"name": "four.js",
|
||||
|
@ -274,6 +281,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/four.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/four.js",
|
||||
},
|
||||
"name": "four.js",
|
||||
|
@ -291,6 +299,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/one.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/one.js",
|
||||
},
|
||||
"name": "one.js",
|
||||
|
@ -308,6 +317,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/three.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/three.js",
|
||||
},
|
||||
"name": "three.js",
|
||||
|
@ -325,6 +335,7 @@ exports[`SourcesTree on receiving new props updates highlighted items updates hi
|
|||
"isPrettyPrinted": false,
|
||||
"isWasm": false,
|
||||
"relativeUrl": "http://mdn.com/two.js",
|
||||
"sourceMapURL": null,
|
||||
"url": "http://mdn.com/two.js",
|
||||
},
|
||||
"name": "two.js",
|
||||
|
|
|
@ -109,31 +109,11 @@ export default function update(
|
|||
case "SET_SOURCE_ACTOR_BREAKABLE_LINES":
|
||||
state = updateBreakableLines(state, action);
|
||||
break;
|
||||
|
||||
case "CLEAR_SOURCE_ACTOR_MAP_URL":
|
||||
state = clearSourceActorMapURL(state, action.id);
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
function clearSourceActorMapURL(
|
||||
state: SourceActorsState,
|
||||
id: SourceActorId
|
||||
): SourceActorsState {
|
||||
if (!hasResource(state, id)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
return updateResources(state, [
|
||||
{
|
||||
id,
|
||||
sourceMapURL: "",
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
function updateBreakpointColumns(
|
||||
state: SourceActorsState,
|
||||
action: SourceActorBreakpointColumnsAction
|
||||
|
|
|
@ -17,8 +17,6 @@ import {
|
|||
isGenerated,
|
||||
isOriginal as isOriginalSource,
|
||||
getPlainUrl,
|
||||
isPretty,
|
||||
isJavaScript,
|
||||
} from "../utils/source";
|
||||
import {
|
||||
createInitial,
|
||||
|
@ -39,14 +37,7 @@ import {
|
|||
} from "../utils/resource";
|
||||
|
||||
import { findPosition } from "../utils/breakpoint/breakpointPositions";
|
||||
import {
|
||||
pending,
|
||||
fulfilled,
|
||||
rejected,
|
||||
asSettled,
|
||||
isFulfilled,
|
||||
} from "../utils/async-value";
|
||||
|
||||
import * as asyncValue from "../utils/async-value";
|
||||
import type { AsyncValue, SettledValue } from "../utils/async-value";
|
||||
import { originalToGeneratedId } from "devtools-source-map";
|
||||
import { prefs } from "../utils/prefs";
|
||||
|
@ -89,6 +80,7 @@ type PlainUrlsMap = { [string]: string[] };
|
|||
export type SourceBase = {|
|
||||
+id: SourceId,
|
||||
+url: string,
|
||||
+sourceMapURL?: string,
|
||||
+isBlackBoxed: boolean,
|
||||
+isPrettyPrinted: boolean,
|
||||
+relativeUrl: string,
|
||||
|
@ -158,6 +150,8 @@ function update(
|
|||
let location = null;
|
||||
|
||||
switch (action.type) {
|
||||
case "CLEAR_SOURCE_MAP_URL":
|
||||
return clearSourceMaps(state, action.sourceId);
|
||||
case "ADD_SOURCE":
|
||||
return addSources(state, [action.source]);
|
||||
|
||||
|
@ -266,7 +260,7 @@ const resourceAsSourceBase = memoizeResourceShallow(
|
|||
const resourceAsSourceWithContent = memoizeResourceShallow(
|
||||
({ content, ...source }: SourceResource): SourceWithContent => ({
|
||||
...source,
|
||||
content: asSettled(content),
|
||||
content: asyncValue.asSettled(content),
|
||||
})
|
||||
);
|
||||
|
||||
|
@ -423,17 +417,17 @@ function updateLoadedState(
|
|||
|
||||
let content;
|
||||
if (action.status === "start") {
|
||||
content = pending();
|
||||
content = asyncValue.pending();
|
||||
} else if (action.status === "error") {
|
||||
content = rejected(action.error);
|
||||
content = asyncValue.rejected(action.error);
|
||||
} else if (typeof action.value.text === "string") {
|
||||
content = fulfilled({
|
||||
content = asyncValue.fulfilled({
|
||||
type: "text",
|
||||
value: action.value.text,
|
||||
contentType: action.value.contentType,
|
||||
});
|
||||
} else {
|
||||
content = fulfilled({
|
||||
content = asyncValue.fulfilled({
|
||||
type: "wasm",
|
||||
value: action.value.text,
|
||||
});
|
||||
|
@ -450,6 +444,25 @@ function updateLoadedState(
|
|||
};
|
||||
}
|
||||
|
||||
function clearSourceMaps(
|
||||
state: SourcesState,
|
||||
sourceId: SourceId
|
||||
): SourcesState {
|
||||
if (!hasResource(state.sources, sourceId)) {
|
||||
return state;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
sources: updateResources(state.sources, [
|
||||
{
|
||||
id: sourceId,
|
||||
sourceMapURL: "",
|
||||
},
|
||||
]),
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Update a source when its state changes
|
||||
* e.g. the text was loaded, it was blackboxed
|
||||
|
@ -776,7 +789,7 @@ export function getSourceContent(
|
|||
id: SourceId
|
||||
): SettledValue<SourceContent> | null {
|
||||
const { content } = getResource(state.sources.sources, id);
|
||||
return asSettled(content);
|
||||
return asyncValue.asSettled(content);
|
||||
}
|
||||
|
||||
export function getSelectedSourceId(state: OuterState) {
|
||||
|
@ -913,39 +926,6 @@ export function canLoadSource(
|
|||
return actors.length != 0;
|
||||
}
|
||||
|
||||
export function isSourceWithMap(
|
||||
state: OuterState & SourceActorOuterState,
|
||||
id: SourceId
|
||||
): boolean {
|
||||
return getSourceActorsForSource(state, id).some(
|
||||
soureActor => soureActor.sourceMapURL
|
||||
);
|
||||
}
|
||||
|
||||
export function canPrettyPrintSource(
|
||||
state: OuterState & SourceActorOuterState,
|
||||
id: SourceId
|
||||
): boolean {
|
||||
const source: SourceWithContent = getSourceWithContent(state, id);
|
||||
if (
|
||||
!source ||
|
||||
isPretty(source) ||
|
||||
isOriginalSource(source) ||
|
||||
(prefs.clientSourceMapsEnabled && isSourceWithMap(state, id))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const sourceContent =
|
||||
source.content && isFulfilled(source.content) ? source.content.value : null;
|
||||
|
||||
if (!sourceContent || !isJavaScript(source, sourceContent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function getBreakpointPositions(
|
||||
state: OuterState
|
||||
): BreakpointPositionsMap {
|
||||
|
|
|
@ -253,11 +253,12 @@ export type ChromeFrame = {
|
|||
location: ?SourceLocation,
|
||||
};
|
||||
|
||||
export type OriginalFrame = {|
|
||||
export type OriginalFrame = {
|
||||
displayName: string,
|
||||
variables?: Object,
|
||||
location?: SourceLocation,
|
||||
|};
|
||||
thread: string,
|
||||
};
|
||||
|
||||
/**
|
||||
* ContextMenuItem
|
||||
|
@ -400,6 +401,7 @@ export type SourceWithContentAndType<+Content: SourceContent> = $ReadOnly<{
|
|||
export type Source = {
|
||||
+id: SourceId,
|
||||
+url: string,
|
||||
+sourceMapURL?: string,
|
||||
+isBlackBoxed: boolean,
|
||||
+isPrettyPrinted: boolean,
|
||||
+relativeUrl: string,
|
||||
|
|
|
@ -11,13 +11,19 @@ export * from "../ui";
|
|||
export { onMouseOver } from "./token-events";
|
||||
|
||||
import { createEditor } from "./create-editor";
|
||||
import { shouldPrettyPrint } from "../source";
|
||||
import { findNext, findPrev } from "./source-search";
|
||||
|
||||
import { isWasm, lineToWasmOffset, wasmOffsetToLine } from "../wasm";
|
||||
|
||||
import type { AstLocation } from "../../workers/parser";
|
||||
import type { EditorPosition, EditorRange } from "../editor/types";
|
||||
import type { SearchModifiers, Source, SourceLocation } from "../../types";
|
||||
import type {
|
||||
SearchModifiers,
|
||||
Source,
|
||||
SourceContent,
|
||||
SourceLocation,
|
||||
} from "../../types";
|
||||
type Editor = Object;
|
||||
|
||||
let editor: ?Editor;
|
||||
|
@ -57,6 +63,10 @@ export function endOperation() {
|
|||
codeMirror.endOperation();
|
||||
}
|
||||
|
||||
export function shouldShowPrettyPrint(source: Source, content: SourceContent) {
|
||||
return shouldPrettyPrint(source, content);
|
||||
}
|
||||
|
||||
export function traverseResults(
|
||||
e: Event,
|
||||
ctx: any,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
// @flow
|
||||
|
||||
import {
|
||||
shouldShowPrettyPrint,
|
||||
traverseResults,
|
||||
toEditorLine,
|
||||
toEditorPosition,
|
||||
|
@ -21,7 +22,19 @@ import {
|
|||
getCursorLine,
|
||||
} from "../index";
|
||||
|
||||
import { makeMockSource } from "../../test-mockup";
|
||||
import { makeMockSource, makeMockSourceAndContent } from "../../test-mockup";
|
||||
|
||||
describe("shouldShowPrettyPrint", () => {
|
||||
it("shows pretty print for a source", () => {
|
||||
const { content, ...source } = makeMockSourceAndContent(
|
||||
"http://example.com/index.js",
|
||||
"test-id-123",
|
||||
"text/javascript",
|
||||
"some text here"
|
||||
);
|
||||
expect(shouldShowPrettyPrint(source, content)).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("traverseResults", () => {
|
||||
const e: any = { stopPropagation: jest.fn(), preventDefault: jest.fn() };
|
||||
|
|
|
@ -38,8 +38,8 @@ export async function originalRangeStartsInside(
|
|||
},
|
||||
sourceMaps: SourceMaps
|
||||
) {
|
||||
const endPosition = await sourceMaps.getGeneratedLocation(end);
|
||||
const startPosition = await sourceMaps.getGeneratedLocation(start);
|
||||
const endPosition = await sourceMaps.getGeneratedLocation(end, source);
|
||||
const startPosition = await sourceMaps.getGeneratedLocation(start, source);
|
||||
|
||||
// If the start and end positions collapse into eachother, it means that
|
||||
// the range in the original content didn't _start_ at the start position.
|
||||
|
@ -62,7 +62,7 @@ export async function getApplicableBindingsForOriginalPosition(
|
|||
locationType: BindingLocationType,
|
||||
sourceMaps: SourceMaps
|
||||
): Promise<Array<ApplicableBinding>> {
|
||||
const ranges = await sourceMaps.getGeneratedRanges(start);
|
||||
const ranges = await sourceMaps.getGeneratedRanges(start, source);
|
||||
|
||||
const resultRanges: GeneratedRange[] = ranges.map(mapRange => ({
|
||||
start: {
|
||||
|
@ -85,8 +85,8 @@ export async function getApplicableBindingsForOriginalPosition(
|
|||
// var _mod = require("mod"); // mapped from import statement
|
||||
// var _mod2 = interop(_mod); // entirely unmapped
|
||||
if (bindingType === "import" && locationType !== "ref") {
|
||||
const endPosition = await sourceMaps.getGeneratedLocation(end);
|
||||
const startPosition = await sourceMaps.getGeneratedLocation(start);
|
||||
const endPosition = await sourceMaps.getGeneratedLocation(end, source);
|
||||
const startPosition = await sourceMaps.getGeneratedLocation(start, source);
|
||||
|
||||
for (const range of resultRanges) {
|
||||
if (
|
||||
|
|
|
@ -70,6 +70,7 @@ export async function buildMappedScopes(
|
|||
}
|
||||
|
||||
const originalRanges = await loadRangeMetadata(
|
||||
source,
|
||||
frame,
|
||||
originalAstScopes,
|
||||
sourceMaps
|
||||
|
@ -224,15 +225,15 @@ function batchScopeMappings(
|
|||
for (const loc of locs) {
|
||||
precalculatedRanges.set(
|
||||
buildLocationKey(loc.start),
|
||||
sourceMaps.getGeneratedRanges(loc.start)
|
||||
sourceMaps.getGeneratedRanges(loc.start, source)
|
||||
);
|
||||
precalculatedLocations.set(
|
||||
buildLocationKey(loc.start),
|
||||
sourceMaps.getGeneratedLocation(loc.start)
|
||||
sourceMaps.getGeneratedLocation(loc.start, source)
|
||||
);
|
||||
precalculatedLocations.set(
|
||||
buildLocationKey(loc.end),
|
||||
sourceMaps.getGeneratedLocation(loc.end)
|
||||
sourceMaps.getGeneratedLocation(loc.end, source)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -240,21 +241,21 @@ function batchScopeMappings(
|
|||
}
|
||||
|
||||
return {
|
||||
async getGeneratedRanges(pos) {
|
||||
async getGeneratedRanges(pos, s) {
|
||||
const key = buildLocationKey(pos);
|
||||
|
||||
if (!precalculatedRanges.has(key)) {
|
||||
if (s !== source || !precalculatedRanges.has(key)) {
|
||||
log("Bad precalculated mapping");
|
||||
return sourceMaps.getGeneratedRanges(pos);
|
||||
return sourceMaps.getGeneratedRanges(pos, s);
|
||||
}
|
||||
return precalculatedRanges.get(key);
|
||||
},
|
||||
async getGeneratedLocation(pos) {
|
||||
async getGeneratedLocation(pos, s) {
|
||||
const key = buildLocationKey(pos);
|
||||
|
||||
if (!precalculatedLocations.has(key)) {
|
||||
if (s !== source || !precalculatedLocations.has(key)) {
|
||||
log("Bad precalculated mapping");
|
||||
return sourceMaps.getGeneratedLocation(pos);
|
||||
return sourceMaps.getGeneratedLocation(pos, s);
|
||||
}
|
||||
return precalculatedLocations.get(key);
|
||||
},
|
||||
|
|
|
@ -11,7 +11,7 @@ import { positionCmp } from "./positionCmp";
|
|||
import { filterSortedArray } from "./filtering";
|
||||
|
||||
import type { SourceScope } from "../../../workers/parser";
|
||||
import type { PartialPosition, Frame } from "../../../types";
|
||||
import type { PartialPosition, Frame, Source } from "../../../types";
|
||||
|
||||
type SourceOriginalRange = {
|
||||
line: number,
|
||||
|
@ -33,12 +33,14 @@ export type MappedOriginalRange = {
|
|||
};
|
||||
|
||||
export async function loadRangeMetadata(
|
||||
source: Source,
|
||||
frame: Frame,
|
||||
originalAstScopes: Array<SourceScope>,
|
||||
sourceMaps: SourceMaps
|
||||
): Promise<Array<MappedOriginalRange>> {
|
||||
const originalRanges: Array<SourceOriginalRange> = await sourceMaps.getOriginalRanges(
|
||||
frame.location.sourceId
|
||||
frame.location.sourceId,
|
||||
source.url
|
||||
);
|
||||
|
||||
const sortedOriginalAstBindings = [];
|
||||
|
|
|
@ -20,7 +20,8 @@ export async function getGeneratedLocation(
|
|||
}
|
||||
|
||||
const { line, sourceId, column } = await sourceMaps.getGeneratedLocation(
|
||||
location
|
||||
location,
|
||||
source
|
||||
);
|
||||
|
||||
const generatedSource = getSource(state, sourceId);
|
||||
|
|
|
@ -20,7 +20,7 @@ import { renderWasmText } from "./wasm";
|
|||
import { toEditorLine } from "./editor";
|
||||
export { isMinified } from "./isMinified";
|
||||
import { getURL, getFileExtension } from "./sources-tree";
|
||||
import { features } from "./prefs";
|
||||
import { prefs, features } from "./prefs";
|
||||
|
||||
import type {
|
||||
SourceId,
|
||||
|
@ -78,6 +78,23 @@ export function shouldBlackbox(source: ?Source) {
|
|||
return true;
|
||||
}
|
||||
|
||||
export function shouldPrettyPrint(
|
||||
source: Source,
|
||||
content: SourceContent
|
||||
): boolean {
|
||||
if (
|
||||
!source ||
|
||||
isPretty(source) ||
|
||||
!isJavaScript(source, content) ||
|
||||
isOriginal(source) ||
|
||||
(prefs.clientSourceMapsEnabled && source.sourceMapURL)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified url and/or content type are specific to
|
||||
* javascript files.
|
||||
|
|
|
@ -89,6 +89,7 @@ function makeFrame({ id, sourceId }: Object, opts: Object = {}) {
|
|||
function createSourceObject(
|
||||
filename: string,
|
||||
props: {
|
||||
sourceMapURL?: string,
|
||||
introductionType?: string,
|
||||
introductionUrl?: string,
|
||||
isBlackBoxed?: boolean,
|
||||
|
|
|
@ -1144,14 +1144,14 @@ Toolbox.prototype = {
|
|||
};
|
||||
|
||||
case "getOriginalSourceText":
|
||||
return originalSourceId => {
|
||||
return originalSource => {
|
||||
return target
|
||||
.getOriginalSourceText(originalSourceId)
|
||||
.catch(error => {
|
||||
.getOriginalSourceText(originalSource)
|
||||
.catch(text => {
|
||||
const message = L10N.getFormatStr(
|
||||
"toolbox.sourceMapSourceFailure",
|
||||
error.message,
|
||||
error.metadata ? error.metadata.url : "<unknown>"
|
||||
text,
|
||||
originalSource.url
|
||||
);
|
||||
this.target.logWarningInPage(message, "source map");
|
||||
// Also replace the result with the error text.
|
||||
|
|
|
@ -487,9 +487,7 @@ WorkerDispatcher.prototype = {
|
|||
const [, resolve, reject] = items[i];
|
||||
|
||||
if (resultData.error) {
|
||||
const err = new Error(resultData.message);
|
||||
err.metadata = resultData.metadata;
|
||||
reject(err);
|
||||
reject(resultData.error);
|
||||
} else {
|
||||
resolve(resultData.response);
|
||||
}
|
||||
|
@ -522,14 +520,22 @@ function workerHandler(publicInterface) {
|
|||
if (response instanceof Promise) {
|
||||
return response.then(val => ({
|
||||
response: val
|
||||
}), err => asErrorMessage(err));
|
||||
}), // Error can't be sent via postMessage, so be sure to
|
||||
// convert to string.
|
||||
err => ({
|
||||
error: err.toString()
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
response
|
||||
};
|
||||
} catch (error) {
|
||||
return asErrorMessage(error);
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: error.toString()
|
||||
};
|
||||
}
|
||||
})).then(results => {
|
||||
self.postMessage({
|
||||
|
@ -540,24 +546,6 @@ function workerHandler(publicInterface) {
|
|||
};
|
||||
}
|
||||
|
||||
function asErrorMessage(error) {
|
||||
if (typeof error === "object" && error && "message" in error) {
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: true,
|
||||
message: error.message,
|
||||
metadata: error.metadata
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
error: true,
|
||||
message: error == null ? error : error.toString(),
|
||||
metadata: undefined
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WorkerDispatcher,
|
||||
workerHandler
|
||||
|
@ -598,7 +586,7 @@ Object.defineProperty(exports, "isOriginalId", {
|
|||
return _utils.isOriginalId;
|
||||
}
|
||||
});
|
||||
exports.default = exports.stopSourceMapWorker = exports.startSourceMapWorker = exports.getOriginalStackFrames = exports.clearSourceMaps = exports.applySourceMap = exports.getOriginalSourceText = exports.getFileGeneratedRange = exports.getGeneratedRangesForOriginal = exports.getOriginalLocations = exports.getOriginalLocation = exports.getAllGeneratedLocations = exports.getGeneratedLocation = exports.getGeneratedRanges = exports.getOriginalRanges = exports.hasOriginalURL = exports.getOriginalURLs = exports.setAssetRootURL = exports.dispatcher = void 0;
|
||||
exports.default = exports.stopSourceMapWorker = exports.startSourceMapWorker = exports.getOriginalStackFrames = exports.hasMappedSource = exports.clearSourceMaps = exports.applySourceMap = exports.getOriginalSourceText = exports.getLocationScopes = exports.getFileGeneratedRange = exports.getGeneratedRangesForOriginal = exports.getOriginalLocations = exports.getOriginalLocation = exports.getAllGeneratedLocations = exports.getGeneratedLocation = exports.getGeneratedRanges = exports.getOriginalRanges = exports.hasOriginalURL = exports.getOriginalURLs = exports.setAssetRootURL = exports.dispatcher = void 0;
|
||||
|
||||
var _utils = __webpack_require__(64);
|
||||
|
||||
|
@ -646,19 +634,19 @@ const hasOriginalURL = async url => dispatcher.invoke("hasOriginalURL", url);
|
|||
|
||||
exports.hasOriginalURL = hasOriginalURL;
|
||||
|
||||
const getOriginalRanges = async sourceId => dispatcher.invoke("getOriginalRanges", sourceId);
|
||||
const getOriginalRanges = async (sourceId, url) => dispatcher.invoke("getOriginalRanges", sourceId, url);
|
||||
|
||||
exports.getOriginalRanges = getOriginalRanges;
|
||||
|
||||
const getGeneratedRanges = async location => _getGeneratedRanges(location);
|
||||
const getGeneratedRanges = async (location, originalSource) => _getGeneratedRanges(location, originalSource);
|
||||
|
||||
exports.getGeneratedRanges = getGeneratedRanges;
|
||||
|
||||
const getGeneratedLocation = async location => _getGeneratedLocation(location);
|
||||
const getGeneratedLocation = async (location, originalSource) => _getGeneratedLocation(location, originalSource);
|
||||
|
||||
exports.getGeneratedLocation = getGeneratedLocation;
|
||||
|
||||
const getAllGeneratedLocations = async location => _getAllGeneratedLocations(location);
|
||||
const getAllGeneratedLocations = async (location, originalSource) => _getAllGeneratedLocations(location, originalSource);
|
||||
|
||||
exports.getAllGeneratedLocations = getAllGeneratedLocations;
|
||||
|
||||
|
@ -666,19 +654,21 @@ const getOriginalLocation = async (location, options = {}) => _getOriginalLocati
|
|||
|
||||
exports.getOriginalLocation = getOriginalLocation;
|
||||
|
||||
const getOriginalLocations = async (locations, options = {}) => dispatcher.invoke("getOriginalLocations", locations, options);
|
||||
const getOriginalLocations = async (sourceId, locations, options = {}) => dispatcher.invoke("getOriginalLocations", sourceId, locations, options);
|
||||
|
||||
exports.getOriginalLocations = getOriginalLocations;
|
||||
|
||||
const getGeneratedRangesForOriginal = async (sourceId, mergeUnmappedRegions) => dispatcher.invoke("getGeneratedRangesForOriginal", sourceId, mergeUnmappedRegions);
|
||||
const getGeneratedRangesForOriginal = async (sourceId, url, mergeUnmappedRegions) => dispatcher.invoke("getGeneratedRangesForOriginal", sourceId, url, mergeUnmappedRegions);
|
||||
|
||||
exports.getGeneratedRangesForOriginal = getGeneratedRangesForOriginal;
|
||||
|
||||
const getFileGeneratedRange = async originalSourceId => dispatcher.invoke("getFileGeneratedRange", originalSourceId);
|
||||
const getFileGeneratedRange = async originalSource => dispatcher.invoke("getFileGeneratedRange", originalSource);
|
||||
|
||||
exports.getFileGeneratedRange = getFileGeneratedRange;
|
||||
const getLocationScopes = dispatcher.task("getLocationScopes");
|
||||
exports.getLocationScopes = getLocationScopes;
|
||||
|
||||
const getOriginalSourceText = async originalSourceId => dispatcher.invoke("getOriginalSourceText", originalSourceId);
|
||||
const getOriginalSourceText = async originalSource => dispatcher.invoke("getOriginalSourceText", originalSource);
|
||||
|
||||
exports.getOriginalSourceText = getOriginalSourceText;
|
||||
|
||||
|
@ -690,6 +680,10 @@ const clearSourceMaps = async () => dispatcher.invoke("clearSourceMaps");
|
|||
|
||||
exports.clearSourceMaps = clearSourceMaps;
|
||||
|
||||
const hasMappedSource = async location => dispatcher.invoke("hasMappedSource", location);
|
||||
|
||||
exports.hasMappedSource = hasMappedSource;
|
||||
|
||||
const getOriginalStackFrames = async generatedLocation => dispatcher.invoke("getOriginalStackFrames", generatedLocation);
|
||||
|
||||
exports.getOriginalStackFrames = getOriginalStackFrames;
|
||||
|
|
|
@ -76,64 +76,27 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
/******/ ({
|
||||
|
||||
/***/ 104:
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
const {
|
||||
generatedToOriginalId
|
||||
} = __webpack_require__(64);
|
||||
|
||||
const sourceMapRequests = new Map();
|
||||
|
||||
function clearSourceMaps() {
|
||||
sourceMapRequests.clear();
|
||||
}
|
||||
|
||||
function getSourceMapWithMetadata(generatedSourceId) {
|
||||
function getSourceMap(generatedSourceId) {
|
||||
return sourceMapRequests.get(generatedSourceId);
|
||||
}
|
||||
|
||||
function getSourceMap(generatedSourceId) {
|
||||
const request = getSourceMapWithMetadata(generatedSourceId);
|
||||
|
||||
if (!request) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return request.then(result => result ? result.map : null);
|
||||
}
|
||||
|
||||
function setSourceMap(generatedId, request) {
|
||||
sourceMapRequests.set(generatedId, request.then(map => {
|
||||
if (!map || !map.sources) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const urlsById = new Map();
|
||||
const sources = [];
|
||||
|
||||
for (const url of map.sources) {
|
||||
const id = generatedToOriginalId(generatedId, url);
|
||||
urlsById.set(id, url);
|
||||
sources.push({
|
||||
id,
|
||||
url
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
map,
|
||||
urlsById,
|
||||
sources
|
||||
};
|
||||
}));
|
||||
sourceMapRequests.set(generatedId, request);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
clearSourceMaps,
|
||||
getSourceMapWithMetadata,
|
||||
getSourceMap,
|
||||
setSourceMap
|
||||
};
|
||||
|
@ -548,9 +511,7 @@ WorkerDispatcher.prototype = {
|
|||
const [, resolve, reject] = items[i];
|
||||
|
||||
if (resultData.error) {
|
||||
const err = new Error(resultData.message);
|
||||
err.metadata = resultData.metadata;
|
||||
reject(err);
|
||||
reject(resultData.error);
|
||||
} else {
|
||||
resolve(resultData.response);
|
||||
}
|
||||
|
@ -583,14 +544,22 @@ function workerHandler(publicInterface) {
|
|||
if (response instanceof Promise) {
|
||||
return response.then(val => ({
|
||||
response: val
|
||||
}), err => asErrorMessage(err));
|
||||
}), // Error can't be sent via postMessage, so be sure to
|
||||
// convert to string.
|
||||
err => ({
|
||||
error: err.toString()
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
response
|
||||
};
|
||||
} catch (error) {
|
||||
return asErrorMessage(error);
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: error.toString()
|
||||
};
|
||||
}
|
||||
})).then(results => {
|
||||
self.postMessage({
|
||||
|
@ -601,24 +570,6 @@ function workerHandler(publicInterface) {
|
|||
};
|
||||
}
|
||||
|
||||
function asErrorMessage(error) {
|
||||
if (typeof error === "object" && error && "message" in error) {
|
||||
// Error can't be sent via postMessage, so be sure to convert to
|
||||
// string.
|
||||
return {
|
||||
error: true,
|
||||
message: error.message,
|
||||
metadata: error.metadata
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
error: true,
|
||||
message: error == null ? error : error.toString(),
|
||||
metadata: undefined
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
WorkerDispatcher,
|
||||
workerHandler
|
||||
|
@ -1387,6 +1338,7 @@ const {
|
|||
getOriginalSourceText,
|
||||
getGeneratedRangesForOriginal,
|
||||
getFileGeneratedRange,
|
||||
hasMappedSource,
|
||||
clearSourceMaps,
|
||||
applySourceMap
|
||||
} = __webpack_require__(391);
|
||||
|
@ -1421,6 +1373,7 @@ self.onmessage = workerHandler({
|
|||
getOriginalStackFrames,
|
||||
getGeneratedRangesForOriginal,
|
||||
getFileGeneratedRange,
|
||||
hasMappedSource,
|
||||
applySourceMap,
|
||||
clearSourceMaps
|
||||
});
|
||||
|
@ -1461,7 +1414,6 @@ const {
|
|||
|
||||
const {
|
||||
getSourceMap,
|
||||
getSourceMapWithMetadata,
|
||||
setSourceMap,
|
||||
clearSourceMaps: clearSourceMapsRequests
|
||||
} = __webpack_require__(104);
|
||||
|
@ -1479,30 +1431,25 @@ const {
|
|||
} = __webpack_require__(510);
|
||||
|
||||
async function getOriginalURLs(generatedSource) {
|
||||
await fetchSourceMap(generatedSource);
|
||||
const data = await getSourceMapWithMetadata(generatedSource.id);
|
||||
return data ? data.sources : null;
|
||||
const map = await fetchSourceMap(generatedSource);
|
||||
return map && map.sources;
|
||||
}
|
||||
|
||||
const COMPUTED_SPANS = new WeakSet();
|
||||
const SOURCE_MAPPINGS = new WeakMap();
|
||||
|
||||
async function getOriginalRanges(sourceId) {
|
||||
async function getOriginalRanges(sourceId, url) {
|
||||
if (!isOriginalId(sourceId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(sourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
|
||||
if (!data) {
|
||||
if (!map) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const {
|
||||
map
|
||||
} = data;
|
||||
const url = data.urlsById.get(sourceId);
|
||||
let mappings = SOURCE_MAPPINGS.get(map);
|
||||
|
||||
if (!mappings) {
|
||||
|
@ -1548,23 +1495,18 @@ async function getOriginalRanges(sourceId) {
|
|||
*/
|
||||
|
||||
|
||||
async function getGeneratedRanges(location) {
|
||||
async function getGeneratedRanges(location, originalSource) {
|
||||
if (!isOriginalId(location.sourceId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(location.sourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
|
||||
if (!data) {
|
||||
if (!map) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const {
|
||||
urlsById,
|
||||
map
|
||||
} = data;
|
||||
|
||||
if (!COMPUTED_SPANS.has(map)) {
|
||||
COMPUTED_SPANS.add(map);
|
||||
map.computeColumnSpans();
|
||||
|
@ -1577,7 +1519,7 @@ async function getGeneratedRanges(location) {
|
|||
|
||||
|
||||
const genPos = map.generatedPositionFor({
|
||||
source: urlsById.get(location.sourceId),
|
||||
source: originalSource.url,
|
||||
line: location.line,
|
||||
column: location.column == null ? 0 : location.column,
|
||||
bias: SourceMapConsumer.GREATEST_LOWER_BOUND
|
||||
|
@ -1601,24 +1543,20 @@ async function getGeneratedRanges(location) {
|
|||
});
|
||||
}
|
||||
|
||||
async function getGeneratedLocation(location) {
|
||||
async function getGeneratedLocation(location, originalSource) {
|
||||
if (!isOriginalId(location.sourceId)) {
|
||||
return location;
|
||||
}
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(location.sourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
|
||||
if (!data) {
|
||||
if (!map) {
|
||||
return location;
|
||||
}
|
||||
|
||||
const {
|
||||
urlsById,
|
||||
map
|
||||
} = data;
|
||||
const positions = map.allGeneratedPositionsFor({
|
||||
source: urlsById.get(location.sourceId),
|
||||
source: originalSource.url,
|
||||
line: location.line,
|
||||
column: location.column == null ? 0 : location.column
|
||||
}); // Prior to source-map 0.7, the source-map module returned the earliest
|
||||
|
@ -1636,7 +1574,7 @@ async function getGeneratedLocation(location) {
|
|||
|
||||
if (!match) {
|
||||
match = map.generatedPositionFor({
|
||||
source: urlsById.get(location.sourceId),
|
||||
source: originalSource.url,
|
||||
line: location.line,
|
||||
column: location.column == null ? 0 : location.column,
|
||||
bias: SourceMapConsumer.LEAST_UPPER_BOUND
|
||||
|
@ -1650,24 +1588,20 @@ async function getGeneratedLocation(location) {
|
|||
};
|
||||
}
|
||||
|
||||
async function getAllGeneratedLocations(location) {
|
||||
async function getAllGeneratedLocations(location, originalSource) {
|
||||
if (!isOriginalId(location.sourceId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const generatedSourceId = originalToGeneratedId(location.sourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
|
||||
if (!data) {
|
||||
if (!map) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const {
|
||||
urlsById,
|
||||
map
|
||||
} = data;
|
||||
const positions = map.allGeneratedPositionsFor({
|
||||
source: urlsById.get(location.sourceId),
|
||||
source: originalSource.url,
|
||||
line: location.line,
|
||||
column: location.column == null ? 0 : location.column
|
||||
});
|
||||
|
@ -1681,22 +1615,18 @@ async function getAllGeneratedLocations(location) {
|
|||
}));
|
||||
}
|
||||
|
||||
async function getOriginalLocations(locations, options = {}) {
|
||||
const maps = {};
|
||||
const results = [];
|
||||
|
||||
for (const location of locations) {
|
||||
let map = maps[location.sourceId];
|
||||
|
||||
if (map === undefined) {
|
||||
map = await getSourceMap(location.sourceId);
|
||||
maps[location.sourceId] = map || null;
|
||||
}
|
||||
|
||||
results.push(map ? getOriginalLocationSync(map, location, options) : location);
|
||||
async function getOriginalLocations(sourceId, locations, options = {}) {
|
||||
if (locations.some(location => location.sourceId != sourceId)) {
|
||||
throw new Error("Generated locations must belong to the same source");
|
||||
}
|
||||
|
||||
return results;
|
||||
const map = await getSourceMap(sourceId);
|
||||
|
||||
if (!map) {
|
||||
return locations;
|
||||
}
|
||||
|
||||
return locations.map(location => getOriginalLocationSync(map, location, options));
|
||||
}
|
||||
|
||||
function getOriginalLocationSync(map, location, {
|
||||
|
@ -1757,41 +1687,26 @@ async function getOriginalLocation(location, options = {}) {
|
|||
return getOriginalLocationSync(map, location, options);
|
||||
}
|
||||
|
||||
async function getOriginalSourceText(originalSourceId) {
|
||||
assert(isOriginalId(originalSourceId), "Source is not an original source");
|
||||
const generatedSourceId = originalToGeneratedId(originalSourceId);
|
||||
const data = await getSourceMapWithMetadata(generatedSourceId);
|
||||
async function getOriginalSourceText(originalSource) {
|
||||
assert(isOriginalId(originalSource.id), "Source is not an original source");
|
||||
const generatedSourceId = originalToGeneratedId(originalSource.id);
|
||||
const map = await getSourceMap(generatedSourceId);
|
||||
|
||||
if (!data) {
|
||||
if (!map) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
urlsById,
|
||||
map
|
||||
} = data;
|
||||
const url = urlsById.get(originalSourceId);
|
||||
let text = map.sourceContentFor(url);
|
||||
let text = map.sourceContentFor(originalSource.url);
|
||||
|
||||
if (!text) {
|
||||
try {
|
||||
const response = await networkRequest(url, {
|
||||
loadFromCache: false
|
||||
});
|
||||
text = response.content;
|
||||
} catch (err) {
|
||||
// Wrapper logic renders a notification about the specific URL that
|
||||
// failed to load, so we include it in the error metadata.
|
||||
err.metadata = { ...err.metadata,
|
||||
url
|
||||
};
|
||||
throw err;
|
||||
}
|
||||
text = (await networkRequest(originalSource.url, {
|
||||
loadFromCache: false
|
||||
})).content;
|
||||
}
|
||||
|
||||
return {
|
||||
text,
|
||||
contentType: getContentType(url || "")
|
||||
contentType: getContentType(originalSource.url || "")
|
||||
};
|
||||
}
|
||||
/**
|
||||
|
@ -1810,20 +1725,14 @@ async function getOriginalSourceText(originalSourceId) {
|
|||
|
||||
const GENERATED_MAPPINGS = new WeakMap();
|
||||
|
||||
async function getGeneratedRangesForOriginal(sourceId, mergeUnmappedRegions = false) {
|
||||
async function getGeneratedRangesForOriginal(sourceId, url, mergeUnmappedRegions = false) {
|
||||
assert(isOriginalId(sourceId), "Source is not an original source");
|
||||
const data = await getSourceMapWithMetadata(originalToGeneratedId(sourceId)); // NOTE: this is only needed for Flow
|
||||
const map = await getSourceMap(originalToGeneratedId(sourceId)); // NOTE: this is only needed for Flow
|
||||
|
||||
if (!data) {
|
||||
if (!map) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const {
|
||||
urlsById,
|
||||
map
|
||||
} = data;
|
||||
const url = urlsById.get(sourceId);
|
||||
|
||||
if (!COMPUTED_SPANS.has(map)) {
|
||||
COMPUTED_SPANS.add(map);
|
||||
map.computeColumnSpans();
|
||||
|
@ -1927,26 +1836,22 @@ function wrappedMappingPosition(pos) {
|
|||
};
|
||||
}
|
||||
|
||||
async function getFileGeneratedRange(originalSourceId) {
|
||||
assert(isOriginalId(originalSourceId), "Source is not an original source");
|
||||
const data = await getSourceMapWithMetadata(originalToGeneratedId(originalSourceId));
|
||||
async function getFileGeneratedRange(originalSource) {
|
||||
assert(isOriginalId(originalSource.id), "Source is not an original source");
|
||||
const map = await getSourceMap(originalToGeneratedId(originalSource.id));
|
||||
|
||||
if (!data) {
|
||||
if (!map) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
urlsById,
|
||||
map
|
||||
} = data;
|
||||
const start = map.generatedPositionFor({
|
||||
source: urlsById.get(originalSourceId),
|
||||
source: originalSource.url,
|
||||
line: 1,
|
||||
column: 0,
|
||||
bias: SourceMapConsumer.LEAST_UPPER_BOUND
|
||||
});
|
||||
const end = map.generatedPositionFor({
|
||||
source: urlsById.get(originalSourceId),
|
||||
source: originalSource.url,
|
||||
line: Number.MAX_SAFE_INTEGER,
|
||||
column: Number.MAX_SAFE_INTEGER,
|
||||
bias: SourceMapConsumer.GREATEST_LOWER_BOUND
|
||||
|
@ -1957,6 +1862,15 @@ async function getFileGeneratedRange(originalSourceId) {
|
|||
};
|
||||
}
|
||||
|
||||
async function hasMappedSource(location) {
|
||||
if (isOriginalId(location.sourceId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const loc = await getOriginalLocation(location);
|
||||
return loc.sourceId !== location.sourceId;
|
||||
}
|
||||
|
||||
function applySourceMap(generatedId, url, code, mappings) {
|
||||
const generator = new SourceMapGenerator({
|
||||
file: url
|
||||
|
@ -1986,7 +1900,8 @@ module.exports = {
|
|||
getGeneratedRangesForOriginal,
|
||||
getFileGeneratedRange,
|
||||
applySourceMap,
|
||||
clearSourceMaps
|
||||
clearSourceMaps,
|
||||
hasMappedSource
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
|
@ -3839,9 +3754,9 @@ const {
|
|||
|
||||
const {
|
||||
createConsumer
|
||||
} = __webpack_require__(179); // URLs which have been seen in a completed source map request.
|
||||
|
||||
} = __webpack_require__(179);
|
||||
|
||||
// URLs which have been seen in a completed source map request.
|
||||
const originalURLs = new Set();
|
||||
|
||||
function clearOriginalURLs() {
|
||||
|
|
|
@ -366,10 +366,14 @@ StyleEditorUI.prototype = {
|
|||
this._removeStyleSheetEditor(editor);
|
||||
editor = null;
|
||||
|
||||
for (const { id: originalId, url: originalURL } of sources) {
|
||||
for (const source of sources) {
|
||||
const generatedId = sourceMapService.generatedToOriginalId(
|
||||
id,
|
||||
source
|
||||
);
|
||||
const original = new OriginalSource(
|
||||
originalURL,
|
||||
originalId,
|
||||
source,
|
||||
generatedId,
|
||||
sourceMapService
|
||||
);
|
||||
|
||||
|
|
|
@ -46,7 +46,10 @@ OriginalSource.prototype = {
|
|||
getText: function() {
|
||||
if (!this._sourcePromise) {
|
||||
this._sourcePromise = this._sourceMapService
|
||||
.getOriginalSourceText(this._sourceId)
|
||||
.getOriginalSourceText({
|
||||
id: this._sourceId,
|
||||
url: this._url,
|
||||
})
|
||||
.then(contents => {
|
||||
// Make it look like a long string actor.
|
||||
return {
|
||||
|
|
Загрузка…
Ссылка в новой задаче