Skip to content

Commit

Permalink
Add diff search
Browse files Browse the repository at this point in the history
  • Loading branch information
phschaad committed Sep 2, 2024
1 parent 74aee57 commit b518e24
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 22 deletions.
143 changes: 143 additions & 0 deletions src/sdfg_diff_viewr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import $ from 'jquery';

import {
DagreGraph,
findInGraph,
findInGraphPredicate,
graphFindRecursive,
htmlSanitize,
JsonSDFG,
JsonSDFGControlFlowRegion,
Expand Down Expand Up @@ -193,6 +196,100 @@ export abstract class SDFGDiffViewer {
public abstract outline(): void;
public abstract fill_info(elem: SDFGElement | DagreGraph | null): void;

protected findInDiffGraphPredicate(predicate: CallableFunction): void {
const lGraph = this.leftRenderer.get_graph();
const rGraph = this.rightRenderer.get_graph();
if (!lGraph || !rGraph)
return;

SDFVWebUI.getInstance().infoSetTitle('Search Results');

const lResults: (dagre.Node<SDFGElement> | dagre.GraphEdge)[] = [];
graphFindRecursive(lGraph, predicate, lResults);
const rResults: (dagre.Node<SDFGElement> | dagre.GraphEdge)[] = [];
graphFindRecursive(rGraph, predicate, rResults);

// Zoom to bounding box of all results first
if (lResults.length > 0)
this.leftRenderer.zoom_to_view(lResults);
if (rResults.length > 0)
this.rightRenderer.zoom_to_view(rResults);

const addedIDs: Map<string, [any, SDFGRenderer][]> = new Map();
const mergedResults: string[] = [];
for (const res of lResults) {
const existing = addedIDs.get(res.attributes().guid);
if (existing) {
existing.push([res, this.leftRenderer]);
} else {
const newEntry: [any, SDFGRenderer][] =
[[res, this.leftRenderer]];
addedIDs.set(res.attributes().guid, newEntry);
mergedResults.push(res.attributes().guid);
}
}
for (const res of rResults) {
const existing = addedIDs.get(res.attributes().guid);
if (existing) {
existing.push([res, this.rightRenderer]);
} else {
const newEntry: [any, SDFGRenderer][] =
[[res, this.rightRenderer]];
addedIDs.set(res.attributes().guid, newEntry);
mergedResults.push(res.attributes().guid);
}
}

// Show clickable results in sidebar
const sidebar = SDFVWebUI.getInstance().infoContentContainer;
if (sidebar) {
sidebar.html('');
for (const resId of mergedResults) {
const res = addedIDs.get(resId);
if (!res)
continue;

let status: ChangeState = 'nodiff';
const guid = res[0][0].attributes().guid;
if (this.diffMap?.changedKeys.has(guid))
status = 'changed';
else if (this.diffMap?.removedKeys.has(guid))
status = 'removed';
else if (this.diffMap?.addedKeys.has(guid))
status = 'added';

const d = $('<div>', {
class: `diff-outline-entry ${status}`,
html: htmlSanitize`${res[0][0].type()} ${res[0][0].label()}`,
click: () => {
for (const entry of res)
entry[1].zoom_to_view([entry[0]]);
},
});
d.on('mouseenter', () => {
for (const entry of res) {
if (!entry[0].highlighted) {
entry[0].highlighted = true;
entry[1].draw_async();
}
}
});
d.on('mouseleave', () => {
for (const entry of res) {
if (entry[0].highlighted) {
entry[0].highlighted = false;
entry[1].draw_async();
}
}
});

sidebar.append(d);
}
}

SDFVWebUI.getInstance().infoShow();
}

}

export class WebSDFGDiffViewer extends SDFGDiffViewer {
Expand Down Expand Up @@ -222,6 +319,28 @@ export class WebSDFGDiffViewer extends SDFGDiffViewer {
$(document).on(
'click.sdfv-diff', '#outline', this.outline.bind(this)
);
$(document).on(
'click.sdfv-diff', '#search-btn', (e) => {
e.preventDefault();
this.runSearch(false);
return false;
}
);
$(document).on(
'click.sdfv-diff', '#advsearch-btn', (e) => {
e.preventDefault();
this.runSearch(true);
return false;
}
);
$(document).on(
'keydown.sdfv-diff', '#search', (e) => {
if (e.key === 'Enter' || e.which === 13) {
this.runSearch(false);
e.preventDefault();
}
}
);
}

private deregisterEventListeners(): void {
Expand Down Expand Up @@ -551,6 +670,30 @@ export class WebSDFGDiffViewer extends SDFGDiffViewer {
SDFVWebUI.getInstance().infoShow();
}

public runSearch(advanced: boolean = false): void {
// Make sure the UI is not blocked during search.
setTimeout(() => {
const query = advanced ? $('#advsearch').val() : $('#search').val();
if (query) {
if (advanced) {
const predicate = eval(query.toString());
this.findInDiffGraphPredicate(predicate);
} else {
const caseSensitive = $('#search-case').is(':checked');
const queryString = caseSensitive ?
query.toString() : query.toString().toLowerCase();
this.findInDiffGraphPredicate(
(g: DagreGraph, elem: SDFGElement) => {
const text = caseSensitive ? elem.text_for_find() :
elem.text_for_find().toLowerCase();
return text.indexOf(queryString) !== -1;
}
);
}
}
}, 1);
}

public fill_info(elem: SDFGElement | DagreGraph | null): void {
// TODO: implement
console.log(elem);
Expand Down
43 changes: 21 additions & 22 deletions src/sdfv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
stringify_sdfg,
} from './utils/sdfg/json_serializer';
import { SDFVSettings } from './utils/sdfv_settings';
import { WebSDFGDiffViewer } from './sdfg_diff_viewr';
import { DiffMap, WebSDFGDiffViewer } from './sdfg_diff_viewr';

declare const vscode: any;

Expand Down Expand Up @@ -692,17 +692,14 @@ export class WebSDFV extends SDFV {
public runSearch(advanced: boolean = false): void {
// Make sure the UI is not blocked during search.
setTimeout(() => {
const graph = this.renderer?.get_graph();
const query = advanced ? $('#advsearch').val() : $('#search').val();
if (graph && query && this.renderer) {
if (query && this.renderer) {
if (advanced) {
const predicate = eval(query.toString());
find_in_graph_predicate(
this, this.renderer, graph, predicate
);
findInGraphPredicate(this.renderer, predicate);
} else {
find_in_graph(
this, this.renderer, graph, query.toString(),
findInGraph(
this.renderer, query.toString(),
$('#search-case').is(':checked')
);
}
Expand Down Expand Up @@ -791,16 +788,17 @@ function loadSDFGFromURL(url: string): void {
request.send();
}

function find_recursive(
graph: DagreGraph, predicate: CallableFunction, results: any[]
export function graphFindRecursive(
graph: DagreGraph, predicate: CallableFunction,
results: (dagre.Node<SDFGElement> | dagre.GraphEdge)[]
): void {
for (const nodeid of graph.nodes()) {
const node = graph.node(nodeid);
if (predicate(graph, node))
results.push(node);
// Enter states or nested SDFGs recursively
if (node.data.graph)
find_recursive(node.data.graph, predicate, results);
graphFindRecursive(node.data.graph, predicate, results);
}
for (const edgeid of graph.edges()) {
const edge = graph.edge(edgeid);
Expand All @@ -809,14 +807,17 @@ function find_recursive(
}
}

export function find_in_graph_predicate(
sdfv: SDFV, renderer: SDFGRenderer, sdfg: DagreGraph,
predicate: CallableFunction
export function findInGraphPredicate(
renderer: SDFGRenderer, predicate: CallableFunction
): void {
const sdfg = renderer.get_graph();
if (!sdfg)
return;

SDFVWebUI.getInstance().infoSetTitle('Search Results');

const results: any[] = [];
find_recursive(sdfg, predicate, results);
const results: (dagre.Node<SDFGElement> | dagre.GraphEdge)[] = [];
graphFindRecursive(sdfg, predicate, results);

// Zoom to bounding box of all results first
if (results.length > 0)
Expand Down Expand Up @@ -853,21 +854,19 @@ export function find_in_graph_predicate(
SDFVWebUI.getInstance().infoShow();
}

export function find_in_graph(
sdfv: SDFV, renderer: SDFGRenderer, sdfg: DagreGraph, query: string,
case_sensitive: boolean = false
export function findInGraph(
renderer: SDFGRenderer, query: string, case_sensitive: boolean = false
): void {
if (!case_sensitive)
query = query.toLowerCase();
find_in_graph_predicate(
sdfv, renderer, sdfg, (graph: DagreGraph, element: SDFGElement) => {
findInGraphPredicate(
renderer, (graph: DagreGraph, element: SDFGElement) => {
let text = element.text_for_find();
if (!case_sensitive)
text = text.toLowerCase();
return text.indexOf(query) !== -1;
}
);
SDFVWebUI.getInstance().infoSetTitle('Search Results for "' + query + '"');
}

function parseScriptParamValue(
Expand Down

0 comments on commit b518e24

Please sign in to comment.