fix AST for if expressions

then is not always a block...
This commit is contained in:
Aleksey Kladov 2019-01-27 00:23:07 +03:00
parent 2d337c88b0
commit 619af1e22c
6 changed files with 112 additions and 5 deletions

View file

@ -285,13 +285,27 @@ impl LetStmt {
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ElseBranchFlavor<'a> {
Block(&'a Block),
IfExpr(&'a IfExpr),
}
impl IfExpr {
pub fn then_branch(&self) -> Option<&Block> {
self.blocks().nth(0)
}
pub fn else_branch(&self) -> Option<&Block> {
self.blocks().nth(1)
pub fn else_branch(&self) -> Option<ElseBranchFlavor> {
let res = match self.blocks().nth(1) {
Some(block) => ElseBranchFlavor::Block(block),
None => {
let elif: &IfExpr = child_opt(self)?;
ElseBranchFlavor::IfExpr(elif)
}
};
Some(res)
}
fn blocks(&self) -> AstChildren<Block> {
children(self)
}

View file

@ -660,6 +660,50 @@ impl ToOwned for DynTraitType {
impl DynTraitType {}
// ElseBranch
#[derive(Debug, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct ElseBranch {
pub(crate) syntax: SyntaxNode,
}
unsafe impl TransparentNewType for ElseBranch {
type Repr = rowan::SyntaxNode<RaTypes>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ElseBranchKind<'a> {
Block(&'a Block),
IfExpr(&'a IfExpr),
}
impl AstNode for ElseBranch {
fn cast(syntax: &SyntaxNode) -> Option<&Self> {
match syntax.kind() {
| BLOCK
| IF_EXPR => Some(ElseBranch::from_repr(syntax.into_repr())),
_ => None,
}
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl ToOwned for ElseBranch {
type Owned = TreeArc<ElseBranch>;
fn to_owned(&self) -> TreeArc<ElseBranch> { TreeArc::cast(self.syntax.to_owned()) }
}
impl ElseBranch {
pub fn kind(&self) -> ElseBranchKind {
match self.syntax.kind() {
BLOCK => ElseBranchKind::Block(Block::cast(&self.syntax).unwrap()),
IF_EXPR => ElseBranchKind::IfExpr(IfExpr::cast(&self.syntax).unwrap()),
_ => unreachable!(),
}
}
}
impl ElseBranch {}
// EnumDef
#[derive(Debug, PartialEq, Eq, Hash)]
#[repr(transparent)]