aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/ast_src.rs147
-rw-r--r--xtask/src/codegen/gen_syntax.rs90
2 files changed, 133 insertions, 104 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 15bd8a2e4..3da280551 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -233,7 +233,12 @@ pub(crate) struct AstSrc<'a> {
233pub(crate) struct AstNodeSrc<'a> { 233pub(crate) struct AstNodeSrc<'a> {
234 pub(crate) name: &'a str, 234 pub(crate) name: &'a str,
235 pub(crate) traits: &'a [&'a str], 235 pub(crate) traits: &'a [&'a str],
236 pub(crate) fields: &'a [(&'a str, FieldSrc<'a>)], 236 pub(crate) fields: &'a [Field<'a>],
237}
238
239pub(crate) enum Field<'a> {
240 Token(&'a str),
241 Node { name: &'a str, src: FieldSrc<'a> },
237} 242}
238 243
239pub(crate) enum FieldSrc<'a> { 244pub(crate) enum FieldSrc<'a> {
@@ -251,31 +256,34 @@ pub(crate) struct AstEnumSrc<'a> {
251macro_rules! ast_nodes { 256macro_rules! ast_nodes {
252 ($( 257 ($(
253 struct $name:ident$(: $($trait:ident),*)? { 258 struct $name:ident$(: $($trait:ident),*)? {
254 $($field_name:ident $(: $ty:tt)?),*$(,)? 259 $($field_name:ident $(![$token:tt])? $(: $ty:tt)?),*$(,)?
255 } 260 }
256 )*) => { 261 )*) => {
257 [$( 262 [$(
258 AstNodeSrc { 263 AstNodeSrc {
259 name: stringify!($name), 264 name: stringify!($name),
260 traits: &[$($(stringify!($trait)),*)?], 265 traits: &[$($(stringify!($trait)),*)?],
261 fields: &[$( 266 fields: &[
262 (stringify!($field_name), field_ty!($field_name $($ty)?)) 267 $(field!($(T![$token])? $field_name $($ty)?)),*
263 ),*], 268 ],
264 269
265 } 270 }
266 ),*] 271 ),*]
267 }; 272 };
268} 273}
269 274
270macro_rules! field_ty { 275macro_rules! field {
276 (T![$token:tt] T) => {
277 Field::Token(stringify!($token))
278 };
271 ($field_name:ident) => { 279 ($field_name:ident) => {
272 FieldSrc::Shorthand 280 Field::Node { name: stringify!($field_name), src: FieldSrc::Shorthand }
273 }; 281 };
274 ($field_name:ident [$ty:ident]) => { 282 ($field_name:ident [$ty:ident]) => {
275 FieldSrc::Many(stringify!($ty)) 283 Field::Node { name: stringify!($field_name), src: FieldSrc::Many(stringify!($ty)) }
276 }; 284 };
277 ($field_name:ident $ty:ident) => { 285 ($field_name:ident $ty:ident) => {
278 FieldSrc::Optional(stringify!($ty)) 286 Field::Node { name: stringify!($field_name), src: FieldSrc::Optional(stringify!($ty)) }
279 }; 287 };
280} 288}
281 289
@@ -290,7 +298,6 @@ macro_rules! ast_enums {
290 name: stringify!($name), 298 name: stringify!($name),
291 traits: &[$($(stringify!($trait)),*)?], 299 traits: &[$($(stringify!($trait)),*)?],
292 variants: &[$(stringify!($variant)),*], 300 variants: &[$(stringify!($variant)),*],
293
294 } 301 }
295 ),*] 302 ),*]
296 }; 303 };
@@ -304,11 +311,11 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
304 311
305 struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner { 312 struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
306 Abi, 313 Abi,
307 ConstKw, 314 T![const],
308 DefaultKw, 315 T![default],
309 AsyncKw, 316 T![async],
310 UnsafeKw, 317 T![unsafe],
311 FnKw, 318 T![fn],
312 ParamList, 319 ParamList,
313 RetType, 320 RetType,
314 body: BlockExpr, 321 body: BlockExpr,
@@ -318,13 +325,13 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
318 struct RetType { ThinArrow, TypeRef } 325 struct RetType { ThinArrow, TypeRef }
319 326
320 struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 327 struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
321 StructKw, 328 T![struct],
322 FieldDefList, 329 FieldDefList,
323 Semi 330 Semi
324 } 331 }
325 332
326 struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 333 struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
327 UnionKw, 334 T![union],
328 RecordFieldDefList, 335 RecordFieldDefList,
329 } 336 }
330 337
@@ -337,7 +344,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
337 } 344 }
338 345
339 struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 346 struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
340 EnumKw, 347 T![enum],
341 variant_list: EnumVariantList, 348 variant_list: EnumVariantList,
342 } 349 }
343 struct EnumVariantList { 350 struct EnumVariantList {
@@ -352,14 +359,14 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
352 } 359 }
353 360
354 struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner { 361 struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
355 UnsafeKw, 362 T![unsafe],
356 AutoKw, 363 T![auto],
357 TraitKw, 364 T![trait],
358 ItemList, 365 ItemList,
359 } 366 }
360 367
361 struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner { 368 struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
362 ModKw, 369 T![mod],
363 ItemList, 370 ItemList,
364 Semi 371 Semi
365 } 372 }
@@ -371,36 +378,36 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
371 } 378 }
372 379
373 struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { 380 struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
374 DefaultKw, 381 T![default],
375 ConstKw, 382 T![const],
376 Eq, 383 Eq,
377 body: Expr, 384 body: Expr,
378 Semi 385 Semi
379 } 386 }
380 387
381 struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { 388 struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
382 StaticKw, 389 T![static],
383 MutKw, 390 T![mut],
384 Eq, 391 Eq,
385 body: Expr, 392 body: Expr,
386 Semi 393 Semi
387 } 394 }
388 395
389 struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner { 396 struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
390 DefaultKw, 397 T![default],
391 TypeKw, 398 T![type],
392 Eq, 399 Eq,
393 TypeRef, 400 TypeRef,
394 Semi 401 Semi
395 } 402 }
396 403
397 struct ImplDef: TypeParamsOwner, AttrsOwner { 404 struct ImplDef: TypeParamsOwner, AttrsOwner {
398 DefaultKw, 405 T![default],
399 ConstKw, 406 T![const],
400 UnsafeKw, 407 T![unsafe],
401 ImplKw, 408 T![impl],
402 Excl, 409 Excl,
403 ForKw, 410 T![for],
404 ItemList, 411 ItemList,
405 } 412 }
406 413
@@ -408,42 +415,42 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
408 struct TupleType { LParen, fields: [TypeRef], RParen } 415 struct TupleType { LParen, fields: [TypeRef], RParen }
409 struct NeverType { Excl } 416 struct NeverType { Excl }
410 struct PathType { Path } 417 struct PathType { Path }
411 struct PointerType { Star, ConstKw, MutKw, TypeRef } 418 struct PointerType { Star, T![const], T![mut], TypeRef }
412 struct ArrayType { LBrack, TypeRef, Semi, Expr, RBrack } 419 struct ArrayType { LBrack, TypeRef, Semi, Expr, RBrack }
413 struct SliceType { LBrack, TypeRef, RBrack } 420 struct SliceType { LBrack, TypeRef, RBrack }
414 struct ReferenceType { Amp, Lifetime, MutKw, TypeRef } 421 struct ReferenceType { Amp, Lifetime, T![mut], TypeRef }
415 struct PlaceholderType { Underscore } 422 struct PlaceholderType { Underscore }
416 struct FnPointerType { Abi, UnsafeKw, FnKw, ParamList, RetType } 423 struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType }
417 struct ForType { ForKw, TypeParamList, TypeRef } 424 struct ForType { T![for], TypeParamList, TypeRef }
418 struct ImplTraitType: TypeBoundsOwner { ImplKw } 425 struct ImplTraitType: TypeBoundsOwner { T![impl] }
419 struct DynTraitType: TypeBoundsOwner { DynKw } 426 struct DynTraitType: TypeBoundsOwner { T![dyn] }
420 427
421 struct TupleExpr: AttrsOwner { LParen, exprs: [Expr], RParen } 428 struct TupleExpr: AttrsOwner { LParen, exprs: [Expr], RParen }
422 struct ArrayExpr: AttrsOwner { LBrack, exprs: [Expr], Semi, RBrack } 429 struct ArrayExpr: AttrsOwner { LBrack, exprs: [Expr], Semi, RBrack }
423 struct ParenExpr: AttrsOwner { LParen, Expr, RParen } 430 struct ParenExpr: AttrsOwner { LParen, Expr, RParen }
424 struct PathExpr { Path } 431 struct PathExpr { Path }
425 struct LambdaExpr: AttrsOwner { 432 struct LambdaExpr: AttrsOwner {
426 StaticKw, 433 T![static],
427 AsyncKw, 434 T![async],
428 MoveKw, 435 T![move],
429 ParamList, 436 ParamList,
430 RetType, 437 RetType,
431 body: Expr, 438 body: Expr,
432 } 439 }
433 struct IfExpr: AttrsOwner { IfKw, Condition } 440 struct IfExpr: AttrsOwner { T![if], Condition }
434 struct LoopExpr: AttrsOwner, LoopBodyOwner { LoopKw } 441 struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
435 struct TryBlockExpr: AttrsOwner { TryKw, body: BlockExpr } 442 struct TryBlockExpr: AttrsOwner { T![try], body: BlockExpr }
436 struct ForExpr: AttrsOwner, LoopBodyOwner { 443 struct ForExpr: AttrsOwner, LoopBodyOwner {
437 ForKw, 444 T![for],
438 Pat, 445 Pat,
439 InKw, 446 T![in],
440 iterable: Expr, 447 iterable: Expr,
441 } 448 }
442 struct WhileExpr: AttrsOwner, LoopBodyOwner { WhileKw, Condition } 449 struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition }
443 struct ContinueExpr: AttrsOwner { ContinueKw, Lifetime } 450 struct ContinueExpr: AttrsOwner { T![continue], Lifetime }
444 struct BreakExpr: AttrsOwner { BreakKw, Lifetime, Expr } 451 struct BreakExpr: AttrsOwner { T![break], Lifetime, Expr }
445 struct Label { Lifetime } 452 struct Label { Lifetime }
446 struct BlockExpr: AttrsOwner { Label, UnsafeKw, Block } 453 struct BlockExpr: AttrsOwner { Label, T![unsafe], Block }
447 struct ReturnExpr: AttrsOwner { Expr } 454 struct ReturnExpr: AttrsOwner { Expr }
448 struct CallExpr: ArgListOwner { Expr } 455 struct CallExpr: ArgListOwner { Expr }
449 struct MethodCallExpr: AttrsOwner, ArgListOwner { 456 struct MethodCallExpr: AttrsOwner, ArgListOwner {
@@ -451,17 +458,17 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
451 } 458 }
452 struct IndexExpr: AttrsOwner { LBrack, RBrack } 459 struct IndexExpr: AttrsOwner { LBrack, RBrack }
453 struct FieldExpr: AttrsOwner { Expr, Dot, NameRef } 460 struct FieldExpr: AttrsOwner { Expr, Dot, NameRef }
454 struct AwaitExpr: AttrsOwner { Expr, Dot, AwaitKw } 461 struct AwaitExpr: AttrsOwner { Expr, Dot, T![await] }
455 struct TryExpr: AttrsOwner { TryKw, Expr } 462 struct TryExpr: AttrsOwner { T![try], Expr }
456 struct CastExpr: AttrsOwner { Expr, AsKw, TypeRef } 463 struct CastExpr: AttrsOwner { Expr, T![as], TypeRef }
457 struct RefExpr: AttrsOwner { Amp, RawKw, MutKw, Expr } 464 struct RefExpr: AttrsOwner { Amp, T![raw], T![mut], Expr }
458 struct PrefixExpr: AttrsOwner { PrefixOp, Expr } 465 struct PrefixExpr: AttrsOwner { PrefixOp, Expr }
459 struct BoxExpr: AttrsOwner { BoxKw, Expr } 466 struct BoxExpr: AttrsOwner { T![box], Expr }
460 struct RangeExpr: AttrsOwner { RangeOp } 467 struct RangeExpr: AttrsOwner { RangeOp }
461 struct BinExpr: AttrsOwner { BinOp } 468 struct BinExpr: AttrsOwner { BinOp }
462 struct Literal { LiteralToken } 469 struct Literal { LiteralToken }
463 470
464 struct MatchExpr: AttrsOwner { MatchKw, Expr, MatchArmList } 471 struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList }
465 struct MatchArmList: AttrsOwner { LCurly, arms: [MatchArm], RCurly } 472 struct MatchArmList: AttrsOwner { LCurly, arms: [MatchArm], RCurly }
466 struct MatchArm: AttrsOwner { 473 struct MatchArm: AttrsOwner {
467 pat: Pat, 474 pat: Pat,
@@ -469,7 +476,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
469 FatArrow, 476 FatArrow,
470 Expr, 477 Expr,
471 } 478 }
472 struct MatchGuard { IfKw, Expr } 479 struct MatchGuard { T![if], Expr }
473 480
474 struct RecordLit { Path, RecordFieldList} 481 struct RecordLit { Path, RecordFieldList}
475 struct RecordFieldList { 482 struct RecordFieldList {
@@ -483,9 +490,9 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
483 490
484 struct OrPat { pats: [Pat] } 491 struct OrPat { pats: [Pat] }
485 struct ParenPat { LParen, Pat, RParen } 492 struct ParenPat { LParen, Pat, RParen }
486 struct RefPat { Amp, MutKw, Pat } 493 struct RefPat { Amp, T![mut], Pat }
487 struct BoxPat { BoxKw, Pat } 494 struct BoxPat { T![box], Pat }
488 struct BindPat: AttrsOwner, NameOwner { RefKw, MutKw, At, Pat } 495 struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], At, Pat }
489 struct PlaceholderPat { Underscore } 496 struct PlaceholderPat { Underscore }
490 struct DotDotPat { Dotdot } 497 struct DotDotPat { Dotdot }
491 struct PathPat { Path } 498 struct PathPat { Path }
@@ -508,7 +515,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
508 struct TupleStructPat { Path, LParen, args: [Pat], RParen } 515 struct TupleStructPat { Path, LParen, args: [Pat], RParen }
509 struct TuplePat { LParen, args: [Pat], RParen } 516 struct TuplePat { LParen, args: [Pat], RParen }
510 517
511 struct Visibility { PubKw, SuperKw, SelfKw, CrateKw } 518 struct Visibility { T![pub], T![super], T![self], T![crate] }
512 struct Name { Ident } 519 struct Name { Ident }
513 struct NameRef { NameRefToken } 520 struct NameRef { NameRefToken }
514 521
@@ -534,20 +541,20 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
534 default_val: Expr, 541 default_val: Expr,
535 } 542 }
536 struct LifetimeParam: AttrsOwner { Lifetime} 543 struct LifetimeParam: AttrsOwner { Lifetime}
537 struct TypeBound { Lifetime, /* Question, */ ConstKw, /* Question, */ TypeRef} 544 struct TypeBound { Lifetime, /* Question, */ T![const], /* Question, */ TypeRef}
538 struct TypeBoundList { bounds: [TypeBound] } 545 struct TypeBoundList { bounds: [TypeBound] }
539 struct WherePred: TypeBoundsOwner { Lifetime, TypeRef } 546 struct WherePred: TypeBoundsOwner { Lifetime, TypeRef }
540 struct WhereClause { WhereKw, predicates: [WherePred] } 547 struct WhereClause { T![where], predicates: [WherePred] }
541 struct Abi { String } 548 struct Abi { String }
542 struct ExprStmt: AttrsOwner { Expr, Semi } 549 struct ExprStmt: AttrsOwner { Expr, Semi }
543 struct LetStmt: AttrsOwner, TypeAscriptionOwner { 550 struct LetStmt: AttrsOwner, TypeAscriptionOwner {
544 LetKw, 551 T![let],
545 Pat, 552 Pat,
546 Eq, 553 Eq,
547 initializer: Expr, 554 initializer: Expr,
548 Semi, 555 Semi,
549 } 556 }
550 struct Condition { LetKw, Pat, Eq, Expr } 557 struct Condition { T![let], Pat, Eq, Expr }
551 struct Block: AttrsOwner, ModuleItemOwner { 558 struct Block: AttrsOwner, ModuleItemOwner {
552 LCurly, 559 LCurly,
553 statements: [Stmt], 560 statements: [Stmt],
@@ -560,22 +567,22 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
560 params: [Param], 567 params: [Param],
561 RParen 568 RParen
562 } 569 }
563 struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, SelfKw } 570 struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, T![self] }
564 struct Param: TypeAscriptionOwner, AttrsOwner { 571 struct Param: TypeAscriptionOwner, AttrsOwner {
565 Pat, 572 Pat,
566 Dotdotdot 573 Dotdotdot
567 } 574 }
568 struct UseItem: AttrsOwner, VisibilityOwner { 575 struct UseItem: AttrsOwner, VisibilityOwner {
569 UseKw, 576 T![use],
570 UseTree, 577 UseTree,
571 } 578 }
572 struct UseTree { 579 struct UseTree {
573 Path, Star, UseTreeList, Alias 580 Path, Star, UseTreeList, Alias
574 } 581 }
575 struct Alias: NameOwner { AsKw } 582 struct Alias: NameOwner { T![as] }
576 struct UseTreeList { LCurly, use_trees: [UseTree], RCurly } 583 struct UseTreeList { LCurly, use_trees: [UseTree], RCurly }
577 struct ExternCrateItem: AttrsOwner, VisibilityOwner { 584 struct ExternCrateItem: AttrsOwner, VisibilityOwner {
578 ExternKw, CrateKw, NameRef, Alias, 585 T![extern], T![crate], NameRef, Alias,
579 } 586 }
580 struct ArgList { 587 struct ArgList {
581 LParen, 588 LParen,
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index cc98802f6..c4fb29bbf 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -12,7 +12,7 @@ use proc_macro2::{Punct, Spacing};
12use quote::{format_ident, quote}; 12use quote::{format_ident, quote};
13 13
14use crate::{ 14use crate::{
15 ast_src::{AstSrc, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC}, 15 ast_src::{AstSrc, Field, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC},
16 codegen::{self, update, Mode}, 16 codegen::{self, update, Mode},
17 project_root, Result, 17 project_root, Result,
18}; 18};
@@ -189,46 +189,30 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
189 quote!(impl ast::#trait_name for #name {}) 189 quote!(impl ast::#trait_name for #name {})
190 }); 190 });
191 191
192 let methods = node.fields.iter().map(|(name, field)| { 192 let methods = node.fields.iter().map(|field| {
193 let is_kw = name.ends_with("Kw"); 193 let method_name = field.method_name();
194 let method_name = match field { 194 let ty = field.ty();
195 FieldSrc::Shorthand => {
196 let name = if is_kw { &name[..name.len() - 2] } else { &name };
197 format_ident!("{}", to_lower_snake_case(name))
198 }
199 _ => format_ident!("{}", name),
200 };
201 let ty = match field {
202 FieldSrc::Optional(ty) | FieldSrc::Many(ty) => ty,
203 FieldSrc::Shorthand => name,
204 };
205
206 let ty = format_ident!("{}", ty);
207 195
208 match field { 196 if field.is_many() {
209 FieldSrc::Many(_) => { 197 quote! {
198 pub fn #method_name(&self) -> AstChildren<#ty> {
199 support::children(&self.syntax)
200 }
201 }
202 } else {
203 if let Some(token_kind) = field.token_kind() {
210 quote! { 204 quote! {
211 pub fn #method_name(&self) -> AstChildren<#ty> { 205 pub fn #method_name(&self) -> Option<#ty> {
212 support::children(&self.syntax) 206 support::token2(&self.syntax, #token_kind)
213 } 207 }
214 } 208 }
215 } 209 } else {
216 FieldSrc::Optional(_) | FieldSrc::Shorthand => {
217 let is_token = token_kinds.contains(&ty.to_string()); 210 let is_token = token_kinds.contains(&ty.to_string());
218 if is_token { 211 if is_token {
219 let method_name = format_ident!("{}_token", method_name); 212 let method_name = format_ident!("{}_token", method_name);
220 if is_kw { 213 quote! {
221 let token_kind = format_ident!("{}", to_upper_snake_case(name)); 214 pub fn #method_name(&self) -> Option<#ty> {
222 quote! { 215 support::token(&self.syntax)
223 pub fn #method_name(&self) -> Option<SyntaxToken> {
224 support::token2(&self.syntax, #token_kind)
225 }
226 }
227 } else {
228 quote! {
229 pub fn #method_name(&self) -> Option<#ty> {
230 support::token(&self.syntax)
231 }
232 } 216 }
233 } 217 }
234 } else { 218 } else {
@@ -351,6 +335,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
351 use crate::{ 335 use crate::{
352 SyntaxNode, SyntaxToken, SyntaxKind::{self, *}, 336 SyntaxNode, SyntaxToken, SyntaxKind::{self, *},
353 ast::{self, AstNode, AstChildren, support}, 337 ast::{self, AstNode, AstChildren, support},
338 T,
354 }; 339 };
355 340
356 use super::tokens::*; 341 use super::tokens::*;
@@ -519,3 +504,40 @@ fn to_pascal_case(s: &str) -> String {
519 } 504 }
520 buf 505 buf
521} 506}
507
508impl Field<'_> {
509 fn is_many(&self) -> bool {
510 match self {
511 Field::Node { src: FieldSrc::Many(_), .. } => true,
512 _ => false,
513 }
514 }
515 fn token_kind(&self) -> Option<proc_macro2::TokenStream> {
516 let res = match self {
517 Field::Token(token) => {
518 let token = format_ident!("{}", token);
519 quote! { T![#token] }
520 }
521 _ => return None,
522 };
523 Some(res)
524 }
525 fn method_name(&self) -> proc_macro2::Ident {
526 match self {
527 Field::Token(name) => format_ident!("{}_token", name),
528 Field::Node { name, src } => match src {
529 FieldSrc::Shorthand => format_ident!("{}", to_lower_snake_case(name)),
530 _ => format_ident!("{}", name),
531 },
532 }
533 }
534 fn ty(&self) -> proc_macro2::Ident {
535 match self {
536 Field::Token(_) => format_ident!("SyntaxToken"),
537 Field::Node { name, src } => match src {
538 FieldSrc::Optional(ty) | FieldSrc::Many(ty) => format_ident!("{}", ty),
539 FieldSrc::Shorthand => format_ident!("{}", name),
540 },
541 }
542 }
543}