aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/ast_src.rs417
-rw-r--r--xtask/src/codegen/gen_syntax.rs287
2 files changed, 284 insertions, 420 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index bb97b13fe..8c0b5f5a8 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -11,7 +11,7 @@ pub(crate) struct KindsSrc<'a> {
11 11
12pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { 12pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
13 punct: &[ 13 punct: &[
14 (";", "SEMI"), 14 (";", "SEMICOLON"),
15 (",", "COMMA"), 15 (",", "COMMA"),
16 ("(", "L_PAREN"), 16 ("(", "L_PAREN"),
17 (")", "R_PAREN"), 17 (")", "R_PAREN"),
@@ -35,15 +35,15 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
35 ("%", "PERCENT"), 35 ("%", "PERCENT"),
36 ("_", "UNDERSCORE"), 36 ("_", "UNDERSCORE"),
37 (".", "DOT"), 37 (".", "DOT"),
38 ("..", "DOTDOT"), 38 ("..", "DOT2"),
39 ("...", "DOTDOTDOT"), 39 ("...", "DOT3"),
40 ("..=", "DOTDOTEQ"), 40 ("..=", "DOT2EQ"),
41 (":", "COLON"), 41 (":", "COLON"),
42 ("::", "COLONCOLON"), 42 ("::", "COLON2"),
43 ("=", "EQ"), 43 ("=", "EQ"),
44 ("==", "EQEQ"), 44 ("==", "EQ2"),
45 ("=>", "FAT_ARROW"), 45 ("=>", "FAT_ARROW"),
46 ("!", "EXCL"), 46 ("!", "BANG"),
47 ("!=", "NEQ"), 47 ("!=", "NEQ"),
48 ("-", "MINUS"), 48 ("-", "MINUS"),
49 ("->", "THIN_ARROW"), 49 ("->", "THIN_ARROW"),
@@ -57,8 +57,8 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
57 ("/=", "SLASHEQ"), 57 ("/=", "SLASHEQ"),
58 ("*=", "STAREQ"), 58 ("*=", "STAREQ"),
59 ("%=", "PERCENTEQ"), 59 ("%=", "PERCENTEQ"),
60 ("&&", "AMPAMP"), 60 ("&&", "AMP2"),
61 ("||", "PIPEPIPE"), 61 ("||", "PIPE2"),
62 ("<<", "SHL"), 62 ("<<", "SHL"),
63 (">>", "SHR"), 63 (">>", "SHR"),
64 ("<<=", "SHLEQ"), 64 ("<<=", "SHLEQ"),
@@ -225,21 +225,26 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
225}; 225};
226 226
227pub(crate) struct AstSrc<'a> { 227pub(crate) struct AstSrc<'a> {
228 pub(crate) tokens: &'a [&'a str],
228 pub(crate) nodes: &'a [AstNodeSrc<'a>], 229 pub(crate) nodes: &'a [AstNodeSrc<'a>],
229 pub(crate) enums: &'a [AstEnumSrc<'a>], 230 pub(crate) enums: &'a [AstEnumSrc<'a>],
230 pub(crate) token_enums: &'a [AstEnumSrc<'a>],
231} 231}
232 232
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 str>)], 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<T> { 244pub(crate) enum FieldSrc<'a> {
240 Shorthand, 245 Shorthand,
241 Optional(T), 246 Optional(&'a str),
242 Many(T), 247 Many(&'a str),
243} 248}
244 249
245pub(crate) struct AstEnumSrc<'a> { 250pub(crate) struct AstEnumSrc<'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,13 +298,13 @@ 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 };
297} 304}
298 305
299pub(crate) const AST_SRC: AstSrc = AstSrc { 306pub(crate) const AST_SRC: AstSrc = AstSrc {
307 tokens: &["Whitespace", "Comment", "String", "RawString"],
300 nodes: &ast_nodes! { 308 nodes: &ast_nodes! {
301 struct SourceFile: ModuleItemOwner, AttrsOwner { 309 struct SourceFile: ModuleItemOwner, AttrsOwner {
302 modules: [Module], 310 modules: [Module],
@@ -304,305 +312,305 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
304 312
305 struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner { 313 struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
306 Abi, 314 Abi,
307 ConstKw, 315 T![const],
308 DefaultKw, 316 T![default],
309 AsyncKw, 317 T![async],
310 UnsafeKw, 318 T![unsafe],
311 FnKw, 319 T![fn],
312 ParamList, 320 ParamList,
313 RetType, 321 RetType,
314 body: BlockExpr, 322 body: BlockExpr,
315 Semi 323 T![;]
316 } 324 }
317 325
318 struct RetType { ThinArrow, TypeRef } 326 struct RetType { T![->], TypeRef }
319 327
320 struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 328 struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
321 StructKw, 329 T![struct],
322 FieldDefList, 330 FieldDefList,
323 Semi 331 T![;]
324 } 332 }
325 333
326 struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 334 struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
327 UnionKw, 335 T![union],
328 RecordFieldDefList, 336 RecordFieldDefList,
329 } 337 }
330 338
331 struct RecordFieldDefList { LCurly, fields: [RecordFieldDef], RCurly } 339 struct RecordFieldDefList { T!['{'], fields: [RecordFieldDef], T!['}'] }
332 struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { } 340 struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { }
333 341
334 struct TupleFieldDefList { LParen, fields: [TupleFieldDef], RParen } 342 struct TupleFieldDefList { T!['('], fields: [TupleFieldDef], T![')'] }
335 struct TupleFieldDef: VisibilityOwner, AttrsOwner { 343 struct TupleFieldDef: VisibilityOwner, AttrsOwner {
336 TypeRef, 344 TypeRef,
337 } 345 }
338 346
339 struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 347 struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
340 EnumKw, 348 T![enum],
341 variant_list: EnumVariantList, 349 variant_list: EnumVariantList,
342 } 350 }
343 struct EnumVariantList { 351 struct EnumVariantList {
344 LCurly, 352 T!['{'],
345 variants: [EnumVariant], 353 variants: [EnumVariant],
346 RCurly 354 T!['}']
347 } 355 }
348 struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner { 356 struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner {
349 FieldDefList, 357 FieldDefList,
350 Eq, 358 T![=],
351 Expr 359 Expr
352 } 360 }
353 361
354 struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner { 362 struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
355 UnsafeKw, 363 T![unsafe],
356 AutoKw, 364 T![auto],
357 TraitKw, 365 T![trait],
358 ItemList, 366 ItemList,
359 } 367 }
360 368
361 struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner { 369 struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
362 ModKw, 370 T![mod],
363 ItemList, 371 ItemList,
364 Semi 372 T![;]
365 } 373 }
366 374
367 struct ItemList: ModuleItemOwner { 375 struct ItemList: ModuleItemOwner {
368 LCurly, 376 T!['{'],
369 impl_items: [ImplItem], 377 impl_items: [ImplItem],
370 RCurly 378 T!['}']
371 } 379 }
372 380
373 struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { 381 struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
374 DefaultKw, 382 T![default],
375 ConstKw, 383 T![const],
376 Eq, 384 T![=],
377 body: Expr, 385 body: Expr,
378 Semi 386 T![;]
379 } 387 }
380 388
381 struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { 389 struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
382 StaticKw, 390 T![static],
383 MutKw, 391 T![mut],
384 Eq, 392 T![=],
385 body: Expr, 393 body: Expr,
386 Semi 394 T![;]
387 } 395 }
388 396
389 struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner { 397 struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
390 DefaultKw, 398 T![default],
391 TypeKw, 399 T![type],
392 Eq, 400 T![=],
393 TypeRef, 401 TypeRef,
394 Semi 402 T![;]
395 } 403 }
396 404
397 struct ImplDef: TypeParamsOwner, AttrsOwner { 405 struct ImplDef: TypeParamsOwner, AttrsOwner {
398 DefaultKw, 406 T![default],
399 ConstKw, 407 T![const],
400 UnsafeKw, 408 T![unsafe],
401 ImplKw, 409 T![impl],
402 Excl, 410 T![!],
403 ForKw, 411 T![for],
404 ItemList, 412 ItemList,
405 } 413 }
406 414
407 struct ParenType { LParen, TypeRef, RParen } 415 struct ParenType { T!['('], TypeRef, T![')'] }
408 struct TupleType { LParen, fields: [TypeRef], RParen } 416 struct TupleType { T!['('], fields: [TypeRef], T![')'] }
409 struct NeverType { Excl } 417 struct NeverType { T![!] }
410 struct PathType { Path } 418 struct PathType { Path }
411 struct PointerType { Star, ConstKw, MutKw, TypeRef } 419 struct PointerType { T![*], T![const], T![mut], TypeRef }
412 struct ArrayType { LBrack, TypeRef, Semi, Expr, RBrack } 420 struct ArrayType { T!['['], TypeRef, T![;], Expr, T![']'] }
413 struct SliceType { LBrack, TypeRef, RBrack } 421 struct SliceType { T!['['], TypeRef, T![']'] }
414 struct ReferenceType { Amp, Lifetime, MutKw, TypeRef } 422 struct ReferenceType { T![&], T![lifetime], T![mut], TypeRef }
415 struct PlaceholderType { Underscore } 423 struct PlaceholderType { T![_] }
416 struct FnPointerType { Abi, UnsafeKw, FnKw, ParamList, RetType } 424 struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType }
417 struct ForType { ForKw, TypeParamList, TypeRef } 425 struct ForType { T![for], TypeParamList, TypeRef }
418 struct ImplTraitType: TypeBoundsOwner { ImplKw } 426 struct ImplTraitType: TypeBoundsOwner { T![impl] }
419 struct DynTraitType: TypeBoundsOwner { DynKw } 427 struct DynTraitType: TypeBoundsOwner { T![dyn] }
420 428
421 struct TupleExpr: AttrsOwner { LParen, exprs: [Expr], RParen } 429 struct TupleExpr: AttrsOwner { T!['('], exprs: [Expr], T![')'] }
422 struct ArrayExpr: AttrsOwner { LBrack, exprs: [Expr], Semi, RBrack } 430 struct ArrayExpr: AttrsOwner { T!['['], exprs: [Expr], T![;], T![']'] }
423 struct ParenExpr: AttrsOwner { LParen, Expr, RParen } 431 struct ParenExpr: AttrsOwner { T!['('], Expr, T![')'] }
424 struct PathExpr { Path } 432 struct PathExpr { Path }
425 struct LambdaExpr: AttrsOwner { 433 struct LambdaExpr: AttrsOwner {
426 StaticKw, 434 T![static],
427 AsyncKw, 435 T![async],
428 MoveKw, 436 T![move],
429 ParamList, 437 ParamList,
430 RetType, 438 RetType,
431 body: Expr, 439 body: Expr,
432 } 440 }
433 struct IfExpr: AttrsOwner { IfKw, Condition } 441 struct IfExpr: AttrsOwner { T![if], Condition }
434 struct LoopExpr: AttrsOwner, LoopBodyOwner { LoopKw } 442 struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
435 struct TryBlockExpr: AttrsOwner { TryKw, body: BlockExpr } 443 struct TryBlockExpr: AttrsOwner { T![try], body: BlockExpr }
436 struct ForExpr: AttrsOwner, LoopBodyOwner { 444 struct ForExpr: AttrsOwner, LoopBodyOwner {
437 ForKw, 445 T![for],
438 Pat, 446 Pat,
439 InKw, 447 T![in],
440 iterable: Expr, 448 iterable: Expr,
441 } 449 }
442 struct WhileExpr: AttrsOwner, LoopBodyOwner { WhileKw, Condition } 450 struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition }
443 struct ContinueExpr: AttrsOwner { ContinueKw, Lifetime } 451 struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] }
444 struct BreakExpr: AttrsOwner { BreakKw, Lifetime, Expr } 452 struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr }
445 struct Label { Lifetime } 453 struct Label { T![lifetime] }
446 struct BlockExpr: AttrsOwner { Label, UnsafeKw, Block } 454 struct BlockExpr: AttrsOwner { Label, T![unsafe], Block }
447 struct ReturnExpr: AttrsOwner { Expr } 455 struct ReturnExpr: AttrsOwner { Expr }
448 struct CallExpr: ArgListOwner { Expr } 456 struct CallExpr: ArgListOwner { Expr }
449 struct MethodCallExpr: AttrsOwner, ArgListOwner { 457 struct MethodCallExpr: AttrsOwner, ArgListOwner {
450 Expr, Dot, NameRef, TypeArgList, 458 Expr, T![.], NameRef, TypeArgList,
451 } 459 }
452 struct IndexExpr: AttrsOwner { LBrack, RBrack } 460 struct IndexExpr: AttrsOwner { T!['['], T![']'] }
453 struct FieldExpr: AttrsOwner { Expr, Dot, NameRef } 461 struct FieldExpr: AttrsOwner { Expr, T![.], NameRef }
454 struct AwaitExpr: AttrsOwner { Expr, Dot, AwaitKw } 462 struct AwaitExpr: AttrsOwner { Expr, T![.], T![await] }
455 struct TryExpr: AttrsOwner { TryKw, Expr } 463 struct TryExpr: AttrsOwner { T![try], Expr }
456 struct CastExpr: AttrsOwner { Expr, AsKw, TypeRef } 464 struct CastExpr: AttrsOwner { Expr, T![as], TypeRef }
457 struct RefExpr: AttrsOwner { Amp, RawKw, MutKw, Expr } 465 struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], Expr }
458 struct PrefixExpr: AttrsOwner { PrefixOp, Expr } 466 struct PrefixExpr: AttrsOwner { /*PrefixOp,*/ Expr }
459 struct BoxExpr: AttrsOwner { BoxKw, Expr } 467 struct BoxExpr: AttrsOwner { T![box], Expr }
460 struct RangeExpr: AttrsOwner { RangeOp } 468 struct RangeExpr: AttrsOwner { /*RangeOp*/ }
461 struct BinExpr: AttrsOwner { BinOp } 469 struct BinExpr: AttrsOwner { /*BinOp*/ }
462 struct Literal { LiteralToken } 470 struct Literal { /*LiteralToken*/ }
463 471
464 struct MatchExpr: AttrsOwner { MatchKw, Expr, MatchArmList } 472 struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList }
465 struct MatchArmList: AttrsOwner { LCurly, arms: [MatchArm], RCurly } 473 struct MatchArmList: AttrsOwner { T!['{'], arms: [MatchArm], T!['}'] }
466 struct MatchArm: AttrsOwner { 474 struct MatchArm: AttrsOwner {
467 pat: Pat, 475 pat: Pat,
468 guard: MatchGuard, 476 guard: MatchGuard,
469 FatArrow, 477 T![=>],
470 Expr, 478 Expr,
471 } 479 }
472 struct MatchGuard { IfKw, Expr } 480 struct MatchGuard { T![if], Expr }
473 481
474 struct RecordLit { Path, RecordFieldList} 482 struct RecordLit { Path, RecordFieldList}
475 struct RecordFieldList { 483 struct RecordFieldList {
476 LCurly, 484 T!['{'],
477 fields: [RecordField], 485 fields: [RecordField],
478 Dotdot, 486 T![..],
479 spread: Expr, 487 spread: Expr,
480 RCurly 488 T!['}']
481 } 489 }
482 struct RecordField: AttrsOwner { NameRef, Colon, Expr } 490 struct RecordField: AttrsOwner { NameRef, T![:], Expr }
483 491
484 struct OrPat { pats: [Pat] } 492 struct OrPat { pats: [Pat] }
485 struct ParenPat { LParen, Pat, RParen } 493 struct ParenPat { T!['('], Pat, T![')'] }
486 struct RefPat { Amp, MutKw, Pat } 494 struct RefPat { T![&], T![mut], Pat }
487 struct BoxPat { BoxKw, Pat } 495 struct BoxPat { T![box], Pat }
488 struct BindPat: AttrsOwner, NameOwner { RefKw, MutKw, At, Pat } 496 struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], T![@], Pat }
489 struct PlaceholderPat { Underscore } 497 struct PlaceholderPat { T![_] }
490 struct DotDotPat { Dotdot } 498 struct DotDotPat { T![..] }
491 struct PathPat { Path } 499 struct PathPat { Path }
492 struct SlicePat { LBrack, args: [Pat], RBrack } 500 struct SlicePat { T!['['], args: [Pat], T![']'] }
493 struct RangePat { RangeSeparator } 501 struct RangePat { /*RangeSeparator*/ }
494 struct LiteralPat { Literal } 502 struct LiteralPat { Literal }
495 struct MacroPat { MacroCall } 503 struct MacroPat { MacroCall }
496 504
497 struct RecordPat { RecordFieldPatList, Path } 505 struct RecordPat { RecordFieldPatList, Path }
498 struct RecordFieldPatList { 506 struct RecordFieldPatList {
499 LCurly, 507 T!['{'],
500 pats: [RecordInnerPat], 508 pats: [RecordInnerPat],
501 record_field_pats: [RecordFieldPat], 509 record_field_pats: [RecordFieldPat],
502 bind_pats: [BindPat], 510 bind_pats: [BindPat],
503 Dotdot, 511 T![..],
504 RCurly 512 T!['}']
505 } 513 }
506 struct RecordFieldPat: AttrsOwner, NameOwner { Colon, Pat } 514 struct RecordFieldPat: AttrsOwner, NameOwner { T![:], Pat }
507 515
508 struct TupleStructPat { Path, LParen, args: [Pat], RParen } 516 struct TupleStructPat { Path, T!['('], args: [Pat], T![')'] }
509 struct TuplePat { LParen, args: [Pat], RParen } 517 struct TuplePat { T!['('], args: [Pat], T![')'] }
510 518
511 struct Visibility { PubKw, SuperKw, SelfKw, CrateKw } 519 struct Visibility { T![pub], T![super], T![self], T![crate] }
512 struct Name { Ident } 520 struct Name { T![ident] }
513 struct NameRef { NameRefToken } 521 struct NameRef { /*NameRefToken*/ }
514 522
515 struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner { 523 struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner {
516 Path, Excl, TokenTree, Semi 524 Path, T![!], TokenTree, T![;]
517 } 525 }
518 struct Attr { Pound, Excl, LBrack, Path, Eq, input: AttrInput, RBrack } 526 struct Attr { T![#], T![!], T!['['], Path, T![=], input: AttrInput, T![']'] }
519 struct TokenTree {} 527 struct TokenTree {}
520 struct TypeParamList { 528 struct TypeParamList {
521 LAngle, 529 T![<],
522 generic_params: [GenericParam], 530 generic_params: [GenericParam],
523 type_params: [TypeParam], 531 type_params: [TypeParam],
524 lifetime_params: [LifetimeParam], 532 lifetime_params: [LifetimeParam],
525 const_params: [ConstParam], 533 const_params: [ConstParam],
526 RAngle 534 T![>]
527 } 535 }
528 struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner { 536 struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner {
529 Eq, 537 T![=],
530 default_type: TypeRef, 538 default_type: TypeRef,
531 } 539 }
532 struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner { 540 struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner {
533 Eq, 541 T![=],
534 default_val: Expr, 542 default_val: Expr,
535 } 543 }
536 struct LifetimeParam: AttrsOwner { Lifetime} 544 struct LifetimeParam: AttrsOwner { T![lifetime] }
537 struct TypeBound { Lifetime, /* Question, */ ConstKw, /* Question, */ TypeRef} 545 struct TypeBound { T![lifetime], /* Question, */ T![const], /* Question, */ TypeRef}
538 struct TypeBoundList { bounds: [TypeBound] } 546 struct TypeBoundList { bounds: [TypeBound] }
539 struct WherePred: TypeBoundsOwner { Lifetime, TypeRef } 547 struct WherePred: TypeBoundsOwner { T![lifetime], TypeRef }
540 struct WhereClause { WhereKw, predicates: [WherePred] } 548 struct WhereClause { T![where], predicates: [WherePred] }
541 struct Abi { String } 549 struct Abi { /*String*/ }
542 struct ExprStmt: AttrsOwner { Expr, Semi } 550 struct ExprStmt: AttrsOwner { Expr, T![;] }
543 struct LetStmt: AttrsOwner, TypeAscriptionOwner { 551 struct LetStmt: AttrsOwner, TypeAscriptionOwner {
544 LetKw, 552 T![let],
545 Pat, 553 Pat,
546 Eq, 554 T![=],
547 initializer: Expr, 555 initializer: Expr,
548 Semi, 556 T![;],
549 } 557 }
550 struct Condition { LetKw, Pat, Eq, Expr } 558 struct Condition { T![let], Pat, T![=], Expr }
551 struct Block: AttrsOwner, ModuleItemOwner { 559 struct Block: AttrsOwner, ModuleItemOwner {
552 LCurly, 560 T!['{'],
553 statements: [Stmt], 561 statements: [Stmt],
554 Expr, 562 Expr,
555 RCurly, 563 T!['}'],
556 } 564 }
557 struct ParamList { 565 struct ParamList {
558 LParen, 566 T!['('],
559 SelfParam, 567 SelfParam,
560 params: [Param], 568 params: [Param],
561 RParen 569 T![')']
562 } 570 }
563 struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, SelfKw } 571 struct SelfParam: TypeAscriptionOwner, AttrsOwner { T![&], T![lifetime], T![self] }
564 struct Param: TypeAscriptionOwner, AttrsOwner { 572 struct Param: TypeAscriptionOwner, AttrsOwner {
565 Pat, 573 Pat,
566 Dotdotdot 574 T![...]
567 } 575 }
568 struct UseItem: AttrsOwner, VisibilityOwner { 576 struct UseItem: AttrsOwner, VisibilityOwner {
569 UseKw, 577 T![use],
570 UseTree, 578 UseTree,
571 } 579 }
572 struct UseTree { 580 struct UseTree {
573 Path, Star, UseTreeList, Alias 581 Path, T![*], UseTreeList, Alias
574 } 582 }
575 struct Alias: NameOwner { AsKw } 583 struct Alias: NameOwner { T![as] }
576 struct UseTreeList { LCurly, use_trees: [UseTree], RCurly } 584 struct UseTreeList { T!['{'], use_trees: [UseTree], T!['}'] }
577 struct ExternCrateItem: AttrsOwner, VisibilityOwner { 585 struct ExternCrateItem: AttrsOwner, VisibilityOwner {
578 ExternKw, CrateKw, NameRef, Alias, 586 T![extern], T![crate], NameRef, Alias,
579 } 587 }
580 struct ArgList { 588 struct ArgList {
581 LParen, 589 T!['('],
582 args: [Expr], 590 args: [Expr],
583 RParen 591 T![')']
584 } 592 }
585 struct Path { 593 struct Path {
586 segment: PathSegment, 594 segment: PathSegment,
587 qualifier: Path, 595 qualifier: Path,
588 } 596 }
589 struct PathSegment { 597 struct PathSegment {
590 Coloncolon, LAngle, NameRef, TypeArgList, ParamList, RetType, PathType, RAngle 598 T![::], T![<], NameRef, TypeArgList, ParamList, RetType, PathType, T![>]
591 } 599 }
592 struct TypeArgList { 600 struct TypeArgList {
593 Coloncolon, 601 T![::],
594 LAngle, 602 T![<],
595 generic_args: [GenericArg], 603 generic_args: [GenericArg],
596 type_args: [TypeArg], 604 type_args: [TypeArg],
597 lifetime_args: [LifetimeArg], 605 lifetime_args: [LifetimeArg],
598 assoc_type_args: [AssocTypeArg], 606 assoc_type_args: [AssocTypeArg],
599 const_args: [ConstArg], 607 const_args: [ConstArg],
600 RAngle 608 T![>]
601 } 609 }
602 struct TypeArg { TypeRef } 610 struct TypeArg { TypeRef }
603 struct AssocTypeArg : TypeBoundsOwner { NameRef, Eq, TypeRef } 611 struct AssocTypeArg : TypeBoundsOwner { NameRef, T![=], TypeRef }
604 struct LifetimeArg { Lifetime } 612 struct LifetimeArg { T![lifetime] }
605 struct ConstArg { Literal, Eq, BlockExpr } 613 struct ConstArg { Literal, T![=], BlockExpr }
606 614
607 struct MacroItems: ModuleItemOwner{ } 615 struct MacroItems: ModuleItemOwner{ }
608 616
@@ -612,9 +620,9 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
612 } 620 }
613 621
614 struct ExternItemList: ModuleItemOwner { 622 struct ExternItemList: ModuleItemOwner {
615 LCurly, 623 T!['{'],
616 extern_items: [ExternItem], 624 extern_items: [ExternItem],
617 RCurly 625 T!['}']
618 } 626 }
619 627
620 struct ExternBlock { 628 struct ExternBlock {
@@ -623,7 +631,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
623 } 631 }
624 632
625 struct MetaItem { 633 struct MetaItem {
626 Path, Eq, AttrInput, nested_meta_items: [MetaItem] 634 Path, T![=], AttrInput, nested_meta_items: [MetaItem]
627 } 635 }
628 636
629 struct MacroDef { 637 struct MacroDef {
@@ -760,71 +768,4 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
760 TupleFieldDefList, 768 TupleFieldDefList,
761 } 769 }
762 }, 770 },
763
764 token_enums: &ast_enums! {
765 enum LeftDelimiter { LParen, LBrack, LCurly }
766 enum RightDelimiter { RParen, RBrack, RCurly }
767 enum RangeSeparator { Dotdot, Dotdotdot, Dotdoteq}
768
769 enum BinOp {
770 Pipepipe,
771 Ampamp,
772 Eqeq,
773 Neq,
774 Lteq,
775 Gteq,
776 LAngle,
777 RAngle,
778 Plus,
779 Star,
780 Minus,
781 Slash,
782 Percent,
783 Shl,
784 Shr,
785 Caret,
786 Pipe,
787 Amp,
788 Eq,
789 Pluseq,
790 Slasheq,
791 Stareq,
792 Percenteq,
793 Shreq,
794 Shleq,
795 Minuseq,
796 Pipeeq,
797 Ampeq,
798 Careteq,
799 }
800
801 enum PrefixOp {
802 Minus,
803 Excl,
804 Star
805 }
806
807 enum RangeOp {
808 Dotdot,
809 Dotdoteq
810 }
811
812 enum LiteralToken {
813 IntNumber,
814 FloatNumber,
815 String,
816 RawString,
817 // TrueKw,
818 // FalseKw,
819 ByteString,
820 RawByteString,
821 Char,
822 Byte
823 }
824
825 enum NameRefToken {
826 Ident,
827 IntNumber
828 }
829 },
830}; 771};
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index cc98802f6..ec1f6ad8a 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -3,16 +3,13 @@
3//! Specifically, it generates the `SyntaxKind` enum and a number of newtype 3//! Specifically, it generates the `SyntaxKind` enum and a number of newtype
4//! wrappers around `SyntaxNode` which implement `ra_syntax::AstNode`. 4//! wrappers around `SyntaxNode` which implement `ra_syntax::AstNode`.
5 5
6use std::{ 6use std::collections::HashSet;
7 borrow::Cow,
8 collections::{BTreeSet, HashSet},
9};
10 7
11use proc_macro2::{Punct, Spacing}; 8use proc_macro2::{Punct, Spacing};
12use quote::{format_ident, quote}; 9use quote::{format_ident, quote};
13 10
14use crate::{ 11use crate::{
15 ast_src::{AstSrc, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC}, 12 ast_src::{AstSrc, Field, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC},
16 codegen::{self, update, Mode}, 13 codegen::{self, update, Mode},
17 project_root, Result, 14 project_root, Result,
18}; 15};
@@ -22,61 +19,31 @@ pub fn generate_syntax(mode: Mode) -> Result<()> {
22 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; 19 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
23 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; 20 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
24 21
22 let ast_tokens_file = project_root().join(codegen::AST_TOKENS);
23 let contents = generate_tokens(AST_SRC)?;
24 update(ast_tokens_file.as_path(), &contents, mode)?;
25
25 let ast_nodes_file = project_root().join(codegen::AST_NODES); 26 let ast_nodes_file = project_root().join(codegen::AST_NODES);
26 let contents = generate_nodes(KINDS_SRC, AST_SRC)?; 27 let contents = generate_nodes(KINDS_SRC, AST_SRC)?;
27 update(ast_nodes_file.as_path(), &contents, mode)?; 28 update(ast_nodes_file.as_path(), &contents, mode)?;
28 29
29 let ast_tokens_file = project_root().join(codegen::AST_TOKENS);
30 let contents = generate_tokens(KINDS_SRC, AST_SRC)?;
31 update(ast_tokens_file.as_path(), &contents, mode)?;
32
33 Ok(()) 30 Ok(())
34} 31}
35 32
36#[derive(Debug, Default, Clone)] 33fn generate_tokens(grammar: AstSrc<'_>) -> Result<String> {
37struct ElementKinds { 34 let tokens = grammar.tokens.iter().map(|token| {
38 kinds: BTreeSet<proc_macro2::Ident>, 35 let name = format_ident!("{}", token);
39 has_nodes: bool, 36 let kind = format_ident!("{}", to_upper_snake_case(token));
40 has_tokens: bool, 37 quote! {
41}
42
43fn generate_tokens(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
44 let all_token_kinds: Vec<_> = kinds
45 .punct
46 .into_iter()
47 .map(|(_, kind)| kind)
48 .copied()
49 .map(|x| x.into())
50 .chain(
51 kinds
52 .keywords
53 .into_iter()
54 .chain(kinds.contextual_keywords.into_iter())
55 .map(|name| Cow::Owned(format!("{}_KW", to_upper_snake_case(&name)))),
56 )
57 .chain(kinds.literals.into_iter().copied().map(|x| x.into()))
58 .chain(kinds.tokens.into_iter().copied().map(|x| x.into()))
59 .collect();
60
61 let tokens = all_token_kinds.iter().filter_map(|kind_str| {
62 if kind_str.ends_with("_KW") {
63 return None;
64 }
65 let kind_str = &**kind_str;
66 let kind = format_ident!("{}", kind_str);
67 let name = format_ident!("{}", to_pascal_case(kind_str));
68 let res = quote! {
69 #[derive(Debug, Clone, PartialEq, Eq, Hash)] 38 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
70 pub struct #name { 39 pub struct #name {
71 pub(crate) syntax: SyntaxToken, 40 pub(crate) syntax: SyntaxToken,
72 } 41 }
73
74 impl std::fmt::Display for #name { 42 impl std::fmt::Display for #name {
75 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 43 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
76 std::fmt::Display::fmt(&self.syntax, f) 44 std::fmt::Display::fmt(&self.syntax, f)
77 } 45 }
78 } 46 }
79
80 impl AstToken for #name { 47 impl AstToken for #name {
81 fn can_cast(kind: SyntaxKind) -> bool { kind == #kind } 48 fn can_cast(kind: SyntaxKind) -> bool { kind == #kind }
82 fn cast(syntax: SyntaxToken) -> Option<Self> { 49 fn cast(syntax: SyntaxToken) -> Option<Self> {
@@ -84,103 +51,18 @@ fn generate_tokens(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
84 } 51 }
85 fn syntax(&self) -> &SyntaxToken { &self.syntax } 52 fn syntax(&self) -> &SyntaxToken { &self.syntax }
86 } 53 }
87 };
88 Some(res)
89 });
90
91 let enums = grammar.token_enums.iter().map(|en| {
92 let variants = en.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>();
93 let name = format_ident!("{}", en.name);
94 let kinds = variants
95 .iter()
96 .map(|name| format_ident!("{}", to_upper_snake_case(&name.to_string())))
97 .collect::<Vec<_>>();
98 assert!(en.traits.is_empty());
99
100 quote! {
101 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
102 pub enum #name {
103 #(#variants(#variants),)*
104 }
105
106 #(
107 impl From<#variants> for #name {
108 fn from(node: #variants) -> #name {
109 #name::#variants(node)
110 }
111 }
112 )*
113
114 impl std::fmt::Display for #name {
115 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
116 std::fmt::Display::fmt(self.syntax(), f)
117 }
118 }
119
120 impl AstToken for #name {
121 fn can_cast(kind: SyntaxKind) -> bool {
122 match kind {
123 #(#kinds)|* => true,
124 _ => false,
125 }
126 }
127 fn cast(syntax: SyntaxToken) -> Option<Self> {
128 let res = match syntax.kind() {
129 #(
130 #kinds => #name::#variants(#variants { syntax }),
131 )*
132 _ => return None,
133 };
134 Some(res)
135 }
136 fn syntax(&self) -> &SyntaxToken {
137 match self {
138 #(
139 #name::#variants(it) => &it.syntax,
140 )*
141 }
142 }
143 }
144 } 54 }
145 }); 55 });
146 56
147 crate::reformat(quote! { 57 let pretty = crate::reformat(quote! {
148 use crate::{SyntaxToken, SyntaxKind::{self, *}, ast::AstToken}; 58 use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken};
149
150 #(#tokens)* 59 #(#tokens)*
151 #(#enums)* 60 })?
152 }) 61 .replace("#[derive", "\n#[derive");
62 Ok(pretty)
153} 63}
154 64
155fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { 65fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
156 let all_token_kinds: Vec<_> = kinds
157 .punct
158 .into_iter()
159 .map(|(_, kind)| kind)
160 .copied()
161 .map(|x| x.into())
162 .chain(
163 kinds
164 .keywords
165 .into_iter()
166 .chain(kinds.contextual_keywords.into_iter())
167 .map(|name| Cow::Owned(format!("{}_KW", to_upper_snake_case(&name)))),
168 )
169 .chain(kinds.literals.into_iter().copied().map(|x| x.into()))
170 .chain(kinds.tokens.into_iter().copied().map(|x| x.into()))
171 .collect();
172
173 let mut token_kinds = HashSet::new();
174 for kind in &all_token_kinds {
175 let kind = &**kind;
176 let name = to_pascal_case(kind);
177 token_kinds.insert(name);
178 }
179
180 for en in grammar.token_enums {
181 token_kinds.insert(en.name.to_string());
182 }
183
184 let nodes = grammar.nodes.iter().map(|node| { 66 let nodes = grammar.nodes.iter().map(|node| {
185 let name = format_ident!("{}", node.name); 67 let name = format_ident!("{}", node.name);
186 let kind = format_ident!("{}", to_upper_snake_case(&name.to_string())); 68 let kind = format_ident!("{}", to_upper_snake_case(&name.to_string()));
@@ -189,53 +71,27 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
189 quote!(impl ast::#trait_name for #name {}) 71 quote!(impl ast::#trait_name for #name {})
190 }); 72 });
191 73
192 let methods = node.fields.iter().map(|(name, field)| { 74 let methods = node.fields.iter().map(|field| {
193 let is_kw = name.ends_with("Kw"); 75 let method_name = field.method_name();
194 let method_name = match field { 76 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 77
206 let ty = format_ident!("{}", ty); 78 if field.is_many() {
207 79 quote! {
208 match field { 80 pub fn #method_name(&self) -> AstChildren<#ty> {
209 FieldSrc::Many(_) => { 81 support::children(&self.syntax)
210 quote! {
211 pub fn #method_name(&self) -> AstChildren<#ty> {
212 support::children(&self.syntax)
213 }
214 } 82 }
215 } 83 }
216 FieldSrc::Optional(_) | FieldSrc::Shorthand => { 84 } else {
217 let is_token = token_kinds.contains(&ty.to_string()); 85 if let Some(token_kind) = field.token_kind() {
218 if is_token { 86 quote! {
219 let method_name = format_ident!("{}_token", method_name); 87 pub fn #method_name(&self) -> Option<#ty> {
220 if is_kw { 88 support::token(&self.syntax, #token_kind)
221 let token_kind = format_ident!("{}", to_upper_snake_case(name));
222 quote! {
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 }
233 } 89 }
234 } else { 90 }
235 quote! { 91 } else {
236 pub fn #method_name(&self) -> Option<#ty> { 92 quote! {
237 support::child(&self.syntax) 93 pub fn #method_name(&self) -> Option<#ty> {
238 } 94 support::child(&self.syntax)
239 } 95 }
240 } 96 }
241 } 97 }
@@ -351,16 +207,16 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
351 use crate::{ 207 use crate::{
352 SyntaxNode, SyntaxToken, SyntaxKind::{self, *}, 208 SyntaxNode, SyntaxToken, SyntaxKind::{self, *},
353 ast::{self, AstNode, AstChildren, support}, 209 ast::{self, AstNode, AstChildren, support},
210 T,
354 }; 211 };
355 212
356 use super::tokens::*;
357
358 #(#nodes)* 213 #(#nodes)*
359 #(#enums)* 214 #(#enums)*
360 #(#displays)* 215 #(#displays)*
361 }; 216 };
362 217
363 let pretty = crate::reformat(ast)?; 218 let ast = ast.to_string().replace("T ! [ ", "T![").replace(" ] )", "])");
219 let pretty = crate::reformat(ast)?.replace("#[derive", "\n#[derive");
364 Ok(pretty) 220 Ok(pretty)
365} 221}
366 222
@@ -468,8 +324,10 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> Result<String> {
468 324
469 #[macro_export] 325 #[macro_export]
470 macro_rules! T { 326 macro_rules! T {
471 #((#punctuation_values) => { $crate::SyntaxKind::#punctuation };)* 327 #([#punctuation_values] => { $crate::SyntaxKind::#punctuation };)*
472 #((#all_keywords_idents) => { $crate::SyntaxKind::#all_keywords };)* 328 #([#all_keywords_idents] => { $crate::SyntaxKind::#all_keywords };)*
329 [lifetime] => { $crate::SyntaxKind::LIFETIME };
330 [ident] => { $crate::SyntaxKind::IDENT };
473 } 331 }
474 }; 332 };
475 333
@@ -519,3 +377,68 @@ fn to_pascal_case(s: &str) -> String {
519 } 377 }
520 buf 378 buf
521} 379}
380
381impl Field<'_> {
382 fn is_many(&self) -> bool {
383 match self {
384 Field::Node { src: FieldSrc::Many(_), .. } => true,
385 _ => false,
386 }
387 }
388 fn token_kind(&self) -> Option<proc_macro2::TokenStream> {
389 let res = match self {
390 Field::Token(token) => {
391 let token: proc_macro2::TokenStream = token.parse().unwrap();
392 quote! { T![#token] }
393 }
394 _ => return None,
395 };
396 Some(res)
397 }
398 fn method_name(&self) -> proc_macro2::Ident {
399 match self {
400 Field::Token(name) => {
401 let name = match *name {
402 ";" => "semicolon",
403 "->" => "thin_arrow",
404 "'{'" => "l_curly",
405 "'}'" => "r_curly",
406 "'('" => "l_paren",
407 "')'" => "r_paren",
408 "'['" => "l_brack",
409 "']'" => "r_brack",
410 "<" => "l_angle",
411 ">" => "r_angle",
412 "=" => "eq",
413 "!" => "excl",
414 "*" => "star",
415 "&" => "amp",
416 "_" => "underscore",
417 "." => "dot",
418 ".." => "dotdot",
419 "..." => "dotdotdot",
420 "=>" => "fat_arrow",
421 "@" => "at",
422 ":" => "colon",
423 "::" => "coloncolon",
424 "#" => "pound",
425 _ => name,
426 };
427 format_ident!("{}_token", name)
428 }
429 Field::Node { name, src } => match src {
430 FieldSrc::Shorthand => format_ident!("{}", to_lower_snake_case(name)),
431 _ => format_ident!("{}", name),
432 },
433 }
434 }
435 fn ty(&self) -> proc_macro2::Ident {
436 match self {
437 Field::Token(_) => format_ident!("SyntaxToken"),
438 Field::Node { name, src } => match src {
439 FieldSrc::Optional(ty) | FieldSrc::Many(ty) => format_ident!("{}", ty),
440 FieldSrc::Shorthand => format_ident!("{}", name),
441 },
442 }
443 }
444}