Skip to content
This repository was archived by the owner on Jul 27, 2023. It is now read-only.

Refactor if statement, introduce nodes for elif and else #22

Merged
merged 2 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions ast/src/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,12 +650,12 @@ pub struct StmtIf {
pub range: TextRange,
pub test: Box<Expr>,
pub body: Vec<Stmt>,
pub orelse: Vec<Stmt>,
pub elif_else_clauses: Vec<ElifElseClause>,
}

impl Node for StmtIf {
const NAME: &'static str = "If";
const FIELD_NAMES: &'static [&'static str] = &["test", "body", "orelse"];
const FIELD_NAMES: &'static [&'static str] = &["test", "body", "elif_else_clauses"];
}
impl From<StmtIf> for Stmt {
fn from(payload: StmtIf) -> Self {
Expand All @@ -668,6 +668,18 @@ impl From<StmtIf> for Ast {
}
}

#[derive(Clone, Debug, PartialEq)]
pub struct ElifElseClause {
pub range: TextRange,
pub test: Option<Expr>,
pub body: Vec<Stmt>,
}

impl Node for ElifElseClause {
const NAME: &'static str = "ElifElse";
const FIELD_NAMES: &'static [&'static str] = &["test", "body"];
}
Comment on lines +678 to +681
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to your change (and this PR): I think we can remove this. It was added for the Pyo3 support which I believe we removed too?


/// See also [With](https://docs.python.org/3/library/ast.html#ast.With)
#[derive(Clone, Debug, PartialEq)]
pub struct StmtWith {
Expand Down
5 changes: 5 additions & 0 deletions ast/src/ranged.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ impl Ranged for crate::generic::StmtIf {
self.range
}
}
impl Ranged for crate::generic::ElifElseClause {
fn range(&self) -> TextRange {
self.range
}
}
impl Ranged for crate::generic::StmtWith {
fn range(&self) -> TextRange {
self.range
Expand Down
31 changes: 15 additions & 16 deletions parser/src/python.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -760,25 +760,24 @@ ClassPattern: ast::Pattern = {
}

IfStatement: ast::Stmt = {
<location:@L> "if" <test:NamedExpressionTest> ":" <body:Suite> <s2:(<@L> "elif" <NamedExpressionTest> ":" <Suite>)*> <s3:("else" ":" <Suite>)?> => {
// Determine last else:
let mut last = s3.unwrap_or_default();
let end_location = last
<location:@L> "if" <test:NamedExpressionTest> ":" <body:Suite> <s2:(<@L> "elif" <NamedExpressionTest> ":" <Suite>)*> <s3:(<@L> "else" ":" <Suite>)?> => {
let elif_else_clauses: Vec<_> = s2.into_iter().map(|(start, test, body)| ast::ElifElseClause {
range: (start..body.last().unwrap().end()).into(),
test: Some(test),
body,
}).chain(s3.into_iter().map(|(start, body)| ast::ElifElseClause {
range: (start..body.last().unwrap().end()).into(),
test: None,
body,
})).collect();

let end_location = elif_else_clauses
.last()
.or_else(|| s2.last().and_then(|last| last.2.last()))
.or_else(|| body.last())
.unwrap()
.end();
// handle elif:
for i in s2.into_iter().rev() {
let x = ast::Stmt::If(
ast::StmtIf { test: Box::new(i.1), body: i.2, orelse: last, range: (i.0..end_location).into() }
);
last = vec![x];
}
.map(|last| last.end())
.unwrap_or_else(|| body.last().unwrap().end());

ast::Stmt::If(
ast::StmtIf { test: Box::new(test), body, orelse: last, range: (location..end_location).into() }
ast::StmtIf { test: Box::new(test), body, elif_else_clauses, range: (location..end_location).into() }
)
},
};
Expand Down
21,101 changes: 10,635 additions & 10,466 deletions parser/src/python.rs

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.