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}