Bug 1814177 - [devtools] Clear AST reducer on each target removal. r=bomsy,devtools-reviewers

Also tweak waitForSelectedSource to use location and
match the precise selected source actor.

Differential Revision: https://phabricator.services.mozilla.com/D168430
This commit is contained in:
Alexandre Poirot 2023-04-14 12:44:03 +00:00
Родитель 5c3731a031
Коммит 74e5efb615
3 изменённых файлов: 40 добавлений и 22 удалений

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

@ -12,7 +12,9 @@ import { makeBreakpointId } from "../utils/breakpoint";
export function initialASTState() {
return {
// We are using mutable objects as we never return the dictionary as-is from the selectors
// but only their values .
// but only their values.
// Note that all these dictionaries are storing objects as values
// which all will have a threadActorId attribute.
// We have two maps, a first one for original sources.
// This is keyed by source id.
@ -34,16 +36,19 @@ function update(state = initialASTState(), action) {
return state;
}
const value = action.value;
const entry = {
value: action.value,
threadActorId: location.sourceActor?.thread,
};
if (location.source.isOriginal) {
state.mutableOriginalSourcesSymbols[location.source.id] = value;
state.mutableOriginalSourcesSymbols[location.source.id] = entry;
} else {
if (!location.sourceActor) {
throw new Error(
"Expects a location with a source actor when adding symbols for non-original sources"
);
}
state.mutableSourceActorSymbols[location.sourceActor.id] = value;
state.mutableSourceActorSymbols[location.sourceActor.id] = entry;
}
return {
...state,
@ -51,8 +56,10 @@ function update(state = initialASTState(), action) {
}
case "IN_SCOPE_LINES": {
state.mutableInScopeLines[makeBreakpointId(action.location)] =
action.lines;
state.mutableInScopeLines[makeBreakpointId(action.location)] = {
lines: action.lines,
threadActorId: action.location.sourceActor?.thread,
};
return {
...state,
};
@ -62,6 +69,20 @@ function update(state = initialASTState(), action) {
return { ...state, mutableInScopeLines: {} };
}
case "REMOVE_THREAD": {
function clearDict(dict, threadId) {
for (const key in dict) {
if (dict[key].threadActorId == threadId) {
delete dict[key];
}
}
}
clearDict(state.mutableSourceActorSymbols, action.threadActorID);
clearDict(state.mutableOriginalSourcesSymbols, action.threadActorID);
clearDict(state.mutableInScopeLines, action.threadActorID);
return { ...state };
}
case "NAVIGATE": {
return initialASTState();
}

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

@ -9,18 +9,22 @@ export function getSymbols(state, location) {
return null;
}
if (location.source.isOriginal) {
return state.ast.mutableOriginalSourcesSymbols[location.source.id] || null;
return (
state.ast.mutableOriginalSourcesSymbols[location.source.id]?.value || null
);
}
if (!location.sourceActor) {
throw new Error(
"Expects a location with a source actor when passing non-original sources to getSymbols"
);
}
return state.ast.mutableSourceActorSymbols[location.sourceActor.id] || null;
return (
state.ast.mutableSourceActorSymbols[location.sourceActor.id]?.value || null
);
}
export function getInScopeLines(state, location) {
return state.ast.mutableInScopeLines[makeBreakpointId(location)];
return state.ast.mutableInScopeLines[makeBreakpointId(location)]?.lines;
}
export function hasInScopeLines(state, location) {

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

@ -200,7 +200,6 @@ function waitForSelectedLocation(dbg, line, column) {
*/
function waitForSelectedSource(dbg, sourceOrUrl) {
const {
getSelectedSource,
getSelectedSourceTextContent,
getSymbols,
getBreakableLines,
@ -212,7 +211,7 @@ function waitForSelectedSource(dbg, sourceOrUrl) {
return waitForState(
dbg,
state => {
const source = getSelectedSource() || {};
const location = dbg.selectors.getSelectedLocation() || {};
const sourceTextContent = getSelectedSourceTextContent();
if (!sourceTextContent) {
return false;
@ -222,37 +221,31 @@ function waitForSelectedSource(dbg, sourceOrUrl) {
// Second argument is either a source URL (string)
// or a Source object.
if (typeof sourceOrUrl == "string") {
if (!source.url.includes(encodeURI(sourceOrUrl))) {
if (!location.source.url.includes(encodeURI(sourceOrUrl))) {
return false;
}
} else if (source.id != sourceOrUrl.id) {
} else if (location.source.id != sourceOrUrl.id) {
return false;
}
}
const firstSourceActor = getFirstSourceActorForGeneratedSource(source.id);
const location = createLocation({
source,
sourceActor: firstSourceActor,
});
// Wait for symbols/AST to be parsed
if (!getSymbols(location)) {
return false;
}
// Finaly wait for breakable lines to be set
if (source.isHTML) {
if (location.source.isHTML) {
// For HTML sources we need to wait for each source actor to be processed.
// getBreakableLines will return the aggregation without being able to know
// if that's complete, with all the source actors.
const sourceActors = getSourceActorsForSource(source.id);
const sourceActors = getSourceActorsForSource(location.source.id);
const allSourceActorsProcessed = sourceActors.every(
sourceActor => !!getSourceActorBreakableLines(sourceActor.id)
);
return allSourceActorsProcessed;
}
return getBreakableLines(source.id);
return getBreakableLines(location.source.id);
},
"selected source"
);