From ca9b9d88be88a59ee7743d5098cf6c447c721a3f Mon Sep 17 00:00:00 2001 From: JensLincke Date: Fri, 6 Oct 2023 17:40:42 +0200 Subject: [PATCH] fixed a lot of edit history bugs SQUASHED: AUTO-COMMIT-demos-tree-sitter-edit-history.md,AUTO-COMMIT-src-client-domain-code-chawathe-script-generator.js,AUTO-COMMIT-src-components-tools-lively-container.js,AUTO-COMMIT-test-chawathe-script-generator-test.js, --- demos/tree-sitter/edit-history.md | 53 +++++++++++++++++++ .../domain-code/chawathe-script-generator.js | 52 ++++++++++++------ src/components/tools/lively-container.js | 2 +- test/chawathe-script-generator-test.js | 46 +++++++++++++++- 4 files changed, 136 insertions(+), 17 deletions(-) create mode 100644 demos/tree-sitter/edit-history.md diff --git a/demos/tree-sitter/edit-history.md b/demos/tree-sitter/edit-history.md new file mode 100644 index 000000000..69112abd9 --- /dev/null +++ b/demos/tree-sitter/edit-history.md @@ -0,0 +1,53 @@ +# Edit History + + \ No newline at end of file diff --git a/src/client/domain-code/chawathe-script-generator.js b/src/client/domain-code/chawathe-script-generator.js index 77a1ad5bb..1de92e15f 100644 --- a/src/client/domain-code/chawathe-script-generator.js +++ b/src/client/domain-code/chawathe-script-generator.js @@ -45,9 +45,12 @@ function setLabel(node, label) { } function getLabel(node) { - node.label || label(node) + return node.label || label(node) } +function equals(node1, node2) { + return node1.id == node2.id && (getLabel(node1) == getLabel(node2)) +} // SOURCE: gumtree/core/src/main/java/com/github/gumtreediff/actions/EditScript.java @@ -143,6 +146,9 @@ export class Move extends Action { constructor(node, parent, pos) { super() + if (!node) { + debugger + } this.node = node this.parent = parent this.pos = pos @@ -163,11 +169,11 @@ export class Update extends Action { } } -function* preOrderIterator(node) { +export function* preOrderIterator(node) { yield node - for (let i = 0; i < node.childCount; i++) { - let ea = node.child(i) - preOrderIterator(ea) + for (let i = 0; i < node.children.length; i++) { + let ea = node.children[i] + yield * preOrderIterator(ea) } } @@ -205,13 +211,15 @@ export class ChawatheScriptGenerator { const cpyTreeIterator = preOrderIterator(this.cpySrc); - visit(this.origSrc, origTree => { + + for(let origTree of preOrderIterator(this.origSrc)) { + debugger const cpyTree = cpyTreeIterator.next().value; if (cpyTree) { this.origToCopy.set(origTree.id, cpyTree); this.copyToOrig.set(cpyTree.id, origTree); } - }) + } this.cpyMappings = mappings.clone() for (const m of this.origMappings) { @@ -239,26 +247,32 @@ export class ChawatheScriptGenerator { } generate() { - this.cpySrc - this.origDst +// let srcFakeRoot = {id: Math.round(Math.random() * 1000000), children: [this.cpySrc], meta: 'FakeRoot'} +// let dstFakeRoot = {id: Math.round(Math.random() * 1000000), children: [this.cpySrc], meta: 'FakeRoot'} + +// this.cpySrc.parent = srcFakeRoot +// this.origDst.parent = dstFakeRoot this.actions = new EditScript(); this.dstInOrder = new Set(); this.srcInOrder = new Set(); + + // cpyMappings.addMapping(srcFakeRoot, dstFakeRoot); const bfsDst = this.breadthFirst(this.origDst); for (const x of bfsDst) { let w; const y = x.parent; - if (!y) continue // root + + if (!y) continue; const z = getSrcForDst(this.cpyMappings, y); if (!isDstMapped(this.cpyMappings, x)) { const k = this.findPos(x); // Insertion case: insert new node. - w = {children: []}; + w = {id: Math.round(Math.random() * 1000000), children: [], meta: "InsertNewNode"}; // In order to use the real nodes from the second tree, we // furnish x instead of w const ins = new Insert(x, this.copyToOrig.get(z.id), k); @@ -268,15 +282,23 @@ export class ChawatheScriptGenerator { insertChild(z, w, k); } else { w = getSrcForDst(this.cpyMappings, x); - if (!x.equals(this.origDst)) { + if (!equals(x, this.origDst)) { // not root + const v = w.parent; if (getLabel(w) !== getLabel(x)) { - this.actions.add(new Update(this.copyToOrig.get(w.id), getLabel(x))); + + const node = this.copyToOrig.get(w.id) + if (!node) {debugger} + this.actions.add(new Update(node, getLabel(x))); setLabel(w, getLabel(x)); } - if (!z.equals(v)) { + if (!equals(z, v)) { const k = this.findPos(x); - const mv = new Move(this.copyToOrig.get(w.id), this.copyToOrig.get(z.id), k); + const node = this.copyToOrig.get(w.id) + // if (!node) { + // continue + // } + const mv = new Move(node, this.copyToOrig.get(z.id), k); this.actions.add(mv); const oldk = positionInParent(w); w.parent.children.splice(oldk, 1); diff --git a/src/components/tools/lively-container.js b/src/components/tools/lively-container.js index d3caeb3b1..4c83a5fba 100644 --- a/src/components/tools/lively-container.js +++ b/src/components/tools/lively-container.js @@ -735,7 +735,7 @@ export default class Container extends Morph { console.groupEnd("run test: " + this.getPath()); } } else { - lively.notify("no test-runner to run " + url.toString().replace(/.*\//,"")); + lively.notify("no test-runner to run " + listOfTests.toString().replace(/.*\//,"")); } } diff --git a/test/chawathe-script-generator-test.js b/test/chawathe-script-generator-test.js index ef7a22472..0a43a6bce 100644 --- a/test/chawathe-script-generator-test.js +++ b/test/chawathe-script-generator-test.js @@ -3,7 +3,7 @@ import { expect } from 'src/external/chai.js'; import { Parser, JavaScript, match, parseAll, query, addMapping } from 'src/client/tree-sitter.js'; // test internals -import { ChawatheScriptGenerator, EditScript, Insert} from 'src/client/domain-code/chawathe-script-generator.js'; +import { ChawatheScriptGenerator, EditScript, Insert, preOrderIterator} from 'src/client/domain-code/chawathe-script-generator.js'; describe('ChawatheScriptGenerator', () => { @@ -33,6 +33,50 @@ describe('ChawatheScriptGenerator', () => { }) + describe('preOrderIterator', () => { + + it("iterate over tree", () => { + + + let [tree] = parseAll([`3`]) + + var generator = new ChawatheScriptGenerator() + var iter = preOrderIterator(tree) + + var count = 0 + + while(iter.next().value) { + count ++ + } + + + expect(count).to.equal(3) + + }) + + + it("iterate manually", () => { + + + let [tree] = parseAll([`3`]) + + var generator = new ChawatheScriptGenerator() + var iter = preOrderIterator(tree) + + var count = 0 + + var program = iter.next().value + var expr = iter.next().value + var number = iter.next().value + + + + expect(number.type).to.equal("number") + + }) + }) + + describe('generate', () => { it("finds actions", () => {