Support nested import syntax
diff --git a/src/gen/fold.rs b/src/gen/fold.rs
index ba63aa4..84523a1 100644
--- a/src/gen/fold.rs
+++ b/src/gen/fold.rs
@@ -394,10 +394,14 @@
# [ cfg ( feature = "full" ) ]
fn fold_use_glob(&mut self, i: UseGlob) -> UseGlob { fold_use_glob(self, i) }
# [ cfg ( feature = "full" ) ]
-fn fold_use_list(&mut self, i: UseList) -> UseList { fold_use_list(self, i) }
+fn fold_use_group(&mut self, i: UseGroup) -> UseGroup { fold_use_group(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn fold_use_name(&mut self, i: UseName) -> UseName { fold_use_name(self, i) }
# [ cfg ( feature = "full" ) ]
fn fold_use_path(&mut self, i: UsePath) -> UsePath { fold_use_path(self, i) }
# [ cfg ( feature = "full" ) ]
+fn fold_use_rename(&mut self, i: UseRename) -> UseRename { fold_use_rename(self, i) }
+# [ cfg ( feature = "full" ) ]
fn fold_use_tree(&mut self, i: UseTree) -> UseTree { fold_use_tree(self, i) }
# [ cfg ( any ( feature = "full" , feature = "derive" ) ) ]
fn fold_variant(&mut self, i: Variant) -> Variant { fold_variant(self, i) }
@@ -1957,7 +1961,6 @@
vis: _visitor.fold_visibility(_i . vis),
use_token: Token ! [ use ](tokens_helper(_visitor, &(_i . use_token).0)),
leading_colon: (_i . leading_colon).map(|it| { Token ! [ :: ](tokens_helper(_visitor, &(it).0)) }),
- prefix: FoldHelper::lift(_i . prefix, |it| { _visitor.fold_ident(it) }),
tree: _visitor.fold_use_tree(_i . tree),
semi_token: Token ! [ ; ](tokens_helper(_visitor, &(_i . semi_token).0)),
}
@@ -2825,20 +2828,32 @@
}
}
# [ cfg ( feature = "full" ) ]
-pub fn fold_use_list<V: Fold + ?Sized>(_visitor: &mut V, _i: UseList) -> UseList {
- UseList {
+pub fn fold_use_group<V: Fold + ?Sized>(_visitor: &mut V, _i: UseGroup) -> UseGroup {
+ UseGroup {
brace_token: Brace(tokens_helper(_visitor, &(_i . brace_token).0)),
items: FoldHelper::lift(_i . items, |it| { _visitor.fold_use_tree(it) }),
}
}
# [ cfg ( feature = "full" ) ]
+pub fn fold_use_name<V: Fold + ?Sized>(_visitor: &mut V, _i: UseName) -> UseName {
+ UseName {
+ ident: _visitor.fold_ident(_i . ident),
+ }
+}
+# [ cfg ( feature = "full" ) ]
pub fn fold_use_path<V: Fold + ?Sized>(_visitor: &mut V, _i: UsePath) -> UsePath {
UsePath {
ident: _visitor.fold_ident(_i . ident),
- rename: (_i . rename).map(|it| { (
- Token ! [ as ](tokens_helper(_visitor, &(( it ) . 0).0)),
- _visitor.fold_ident(( it ) . 1),
- ) }),
+ colon2_token: Token ! [ :: ](tokens_helper(_visitor, &(_i . colon2_token).0)),
+ tree: Box::new(_visitor.fold_use_tree(* _i . tree)),
+ }
+}
+# [ cfg ( feature = "full" ) ]
+pub fn fold_use_rename<V: Fold + ?Sized>(_visitor: &mut V, _i: UseRename) -> UseRename {
+ UseRename {
+ ident: _visitor.fold_ident(_i . ident),
+ as_token: Token ! [ as ](tokens_helper(_visitor, &(_i . as_token).0)),
+ rename: _visitor.fold_ident(_i . rename),
}
}
# [ cfg ( feature = "full" ) ]
@@ -2849,14 +2864,24 @@
_visitor.fold_use_path(_binding_0),
)
}
+ UseTree::Name(_binding_0, ) => {
+ UseTree::Name (
+ _visitor.fold_use_name(_binding_0),
+ )
+ }
+ UseTree::Rename(_binding_0, ) => {
+ UseTree::Rename (
+ _visitor.fold_use_rename(_binding_0),
+ )
+ }
UseTree::Glob(_binding_0, ) => {
UseTree::Glob (
_visitor.fold_use_glob(_binding_0),
)
}
- UseTree::List(_binding_0, ) => {
- UseTree::List (
- _visitor.fold_use_list(_binding_0),
+ UseTree::Group(_binding_0, ) => {
+ UseTree::Group (
+ _visitor.fold_use_group(_binding_0),
)
}
}
diff --git a/src/gen/visit.rs b/src/gen/visit.rs
index d0969f8..5af584f 100644
--- a/src/gen/visit.rs
+++ b/src/gen/visit.rs
@@ -392,10 +392,14 @@
# [ cfg ( feature = "full" ) ]
fn visit_use_glob(&mut self, i: &'ast UseGlob) { visit_use_glob(self, i) }
# [ cfg ( feature = "full" ) ]
-fn visit_use_list(&mut self, i: &'ast UseList) { visit_use_list(self, i) }
+fn visit_use_group(&mut self, i: &'ast UseGroup) { visit_use_group(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_name(&mut self, i: &'ast UseName) { visit_use_name(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_use_path(&mut self, i: &'ast UsePath) { visit_use_path(self, i) }
# [ cfg ( feature = "full" ) ]
+fn visit_use_rename(&mut self, i: &'ast UseRename) { visit_use_rename(self, i) }
+# [ cfg ( feature = "full" ) ]
fn visit_use_tree(&mut self, i: &'ast UseTree) { visit_use_tree(self, i) }
# [ cfg ( any ( feature = "full" , feature = "derive" ) ) ]
fn visit_variant(&mut self, i: &'ast Variant) { visit_variant(self, i) }
@@ -1526,7 +1530,6 @@
_visitor.visit_visibility(& _i . vis);
tokens_helper(_visitor, &(& _i . use_token).0);
if let Some(ref it) = _i . leading_colon { tokens_helper(_visitor, &(it).0) };
- for el in Punctuated::pairs(& _i . prefix) { let it = el.value(); _visitor.visit_ident(it) };
_visitor.visit_use_tree(& _i . tree);
tokens_helper(_visitor, &(& _i . semi_token).0);
}
@@ -2180,17 +2183,25 @@
tokens_helper(_visitor, &(& _i . star_token).0);
}
# [ cfg ( feature = "full" ) ]
-pub fn visit_use_list<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseList) {
+pub fn visit_use_group<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseGroup) {
tokens_helper(_visitor, &(& _i . brace_token).0);
for el in Punctuated::pairs(& _i . items) { let it = el.value(); _visitor.visit_use_tree(it) };
}
# [ cfg ( feature = "full" ) ]
+pub fn visit_use_name<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseName) {
+ _visitor.visit_ident(& _i . ident);
+}
+# [ cfg ( feature = "full" ) ]
pub fn visit_use_path<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UsePath) {
_visitor.visit_ident(& _i . ident);
- if let Some(ref it) = _i . rename {
- tokens_helper(_visitor, &(& ( it ) . 0).0);
- _visitor.visit_ident(& ( it ) . 1);
- };
+ tokens_helper(_visitor, &(& _i . colon2_token).0);
+ _visitor.visit_use_tree(& * _i . tree);
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_rename<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseRename) {
+ _visitor.visit_ident(& _i . ident);
+ tokens_helper(_visitor, &(& _i . as_token).0);
+ _visitor.visit_ident(& _i . rename);
}
# [ cfg ( feature = "full" ) ]
pub fn visit_use_tree<'ast, V: Visit<'ast> + ?Sized>(_visitor: &mut V, _i: &'ast UseTree) {
@@ -2198,11 +2209,17 @@
UseTree::Path(ref _binding_0, ) => {
_visitor.visit_use_path(_binding_0);
}
+ UseTree::Name(ref _binding_0, ) => {
+ _visitor.visit_use_name(_binding_0);
+ }
+ UseTree::Rename(ref _binding_0, ) => {
+ _visitor.visit_use_rename(_binding_0);
+ }
UseTree::Glob(ref _binding_0, ) => {
_visitor.visit_use_glob(_binding_0);
}
- UseTree::List(ref _binding_0, ) => {
- _visitor.visit_use_list(_binding_0);
+ UseTree::Group(ref _binding_0, ) => {
+ _visitor.visit_use_group(_binding_0);
}
}
}
diff --git a/src/gen/visit_mut.rs b/src/gen/visit_mut.rs
index 30dee23..e81d52e 100644
--- a/src/gen/visit_mut.rs
+++ b/src/gen/visit_mut.rs
@@ -393,10 +393,14 @@
# [ cfg ( feature = "full" ) ]
fn visit_use_glob_mut(&mut self, i: &mut UseGlob) { visit_use_glob_mut(self, i) }
# [ cfg ( feature = "full" ) ]
-fn visit_use_list_mut(&mut self, i: &mut UseList) { visit_use_list_mut(self, i) }
+fn visit_use_group_mut(&mut self, i: &mut UseGroup) { visit_use_group_mut(self, i) }
+# [ cfg ( feature = "full" ) ]
+fn visit_use_name_mut(&mut self, i: &mut UseName) { visit_use_name_mut(self, i) }
# [ cfg ( feature = "full" ) ]
fn visit_use_path_mut(&mut self, i: &mut UsePath) { visit_use_path_mut(self, i) }
# [ cfg ( feature = "full" ) ]
+fn visit_use_rename_mut(&mut self, i: &mut UseRename) { visit_use_rename_mut(self, i) }
+# [ cfg ( feature = "full" ) ]
fn visit_use_tree_mut(&mut self, i: &mut UseTree) { visit_use_tree_mut(self, i) }
# [ cfg ( any ( feature = "full" , feature = "derive" ) ) ]
fn visit_variant_mut(&mut self, i: &mut Variant) { visit_variant_mut(self, i) }
@@ -1527,7 +1531,6 @@
_visitor.visit_visibility_mut(& mut _i . vis);
tokens_helper(_visitor, &mut (& mut _i . use_token).0);
if let Some(ref mut it) = _i . leading_colon { tokens_helper(_visitor, &mut (it).0) };
- for mut el in Punctuated::pairs_mut(& mut _i . prefix) { let it = el.value_mut(); _visitor.visit_ident_mut(it) };
_visitor.visit_use_tree_mut(& mut _i . tree);
tokens_helper(_visitor, &mut (& mut _i . semi_token).0);
}
@@ -2181,17 +2184,25 @@
tokens_helper(_visitor, &mut (& mut _i . star_token).0);
}
# [ cfg ( feature = "full" ) ]
-pub fn visit_use_list_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseList) {
+pub fn visit_use_group_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseGroup) {
tokens_helper(_visitor, &mut (& mut _i . brace_token).0);
for mut el in Punctuated::pairs_mut(& mut _i . items) { let it = el.value_mut(); _visitor.visit_use_tree_mut(it) };
}
# [ cfg ( feature = "full" ) ]
+pub fn visit_use_name_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseName) {
+ _visitor.visit_ident_mut(& mut _i . ident);
+}
+# [ cfg ( feature = "full" ) ]
pub fn visit_use_path_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UsePath) {
_visitor.visit_ident_mut(& mut _i . ident);
- if let Some(ref mut it) = _i . rename {
- tokens_helper(_visitor, &mut (& mut ( it ) . 0).0);
- _visitor.visit_ident_mut(& mut ( it ) . 1);
- };
+ tokens_helper(_visitor, &mut (& mut _i . colon2_token).0);
+ _visitor.visit_use_tree_mut(& mut * _i . tree);
+}
+# [ cfg ( feature = "full" ) ]
+pub fn visit_use_rename_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseRename) {
+ _visitor.visit_ident_mut(& mut _i . ident);
+ tokens_helper(_visitor, &mut (& mut _i . as_token).0);
+ _visitor.visit_ident_mut(& mut _i . rename);
}
# [ cfg ( feature = "full" ) ]
pub fn visit_use_tree_mut<V: VisitMut + ?Sized>(_visitor: &mut V, _i: &mut UseTree) {
@@ -2199,11 +2210,17 @@
UseTree::Path(ref mut _binding_0, ) => {
_visitor.visit_use_path_mut(_binding_0);
}
+ UseTree::Name(ref mut _binding_0, ) => {
+ _visitor.visit_use_name_mut(_binding_0);
+ }
+ UseTree::Rename(ref mut _binding_0, ) => {
+ _visitor.visit_use_rename_mut(_binding_0);
+ }
UseTree::Glob(ref mut _binding_0, ) => {
_visitor.visit_use_glob_mut(_binding_0);
}
- UseTree::List(ref mut _binding_0, ) => {
- _visitor.visit_use_list_mut(_binding_0);
+ UseTree::Group(ref mut _binding_0, ) => {
+ _visitor.visit_use_group_mut(_binding_0);
}
}
}
diff --git a/src/item.rs b/src/item.rs
index 17ea6b9..152e579 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -49,7 +49,6 @@
pub vis: Visibility,
pub use_token: Token![use],
pub leading_colon: Option<Token![::]>,
- pub prefix: Punctuated<Ident, Token![::]>,
pub tree: UseTree,
pub semi_token: Token![;],
}),
@@ -338,12 +337,29 @@
///
/// [syntax tree enum]: enum.Expr.html#syntax-tree-enums
pub enum UseTree {
- /// An identifier imported by a `use` item: `Type` or `Type as Renamed`.
+ /// A path prefix of imports in a `use` item: `std::...`.
///
/// *This type is available if Syn is built with the `"full"` feature.*
pub Path(UsePath {
pub ident: Ident,
- pub rename: Option<(Token![as], Ident)>,
+ pub colon2_token: Token![::],
+ pub tree: Box<UseTree>,
+ }),
+
+ /// An identifier imported by a `use` item: `HashMap`.
+ ///
+ /// *This type is available if Syn is built with the `"full"` feature.*
+ pub Name(UseName {
+ pub ident: Ident,
+ }),
+
+ /// An renamed identifier imported by a `use` item: `HashMap as Map`.
+ ///
+ /// *This type is available if Syn is built with the `"full"` feature.*
+ pub Rename(UseRename {
+ pub ident: Ident,
+ pub as_token: Token![as],
+ pub rename: Ident,
}),
/// A glob import in a `use` item: `*`.
@@ -353,10 +369,10 @@
pub star_token: Token![*],
}),
- /// A braced list of imports in a `use` item: `{A, B, C}`.
+ /// A braced group of imports in a `use` item: `{A, B, C}`.
///
/// *This type is available if Syn is built with the `"full"` feature.*
- pub List(UseList {
+ pub Group(UseGroup {
pub brace_token: token::Brace,
pub items: Punctuated<UseTree, Token![,]>,
}),
@@ -793,39 +809,19 @@
vis: syn!(Visibility) >>
use_: keyword!(use) >>
leading_colon: option!(punct!(::)) >>
- mut prefix: call!(Punctuated::parse_terminated_with, use_prefix) >>
- tree: switch!(value!(prefix.empty_or_trailing()),
- true => syn!(UseTree)
- |
- false => alt!(
- tuple!(keyword!(as), syn!(Ident)) => {
- |rename| UseTree::Path(UsePath {
- ident: prefix.pop().unwrap().into_value(),
- rename: Some(rename),
- })
- }
- |
- epsilon!() => {
- |_| UseTree::Path(UsePath {
- ident: prefix.pop().unwrap().into_value(),
- rename: None,
- })
- }
- )
- ) >>
+ tree: syn!(UseTree) >>
semi: punct!(;) >>
(ItemUse {
attrs: attrs,
vis: vis,
use_token: use_,
leading_colon: leading_colon,
- prefix: prefix,
tree: tree,
semi_token: semi,
})
));
- named!(use_prefix -> Ident, alt!(
+ named!(use_element -> Ident, alt!(
syn!(Ident)
|
keyword!(self) => { Into::into }
@@ -836,22 +832,42 @@
));
impl_synom!(UseTree "use tree" alt!(
+ syn!(UseRename) => { UseTree::Rename }
+ |
syn!(UsePath) => { UseTree::Path }
|
+ syn!(UseName) => { UseTree::Name }
+ |
syn!(UseGlob) => { UseTree::Glob }
|
- syn!(UseList) => { UseTree::List }
+ syn!(UseGroup) => { UseTree::Group }
));
impl_synom!(UsePath "use path" do_parse!(
- ident: alt!(
- syn!(Ident)
- |
- keyword!(self) => { Into::into }
- ) >>
- rename: option!(tuple!(keyword!(as), syn!(Ident))) >>
+ ident: call!(use_element) >>
+ colon2_token: punct!(::) >>
+ tree: syn!(UseTree) >>
(UsePath {
ident: ident,
+ colon2_token: colon2_token,
+ tree: Box::new(tree),
+ })
+ ));
+
+ impl_synom!(UseName "use name" do_parse!(
+ ident: call!(use_element) >>
+ (UseName {
+ ident: ident,
+ })
+ ));
+
+ impl_synom!(UseRename "use rename" do_parse!(
+ ident: call!(use_element) >>
+ as_token: keyword!(as) >>
+ rename: syn!(Ident) >>
+ (UseRename {
+ ident: ident,
+ as_token: as_token,
rename: rename,
})
));
@@ -863,9 +879,9 @@
})
));
- impl_synom!(UseList "use list" do_parse!(
+ impl_synom!(UseGroup "use group" do_parse!(
list: braces!(Punctuated::parse_terminated) >>
- (UseList {
+ (UseGroup {
brace_token: list.0,
items: list.1,
})
@@ -1536,7 +1552,6 @@
self.vis.to_tokens(tokens);
self.use_token.to_tokens(tokens);
self.leading_colon.to_tokens(tokens);
- self.prefix.to_tokens(tokens);
self.tree.to_tokens(tokens);
self.semi_token.to_tokens(tokens);
}
@@ -1763,10 +1778,22 @@
impl ToTokens for UsePath {
fn to_tokens(&self, tokens: &mut Tokens) {
self.ident.to_tokens(tokens);
- if let Some((ref as_token, ref rename)) = self.rename {
- as_token.to_tokens(tokens);
- rename.to_tokens(tokens);
- }
+ self.colon2_token.to_tokens(tokens);
+ self.tree.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for UseName {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.ident.to_tokens(tokens);
+ }
+ }
+
+ impl ToTokens for UseRename {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ self.ident.to_tokens(tokens);
+ self.as_token.to_tokens(tokens);
+ self.rename.to_tokens(tokens);
}
}
@@ -1776,7 +1803,7 @@
}
}
- impl ToTokens for UseList {
+ impl ToTokens for UseGroup {
fn to_tokens(&self, tokens: &mut Tokens) {
self.brace_token.surround(tokens, |tokens| {
self.items.to_tokens(tokens);
diff --git a/src/lib.rs b/src/lib.rs
index fc6d978..1f56003 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -329,8 +329,8 @@
ItemEnum, ItemExternCrate, ItemFn, ItemForeignMod, ItemImpl, ItemMacro, ItemMacro2,
ItemMod, ItemStatic, ItemStruct, ItemTrait, ItemType, ItemUnion, ItemUse,
ItemVerbatim, MethodSig, TraitItem, TraitItemConst, TraitItemMacro,
- TraitItemMethod, TraitItemType, TraitItemVerbatim, UseGlob, UseList, UsePath,
- UseTree};
+ TraitItemMethod, TraitItemType, TraitItemVerbatim, UseGlob, UseGroup, UseName,
+ UsePath, UseRename, UseTree};
#[cfg(feature = "full")]
mod file;