import { useDebugSsa } from '../../api/queries/debug';
import { ApiError } from '../../api/client';
import { EmptyState } from '../../components/ui/EmptyState';
import { ErrorState } from '../../components/ui/ErrorState';
import { LoadingState } from '../../components/ui/LoadingState';
import type { SsaBlockView, SsaInstView } from '../../api/types';
interface SsaAnalysisPanelProps {
file: string;
functionName: string;
}
export function SsaAnalysisPanel({
file,
functionName,
}: SsaAnalysisPanelProps) {
const { data, isLoading, error } = useDebugSsa(file, functionName);
if (isLoading) {
return ;
}
if (error) {
if (error instanceof ApiError && error.status === 404) {
return (
);
}
return ;
}
if (!data) {
return ;
}
// Render entry block first, then the rest in order
const entryBlock = data.blocks.find((b) => b.id === data.entry);
const otherBlocks = data.blocks.filter((b) => b.id !== data.entry);
const ordered = entryBlock ? [entryBlock, ...otherBlocks] : data.blocks;
return (
{data.num_values} SSA values, {data.blocks.length} blocks
{ordered.map((block) => (
))}
);
}
function SsaBlock({
block,
isEntry,
}: {
block: SsaBlockView;
isEntry: boolean;
}) {
return (
B{block.id}
{isEntry && entry}
{block.preds.length > 0 && (
preds: {block.preds.map((p) => `B${p}`).join(', ')}
)}
{block.succs.length > 0 && (
succs: {block.succs.map((s) => `B${s}`).join(', ')}
)}
{block.phis.length > 0 && (
{block.phis.map((inst) => (
))}
)}
{block.body.map((inst) => (
))}
{block.terminator}
);
}
function SsaInstLine({ inst, isPhi }: { inst: SsaInstView; isPhi?: boolean }) {
const operands =
inst.operands.length > 0 ? `(${inst.operands.join(', ')})` : '';
return (
v{inst.value}
=
{inst.op}
{operands}
{inst.var_name && (
# {inst.var_name}
)}
L{inst.line}
);
}