fix and simplify cycle detection

pull/1405/head
Rich Harris 7 years ago
parent 968b7956a4
commit 367f062e4e

@ -50,29 +50,29 @@ assign(Store.prototype, {
var computed = this._computed; var computed = this._computed;
var sorted = this._sortedComputedProperties = []; var sorted = this._sortedComputedProperties = [];
var visited = blankObject(); var visited = blankObject();
var cycles = blankObject(); var currentKey;
function visit(key) { function visit(key) {
if (visited[key]) return;
visited[key] = true;
var c = computed[key]; var c = computed[key];
if (c) { if (c) {
if (!cycles[key]) cycles[key] = blankObject();
c.deps.forEach(dep => { c.deps.forEach(dep => {
if (cycles[dep] && cycles[dep][key]) { if (dep === currentKey) {
throw new Error(`Cyclical dependency detected between ${dep} <-> ${key}`); throw new Error(`Cyclical dependency detected between ${dep} <-> ${key}`);
} }
cycles[key][dep] = true;
visit(dep); visit(dep);
}); });
if (!visited[key]) {
visited[key] = true;
sorted.push(c); sorted.push(c);
} }
} }
}
for (var key in this._computed) { for (var key in this._computed) {
visit(key); visit(currentKey = key);
} }
}, },

@ -141,8 +141,9 @@ describe('store', () => {
assert.throws(() => { assert.throws(() => {
store.compute('a', ['b'], b => b + 1); store.compute('a', ['b'], b => b + 1);
store.compute('b', ['a'], a => a + 1); store.compute('b', ['c'], c => c + 1);
}, /Cyclical dependency detected/); store.compute('c', ['a'], a => a + 1);
}, /Cyclical dependency detected between a <-> c/);
}); });
it('does not falsely report cycles', () => { it('does not falsely report cycles', () => {

Loading…
Cancel
Save