mod expr;
mod item;
mod operators;
mod pattern;
mod stmt;
mod ty;
pub use expr::*;
pub use item::*;
pub use operators::*;
pub use pattern::*;
pub use stmt::*;
pub use ty::*;
pub use crate::lexer::Span;
use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct NodeId(pub u32);
impl NodeId {
pub const DUMMY: Self = Self(u32::MAX);
pub const fn new(id: u32) -> Self {
Self(id)
}
}
impl Default for NodeId {
fn default() -> Self {
Self::DUMMY
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Ident {
pub name: Arc<str>,
pub span: Span,
}
impl Ident {
pub fn new(name: impl Into<Arc<str>>, span: Span) -> Self {
Self {
name: name.into(),
span,
}
}
pub fn dummy(name: impl Into<Arc<str>>) -> Self {
Self {
name: name.into(),
span: Span::dummy(),
}
}
pub fn as_str(&self) -> &str {
&self.name
}
}
impl std::fmt::Display for Ident {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name)
}
}
impl AsRef<str> for Ident {
fn as_ref(&self) -> &str {
&self.name
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Path {
pub segments: Vec<PathSegment>,
pub span: Span,
}
impl Path {
pub fn new(segments: Vec<PathSegment>, span: Span) -> Self {
Self { segments, span }
}
pub fn from_ident(ident: Ident) -> Self {
let span = ident.span;
Self {
segments: vec![PathSegment::from_ident(ident)],
span,
}
}
pub fn is_simple(&self) -> bool {
self.segments.len() == 1 && self.segments[0].generics.is_empty()
}
pub fn last_ident(&self) -> Option<&Ident> {
self.segments.last().map(|s| &s.ident)
}
pub fn last_generics(&self) -> Option<&[GenericArg]> {
self.segments.last().map(|s| s.generics.as_slice())
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct PathSegment {
pub ident: Ident,
pub generics: Vec<GenericArg>,
}
impl PathSegment {
pub fn from_ident(ident: Ident) -> Self {
Self {
ident,
generics: Vec::new(),
}
}
pub fn simple(ident: Ident) -> Self {
Self::from_ident(ident)
}
pub fn with_generics(ident: Ident, generics: Vec<GenericArg>) -> Self {
Self { ident, generics }
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum GenericArg {
Type(Box<Type>),
Lifetime(Lifetime),
Const(Box<Expr>),
}
#[derive(Debug, Clone, PartialEq)]
pub struct Lifetime {
pub name: Ident,
pub span: Span,
}
impl Lifetime {
pub fn new(name: Ident, span: Span) -> Self {
Self { name, span }
}
pub fn is_static(&self) -> bool {
self.name.as_str() == "static"
}
pub fn is_anonymous(&self) -> bool {
self.name.as_str() == "_"
}
}
#[derive(Debug, Clone, PartialEq, Default)]
pub enum Visibility {
#[default]
Private,
Public(Span),
Crate(Span),
Super(Span),
Restricted { path: Path, span: Span },
}
impl Visibility {
pub fn is_public(&self) -> bool {
matches!(self, Visibility::Public(_))
}
pub fn span(&self) -> Option<Span> {
match self {
Visibility::Private => None,
Visibility::Public(span) => Some(*span),
Visibility::Crate(span) => Some(*span),
Visibility::Super(span) => Some(*span),
Visibility::Restricted { span, .. } => Some(*span),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub enum Mutability {
#[default]
Immutable,
Mutable,
}
impl Mutability {
pub fn is_mut(&self) -> bool {
matches!(self, Mutability::Mutable)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Attribute {
pub path: Path,
pub args: AttrArgs,
pub is_inner: bool,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum AttrArgs {
Empty,
Delimited(Vec<TokenTree>),
Eq(Box<Expr>),
}
#[derive(Debug, Clone, PartialEq)]
pub enum TokenTree {
Token(crate::lexer::Token),
Delimited {
delimiter: crate::lexer::Delimiter,
tokens: Vec<TokenTree>,
span: Span,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct Module {
pub attrs: Vec<Attribute>,
pub items: Vec<Item>,
pub span: Span,
}
impl Module {
pub fn new(attrs: Vec<Attribute>, items: Vec<Item>, span: Span) -> Self {
Self { attrs, items, span }
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Block {
pub stmts: Vec<Stmt>,
pub span: Span,
pub id: NodeId,
}
impl Block {
pub fn new(stmts: Vec<Stmt>, span: Span) -> Self {
Self {
stmts,
span,
id: NodeId::DUMMY,
}
}
pub fn is_empty(&self) -> bool {
self.stmts.is_empty()
}
pub fn tail_expr(&self) -> Option<&Expr> {
match self.stmts.last() {
Some(stmt) => match &stmt.kind {
StmtKind::Expr(expr) => Some(expr),
_ => None,
},
None => None,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct GenericParam {
pub ident: Ident,
pub kind: GenericParamKind,
pub attrs: Vec<Attribute>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub enum GenericParamKind {
Type {
bounds: Vec<TypeBound>,
default: Option<Box<Type>>,
},
Lifetime { bounds: Vec<Lifetime> },
Const {
ty: Box<Type>,
default: Option<Box<Expr>>,
},
}
#[derive(Debug, Clone, PartialEq)]
pub struct TypeBound {
pub path: Path,
pub is_maybe: bool,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct WhereClause {
pub predicates: Vec<WherePredicate>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct WherePredicate {
pub ty: Box<Type>,
pub bounds: Vec<TypeBound>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Generics {
pub params: Vec<GenericParam>,
pub where_clause: Option<WhereClause>,
pub span: Span,
}
impl Generics {
pub fn empty() -> Self {
Self::default()
}
pub fn is_empty(&self) -> bool {
self.params.is_empty() && self.where_clause.is_none()
}
}