diff --git a/grammar.ron b/grammar.ron index 0717b7a7694..c2fcc44f5be 100644 --- a/grammar.ron +++ b/grammar.ron @@ -91,6 +91,8 @@ Grammar( "USE_ITEM", "STATIC_ITEM", "CONST_ITEM", + "TRAIT_ITEM", + "IMPL_ITEM", "EXTERN_BLOCK", "ENUM_VARIANT", diff --git a/src/parser/event_parser/grammar/items/mod.rs b/src/parser/event_parser/grammar/items/mod.rs index 6d6fabbd794..3612802e17b 100644 --- a/src/parser/event_parser/grammar/items/mod.rs +++ b/src/parser/event_parser/grammar/items/mod.rs @@ -3,6 +3,7 @@ mod structs; mod use_item; mod consts; +mod traits; pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { attributes::inner_attributes(p); @@ -80,6 +81,22 @@ fn item(p: &mut Parser) { CONST_ITEM } }, + // TODO: auto trait + // test unsafe_trait + // unsafe trait T {} + UNSAFE_KW if la == TRAIT_KW => { + p.bump(); + traits::trait_item(p); + TRAIT_ITEM + } + // TODO: default impl + // test unsafe_impl + // unsafe impl Foo {} + UNSAFE_KW if la == IMPL_KW => { + p.bump(); + traits::impl_item(p); + IMPL_ITEM + } MOD_KW => { mod_item(p); MOD_ITEM @@ -131,6 +148,7 @@ fn extern_block(p: &mut Parser) { p.bump(); p.expect(R_CURLY); } + fn mod_item(p: &mut Parser) { assert!(p.at(MOD_KW)); p.bump(); diff --git a/src/parser/event_parser/grammar/items/traits.rs b/src/parser/event_parser/grammar/items/traits.rs new file mode 100644 index 00000000000..3bef9639f02 --- /dev/null +++ b/src/parser/event_parser/grammar/items/traits.rs @@ -0,0 +1,17 @@ +use super::*; + +pub(super) fn trait_item(p: &mut Parser) { + assert!(p.at(TRAIT_KW)); + p.bump(); + p.expect(IDENT); + p.expect(L_CURLY); + p.expect(R_CURLY); +} + +pub(super) fn impl_item(p: &mut Parser) { + assert!(p.at(IMPL_KW)); + p.bump(); + p.expect(IDENT); + p.expect(L_CURLY); + p.expect(R_CURLY); +} diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index c182aea78fd..22c61583155 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -92,6 +92,8 @@ pub enum SyntaxKind { USE_ITEM, STATIC_ITEM, CONST_ITEM, + TRAIT_ITEM, + IMPL_ITEM, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -207,6 +209,8 @@ pub(crate) fn info(self) -> &'static SyntaxInfo { USE_ITEM => &SyntaxInfo { name: "USE_ITEM" }, STATIC_ITEM => &SyntaxInfo { name: "STATIC_ITEM" }, CONST_ITEM => &SyntaxInfo { name: "CONST_ITEM" }, + TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" }, + IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, diff --git a/tests/data/parser/inline/0007_unsafe_trait.rs b/tests/data/parser/inline/0007_unsafe_trait.rs new file mode 100644 index 00000000000..04e021550d8 --- /dev/null +++ b/tests/data/parser/inline/0007_unsafe_trait.rs @@ -0,0 +1 @@ +unsafe trait T {} diff --git a/tests/data/parser/inline/0007_unsafe_trait.txt b/tests/data/parser/inline/0007_unsafe_trait.txt new file mode 100644 index 00000000000..d6f6a4cfa7b --- /dev/null +++ b/tests/data/parser/inline/0007_unsafe_trait.txt @@ -0,0 +1,11 @@ +FILE@[0; 18) + TRAIT_ITEM@[0; 18) + UNSAFE_KW@[0; 6) + WHITESPACE@[6; 7) + TRAIT_KW@[7; 12) + WHITESPACE@[12; 13) + IDENT@[13; 14) "T" + WHITESPACE@[14; 15) + L_CURLY@[15; 16) + R_CURLY@[16; 17) + WHITESPACE@[17; 18) diff --git a/tests/data/parser/inline/0008_unsafe_impl.rs b/tests/data/parser/inline/0008_unsafe_impl.rs new file mode 100644 index 00000000000..41055f41d96 --- /dev/null +++ b/tests/data/parser/inline/0008_unsafe_impl.rs @@ -0,0 +1 @@ +unsafe impl Foo {} diff --git a/tests/data/parser/inline/0008_unsafe_impl.txt b/tests/data/parser/inline/0008_unsafe_impl.txt new file mode 100644 index 00000000000..a88a447cb30 --- /dev/null +++ b/tests/data/parser/inline/0008_unsafe_impl.txt @@ -0,0 +1,11 @@ +FILE@[0; 19) + IMPL_ITEM@[0; 19) + UNSAFE_KW@[0; 6) + WHITESPACE@[6; 7) + IMPL_KW@[7; 11) + WHITESPACE@[11; 12) + IDENT@[12; 15) "Foo" + WHITESPACE@[15; 16) + L_CURLY@[16; 17) + R_CURLY@[17; 18) + WHITESPACE@[18; 19) diff --git a/tools/src/bin/collect-tests.rs b/tools/src/bin/collect-tests.rs index df9d2db8158..9a84d92fc8b 100644 --- a/tools/src/bin/collect-tests.rs +++ b/tools/src/bin/collect-tests.rs @@ -79,16 +79,19 @@ fn collect_tests(s: &str) -> Vec { .map(str::trim_left) .group_by(|line| line.starts_with(prefix)); - for (is_comment, block) in comment_blocks.into_iter() { + 'outer: for (is_comment, block) in comment_blocks.into_iter() { if !is_comment { continue; } let mut block = block.map(|line| &line[prefix.len()..]); - let first = block.next().unwrap(); - if !first.starts_with("test ") { - continue; - } - let name = first["test ".len()..].to_string(); + + let name = loop { + match block.next() { + Some(line) if line.starts_with("test ") => break line["test ".len()..].to_string(), + Some(_) => (), + None => continue 'outer, + } + }; let text: String = itertools::join(block.chain(::std::iter::once("")), "\n"); assert!(!text.trim().is_empty() && text.ends_with("\n")); res.push(Test { name, text })