From 451d759aa26c7840101a27d68d36f1e267187ed0 Mon Sep 17 00:00:00 2001 From: JensLincke Date: Tue, 9 Jan 2024 15:05:50 +0100 Subject: [PATCH] sandblocks_tree_matches wip SQUASHED: sandblocks_tree_matches, --- .../tools/sandblocks-tree-matches.html | 15 ++ .../tools/sandblocks-tree-matches.js | 135 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/components/tools/sandblocks-tree-matches.html create mode 100644 src/components/tools/sandblocks-tree-matches.js diff --git a/src/components/tools/sandblocks-tree-matches.html b/src/components/tools/sandblocks-tree-matches.html new file mode 100644 index 000000000..b29d7cfce --- /dev/null +++ b/src/components/tools/sandblocks-tree-matches.html @@ -0,0 +1,15 @@ + + diff --git a/src/components/tools/sandblocks-tree-matches.js b/src/components/tools/sandblocks-tree-matches.js new file mode 100644 index 000000000..093b0a86c --- /dev/null +++ b/src/components/tools/sandblocks-tree-matches.js @@ -0,0 +1,135 @@ + + +/*MD [Demo](browse://demos/tree-sitter/matches.md) MD*/ + +import Morph from 'src/components/widgets/lively-morph.js'; +import {visit, Parser, JavaScript, match} from 'src/client/tree-sitter.js'; + +export default class TreesitterMatches extends Morph { + + get livelyUpdateStrategy() { return 'inplace'; } + + async update() { + let graphviz = await () + + function renderTree(rootNode, clusterName) { + let dotEdges = [] + let dotNodes = [] + + visit(rootNode, node => { + dotNodes.push(`${node.id}[label="${node.type.replace(/\"/,'\\"')}"]`) + if (node.parent) dotEdges.push(`${node.parent.id} -> ${node.id}`) + }) + + return `subgraph ${clusterName} { + ${dotNodes.join(";\n")} + ${dotEdges.join(";\n")} + }` + + } + + function colorForPhase(phase) { + var colors = { + mapTrees_01: "green", + mapTrees_02: "green", + lastChanceMatch: "blue", + bottomUp: "red", + bottomUpRoot: "orange" + } + + if (!colors[phase]) { + debugger + } + + return colors[phase] || "gray" + } + + function labelFor(match) { + if (match.debugInfo && match.debugInfo.phase === "lastChanceMatch") { + return match.debugInfo.lastChanceCounter + } + return "" + } + + function tooltipFor(match) { + if (!match.debugInfo) return "" + var s = match.debugInfo.phase + if (match.debugInfo.time) { + s += " " + match.debugInfo.time +"ms" + } + return s + } + + function widthFor(match) { + if (match.debugInfo && match.debugInfo.time) { + return match.debugInfo.time * 1 + } + return 1 + } + + + function renderEdits(edits) { + let dotEdges = [] + // for(let match of matches) { + // dotEdges.push(`${match.node1.id} -> ${match.node2.id} [color="${match.debugInfo ? colorForPhase(match.debugInfo.phase) : "gray"}" penwidth="${widthFor(match)}" tooltip="${tooltipFor(match)}" label="${labelFor(match)}"]`) + // } + + for(let operation of edits.negBuf) { + // dotEdges.push(`${match.node1.id} -> ${match.node2.id} [color="${match.debugInfo ? colorForPhase(match.debugInfo.phase) : "gray"}" penwidth="${widthFor(match)}" tooltip="${tooltipFor(match)}" label="${labelFor(match)}"]`) + } + + + + return dotEdges.join(";\n") + } + + var source = `digraph { + rankdir=TB; + graph [ + splines="true" + overlap="false" ]; + node [ style="solid" shape="plain" fontname="Arial" fontsize="14" fontcolor="black" ]; + edge [ fontname="Arial" fontsize="8" ]; + ${renderTree(this.tree1.rootNode, "cluster_0")} + ${renderTree(this.tree2.rootNode, "cluster_1")} + ${renderEdits(this.edits)} + }` + graphviz.innerHTML = `<` +`script type="graphviz">${source}<` + `/script>}` + + graphviz.updateViz() + + this.get("#pane").innerHTML = "" + this.get("#pane").appendChild(graphviz) + } + + + async livelyExample() { + + +// var parser = new Parser(); +// parser.setLanguage(JavaScript); + +// let sourceCode1 = `class Test { +// foo(i) { +// if (i == 0) return "Foo!" +// } +// }` +// this.tree1 = parser.parse(sourceCode1); + +// let sourceCode2 = `class Test { +// foo(i) { +// if (i == 0) return "Bar" +// else if (i == -1) return "Foo!" +// } +// }` +// this.tree2 = parser.parse(sourceCode2); + +// this.matches = match(this.tree1.rootNode, this.tree2.rootNode) + +// this.update() + } + + + + +} \ No newline at end of file