Use dedicated AST nodes on MemberKind (#6374)

## Summary

This PR leverages the unified function definition node to add precise
AST node types to `MemberKind`, which is used to power our docstring
definition tracking (e.g., classes and functions, whether they're
methods or functions or nested functions and so on, whether they have a
docstring, etc.). It was painful to do this in the past because the
function variants needed to support a union anyway, but storing precise
nodes removes like a dozen panics.

No behavior changes -- purely a refactor.

## Test Plan

`cargo test`
This commit is contained in:
Charlie Marsh 2023-08-07 13:17:58 -04:00 committed by GitHub
parent daefa74e9a
commit c439435615
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 316 additions and 414 deletions

View file

@ -1,15 +0,0 @@
use crate::{nodes, Decorator, Stmt};
pub fn name(stmt: &Stmt) -> &str {
let Stmt::FunctionDef(nodes::StmtFunctionDef { name, .. }) = stmt else {
panic!("Expected Stmt::FunctionDef")
};
name.as_str()
}
pub fn decorator_list(stmt: &Stmt) -> &[Decorator] {
let Stmt::FunctionDef(nodes::StmtFunctionDef { decorator_list, .. }) = stmt else {
panic!("Expected Stmt::FunctionDef")
};
decorator_list
}

View file

@ -20,6 +20,32 @@ pub trait Identifier {
fn identifier(&self) -> TextRange;
}
impl Identifier for ast::StmtFunctionDef {
/// Return the [`TextRange`] of the identifier in the given function definition.
///
/// For example, return the range of `f` in:
/// ```python
/// def f():
/// ...
/// ```
fn identifier(&self) -> TextRange {
self.name.range()
}
}
impl Identifier for ast::StmtClassDef {
/// Return the [`TextRange`] of the identifier in the given class definition.
///
/// For example, return the range of `C` in:
/// ```python
/// class C():
/// ...
/// ```
fn identifier(&self) -> TextRange {
self.name.range()
}
}
impl Identifier for Stmt {
/// Return the [`TextRange`] of the identifier in the given statement.
///
@ -30,8 +56,8 @@ impl Identifier for Stmt {
/// ```
fn identifier(&self) -> TextRange {
match self {
Stmt::ClassDef(ast::StmtClassDef { name, .. })
| Stmt::FunctionDef(ast::StmtFunctionDef { name, .. }) => name.range(),
Stmt::ClassDef(class) => class.identifier(),
Stmt::FunctionDef(function) => function.identifier(),
_ => self.range(),
}
}

View file

@ -3,7 +3,6 @@ use std::path::Path;
pub mod all;
pub mod call_path;
pub mod cast;
pub mod comparable;
pub mod docstrings;
pub mod hashable;