Live-preview: Prospective fix for panic when moving a component

We were trying to convert a node to a wrong kind of node.
Then of course it didn't have the expected children

In debug mode you'd have
```
assertion `left == right` failed
  left: SubElement
 right: Component
```
from the debug_assert! in `$Node::from`

I changed the call to `.into` to a call to `$Node::new` that return an
option.

Also made the debug_assert into an assert and added track_caller so such
problem are easier to debug in the future. (Retrospectively, we probably
shouldn't have derived From for $Node)

Fix #5642

The change contains no tests because the is_recursive_inclusion function
is currently not tested and would need some effort to create a test
This commit is contained in:
Olivier Goffart 2024-07-19 19:11:50 +02:00
parent 62c55dd188
commit 5acc7dd42a
2 changed files with 15 additions and 10 deletions

View file

@ -118,29 +118,32 @@ macro_rules! node_accessors {
};
(@ 2 $kind:ident) => {
#[allow(non_snake_case)]
#[track_caller]
pub fn $kind(&self) -> ($kind, $kind) {
let mut it = self.0.children().filter(|n| n.kind() == SyntaxKind::$kind);
let a = it.next().unwrap();
let b = it.next().unwrap();
debug_assert!(it.next().is_none());
let a = it.next().expect(stringify!("Missing first ", $kind));
let b = it.next().expect(stringify!("Missing second ", $kind));
debug_assert!(it.next().is_none(), stringify!("More ", $kind, " than expected"));
(a.into(), b.into())
}
};
(@ 3 $kind:ident) => {
#[allow(non_snake_case)]
#[track_caller]
pub fn $kind(&self) -> ($kind, $kind, $kind) {
let mut it = self.0.children().filter(|n| n.kind() == SyntaxKind::$kind);
let a = it.next().unwrap();
let b = it.next().unwrap();
let c = it.next().unwrap();
debug_assert!(it.next().is_none());
let a = it.next().expect(stringify!("Missing first ", $kind));
let b = it.next().expect(stringify!("Missing second ", $kind));
let c = it.next().expect(stringify!("Missing third ", $kind));
debug_assert!(it.next().is_none(), stringify!("More ", $kind, " than expected"));
(a.into(), b.into(), c.into())
}
};
(@ $kind:ident) => {
#[allow(non_snake_case)]
#[track_caller]
pub fn $kind(&self) -> $kind {
self.0.child_node(SyntaxKind::$kind).unwrap().into()
self.0.child_node(SyntaxKind::$kind).expect(stringify!("Missing ", $kind)).into()
}
};
@ -240,6 +243,7 @@ macro_rules! declare_syntax {
#[cfg(test)]
impl SyntaxNodeVerify for $nodekind {
const KIND: SyntaxKind = SyntaxKind::$nodekind;
#[track_caller]
fn verify(node: SyntaxNode) {
assert_eq!(node.kind(), Self::KIND);
verify_node!(node, $children);
@ -255,8 +259,9 @@ macro_rules! declare_syntax {
}
impl From<SyntaxNode> for $nodekind {
#[track_caller]
fn from(node: SyntaxNode) -> Self {
debug_assert_eq!(node.kind(), SyntaxKind::$nodekind);
assert_eq!(node.kind(), SyntaxKind::$nodekind);
Self(node)
}
}