mirror of https://github.com/sveltejs/svelte
- fixes #3459 - uses DFS traversal to inspect reactive declarations for cycles - returns the cycle detected (e.g.; `a → b → a`) for error messagingpull/3516/head
parent
cc107147ec
commit
ee8825d34f
@ -0,0 +1,36 @@
|
||||
export default function checkGraphForCycles(edges: Array<[any, any]>): any[] {
|
||||
const graph: Map<any, any[]> = edges.reduce((g, edge) => {
|
||||
const [u, v] = edge;
|
||||
if (!g.has(u)) g.set(u, []);
|
||||
if (!g.has(v)) g.set(v, []);
|
||||
g.get(u).push(v);
|
||||
return g;
|
||||
}, new Map());
|
||||
|
||||
const visited = new Set();
|
||||
const onStack = new Set();
|
||||
const cycles = [];
|
||||
|
||||
function visit (v) {
|
||||
visited.add(v);
|
||||
onStack.add(v);
|
||||
|
||||
graph.get(v).forEach(w => {
|
||||
if (!visited.has(w)) {
|
||||
visit(w);
|
||||
} else if (onStack.has(w)) {
|
||||
cycles.push([...onStack, w]);
|
||||
}
|
||||
});
|
||||
|
||||
onStack.delete(v);
|
||||
}
|
||||
|
||||
graph.forEach((_, v) => {
|
||||
if (!visited.has(v)) {
|
||||
visit(v);
|
||||
}
|
||||
});
|
||||
|
||||
return cycles[0];
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
export default {
|
||||
html: `
|
||||
<p>2+2=4</p>
|
||||
`,
|
||||
|
||||
test({ assert, target }) {
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<p>2+2=4</p>
|
||||
`);
|
||||
}
|
||||
};
|
@ -0,0 +1,7 @@
|
||||
<script>
|
||||
$: c = a + b;
|
||||
$: a = 2;
|
||||
$: b = a;
|
||||
</script>
|
||||
|
||||
<p>{a}+{b}={c}</p>
|
@ -1,7 +1,7 @@
|
||||
[{
|
||||
"message": "Cyclical dependency detected",
|
||||
"message": "Cyclical dependency detected: a → b → a",
|
||||
"code": "cyclical-reactive-declaration",
|
||||
"start": { "line": 5, "column": 1, "character": 35 },
|
||||
"end": { "line": 5, "column": 14, "character": 48 },
|
||||
"pos": 35
|
||||
}]
|
||||
}]
|
||||
|
Loading…
Reference in new issue