aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/ast_src.rs379
-rw-r--r--xtask/src/codegen.rs5
-rw-r--r--xtask/src/codegen/gen_syntax.rs257
-rw-r--r--xtask/src/lib.rs1
4 files changed, 518 insertions, 124 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index d9f51ec39..74a87e900 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -70,7 +70,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
70 "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super", 70 "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super",
71 "trait", "true", "try", "type", "unsafe", "use", "where", "while", 71 "trait", "true", "try", "type", "unsafe", "use", "where", "while",
72 ], 72 ],
73 contextual_keywords: &["auto", "default", "existential", "union"], 73 contextual_keywords: &["auto", "default", "existential", "union", "raw"],
74 literals: &[ 74 literals: &[
75 "INT_NUMBER", 75 "INT_NUMBER",
76 "FLOAT_NUMBER", 76 "FLOAT_NUMBER",
@@ -227,6 +227,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
227pub(crate) struct AstSrc<'a> { 227pub(crate) struct AstSrc<'a> {
228 pub(crate) nodes: &'a [AstNodeSrc<'a>], 228 pub(crate) nodes: &'a [AstNodeSrc<'a>],
229 pub(crate) enums: &'a [AstEnumSrc<'a>], 229 pub(crate) enums: &'a [AstEnumSrc<'a>],
230 pub(crate) token_enums: &'a [AstEnumSrc<'a>],
230} 231}
231 232
232pub(crate) struct AstNodeSrc<'a> { 233pub(crate) struct AstNodeSrc<'a> {
@@ -297,235 +298,311 @@ macro_rules! ast_enums {
297 298
298pub(crate) const AST_SRC: AstSrc = AstSrc { 299pub(crate) const AST_SRC: AstSrc = AstSrc {
299 nodes: &ast_nodes! { 300 nodes: &ast_nodes! {
300 struct SourceFile: ModuleItemOwner, FnDefOwner { 301 struct SourceFile: ModuleItemOwner, FnDefOwner, AttrsOwner {
301 modules: [Module], 302 modules: [Module],
302 } 303 }
303 304
304 struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner { 305 struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
306 Abi,
307 ConstKw,
308 DefaultKw,
309 AsyncKw,
310 UnsafeKw,
311 FnKw,
305 ParamList, 312 ParamList,
306 RetType, 313 RetType,
307 body: BlockExpr, 314 body: BlockExpr,
315 Semi
308 } 316 }
309 317
310 struct RetType { TypeRef } 318 struct RetType { ThinArrow, TypeRef }
311 319
312 struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 320 struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
321 StructKw,
322 FieldDefList,
323 Semi
313 } 324 }
314 325
315 struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 326 struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
327 UnionKw,
316 RecordFieldDefList, 328 RecordFieldDefList,
317 } 329 }
318 330
319 struct RecordFieldDefList { fields: [RecordFieldDef] } 331 struct RecordFieldDefList { LCurly, fields: [RecordFieldDef], RCurly }
320 struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { } 332 struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { }
321 333
322 struct TupleFieldDefList { fields: [TupleFieldDef] } 334 struct TupleFieldDefList { LParen, fields: [TupleFieldDef], RParen }
323 struct TupleFieldDef: VisibilityOwner, AttrsOwner { 335 struct TupleFieldDef: VisibilityOwner, AttrsOwner {
324 TypeRef, 336 TypeRef,
325 } 337 }
326 338
327 struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner { 339 struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
340 EnumKw,
328 variant_list: EnumVariantList, 341 variant_list: EnumVariantList,
329 } 342 }
330 struct EnumVariantList { 343 struct EnumVariantList {
344 LCurly,
331 variants: [EnumVariant], 345 variants: [EnumVariant],
346 RCurly
332 } 347 }
333 struct EnumVariant: NameOwner, DocCommentsOwner, AttrsOwner { 348 struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner {
349 FieldDefList,
350 Eq,
334 Expr 351 Expr
335 } 352 }
336 353
337 struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner { 354 struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
355 UnsafeKw,
356 AutoKw,
357 TraitKw,
338 ItemList, 358 ItemList,
339 } 359 }
340 360
341 struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner { 361 struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
362 ModKw,
342 ItemList, 363 ItemList,
364 Semi
343 } 365 }
344 366
345 struct ItemList: FnDefOwner, ModuleItemOwner { 367 struct ItemList: FnDefOwner, ModuleItemOwner {
368 LCurly,
346 impl_items: [ImplItem], 369 impl_items: [ImplItem],
370 RCurly
347 } 371 }
348 372
349 struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { 373 struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
374 DefaultKw,
375 ConstKw,
376 Eq,
350 body: Expr, 377 body: Expr,
378 Semi
351 } 379 }
352 380
353 struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { 381 struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
382 StaticKw,
383 MutKw,
384 Eq,
354 body: Expr, 385 body: Expr,
386 Semi
355 } 387 }
356 388
357 struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner { 389 struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
390 DefaultKw,
391 TypeKw,
392 Eq,
358 TypeRef, 393 TypeRef,
394 Semi
359 } 395 }
360 396
361 struct ImplDef: TypeParamsOwner, AttrsOwner { 397 struct ImplDef: TypeParamsOwner, AttrsOwner {
398 DefaultKw,
399 ConstKw,
400 UnsafeKw,
401 ImplKw,
402 Excl,
403 ForKw,
362 ItemList, 404 ItemList,
363 } 405 }
364 406
365 struct ParenType { TypeRef } 407 struct ParenType { LParen, TypeRef, RParen }
366 struct TupleType { fields: [TypeRef] } 408 struct TupleType { LParen, fields: [TypeRef], RParen }
367 struct NeverType { } 409 struct NeverType { Excl }
368 struct PathType { Path } 410 struct PathType { Path }
369 struct PointerType { TypeRef } 411 struct PointerType { Star, ConstKw, MutKw, TypeRef }
370 struct ArrayType { TypeRef, Expr } 412 struct ArrayType { LBrack, TypeRef, Semi, Expr, RBrack }
371 struct SliceType { TypeRef } 413 struct SliceType { LBrack, TypeRef, RBrack }
372 struct ReferenceType { TypeRef } 414 struct ReferenceType { Amp, Lifetime, MutKw, TypeRef }
373 struct PlaceholderType { } 415 struct PlaceholderType { Underscore }
374 struct FnPointerType { ParamList, RetType } 416 struct FnPointerType { Abi, UnsafeKw, FnKw, ParamList, RetType }
375 struct ForType { TypeRef } 417 struct ForType { ForKw, TypeParamList, TypeRef }
376 struct ImplTraitType: TypeBoundsOwner {} 418 struct ImplTraitType: TypeBoundsOwner { ImplKw }
377 struct DynTraitType: TypeBoundsOwner {} 419 struct DynTraitType: TypeBoundsOwner { DynKw }
378 420
379 struct TupleExpr { exprs: [Expr] } 421 struct TupleExpr: AttrsOwner { LParen, exprs: [Expr], RParen }
380 struct ArrayExpr { exprs: [Expr] } 422 struct ArrayExpr: AttrsOwner { LBrack, exprs: [Expr], Semi, RBrack }
381 struct ParenExpr { Expr } 423 struct ParenExpr: AttrsOwner { LParen, Expr, RParen }
382 struct PathExpr { Path } 424 struct PathExpr { Path }
383 struct LambdaExpr { 425 struct LambdaExpr: AttrsOwner {
426 StaticKw,
427 AsyncKw,
428 MoveKw,
384 ParamList, 429 ParamList,
385 RetType, 430 RetType,
386 body: Expr, 431 body: Expr,
387 } 432 }
388 struct IfExpr { Condition } 433 struct IfExpr: AttrsOwner { IfKw, Condition }
389 struct LoopExpr: LoopBodyOwner { } 434 struct LoopExpr: AttrsOwner, LoopBodyOwner { LoopKw }
390 struct TryBlockExpr { body: BlockExpr } 435 struct TryBlockExpr: AttrsOwner { TryKw, body: BlockExpr }
391 struct ForExpr: LoopBodyOwner { 436 struct ForExpr: AttrsOwner, LoopBodyOwner {
437 ForKw,
392 Pat, 438 Pat,
439 InKw,
393 iterable: Expr, 440 iterable: Expr,
394 } 441 }
395 struct WhileExpr: LoopBodyOwner { Condition } 442 struct WhileExpr: AttrsOwner, LoopBodyOwner { WhileKw, Condition }
396 struct ContinueExpr {} 443 struct ContinueExpr: AttrsOwner { ContinueKw, Lifetime }
397 struct BreakExpr { Expr } 444 struct BreakExpr: AttrsOwner { BreakKw, Lifetime, Expr }
398 struct Label {} 445 struct Label { Lifetime }
399 struct BlockExpr { Block } 446 struct BlockExpr: AttrsOwner { Label, UnsafeKw, Block }
400 struct ReturnExpr { Expr } 447 struct ReturnExpr: AttrsOwner { Expr }
401 struct CallExpr: ArgListOwner { Expr } 448 struct CallExpr: ArgListOwner { Expr }
402 struct MethodCallExpr: ArgListOwner { 449 struct MethodCallExpr: AttrsOwner, ArgListOwner {
403 Expr, NameRef, TypeArgList, 450 Expr, Dot, NameRef, TypeArgList,
404 } 451 }
405 struct IndexExpr {} 452 struct IndexExpr: AttrsOwner { LBrack, RBrack }
406 struct FieldExpr { Expr, NameRef } 453 struct FieldExpr: AttrsOwner { Expr, Dot, NameRef }
407 struct AwaitExpr { Expr } 454 struct AwaitExpr: AttrsOwner { Expr, Dot, AwaitKw }
408 struct TryExpr { Expr } 455 struct TryExpr: AttrsOwner { TryKw, Expr }
409 struct CastExpr { Expr, TypeRef } 456 struct CastExpr: AttrsOwner { Expr, AsKw, TypeRef }
410 struct RefExpr { Expr } 457 struct RefExpr: AttrsOwner { Amp, RawKw, MutKw, Expr }
411 struct PrefixExpr { Expr } 458 struct PrefixExpr: AttrsOwner { PrefixOp, Expr }
412 struct BoxExpr { Expr } 459 struct BoxExpr: AttrsOwner { BoxKw, Expr }
413 struct RangeExpr {} 460 struct RangeExpr: AttrsOwner { RangeOp }
414 struct BinExpr {} 461 struct BinExpr: AttrsOwner { BinOp }
415 struct Literal {} 462 struct Literal { LiteralToken }
416 463
417 struct MatchExpr { Expr, MatchArmList } 464 struct MatchExpr: AttrsOwner { MatchKw, Expr, MatchArmList }
418 struct MatchArmList: AttrsOwner { arms: [MatchArm] } 465 struct MatchArmList: AttrsOwner { LCurly, arms: [MatchArm], RCurly }
419 struct MatchArm: AttrsOwner { 466 struct MatchArm: AttrsOwner {
420 pat: Pat, 467 pat: Pat,
421 guard: MatchGuard, 468 guard: MatchGuard,
469 FatArrow,
422 Expr, 470 Expr,
423 } 471 }
424 struct MatchGuard { Expr } 472 struct MatchGuard { IfKw, Expr }
425 473
426 struct RecordLit { Path, RecordFieldList } 474 struct RecordLit { Path, RecordFieldList}
427 struct RecordFieldList { 475 struct RecordFieldList {
476 LCurly,
428 fields: [RecordField], 477 fields: [RecordField],
478 Dotdot,
429 spread: Expr, 479 spread: Expr,
480 RCurly
430 } 481 }
431 struct RecordField { NameRef, Expr } 482 struct RecordField: AttrsOwner { NameRef, Colon, Expr }
432 483
433 struct OrPat { pats: [Pat] } 484 struct OrPat { pats: [Pat] }
434 struct ParenPat { Pat } 485 struct ParenPat { LParen, Pat, RParen }
435 struct RefPat { Pat } 486 struct RefPat { Amp, MutKw, Pat }
436 struct BoxPat { Pat } 487 struct BoxPat { BoxKw, Pat }
437 struct BindPat: NameOwner { Pat } 488 struct BindPat: AttrsOwner, NameOwner { RefKw, MutKw, At, Pat }
438 struct PlaceholderPat { } 489 struct PlaceholderPat { Underscore }
439 struct DotDotPat { } 490 struct DotDotPat { Dotdot }
440 struct PathPat { Path } 491 struct PathPat { Path }
441 struct SlicePat { args: [Pat] } 492 struct SlicePat { LBrack, args: [Pat], RBrack }
442 struct RangePat {} 493 struct RangePat { RangeSeparator }
443 struct LiteralPat { Literal } 494 struct LiteralPat { Literal }
444 struct MacroPat { MacroCall } 495 struct MacroPat { MacroCall }
445 496
446 struct RecordPat { RecordFieldPatList, Path } 497 struct RecordPat { RecordFieldPatList, Path }
447 struct RecordFieldPatList { 498 struct RecordFieldPatList {
499 LCurly,
500 pats: [RecordInnerPat],
448 record_field_pats: [RecordFieldPat], 501 record_field_pats: [RecordFieldPat],
449 bind_pats: [BindPat], 502 bind_pats: [BindPat],
503 Dotdot,
504 RCurly
450 } 505 }
451 struct RecordFieldPat: NameOwner { Pat } 506 struct RecordFieldPat: AttrsOwner, NameOwner { Colon, Pat }
452 507
453 struct TupleStructPat { Path, args: [Pat] } 508 struct TupleStructPat { Path, LParen, args: [Pat], RParen }
454 struct TuplePat { args: [Pat] } 509 struct TuplePat { LParen, args: [Pat], RParen }
455 510
456 struct Visibility {} 511 struct Visibility { PubKw, SuperKw, SelfKw, CrateKw }
457 struct Name {} 512 struct Name { Ident }
458 struct NameRef {} 513 struct NameRef { NameRefToken }
459 514
460 struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner { 515 struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner {
461 TokenTree, Path 516 Path, Excl, TokenTree, Semi
462 } 517 }
463 struct Attr { Path, input: AttrInput } 518 struct Attr { Pound, Excl, LBrack, Path, Eq, input: AttrInput, RBrack }
464 struct TokenTree {} 519 struct TokenTree {}
465 struct TypeParamList { 520 struct TypeParamList {
521 LAngle,
522 generic_params: [GenericParam],
466 type_params: [TypeParam], 523 type_params: [TypeParam],
467 lifetime_params: [LifetimeParam], 524 lifetime_params: [LifetimeParam],
525 const_params: [ConstParam],
526 RAngle
468 } 527 }
469 struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner { 528 struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner {
529 Eq,
470 default_type: TypeRef, 530 default_type: TypeRef,
471 } 531 }
472 struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner { 532 struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner {
533 Eq,
473 default_val: Expr, 534 default_val: Expr,
474 } 535 }
475 struct LifetimeParam: AttrsOwner { } 536 struct LifetimeParam: AttrsOwner { Lifetime}
476 struct TypeBound { TypeRef} 537 struct TypeBound { Lifetime, /* Question, */ ConstKw, /* Question, */ TypeRef}
477 struct TypeBoundList { bounds: [TypeBound] } 538 struct TypeBoundList { bounds: [TypeBound] }
478 struct WherePred: TypeBoundsOwner { TypeRef } 539 struct WherePred: TypeBoundsOwner { Lifetime, TypeRef }
479 struct WhereClause { predicates: [WherePred] } 540 struct WhereClause { WhereKw, predicates: [WherePred] }
480 struct ExprStmt { Expr } 541 struct Abi { String }
481 struct LetStmt: TypeAscriptionOwner { 542 struct ExprStmt: AttrsOwner { Expr, Semi }
543 struct LetStmt: AttrsOwner, TypeAscriptionOwner {
544 LetKw,
482 Pat, 545 Pat,
546 Eq,
483 initializer: Expr, 547 initializer: Expr,
548 Semi,
484 } 549 }
485 struct Condition { Pat, Expr } 550 struct Condition { LetKw, Pat, Eq, Expr }
486 struct Block: AttrsOwner, ModuleItemOwner { 551 struct Block: AttrsOwner, ModuleItemOwner {
552 LCurly,
487 statements: [Stmt], 553 statements: [Stmt],
488 Expr, 554 Expr,
555 RCurly,
489 } 556 }
490 struct ParamList { 557 struct ParamList {
558 LParen,
491 SelfParam, 559 SelfParam,
492 params: [Param], 560 params: [Param],
561 RParen
493 } 562 }
494 struct SelfParam: TypeAscriptionOwner, AttrsOwner { } 563 struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, SelfKw }
495 struct Param: TypeAscriptionOwner, AttrsOwner { 564 struct Param: TypeAscriptionOwner, AttrsOwner {
496 Pat, 565 Pat,
566 Dotdotdot
497 } 567 }
498 struct UseItem: AttrsOwner, VisibilityOwner { 568 struct UseItem: AttrsOwner, VisibilityOwner {
569 UseKw,
499 UseTree, 570 UseTree,
500 } 571 }
501 struct UseTree { 572 struct UseTree {
502 Path, UseTreeList, Alias 573 Path, Star, UseTreeList, Alias
503 } 574 }
504 struct Alias: NameOwner { } 575 struct Alias: NameOwner { AsKw }
505 struct UseTreeList { use_trees: [UseTree] } 576 struct UseTreeList { LCurly, use_trees: [UseTree], RCurly }
506 struct ExternCrateItem: AttrsOwner, VisibilityOwner { 577 struct ExternCrateItem: AttrsOwner, VisibilityOwner {
507 NameRef, Alias, 578 ExternKw, CrateKw, NameRef, Alias,
508 } 579 }
509 struct ArgList { 580 struct ArgList {
581 LParen,
510 args: [Expr], 582 args: [Expr],
583 RParen
511 } 584 }
512 struct Path { 585 struct Path {
513 segment: PathSegment, 586 segment: PathSegment,
514 qualifier: Path, 587 qualifier: Path,
515 } 588 }
516 struct PathSegment { 589 struct PathSegment {
517 NameRef, TypeArgList, ParamList, RetType, PathType, 590 Coloncolon, LAngle, NameRef, TypeArgList, ParamList, RetType, PathType, RAngle
518 } 591 }
519 struct TypeArgList { 592 struct TypeArgList {
593 Coloncolon,
594 LAngle,
595 generic_args: [GenericArg],
520 type_args: [TypeArg], 596 type_args: [TypeArg],
521 lifetime_args: [LifetimeArg], 597 lifetime_args: [LifetimeArg],
522 assoc_type_args: [AssocTypeArg], 598 assoc_type_args: [AssocTypeArg],
523 const_arg: [ConstArg], 599 const_args: [ConstArg],
600 RAngle
524 } 601 }
525 struct TypeArg { TypeRef } 602 struct TypeArg { TypeRef }
526 struct AssocTypeArg { NameRef, TypeRef } 603 struct AssocTypeArg : TypeBoundsOwner { NameRef, Eq, TypeRef }
527 struct LifetimeArg {} 604 struct LifetimeArg { Lifetime }
528 struct ConstArg { Literal, BlockExpr } 605 struct ConstArg { Literal, Eq, BlockExpr }
529 606
530 struct MacroItems: ModuleItemOwner, FnDefOwner { } 607 struct MacroItems: ModuleItemOwner, FnDefOwner { }
531 608
@@ -533,12 +610,44 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
533 statements: [Stmt], 610 statements: [Stmt],
534 Expr, 611 Expr,
535 } 612 }
613
614 struct ExternItemList: FnDefOwner, ModuleItemOwner {
615 LCurly,
616 extern_items: [ExternItem],
617 RCurly
618 }
619
620 struct ExternBlock {
621 Abi,
622 ExternItemList
623 }
624
625 struct MetaItem {
626 Path, Eq, AttrInput, nested_meta_items: [MetaItem]
627 }
628
629 struct MacroDef {
630 Name, TokenTree
631 }
536 }, 632 },
537 enums: &ast_enums! { 633 enums: &ast_enums! {
538 enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner { 634 enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner {
539 StructDef, EnumDef, UnionDef, 635 StructDef, EnumDef, UnionDef,
540 } 636 }
541 637
638 enum GenericParam {
639 LifetimeParam,
640 TypeParam,
641 ConstParam
642 }
643
644 enum GenericArg {
645 LifetimeArg,
646 TypeArg,
647 ConstArg,
648 AssocTypeArg
649 }
650
542 enum TypeRef { 651 enum TypeRef {
543 ParenType, 652 ParenType,
544 TupleType, 653 TupleType,
@@ -555,7 +664,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
555 DynTraitType, 664 DynTraitType,
556 } 665 }
557 666
558 enum ModuleItem: AttrsOwner, VisibilityOwner { 667 enum ModuleItem: NameOwner, AttrsOwner, VisibilityOwner {
559 StructDef, 668 StructDef,
560 UnionDef, 669 UnionDef,
561 EnumDef, 670 EnumDef,
@@ -569,13 +678,20 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
569 StaticDef, 678 StaticDef,
570 Module, 679 Module,
571 MacroCall, 680 MacroCall,
681 ExternBlock
572 } 682 }
573 683
574 enum ImplItem: AttrsOwner { 684 /* impl blocks can also contain MacroCall */
575 FnDef, TypeAliasDef, ConstDef, 685 enum ImplItem: NameOwner, AttrsOwner {
686 FnDef, TypeAliasDef, ConstDef
576 } 687 }
577 688
578 enum Expr { 689 /* extern blocks can also contain MacroCall */
690 enum ExternItem: NameOwner, AttrsOwner, VisibilityOwner {
691 FnDef, StaticDef
692 }
693
694 enum Expr: AttrsOwner {
579 TupleExpr, 695 TupleExpr,
580 ArrayExpr, 696 ArrayExpr,
581 ParenExpr, 697 ParenExpr,
@@ -627,7 +743,88 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
627 MacroPat, 743 MacroPat,
628 } 744 }
629 745
746 enum RecordInnerPat {
747 RecordFieldPat,
748 BindPat
749 }
750
630 enum AttrInput { Literal, TokenTree } 751 enum AttrInput { Literal, TokenTree }
631 enum Stmt { ExprStmt, LetStmt } 752 enum Stmt {
753 LetStmt,
754 ExprStmt,
755 // macro calls are parsed as expression statements */
756 }
757
758 enum FieldDefList {
759 RecordFieldDefList,
760 TupleFieldDefList,
761 }
762 },
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 }
632 }, 829 },
633}; 830};
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index a53d57335..678b40133 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -22,8 +22,9 @@ const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar";
22const OK_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/ok"; 22const OK_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/ok";
23const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/err"; 23const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/err";
24 24
25pub const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs"; 25const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs";
26pub const AST: &str = "crates/ra_syntax/src/ast/generated.rs"; 26const AST_NODES: &str = "crates/ra_syntax/src/ast/generated/nodes.rs";
27const AST_TOKENS: &str = "crates/ra_syntax/src/ast/generated/tokens.rs";
27 28
28const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers"; 29const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers";
29const ASSISTS_TESTS: &str = "crates/ra_assists/src/doc_tests/generated.rs"; 30const ASSISTS_TESTS: &str = "crates/ra_assists/src/doc_tests/generated.rs";
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 32afd47bc..b5594e3a9 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -3,6 +3,11 @@
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::{
7 borrow::Cow,
8 collections::{BTreeSet, HashSet},
9};
10
6use proc_macro2::{Punct, Spacing}; 11use proc_macro2::{Punct, Spacing};
7use quote::{format_ident, quote}; 12use quote::{format_ident, quote};
8 13
@@ -17,14 +22,161 @@ pub fn generate_syntax(mode: Mode) -> Result<()> {
17 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; 22 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
18 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; 23 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
19 24
20 let ast_file = project_root().join(codegen::AST); 25 let ast_nodes_file = project_root().join(codegen::AST_NODES);
21 let ast = generate_ast(AST_SRC)?; 26 let contents = generate_nodes(KINDS_SRC, AST_SRC)?;
22 update(ast_file.as_path(), &ast, mode)?; 27 update(ast_nodes_file.as_path(), &contents, mode)?;
28
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)?;
23 32
24 Ok(()) 33 Ok(())
25} 34}
26 35
27fn generate_ast(grammar: AstSrc<'_>) -> Result<String> { 36#[derive(Debug, Default, Clone)]
37struct ElementKinds {
38 kinds: BTreeSet<proc_macro2::Ident>,
39 has_nodes: bool,
40 has_tokens: bool,
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().map(|kind_str| {
62 let kind_str = &**kind_str;
63 let kind = format_ident!("{}", kind_str);
64 let name = format_ident!("{}", to_pascal_case(kind_str));
65 quote! {
66 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
67 pub struct #name {
68 pub(crate) syntax: SyntaxToken,
69 }
70
71 impl std::fmt::Display for #name {
72 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
73 std::fmt::Display::fmt(&self.syntax, f)
74 }
75 }
76
77 impl AstToken for #name {
78 fn can_cast(kind: SyntaxKind) -> bool { kind == #kind }
79 fn cast(syntax: SyntaxToken) -> Option<Self> {
80 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
81 }
82 fn syntax(&self) -> &SyntaxToken { &self.syntax }
83 }
84 }
85 });
86
87 let enums = grammar.token_enums.iter().map(|en| {
88 let variants = en.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>();
89 let name = format_ident!("{}", en.name);
90 let kinds = variants
91 .iter()
92 .map(|name| format_ident!("{}", to_upper_snake_case(&name.to_string())))
93 .collect::<Vec<_>>();
94 assert!(en.traits.is_empty());
95
96 quote! {
97 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
98 pub enum #name {
99 #(#variants(#variants),)*
100 }
101
102 #(
103 impl From<#variants> for #name {
104 fn from(node: #variants) -> #name {
105 #name::#variants(node)
106 }
107 }
108 )*
109
110 impl std::fmt::Display for #name {
111 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
112 std::fmt::Display::fmt(self.syntax(), f)
113 }
114 }
115
116 impl AstToken for #name {
117 fn can_cast(kind: SyntaxKind) -> bool {
118 match kind {
119 #(#kinds)|* => true,
120 _ => false,
121 }
122 }
123 fn cast(syntax: SyntaxToken) -> Option<Self> {
124 let res = match syntax.kind() {
125 #(
126 #kinds => #name::#variants(#variants { syntax }),
127 )*
128 _ => return None,
129 };
130 Some(res)
131 }
132 fn syntax(&self) -> &SyntaxToken {
133 match self {
134 #(
135 #name::#variants(it) => &it.syntax,
136 )*
137 }
138 }
139 }
140 }
141 });
142
143 crate::reformat(quote! {
144 use crate::{SyntaxToken, SyntaxKind::{self, *}, ast::AstToken};
145
146 #(#tokens)*
147 #(#enums)*
148 })
149}
150
151fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
152 let all_token_kinds: Vec<_> = kinds
153 .punct
154 .into_iter()
155 .map(|(_, kind)| kind)
156 .copied()
157 .map(|x| x.into())
158 .chain(
159 kinds
160 .keywords
161 .into_iter()
162 .chain(kinds.contextual_keywords.into_iter())
163 .map(|name| Cow::Owned(format!("{}_KW", to_upper_snake_case(&name)))),
164 )
165 .chain(kinds.literals.into_iter().copied().map(|x| x.into()))
166 .chain(kinds.tokens.into_iter().copied().map(|x| x.into()))
167 .collect();
168
169 let mut token_kinds = HashSet::new();
170 for kind in &all_token_kinds {
171 let kind = &**kind;
172 let name = to_pascal_case(kind);
173 token_kinds.insert(name);
174 }
175
176 for en in grammar.token_enums {
177 token_kinds.insert(en.name.to_string());
178 }
179
28 let nodes = grammar.nodes.iter().map(|node| { 180 let nodes = grammar.nodes.iter().map(|node| {
29 let name = format_ident!("{}", node.name); 181 let name = format_ident!("{}", node.name);
30 let kind = format_ident!("{}", to_upper_snake_case(&name.to_string())); 182 let kind = format_ident!("{}", to_upper_snake_case(&name.to_string()));
@@ -42,20 +194,31 @@ fn generate_ast(grammar: AstSrc<'_>) -> Result<String> {
42 FieldSrc::Optional(ty) | FieldSrc::Many(ty) => ty, 194 FieldSrc::Optional(ty) | FieldSrc::Many(ty) => ty,
43 FieldSrc::Shorthand => name, 195 FieldSrc::Shorthand => name,
44 }; 196 };
197
45 let ty = format_ident!("{}", ty); 198 let ty = format_ident!("{}", ty);
46 199
47 match field { 200 match field {
48 FieldSrc::Many(_) => { 201 FieldSrc::Many(_) => {
49 quote! { 202 quote! {
50 pub fn #method_name(&self) -> AstChildren<#ty> { 203 pub fn #method_name(&self) -> AstChildren<#ty> {
51 AstChildren::new(&self.syntax) 204 support::children(&self.syntax)
52 } 205 }
53 } 206 }
54 } 207 }
55 FieldSrc::Optional(_) | FieldSrc::Shorthand => { 208 FieldSrc::Optional(_) | FieldSrc::Shorthand => {
56 quote! { 209 let is_token = token_kinds.contains(&ty.to_string());
57 pub fn #method_name(&self) -> Option<#ty> { 210 if is_token {
58 AstChildren::new(&self.syntax).next() 211 let method_name = format_ident!("{}_token", method_name);
212 quote! {
213 pub fn #method_name(&self) -> Option<#ty> {
214 support::token(&self.syntax)
215 }
216 }
217 } else {
218 quote! {
219 pub fn #method_name(&self) -> Option<#ty> {
220 support::child(&self.syntax)
221 }
59 } 222 }
60 } 223 }
61 } 224 }
@@ -68,24 +231,16 @@ fn generate_ast(grammar: AstSrc<'_>) -> Result<String> {
68 pub(crate) syntax: SyntaxNode, 231 pub(crate) syntax: SyntaxNode,
69 } 232 }
70 233
71 impl std::fmt::Display for #name {
72 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
73 std::fmt::Display::fmt(self.syntax(), f)
74 }
75 }
76
77 impl AstNode for #name { 234 impl AstNode for #name {
78 fn can_cast(kind: SyntaxKind) -> bool { 235 fn can_cast(kind: SyntaxKind) -> bool {
79 match kind { 236 kind == #kind
80 #kind => true,
81 _ => false,
82 }
83 } 237 }
84 fn cast(syntax: SyntaxNode) -> Option<Self> { 238 fn cast(syntax: SyntaxNode) -> Option<Self> {
85 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } 239 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
86 } 240 }
87 fn syntax(&self) -> &SyntaxNode { &self.syntax } 241 fn syntax(&self) -> &SyntaxNode { &self.syntax }
88 } 242 }
243
89 #(#traits)* 244 #(#traits)*
90 245
91 impl #name { 246 impl #name {
@@ -120,12 +275,6 @@ fn generate_ast(grammar: AstSrc<'_>) -> Result<String> {
120 } 275 }
121 )* 276 )*
122 277
123 impl std::fmt::Display for #name {
124 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
125 std::fmt::Display::fmt(self.syntax(), f)
126 }
127 }
128
129 impl AstNode for #name { 278 impl AstNode for #name {
130 fn can_cast(kind: SyntaxKind) -> bool { 279 fn can_cast(kind: SyntaxKind) -> bool {
131 match kind { 280 match kind {
@@ -150,18 +299,48 @@ fn generate_ast(grammar: AstSrc<'_>) -> Result<String> {
150 } 299 }
151 } 300 }
152 } 301 }
302
153 #(#traits)* 303 #(#traits)*
154 } 304 }
155 }); 305 });
156 306
307 let displays = grammar
308 .enums
309 .iter()
310 .map(|it| format_ident!("{}", it.name))
311 .chain(grammar.nodes.iter().map(|it| format_ident!("{}", it.name)))
312 .map(|name| {
313 quote! {
314 impl std::fmt::Display for #name {
315 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
316 std::fmt::Display::fmt(self.syntax(), f)
317 }
318 }
319 }
320 });
321
322 let defined_nodes: HashSet<_> = grammar.nodes.iter().map(|node| node.name).collect();
323
324 for node in kinds
325 .nodes
326 .iter()
327 .map(|kind| to_pascal_case(*kind))
328 .filter(|name| !defined_nodes.contains(&**name))
329 {
330 eprintln!("Warning: node {} not defined in ast source", node);
331 }
332
157 let ast = quote! { 333 let ast = quote! {
158 use crate::{ 334 use crate::{
159 SyntaxNode, SyntaxKind::{self, *}, 335 SyntaxNode, SyntaxKind::{self, *},
160 ast::{self, AstNode, AstChildren}, 336 ast::{self, AstNode, AstChildren, support},
161 }; 337 };
162 338
339 use super::tokens::*;
340
163 #(#nodes)* 341 #(#nodes)*
164 #(#enums)* 342 #(#enums)*
343 #(#displays)*
165 }; 344 };
166 345
167 let pretty = crate::reformat(ast)?; 346 let pretty = crate::reformat(ast)?;
@@ -282,12 +461,12 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> Result<String> {
282 461
283fn to_upper_snake_case(s: &str) -> String { 462fn to_upper_snake_case(s: &str) -> String {
284 let mut buf = String::with_capacity(s.len()); 463 let mut buf = String::with_capacity(s.len());
285 let mut prev_is_upper = None; 464 let mut prev = false;
286 for c in s.chars() { 465 for c in s.chars() {
287 if c.is_ascii_uppercase() && prev_is_upper == Some(false) { 466 if c.is_ascii_uppercase() && prev {
288 buf.push('_') 467 buf.push('_')
289 } 468 }
290 prev_is_upper = Some(c.is_ascii_uppercase()); 469 prev = true;
291 470
292 buf.push(c.to_ascii_uppercase()); 471 buf.push(c.to_ascii_uppercase());
293 } 472 }
@@ -296,14 +475,30 @@ fn to_upper_snake_case(s: &str) -> String {
296 475
297fn to_lower_snake_case(s: &str) -> String { 476fn to_lower_snake_case(s: &str) -> String {
298 let mut buf = String::with_capacity(s.len()); 477 let mut buf = String::with_capacity(s.len());
299 let mut prev_is_upper = None; 478 let mut prev = false;
300 for c in s.chars() { 479 for c in s.chars() {
301 if c.is_ascii_uppercase() && prev_is_upper == Some(false) { 480 if c.is_ascii_uppercase() && prev {
302 buf.push('_') 481 buf.push('_')
303 } 482 }
304 prev_is_upper = Some(c.is_ascii_uppercase()); 483 prev = true;
305 484
306 buf.push(c.to_ascii_lowercase()); 485 buf.push(c.to_ascii_lowercase());
307 } 486 }
308 buf 487 buf
309} 488}
489
490fn to_pascal_case(s: &str) -> String {
491 let mut buf = String::with_capacity(s.len());
492 let mut prev_is_underscore = true;
493 for c in s.chars() {
494 if c == '_' {
495 prev_is_underscore = true;
496 } else if prev_is_underscore {
497 buf.push(c.to_ascii_uppercase());
498 prev_is_underscore = false;
499 } else {
500 buf.push(c.to_ascii_lowercase());
501 }
502 }
503 buf
504}
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 9d087daa2..ec824a518 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -67,6 +67,7 @@ fn reformat(text: impl std::fmt::Display) -> Result<String> {
67 let mut rustfmt = Command::new("rustup") 67 let mut rustfmt = Command::new("rustup")
68 .args(&["run", TOOLCHAIN, "--", "rustfmt", "--config-path"]) 68 .args(&["run", TOOLCHAIN, "--", "rustfmt", "--config-path"])
69 .arg(project_root().join("rustfmt.toml")) 69 .arg(project_root().join("rustfmt.toml"))
70 .args(&["--config", "fn_single_line=true"])
70 .stdin(Stdio::piped()) 71 .stdin(Stdio::piped())
71 .stdout(Stdio::piped()) 72 .stdout(Stdio::piped())
72 .spawn()?; 73 .spawn()?;