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