mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
tt-attrs
This commit is contained in:
parent
1193c5f829
commit
7094291573
18 changed files with 260 additions and 276 deletions
|
@ -26,9 +26,8 @@ use std::{
|
|||
use libsyntax2::{
|
||||
TextUnit,
|
||||
ast::{self, AstNode},
|
||||
algo::{find_leaf_at_offset, ancestors},
|
||||
};
|
||||
use libeditor::{LineIndex, FileSymbol};
|
||||
use libeditor::{LineIndex, FileSymbol, find_node};
|
||||
|
||||
use self::symbol_index::FileSymbols;
|
||||
pub use self::symbol_index::Query;
|
||||
|
@ -123,13 +122,7 @@ impl World {
|
|||
let file = self.file_syntax(id)?;
|
||||
let syntax = file.syntax();
|
||||
let syntax = syntax.as_ref();
|
||||
let name_ref =
|
||||
find_leaf_at_offset(syntax, offset)
|
||||
.left_biased()
|
||||
.into_iter()
|
||||
.flat_map(|node| ancestors(node))
|
||||
.flat_map(ast::NameRef::cast)
|
||||
.next();
|
||||
let name_ref = find_node::<ast::NameRef<_>>(syntax, offset);
|
||||
let name = match name_ref {
|
||||
None => return Ok(vec![]),
|
||||
Some(name_ref) => name_ref.text(),
|
||||
|
|
|
@ -66,7 +66,7 @@ fn find_non_trivia_leaf(syntax: SyntaxNodeRef, offset: TextUnit) -> Option<Synta
|
|||
.find(|leaf| !leaf.kind().is_trivia())
|
||||
}
|
||||
|
||||
fn find_node<'a, N: AstNode<&'a SyntaxRoot>>(syntax: SyntaxNodeRef<'a>, offset: TextUnit) -> Option<N> {
|
||||
pub fn find_node<'a, N: AstNode<&'a SyntaxRoot>>(syntax: SyntaxNodeRef<'a>, offset: TextUnit) -> Option<N> {
|
||||
let leaf = find_non_trivia_leaf(syntax, offset)?;
|
||||
ancestors(leaf)
|
||||
.filter_map(N::cast)
|
||||
|
|
|
@ -21,7 +21,10 @@ pub use self::{
|
|||
extend_selection::extend_selection,
|
||||
symbols::{StructureNode, file_structure, FileSymbol, file_symbols},
|
||||
edit::{EditBuilder, Edit, AtomEdit},
|
||||
code_actions::{flip_comma, add_derive, ActionResult, CursorPosition},
|
||||
code_actions::{
|
||||
ActionResult, CursorPosition, find_node,
|
||||
flip_comma, add_derive,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -59,9 +62,7 @@ pub fn matching_brace(file: &ast::File, offset: TextUnit) -> Option<TextUnit> {
|
|||
L_PAREN, R_PAREN,
|
||||
L_ANGLE, R_ANGLE,
|
||||
];
|
||||
let syntax = file.syntax();
|
||||
let syntax = syntax.as_ref();
|
||||
let (brace_node, brace_idx) = find_leaf_at_offset(syntax, offset)
|
||||
let (brace_node, brace_idx) = find_leaf_at_offset(file.syntax_ref(), offset)
|
||||
.filter_map(|node| {
|
||||
let idx = BRACES.iter().position(|&brace| brace == node.kind())?;
|
||||
Some((node, idx))
|
||||
|
@ -75,9 +76,8 @@ pub fn matching_brace(file: &ast::File, offset: TextUnit) -> Option<TextUnit> {
|
|||
}
|
||||
|
||||
pub fn highlight(file: &ast::File) -> Vec<HighlightedRange> {
|
||||
let syntax = file.syntax();
|
||||
let mut res = Vec::new();
|
||||
for node in walk::preorder(syntax.as_ref()) {
|
||||
for node in walk::preorder(file.syntax_ref()) {
|
||||
let tag = match node.kind() {
|
||||
ERROR => "error",
|
||||
COMMENT | DOC_COMMENT => "comment",
|
||||
|
@ -99,10 +99,9 @@ pub fn highlight(file: &ast::File) -> Vec<HighlightedRange> {
|
|||
}
|
||||
|
||||
pub fn diagnostics(file: &ast::File) -> Vec<Diagnostic> {
|
||||
let syntax = file.syntax();
|
||||
let mut res = Vec::new();
|
||||
|
||||
for node in walk::preorder(syntax.as_ref()) {
|
||||
for node in walk::preorder(file.syntax_ref()) {
|
||||
if node.kind() == ERROR {
|
||||
res.push(Diagnostic {
|
||||
range: node.range(),
|
||||
|
|
|
@ -26,8 +26,7 @@ pub struct FileSymbol {
|
|||
}
|
||||
|
||||
pub fn file_symbols(file: &ast::File) -> Vec<FileSymbol> {
|
||||
let syntax = file.syntax();
|
||||
preorder(syntax.as_ref())
|
||||
preorder(file.syntax_ref())
|
||||
.filter_map(to_symbol)
|
||||
.collect()
|
||||
}
|
||||
|
@ -57,9 +56,8 @@ fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> {
|
|||
pub fn file_structure(file: &ast::File) -> Vec<StructureNode> {
|
||||
let mut res = Vec::new();
|
||||
let mut stack = Vec::new();
|
||||
let syntax = file.syntax();
|
||||
|
||||
for event in walk(syntax.as_ref()) {
|
||||
for event in walk(file.syntax_ref()) {
|
||||
match event {
|
||||
WalkEvent::Enter(node) => {
|
||||
match structure_node(node) {
|
||||
|
|
|
@ -23,6 +23,31 @@ impl<R: TreeRoot> AstNode<R> for ArrayType<R> {
|
|||
|
||||
impl<R: TreeRoot> ArrayType<R> {}
|
||||
|
||||
// Attr
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Attr<R: TreeRoot = Arc<SyntaxRoot>> {
|
||||
syntax: SyntaxNode<R>,
|
||||
}
|
||||
|
||||
impl<R: TreeRoot> AstNode<R> for Attr<R> {
|
||||
fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
|
||||
match syntax.kind() {
|
||||
ATTR => Some(Attr { syntax }),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
|
||||
}
|
||||
|
||||
impl<R: TreeRoot> Attr<R> {
|
||||
pub fn value(&self) -> Option<TokenTree<R>> {
|
||||
self.syntax()
|
||||
.children()
|
||||
.filter_map(TokenTree::cast)
|
||||
.next()
|
||||
}
|
||||
}
|
||||
|
||||
// ConstDef
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ConstDef<R: TreeRoot = Arc<SyntaxRoot>> {
|
||||
|
@ -40,6 +65,7 @@ impl<R: TreeRoot> AstNode<R> for ConstDef<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for ConstDef<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for ConstDef<R> {}
|
||||
impl<R: TreeRoot> ConstDef<R> {}
|
||||
|
||||
// DynTraitType
|
||||
|
@ -77,6 +103,7 @@ impl<R: TreeRoot> AstNode<R> for EnumDef<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for EnumDef<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for EnumDef<R> {}
|
||||
impl<R: TreeRoot> EnumDef<R> {}
|
||||
|
||||
// File
|
||||
|
@ -120,6 +147,7 @@ impl<R: TreeRoot> AstNode<R> for FnDef<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for FnDef<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for FnDef<R> {}
|
||||
impl<R: TreeRoot> FnDef<R> {}
|
||||
|
||||
// FnPointerType
|
||||
|
@ -211,6 +239,7 @@ impl<R: TreeRoot> AstNode<R> for Module<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for Module<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for Module<R> {}
|
||||
impl<R: TreeRoot> Module<R> {}
|
||||
|
||||
// Name
|
||||
|
@ -266,6 +295,7 @@ impl<R: TreeRoot> AstNode<R> for NamedField<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for NamedField<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for NamedField<R> {}
|
||||
impl<R: TreeRoot> NamedField<R> {}
|
||||
|
||||
// NeverType
|
||||
|
@ -436,6 +466,7 @@ impl<R: TreeRoot> AstNode<R> for StaticDef<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for StaticDef<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for StaticDef<R> {}
|
||||
impl<R: TreeRoot> StaticDef<R> {}
|
||||
|
||||
// StructDef
|
||||
|
@ -455,6 +486,7 @@ impl<R: TreeRoot> AstNode<R> for StructDef<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for StructDef<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for StructDef<R> {}
|
||||
impl<R: TreeRoot> StructDef<R> {
|
||||
pub fn fields<'a>(&'a self) -> impl Iterator<Item = NamedField<R>> + 'a {
|
||||
self.syntax()
|
||||
|
@ -463,6 +495,24 @@ impl<R: TreeRoot> StructDef<R> {
|
|||
}
|
||||
}
|
||||
|
||||
// TokenTree
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct TokenTree<R: TreeRoot = Arc<SyntaxRoot>> {
|
||||
syntax: SyntaxNode<R>,
|
||||
}
|
||||
|
||||
impl<R: TreeRoot> AstNode<R> for TokenTree<R> {
|
||||
fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
|
||||
match syntax.kind() {
|
||||
TOKEN_TREE => Some(TokenTree { syntax }),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
|
||||
}
|
||||
|
||||
impl<R: TreeRoot> TokenTree<R> {}
|
||||
|
||||
// TraitDef
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct TraitDef<R: TreeRoot = Arc<SyntaxRoot>> {
|
||||
|
@ -480,6 +530,7 @@ impl<R: TreeRoot> AstNode<R> for TraitDef<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for TraitDef<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for TraitDef<R> {}
|
||||
impl<R: TreeRoot> TraitDef<R> {}
|
||||
|
||||
// TupleType
|
||||
|
@ -517,6 +568,7 @@ impl<R: TreeRoot> AstNode<R> for TypeDef<R> {
|
|||
}
|
||||
|
||||
impl<R: TreeRoot> ast::NameOwner<R> for TypeDef<R> {}
|
||||
impl<R: TreeRoot> ast::AttrsOwner<R> for TypeDef<R> {}
|
||||
impl<R: TreeRoot> TypeDef<R> {}
|
||||
|
||||
// TypeRef
|
||||
|
|
|
@ -2,10 +2,11 @@ mod generated;
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use itertools::Itertools;
|
||||
use smol_str::SmolStr;
|
||||
|
||||
use {
|
||||
SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError,
|
||||
SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot, SyntaxError,
|
||||
SyntaxKind::*,
|
||||
};
|
||||
pub use self::generated::*;
|
||||
|
@ -14,6 +15,9 @@ pub trait AstNode<R: TreeRoot> {
|
|||
fn cast(syntax: SyntaxNode<R>) -> Option<Self>
|
||||
where Self: Sized;
|
||||
fn syntax(&self) -> &SyntaxNode<R>;
|
||||
fn syntax_ref<'a>(&'a self) -> SyntaxNodeRef<'a> where R: 'a {
|
||||
self.syntax().as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NameOwner<R: TreeRoot>: AstNode<R> {
|
||||
|
@ -25,6 +29,14 @@ pub trait NameOwner<R: TreeRoot>: AstNode<R> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait AttrsOwner<R: TreeRoot>: AstNode<R> {
|
||||
fn attrs<'a>(&'a self) -> Box<Iterator<Item=Attr<R>> + 'a> where R: 'a {
|
||||
let it = self.syntax().children()
|
||||
.filter_map(Attr::cast);
|
||||
Box::new(it)
|
||||
}
|
||||
}
|
||||
|
||||
impl File<Arc<SyntaxRoot>> {
|
||||
pub fn parse(text: &str) -> Self {
|
||||
File::cast(::parse(text)).unwrap()
|
||||
|
@ -39,31 +51,20 @@ impl<R: TreeRoot> File<R> {
|
|||
|
||||
impl<R: TreeRoot> FnDef<R> {
|
||||
pub fn has_atom_attr(&self, atom: &str) -> bool {
|
||||
self.syntax()
|
||||
.children()
|
||||
.filter(|node| node.kind() == ATTR)
|
||||
.any(|attr| {
|
||||
let mut metas = attr.children().filter(|node| node.kind() == META_ITEM);
|
||||
let meta = match metas.next() {
|
||||
None => return false,
|
||||
Some(meta) => {
|
||||
if metas.next().is_some() {
|
||||
return false;
|
||||
}
|
||||
meta
|
||||
}
|
||||
};
|
||||
let mut children = meta.children();
|
||||
match children.next() {
|
||||
None => false,
|
||||
Some(child) => {
|
||||
if children.next().is_some() {
|
||||
return false;
|
||||
}
|
||||
child.kind() == IDENT && child.text() == atom
|
||||
}
|
||||
}
|
||||
})
|
||||
self.attrs()
|
||||
.filter_map(|x| x.value())
|
||||
.filter_map(|x| as_atom(x))
|
||||
.any(|x| x == atom)
|
||||
}
|
||||
}
|
||||
|
||||
fn as_atom<R: TreeRoot>(tt: TokenTree<R>) -> Option<SmolStr> {
|
||||
let syntax = tt.syntax_ref();
|
||||
let (_bra, attr, _ket) = syntax.children().collect_tuple()?;
|
||||
if attr.kind() == IDENT {
|
||||
Some(attr.leaf_text().unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -221,24 +221,26 @@ Grammar(
|
|||
["functions", "FnDef"]
|
||||
]
|
||||
),
|
||||
"FnDef": ( traits: ["NameOwner"] ),
|
||||
"FnDef": ( traits: ["NameOwner", "AttrsOwner"] ),
|
||||
"StructDef": (
|
||||
traits: ["NameOwner"],
|
||||
traits: ["NameOwner", "AttrsOwner"],
|
||||
collections: [
|
||||
["fields", "NamedField"]
|
||||
]
|
||||
),
|
||||
"NamedField": ( traits: ["NameOwner"] ),
|
||||
"EnumDef": ( traits: ["NameOwner"] ),
|
||||
"TraitDef": ( traits: ["NameOwner"] ),
|
||||
"Module": ( traits: ["NameOwner"] ),
|
||||
"ConstDef": ( traits: ["NameOwner"] ),
|
||||
"StaticDef": ( traits: ["NameOwner"] ),
|
||||
"TypeDef": ( traits: ["NameOwner"] ),
|
||||
"NamedField": ( traits: ["NameOwner", "AttrsOwner"] ),
|
||||
"EnumDef": ( traits: ["NameOwner", "AttrsOwner"] ),
|
||||
"TraitDef": ( traits: ["NameOwner", "AttrsOwner"] ),
|
||||
"Module": ( traits: ["NameOwner", "AttrsOwner"] ),
|
||||
"ConstDef": ( traits: ["NameOwner", "AttrsOwner"] ),
|
||||
"StaticDef": ( traits: ["NameOwner", "AttrsOwner"] ),
|
||||
"TypeDef": ( traits: ["NameOwner", "AttrsOwner"] ),
|
||||
"ImplItem": (),
|
||||
|
||||
"Name": (),
|
||||
"NameRef": (),
|
||||
"Attr": ( options: [ ["value", "TokenTree"] ] ),
|
||||
"TokenTree": (),
|
||||
|
||||
"ParenType": (),
|
||||
"TupleType": (),
|
||||
|
|
|
@ -22,58 +22,10 @@ fn attribute(p: &mut Parser, inner: bool) {
|
|||
p.bump();
|
||||
}
|
||||
|
||||
if p.expect(L_BRACK) {
|
||||
meta_item(p);
|
||||
p.expect(R_BRACK);
|
||||
if p.at(L_BRACK) {
|
||||
items::token_tree(p);
|
||||
} else {
|
||||
p.error("expected `[`");
|
||||
}
|
||||
attr.complete(p, ATTR);
|
||||
}
|
||||
|
||||
fn meta_item(p: &mut Parser) {
|
||||
if p.at(IDENT) {
|
||||
let meta_item = p.start();
|
||||
p.bump();
|
||||
match p.current() {
|
||||
EQ => {
|
||||
p.bump();
|
||||
if expressions::literal(p).is_none() {
|
||||
p.error("expected literal");
|
||||
}
|
||||
}
|
||||
L_PAREN => meta_item_arg_list(p),
|
||||
_ => (),
|
||||
}
|
||||
meta_item.complete(p, META_ITEM);
|
||||
} else {
|
||||
p.error("expected attribute value");
|
||||
}
|
||||
}
|
||||
|
||||
fn meta_item_arg_list(p: &mut Parser) {
|
||||
assert!(p.at(L_PAREN));
|
||||
p.bump();
|
||||
loop {
|
||||
match p.current() {
|
||||
EOF | R_PAREN => break,
|
||||
IDENT => meta_item(p),
|
||||
c => if expressions::literal(p).is_none() {
|
||||
let message = "expected attribute";
|
||||
|
||||
if items::ITEM_FIRST.contains(c) {
|
||||
p.error(message);
|
||||
return;
|
||||
}
|
||||
|
||||
let err = p.start();
|
||||
p.error(message);
|
||||
p.bump();
|
||||
err.complete(p, ERROR);
|
||||
continue;
|
||||
},
|
||||
}
|
||||
if !p.at(R_PAREN) {
|
||||
p.expect(COMMA);
|
||||
}
|
||||
}
|
||||
p.expect(R_PAREN);
|
||||
}
|
||||
|
|
|
@ -55,9 +55,6 @@ pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemF
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) const ITEM_FIRST: TokenSet =
|
||||
token_set![EXTERN_KW, MOD_KW, USE_KW, STRUCT_KW, ENUM_KW, FN_KW, PUB_KW, POUND];
|
||||
|
||||
pub(super) enum MaybeItem {
|
||||
None,
|
||||
Item(SyntaxKind),
|
||||
|
@ -322,13 +319,14 @@ pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike {
|
|||
flavor
|
||||
}
|
||||
|
||||
fn token_tree(p: &mut Parser) {
|
||||
pub(super) fn token_tree(p: &mut Parser) {
|
||||
let closing_paren_kind = match p.current() {
|
||||
L_CURLY => R_CURLY,
|
||||
L_PAREN => R_PAREN,
|
||||
L_BRACK => R_BRACK,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let m = p.start();
|
||||
p.bump();
|
||||
while !p.at(EOF) && !p.at(closing_paren_kind) {
|
||||
match p.current() {
|
||||
|
@ -338,4 +336,5 @@ fn token_tree(p: &mut Parser) {
|
|||
}
|
||||
};
|
||||
p.expect(closing_paren_kind);
|
||||
m.complete(p, TOKEN_TREE);
|
||||
}
|
||||
|
|
|
@ -2,25 +2,20 @@ FILE@[0; 54)
|
|||
FN_DEF@[0; 31)
|
||||
ATTR@[0; 18)
|
||||
POUND@[0; 1)
|
||||
L_BRACK@[1; 2)
|
||||
META_ITEM@[2; 17)
|
||||
TOKEN_TREE@[1; 18)
|
||||
L_BRACK@[1; 2)
|
||||
IDENT@[2; 5) "foo"
|
||||
L_PAREN@[5; 6)
|
||||
META_ITEM@[6; 9)
|
||||
TOKEN_TREE@[5; 17)
|
||||
L_PAREN@[5; 6)
|
||||
IDENT@[6; 9) "foo"
|
||||
COMMA@[9; 10)
|
||||
WHITESPACE@[10; 11)
|
||||
err: `expected attribute`
|
||||
ERROR@[11; 12)
|
||||
COMMA@[9; 10)
|
||||
WHITESPACE@[10; 11)
|
||||
PLUS@[11; 12)
|
||||
err: `expected attribute`
|
||||
ERROR@[12; 13)
|
||||
COMMA@[12; 13)
|
||||
WHITESPACE@[13; 14)
|
||||
LITERAL@[14; 16)
|
||||
WHITESPACE@[13; 14)
|
||||
INT_NUMBER@[14; 16) "92"
|
||||
R_PAREN@[16; 17)
|
||||
R_BRACK@[17; 18)
|
||||
R_PAREN@[16; 17)
|
||||
R_BRACK@[17; 18)
|
||||
WHITESPACE@[18; 19)
|
||||
FN_KW@[19; 21)
|
||||
WHITESPACE@[21; 22)
|
||||
|
@ -35,26 +30,26 @@ FILE@[0; 54)
|
|||
WHITESPACE@[29; 30)
|
||||
R_CURLY@[30; 31)
|
||||
WHITESPACE@[31; 34)
|
||||
FN_DEF@[34; 53)
|
||||
ATTR@[34; 40)
|
||||
POUND@[34; 35)
|
||||
ATTR@[34; 53)
|
||||
POUND@[34; 35)
|
||||
TOKEN_TREE@[35; 53)
|
||||
L_BRACK@[35; 36)
|
||||
META_ITEM@[36; 40)
|
||||
IDENT@[36; 39) "foo"
|
||||
IDENT@[36; 39) "foo"
|
||||
TOKEN_TREE@[39; 53)
|
||||
L_PAREN@[39; 40)
|
||||
err: `expected attribute`
|
||||
err: `expected R_BRACK`
|
||||
WHITESPACE@[40; 41)
|
||||
FN_KW@[41; 43)
|
||||
WHITESPACE@[43; 44)
|
||||
NAME@[44; 47)
|
||||
IDENT@[44; 47) "foo"
|
||||
PARAM_LIST@[47; 49)
|
||||
L_PAREN@[47; 48)
|
||||
R_PAREN@[48; 49)
|
||||
WHITESPACE@[49; 50)
|
||||
BLOCK_EXPR@[50; 53)
|
||||
L_CURLY@[50; 51)
|
||||
WHITESPACE@[51; 52)
|
||||
R_CURLY@[52; 53)
|
||||
WHITESPACE@[40; 41)
|
||||
FN_KW@[41; 43)
|
||||
WHITESPACE@[43; 44)
|
||||
IDENT@[44; 47) "foo"
|
||||
TOKEN_TREE@[47; 49)
|
||||
L_PAREN@[47; 48)
|
||||
R_PAREN@[48; 49)
|
||||
WHITESPACE@[49; 50)
|
||||
TOKEN_TREE@[50; 53)
|
||||
L_CURLY@[50; 51)
|
||||
WHITESPACE@[51; 52)
|
||||
R_CURLY@[52; 53)
|
||||
err: `expected R_PAREN`
|
||||
err: `expected R_BRACK`
|
||||
err: `expected an item`
|
||||
WHITESPACE@[53; 54)
|
||||
|
|
|
@ -19,9 +19,10 @@ FILE@[0; 95)
|
|||
NAME_REF@[14; 17)
|
||||
IDENT@[14; 17) "bar"
|
||||
err: `expected EXCL`
|
||||
L_PAREN@[17; 18)
|
||||
R_PAREN@[18; 19)
|
||||
err: `expected SEMI`
|
||||
TOKEN_TREE@[17; 19)
|
||||
L_PAREN@[17; 18)
|
||||
R_PAREN@[18; 19)
|
||||
err: `expected SEMI`
|
||||
WHITESPACE@[19; 20)
|
||||
err: `expected an item`
|
||||
ERROR@[20; 80)
|
||||
|
|
|
@ -86,8 +86,9 @@ FILE@[0; 91)
|
|||
NAME_REF@[78; 84)
|
||||
IDENT@[78; 84) "format"
|
||||
EXCL@[84; 85)
|
||||
L_PAREN@[85; 86)
|
||||
R_PAREN@[86; 87)
|
||||
TOKEN_TREE@[85; 87)
|
||||
L_PAREN@[85; 86)
|
||||
R_PAREN@[86; 87)
|
||||
SEMI@[87; 88)
|
||||
WHITESPACE@[88; 89)
|
||||
R_CURLY@[89; 90)
|
||||
|
|
|
@ -21,8 +21,9 @@ FILE@[0; 70)
|
|||
WHITESPACE@[24; 25)
|
||||
IDENT@[25; 28) "foo"
|
||||
WHITESPACE@[28; 29)
|
||||
L_CURLY@[29; 30)
|
||||
R_CURLY@[30; 31)
|
||||
TOKEN_TREE@[29; 31)
|
||||
L_CURLY@[29; 30)
|
||||
R_CURLY@[30; 31)
|
||||
WHITESPACE@[31; 32)
|
||||
MACRO_CALL@[32; 44)
|
||||
PATH@[32; 40)
|
||||
|
@ -35,8 +36,9 @@ FILE@[0; 70)
|
|||
NAME_REF@[37; 40)
|
||||
IDENT@[37; 40) "bar"
|
||||
EXCL@[40; 41)
|
||||
L_PAREN@[41; 42)
|
||||
R_PAREN@[42; 43)
|
||||
TOKEN_TREE@[41; 43)
|
||||
L_PAREN@[41; 42)
|
||||
R_PAREN@[42; 43)
|
||||
SEMI@[43; 44)
|
||||
WHITESPACE@[44; 45)
|
||||
MACRO_CALL@[45; 59)
|
||||
|
@ -50,8 +52,9 @@ FILE@[0; 70)
|
|||
IDENT@[52; 55) "baz"
|
||||
EXCL@[55; 56)
|
||||
WHITESPACE@[56; 57)
|
||||
L_CURLY@[57; 58)
|
||||
R_CURLY@[58; 59)
|
||||
TOKEN_TREE@[57; 59)
|
||||
L_CURLY@[57; 58)
|
||||
R_CURLY@[58; 59)
|
||||
WHITESPACE@[59; 60)
|
||||
STRUCT_DEF@[60; 69)
|
||||
STRUCT_KW@[60; 66)
|
||||
|
|
|
@ -2,175 +2,163 @@ FILE@[0; 236)
|
|||
ATTR@[0; 8)
|
||||
POUND@[0; 1)
|
||||
EXCL@[1; 2)
|
||||
L_BRACK@[2; 3)
|
||||
META_ITEM@[3; 7)
|
||||
TOKEN_TREE@[2; 8)
|
||||
L_BRACK@[2; 3)
|
||||
IDENT@[3; 7) "attr"
|
||||
R_BRACK@[7; 8)
|
||||
R_BRACK@[7; 8)
|
||||
WHITESPACE@[8; 9)
|
||||
ATTR@[9; 23)
|
||||
POUND@[9; 10)
|
||||
EXCL@[10; 11)
|
||||
L_BRACK@[11; 12)
|
||||
META_ITEM@[12; 22)
|
||||
TOKEN_TREE@[11; 23)
|
||||
L_BRACK@[11; 12)
|
||||
IDENT@[12; 16) "attr"
|
||||
L_PAREN@[16; 17)
|
||||
LITERAL@[17; 21)
|
||||
TOKEN_TREE@[16; 22)
|
||||
L_PAREN@[16; 17)
|
||||
TRUE_KW@[17; 21)
|
||||
R_PAREN@[21; 22)
|
||||
R_BRACK@[22; 23)
|
||||
R_PAREN@[21; 22)
|
||||
R_BRACK@[22; 23)
|
||||
WHITESPACE@[23; 24)
|
||||
ATTR@[24; 39)
|
||||
POUND@[24; 25)
|
||||
EXCL@[25; 26)
|
||||
L_BRACK@[26; 27)
|
||||
META_ITEM@[27; 38)
|
||||
TOKEN_TREE@[26; 39)
|
||||
L_BRACK@[26; 27)
|
||||
IDENT@[27; 31) "attr"
|
||||
L_PAREN@[31; 32)
|
||||
META_ITEM@[32; 37)
|
||||
TOKEN_TREE@[31; 38)
|
||||
L_PAREN@[31; 32)
|
||||
IDENT@[32; 37) "ident"
|
||||
R_PAREN@[37; 38)
|
||||
R_BRACK@[38; 39)
|
||||
R_PAREN@[37; 38)
|
||||
R_BRACK@[38; 39)
|
||||
WHITESPACE@[39; 40)
|
||||
ATTR@[40; 116)
|
||||
POUND@[40; 41)
|
||||
EXCL@[41; 42)
|
||||
L_BRACK@[42; 43)
|
||||
META_ITEM@[43; 115)
|
||||
TOKEN_TREE@[42; 116)
|
||||
L_BRACK@[42; 43)
|
||||
IDENT@[43; 47) "attr"
|
||||
L_PAREN@[47; 48)
|
||||
META_ITEM@[48; 53)
|
||||
TOKEN_TREE@[47; 115)
|
||||
L_PAREN@[47; 48)
|
||||
IDENT@[48; 53) "ident"
|
||||
COMMA@[53; 54)
|
||||
WHITESPACE@[54; 55)
|
||||
LITERAL@[55; 58)
|
||||
COMMA@[53; 54)
|
||||
WHITESPACE@[54; 55)
|
||||
INT_NUMBER@[55; 58) "100"
|
||||
COMMA@[58; 59)
|
||||
WHITESPACE@[59; 60)
|
||||
LITERAL@[60; 64)
|
||||
COMMA@[58; 59)
|
||||
WHITESPACE@[59; 60)
|
||||
TRUE_KW@[60; 64)
|
||||
COMMA@[64; 65)
|
||||
WHITESPACE@[65; 66)
|
||||
LITERAL@[66; 72)
|
||||
COMMA@[64; 65)
|
||||
WHITESPACE@[65; 66)
|
||||
STRING@[66; 72)
|
||||
COMMA@[72; 73)
|
||||
WHITESPACE@[73; 74)
|
||||
META_ITEM@[74; 85)
|
||||
COMMA@[72; 73)
|
||||
WHITESPACE@[73; 74)
|
||||
IDENT@[74; 79) "ident"
|
||||
WHITESPACE@[79; 80)
|
||||
EQ@[80; 81)
|
||||
WHITESPACE@[81; 82)
|
||||
LITERAL@[82; 85)
|
||||
INT_NUMBER@[82; 85) "100"
|
||||
COMMA@[85; 86)
|
||||
WHITESPACE@[86; 87)
|
||||
META_ITEM@[87; 102)
|
||||
INT_NUMBER@[82; 85) "100"
|
||||
COMMA@[85; 86)
|
||||
WHITESPACE@[86; 87)
|
||||
IDENT@[87; 92) "ident"
|
||||
WHITESPACE@[92; 93)
|
||||
EQ@[93; 94)
|
||||
WHITESPACE@[94; 95)
|
||||
LITERAL@[95; 102)
|
||||
STRING@[95; 102)
|
||||
COMMA@[102; 103)
|
||||
WHITESPACE@[103; 104)
|
||||
META_ITEM@[104; 114)
|
||||
STRING@[95; 102)
|
||||
COMMA@[102; 103)
|
||||
WHITESPACE@[103; 104)
|
||||
IDENT@[104; 109) "ident"
|
||||
L_PAREN@[109; 110)
|
||||
LITERAL@[110; 113)
|
||||
TOKEN_TREE@[109; 114)
|
||||
L_PAREN@[109; 110)
|
||||
INT_NUMBER@[110; 113) "100"
|
||||
R_PAREN@[113; 114)
|
||||
R_PAREN@[114; 115)
|
||||
R_BRACK@[115; 116)
|
||||
R_PAREN@[113; 114)
|
||||
R_PAREN@[114; 115)
|
||||
R_BRACK@[115; 116)
|
||||
WHITESPACE@[116; 117)
|
||||
ATTR@[117; 130)
|
||||
POUND@[117; 118)
|
||||
EXCL@[118; 119)
|
||||
L_BRACK@[119; 120)
|
||||
META_ITEM@[120; 129)
|
||||
TOKEN_TREE@[119; 130)
|
||||
L_BRACK@[119; 120)
|
||||
IDENT@[120; 124) "attr"
|
||||
L_PAREN@[124; 125)
|
||||
LITERAL@[125; 128)
|
||||
TOKEN_TREE@[124; 129)
|
||||
L_PAREN@[124; 125)
|
||||
INT_NUMBER@[125; 128) "100"
|
||||
R_PAREN@[128; 129)
|
||||
R_BRACK@[129; 130)
|
||||
R_PAREN@[128; 129)
|
||||
R_BRACK@[129; 130)
|
||||
WHITESPACE@[130; 131)
|
||||
ATTR@[131; 155)
|
||||
POUND@[131; 132)
|
||||
EXCL@[132; 133)
|
||||
L_BRACK@[133; 134)
|
||||
META_ITEM@[134; 154)
|
||||
TOKEN_TREE@[133; 155)
|
||||
L_BRACK@[133; 134)
|
||||
IDENT@[134; 138) "attr"
|
||||
L_PAREN@[138; 139)
|
||||
META_ITEM@[139; 153)
|
||||
TOKEN_TREE@[138; 154)
|
||||
L_PAREN@[138; 139)
|
||||
IDENT@[139; 146) "enabled"
|
||||
WHITESPACE@[146; 147)
|
||||
EQ@[147; 148)
|
||||
WHITESPACE@[148; 149)
|
||||
LITERAL@[149; 153)
|
||||
TRUE_KW@[149; 153)
|
||||
R_PAREN@[153; 154)
|
||||
R_BRACK@[154; 155)
|
||||
TRUE_KW@[149; 153)
|
||||
R_PAREN@[153; 154)
|
||||
R_BRACK@[154; 155)
|
||||
WHITESPACE@[155; 156)
|
||||
ATTR@[156; 173)
|
||||
POUND@[156; 157)
|
||||
EXCL@[157; 158)
|
||||
L_BRACK@[158; 159)
|
||||
META_ITEM@[159; 172)
|
||||
TOKEN_TREE@[158; 173)
|
||||
L_BRACK@[158; 159)
|
||||
IDENT@[159; 166) "enabled"
|
||||
L_PAREN@[166; 167)
|
||||
LITERAL@[167; 171)
|
||||
TOKEN_TREE@[166; 172)
|
||||
L_PAREN@[166; 167)
|
||||
TRUE_KW@[167; 171)
|
||||
R_PAREN@[171; 172)
|
||||
R_BRACK@[172; 173)
|
||||
R_PAREN@[171; 172)
|
||||
R_BRACK@[172; 173)
|
||||
WHITESPACE@[173; 174)
|
||||
ATTR@[174; 191)
|
||||
POUND@[174; 175)
|
||||
EXCL@[175; 176)
|
||||
L_BRACK@[176; 177)
|
||||
META_ITEM@[177; 190)
|
||||
TOKEN_TREE@[176; 191)
|
||||
L_BRACK@[176; 177)
|
||||
IDENT@[177; 181) "attr"
|
||||
L_PAREN@[181; 182)
|
||||
LITERAL@[182; 189)
|
||||
TOKEN_TREE@[181; 190)
|
||||
L_PAREN@[181; 182)
|
||||
STRING@[182; 189)
|
||||
R_PAREN@[189; 190)
|
||||
R_BRACK@[190; 191)
|
||||
R_PAREN@[189; 190)
|
||||
R_BRACK@[190; 191)
|
||||
WHITESPACE@[191; 192)
|
||||
ATTR@[192; 214)
|
||||
POUND@[192; 193)
|
||||
EXCL@[193; 194)
|
||||
L_BRACK@[194; 195)
|
||||
META_ITEM@[195; 213)
|
||||
TOKEN_TREE@[194; 214)
|
||||
L_BRACK@[194; 195)
|
||||
IDENT@[195; 199) "repr"
|
||||
L_PAREN@[199; 200)
|
||||
META_ITEM@[200; 201)
|
||||
TOKEN_TREE@[199; 213)
|
||||
L_PAREN@[199; 200)
|
||||
IDENT@[200; 201) "C"
|
||||
COMMA@[201; 202)
|
||||
WHITESPACE@[202; 203)
|
||||
META_ITEM@[203; 212)
|
||||
COMMA@[201; 202)
|
||||
WHITESPACE@[202; 203)
|
||||
IDENT@[203; 208) "align"
|
||||
WHITESPACE@[208; 209)
|
||||
EQ@[209; 210)
|
||||
WHITESPACE@[210; 211)
|
||||
LITERAL@[211; 212)
|
||||
INT_NUMBER@[211; 212) "4"
|
||||
R_PAREN@[212; 213)
|
||||
R_BRACK@[213; 214)
|
||||
INT_NUMBER@[211; 212) "4"
|
||||
R_PAREN@[212; 213)
|
||||
R_BRACK@[213; 214)
|
||||
WHITESPACE@[214; 215)
|
||||
ATTR@[215; 236)
|
||||
POUND@[215; 216)
|
||||
EXCL@[216; 217)
|
||||
L_BRACK@[217; 218)
|
||||
META_ITEM@[218; 235)
|
||||
TOKEN_TREE@[217; 236)
|
||||
L_BRACK@[217; 218)
|
||||
IDENT@[218; 222) "repr"
|
||||
L_PAREN@[222; 223)
|
||||
META_ITEM@[223; 224)
|
||||
TOKEN_TREE@[222; 235)
|
||||
L_PAREN@[222; 223)
|
||||
IDENT@[223; 224) "C"
|
||||
COMMA@[224; 225)
|
||||
WHITESPACE@[225; 226)
|
||||
META_ITEM@[226; 234)
|
||||
COMMA@[224; 225)
|
||||
WHITESPACE@[225; 226)
|
||||
IDENT@[226; 231) "align"
|
||||
L_PAREN@[231; 232)
|
||||
LITERAL@[232; 233)
|
||||
TOKEN_TREE@[231; 234)
|
||||
L_PAREN@[231; 232)
|
||||
INT_NUMBER@[232; 233) "4"
|
||||
R_PAREN@[233; 234)
|
||||
R_PAREN@[234; 235)
|
||||
R_BRACK@[235; 236)
|
||||
R_PAREN@[233; 234)
|
||||
R_PAREN@[234; 235)
|
||||
R_BRACK@[235; 236)
|
||||
|
|
|
@ -60,10 +60,10 @@ FILE@[0; 118)
|
|||
ATTR@[79; 87)
|
||||
POUND@[79; 80)
|
||||
EXCL@[80; 81)
|
||||
L_BRACK@[81; 82)
|
||||
META_ITEM@[82; 86)
|
||||
TOKEN_TREE@[81; 87)
|
||||
L_BRACK@[81; 82)
|
||||
IDENT@[82; 86) "attr"
|
||||
R_BRACK@[86; 87)
|
||||
R_BRACK@[86; 87)
|
||||
WHITESPACE@[87; 92)
|
||||
MODULE@[92; 98)
|
||||
MOD_KW@[92; 95)
|
||||
|
|
|
@ -2,21 +2,21 @@ FILE@[0; 35)
|
|||
FN_DEF@[0; 34)
|
||||
ATTR@[0; 12)
|
||||
POUND@[0; 1)
|
||||
L_BRACK@[1; 2)
|
||||
META_ITEM@[2; 11)
|
||||
TOKEN_TREE@[1; 12)
|
||||
L_BRACK@[1; 2)
|
||||
IDENT@[2; 5) "cfg"
|
||||
L_PAREN@[5; 6)
|
||||
META_ITEM@[6; 10)
|
||||
TOKEN_TREE@[5; 11)
|
||||
L_PAREN@[5; 6)
|
||||
IDENT@[6; 10) "test"
|
||||
R_PAREN@[10; 11)
|
||||
R_BRACK@[11; 12)
|
||||
R_PAREN@[10; 11)
|
||||
R_BRACK@[11; 12)
|
||||
WHITESPACE@[12; 13)
|
||||
ATTR@[13; 22)
|
||||
POUND@[13; 14)
|
||||
L_BRACK@[14; 15)
|
||||
META_ITEM@[15; 21)
|
||||
TOKEN_TREE@[14; 22)
|
||||
L_BRACK@[14; 15)
|
||||
IDENT@[15; 21) "ignore"
|
||||
R_BRACK@[21; 22)
|
||||
R_BRACK@[21; 22)
|
||||
WHITESPACE@[22; 23)
|
||||
FN_KW@[23; 25)
|
||||
WHITESPACE@[25; 26)
|
||||
|
|
|
@ -2,15 +2,15 @@ FILE@[0; 23)
|
|||
FN_DEF@[0; 22)
|
||||
ATTR@[0; 10)
|
||||
POUND@[0; 1)
|
||||
L_BRACK@[1; 2)
|
||||
META_ITEM@[2; 9)
|
||||
TOKEN_TREE@[1; 10)
|
||||
L_BRACK@[1; 2)
|
||||
IDENT@[2; 5) "foo"
|
||||
L_PAREN@[5; 6)
|
||||
META_ITEM@[6; 7)
|
||||
TOKEN_TREE@[5; 9)
|
||||
L_PAREN@[5; 6)
|
||||
IDENT@[6; 7) "a"
|
||||
COMMA@[7; 8)
|
||||
R_PAREN@[8; 9)
|
||||
R_BRACK@[9; 10)
|
||||
COMMA@[7; 8)
|
||||
R_PAREN@[8; 9)
|
||||
R_BRACK@[9; 10)
|
||||
WHITESPACE@[10; 11)
|
||||
FN_KW@[11; 13)
|
||||
WHITESPACE@[13; 14)
|
||||
|
|
|
@ -70,19 +70,19 @@ fn assert_equal_text(expected: &str, actual: &str, path: &Path) {
|
|||
return;
|
||||
}
|
||||
let dir = project_dir();
|
||||
let path = path.strip_prefix(&dir).unwrap_or_else(|_| path);
|
||||
let pretty_path = path.strip_prefix(&dir).unwrap_or_else(|_| path);
|
||||
if expected.trim() == actual.trim() {
|
||||
println!("whitespace difference, rewriting");
|
||||
println!("file: {}\n", path.display());
|
||||
println!("file: {}\n", pretty_path.display());
|
||||
fs::write(path, actual).unwrap();
|
||||
return;
|
||||
}
|
||||
if REWRITE {
|
||||
println!("rewriting {}", path.display());
|
||||
println!("rewriting {}", pretty_path.display());
|
||||
fs::write(path, actual).unwrap();
|
||||
return;
|
||||
}
|
||||
assert_eq_text!(expected, actual, "file: {}", path.display());
|
||||
assert_eq_text!(expected, actual, "file: {}", pretty_path.display());
|
||||
}
|
||||
|
||||
fn collect_tests(paths: &[&str]) -> Vec<PathBuf> {
|
||||
|
|
Loading…
Reference in a new issue