aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
authorBenjamin Coenen <[email protected]>2020-04-09 17:37:34 +0100
committerBenjamin Coenen <[email protected]>2020-04-09 18:12:50 +0100
commitc1317d692321ba5ba8f138067ebefbb9559d098d (patch)
treee29a44577e4d2cf55b6f53e3428abea43bbd33d7 /xtask
parentfc70cf9458c5234decafdd52b9aced790ac43d7a (diff)
parent30f0ad159a0f260f54356385de63c171722adb72 (diff)
feat: add support for feature attributes in struct literal
Signed-off-by: Benjamin Coenen <[email protected]>
Diffstat (limited to 'xtask')
-rw-r--r--xtask/src/ast_src.rs378
-rw-r--r--xtask/src/codegen.rs5
-rw-r--r--xtask/src/codegen/gen_syntax.rs218
-rw-r--r--xtask/src/lib.rs1
4 files changed, 433 insertions, 169 deletions
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index d9f51ec39..eba66ff4d 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,310 @@ 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, 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, 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,
484 } 548 }
485 struct Condition { Pat, Expr } 549 struct Condition { LetKw, Pat, Eq, Expr }
486 struct Block: AttrsOwner, ModuleItemOwner { 550 struct Block: AttrsOwner, ModuleItemOwner {
551 LCurly,
487 statements: [Stmt], 552 statements: [Stmt],
488 Expr, 553 Expr,
554 RCurly,
489 } 555 }
490 struct ParamList { 556 struct ParamList {
557 LParen,
491 SelfParam, 558 SelfParam,
492 params: [Param], 559 params: [Param],
560 RParen
493 } 561 }
494 struct SelfParam: TypeAscriptionOwner, AttrsOwner { } 562 struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, SelfKw }
495 struct Param: TypeAscriptionOwner, AttrsOwner { 563 struct Param: TypeAscriptionOwner, AttrsOwner {
496 Pat, 564 Pat,
565 Dotdotdot
497 } 566 }
498 struct UseItem: AttrsOwner, VisibilityOwner { 567 struct UseItem: AttrsOwner, VisibilityOwner {
568 UseKw,
499 UseTree, 569 UseTree,
500 } 570 }
501 struct UseTree { 571 struct UseTree {
502 Path, UseTreeList, Alias 572 Path, Star, UseTreeList, Alias
503 } 573 }
504 struct Alias: NameOwner { } 574 struct Alias: NameOwner { AsKw }
505 struct UseTreeList { use_trees: [UseTree] } 575 struct UseTreeList { LCurly, use_trees: [UseTree], RCurly }
506 struct ExternCrateItem: AttrsOwner, VisibilityOwner { 576 struct ExternCrateItem: AttrsOwner, VisibilityOwner {
507 NameRef, Alias, 577 ExternKw, CrateKw, NameRef, Alias,
508 } 578 }
509 struct ArgList { 579 struct ArgList {
580 LParen,
510 args: [Expr], 581 args: [Expr],
582 RParen
511 } 583 }
512 struct Path { 584 struct Path {
513 segment: PathSegment, 585 segment: PathSegment,
514 qualifier: Path, 586 qualifier: Path,
515 } 587 }
516 struct PathSegment { 588 struct PathSegment {
517 NameRef, TypeArgList, ParamList, RetType, PathType, 589 Coloncolon, LAngle, NameRef, TypeArgList, ParamList, RetType, PathType, RAngle
518 } 590 }
519 struct TypeArgList { 591 struct TypeArgList {
592 Coloncolon,
593 LAngle,
594 generic_args: [GenericArg],
520 type_args: [TypeArg], 595 type_args: [TypeArg],
521 lifetime_args: [LifetimeArg], 596 lifetime_args: [LifetimeArg],
522 assoc_type_args: [AssocTypeArg], 597 assoc_type_args: [AssocTypeArg],
523 const_arg: [ConstArg], 598 const_args: [ConstArg],
599 RAngle
524 } 600 }
525 struct TypeArg { TypeRef } 601 struct TypeArg { TypeRef }
526 struct AssocTypeArg { NameRef, TypeRef } 602 struct AssocTypeArg : TypeBoundsOwner { NameRef, Eq, TypeRef }
527 struct LifetimeArg {} 603 struct LifetimeArg { Lifetime }
528 struct ConstArg { Literal, BlockExpr } 604 struct ConstArg { Literal, Eq, BlockExpr }
529 605
530 struct MacroItems: ModuleItemOwner, FnDefOwner { } 606 struct MacroItems: ModuleItemOwner, FnDefOwner { }
531 607
@@ -533,12 +609,44 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
533 statements: [Stmt], 609 statements: [Stmt],
534 Expr, 610 Expr,
535 } 611 }
612
613 struct ExternItemList: FnDefOwner, ModuleItemOwner {
614 LCurly,
615 extern_items: [ExternItem],
616 RCurly
617 }
618
619 struct ExternBlock {
620 Abi,
621 ExternItemList
622 }
623
624 struct MetaItem {
625 Path, Eq, AttrInput, nested_meta_items: [MetaItem]
626 }
627
628 struct MacroDef {
629 Name, TokenTree
630 }
536 }, 631 },
537 enums: &ast_enums! { 632 enums: &ast_enums! {
538 enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner { 633 enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner {
539 StructDef, EnumDef, UnionDef, 634 StructDef, EnumDef, UnionDef,
540 } 635 }
541 636
637 enum GenericParam {
638 LifetimeParam,
639 TypeParam,
640 ConstParam
641 }
642
643 enum GenericArg {
644 LifetimeArg,
645 TypeArg,
646 ConstArg,
647 AssocTypeArg
648 }
649
542 enum TypeRef { 650 enum TypeRef {
543 ParenType, 651 ParenType,
544 TupleType, 652 TupleType,
@@ -555,7 +663,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
555 DynTraitType, 663 DynTraitType,
556 } 664 }
557 665
558 enum ModuleItem: AttrsOwner, VisibilityOwner { 666 enum ModuleItem: NameOwner, AttrsOwner, VisibilityOwner {
559 StructDef, 667 StructDef,
560 UnionDef, 668 UnionDef,
561 EnumDef, 669 EnumDef,
@@ -569,13 +677,20 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
569 StaticDef, 677 StaticDef,
570 Module, 678 Module,
571 MacroCall, 679 MacroCall,
680 ExternBlock
572 } 681 }
573 682
574 enum ImplItem: AttrsOwner { 683 /* impl blocks can also contain MacroCall */
575 FnDef, TypeAliasDef, ConstDef, 684 enum ImplItem: NameOwner, AttrsOwner {
685 FnDef, TypeAliasDef, ConstDef
576 } 686 }
577 687
578 enum Expr { 688 /* extern blocks can also contain MacroCall */
689 enum ExternItem: NameOwner, AttrsOwner, VisibilityOwner {
690 FnDef, StaticDef
691 }
692
693 enum Expr: AttrsOwner {
579 TupleExpr, 694 TupleExpr,
580 ArrayExpr, 695 ArrayExpr,
581 ParenExpr, 696 ParenExpr,
@@ -627,7 +742,88 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
627 MacroPat, 742 MacroPat,
628 } 743 }
629 744
745 enum RecordInnerPat {
746 RecordFieldPat,
747 BindPat
748 }
749
630 enum AttrInput { Literal, TokenTree } 750 enum AttrInput { Literal, TokenTree }
631 enum Stmt { ExprStmt, LetStmt } 751 enum Stmt {
752 LetStmt,
753 ExprStmt,
754 // macro calls are parsed as expression statements */
755 }
756
757 enum FieldDefList {
758 RecordFieldDefList,
759 TupleFieldDefList,
760 }
761 },
762
763 token_enums: &ast_enums! {
764 enum LeftDelimiter { LParen, LBrack, LCurly }
765 enum RightDelimiter { RParen, RBrack, RCurly }
766 enum RangeSeparator { Dotdot, Dotdotdot, Dotdoteq}
767
768 enum BinOp {
769 Pipepipe,
770 Ampamp,
771 Eqeq,
772 Neq,
773 Lteq,
774 Gteq,
775 LAngle,
776 RAngle,
777 Plus,
778 Star,
779 Minus,
780 Slash,
781 Percent,
782 Shl,
783 Shr,
784 Caret,
785 Pipe,
786 Amp,
787 Eq,
788 Pluseq,
789 Slasheq,
790 Stareq,
791 Percenteq,
792 Shreq,
793 Shleq,
794 Minuseq,
795 Pipeeq,
796 Ampeq,
797 Careteq,
798 }
799
800 enum PrefixOp {
801 Minus,
802 Excl,
803 Star
804 }
805
806 enum RangeOp {
807 Dotdot,
808 Dotdoteq
809 }
810
811 enum LiteralToken {
812 IntNumber,
813 FloatNumber,
814 String,
815 RawString,
816 TrueKw,
817 FalseKw,
818 ByteString,
819 RawByteString,
820 Char,
821 Byte
822 }
823
824 enum NameRefToken {
825 Ident,
826 IntNumber
827 }
632 }, 828 },
633}; 829};
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 2dfb68371..6657c9fc5 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -3,10 +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::{
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};
8use std::borrow::Cow;
9use std::collections::{BTreeSet, HashMap, HashSet};
10 13
11use crate::{ 14use crate::{
12 ast_src::{AstSrc, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC}, 15 ast_src::{AstSrc, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC},
@@ -19,9 +22,13 @@ pub fn generate_syntax(mode: Mode) -> Result<()> {
19 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?; 22 let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
20 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?; 23 update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
21 24
22 let ast_file = project_root().join(codegen::AST); 25 let ast_nodes_file = project_root().join(codegen::AST_NODES);
23 let ast = generate_ast(KINDS_SRC, AST_SRC)?; 26 let contents = generate_nodes(KINDS_SRC, AST_SRC)?;
24 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)?;
25 32
26 Ok(()) 33 Ok(())
27} 34}
@@ -33,7 +40,7 @@ struct ElementKinds {
33 has_tokens: bool, 40 has_tokens: bool,
34} 41}
35 42
36fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> { 43fn generate_tokens(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
37 let all_token_kinds: Vec<_> = kinds 44 let all_token_kinds: Vec<_> = kinds
38 .punct 45 .punct
39 .into_iter() 46 .into_iter()
@@ -51,46 +58,6 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
51 .chain(kinds.tokens.into_iter().copied().map(|x| x.into())) 58 .chain(kinds.tokens.into_iter().copied().map(|x| x.into()))
52 .collect(); 59 .collect();
53 60
54 let mut element_kinds_map = HashMap::new();
55 for kind in &all_token_kinds {
56 let kind = &**kind;
57 let name = to_pascal_case(kind);
58 element_kinds_map.insert(
59 name,
60 ElementKinds {
61 kinds: Some(format_ident!("{}", kind)).into_iter().collect(),
62 has_nodes: false,
63 has_tokens: true,
64 },
65 );
66 }
67
68 for kind in kinds.nodes {
69 let name = to_pascal_case(kind);
70 element_kinds_map.insert(
71 name,
72 ElementKinds {
73 kinds: Some(format_ident!("{}", *kind)).into_iter().collect(),
74 has_nodes: true,
75 has_tokens: false,
76 },
77 );
78 }
79
80 for en in grammar.enums {
81 let mut element_kinds: ElementKinds = Default::default();
82 for variant in en.variants {
83 if let Some(variant_element_kinds) = element_kinds_map.get(*variant) {
84 element_kinds.kinds.extend(variant_element_kinds.kinds.iter().cloned());
85 element_kinds.has_tokens |= variant_element_kinds.has_tokens;
86 element_kinds.has_nodes |= variant_element_kinds.has_nodes;
87 } else {
88 panic!("Enum variant has type that does not exist or was not declared before the enum: {}", *variant);
89 }
90 }
91 element_kinds_map.insert(en.name.to_string(), element_kinds);
92 }
93
94 let tokens = all_token_kinds.iter().map(|kind_str| { 61 let tokens = all_token_kinds.iter().map(|kind_str| {
95 let kind_str = &**kind_str; 62 let kind_str = &**kind_str;
96 let kind = format_ident!("{}", kind_str); 63 let kind = format_ident!("{}", kind_str);
@@ -108,12 +75,7 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
108 } 75 }
109 76
110 impl AstToken for #name { 77 impl AstToken for #name {
111 fn can_cast(kind: SyntaxKind) -> bool { 78 fn can_cast(kind: SyntaxKind) -> bool { kind == #kind }
112 match kind {
113 #kind => true,
114 _ => false,
115 }
116 }
117 fn cast(syntax: SyntaxToken) -> Option<Self> { 79 fn cast(syntax: SyntaxToken) -> Option<Self> {
118 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } 80 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
119 } 81 }
@@ -122,6 +84,99 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
122 } 84 }
123 }); 85 });
124 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
125 let nodes = grammar.nodes.iter().map(|node| { 180 let nodes = grammar.nodes.iter().map(|node| {
126 let name = format_ident!("{}", node.name); 181 let name = format_ident!("{}", node.name);
127 let kind = format_ident!("{}", to_upper_snake_case(&name.to_string())); 182 let kind = format_ident!("{}", to_upper_snake_case(&name.to_string()));
@@ -146,14 +201,23 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
146 FieldSrc::Many(_) => { 201 FieldSrc::Many(_) => {
147 quote! { 202 quote! {
148 pub fn #method_name(&self) -> AstChildren<#ty> { 203 pub fn #method_name(&self) -> AstChildren<#ty> {
149 AstChildren::new(&self.syntax) 204 support::children(&self.syntax)
150 } 205 }
151 } 206 }
152 } 207 }
153 FieldSrc::Optional(_) | FieldSrc::Shorthand => { 208 FieldSrc::Optional(_) | FieldSrc::Shorthand => {
154 quote! { 209 let is_token = token_kinds.contains(&ty.to_string());
155 pub fn #method_name(&self) -> Option<#ty> { 210 if is_token {
156 AstChildren::new(&self.syntax).next() 211 quote! {
212 pub fn #method_name(&self) -> Option<#ty> {
213 support::token(&self.syntax)
214 }
215 }
216 } else {
217 quote! {
218 pub fn #method_name(&self) -> Option<#ty> {
219 support::child(&self.syntax)
220 }
157 } 221 }
158 } 222 }
159 } 223 }
@@ -166,18 +230,9 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
166 pub(crate) syntax: SyntaxNode, 230 pub(crate) syntax: SyntaxNode,
167 } 231 }
168 232
169 impl std::fmt::Display for #name {
170 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
171 std::fmt::Display::fmt(self.syntax(), f)
172 }
173 }
174
175 impl AstNode for #name { 233 impl AstNode for #name {
176 fn can_cast(kind: SyntaxKind) -> bool { 234 fn can_cast(kind: SyntaxKind) -> bool {
177 match kind { 235 kind == #kind
178 #kind => true,
179 _ => false,
180 }
181 } 236 }
182 fn cast(syntax: SyntaxNode) -> Option<Self> { 237 fn cast(syntax: SyntaxNode) -> Option<Self> {
183 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } 238 if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
@@ -219,12 +274,6 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
219 } 274 }
220 )* 275 )*
221 276
222 impl std::fmt::Display for #name {
223 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
224 std::fmt::Display::fmt(self.syntax(), f)
225 }
226 }
227
228 impl AstNode for #name { 277 impl AstNode for #name {
229 fn can_cast(kind: SyntaxKind) -> bool { 278 fn can_cast(kind: SyntaxKind) -> bool {
230 match kind { 279 match kind {
@@ -249,10 +298,26 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
249 } 298 }
250 } 299 }
251 } 300 }
301
252 #(#traits)* 302 #(#traits)*
253 } 303 }
254 }); 304 });
255 305
306 let displays = grammar
307 .enums
308 .iter()
309 .map(|it| format_ident!("{}", it.name))
310 .chain(grammar.nodes.iter().map(|it| format_ident!("{}", it.name)))
311 .map(|name| {
312 quote! {
313 impl std::fmt::Display for #name {
314 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
315 std::fmt::Display::fmt(self.syntax(), f)
316 }
317 }
318 }
319 });
320
256 let defined_nodes: HashSet<_> = grammar.nodes.iter().map(|node| node.name).collect(); 321 let defined_nodes: HashSet<_> = grammar.nodes.iter().map(|node| node.name).collect();
257 322
258 for node in kinds 323 for node in kinds
@@ -265,15 +330,16 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
265 } 330 }
266 331
267 let ast = quote! { 332 let ast = quote! {
268 #[allow(unused_imports)]
269 use crate::{ 333 use crate::{
270 SyntaxNode, SyntaxToken, SyntaxElement, NodeOrToken, SyntaxKind::{self, *}, 334 SyntaxNode, SyntaxKind::{self, *},
271 ast::{self, AstNode, AstToken, AstChildren}, 335 ast::{self, AstNode, AstChildren, support},
272 }; 336 };
273 337
274 #(#tokens)* 338 use super::tokens::*;
339
275 #(#nodes)* 340 #(#nodes)*
276 #(#enums)* 341 #(#enums)*
342 #(#displays)*
277 }; 343 };
278 344
279 let pretty = crate::reformat(ast)?; 345 let pretty = crate::reformat(ast)?;
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()?;