build(rust): vendor rnix parser crate
This commit was merged in pull request #57.
This commit is contained in:
1 parent
cbdf482422
commit
82ad65a3a4
492 files changed
+67785
-1
No files matched your search
+464
@@ -0,0 +1,464 @@
|
||||
use crate::{NixLanguage, SyntaxKind, SyntaxKind::*, SyntaxNode, SyntaxToken};
|
||||
|
||||
use super::{operators::BinOpKind, support::*, AstNode, UnaryOpKind};
|
||||
use rowan::ast::{AstChildren, AstNode as OtherAstNode};
|
||||
|
||||
pub trait HasEntry: AstNode {
|
||||
fn entries(&self) -> AstChildren<Entry>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
children(self)
|
||||
}
|
||||
|
||||
fn attrpath_values(&self) -> AstChildren<AttrpathValue>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
children(self)
|
||||
}
|
||||
|
||||
fn inherits(&self) -> AstChildren<Inherit>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
children(self)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! node {
|
||||
(
|
||||
#[from($kind:ident)]
|
||||
$(#[$meta:meta])*
|
||||
struct $name:ident;
|
||||
) => {
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
$(#[$meta])*
|
||||
pub struct $name(pub(super) SyntaxNode);
|
||||
|
||||
impl std::fmt::Display for $name {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl rowan::ast::AstNode for $name {
|
||||
type Language = crate::NixLanguage;
|
||||
|
||||
fn can_cast(kind: crate::SyntaxKind) -> bool {
|
||||
kind == $kind
|
||||
}
|
||||
|
||||
fn cast(from: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(from.kind()) {
|
||||
Some(Self(from))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl $name {
|
||||
pub const KIND: SyntaxKind = $kind;
|
||||
}
|
||||
};
|
||||
(
|
||||
#[from($($variant:ident),* $(,)?)]
|
||||
$(#[$meta:meta])*
|
||||
enum $name:ident;
|
||||
) => {
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
$(#[$meta])*
|
||||
pub enum $name {
|
||||
$(
|
||||
$variant($variant),
|
||||
)*
|
||||
}
|
||||
|
||||
impl std::fmt::Display for $name {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl rowan::ast::AstNode for $name {
|
||||
type Language = NixLanguage;
|
||||
|
||||
fn can_cast(kind: SyntaxKind) -> bool {
|
||||
matches!(kind, $($variant::KIND)|*)
|
||||
}
|
||||
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
let res = match syntax.kind() {
|
||||
$(
|
||||
$variant::KIND => $name::$variant($variant(syntax))
|
||||
),*,
|
||||
_ => return None,
|
||||
};
|
||||
Some(res)
|
||||
}
|
||||
|
||||
fn syntax(&self) -> &SyntaxNode {
|
||||
match self {
|
||||
$(
|
||||
$name::$variant(it) => &it.0,
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
impl From<$variant> for $name {
|
||||
fn from(node: $variant) -> $name { $name::$variant(node) }
|
||||
}
|
||||
|
||||
impl TryFrom<$name> for $variant {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(node: $name) -> Result<$variant, ()> {
|
||||
match node {
|
||||
$name::$variant(it) => Ok(it),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! tg {
|
||||
(
|
||||
$(#[doc=$doc:tt])?
|
||||
$name:ident,
|
||||
$token:tt
|
||||
) => {
|
||||
$(#[doc=$doc])?
|
||||
pub fn $name(&self) -> Option<SyntaxToken> {
|
||||
token_u(self, T![$token])
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! ng {
|
||||
(
|
||||
$(#[$meta:meta])*
|
||||
$name:ident,
|
||||
$ty:ty,
|
||||
$i:expr
|
||||
) => {
|
||||
$(#[$meta])*
|
||||
pub fn $name(&self) -> Option<$ty> {
|
||||
nth(self, $i)
|
||||
}
|
||||
};
|
||||
(
|
||||
$(#[$meta:meta])*
|
||||
$name:ident,
|
||||
[$ty:ty]
|
||||
) => {
|
||||
$(#[$meta])*
|
||||
pub fn $name(&self) -> AstChildren<$ty> {
|
||||
children(self)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
node! { #[from(NODE_LITERAL)] struct Literal; }
|
||||
|
||||
node! {
|
||||
#[from(
|
||||
Apply,
|
||||
Assert,
|
||||
Error,
|
||||
IfElse,
|
||||
Select,
|
||||
Str,
|
||||
PathAbs,
|
||||
PathRel,
|
||||
PathHome,
|
||||
PathSearch,
|
||||
Literal,
|
||||
Lambda,
|
||||
LegacyLet,
|
||||
LetIn,
|
||||
List,
|
||||
BinOp,
|
||||
Paren,
|
||||
Root,
|
||||
AttrSet,
|
||||
UnaryOp,
|
||||
Ident,
|
||||
With,
|
||||
HasAttr,
|
||||
CurPos,
|
||||
)]
|
||||
/// An expression. The fundamental nix ast type.
|
||||
enum Expr;
|
||||
}
|
||||
|
||||
node! {
|
||||
#[from(
|
||||
Ident,
|
||||
Dynamic,
|
||||
Str,
|
||||
)]
|
||||
enum Attr;
|
||||
}
|
||||
|
||||
node! { #[from(NODE_IDENT)] struct Ident; }
|
||||
|
||||
impl Ident {
|
||||
// A NODE_IDENT may either have a nested TOKEN_OR if the identifier was "or" or TOKEN_IDENT for everything else
|
||||
tg! { ident_token, TOKEN_IDENT }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_APPLY)] struct Apply; }
|
||||
|
||||
impl Apply {
|
||||
ng! { lambda, Expr, 0 }
|
||||
ng! { argument, Expr, 1 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_ASSERT)] struct Assert; }
|
||||
|
||||
impl Assert {
|
||||
tg! { assert_token, assert }
|
||||
ng! { condition, Expr, 0 }
|
||||
ng! { body, Expr, 1 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_ATTRPATH)] struct Attrpath; }
|
||||
|
||||
impl Attrpath {
|
||||
ng! { attrs, [Attr] }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_DYNAMIC)] struct Dynamic; }
|
||||
|
||||
impl Dynamic {
|
||||
tg! { interpol_start_token, TOKEN_INTERPOL_START }
|
||||
ng! { expr, Expr, 0 }
|
||||
tg! { interpol_end_token, TOKEN_INTERPOL_END }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_ERROR)] struct Error; }
|
||||
|
||||
node! { #[from(NODE_IF_ELSE)] struct IfElse; }
|
||||
|
||||
impl IfElse {
|
||||
tg! { if_token, if }
|
||||
ng! { condition, Expr, 0 }
|
||||
tg! { then_token, then }
|
||||
ng! { body, Expr, 1 }
|
||||
tg! { else_token, else }
|
||||
ng! { else_body, Expr, 2 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_SELECT)] struct Select; }
|
||||
|
||||
impl Select {
|
||||
ng! { expr, Expr, 0 }
|
||||
tg! { dot_token, . }
|
||||
ng! { attrpath, Attrpath, 0 }
|
||||
tg! { or_token, or }
|
||||
ng! { default_expr, Expr, 1 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_INHERIT)] struct Inherit; }
|
||||
|
||||
impl Inherit {
|
||||
tg! { inherit_token, inherit }
|
||||
ng! { from, InheritFrom, 0 }
|
||||
ng! { attrs, [Attr] }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_INHERIT_FROM)] struct InheritFrom; }
|
||||
|
||||
impl InheritFrom {
|
||||
tg! { l_paren_token, '(' }
|
||||
ng! { expr, Expr, 0 }
|
||||
tg! { r_paren_token, ')' }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_PATH_ABS)] struct PathAbs; }
|
||||
node! { #[from(NODE_PATH_REL)] struct PathRel; }
|
||||
node! { #[from(NODE_PATH_HOME)] struct PathHome; }
|
||||
node! { #[from(NODE_PATH_SEARCH)] struct PathSearch; }
|
||||
|
||||
node! {
|
||||
#[from(
|
||||
PathAbs,
|
||||
PathRel,
|
||||
PathHome,
|
||||
PathSearch,
|
||||
)]
|
||||
enum Path;
|
||||
}
|
||||
|
||||
node! { #[from(NODE_STRING)] struct Str; }
|
||||
|
||||
node! { #[from(NODE_INTERPOL)] struct Interpol; }
|
||||
|
||||
impl Interpol {
|
||||
ng! { expr, Expr, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_LAMBDA)] struct Lambda; }
|
||||
|
||||
impl Lambda {
|
||||
ng! { param, Param, 0 }
|
||||
tg! { token_colon, : }
|
||||
ng! { body, Expr, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_LEGACY_LET)] struct LegacyLet; }
|
||||
|
||||
impl HasEntry for LegacyLet {}
|
||||
|
||||
impl LegacyLet {
|
||||
tg! { let_token, let }
|
||||
tg! { curly_open_token, '{' }
|
||||
tg! { curly_close_token, '}' }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_LET_IN)] struct LetIn; }
|
||||
|
||||
impl HasEntry for LetIn {}
|
||||
|
||||
impl LetIn {
|
||||
tg! { let_token, let }
|
||||
tg! { in_token, in }
|
||||
ng! { body, Expr, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_LIST)] struct List; }
|
||||
|
||||
impl List {
|
||||
tg! { l_brack_token, '[' }
|
||||
ng! { items, [Expr] }
|
||||
tg! { r_brack_token, ']' }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_BIN_OP)] struct BinOp; }
|
||||
|
||||
impl BinOp {
|
||||
ng! { lhs, Expr, 0 }
|
||||
|
||||
pub fn operator(&self) -> Option<BinOpKind> {
|
||||
children_tokens_u(self).find_map(|t| BinOpKind::from_kind(t.kind()))
|
||||
}
|
||||
|
||||
ng! { rhs, Expr, 1 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_PAREN)] struct Paren; }
|
||||
|
||||
impl Paren {
|
||||
tg! { l_paren_token, '(' }
|
||||
ng! { expr, Expr, 0 }
|
||||
tg! { r_paren_token, ')' }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_PAT_BIND)] struct PatBind; }
|
||||
|
||||
impl PatBind {
|
||||
ng! { ident, Ident, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_PAT_ENTRY)] struct PatEntry; }
|
||||
|
||||
impl PatEntry {
|
||||
ng! { ident, Ident, 0 }
|
||||
tg! { question_token, ? }
|
||||
ng! { default, Expr, 1 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_IDENT_PARAM)] struct IdentParam; }
|
||||
|
||||
impl IdentParam {
|
||||
ng! { ident, Ident, 0 }
|
||||
}
|
||||
|
||||
node! {
|
||||
#[from(
|
||||
Pattern,
|
||||
IdentParam,
|
||||
)]
|
||||
enum Param;
|
||||
}
|
||||
|
||||
node! { #[from(NODE_PATTERN)] struct Pattern; }
|
||||
|
||||
impl Pattern {
|
||||
tg! { at_token, @ }
|
||||
ng! { pat_entries, [PatEntry] }
|
||||
tg! { ellipsis_token, ... }
|
||||
ng! { pat_bind, PatBind, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_ROOT)] struct Root; }
|
||||
|
||||
impl Root {
|
||||
ng! { expr, Expr, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_ATTR_SET)] struct AttrSet; }
|
||||
|
||||
impl HasEntry for AttrSet {}
|
||||
|
||||
impl AttrSet {
|
||||
tg! { rec_token, rec }
|
||||
tg! { l_curly_token, '{' }
|
||||
tg! { r_curly_token, '}' }
|
||||
}
|
||||
|
||||
node! {
|
||||
#[from(
|
||||
Inherit,
|
||||
AttrpathValue,
|
||||
)]
|
||||
enum Entry;
|
||||
}
|
||||
|
||||
node! { #[from(NODE_ATTRPATH_VALUE)] struct AttrpathValue; }
|
||||
|
||||
impl AttrpathValue {
|
||||
ng! { attrpath, Attrpath, 0 }
|
||||
tg! { assign_token, = }
|
||||
ng! { value, Expr, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_UNARY_OP)] struct UnaryOp; }
|
||||
|
||||
impl UnaryOp {
|
||||
pub fn operator(&self) -> Option<UnaryOpKind> {
|
||||
children_tokens_u(self).find_map(|t| UnaryOpKind::from_kind(t.kind()))
|
||||
}
|
||||
ng! { expr, Expr, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_WITH)] struct With; }
|
||||
|
||||
impl With {
|
||||
tg! { with_token, with }
|
||||
ng! { namespace, Expr, 0 }
|
||||
tg! { semicolon_token, ; }
|
||||
ng! { body, Expr, 1 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_HAS_ATTR)] struct HasAttr; }
|
||||
|
||||
impl HasAttr {
|
||||
ng! { expr, Expr, 0 }
|
||||
tg! { question_token, ? }
|
||||
ng! { attrpath, Attrpath, 0 }
|
||||
}
|
||||
|
||||
node! { #[from(NODE_CUR_POS)] struct CurPos; }
|
||||
|
||||
impl CurPos {
|
||||
tg! { cur_pos_token, __curPos }
|
||||
}
|
||||
Reference in new issue
Block a user