Skip to content

Commit 9201842

Browse files
committed
Remove UI objects from verifierLogState
The verifierLogState should not contain objects only used by the UI so create a separate UI state object: VisualLogState that contains verifierLogState as well as other UI-specific objects (e.g. logLines). There are no behavior changes, just a refactoring.
1 parent 81a3d70 commit 9201842

File tree

4 files changed

+128
-79
lines changed

4 files changed

+128
-79
lines changed

src/App.tsx

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ import {
1313
scrollToLogLine,
1414
scrollToCLine,
1515
siblingInsLine,
16+
getVisibleLogLines,
17+
getVisibleCLines,
1618
} from "./utils";
1719

1820
import {
21+
VisualLogState,
1922
LogLineState,
2023
Example,
2124
HoveredLineHint,
@@ -24,13 +27,39 @@ import {
2427
SelectedLineHint,
2528
ToolTip,
2629
} from "./components";
27-
import { ParsedLine, ParsedLineType } from "./parser";
30+
import { ParsedLineType } from "./parser";
31+
32+
function getEmptyVisualLogState(): VisualLogState {
33+
return {
34+
verifierLogState: getEmptyVerifierState(),
35+
logLines: [],
36+
logLineIdToIdx: new Map(),
37+
cLines: [],
38+
cLineIdtoIdx: new Map(),
39+
};
40+
}
41+
42+
function getVisualLogState(
43+
verifierLogState: VerifierLogState,
44+
fullLogView: boolean,
45+
): VisualLogState {
46+
const [logLines, logLineIdToIdx] = getVisibleLogLines(
47+
verifierLogState,
48+
fullLogView,
49+
);
50+
const [cLines, cLineIdtoIdx] = getVisibleCLines(verifierLogState);
51+
return {
52+
verifierLogState: verifierLogState,
53+
logLines,
54+
logLineIdToIdx,
55+
cLines,
56+
cLineIdtoIdx,
57+
};
58+
}
2859

2960
const ContentRaw = ({
3061
loadError,
31-
verifierLogState,
32-
logLines,
33-
logLineIdToIdx,
62+
visualLogState,
3463
selectedLine,
3564
selectedMemSlotId,
3665
selectedCLine,
@@ -43,9 +72,7 @@ const ContentRaw = ({
4372
handleStateRowClick,
4473
}: {
4574
loadError: string | null;
46-
verifierLogState: VerifierLogState;
47-
logLines: ParsedLine[];
48-
logLineIdToIdx: Map<number, number>;
75+
visualLogState: VisualLogState;
4976
selectedLine: number;
5077
selectedMemSlotId: string;
5178
selectedCLine: number;
@@ -59,12 +86,10 @@ const ContentRaw = ({
5986
}) => {
6087
if (loadError) {
6188
return <div>{loadError}</div>;
62-
} else if (logLines.length > 0) {
89+
} else if (visualLogState.logLines.length > 0) {
6390
return (
6491
<MainContent
65-
verifierLogState={verifierLogState}
66-
logLines={logLines}
67-
logLineIdToIdx={logLineIdToIdx}
92+
visualLogState={visualLogState}
6893
selectedLine={selectedLine}
6994
selectedMemSlotId={selectedMemSlotId}
7095
selectedCLine={selectedCLine}
@@ -90,8 +115,8 @@ const ContentRaw = ({
90115
const Content = React.memo(ContentRaw);
91116

92117
function App() {
93-
const [verifierLogState, setVerifierLogState] = useState<VerifierLogState>(
94-
getEmptyVerifierState(),
118+
const [visualLogState, setVisualLogState] = useState<VisualLogState>(
119+
getEmptyVisualLogState(),
95120
);
96121
const [hoveredState, setHoveredState] = useState<LogLineState>({
97122
memSlotId: "",
@@ -108,22 +133,8 @@ function App() {
108133

109134
const fileInputRef = useRef<HTMLInputElement>(null);
110135

111-
const { cLines, cLineIdtoIdx } = verifierLogState;
112-
113-
const [logLines, logLineIdToIdx] = useMemo(() => {
114-
const logLines: ParsedLine[] = [];
115-
const logLineIdToIdx: Map<number, number> = new Map();
116-
117-
let idx = 0;
118-
verifierLogState.lines.forEach((line) => {
119-
if (line.type !== ParsedLineType.C_SOURCE || fullLogView) {
120-
logLines.push(line);
121-
logLineIdToIdx.set(line.idx, idx++);
122-
}
123-
});
124-
125-
return [logLines, logLineIdToIdx];
126-
}, [verifierLogState, fullLogView]);
136+
const { verifierLogState, cLines, cLineIdtoIdx, logLines, logLineIdToIdx } =
137+
visualLogState;
127138

128139
const { line: selectedLine, memSlotId: selectedMemSlotId } = selectedState;
129140
const selectedLineIdx = logLineIdToIdx.get(selectedLine) || 0;
@@ -189,7 +200,7 @@ function App() {
189200
}
190201

191202
const onClear = useCallback(() => {
192-
setVerifierLogState(getEmptyVerifierState());
203+
setVisualLogState(getEmptyVisualLogState());
193204
setSelectedState({ line: 0, memSlotId: "", cLine: "" });
194205
const fiCurrent = fileInputRef.current;
195206
if (fiCurrent) {
@@ -199,7 +210,18 @@ function App() {
199210

200211
const onLogToggle = useCallback(() => {
201212
setfullLogView((prev) => !prev);
202-
}, []);
213+
const [newLogLines, newLogLineIdToIdx] = getVisibleLogLines(
214+
verifierLogState,
215+
!fullLogView,
216+
);
217+
setVisualLogState((prev) => {
218+
return {
219+
...prev,
220+
logLines: newLogLines,
221+
logLineIdToIdx: newLogLineIdToIdx,
222+
};
223+
});
224+
}, [fullLogView, verifierLogState]);
203225

204226
useEffect(() => {
205227
const handleKeyDown = (e: KeyboardEvent) => {
@@ -291,9 +313,13 @@ function App() {
291313
onGotoEnd();
292314
}, [verifierLogState]);
293315

294-
const loadInputText = useCallback((text: string) => {
295-
setVerifierLogState(processRawLines(text.split("\n")));
296-
}, []);
316+
const loadInputText = useCallback(
317+
(text: string) => {
318+
const newVerifierLogState = processRawLines(text.split("\n"));
319+
setVisualLogState(getVisualLogState(newVerifierLogState, fullLogView));
320+
},
321+
[fullLogView],
322+
);
297323

298324
const handlePaste = useCallback(
299325
(event: React.ClipboardEvent) => {
@@ -508,7 +534,8 @@ function App() {
508534
}
509535
rawLines = rawLines.concat(lines);
510536
}
511-
setVerifierLogState(processRawLines(rawLines));
537+
const newVerifierLogState = processRawLines(rawLines);
538+
setVisualLogState(getVisualLogState(newVerifierLogState, fullLogView));
512539
}
513540
},
514541
[],
@@ -562,9 +589,7 @@ function App() {
562589
</div>
563590
<Content
564591
loadError={loadError}
565-
verifierLogState={verifierLogState}
566-
logLines={logLines}
567-
logLineIdToIdx={logLineIdToIdx}
592+
visualLogState={visualLogState}
568593
selectedLine={selectedLine}
569594
selectedMemSlotId={selectedMemSlotId}
570595
selectedCLine={selectedCLine}

src/analyzer.ts

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
ParsedLine,
99
ParsedLineType,
1010
parseLine,
11-
getCLineId,
1211
KnownMessageInfoType,
1312
GlobalFuncValidInfo,
1413
InstructionLine,
@@ -79,8 +78,6 @@ export class CSourceMap {
7978
*/
8079
export type VerifierLogState = {
8180
lines: ParsedLine[];
82-
cLines: string[];
83-
cLineIdtoIdx: Map<string, number>;
8481
bpfStates: BpfState[];
8582
cSourceMap: CSourceMap;
8683
lastInsIdx: number;
@@ -332,8 +329,6 @@ function nextBpfState(
332329
export function getEmptyVerifierState(): VerifierLogState {
333330
return {
334331
lines: [],
335-
cLines: [],
336-
cLineIdtoIdx: new Map(),
337332
bpfStates: [],
338333
cSourceMap: new CSourceMap(),
339334
lastInsIdx: 0,
@@ -435,36 +430,10 @@ export function processRawLines(rawLines: string[]): VerifierLogState {
435430
cSourceMap.addCSourceLine(currentCSourceLine, idxsForCLine);
436431
}
437432

438-
const cLines = [];
439-
const cLineIdtoIdx: Map<string, number> = new Map();
440-
let i = 0;
441-
for (const [file, range] of cSourceMap.fileRange) {
442-
let unknownStart = 0;
443-
for (let j = range[0]; j < range[1]; ++j) {
444-
const cLineId = getCLineId(file, j);
445-
const sourceLine = cSourceMap.cSourceLines.get(cLineId);
446-
if (!sourceLine) {
447-
if (!unknownStart) {
448-
unknownStart = i;
449-
}
450-
continue;
451-
}
452-
if (unknownStart > 0) {
453-
cLines.push("");
454-
cLineIdtoIdx.set(cLineId, i++);
455-
}
456-
unknownStart = 0;
457-
cLines.push(cLineId);
458-
cLineIdtoIdx.set(cLineId, i++);
459-
}
460-
}
461-
462433
return {
463434
lines,
464435
bpfStates,
465436
cSourceMap,
466-
cLines,
467-
cLineIdtoIdx,
468437
lastInsIdx,
469438
};
470439
}

src/components.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ import {
2525

2626
import BPF_HELPERS_JSON from "./bpf-helpers.json";
2727

28+
export type VisualLogState = {
29+
verifierLogState: VerifierLogState;
30+
cLines: string[];
31+
cLineIdtoIdx: Map<string, number>;
32+
logLines: ParsedLine[];
33+
logLineIdToIdx: Map<number, number>;
34+
};
35+
2836
export type LogLineState = {
2937
memSlotId: string;
3038
line: number;
@@ -946,9 +954,7 @@ function CSourceLinesRaw({
946954
const CSourceLines = React.memo(CSourceLinesRaw);
947955

948956
export function MainContent({
949-
verifierLogState,
950-
logLines,
951-
logLineIdToIdx,
957+
visualLogState,
952958
selectedLine,
953959
selectedMemSlotId,
954960
selectedCLine,
@@ -959,9 +965,7 @@ export function MainContent({
959965
handleLogLinesOut,
960966
handleStateRowClick,
961967
}: {
962-
verifierLogState: VerifierLogState;
963-
logLines: ParsedLine[];
964-
logLineIdToIdx: Map<number, number>;
968+
visualLogState: VisualLogState;
965969
selectedLine: number;
966970
selectedMemSlotId: string;
967971
selectedCLine: number;
@@ -972,6 +976,8 @@ export function MainContent({
972976
handleLogLinesOut: (event: React.MouseEvent<HTMLDivElement>) => void;
973977
handleStateRowClick: (event: React.MouseEvent<HTMLDivElement>) => void;
974978
}) {
979+
const { verifierLogState, logLines, logLineIdToIdx, cLines, cLineIdtoIdx } =
980+
visualLogState;
975981
const memSlotDependencies: number[] = useMemo(() => {
976982
const lines = verifierLogState.lines;
977983
if (lines.length === 0) {
@@ -1206,14 +1212,14 @@ export function MainContent({
12061212
const cLineId =
12071213
verifierLogState.cSourceMap.logLineToCLine.get(selectedLine);
12081214
if (cLineId) {
1209-
const cLineIdx = verifierLogState.cLineIdtoIdx.get(cLineId);
1215+
const cLineIdx = cLineIdtoIdx.get(cLineId);
12101216
if (cLineIdx) {
1211-
scrollToCLine(cLineIdx, verifierLogState.cLines.length);
1217+
scrollToCLine(cLineIdx, cLines.length);
12121218
}
12131219
}
12141220
e.stopPropagation();
12151221
},
1216-
[verifierLogState, selectedCLine],
1222+
[verifierLogState, cLines, cLineIdtoIdx, selectedCLine],
12171223
);
12181224

12191225
const handleArrowsClick = useCallback(

src/utils.tsx

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { ParsedLine, ParsedLineType } from "./parser";
1+
import { VerifierLogState } from "./analyzer";
2+
import { getCLineId, ParsedLine, ParsedLineType } from "./parser";
23

34
export async function fetchLogFromUrl(url: string) {
45
try {
@@ -129,3 +130,51 @@ export function siblingInsLine(
129130
}
130131
return normalIdx(idx, n);
131132
}
133+
134+
export function getVisibleLogLines(
135+
verifierLogState: VerifierLogState,
136+
fullLogView: boolean,
137+
): [ParsedLine[], Map<number, number>] {
138+
const logLines: ParsedLine[] = [];
139+
const logLineIdToIdx: Map<number, number> = new Map();
140+
141+
let idx = 0;
142+
verifierLogState.lines.forEach((line) => {
143+
if (line.type !== ParsedLineType.C_SOURCE || fullLogView) {
144+
logLines.push(line);
145+
logLineIdToIdx.set(line.idx, idx++);
146+
}
147+
});
148+
149+
return [logLines, logLineIdToIdx];
150+
}
151+
152+
export function getVisibleCLines(
153+
verifierLogState: VerifierLogState,
154+
): [string[], Map<string, number>] {
155+
const cLines = [];
156+
const cLineIdtoIdx: Map<string, number> = new Map();
157+
let i = 0;
158+
const { cSourceMap } = verifierLogState;
159+
for (const [file, range] of cSourceMap.fileRange) {
160+
let unknownStart = 0;
161+
for (let j = range[0]; j < range[1]; ++j) {
162+
const cLineId = getCLineId(file, j);
163+
const sourceLine = cSourceMap.cSourceLines.get(cLineId);
164+
if (!sourceLine) {
165+
if (!unknownStart) {
166+
unknownStart = i;
167+
}
168+
continue;
169+
}
170+
if (unknownStart > 0) {
171+
cLines.push("");
172+
cLineIdtoIdx.set(cLineId, i++);
173+
}
174+
unknownStart = 0;
175+
cLines.push(cLineId);
176+
cLineIdtoIdx.set(cLineId, i++);
177+
}
178+
}
179+
return [cLines, cLineIdtoIdx];
180+
}

0 commit comments

Comments
 (0)