Skip to content

Commit

Permalink
Merge pull request #93 from ninevra/dispatch-on-well-known-attrs
Browse files Browse the repository at this point in the history
Generalize attribute syntax
  • Loading branch information
aryx authored Mar 9, 2022
2 parents 9cede24 + 467fd2c commit 0509e44
Show file tree
Hide file tree
Showing 6 changed files with 64,559 additions and 61,233 deletions.
141 changes: 133 additions & 8 deletions corpus/declarations.txt
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ fn accumulate(self) -> Machine<{State::Accumulate}> {}
name: (identifier)
parameters: (parameters
(attribute_item
(meta_item
(attr_item
(identifier)))
(parameter
pattern: (identifier)
type: (primitive_type))
(attribute_item
(meta_item
(attr_item
(identifier)))
(parameter
pattern: (identifier)
Expand Down Expand Up @@ -473,7 +473,7 @@ struct Inches(i32);
(field_identifier)
(primitive_type))
(attribute_item
(meta_item
(attr_item
(identifier)))
(field_declaration
(field_identifier)
Expand Down Expand Up @@ -632,10 +632,10 @@ pub enum Node<T: Item> {
(field_identifier)
(primitive_type))))
(attribute_item
(meta_item
(attr_item
(identifier)))
(attribute_item
(meta_item
(attr_item
(identifier)))
(enum_variant
(identifier)
Expand Down Expand Up @@ -968,7 +968,7 @@ mod macos_only {}
path: (identifier)
name: (identifier))))))
(attribute_item
(meta_item
(attr_item
(scoped_identifier
path: (identifier)
name: (identifier))
Expand Down Expand Up @@ -996,6 +996,131 @@ mod macos_only {
(identifier)
value: (string_literal))))))))

================================================================================
Key-Value Attribute Expressions
================================================================================

#[doc = include_str!("foo-doc.md")]
fn foo() {}

#[namespace = foo::bar]
fn baz() {}

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

(source_file
(attribute_item
(meta_item
(identifier)
(macro_invocation
(identifier)
(token_tree
(string_literal)))))
(function_item
(identifier)
(parameters)
(block))
(attribute_item
(attr_item
(identifier)
(scoped_identifier
(identifier)
(identifier))))
(function_item
(identifier)
(parameters)
(block)))

================================================================================
Attribute macros
================================================================================

foo(#[attr(=> arbitrary tokens <=)] x, y);

foo(#[bar(some tokens are special in other contexts: $/';()*()+.)] x);

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

(source_file
(expression_statement
(call_expression
function: (identifier)
arguments: (arguments
(attribute_item (attr_item
(identifier)
arguments: (token_tree (identifier) (identifier))))
(identifier)
(identifier))))
(expression_statement
(call_expression
function: (identifier)
arguments: (arguments
(attribute_item (attr_item
(identifier)
arguments: (token_tree
(identifier)
(identifier)
(identifier)
(identifier)
(identifier)
(identifier)
(identifier)
(token_tree)
(token_tree))))
(identifier)))))

================================================================================
Derive macro helper attributes
================================================================================

// Example from https://github.com/dtolnay/thiserror/blob/21c26903e29cb92ba1a7ff11e82ae2001646b60d/README.md

use thiserror::Error;

#[derive(Error, Debug)]
pub enum Error {
#[error("first letter must be lowercase but was {:?}", first_char(.0))]
WrongCase(String),
#[error("invalid index {idx}, expected at least {} and at most {}", .limits.lo, .limits.hi)]
OutOfBounds { idx: usize, limits: Limits },
}

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

(source_file
(line_comment)
(use_declaration
(scoped_identifier (identifier) (identifier)))
(attribute_item
(meta_item (identifier)
(meta_arguments
(meta_item (identifier))
(meta_item (identifier)))))
(enum_item
(visibility_modifier)
(type_identifier)
(enum_variant_list
(attribute_item (attr_item
(identifier)
(token_tree
(string_literal)
(identifier)
(token_tree (integer_literal)))))
(enum_variant (identifier)
(ordered_field_declaration_list (type_identifier)))
(attribute_item (attr_item
(identifier)
(token_tree
(string_literal)
(identifier)
(identifier)
(identifier)
(identifier))))
(enum_variant (identifier)
(field_declaration_list
(field_declaration (field_identifier) (primitive_type))
(field_declaration (field_identifier) (type_identifier)))))))

================================================================================
Attributes and Expressions
================================================================================
Expand Down Expand Up @@ -1032,7 +1157,7 @@ fn foo() {
pattern: (identifier)
value: (array_expression
(attribute_item
(meta_item
(attr_item
(identifier)))
(integer_literal)
(integer_literal)
Expand All @@ -1041,7 +1166,7 @@ fn foo() {
pattern: (identifier)
value: (tuple_expression
(attribute_item
(meta_item
(attr_item
(identifier)))
(integer_literal)
(integer_literal)
Expand Down
2 changes: 1 addition & 1 deletion corpus/expressions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ let msg = match x {
value: (integer_literal))
(match_arm
(attribute_item
(meta_item
(attr_item
(identifier)))
pattern: (match_pattern
(integer_literal))
Expand Down
79 changes: 76 additions & 3 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,54 @@ const numeric_types = [

const primitive_types = numeric_types.concat(['bool', 'str', 'char'])

const built_in_attributes = [
'cfg',
'cfg_attr',
'test',
'ignore',
'should_panic',
'derive',
'automatically_derived',
'macro_export',
'macro_use',
'proc_macro',
'proc_macro_derive',
'proc_macro_attribute',
'allow',
'warn',
'deny',
'forbid',
'deprecated',
'must_use',
'link',
'link_name',
'no_link',
'repr',
'crate_type',
'no_main',
'export_name',
'link_section',
'no_mangle',
'used',
'crate_name',
'inline',
'cold',
'no_builtins',
'target_feature',
'track_caller',
'doc',
'no_std',
'no_implicit_prelude',
'path',
'recursion_limit',
'type_length_limit',
'panic_handler',
'global_allocator',
'windows_subsystem',
'feature',
'non_exhaustive'
]

module.exports = grammar({
name: 'rust',

Expand Down Expand Up @@ -210,22 +258,47 @@ module.exports = grammar({
attribute_item: $ => seq(
'#',
'[',
$.meta_item,
$._attr,
']'
),

inner_attribute_item: $ => seq(
'#',
'!',
'[',
$.meta_item,
$._attr,
']'
),

_attr: $ => choice(
alias($.built_in_attr, $.meta_item),
alias($.custom_attr, $.attr_item),
),

custom_attr: $ => seq(
$._path,
optional(choice(
seq('=', field('value', $._expression)),
field('arguments', alias($.delim_token_tree, $.token_tree))
))
),

built_in_attr: $ => seq(
$._built_in_attr_path,
optional(choice(
seq('=', field('value', $._expression)),
field('arguments', $.meta_arguments)
))
),

_built_in_attr_path: $ => choice(
...built_in_attributes.map(name => alias(name, $.identifier))
),

meta_item: $ => seq(
$._path,
optional(choice(
seq('=', field('value', $._literal)),
seq('=', field('value', $._expression)),
field('arguments', $.meta_arguments)
))
),
Expand Down
Loading

0 comments on commit 0509e44

Please sign in to comment.