]> git.lizzy.rs Git - rust.git/blob - src/imports.rs
Fix trailing commas in where clauses
[rust.git] / src / imports.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use visitor::FmtVisitor;
12 use lists::{write_list, ListFormatting, SeparatorTactic, ListTactic};
13
14 use syntax::ast;
15 use syntax::codemap::Span;
16 use syntax::parse::token;
17 use syntax::print::pprust;
18
19 use {IDEAL_WIDTH, MAX_WIDTH};
20
21 // TODO change import lists with one item to a single import
22 //      remove empty lists (if they're even possible)
23 // TODO (some day) remove unused imports, expand globs, compress many single imports into a list import
24
25 impl<'a> FmtVisitor<'a> {
26     // Basically just pretty prints a multi-item import.
27     pub fn rewrite_use_list(&mut self,
28                             path: &ast::Path,
29                             path_list: &[ast::PathListItem],
30                             vp_span: Span) -> String {
31         // FIXME check indentation
32         let l_loc = self.codemap.lookup_char_pos(vp_span.lo);
33
34         let path_str = pprust::path_to_string(&path);
35
36
37         // 1 = {
38         let mut indent = l_loc.col.0 + path_str.len() + 1;
39         if path_str.len() > 0 {
40             // 2 = ::
41             indent += 2;
42         }
43         // 2 = } + ;
44         let used_width = indent + 2;
45         let budget = if used_width >= IDEAL_WIDTH {
46             if used_width < MAX_WIDTH {
47                 MAX_WIDTH - used_width
48             } else {
49                 // Give up
50                 return String::new();
51             }
52         } else {
53             IDEAL_WIDTH - used_width
54         };
55         let fmt = ListFormatting {
56             tactic: ListTactic::Mixed,
57             separator: ",",
58             trailing_separator: SeparatorTactic::Never,
59             indent: indent,
60             h_width: budget,
61             v_width: budget,
62         };
63
64         // TODO handle any comments inbetween items.
65         // If `self` is in the list, put it first.
66         let head = if path_list.iter().any(|vpi|
67             if let ast::PathListItem_::PathListMod{ .. } = vpi.node {
68                 true
69             } else {
70                 false
71             }
72         ) {
73             Some(("self".to_string(), String::new()))
74         } else {
75             None
76         };
77
78         let items: Vec<_> = head.into_iter().chain(path_list.iter().filter_map(|vpi| {
79             match vpi.node {
80                 ast::PathListItem_::PathListIdent{ name, .. } => {
81                     Some((token::get_ident(name).to_string(), String::new()))
82                 }
83                 // Skip `self`, because we added it above.
84                 ast::PathListItem_::PathListMod{ .. } => None,
85             }
86         })).collect();
87
88         if path_str.len() == 0 {
89             format!("use {{{}}};", write_list(&items, &fmt))
90         } else {
91             format!("use {}::{{{}}};", path_str, write_list(&items, &fmt))
92         }
93     }
94 }