Bug 1818495 - [devtools] Use location source and sourceActor attribute instead of re-querying the selectors. r=bomsy,devtools-reviewers

This may keep running async code whose source have been removed,
but this help remove various selectors lookups.

If we expect to check in async code if the source is still registered,
we should probably have an explicit API for this.

Differential Revision: https://phabricator.services.mozilla.com/D169331
This commit is contained in:
Alexandre Poirot 2023-03-15 13:48:32 +00:00
Родитель d66f5cba8d
Коммит 8ae10544b1
19 изменённых файлов: 99 добавлений и 121 удалений

Просмотреть файл

@ -44246,20 +44246,20 @@ function sortByStart(a, b) {
*/ */
function findOutOfScopeLocations(sourceId, position) { function findOutOfScopeLocations(location) {
const { const {
functions, functions,
comments comments
} = findSymbols(sourceId); } = findSymbols(location.source.id);
const commentLocations = comments.map(c => c.location); const commentLocations = comments.map(c => c.location);
const locations = functions.map(getLocation).concat(commentLocations).sort(sortByStart); const locations = functions.map(getLocation).concat(commentLocations).sort(sortByStart);
const innerLocations = getInnerLocations(locations, position); const innerLocations = getInnerLocations(locations, location);
const outerLocations = locations.filter(loc => { const outerLocations = locations.filter(loc => {
if (innerLocations.includes(loc)) { if (innerLocations.includes(loc)) {
return false; return false;
} }
return !(0, _contains.containsPosition)(loc, position); return !(0, _contains.containsPosition)(loc, location);
}); });
return removeOverlaps(outerLocations); return removeOverlaps(outerLocations);
} }

Просмотреть файл

@ -4,7 +4,6 @@
import { import {
hasInScopeLines, hasInScopeLines,
getLocationSource,
getSourceTextContent, getSourceTextContent,
getVisibleSelectedFrame, getVisibleSelectedFrame,
} from "../../selectors"; } from "../../selectors";
@ -33,12 +32,11 @@ async function getInScopeLines(
location, location,
{ dispatch, getState, parserWorker } { dispatch, getState, parserWorker }
) { ) {
const source = getLocationSource(getState(), location);
const sourceTextContent = getSourceTextContent(getState(), location); const sourceTextContent = getSourceTextContent(getState(), location);
let locations = null; let locations = null;
if (location.line && source && !source.isWasm) { if (location.line && location.source && !location.source.isWasm) {
locations = await parserWorker.findOutOfScopeLocations(source.id, location); locations = await parserWorker.findOutOfScopeLocations(location);
} }
const linesOutOfScope = getOutOfScopeLines(locations); const linesOutOfScope = getOutOfScopeLines(locations);

Просмотреть файл

@ -11,7 +11,6 @@ import {
getBreakpoint, getBreakpoint,
getBreakpointPositionsForLocation, getBreakpointPositionsForLocation,
getFirstBreakpointPosition, getFirstBreakpointPosition,
getLocationSource,
getSettledSourceTextContent, getSettledSourceTextContent,
getBreakpointsList, getBreakpointsList,
getPendingBreakpointList, getPendingBreakpointList,
@ -64,7 +63,7 @@ async function clientSetBreakpoint(
); );
const shouldMapBreakpointExpressions = const shouldMapBreakpointExpressions =
isMapScopesEnabled(getState()) && isMapScopesEnabled(getState()) &&
getLocationSource(getState(), breakpoint.location).isOriginal && breakpoint.location.source.isOriginal &&
(breakpoint.options.logValue || breakpoint.options.condition); (breakpoint.options.logValue || breakpoint.options.condition);
if (shouldMapBreakpointExpressions) { if (shouldMapBreakpointExpressions) {
@ -107,14 +106,15 @@ export function addBreakpoint(
const { dispatch, getState, client } = thunkArgs; const { dispatch, getState, client } = thunkArgs;
recordEvent("add_breakpoint"); recordEvent("add_breakpoint");
const { column, line } = initialLocation;
const initialSource = getLocationSource(getState(), initialLocation);
await dispatch( await dispatch(
setBreakpointPositions({ cx, sourceId: initialSource.id, line }) setBreakpointPositions({
cx,
sourceId: initialLocation.source.id,
line: initialLocation.line,
})
); );
const position = column const position = initialLocation.column
? getBreakpointPositionsForLocation(getState(), initialLocation) ? getBreakpointPositionsForLocation(getState(), initialLocation)
: getFirstBreakpointPosition(getState(), initialLocation); : getFirstBreakpointPosition(getState(), initialLocation);
@ -126,23 +126,20 @@ export function addBreakpoint(
const { location, generatedLocation } = position; const { location, generatedLocation } = position;
const source = getLocationSource(getState(), location); if (!location.source || !generatedLocation.source) {
const generatedSource = getLocationSource(getState(), generatedLocation);
if (!source || !generatedSource) {
return null; return null;
} }
const originalContent = getSettledSourceTextContent(getState(), location); const originalContent = getSettledSourceTextContent(getState(), location);
const originalText = getTextAtPosition( const originalText = getTextAtPosition(
source.id, location.source.id,
originalContent, originalContent,
location location
); );
const content = getSettledSourceTextContent(getState(), generatedLocation); const content = getSettledSourceTextContent(getState(), generatedLocation);
const text = getTextAtPosition( const text = getTextAtPosition(
generatedSource.id, generatedLocation.source.id,
content, content,
generatedLocation generatedLocation
); );
@ -150,7 +147,7 @@ export function addBreakpoint(
const id = makeBreakpointId(location); const id = makeBreakpointId(location);
const breakpoint = createBreakpoint({ const breakpoint = createBreakpoint({
id, id,
thread: generatedSource.thread, thread: generatedLocation.source.thread,
disabled, disabled,
options, options,
location, location,

Просмотреть файл

@ -7,7 +7,6 @@ import {
getExpressions, getExpressions,
getSelectedFrame, getSelectedFrame,
getSelectedFrameId, getSelectedFrameId,
getLocationSource,
getSelectedSource, getSelectedSource,
getSelectedScopeMappings, getSelectedScopeMappings,
getSelectedFrameBindings, getSelectedFrameBindings,
@ -135,11 +134,13 @@ function evaluateExpression(cx, expression) {
const frame = getSelectedFrame(getState(), cx.thread); const frame = getSelectedFrame(getState(), cx.thread);
if (frame) { if (frame) {
const source = getLocationSource(getState(), frame.location);
const selectedSource = getSelectedSource(getState()); const selectedSource = getSelectedSource(getState());
if (selectedSource && source.isOriginal && selectedSource.isOriginal) { if (
selectedSource &&
frame.location.source.isOriginal &&
selectedSource.isOriginal
) {
const mapResult = await dispatch(getMappedExpression(input)); const mapResult = await dispatch(getMappedExpression(input));
if (mapResult) { if (mapResult) {
input = mapResult.expression; input = mapResult.expression;

Просмотреть файл

@ -4,7 +4,6 @@
import { import {
getSymbols, getSymbols,
getLocationSource,
getSelectedFrame, getSelectedFrame,
getCurrentThread, getCurrentThread,
} from "../../selectors"; } from "../../selectors";
@ -46,12 +45,11 @@ export function highlightCalls(cx) {
return null; return null;
} }
const source = getLocationSource(getState(), frame.location); if (!frame.location.source) {
if (!source) {
return null; return null;
} }
const symbols = getSymbols(getState(), source); const symbols = getSymbols(getState(), frame.location.source);
if (!symbols) { if (!symbols) {
return null; return null;

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/>. */ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
import { getFrames, getSymbols, getLocationSource } from "../../selectors"; import { getFrames, getSymbols } from "../../selectors";
import { findClosestFunction } from "../../utils/ast"; import { findClosestFunction } from "../../utils/ast";
@ -11,13 +11,11 @@ function mapDisplayName(frame, { getState }) {
return frame; return frame;
} }
const source = getLocationSource(getState(), frame.location); if (!frame.location.source) {
if (!source) {
return frame; return frame;
} }
const symbols = getSymbols(getState(), source); const symbols = getSymbols(getState(), frame.location.source);
if (!symbols || !symbols.functions) { if (!symbols || !symbols.functions) {
return frame; return frame;

Просмотреть файл

@ -6,7 +6,6 @@ import {
getSource, getSource,
getFrames, getFrames,
getBlackBoxRanges, getBlackBoxRanges,
getLocationSource,
getSelectedFrame, getSelectedFrame,
} from "../../selectors"; } from "../../selectors";
@ -22,20 +21,12 @@ function getSelectedFrameId(state, thread, frames) {
let selectedFrame = getSelectedFrame(state, thread); let selectedFrame = getSelectedFrame(state, thread);
const blackboxedRanges = getBlackBoxRanges(state); const blackboxedRanges = getBlackBoxRanges(state);
if ( if (selectedFrame && !isFrameBlackBoxed(selectedFrame, blackboxedRanges)) {
selectedFrame &&
!isFrameBlackBoxed(
selectedFrame,
getLocationSource(state, selectedFrame.location),
blackboxedRanges
)
) {
return selectedFrame.id; return selectedFrame.id;
} }
selectedFrame = frames.find(frame => { selectedFrame = frames.find(frame => {
const frameSource = getLocationSource(state, frame.location); return !isFrameBlackBoxed(frame, blackboxedRanges);
return !isFrameBlackBoxed(frame, frameSource, blackboxedRanges);
}); });
return selectedFrame?.id; return selectedFrame?.id;
} }
@ -66,12 +57,8 @@ function isWasmOriginalSourceFrame(frame, getState) {
if (isGeneratedId(frame.location.sourceId)) { if (isGeneratedId(frame.location.sourceId)) {
return false; return false;
} }
const generatedSource = getLocationSource(
getState(),
frame.generatedLocation
);
return Boolean(generatedSource?.isWasm); return Boolean(frame.generatedLocation?.source.isWasm);
} }
async function expandFrames(frames, { getState, sourceMapLoader }) { async function expandFrames(frames, { getState, sourceMapLoader }) {

Просмотреть файл

@ -5,7 +5,6 @@
import { import {
getSelectedFrameId, getSelectedFrameId,
getSource, getSource,
getLocationSource,
getSettledSourceTextContent, getSettledSourceTextContent,
isMapScopesEnabled, isMapScopesEnabled,
getSelectedFrame, getSelectedFrame,
@ -135,12 +134,9 @@ export function mapScopes(cx, scopes, frame) {
export function getMappedScopes(cx, scopes, frame) { export function getMappedScopes(cx, scopes, frame) {
return async function(thunkArgs) { return async function(thunkArgs) {
const { getState, dispatch } = thunkArgs; const { getState, dispatch } = thunkArgs;
const generatedSource = getLocationSource( const generatedSource = frame.generatedLocation.source;
getState(),
frame.generatedLocation
);
const source = getLocationSource(getState(), frame.location); const source = frame.location.source;
if ( if (
!isMapScopesEnabled(getState()) || !isMapScopesEnabled(getState()) ||

Просмотреть файл

@ -33,7 +33,6 @@ import {
getSelectedSource, getSelectedSource,
canPrettyPrintSource, canPrettyPrintSource,
getIsCurrentThreadPaused, getIsCurrentThreadPaused,
getLocationSource,
getSourceTextContent, getSourceTextContent,
tabExists, tabExists,
} from "../../selectors"; } from "../../selectors";
@ -131,7 +130,7 @@ export function selectLocation(cx, location, { keepContext = true } = {}) {
return; return;
} }
let source = getLocationSource(getState(), location); let source = location.source;
if (!source) { if (!source) {
// If there is no source we deselect the current selected source // If there is no source we deselect the current selected source
@ -161,7 +160,7 @@ export function selectLocation(cx, location, { keepContext = true } = {}) {
// getRelatedMapLocation will just convert to the related generated/original location. // getRelatedMapLocation will just convert to the related generated/original location.
// i.e if the original location is passed, the related generated location will be returned and vice versa. // i.e if the original location is passed, the related generated location will be returned and vice versa.
location = await getRelatedMapLocation(location, thunkArgs); location = await getRelatedMapLocation(location, thunkArgs);
source = getLocationSource(getState(), location); source = location.source;
} }
let sourceActor = location.sourceActor; let sourceActor = location.sourceActor;

Просмотреть файл

@ -19,8 +19,6 @@ import {
getContext, getContext,
getGeneratedSourceByURL, getGeneratedSourceByURL,
getBlackBoxRanges, getBlackBoxRanges,
getSourceActor,
getSource,
} from "../../selectors"; } from "../../selectors";
// Actions // Actions
@ -32,6 +30,7 @@ import ManagedTree from "../shared/ManagedTree";
// Utils // Utils
import { getRawSourceURL } from "../../utils/source"; import { getRawSourceURL } from "../../utils/source";
import { createLocation } from "../../utils/location";
function shouldAutoExpand(item, mainThreadHost) { function shouldAutoExpand(item, mainThreadHost) {
// There is only one case where we want to force auto expand, // There is only one case where we want to force auto expand,
@ -126,12 +125,12 @@ class SourcesTree extends Component {
// We might fail to find the source if its thread is registered late, // We might fail to find the source if its thread is registered late,
// so that we should re-search the selected source if highlightItems is empty. // so that we should re-search the selected source if highlightItems is empty.
if ( if (
nextProps.selectedTreeLocation.source && nextProps.selectedTreeLocation?.source &&
(nextProps.selectedTreeLocation.source != selectedTreeLocation.source || (nextProps.selectedTreeLocation.source != selectedTreeLocation?.source ||
(nextProps.selectedTreeLocation.source === (nextProps.selectedTreeLocation.source ===
selectedTreeLocation.source && selectedTreeLocation?.source &&
nextProps.selectedTreeLocation.sourceActor != nextProps.selectedTreeLocation.sourceActor !=
selectedTreeLocation.sourceActor) || selectedTreeLocation?.sourceActor) ||
!this.state.highlightItems?.length) !this.state.highlightItems?.length)
) { ) {
let parentDirectory = getDirectoryForSource( let parentDirectory = getDirectoryForSource(
@ -375,17 +374,24 @@ class SourcesTree extends Component {
} }
function getTreeLocation(state, location) { function getTreeLocation(state, location) {
let source = location ? getSource(state, location.sourceId) : null; // In the SourceTree, we never show the pretty printed sources and only
const sourceActor = location // the minified version, so if we are selecting a pretty file, fake selecting
? getSourceActor(state, location.sourceActorId) // the minified version.
: null; if (location?.source.isPrettyPrinted) {
const source = getGeneratedSourceByURL(
if (source && source.isPrettyPrinted) { state,
source = getRawSourceURL(location.source.url)
getGeneratedSourceByURL(state, getRawSourceURL(source.url)) || null; );
if (source) {
return createLocation({
source,
// A source actor is required by getDirectoryForSource
// in order to know in which thread this source relates to.
sourceActor: location.sourceActor,
});
}
} }
return location;
return { source, sourceActor };
} }
const mapStateToProps = state => { const mapStateToProps = state => {

Просмотреть файл

@ -24,7 +24,6 @@ import {
getThreadContext, getThreadContext,
getPauseReason, getPauseReason,
getShouldBreakpointsPaneOpenOnPause, getShouldBreakpointsPaneOpenOnPause,
getLocationSource,
getSkipPausing, getSkipPausing,
shouldLogEventBreakpoints, shouldLogEventBreakpoints,
} from "../../selectors"; } from "../../selectors";
@ -524,7 +523,7 @@ const mapStateToProps = state => {
workers: getThreads(state), workers: getThreads(state),
skipPausing: getSkipPausing(state), skipPausing: getSkipPausing(state),
logEventBreakpoints: shouldLogEventBreakpoints(state), logEventBreakpoints: shouldLogEventBreakpoints(state),
source: selectedFrame && getLocationSource(state, selectedFrame.location), source: selectedFrame && selectedFrame.location.source,
pauseReason: pauseReason?.type ?? "", pauseReason: pauseReason?.type ?? "",
shouldBreakpointsPaneOpenOnPause, shouldBreakpointsPaneOpenOnPause,
thread, thread,

Просмотреть файл

@ -42,7 +42,7 @@ export function formatCallStackFrames(
const formattedFrames = frames const formattedFrames = frames
.filter(frame => getSourceForFrame(sourcesMap, frame)) .filter(frame => getSourceForFrame(sourcesMap, frame))
.map(frame => appendSource(sourcesMap, frame, selectedSource)) .map(frame => appendSource(sourcesMap, frame, selectedSource))
.filter(frame => !isFrameBlackBoxed(frame, frame.source, blackboxedRanges)); .filter(frame => !isFrameBlackBoxed(frame, blackboxedRanges));
return annotateFrames(formattedFrames); return annotateFrames(formattedFrames);
} }

Просмотреть файл

@ -42,10 +42,6 @@ export function getSourceFromId(state, id) {
return source; return source;
} }
export function getLocationSource(state, location) {
return getSource(state, location.sourceId);
}
export function getSourceByActorId(state, actorId) { export function getSourceByActorId(state, actorId) {
if (!hasSourceActor(state, actorId)) { if (!hasSourceActor(state, actorId)) {
return null; return null;
@ -242,7 +238,7 @@ export function canPrettyPrintSource(state, location) {
} }
export function getPrettyPrintMessage(state, location) { export function getPrettyPrintMessage(state, location) {
const source = getSource(state, location.sourceId); const source = location.source;
if (!source) { if (!source) {
return L10N.getStr("sourceTabs.prettyPrint"); return L10N.getStr("sourceTabs.prettyPrint");
} }

Просмотреть файл

@ -6,11 +6,7 @@ import { createSelector } from "reselect";
import { shallowEqual } from "../utils/shallow-equal"; import { shallowEqual } from "../utils/shallow-equal";
import { getPrettySourceURL } from "../utils/source"; import { getPrettySourceURL } from "../utils/source";
import { import { getSpecificSourceByURL, getSourcesMap } from "./sources";
getLocationSource,
getSpecificSourceByURL,
getSourcesMap,
} from "./sources";
import { isOriginalId } from "devtools/client/shared/source-map-loader/index"; import { isOriginalId } from "devtools/client/shared/source-map-loader/index";
import { isSimilarTab } from "../utils/tabs"; import { isSimilarTab } from "../utils/tabs";
@ -54,13 +50,13 @@ export function getNewSelectedSource(state, tabList) {
return null; return null;
} }
const selectedTab = getLocationSource(state, selectedLocation); const selectedSource = selectedLocation.source;
if (!selectedTab) { if (!selectedSource) {
return null; return null;
} }
const matchingTab = availableTabs.find(tab => const matchingTab = availableTabs.find(tab =>
isSimilarTab(tab, selectedTab.url, isOriginalId(selectedLocation.sourceId)) isSimilarTab(tab, selectedSource.url, isOriginalId(selectedSource.id))
); );
if (matchingTab) { if (matchingTab) {
@ -69,21 +65,24 @@ export function getNewSelectedSource(state, tabList) {
return null; return null;
} }
const selectedSource = getSpecificSourceByURL( const specificSelectedSource = getSpecificSourceByURL(
state, state,
selectedTab.url, selectedSource.url,
selectedTab.isOriginal selectedSource.isOriginal
); );
if (selectedSource) { if (specificSelectedSource) {
return selectedSource; return specificSelectedSource;
} }
return null; return null;
} }
const tabUrls = tabList.map(tab => tab.url); const tabUrls = tabList.map(tab => tab.url);
const leftNeighborIndex = Math.max(tabUrls.indexOf(selectedTab.url) - 1, 0); const leftNeighborIndex = Math.max(
tabUrls.indexOf(selectedSource.url) - 1,
0
);
const lastAvailbleTabIndex = availableTabs.length - 1; const lastAvailbleTabIndex = availableTabs.length - 1;
const newSelectedTabIndex = Math.min(leftNeighborIndex, lastAvailbleTabIndex); const newSelectedTabIndex = Math.min(leftNeighborIndex, lastAvailbleTabIndex);
const availableTab = availableTabs[newSelectedTabIndex]; const availableTab = availableTabs[newSelectedTabIndex];

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/>. */ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
import { getLocationSource, getSourceActorsForSource } from "../../selectors"; import { getSourceActorsForSource } from "../../selectors";
import { isGenerated } from "../source"; import { isGenerated } from "../source";
import { sortSelectedLocations } from "../location"; import { sortSelectedLocations } from "../location";
import assert from "../assert"; import assert from "../assert";
@ -30,7 +30,7 @@ export function makePendingLocationId(location) {
} }
export function makeBreakpointLocation(state, location) { export function makeBreakpointLocation(state, location) {
const source = getLocationSource(state, location); const source = location.source;
if (!source) { if (!source) {
throw new Error("no source"); throw new Error("no source");
} }

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
import { isOriginalId } from "devtools/client/shared/source-map-loader/index"; import { isOriginalId } from "devtools/client/shared/source-map-loader/index";
import { getSource, getLocationSource } from "../selectors"; import { getSource } from "../selectors";
import { createLocation } from "./location"; import { createLocation } from "./location";
/** /**
@ -76,10 +76,7 @@ export async function getOriginalLocation(location, thunkArgs) {
} }
export async function getMappedLocation(location, thunkArgs) { export async function getMappedLocation(location, thunkArgs) {
const { getState } = thunkArgs; if (!location.source) {
const source = getLocationSource(getState(), location);
if (!source) {
throw new Error(`no source ${location.sourceId}`); throw new Error(`no source ${location.sourceId}`);
} }
@ -106,6 +103,10 @@ export async function getMappedLocation(location, thunkArgs) {
* related location in the generated source. * related location in the generated source.
*/ */
export async function getRelatedMapLocation(location, thunkArgs) { export async function getRelatedMapLocation(location, thunkArgs) {
if (!location.source) {
return location;
}
if (isOriginalId(location.sourceId)) { if (isOriginalId(location.sourceId)) {
return getGeneratedLocation(location, thunkArgs); return getGeneratedLocation(location, thunkArgs);
} }

Просмотреть файл

@ -65,20 +65,18 @@ export function shouldBlackbox(source) {
* *
* @param {Object} frame * @param {Object} frame
* The current frame * The current frame
* @param {Object} source
* The source related to the frame
* @param {Object} blackboxedRanges * @param {Object} blackboxedRanges
* The currently blackboxedRanges for all the sources. * The currently blackboxedRanges for all the sources.
* @param {Boolean} isFrameBlackBoxed * @param {Boolean} isFrameBlackBoxed
* If the frame is within the blackboxed range * If the frame is within the blackboxed range
* or not. * or not.
*/ */
export function isFrameBlackBoxed(frame, source, blackboxedRanges) { export function isFrameBlackBoxed(frame, blackboxedRanges) {
return ( return (
source && frame.source &&
!!blackboxedRanges[source.url] && !!blackboxedRanges[frame.source.url] &&
(!blackboxedRanges[source.url].length || (!blackboxedRanges[frame.source.url].length ||
!!findBlackBoxRange(source, blackboxedRanges, { !!findBlackBoxRange(frame.source, blackboxedRanges, {
start: frame.location.line, start: frame.location.line,
end: frame.location.line, end: frame.location.line,
})) }))

Просмотреть файл

@ -110,21 +110,21 @@ function sortByStart(a, b) {
* Returns an array of locations that are considered out of scope for the given * Returns an array of locations that are considered out of scope for the given
* location. * location.
*/ */
function findOutOfScopeLocations(sourceId, position) { function findOutOfScopeLocations(location) {
const { functions, comments } = findSymbols(sourceId); const { functions, comments } = findSymbols(location.source.id);
const commentLocations = comments.map(c => c.location); const commentLocations = comments.map(c => c.location);
const locations = functions const locations = functions
.map(getLocation) .map(getLocation)
.concat(commentLocations) .concat(commentLocations)
.sort(sortByStart); .sort(sortByStart);
const innerLocations = getInnerLocations(locations, position); const innerLocations = getInnerLocations(locations, location);
const outerLocations = locations.filter(loc => { const outerLocations = locations.filter(loc => {
if (innerLocations.includes(loc)) { if (innerLocations.includes(loc)) {
return false; return false;
} }
return !containsPosition(loc, position); return !containsPosition(loc, location);
}); });
return removeOverlaps(outerLocations); return removeOverlaps(outerLocations);
} }

Просмотреть файл

@ -19,7 +19,8 @@ function formatLines(actual) {
describe("Parser.findOutOfScopeLocations", () => { describe("Parser.findOutOfScopeLocations", () => {
it("should exclude non-enclosing function blocks", () => { it("should exclude non-enclosing function blocks", () => {
const source = populateSource("outOfScope"); const source = populateSource("outOfScope");
const actual = findOutOfScopeLocations(source.id, { const actual = findOutOfScopeLocations({
source,
line: 5, line: 5,
column: 5, column: 5,
}); });
@ -29,7 +30,8 @@ describe("Parser.findOutOfScopeLocations", () => {
it("should roll up function blocks", () => { it("should roll up function blocks", () => {
const source = populateSource("outOfScope"); const source = populateSource("outOfScope");
const actual = findOutOfScopeLocations(source.id, { const actual = findOutOfScopeLocations({
source,
line: 24, line: 24,
column: 0, column: 0,
}); });
@ -39,7 +41,8 @@ describe("Parser.findOutOfScopeLocations", () => {
it("should exclude function for locations on declaration", () => { it("should exclude function for locations on declaration", () => {
const source = populateSource("outOfScope"); const source = populateSource("outOfScope");
const actual = findOutOfScopeLocations(source.id, { const actual = findOutOfScopeLocations({
source,
line: 3, line: 3,
column: 12, column: 12,
}); });
@ -49,7 +52,8 @@ describe("Parser.findOutOfScopeLocations", () => {
it("should treat comments as out of scope", () => { it("should treat comments as out of scope", () => {
const source = populateSource("outOfScopeComment"); const source = populateSource("outOfScopeComment");
const actual = findOutOfScopeLocations(source.id, { const actual = findOutOfScopeLocations({
source,
line: 3, line: 3,
column: 2, column: 2,
}); });
@ -61,7 +65,8 @@ describe("Parser.findOutOfScopeLocations", () => {
it("should not exclude in-scope inner locations", () => { it("should not exclude in-scope inner locations", () => {
const source = populateSource("outOfScope"); const source = populateSource("outOfScope");
const actual = findOutOfScopeLocations(source.id, { const actual = findOutOfScopeLocations({
source,
line: 61, line: 61,
column: 0, column: 0,
}); });