mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
visitor-less scopes
This commit is contained in:
parent
8b0298ce09
commit
c16530c988
3 changed files with 49 additions and 17 deletions
|
@ -5,7 +5,6 @@ use libsyntax2::{
|
|||
ast::{self, NameOwner},
|
||||
algo::{
|
||||
ancestors,
|
||||
visit::{visitor_ctx, VisitorCtx},
|
||||
walk::preorder,
|
||||
generate,
|
||||
},
|
||||
|
@ -52,24 +51,24 @@ fn compute_scopes(fn_def: ast::FnDef) -> FnScopes {
|
|||
|
||||
let mut scope = root;
|
||||
if let Some(body) = fn_def.body() {
|
||||
for child in body.syntax().children() {
|
||||
let _ = visitor_ctx((&mut scopes, &mut scope))
|
||||
.visit::<ast::LetStmt, _>(|stmt, (scopes, scope)| {
|
||||
*scope = scopes.new_scope(*scope);
|
||||
for stmt in body.statements() {
|
||||
match stmt {
|
||||
ast::Stmt::LetStmt(stmt) => {
|
||||
scope = scopes.new_scope(scope);
|
||||
if let Some(pat) = stmt.pat() {
|
||||
scopes.add_bindings(*scope, pat);
|
||||
scopes.add_bindings(scope, pat);
|
||||
}
|
||||
if let Some(expr) = stmt.initializer() {
|
||||
scopes.set_scope(expr.syntax(), *scope)
|
||||
scopes.set_scope(expr.syntax(), scope)
|
||||
}
|
||||
})
|
||||
.visit::<ast::ExprStmt, _>(|expr, (scopes, scope)| {
|
||||
scopes.set_scope(expr.syntax(), *scope)
|
||||
})
|
||||
.visit::<ast::Expr, _>(|expr, (scopes, scope)| {
|
||||
scopes.set_scope(expr.syntax(), *scope)
|
||||
})
|
||||
.accept(child);
|
||||
}
|
||||
ast::Stmt::ExprStmt(expr) => {
|
||||
scopes.set_scope(expr.syntax(), scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(expr) = body.expr() {
|
||||
scopes.set_scope(expr.syntax(), scope)
|
||||
}
|
||||
}
|
||||
scopes
|
||||
|
|
|
@ -116,9 +116,13 @@ impl<'a> AstNode<'a> for Block<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Block<'a> {
|
||||
pub fn let_stmts(self) -> impl Iterator<Item = LetStmt<'a>> + 'a {
|
||||
pub fn statements(self) -> impl Iterator<Item = Stmt<'a>> + 'a {
|
||||
super::children(self)
|
||||
}
|
||||
|
||||
pub fn expr(self) -> Option<Expr<'a>> {
|
||||
super::child_opt(self)
|
||||
}
|
||||
}
|
||||
|
||||
// BlockExpr
|
||||
|
@ -1370,6 +1374,31 @@ impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {}
|
|||
impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {}
|
||||
impl<'a> StaticDef<'a> {}
|
||||
|
||||
// Stmt
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Stmt<'a> {
|
||||
ExprStmt(ExprStmt<'a>),
|
||||
LetStmt(LetStmt<'a>),
|
||||
}
|
||||
|
||||
impl<'a> AstNode<'a> for Stmt<'a> {
|
||||
fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
|
||||
match syntax.kind() {
|
||||
EXPR_STMT => Some(Stmt::ExprStmt(ExprStmt { syntax })),
|
||||
LET_STMT => Some(Stmt::LetStmt(LetStmt { syntax })),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn syntax(self) -> SyntaxNodeRef<'a> {
|
||||
match self {
|
||||
Stmt::ExprStmt(inner) => inner.syntax(),
|
||||
Stmt::LetStmt(inner) => inner.syntax(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Stmt<'a> {}
|
||||
|
||||
// StructDef
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct StructDef<'a> {
|
||||
|
|
|
@ -437,9 +437,13 @@ Grammar(
|
|||
["pat", "Pat"],
|
||||
["initializer", "Expr"],
|
||||
]),
|
||||
"Stmt": (
|
||||
enum: ["ExprStmt", "LetStmt"],
|
||||
),
|
||||
"Block": (
|
||||
options: [["expr", "Expr"]],
|
||||
collections: [
|
||||
["let_stmts", "LetStmt"],
|
||||
["statements", "Stmt"],
|
||||
]
|
||||
),
|
||||
"ParamList": (
|
||||
|
|
Loading…
Reference in a new issue