Remove syntax and syntax_pos thread locals
This commit is contained in:
parent
fab632f975
commit
cbdf4ec03e
29 changed files with 1212 additions and 998 deletions
|
@ -680,6 +680,7 @@ mod tests {
|
|||
use util::parser_testing::{string_to_stream, string_to_parser};
|
||||
use util::parser_testing::{string_to_expr, string_to_item, string_to_stmt};
|
||||
use util::ThinVec;
|
||||
use with_globals;
|
||||
|
||||
// produce a syntax_pos::span
|
||||
fn sp(a: u32, b: u32) -> Span {
|
||||
|
@ -691,156 +692,170 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test] fn path_exprs_1() {
|
||||
assert!(string_to_expr("a".to_string()) ==
|
||||
P(ast::Expr{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
with_globals(|| {
|
||||
assert!(string_to_expr("a".to_string()) ==
|
||||
P(ast::Expr{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span: sp(0, 1),
|
||||
segments: vec![str2seg("a", 0, 1)],
|
||||
}),
|
||||
span: sp(0, 1),
|
||||
segments: vec![str2seg("a", 0, 1)],
|
||||
}),
|
||||
span: sp(0, 1),
|
||||
attrs: ThinVec::new(),
|
||||
}))
|
||||
attrs: ThinVec::new(),
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn path_exprs_2 () {
|
||||
assert!(string_to_expr("::a::b".to_string()) ==
|
||||
P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
with_globals(|| {
|
||||
assert!(string_to_expr("::a::b".to_string()) ==
|
||||
P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span: sp(0, 6),
|
||||
segments: vec![ast::PathSegment::crate_root(sp(0, 2)),
|
||||
str2seg("a", 2, 3),
|
||||
str2seg("b", 5, 6)]
|
||||
}),
|
||||
span: sp(0, 6),
|
||||
segments: vec![ast::PathSegment::crate_root(sp(0, 2)),
|
||||
str2seg("a", 2, 3),
|
||||
str2seg("b", 5, 6)]
|
||||
}),
|
||||
span: sp(0, 6),
|
||||
attrs: ThinVec::new(),
|
||||
}))
|
||||
attrs: ThinVec::new(),
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
#[should_panic]
|
||||
#[test] fn bad_path_expr_1() {
|
||||
string_to_expr("::abc::def::return".to_string());
|
||||
with_globals(|| {
|
||||
string_to_expr("::abc::def::return".to_string());
|
||||
})
|
||||
}
|
||||
|
||||
// check the token-tree-ization of macros
|
||||
#[test]
|
||||
fn string_to_tts_macro () {
|
||||
let tts: Vec<_> =
|
||||
string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect();
|
||||
let tts: &[TokenTree] = &tts[..];
|
||||
with_globals(|| {
|
||||
let tts: Vec<_> =
|
||||
string_to_stream("macro_rules! zip (($a)=>($a))".to_string()).trees().collect();
|
||||
let tts: &[TokenTree] = &tts[..];
|
||||
|
||||
match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) {
|
||||
(
|
||||
4,
|
||||
Some(&TokenTree::Token(_, token::Ident(name_macro_rules))),
|
||||
Some(&TokenTree::Token(_, token::Not)),
|
||||
Some(&TokenTree::Token(_, token::Ident(name_zip))),
|
||||
Some(&TokenTree::Delimited(_, ref macro_delimed)),
|
||||
)
|
||||
if name_macro_rules.name == "macro_rules"
|
||||
&& name_zip.name == "zip" => {
|
||||
let tts = ¯o_delimed.stream().trees().collect::<Vec<_>>();
|
||||
match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
|
||||
(
|
||||
3,
|
||||
Some(&TokenTree::Delimited(_, ref first_delimed)),
|
||||
Some(&TokenTree::Token(_, token::FatArrow)),
|
||||
Some(&TokenTree::Delimited(_, ref second_delimed)),
|
||||
)
|
||||
if macro_delimed.delim == token::Paren => {
|
||||
let tts = &first_delimed.stream().trees().collect::<Vec<_>>();
|
||||
match (tts.len(), tts.get(0), tts.get(1)) {
|
||||
(
|
||||
2,
|
||||
Some(&TokenTree::Token(_, token::Dollar)),
|
||||
Some(&TokenTree::Token(_, token::Ident(ident))),
|
||||
)
|
||||
if first_delimed.delim == token::Paren && ident.name == "a" => {},
|
||||
_ => panic!("value 3: {:?}", *first_delimed),
|
||||
}
|
||||
let tts = &second_delimed.stream().trees().collect::<Vec<_>>();
|
||||
match (tts.len(), tts.get(0), tts.get(1)) {
|
||||
(
|
||||
2,
|
||||
Some(&TokenTree::Token(_, token::Dollar)),
|
||||
Some(&TokenTree::Token(_, token::Ident(ident))),
|
||||
)
|
||||
if second_delimed.delim == token::Paren
|
||||
&& ident.name == "a" => {},
|
||||
_ => panic!("value 4: {:?}", *second_delimed),
|
||||
}
|
||||
},
|
||||
_ => panic!("value 2: {:?}", *macro_delimed),
|
||||
}
|
||||
},
|
||||
_ => panic!("value: {:?}",tts),
|
||||
}
|
||||
match (tts.len(), tts.get(0), tts.get(1), tts.get(2), tts.get(3)) {
|
||||
(
|
||||
4,
|
||||
Some(&TokenTree::Token(_, token::Ident(name_macro_rules))),
|
||||
Some(&TokenTree::Token(_, token::Not)),
|
||||
Some(&TokenTree::Token(_, token::Ident(name_zip))),
|
||||
Some(&TokenTree::Delimited(_, ref macro_delimed)),
|
||||
)
|
||||
if name_macro_rules.name == "macro_rules"
|
||||
&& name_zip.name == "zip" => {
|
||||
let tts = ¯o_delimed.stream().trees().collect::<Vec<_>>();
|
||||
match (tts.len(), tts.get(0), tts.get(1), tts.get(2)) {
|
||||
(
|
||||
3,
|
||||
Some(&TokenTree::Delimited(_, ref first_delimed)),
|
||||
Some(&TokenTree::Token(_, token::FatArrow)),
|
||||
Some(&TokenTree::Delimited(_, ref second_delimed)),
|
||||
)
|
||||
if macro_delimed.delim == token::Paren => {
|
||||
let tts = &first_delimed.stream().trees().collect::<Vec<_>>();
|
||||
match (tts.len(), tts.get(0), tts.get(1)) {
|
||||
(
|
||||
2,
|
||||
Some(&TokenTree::Token(_, token::Dollar)),
|
||||
Some(&TokenTree::Token(_, token::Ident(ident))),
|
||||
)
|
||||
if first_delimed.delim == token::Paren && ident.name == "a" => {},
|
||||
_ => panic!("value 3: {:?}", *first_delimed),
|
||||
}
|
||||
let tts = &second_delimed.stream().trees().collect::<Vec<_>>();
|
||||
match (tts.len(), tts.get(0), tts.get(1)) {
|
||||
(
|
||||
2,
|
||||
Some(&TokenTree::Token(_, token::Dollar)),
|
||||
Some(&TokenTree::Token(_, token::Ident(ident))),
|
||||
)
|
||||
if second_delimed.delim == token::Paren
|
||||
&& ident.name == "a" => {},
|
||||
_ => panic!("value 4: {:?}", *second_delimed),
|
||||
}
|
||||
},
|
||||
_ => panic!("value 2: {:?}", *macro_delimed),
|
||||
}
|
||||
},
|
||||
_ => panic!("value: {:?}",tts),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn string_to_tts_1() {
|
||||
let tts = string_to_stream("fn a (b : i32) { b; }".to_string());
|
||||
with_globals(|| {
|
||||
let tts = string_to_stream("fn a (b : i32) { b; }".to_string());
|
||||
|
||||
let expected = TokenStream::concat(vec![
|
||||
TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"))).into(),
|
||||
TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"))).into(),
|
||||
TokenTree::Delimited(
|
||||
sp(5, 14),
|
||||
tokenstream::Delimited {
|
||||
delim: token::DelimToken::Paren,
|
||||
tts: TokenStream::concat(vec![
|
||||
TokenTree::Token(sp(6, 7), token::Ident(Ident::from_str("b"))).into(),
|
||||
TokenTree::Token(sp(8, 9), token::Colon).into(),
|
||||
TokenTree::Token(sp(10, 13), token::Ident(Ident::from_str("i32"))).into(),
|
||||
]).into(),
|
||||
}).into(),
|
||||
TokenTree::Delimited(
|
||||
sp(15, 21),
|
||||
tokenstream::Delimited {
|
||||
delim: token::DelimToken::Brace,
|
||||
tts: TokenStream::concat(vec![
|
||||
TokenTree::Token(sp(17, 18), token::Ident(Ident::from_str("b"))).into(),
|
||||
TokenTree::Token(sp(18, 19), token::Semi).into(),
|
||||
]).into(),
|
||||
}).into()
|
||||
]);
|
||||
let expected = TokenStream::concat(vec![
|
||||
TokenTree::Token(sp(0, 2), token::Ident(Ident::from_str("fn"))).into(),
|
||||
TokenTree::Token(sp(3, 4), token::Ident(Ident::from_str("a"))).into(),
|
||||
TokenTree::Delimited(
|
||||
sp(5, 14),
|
||||
tokenstream::Delimited {
|
||||
delim: token::DelimToken::Paren,
|
||||
tts: TokenStream::concat(vec![
|
||||
TokenTree::Token(sp(6, 7), token::Ident(Ident::from_str("b"))).into(),
|
||||
TokenTree::Token(sp(8, 9), token::Colon).into(),
|
||||
TokenTree::Token(sp(10, 13),
|
||||
token::Ident(Ident::from_str("i32"))).into(),
|
||||
]).into(),
|
||||
}).into(),
|
||||
TokenTree::Delimited(
|
||||
sp(15, 21),
|
||||
tokenstream::Delimited {
|
||||
delim: token::DelimToken::Brace,
|
||||
tts: TokenStream::concat(vec![
|
||||
TokenTree::Token(sp(17, 18), token::Ident(Ident::from_str("b"))).into(),
|
||||
TokenTree::Token(sp(18, 19), token::Semi).into(),
|
||||
]).into(),
|
||||
}).into()
|
||||
]);
|
||||
|
||||
assert_eq!(tts, expected);
|
||||
assert_eq!(tts, expected);
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn ret_expr() {
|
||||
assert!(string_to_expr("return d".to_string()) ==
|
||||
P(ast::Expr{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node:ast::ExprKind::Ret(Some(P(ast::Expr{
|
||||
with_globals(|| {
|
||||
assert!(string_to_expr("return d".to_string()) ==
|
||||
P(ast::Expr{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node:ast::ExprKind::Path(None, ast::Path{
|
||||
span: sp(7, 8),
|
||||
segments: vec![str2seg("d", 7, 8)],
|
||||
}),
|
||||
span:sp(7,8),
|
||||
node:ast::ExprKind::Ret(Some(P(ast::Expr{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node:ast::ExprKind::Path(None, ast::Path{
|
||||
span: sp(7, 8),
|
||||
segments: vec![str2seg("d", 7, 8)],
|
||||
}),
|
||||
span:sp(7,8),
|
||||
attrs: ThinVec::new(),
|
||||
}))),
|
||||
span:sp(0,8),
|
||||
attrs: ThinVec::new(),
|
||||
}))),
|
||||
span:sp(0,8),
|
||||
attrs: ThinVec::new(),
|
||||
}))
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn parse_stmt_1 () {
|
||||
assert!(string_to_stmt("b;".to_string()) ==
|
||||
Some(ast::Stmt {
|
||||
node: ast::StmtKind::Expr(P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span:sp(0,1),
|
||||
segments: vec![str2seg("b", 0, 1)],
|
||||
}),
|
||||
span: sp(0,1),
|
||||
attrs: ThinVec::new()})),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: sp(0,1)}))
|
||||
|
||||
with_globals(|| {
|
||||
assert!(string_to_stmt("b;".to_string()) ==
|
||||
Some(ast::Stmt {
|
||||
node: ast::StmtKind::Expr(P(ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None, ast::Path {
|
||||
span:sp(0,1),
|
||||
segments: vec![str2seg("b", 0, 1)],
|
||||
}),
|
||||
span: sp(0,1),
|
||||
attrs: ThinVec::new()})),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: sp(0,1)}))
|
||||
})
|
||||
}
|
||||
|
||||
fn parser_done(p: Parser){
|
||||
|
@ -848,120 +863,128 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test] fn parse_ident_pat () {
|
||||
let sess = ParseSess::new(FilePathMapping::empty());
|
||||
let mut parser = string_to_parser(&sess, "b".to_string());
|
||||
assert!(panictry!(parser.parse_pat())
|
||||
== P(ast::Pat{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable),
|
||||
Spanned{ span:sp(0, 1),
|
||||
node: Ident::from_str("b")
|
||||
},
|
||||
None),
|
||||
span: sp(0,1)}));
|
||||
parser_done(parser);
|
||||
with_globals(|| {
|
||||
let sess = ParseSess::new(FilePathMapping::empty());
|
||||
let mut parser = string_to_parser(&sess, "b".to_string());
|
||||
assert!(panictry!(parser.parse_pat())
|
||||
== P(ast::Pat{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Immutable),
|
||||
Spanned{ span:sp(0, 1),
|
||||
node: Ident::from_str("b")
|
||||
},
|
||||
None),
|
||||
span: sp(0,1)}));
|
||||
parser_done(parser);
|
||||
})
|
||||
}
|
||||
|
||||
// check the contents of the tt manually:
|
||||
#[test] fn parse_fundecl () {
|
||||
// this test depends on the intern order of "fn" and "i32"
|
||||
let item = string_to_item("fn a (b : i32) { b; }".to_string()).map(|m| {
|
||||
m.map(|mut m| {
|
||||
m.tokens = None;
|
||||
m
|
||||
})
|
||||
});
|
||||
assert_eq!(item,
|
||||
Some(
|
||||
P(ast::Item{ident:Ident::from_str("a"),
|
||||
attrs:Vec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
tokens: None,
|
||||
node: ast::ItemKind::Fn(P(ast::FnDecl {
|
||||
inputs: vec![ast::Arg{
|
||||
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
|
||||
node: ast::TyKind::Path(None, ast::Path{
|
||||
span:sp(10,13),
|
||||
segments: vec![str2seg("i32", 10, 13)],
|
||||
with_globals(|| {
|
||||
// this test depends on the intern order of "fn" and "i32"
|
||||
let item = string_to_item("fn a (b : i32) { b; }".to_string()).map(|m| {
|
||||
m.map(|mut m| {
|
||||
m.tokens = None;
|
||||
m
|
||||
})
|
||||
});
|
||||
assert_eq!(item,
|
||||
Some(
|
||||
P(ast::Item{ident:Ident::from_str("a"),
|
||||
attrs:Vec::new(),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
tokens: None,
|
||||
node: ast::ItemKind::Fn(P(ast::FnDecl {
|
||||
inputs: vec![ast::Arg{
|
||||
ty: P(ast::Ty{id: ast::DUMMY_NODE_ID,
|
||||
node: ast::TyKind::Path(None, ast::Path{
|
||||
span:sp(10,13),
|
||||
segments: vec![str2seg("i32", 10, 13)],
|
||||
}),
|
||||
span:sp(10,13)
|
||||
}),
|
||||
span:sp(10,13)
|
||||
}),
|
||||
pat: P(ast::Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: PatKind::Ident(
|
||||
ast::BindingMode::ByValue(
|
||||
ast::Mutability::Immutable),
|
||||
Spanned{
|
||||
span: sp(6,7),
|
||||
node: Ident::from_str("b")},
|
||||
None
|
||||
),
|
||||
span: sp(6,7)
|
||||
}),
|
||||
id: ast::DUMMY_NODE_ID
|
||||
}],
|
||||
output: ast::FunctionRetTy::Default(sp(15, 15)),
|
||||
variadic: false
|
||||
}),
|
||||
ast::Unsafety::Normal,
|
||||
Spanned {
|
||||
span: sp(0,2),
|
||||
node: ast::Constness::NotConst,
|
||||
},
|
||||
Abi::Rust,
|
||||
ast::Generics{
|
||||
params: Vec::new(),
|
||||
where_clause: ast::WhereClause {
|
||||
pat: P(ast::Pat {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
predicates: Vec::new(),
|
||||
node: PatKind::Ident(
|
||||
ast::BindingMode::ByValue(
|
||||
ast::Mutability::Immutable),
|
||||
Spanned{
|
||||
span: sp(6,7),
|
||||
node: Ident::from_str("b")},
|
||||
None
|
||||
),
|
||||
span: sp(6,7)
|
||||
}),
|
||||
id: ast::DUMMY_NODE_ID
|
||||
}],
|
||||
output: ast::FunctionRetTy::Default(sp(15, 15)),
|
||||
variadic: false
|
||||
}),
|
||||
ast::Unsafety::Normal,
|
||||
Spanned {
|
||||
span: sp(0,2),
|
||||
node: ast::Constness::NotConst,
|
||||
},
|
||||
Abi::Rust,
|
||||
ast::Generics{
|
||||
params: Vec::new(),
|
||||
where_clause: ast::WhereClause {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
predicates: Vec::new(),
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
},
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
},
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
},
|
||||
P(ast::Block {
|
||||
stmts: vec![ast::Stmt {
|
||||
node: ast::StmtKind::Semi(P(ast::Expr{
|
||||
P(ast::Block {
|
||||
stmts: vec![ast::Stmt {
|
||||
node: ast::StmtKind::Semi(P(ast::Expr{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None,
|
||||
ast::Path{
|
||||
span:sp(17,18),
|
||||
segments: vec![str2seg("b", 17, 18)],
|
||||
}),
|
||||
span: sp(17,18),
|
||||
attrs: ThinVec::new()})),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprKind::Path(None,
|
||||
ast::Path{
|
||||
span:sp(17,18),
|
||||
segments: vec![str2seg("b", 17, 18)],
|
||||
}),
|
||||
span: sp(17,18),
|
||||
attrs: ThinVec::new()})),
|
||||
span: sp(17,19)}],
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: sp(17,19)}],
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
rules: ast::BlockCheckMode::Default, // no idea
|
||||
span: sp(15,21),
|
||||
recovered: false,
|
||||
})),
|
||||
vis: respan(sp(0, 0), ast::VisibilityKind::Inherited),
|
||||
span: sp(0,21)})));
|
||||
rules: ast::BlockCheckMode::Default, // no idea
|
||||
span: sp(15,21),
|
||||
recovered: false,
|
||||
})),
|
||||
vis: respan(sp(0, 0), ast::VisibilityKind::Inherited),
|
||||
span: sp(0,21)})));
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn parse_use() {
|
||||
let use_s = "use foo::bar::baz;";
|
||||
let vitem = string_to_item(use_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&vitem);
|
||||
assert_eq!(&vitem_s[..], use_s);
|
||||
with_globals(|| {
|
||||
let use_s = "use foo::bar::baz;";
|
||||
let vitem = string_to_item(use_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&vitem);
|
||||
assert_eq!(&vitem_s[..], use_s);
|
||||
|
||||
let use_s = "use foo::bar as baz;";
|
||||
let vitem = string_to_item(use_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&vitem);
|
||||
assert_eq!(&vitem_s[..], use_s);
|
||||
let use_s = "use foo::bar as baz;";
|
||||
let vitem = string_to_item(use_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&vitem);
|
||||
assert_eq!(&vitem_s[..], use_s);
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn parse_extern_crate() {
|
||||
let ex_s = "extern crate foo;";
|
||||
let vitem = string_to_item(ex_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&vitem);
|
||||
assert_eq!(&vitem_s[..], ex_s);
|
||||
with_globals(|| {
|
||||
let ex_s = "extern crate foo;";
|
||||
let vitem = string_to_item(ex_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&vitem);
|
||||
assert_eq!(&vitem_s[..], ex_s);
|
||||
|
||||
let ex_s = "extern crate foo as bar;";
|
||||
let vitem = string_to_item(ex_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&vitem);
|
||||
assert_eq!(&vitem_s[..], ex_s);
|
||||
let ex_s = "extern crate foo as bar;";
|
||||
let vitem = string_to_item(ex_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&vitem);
|
||||
assert_eq!(&vitem_s[..], ex_s);
|
||||
})
|
||||
}
|
||||
|
||||
fn get_spans_of_pat_idents(src: &str) -> Vec<Span> {
|
||||
|
@ -988,31 +1011,36 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test] fn span_of_self_arg_pat_idents_are_correct() {
|
||||
with_globals(|| {
|
||||
|
||||
let srcs = ["impl z { fn a (&self, &myarg: i32) {} }",
|
||||
"impl z { fn a (&mut self, &myarg: i32) {} }",
|
||||
"impl z { fn a (&'a self, &myarg: i32) {} }",
|
||||
"impl z { fn a (self, &myarg: i32) {} }",
|
||||
"impl z { fn a (self: Foo, &myarg: i32) {} }",
|
||||
];
|
||||
let srcs = ["impl z { fn a (&self, &myarg: i32) {} }",
|
||||
"impl z { fn a (&mut self, &myarg: i32) {} }",
|
||||
"impl z { fn a (&'a self, &myarg: i32) {} }",
|
||||
"impl z { fn a (self, &myarg: i32) {} }",
|
||||
"impl z { fn a (self: Foo, &myarg: i32) {} }",
|
||||
];
|
||||
|
||||
for &src in &srcs {
|
||||
let spans = get_spans_of_pat_idents(src);
|
||||
let (lo, hi) = (spans[0].lo(), spans[0].hi());
|
||||
assert!("self" == &src[lo.to_usize()..hi.to_usize()],
|
||||
"\"{}\" != \"self\". src=\"{}\"",
|
||||
&src[lo.to_usize()..hi.to_usize()], src)
|
||||
}
|
||||
for &src in &srcs {
|
||||
let spans = get_spans_of_pat_idents(src);
|
||||
let (lo, hi) = (spans[0].lo(), spans[0].hi());
|
||||
assert!("self" == &src[lo.to_usize()..hi.to_usize()],
|
||||
"\"{}\" != \"self\". src=\"{}\"",
|
||||
&src[lo.to_usize()..hi.to_usize()], src)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn parse_exprs () {
|
||||
// just make sure that they parse....
|
||||
string_to_expr("3 + 4".to_string());
|
||||
string_to_expr("a::z.froob(b,&(987+3))".to_string());
|
||||
with_globals(|| {
|
||||
// just make sure that they parse....
|
||||
string_to_expr("3 + 4".to_string());
|
||||
string_to_expr("a::z.froob(b,&(987+3))".to_string());
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn attrs_fix_bug () {
|
||||
string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
|
||||
with_globals(|| {
|
||||
string_to_item("pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
|
||||
-> Result<Box<Writer>, String> {
|
||||
#[cfg(windows)]
|
||||
fn wb() -> c_int {
|
||||
|
@ -1024,49 +1052,54 @@ mod tests {
|
|||
|
||||
let mut fflags: c_int = wb();
|
||||
}".to_string());
|
||||
})
|
||||
}
|
||||
|
||||
#[test] fn crlf_doc_comments() {
|
||||
let sess = ParseSess::new(FilePathMapping::empty());
|
||||
with_globals(|| {
|
||||
let sess = ParseSess::new(FilePathMapping::empty());
|
||||
|
||||
let name = FileName::Custom("source".to_string());
|
||||
let source = "/// doc comment\r\nfn foo() {}".to_string();
|
||||
let item = parse_item_from_source_str(name.clone(), source, &sess)
|
||||
.unwrap().unwrap();
|
||||
let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
|
||||
assert_eq!(doc, "/// doc comment");
|
||||
let name = FileName::Custom("source".to_string());
|
||||
let source = "/// doc comment\r\nfn foo() {}".to_string();
|
||||
let item = parse_item_from_source_str(name.clone(), source, &sess)
|
||||
.unwrap().unwrap();
|
||||
let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
|
||||
assert_eq!(doc, "/// doc comment");
|
||||
|
||||
let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
|
||||
let item = parse_item_from_source_str(name.clone(), source, &sess)
|
||||
.unwrap().unwrap();
|
||||
let docs = item.attrs.iter().filter(|a| a.path == "doc")
|
||||
.map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
|
||||
let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
|
||||
assert_eq!(&docs[..], b);
|
||||
let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
|
||||
let item = parse_item_from_source_str(name.clone(), source, &sess)
|
||||
.unwrap().unwrap();
|
||||
let docs = item.attrs.iter().filter(|a| a.path == "doc")
|
||||
.map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
|
||||
let b: &[_] = &["/// doc comment".to_string(), "/// line 2".to_string()];
|
||||
assert_eq!(&docs[..], b);
|
||||
|
||||
let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string();
|
||||
let item = parse_item_from_source_str(name, source, &sess).unwrap().unwrap();
|
||||
let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
|
||||
assert_eq!(doc, "/** doc comment\n * with CRLF */");
|
||||
let source = "/** doc comment\r\n * with CRLF */\r\nfn foo() {}".to_string();
|
||||
let item = parse_item_from_source_str(name, source, &sess).unwrap().unwrap();
|
||||
let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
|
||||
assert_eq!(doc, "/** doc comment\n * with CRLF */");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ttdelim_span() {
|
||||
let sess = ParseSess::new(FilePathMapping::empty());
|
||||
let expr = parse::parse_expr_from_source_str(PathBuf::from("foo").into(),
|
||||
"foo!( fn main() { body } )".to_string(), &sess).unwrap();
|
||||
with_globals(|| {
|
||||
let sess = ParseSess::new(FilePathMapping::empty());
|
||||
let expr = parse::parse_expr_from_source_str(PathBuf::from("foo").into(),
|
||||
"foo!( fn main() { body } )".to_string(), &sess).unwrap();
|
||||
|
||||
let tts: Vec<_> = match expr.node {
|
||||
ast::ExprKind::Mac(ref mac) => mac.node.stream().trees().collect(),
|
||||
_ => panic!("not a macro"),
|
||||
};
|
||||
let tts: Vec<_> = match expr.node {
|
||||
ast::ExprKind::Mac(ref mac) => mac.node.stream().trees().collect(),
|
||||
_ => panic!("not a macro"),
|
||||
};
|
||||
|
||||
let span = tts.iter().rev().next().unwrap().span();
|
||||
let span = tts.iter().rev().next().unwrap().span();
|
||||
|
||||
match sess.codemap().span_to_snippet(span) {
|
||||
Ok(s) => assert_eq!(&s[..], "{ body }"),
|
||||
Err(_) => panic!("could not get snippet"),
|
||||
}
|
||||
match sess.codemap().span_to_snippet(span) {
|
||||
Ok(s) => assert_eq!(&s[..], "{ body }"),
|
||||
Err(_) => panic!("could not get snippet"),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// This tests that when parsing a string (rather than a file) we don't try
|
||||
|
@ -1074,17 +1107,19 @@ mod tests {
|
|||
// See `recurse_into_file_modules` in the parser.
|
||||
#[test]
|
||||
fn out_of_line_mod() {
|
||||
let sess = ParseSess::new(FilePathMapping::empty());
|
||||
let item = parse_item_from_source_str(
|
||||
PathBuf::from("foo").into(),
|
||||
"mod foo { struct S; mod this_does_not_exist; }".to_owned(),
|
||||
&sess,
|
||||
).unwrap().unwrap();
|
||||
with_globals(|| {
|
||||
let sess = ParseSess::new(FilePathMapping::empty());
|
||||
let item = parse_item_from_source_str(
|
||||
PathBuf::from("foo").into(),
|
||||
"mod foo { struct S; mod this_does_not_exist; }".to_owned(),
|
||||
&sess,
|
||||
).unwrap().unwrap();
|
||||
|
||||
if let ast::ItemKind::Mod(ref m) = item.node {
|
||||
assert!(m.items.len() == 2);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
if let ast::ItemKind::Mod(ref m) = item.node {
|
||||
assert!(m.items.len() == 2);
|
||||
} else {
|
||||
panic!();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue