================================================================================
Macro invocation - no arguments
================================================================================

a!();
b![];
c!{};
d::e!();
f::g::h!{};

--------------------------------------------------------------------------------

(source_file
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree)))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree)))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree)))
  (expression_statement
    (macro_invocation
      (scoped_identifier
        (identifier)
        (identifier))
      (token_tree)))
  (expression_statement
    (macro_invocation
      (scoped_identifier
        (scoped_identifier
          (identifier)
          (identifier))
        (identifier))
      (token_tree))))

================================================================================
Macro invocation - arbitrary tokens
================================================================================

a!(* a *);
a!(& a &);
a!(- a -);
a!(b + c + +);
a!('a'..='z');
a!('\u{0}'..='\u{2}');
a!('lifetime)
default!(a);
union!(a);
a!($);
a!($());
a!($ a $);
a!(${$([ a ])});
a!($a $a:ident $($a);*);

--------------------------------------------------------------------------------

(source_file
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (identifier))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (identifier))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (identifier))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (identifier)
        (identifier))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (char_literal)
        (char_literal))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (char_literal)
        (char_literal))))
  (macro_invocation_item
    (macro_invocation
      (identifier)
      (token_tree
        (identifier))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (identifier))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (identifier))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree)))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (token_tree))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (identifier))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (token_tree
          (token_tree
            (token_tree
              (identifier)))))))
  (expression_statement
    (macro_invocation
      (identifier)
      (token_tree
        (identifier)
        (identifier)
        (identifier)
        (token_tree
          (identifier))))))

================================================================================
Macro invocation with comments
================================================================================

ok! {
  // one
  /* two */
}

--------------------------------------------------------------------------------

(source_file
  (macro_invocation_item
    (macro_invocation
      (identifier)
      (token_tree
        (line_comment)
        (block_comment)))))

================================================================================
Macro definition
================================================================================

macro_rules! say_hello {
    () => (
        println!("Hello!");
    )
}

macro_rules! four {
    () => {1 + 3};
}

macro_rules! foo {
    (x => $e:expr) => (println!("mode X: {}", $e));
    (y => $e:expr) => (println!("mode Y: {}", $e))
}

macro_rules! o_O {
    (
      $($x:expr; [ $( $y:expr ),* ]);*
    ) => {
      $($($x + $e),*),*
    }
}

macro_rules! zero_or_one {
    ($($e:expr),?) => {
        $($e),?
    };
}

macro_rules ! empty [
    () => {};
];

macro_rules! with_dollar_sign {
    ($a:tt => $b:tt) => {
        macro_rules! __with_dollar_sign { $a => $b }
        __with_dollar_sign!($);
    }
}

macro_rules ! macro_with_whitespace {
    ($ x : expr, $ y : expr) => { $ x + $ y }
}

--------------------------------------------------------------------------------

(source_file
  (macro_definition
    name: (identifier)
    (macro_rule
      left: (token_tree_pattern)
      right: (token_tree
        (identifier)
        (token_tree
          (string_literal
            (string_content))))))
  (macro_definition
    name: (identifier)
    (macro_rule
      left: (token_tree_pattern)
      right: (token_tree
        (integer_literal)
        (integer_literal))))
  (macro_definition
    name: (identifier)
    (macro_rule
      left: (token_tree_pattern
        (identifier)
        (token_binding_pattern
          name: (metavariable)
          type: (fragment_specifier)))
      right: (token_tree
        (identifier)
        (token_tree
          (string_literal
            (string_content))
          (metavariable))))
    (macro_rule
      left: (token_tree_pattern
        (identifier)
        (token_binding_pattern
          name: (metavariable)
          type: (fragment_specifier)))
      right: (token_tree
        (identifier)
        (token_tree
          (string_literal
            (string_content))
          (metavariable)))))
  (macro_definition
    name: (identifier)
    (macro_rule
      left: (token_tree_pattern
        (token_repetition_pattern
          (token_binding_pattern
            name: (metavariable)
            type: (fragment_specifier))
          (token_tree_pattern
            (token_repetition_pattern
              (token_binding_pattern
                name: (metavariable)
                type: (fragment_specifier))))))
      right: (token_tree
        (token_repetition
          (token_repetition
            (metavariable)
            (metavariable))))))
  (macro_definition
    name: (identifier)
    (macro_rule
      left: (token_tree_pattern
        (token_repetition_pattern
          (token_binding_pattern
            name: (metavariable)
            type: (fragment_specifier))))
      right: (token_tree
        (token_repetition
          (metavariable)))))
  (macro_definition
    name: (identifier)
    (macro_rule
      left: (token_tree_pattern)
      right: (token_tree)))
  (macro_definition
    name: (identifier)
    (macro_rule
      left: (token_tree_pattern
        (token_binding_pattern
          name: (metavariable)
          type: (fragment_specifier))
        (token_binding_pattern
          name: (metavariable)
          type: (fragment_specifier)))
      right: (token_tree
        (identifier)
        (identifier)
        (token_tree
          (metavariable)
          (metavariable))
        (identifier)
        (token_tree))))
  (macro_definition
    name: (identifier)
    (macro_rule
      left: (token_tree_pattern
        (token_binding_pattern
          name: (metavariable)
          type: (fragment_specifier))
        (token_binding_pattern
          name: (metavariable)
          type: (fragment_specifier)))
      right: (token_tree
        (metavariable)
        (metavariable)))))

================================================================================
Macro definition with unicode characters
================================================================================

macro_rules! macro_that_defines_a_function {
    (fn $名:ident () $体:tt) => {
        fn $名 () $体 fn 他 () {}
    }
}

--------------------------------------------------------------------------------

(source_file
  (macro_definition
    (identifier)
    (macro_rule
      (token_tree_pattern
        (token_binding_pattern
          (metavariable)
          (fragment_specifier))
        (token_tree_pattern)
        (token_binding_pattern
          (metavariable)
          (fragment_specifier)))
      (token_tree
        (metavariable)
        (token_tree)
        (metavariable)
        (identifier)
        (token_tree)
        (token_tree)))))

================================================================================
Macro definition v2
================================================================================

pub macro m($key_ty:ident, $val_ty:ident) {
    struct $key_ty {
        inner: usize,
    }

    impl T for $val_ty {
        type Key = $key_ty;

        fn index_from_key(key: Self::Key) -> usize {
            key.inner
        }
    }
}

fn main() {
    async {
        macro mm() {}
    };
}

pub macro my_macro_2($($tok:tt)*) {

}

pub macro my_macro_multi {
    (_) => {

    },
    ($foo:ident . $bar:expr) => {

    },
    ($($foo:literal),+) => {

    }
}

#[rustc_builtin_macro]
pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
    /* compiler built-in */
}

--------------------------------------------------------------------------------

(source_file
  (macro_definition_v2
    (visibility_modifier)
    (identifier)
    (macro_arguments_declaration
      (token_binding_pattern
        (metavariable)
        (fragment_specifier))
      (token_binding_pattern
        (metavariable)
        (fragment_specifier)))
    (macro_body_v2
      (metavariable)
      (token_tree
        (identifier)
        (primitive_type))
      (identifier)
      (metavariable)
      (token_tree
        (identifier)
        (metavariable)
        (identifier)
        (token_tree
          (identifier)
          (identifier)
          (identifier))
        (primitive_type)
        (token_tree
          (identifier)
          (identifier)))))
  (function_item
    (identifier)
    (parameters)
    (block
      (expression_statement
        (async_block
          (block
            (macro_definition_v2
              (identifier)
              (macro_arguments_declaration)
              (macro_body_v2)))))
      (empty_statement)))
  (macro_definition_v2
    (visibility_modifier)
    (identifier)
    (macro_arguments_declaration
      (token_repetition_pattern
        (token_binding_pattern
          (metavariable)
          (fragment_specifier))))
    (macro_body_v2))
  (macro_definition_v2
    (visibility_modifier)
    (identifier)
    (macro_rules_v2
      (macro_rule_v2
        (token_tree_pattern)
        (token_tree))
      (macro_rule_v2
        (token_tree_pattern
          (token_binding_pattern
            (metavariable)
            (fragment_specifier))
          (token_binding_pattern
            (metavariable)
            (fragment_specifier)))
        (token_tree))
      (macro_rule_v2
        (token_tree_pattern
          (token_repetition_pattern
            (token_binding_pattern
              (metavariable)
              (fragment_specifier))))
        (token_tree))))
  (macro_definition_v2
    (attributes
      (attribute_item
        (attribute
          (identifier))))
    (visibility_modifier)
    (identifier)
    (macro_arguments_declaration
      (string_literal
        (string_content))
      (token_repetition_pattern
        (identifier))
      (token_repetition_pattern
        (identifier)
        (token_tree_pattern
          (token_repetition_pattern
            (identifier)))))
    (macro_body_v2
      (block_comment))))
