use crate::parse::numpy::kind::NumPySectionKind;
use crate::syntax::{SyntaxKind, SyntaxNode, SyntaxToken};
macro_rules! define_node {
($name:ident, $kind:ident) => {
#[doc = concat!("Typed wrapper for `", stringify!($kind), "` syntax nodes.")]
#[derive(Debug)]
pub struct $name<'a>(pub(crate) &'a SyntaxNode);
impl<'a> $name<'a> {
pub fn cast(node: &'a SyntaxNode) -> Option<Self> {
(node.kind() == SyntaxKind::$kind).then(|| Self(node))
}
pub fn syntax(&self) -> &'a SyntaxNode {
self.0
}
}
};
}
define_node!(NumPyDocstring, NUMPY_DOCSTRING);
impl<'a> NumPyDocstring<'a> {
pub fn summary(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::SUMMARY)
}
pub fn extended_summary(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::EXTENDED_SUMMARY)
}
pub fn deprecation(&self) -> Option<NumPyDeprecation<'a>> {
self.0
.find_node(SyntaxKind::NUMPY_DEPRECATION)
.and_then(NumPyDeprecation::cast)
}
pub fn sections(&self) -> impl Iterator<Item = NumPySection<'a>> {
self.0.nodes(SyntaxKind::NUMPY_SECTION).filter_map(NumPySection::cast)
}
pub fn stray_lines(&self) -> impl Iterator<Item = &'a SyntaxToken> {
self.0.tokens(SyntaxKind::STRAY_LINE)
}
}
define_node!(NumPySection, NUMPY_SECTION);
impl<'a> NumPySection<'a> {
pub fn header(&self) -> NumPySectionHeader<'a> {
NumPySectionHeader::cast(
self.0
.find_node(SyntaxKind::NUMPY_SECTION_HEADER)
.expect("NUMPY_SECTION must have a NUMPY_SECTION_HEADER child"),
)
.unwrap()
}
pub fn section_kind(&self, source: &str) -> NumPySectionKind {
let name_text = self.header().name().text(source);
NumPySectionKind::from_name(&name_text.to_ascii_lowercase())
}
pub fn parameters(&self) -> impl Iterator<Item = NumPyParameter<'a>> {
self.0
.nodes(SyntaxKind::NUMPY_PARAMETER)
.filter_map(NumPyParameter::cast)
}
pub fn returns(&self) -> impl Iterator<Item = NumPyReturns<'a>> {
self.0.nodes(SyntaxKind::NUMPY_RETURNS).filter_map(NumPyReturns::cast)
}
pub fn yields(&self) -> impl Iterator<Item = NumPyYields<'a>> {
self.0.nodes(SyntaxKind::NUMPY_YIELDS).filter_map(NumPyYields::cast)
}
pub fn exceptions(&self) -> impl Iterator<Item = NumPyException<'a>> {
self.0
.nodes(SyntaxKind::NUMPY_EXCEPTION)
.filter_map(NumPyException::cast)
}
pub fn warnings(&self) -> impl Iterator<Item = NumPyWarning<'a>> {
self.0.nodes(SyntaxKind::NUMPY_WARNING).filter_map(NumPyWarning::cast)
}
pub fn see_also_items(&self) -> impl Iterator<Item = NumPySeeAlsoItem<'a>> {
self.0
.nodes(SyntaxKind::NUMPY_SEE_ALSO_ITEM)
.filter_map(NumPySeeAlsoItem::cast)
}
pub fn references(&self) -> impl Iterator<Item = NumPyReference<'a>> {
self.0
.nodes(SyntaxKind::NUMPY_REFERENCE)
.filter_map(NumPyReference::cast)
}
pub fn attributes(&self) -> impl Iterator<Item = NumPyAttribute<'a>> {
self.0
.nodes(SyntaxKind::NUMPY_ATTRIBUTE)
.filter_map(NumPyAttribute::cast)
}
pub fn methods(&self) -> impl Iterator<Item = NumPyMethod<'a>> {
self.0.nodes(SyntaxKind::NUMPY_METHOD).filter_map(NumPyMethod::cast)
}
pub fn body_text(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::BODY_TEXT)
}
}
define_node!(NumPySectionHeader, NUMPY_SECTION_HEADER);
impl<'a> NumPySectionHeader<'a> {
pub fn name(&self) -> &'a SyntaxToken {
self.0.required_token(SyntaxKind::NAME)
}
pub fn underline(&self) -> &'a SyntaxToken {
self.0.required_token(SyntaxKind::UNDERLINE)
}
}
define_node!(NumPyDeprecation, NUMPY_DEPRECATION);
impl<'a> NumPyDeprecation<'a> {
pub fn directive_marker(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DIRECTIVE_MARKER)
}
pub fn keyword(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::KEYWORD)
}
pub fn double_colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DOUBLE_COLON)
}
pub fn version(&self) -> &'a SyntaxToken {
self.0.required_token(SyntaxKind::VERSION)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
}
define_node!(NumPyParameter, NUMPY_PARAMETER);
impl<'a> NumPyParameter<'a> {
pub fn names(&self) -> impl Iterator<Item = &'a SyntaxToken> {
self.0.tokens(SyntaxKind::NAME)
}
pub fn colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::COLON)
}
pub fn r#type(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::TYPE)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
pub fn optional(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::OPTIONAL)
}
pub fn default_keyword(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DEFAULT_KEYWORD)
}
pub fn default_separator(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DEFAULT_SEPARATOR)
}
pub fn default_value(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DEFAULT_VALUE)
}
}
define_node!(NumPyReturns, NUMPY_RETURNS);
impl<'a> NumPyReturns<'a> {
pub fn name(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::NAME)
}
pub fn colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::COLON)
}
pub fn return_type(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::RETURN_TYPE)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
}
define_node!(NumPyYields, NUMPY_YIELDS);
impl<'a> NumPyYields<'a> {
pub fn name(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::NAME)
}
pub fn colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::COLON)
}
pub fn return_type(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::RETURN_TYPE)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
}
define_node!(NumPyException, NUMPY_EXCEPTION);
impl<'a> NumPyException<'a> {
pub fn r#type(&self) -> &'a SyntaxToken {
self.0.required_token(SyntaxKind::TYPE)
}
pub fn colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::COLON)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
}
define_node!(NumPyWarning, NUMPY_WARNING);
impl<'a> NumPyWarning<'a> {
pub fn r#type(&self) -> &'a SyntaxToken {
self.0.required_token(SyntaxKind::TYPE)
}
pub fn colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::COLON)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
}
define_node!(NumPySeeAlsoItem, NUMPY_SEE_ALSO_ITEM);
impl<'a> NumPySeeAlsoItem<'a> {
pub fn names(&self) -> impl Iterator<Item = &'a SyntaxToken> {
self.0.tokens(SyntaxKind::NAME)
}
pub fn colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::COLON)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
}
define_node!(NumPyReference, NUMPY_REFERENCE);
impl<'a> NumPyReference<'a> {
pub fn directive_marker(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DIRECTIVE_MARKER)
}
pub fn open_bracket(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::OPEN_BRACKET)
}
pub fn number(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::NUMBER)
}
pub fn close_bracket(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::CLOSE_BRACKET)
}
pub fn content(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::CONTENT)
}
}
define_node!(NumPyAttribute, NUMPY_ATTRIBUTE);
impl<'a> NumPyAttribute<'a> {
pub fn name(&self) -> &'a SyntaxToken {
self.0.required_token(SyntaxKind::NAME)
}
pub fn colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::COLON)
}
pub fn r#type(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::TYPE)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
}
define_node!(NumPyMethod, NUMPY_METHOD);
impl<'a> NumPyMethod<'a> {
pub fn name(&self) -> &'a SyntaxToken {
self.0.required_token(SyntaxKind::NAME)
}
pub fn colon(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::COLON)
}
pub fn description(&self) -> Option<&'a SyntaxToken> {
self.0.find_token(SyntaxKind::DESCRIPTION)
}
}