Avoid putting decorators in the function scope (#86)

This commit is contained in:
Charlie Marsh 2022-09-02 09:13:06 -04:00 committed by GitHub
parent bf4722a62f
commit c0131e65e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 54 deletions

View File

@ -15,3 +15,13 @@ def baz():
global my_var
global my_dict
my_dict[my_var] += 1
def dec(x):
return x
@dec
def f():
dec = 1
return dec

View File

@ -88,6 +88,7 @@ impl Checker<'_> {
impl Visitor for Checker<'_> {
fn visit_stmt(&mut self, stmt: &Stmt) {
println!("stmt: {:?}", stmt);
match &stmt.node {
StmtKind::Global { names } | StmtKind::Nonlocal { names } => {
// TODO(charlie): Handle doctests.
@ -109,18 +110,24 @@ impl Visitor for Checker<'_> {
}
}
}
StmtKind::FunctionDef { name, .. } => {
self.add_binding(
name.to_string(),
Binding {
kind: BindingKind::Definition,
used: None,
location: stmt.location,
},
);
self.push_scope(Scope::new(Function));
StmtKind::FunctionDef {
name,
decorator_list,
returns,
..
}
StmtKind::AsyncFunctionDef { name, .. } => {
| StmtKind::AsyncFunctionDef {
name,
decorator_list,
returns,
..
} => {
for expr in decorator_list {
self.visit_expr(expr);
}
for expr in returns {
self.visit_annotation(expr);
}
self.add_binding(
name.to_string(),
Binding {
@ -150,7 +157,23 @@ impl Visitor for Checker<'_> {
}
}
}
StmtKind::ClassDef { .. } => self.push_scope(Scope::new(Class)),
StmtKind::ClassDef {
bases,
keywords,
decorator_list,
..
} => {
for expr in bases {
self.visit_expr(expr)
}
for keyword in keywords {
self.visit_keyword(keyword)
}
for expr in decorator_list {
self.visit_expr(expr)
}
self.push_scope(Scope::new(Class))
}
StmtKind::Import { names } => {
for alias in names {
if alias.node.name.contains('.') && alias.node.asname.is_none() {

View File

@ -63,61 +63,22 @@ pub trait Visitor {
pub fn walk_stmt<V: Visitor + ?Sized>(visitor: &mut V, stmt: &Stmt) {
match &stmt.node {
StmtKind::FunctionDef {
args,
body,
decorator_list,
returns,
..
} => {
StmtKind::FunctionDef { args, body, .. } => {
visitor.visit_arguments(args);
for expr in decorator_list {
visitor.visit_expr(expr)
}
for expr in returns {
visitor.visit_annotation(expr);
}
for stmt in body {
visitor.visit_stmt(stmt)
}
}
StmtKind::AsyncFunctionDef {
args,
body,
decorator_list,
returns,
..
} => {
StmtKind::AsyncFunctionDef { args, body, .. } => {
visitor.visit_arguments(args);
for expr in decorator_list {
visitor.visit_expr(expr)
}
for expr in returns {
visitor.visit_annotation(expr);
}
for stmt in body {
visitor.visit_stmt(stmt)
}
}
StmtKind::ClassDef {
bases,
keywords,
body,
decorator_list,
..
} => {
for expr in bases {
visitor.visit_expr(expr)
}
for keyword in keywords {
visitor.visit_keyword(keyword)
}
StmtKind::ClassDef { body, .. } => {
for stmt in body {
visitor.visit_stmt(stmt)
}
for expr in decorator_list {
visitor.visit_expr(expr)
}
}
StmtKind::Return { value } => {
if let Some(expr) = value {