Skip to content

Commit 762003a

Browse files
committed
Merge remote-tracking branch 'upstream/main' into hide-scan-api
2 parents a069f3a + 72b4947 commit 762003a

34 files changed

Lines changed: 1914 additions & 1230 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/codegen/parser/generator/src/parser_definition.rs

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,10 @@ impl ParserDefinitionNodeExtensions for ParserDefinitionNode {
5252
let parser = if name.is_empty() {
5353
parser
5454
} else {
55+
let name = format_ident!("{}", name.to_pascal_case());
56+
5557
quote! {
56-
#parser.with_name(#name)
58+
#parser.with_name(FieldName::#name)
5759
}
5860
};
5961

@@ -68,8 +70,10 @@ impl ParserDefinitionNodeExtensions for ParserDefinitionNode {
6870
let parser = if name.is_empty() {
6971
parser
7072
} else {
73+
let name = format_ident!("{}", name.to_pascal_case());
74+
7175
quote! {
72-
#parser.with_name(#name)
76+
#parser.with_name(FieldName::#name)
7377
}
7478
};
7579

@@ -85,8 +89,10 @@ impl ParserDefinitionNodeExtensions for ParserDefinitionNode {
8589
if name.is_empty() {
8690
parser
8791
} else {
92+
let name = format_ident!("{}", name.to_pascal_case());
93+
8894
quote! {
89-
#parser.with_name(#name)
95+
#parser.with_name(FieldName::#name)
9096
}
9197
}
9298
}
@@ -110,8 +116,10 @@ impl ParserDefinitionNodeExtensions for ParserDefinitionNode {
110116
if name.is_empty() {
111117
parser
112118
} else {
119+
let name = format_ident!("{}", name.to_pascal_case());
120+
113121
quote! {
114-
#parser.with_name(#name)
122+
#parser.with_name(FieldName::#name)
115123
}
116124
}
117125
}
@@ -168,8 +176,8 @@ impl ParserDefinitionNodeExtensions for ParserDefinitionNode {
168176
}
169177

170178
Self::DelimitedBy(open, body, close) => {
171-
let open_field_name = &open.name;
172-
let close_field_name = &close.name;
179+
let open_field_name = format_ident!("{}", open.name.to_pascal_case());
180+
let close_field_name = format_ident!("{}", close.name.to_pascal_case());
173181
let [open_delim, close_delim] = match (open.as_ref(), close.as_ref()) {
174182
(
175183
ParserDefinitionNode::ScannerDefinition(open, ..),
@@ -197,38 +205,44 @@ impl ParserDefinitionNodeExtensions for ParserDefinitionNode {
197205
let mut delim_guard = input.open_delim(TokenKind::#close_delim);
198206
let input = delim_guard.ctx();
199207

200-
seq.elem_named(#open_field_name, self.parse_token_with_trivia::<#lex_ctx>(input, TokenKind::#open_delim))?;
208+
seq.elem_named(
209+
FieldName::#open_field_name,
210+
self.parse_token_with_trivia::<#lex_ctx>(input, TokenKind::#open_delim)
211+
)?;
201212
#body_parser
202-
seq.elem_named(#close_field_name, self.parse_token_with_trivia::<#lex_ctx>(input, TokenKind::#close_delim))?;
213+
seq.elem_named(
214+
FieldName::#close_field_name,
215+
self.parse_token_with_trivia::<#lex_ctx>(input, TokenKind::#close_delim)
216+
)?;
203217
seq.finish()
204218
})
205219
}
206220
}
207221

208222
Self::SeparatedBy(body, separator) => {
209-
let separator_field_name = &separator.name;
223+
let separator_field_name = format_ident!("{}", separator.name.to_pascal_case());
210224
let separator = match separator.as_ref() {
211225
ParserDefinitionNode::ScannerDefinition(scanner, ..) => {
212226
format_ident!("{name}", name = scanner.name())
213227
}
214228
_ => unreachable!("Only tokens are permitted as separators"),
215229
};
216230

217-
let body_field_name = &body.name;
231+
let body_field_name = format_ident!("{}", body.name.to_pascal_case());
218232
let parser = body.to_parser_code(context_name, is_trivia);
219233

220234
quote! {
221235
SeparatedHelper::run::<_, #lex_ctx>(
222236
input,
223237
self,
224-
|input| #parser.with_name(#body_field_name),
238+
|input| #parser.with_name(FieldName::#body_field_name),
225239
TokenKind::#separator,
226-
#separator_field_name,
240+
FieldName::#separator_field_name,
227241
)
228242
}
229243
}
230244
Self::TerminatedBy(body, terminator) => {
231-
let terminator_field_name = &terminator.name;
245+
let terminator_field_name = format_ident!("{}", terminator.name.to_pascal_case());
232246

233247
let terminator = match terminator.as_ref() {
234248
ParserDefinitionNode::ScannerDefinition(scanner, ..) => {
@@ -256,7 +270,7 @@ impl ParserDefinitionNodeExtensions for ParserDefinitionNode {
256270
SequenceHelper::run(|mut seq| {
257271
#body_parser
258272
seq.elem_named(
259-
#terminator_field_name,
273+
FieldName::#terminator_field_name,
260274
self.parse_token_with_trivia::<#lex_ctx>(input, TokenKind::#terminator)
261275
)?;
262276
seq.finish()
@@ -326,7 +340,9 @@ pub fn make_sequence_versioned(
326340
let code = if name.is_empty() {
327341
quote! { seq.elem(#parser)?; }
328342
} else {
329-
quote! { seq.elem_named(#name, #parser)?; }
343+
let field_name = format_ident!("{}", name.to_pascal_case());
344+
345+
quote! { seq.elem_named(FieldName::#field_name, #parser)?; }
330346
};
331347

332348
versions.wrap_code(code, None)

crates/codegen/parser/generator/src/rust_generator.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub struct RustGenerator {
2727
rule_kinds: BTreeSet<&'static str>,
2828
token_kinds: BTreeSet<&'static str>,
2929
trivia_kinds: BTreeSet<&'static str>,
30+
field_names: BTreeSet<String>,
3031

3132
top_level_scanner_names: BTreeSet<&'static str>,
3233
scanner_functions: Vec<(&'static str, String)>, // (name of scanner, code)
@@ -215,6 +216,17 @@ impl GrammarVisitor for RustGenerator {
215216
.into_values()
216217
.collect();
217218

219+
// Make sure empty strings are not there
220+
self.field_names.remove("");
221+
// These are built-in and already pre-defined
222+
// _SLANG_INTERNAL_RESERVED_NODE_FIELD_NAMES_ (keep in sync)
223+
self.field_names.remove("item");
224+
self.field_names.remove("variant");
225+
self.field_names.remove("separator");
226+
self.field_names.remove("operand");
227+
self.field_names.remove("left_operand");
228+
self.field_names.remove("right_operand");
229+
218230
// Just being anal about tidying up :)
219231
self.all_scanners.clear();
220232
self.current_context_name = "";
@@ -304,8 +316,29 @@ impl GrammarVisitor for RustGenerator {
304316
.scanner_definitions
305317
.insert(scanner.name());
306318
}
319+
320+
// Collect field names
321+
ParserDefinitionNode::Choice(choice) => {
322+
self.field_names.insert(choice.name.clone());
323+
}
324+
ParserDefinitionNode::Sequence(sequence) => {
325+
for node in sequence {
326+
self.field_names.insert(node.name.clone());
327+
}
328+
}
329+
ParserDefinitionNode::SeparatedBy(item, separator) => {
330+
self.field_names.insert(item.name.clone());
331+
self.field_names.insert(separator.name.clone());
332+
}
333+
ParserDefinitionNode::TerminatedBy(_, terminator) => {
334+
self.field_names.insert(terminator.name.clone());
335+
}
336+
307337
// Collect delimiters for each context
308338
ParserDefinitionNode::DelimitedBy(open, _, close) => {
339+
self.field_names.insert(open.name.clone());
340+
self.field_names.insert(close.name.clone());
341+
309342
let (open, close) = match (open.as_ref(), close.as_ref()) {
310343
(
311344
ParserDefinitionNode::ScannerDefinition(open, ..),

crates/codegen/parser/runtime/src/cst.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,19 @@ use std::rc::Rc;
33
use serde::Serialize;
44

55
use crate::cursor::Cursor;
6-
use crate::kinds::{RuleKind, TokenKind};
6+
use crate::kinds::{FieldName, RuleKind, TokenKind};
77
use crate::text_index::TextIndex;
88

99
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
1010
pub struct NamedNode {
11-
pub name: String,
11+
pub name: Option<FieldName>,
1212
pub node: Node,
1313
}
1414

1515
impl NamedNode {
1616
/// Creates an anonymous (nameless) node.
1717
pub fn anonymous(node: Node) -> Self {
18-
Self {
19-
name: String::new(),
20-
node,
21-
}
18+
Self { name: None, node }
2219
}
2320
}
2421

crates/codegen/parser/runtime/src/cursor.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::rc::Rc;
44

55
use crate::cst::{NamedNode, Node, RuleNode};
6-
use crate::kinds::{RuleKind, TokenKind};
6+
use crate::kinds::{FieldName, RuleKind, TokenKind};
77
use crate::text_index::{TextIndex, TextRange};
88

99
/// A [`PathNode`] that points to a [`RuleNode`].
@@ -134,14 +134,12 @@ impl Cursor {
134134
self.current.node.clone()
135135
}
136136

137-
pub fn node_name(&self) -> String {
138-
if let Some(parent) = self.path.last() {
139-
parent.rule_node.children[self.current.child_number]
140-
.name
141-
.clone()
142-
} else {
143-
String::new()
144-
}
137+
pub fn node_name(&self) -> Option<FieldName> {
138+
self.path.last().and_then(|parent| {
139+
let this = &parent.rule_node.children[self.current.child_number];
140+
141+
this.name
142+
})
145143
}
146144

147145
/// Returns the text offset that corresponds to the beginning of the currently pointed to node.

crates/codegen/parser/runtime/src/kinds.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,32 @@ impl RuleKind {
4444
}
4545
}
4646

47+
#[derive(
48+
Debug,
49+
Eq,
50+
Ord,
51+
PartialEq,
52+
PartialOrd,
53+
serde::Serialize,
54+
strum_macros::AsRefStr,
55+
strum_macros::Display,
56+
strum_macros::EnumString,
57+
)]
58+
#[cfg_attr(feature = "slang_napi_interfaces", /* derives `Clone` and `Copy` */ napi(string_enum, namespace = "kinds"))]
59+
#[cfg_attr(not(feature = "slang_napi_interfaces"), derive(Clone, Copy))]
60+
pub enum FieldName {
61+
// Built-in fields
62+
// _SLANG_INTERNAL_RESERVED_NODE_FIELD_NAMES_ (keep in sync)
63+
Item,
64+
Variant,
65+
Separator,
66+
Operand,
67+
LeftOperand,
68+
RightOperand,
69+
// Generated
70+
XXX,
71+
}
72+
4773
/// The lexical context of the scanner.
4874
#[derive(strum_macros::FromRepr, Clone, Copy)]
4975
pub(crate) enum LexicalContext {

crates/codegen/parser/runtime/src/support/parser_result.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ops::ControlFlow;
22

33
use crate::cst::{self, NamedNode};
4-
use crate::kinds::{RuleKind, TokenKind};
4+
use crate::kinds::{FieldName, RuleKind, TokenKind};
55
use crate::text_index::TextIndex;
66

77
#[derive(PartialEq, Eq, Clone, Debug)]
@@ -86,12 +86,12 @@ impl ParserResult {
8686
}
8787

8888
#[must_use]
89-
pub fn with_name(mut self, name: impl Into<String>) -> ParserResult {
89+
pub fn with_name(mut self, name: FieldName) -> ParserResult {
9090
if let Some(NamedNode {
9191
name: prev_name, ..
9292
}) = self.significant_node_mut()
9393
{
94-
*prev_name = name.into();
94+
*prev_name = Some(name);
9595
}
9696

9797
self

crates/codegen/parser/runtime/src/support/precedence_helper.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cst::{self, NamedNode};
2-
use crate::kinds::RuleKind;
2+
use crate::kinds::{FieldName, RuleKind};
33
use crate::support::parser_result::PrattElement::{self, Binary, Expression, Postfix, Prefix};
44
use crate::support::parser_result::{ParserResult, PrattOperatorMatch};
55

@@ -152,13 +152,17 @@ impl PrecedenceHelper {
152152
right: Option<PrattElement>| {
153153
assert!(left.is_some() || right.is_some());
154154

155-
let left_name = right.as_ref().map_or("operand", |_| "left_operand");
156-
let right_name = left.as_ref().map_or("operand", |_| "right_operand");
155+
let left_name = right
156+
.as_ref()
157+
.map_or(FieldName::Operand, |_| FieldName::LeftOperand);
158+
let right_name = left
159+
.as_ref()
160+
.map_or(FieldName::Operand, |_| FieldName::RightOperand);
157161

158162
let left_nodes = match left {
159163
Some(Expression { nodes }) => {
160164
vec![NamedNode {
161-
name: left_name.to_owned(),
165+
name: Some(left_name),
162166
node: cst::Node::rule(child_kind, nodes),
163167
}]
164168
}
@@ -169,7 +173,7 @@ impl PrecedenceHelper {
169173
let right_nodes = match right {
170174
Some(Expression { nodes }) => {
171175
vec![NamedNode {
172-
name: right_name.to_owned(),
176+
name: Some(right_name),
173177
node: cst::Node::rule(child_kind, nodes),
174178
}]
175179
}
@@ -181,7 +185,7 @@ impl PrecedenceHelper {
181185

182186
Expression {
183187
nodes: vec![NamedNode {
184-
name: "variant".into(),
188+
name: Some(FieldName::Variant),
185189
node: cst::Node::rule(kind, children),
186190
}],
187191
}

crates/codegen/parser/runtime/src/support/separated_helper.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::cst::{self, NamedNode};
2-
use crate::kinds::{IsLexicalContext, TokenKind};
2+
use crate::kinds::{FieldName, IsLexicalContext, TokenKind};
33
use crate::lexer::Lexer;
44
use crate::parse_error::ParseError;
55
use crate::support::parser_result::{ParserResult, SkippedUntil};
@@ -15,7 +15,7 @@ impl SeparatedHelper {
1515
lexer: &L,
1616
body_parser: impl Fn(&mut ParserContext<'_>) -> ParserResult,
1717
separator: TokenKind,
18-
separator_field_name: &str,
18+
separator_field_name: FieldName,
1919
) -> ParserResult {
2020
let mut accum = vec![];
2121
loop {

crates/codegen/parser/runtime/src/support/sequence_helper.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ops::ControlFlow;
22

33
use crate::cst::{self, NamedNode};
4-
use crate::kinds::TokenKind;
4+
use crate::kinds::{FieldName, TokenKind};
55
use crate::support::parser_result::{Match, ParserResult, PrattElement, SkippedUntil};
66

77
/// Keeps accumulating parses sequentially until it hits an incomplete or no match.
@@ -193,7 +193,7 @@ impl SequenceHelper {
193193
/// Shorthand for `self.elem(value.with_name(name))`.
194194
pub fn elem_named(
195195
&mut self,
196-
name: impl Into<String>,
196+
name: FieldName,
197197
value: ParserResult,
198198
) -> ControlFlow<ParserResult, &mut Self> {
199199
self.elem(value.with_name(name))

0 commit comments

Comments
 (0)