Skip to content

Commit

Permalink
fixed a lot of edit history bugs
Browse files Browse the repository at this point in the history
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,
  • Loading branch information
JensLincke committed Oct 6, 2023
1 parent fab6f5f commit ca9b9d8
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 17 deletions.
53 changes: 53 additions & 0 deletions demos/tree-sitter/edit-history.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Edit History

<script>
import {visit, Parser, JavaScript, match} from 'src/client/tree-sitter.js';
import { ChawatheScriptGenerator} from 'src/client/domain-code/chawathe-script-generator.js';


let editor1 = await (<lively-code-mirror style="display:inline-block; width: 400px; height: 200px; border: 1px solid gray"></lively-code-mirror>)
let editor2 = await (<lively-code-mirror style="display:inline-block; width: 400px; height: 200px; border: 1px solid gray"></lively-code-mirror>)


var parser = new Parser();
parser.setLanguage(JavaScript);
var list = <ul></ul>

// editor1.value = `let a = 3 + 4`
editor1.value = `3`
// editor2.value = `let a = 3 + 4\na++`
editor2.value = `4`

editor1.editor.on("change", (() => update()).debounce(500));
editor2.editor.on("change", (() => update()).debounce(500));


function update() {
let tree1 = parser.parse(editor1.value);
let tree2 = parser.parse(editor2.value );
let mappings = match(tree1.rootNode, tree2.rootNode, 0, 100)
var scriptGenerator = new ChawatheScriptGenerator()
scriptGenerator.initWith(tree1.rootNode, tree2.rootNode, mappings)

scriptGenerator.generate()

list.innerHTML = ""

for(let action of scriptGenerator.actions) {
list.appendChild(<li>{action.type} {action.node && action.node.type}
<button style="font-size:6pt" click={() => lively.openInspector(action)}>inspect</button>
</li>)
}

}

update()

let pane = <div>
{editor1}{editor2}
{list}
</div>


pane
</script>
52 changes: 37 additions & 15 deletions src/client/domain-code/chawathe-script-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
}
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/components/tools/lively-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(/.*\//,""));
}
}

Expand Down
46 changes: 45 additions & 1 deletion test/chawathe-script-generator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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", () => {
Expand Down

0 comments on commit ca9b9d8

Please sign in to comment.