+
+ fn has_comment(&self) -> bool {
+ self.list_item.as_ref().map_or(false, ListItem::has_comment)
+ }
+
+ fn same_visibility(&self, other: &UseTree) -> bool {
+ match (&self.visibility, &other.visibility) {
+ (
+ Some(codemap::Spanned {
+ node: ast::VisibilityKind::Inherited,
+ ..
+ }),
+ None,
+ )
+ | (
+ None,
+ Some(codemap::Spanned {
+ node: ast::VisibilityKind::Inherited,
+ ..
+ }),
+ )
+ | (None, None) => true,
+ (
+ Some(codemap::Spanned { node: lnode, .. }),
+ Some(codemap::Spanned { node: rnode, .. }),
+ ) => lnode == rnode,
+ _ => false,
+ }
+ }
+
+ fn share_prefix(&self, other: &UseTree) -> bool {
+ if self.path.is_empty() || other.path.is_empty() || self.attrs.is_some()
+ || !self.same_visibility(other)
+ {
+ false
+ } else {
+ self.path[0] == other.path[0]
+ }
+ }
+
+ fn flatten(self) -> Vec<UseTree> {
+ if self.path.is_empty() {
+ return vec![self];
+ }
+ match self.path.clone().last().unwrap() {
+ UseSegment::List(list) => {
+ let prefix = &self.path[..self.path.len() - 1];
+ let mut result = vec![];
+ for nested_use_tree in list {
+ for mut flattend in &mut nested_use_tree.clone().flatten() {
+ let mut new_path = prefix.to_vec();
+ new_path.append(&mut flattend.path);
+ result.push(UseTree {
+ path: new_path,
+ span: self.span,
+ list_item: None,
+ visibility: self.visibility.clone(),
+ attrs: None,
+ });
+ }
+ }
+
+ result
+ }
+ _ => vec![self],
+ }
+ }
+
+ fn merge(&mut self, other: UseTree) {
+ let mut new_path = vec![];
+ for (mut a, b) in self.path
+ .clone()
+ .iter_mut()
+ .zip(other.path.clone().into_iter())
+ {
+ if *a == b {
+ new_path.push(b);
+ } else {
+ break;
+ }
+ }
+ if let Some(merged) = merge_rest(&self.path, &other.path, new_path.len()) {
+ new_path.push(merged);
+ self.span = self.span.to(other.span);
+ }
+ self.path = new_path;
+ }
+}
+
+fn merge_rest(a: &[UseSegment], b: &[UseSegment], len: usize) -> Option<UseSegment> {
+ let a_rest = &a[len..];
+ let b_rest = &b[len..];
+ if a_rest.is_empty() && b_rest.is_empty() {
+ return None;
+ }
+ if a_rest.is_empty() {
+ return Some(UseSegment::List(vec![
+ UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
+ UseTree::from_path(b_rest.to_vec(), DUMMY_SP),
+ ]));
+ }
+ if b_rest.is_empty() {
+ return Some(UseSegment::List(vec![
+ UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP),
+ UseTree::from_path(a_rest.to_vec(), DUMMY_SP),
+ ]));
+ }
+ if let UseSegment::List(mut list) = a_rest[0].clone() {
+ merge_use_trees_inner(&mut list, UseTree::from_path(b_rest.to_vec(), DUMMY_SP));
+ list.sort();
+ return Some(UseSegment::List(list.clone()));
+ }
+ let mut list = vec![
+ UseTree::from_path(a_rest.to_vec(), DUMMY_SP),
+ UseTree::from_path(b_rest.to_vec(), DUMMY_SP),
+ ];
+ list.sort();
+ Some(UseSegment::List(list))