Skip to content

Commit 0509e44

Browse files
authored
Merge pull request #93 from ninevra/dispatch-on-well-known-attrs
Generalize attribute syntax
2 parents 9cede24 + 467fd2c commit 0509e44

File tree

6 files changed

+64559
-61233
lines changed

6 files changed

+64559
-61233
lines changed

corpus/declarations.txt

+133-8
Original file line numberDiff line numberDiff line change
@@ -176,13 +176,13 @@ fn accumulate(self) -> Machine<{State::Accumulate}> {}
176176
name: (identifier)
177177
parameters: (parameters
178178
(attribute_item
179-
(meta_item
179+
(attr_item
180180
(identifier)))
181181
(parameter
182182
pattern: (identifier)
183183
type: (primitive_type))
184184
(attribute_item
185-
(meta_item
185+
(attr_item
186186
(identifier)))
187187
(parameter
188188
pattern: (identifier)
@@ -473,7 +473,7 @@ struct Inches(i32);
473473
(field_identifier)
474474
(primitive_type))
475475
(attribute_item
476-
(meta_item
476+
(attr_item
477477
(identifier)))
478478
(field_declaration
479479
(field_identifier)
@@ -632,10 +632,10 @@ pub enum Node<T: Item> {
632632
(field_identifier)
633633
(primitive_type))))
634634
(attribute_item
635-
(meta_item
635+
(attr_item
636636
(identifier)))
637637
(attribute_item
638-
(meta_item
638+
(attr_item
639639
(identifier)))
640640
(enum_variant
641641
(identifier)
@@ -968,7 +968,7 @@ mod macos_only {}
968968
path: (identifier)
969969
name: (identifier))))))
970970
(attribute_item
971-
(meta_item
971+
(attr_item
972972
(scoped_identifier
973973
path: (identifier)
974974
name: (identifier))
@@ -996,6 +996,131 @@ mod macos_only {
996996
(identifier)
997997
value: (string_literal))))))))
998998

999+
================================================================================
1000+
Key-Value Attribute Expressions
1001+
================================================================================
1002+
1003+
#[doc = include_str!("foo-doc.md")]
1004+
fn foo() {}
1005+
1006+
#[namespace = foo::bar]
1007+
fn baz() {}
1008+
1009+
--------------------------------------------------------------------------------
1010+
1011+
(source_file
1012+
(attribute_item
1013+
(meta_item
1014+
(identifier)
1015+
(macro_invocation
1016+
(identifier)
1017+
(token_tree
1018+
(string_literal)))))
1019+
(function_item
1020+
(identifier)
1021+
(parameters)
1022+
(block))
1023+
(attribute_item
1024+
(attr_item
1025+
(identifier)
1026+
(scoped_identifier
1027+
(identifier)
1028+
(identifier))))
1029+
(function_item
1030+
(identifier)
1031+
(parameters)
1032+
(block)))
1033+
1034+
================================================================================
1035+
Attribute macros
1036+
================================================================================
1037+
1038+
foo(#[attr(=> arbitrary tokens <=)] x, y);
1039+
1040+
foo(#[bar(some tokens are special in other contexts: $/';()*()+.)] x);
1041+
1042+
--------------------------------------------------------------------------------
1043+
1044+
(source_file
1045+
(expression_statement
1046+
(call_expression
1047+
function: (identifier)
1048+
arguments: (arguments
1049+
(attribute_item (attr_item
1050+
(identifier)
1051+
arguments: (token_tree (identifier) (identifier))))
1052+
(identifier)
1053+
(identifier))))
1054+
(expression_statement
1055+
(call_expression
1056+
function: (identifier)
1057+
arguments: (arguments
1058+
(attribute_item (attr_item
1059+
(identifier)
1060+
arguments: (token_tree
1061+
(identifier)
1062+
(identifier)
1063+
(identifier)
1064+
(identifier)
1065+
(identifier)
1066+
(identifier)
1067+
(identifier)
1068+
(token_tree)
1069+
(token_tree))))
1070+
(identifier)))))
1071+
1072+
================================================================================
1073+
Derive macro helper attributes
1074+
================================================================================
1075+
1076+
// Example from https://github.com/dtolnay/thiserror/blob/21c26903e29cb92ba1a7ff11e82ae2001646b60d/README.md
1077+
1078+
use thiserror::Error;
1079+
1080+
#[derive(Error, Debug)]
1081+
pub enum Error {
1082+
#[error("first letter must be lowercase but was {:?}", first_char(.0))]
1083+
WrongCase(String),
1084+
#[error("invalid index {idx}, expected at least {} and at most {}", .limits.lo, .limits.hi)]
1085+
OutOfBounds { idx: usize, limits: Limits },
1086+
}
1087+
1088+
--------------------------------------------------------------------------------
1089+
1090+
(source_file
1091+
(line_comment)
1092+
(use_declaration
1093+
(scoped_identifier (identifier) (identifier)))
1094+
(attribute_item
1095+
(meta_item (identifier)
1096+
(meta_arguments
1097+
(meta_item (identifier))
1098+
(meta_item (identifier)))))
1099+
(enum_item
1100+
(visibility_modifier)
1101+
(type_identifier)
1102+
(enum_variant_list
1103+
(attribute_item (attr_item
1104+
(identifier)
1105+
(token_tree
1106+
(string_literal)
1107+
(identifier)
1108+
(token_tree (integer_literal)))))
1109+
(enum_variant (identifier)
1110+
(ordered_field_declaration_list (type_identifier)))
1111+
(attribute_item (attr_item
1112+
(identifier)
1113+
(token_tree
1114+
(string_literal)
1115+
(identifier)
1116+
(identifier)
1117+
(identifier)
1118+
(identifier))))
1119+
(enum_variant (identifier)
1120+
(field_declaration_list
1121+
(field_declaration (field_identifier) (primitive_type))
1122+
(field_declaration (field_identifier) (type_identifier)))))))
1123+
9991124
================================================================================
10001125
Attributes and Expressions
10011126
================================================================================
@@ -1032,7 +1157,7 @@ fn foo() {
10321157
pattern: (identifier)
10331158
value: (array_expression
10341159
(attribute_item
1035-
(meta_item
1160+
(attr_item
10361161
(identifier)))
10371162
(integer_literal)
10381163
(integer_literal)
@@ -1041,7 +1166,7 @@ fn foo() {
10411166
pattern: (identifier)
10421167
value: (tuple_expression
10431168
(attribute_item
1044-
(meta_item
1169+
(attr_item
10451170
(identifier)))
10461171
(integer_literal)
10471172
(integer_literal)

corpus/expressions.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ let msg = match x {
607607
value: (integer_literal))
608608
(match_arm
609609
(attribute_item
610-
(meta_item
610+
(attr_item
611611
(identifier)))
612612
pattern: (match_pattern
613613
(integer_literal))

grammar.js

+76-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,54 @@ const numeric_types = [
3535

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

38+
const built_in_attributes = [
39+
'cfg',
40+
'cfg_attr',
41+
'test',
42+
'ignore',
43+
'should_panic',
44+
'derive',
45+
'automatically_derived',
46+
'macro_export',
47+
'macro_use',
48+
'proc_macro',
49+
'proc_macro_derive',
50+
'proc_macro_attribute',
51+
'allow',
52+
'warn',
53+
'deny',
54+
'forbid',
55+
'deprecated',
56+
'must_use',
57+
'link',
58+
'link_name',
59+
'no_link',
60+
'repr',
61+
'crate_type',
62+
'no_main',
63+
'export_name',
64+
'link_section',
65+
'no_mangle',
66+
'used',
67+
'crate_name',
68+
'inline',
69+
'cold',
70+
'no_builtins',
71+
'target_feature',
72+
'track_caller',
73+
'doc',
74+
'no_std',
75+
'no_implicit_prelude',
76+
'path',
77+
'recursion_limit',
78+
'type_length_limit',
79+
'panic_handler',
80+
'global_allocator',
81+
'windows_subsystem',
82+
'feature',
83+
'non_exhaustive'
84+
]
85+
3886
module.exports = grammar({
3987
name: 'rust',
4088

@@ -210,22 +258,47 @@ module.exports = grammar({
210258
attribute_item: $ => seq(
211259
'#',
212260
'[',
213-
$.meta_item,
261+
$._attr,
214262
']'
215263
),
216264

217265
inner_attribute_item: $ => seq(
218266
'#',
219267
'!',
220268
'[',
221-
$.meta_item,
269+
$._attr,
222270
']'
223271
),
224272

273+
_attr: $ => choice(
274+
alias($.built_in_attr, $.meta_item),
275+
alias($.custom_attr, $.attr_item),
276+
),
277+
278+
custom_attr: $ => seq(
279+
$._path,
280+
optional(choice(
281+
seq('=', field('value', $._expression)),
282+
field('arguments', alias($.delim_token_tree, $.token_tree))
283+
))
284+
),
285+
286+
built_in_attr: $ => seq(
287+
$._built_in_attr_path,
288+
optional(choice(
289+
seq('=', field('value', $._expression)),
290+
field('arguments', $.meta_arguments)
291+
))
292+
),
293+
294+
_built_in_attr_path: $ => choice(
295+
...built_in_attributes.map(name => alias(name, $.identifier))
296+
),
297+
225298
meta_item: $ => seq(
226299
$._path,
227300
optional(choice(
228-
seq('=', field('value', $._literal)),
301+
seq('=', field('value', $._expression)),
229302
field('arguments', $.meta_arguments)
230303
))
231304
),

0 commit comments

Comments
 (0)