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