lady_deirdre/syntax/
void.rs

1////////////////////////////////////////////////////////////////////////////////
2// This file is part of "Lady Deirdre", a compiler front-end foundation       //
3// technology.                                                                //
4//                                                                            //
5// This work is proprietary software with source-available code.              //
6//                                                                            //
7// To copy, use, distribute, or contribute to this work, you must agree to    //
8// the terms of the General License Agreement:                                //
9//                                                                            //
10// https://github.com/Eliah-Lakhin/lady-deirdre/blob/master/EULA.md           //
11//                                                                            //
12// The agreement grants a Basic Commercial License, allowing you to use       //
13// this work in non-commercial and limited commercial products with a total   //
14// gross revenue cap. To remove this commercial limit for one of your         //
15// products, you must acquire a Full Commercial License.                      //
16//                                                                            //
17// If you contribute to the source code, documentation, or related materials, //
18// you must grant me an exclusive license to these contributions.             //
19// Contributions are governed by the "Contributions" section of the General   //
20// License Agreement.                                                         //
21//                                                                            //
22// Copying the work in parts is strictly forbidden, except as permitted       //
23// under the General License Agreement.                                       //
24//                                                                            //
25// If you do not or cannot agree to the terms of this Agreement,              //
26// do not use this work.                                                      //
27//                                                                            //
28// This work is provided "as is", without any warranties, express or implied, //
29// except where such disclaimers are legally invalid.                         //
30//                                                                            //
31// Copyright (c) 2024 Ilya Lakhin (Илья Александрович Лахин).                 //
32// All rights reserved.                                                       //
33////////////////////////////////////////////////////////////////////////////////
34
35use std::{
36    any::TypeId,
37    fmt::{Debug, Formatter},
38    marker::PhantomData,
39};
40
41use crate::{
42    lexis::Token,
43    syntax::{AbstractNode, Capture, Key, Node, NodeRef, NodeRule, SyntaxSession, NON_RULE},
44};
45
46/// A Node without a syntax parser.
47///
48/// You are encouraged to use this object with
49/// the [Document](crate::units::Document) or
50/// the [MutableUnit](crate::units::MutableUnit) when you need an incremental
51/// lexical parser, but you don't need a syntax parser:
52/// `Document::<VoidSyntax<MyToken>>::new_mutable("foo bar baz")`.
53///
54/// This object makes the syntax parsing stage of the incremental reprarser
55/// a noop.
56#[derive(Clone, PartialEq, Eq)]
57#[repr(transparent)]
58pub struct VoidSyntax<T: Token> {
59    _token: PhantomData<T>,
60}
61
62impl<T: Token> Default for VoidSyntax<T> {
63    #[inline(always)]
64    fn default() -> Self {
65        Self {
66            _token: PhantomData,
67        }
68    }
69}
70
71impl<T: Token> Debug for VoidSyntax<T> {
72    #[inline(always)]
73    fn fmt(&self, formatter: &mut Formatter) -> std::fmt::Result {
74        formatter.write_str("NoSyntax")
75    }
76}
77
78impl<T: Token> AbstractNode for VoidSyntax<T> {
79    #[inline(always)]
80    fn rule(&self) -> NodeRule {
81        NON_RULE
82    }
83
84    #[inline(always)]
85    fn name(&self) -> Option<&'static str> {
86        None
87    }
88
89    #[inline(always)]
90    fn describe(&self, _verbose: bool) -> Option<&'static str> {
91        None
92    }
93
94    #[inline(always)]
95    fn node_ref(&self) -> NodeRef {
96        NodeRef::nil()
97    }
98
99    #[inline(always)]
100    fn parent_ref(&self) -> NodeRef {
101        NodeRef::nil()
102    }
103
104    #[inline(always)]
105    fn set_parent_ref(&mut self, _parent_ref: NodeRef) {}
106
107    #[inline(always)]
108    fn capture(&self, _key: Key) -> Option<Capture> {
109        None
110    }
111
112    #[inline(always)]
113    fn capture_keys(&self) -> &'static [Key<'static>] {
114        &[]
115    }
116
117    #[inline(always)]
118    fn rule_name(_rule: NodeRule) -> Option<&'static str>
119    where
120        Self: Sized,
121    {
122        None
123    }
124
125    #[inline(always)]
126    fn rule_description(_rule: NodeRule, _verbose: bool) -> Option<&'static str>
127    where
128        Self: Sized,
129    {
130        None
131    }
132}
133
134impl<T: Token> Node for VoidSyntax<T> {
135    type Token = T;
136
137    #[inline(always)]
138    fn parse<'code>(
139        _session: &mut impl SyntaxSession<'code, Node = Self>,
140        _rule: NodeRule,
141    ) -> Self {
142        Self::default()
143    }
144}
145
146#[inline(always)]
147pub(crate) fn is_void_syntax<N: Node>() -> bool {
148    TypeId::of::<N>() == TypeId::of::<VoidSyntax<N::Token>>()
149}