1- //! Handle syntactic aspects of inserting a new `use`.
1+ //! Handle syntactic aspects of inserting a new `use` item .
22#[ cfg( test) ]
33mod tests;
44
@@ -103,81 +103,6 @@ impl ImportScope {
103103 ImportScope :: Block ( block) => ImportScope :: Block ( block. clone_for_update ( ) ) ,
104104 }
105105 }
106-
107- fn guess_granularity_from_scope ( & self ) -> ImportGranularityGuess {
108- // The idea is simple, just check each import as well as the import and its precedent together for
109- // whether they fulfill a granularity criteria.
110- let use_stmt = |item| match item {
111- ast:: Item :: Use ( use_) => {
112- let use_tree = use_. use_tree ( ) ?;
113- Some ( ( use_tree, use_. visibility ( ) , use_. attrs ( ) ) )
114- }
115- _ => None ,
116- } ;
117- let mut use_stmts = match self {
118- ImportScope :: File ( f) => f. items ( ) ,
119- ImportScope :: Module ( m) => m. items ( ) ,
120- ImportScope :: Block ( b) => b. items ( ) ,
121- }
122- . filter_map ( use_stmt) ;
123- let mut res = ImportGranularityGuess :: Unknown ;
124- let ( mut prev, mut prev_vis, mut prev_attrs) = match use_stmts. next ( ) {
125- Some ( it) => it,
126- None => return res,
127- } ;
128- loop {
129- if let Some ( use_tree_list) = prev. use_tree_list ( ) {
130- if use_tree_list. use_trees ( ) . any ( |tree| tree. use_tree_list ( ) . is_some ( ) ) {
131- // Nested tree lists can only occur in crate style, or with no proper style being enforced in the file.
132- break ImportGranularityGuess :: Crate ;
133- } else {
134- // Could still be crate-style so continue looking.
135- res = ImportGranularityGuess :: CrateOrModule ;
136- }
137- }
138-
139- let ( curr, curr_vis, curr_attrs) = match use_stmts. next ( ) {
140- Some ( it) => it,
141- None => break res,
142- } ;
143- if eq_visibility ( prev_vis, curr_vis. clone ( ) ) && eq_attrs ( prev_attrs, curr_attrs. clone ( ) )
144- {
145- if let Some ( ( prev_path, curr_path) ) = prev. path ( ) . zip ( curr. path ( ) ) {
146- if let Some ( ( prev_prefix, _) ) = common_prefix ( & prev_path, & curr_path) {
147- if prev. use_tree_list ( ) . is_none ( ) && curr. use_tree_list ( ) . is_none ( ) {
148- let prefix_c = prev_prefix. qualifiers ( ) . count ( ) ;
149- let curr_c = curr_path. qualifiers ( ) . count ( ) - prefix_c;
150- let prev_c = prev_path. qualifiers ( ) . count ( ) - prefix_c;
151- if curr_c == 1 && prev_c == 1 {
152- // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style.
153- break ImportGranularityGuess :: Item ;
154- } else {
155- // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still.
156- res = ImportGranularityGuess :: ModuleOrItem ;
157- }
158- } else {
159- // Same prefix with item tree lists, has to be module style as it
160- // can't be crate style since the trees wouldn't share a prefix then.
161- break ImportGranularityGuess :: Module ;
162- }
163- }
164- }
165- }
166- prev = curr;
167- prev_vis = curr_vis;
168- prev_attrs = curr_attrs;
169- }
170- }
171- }
172-
173- #[ derive( PartialEq , PartialOrd , Debug , Clone , Copy ) ]
174- enum ImportGranularityGuess {
175- Unknown ,
176- Item ,
177- Module ,
178- ModuleOrItem ,
179- Crate ,
180- CrateOrModule ,
181106}
182107
183108/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
@@ -189,7 +114,7 @@ pub fn insert_use(scope: &ImportScope, path: ast::Path, cfg: &InsertUseConfig) {
189114 ImportGranularity :: Item | ImportGranularity :: Preserve => None ,
190115 } ;
191116 if !cfg. enforce_granularity {
192- let file_granularity = scope . guess_granularity_from_scope ( ) ;
117+ let file_granularity = guess_granularity_from_scope ( scope ) ;
193118 mb = match file_granularity {
194119 ImportGranularityGuess :: Unknown => mb,
195120 ImportGranularityGuess :: Item => None ,
@@ -271,6 +196,80 @@ impl ImportGroup {
271196 }
272197}
273198
199+ #[ derive( PartialEq , PartialOrd , Debug , Clone , Copy ) ]
200+ enum ImportGranularityGuess {
201+ Unknown ,
202+ Item ,
203+ Module ,
204+ ModuleOrItem ,
205+ Crate ,
206+ CrateOrModule ,
207+ }
208+
209+ fn guess_granularity_from_scope ( scope : & ImportScope ) -> ImportGranularityGuess {
210+ // The idea is simple, just check each import as well as the import and its precedent together for
211+ // whether they fulfill a granularity criteria.
212+ let use_stmt = |item| match item {
213+ ast:: Item :: Use ( use_) => {
214+ let use_tree = use_. use_tree ( ) ?;
215+ Some ( ( use_tree, use_. visibility ( ) , use_. attrs ( ) ) )
216+ }
217+ _ => None ,
218+ } ;
219+ let mut use_stmts = match scope {
220+ ImportScope :: File ( f) => f. items ( ) ,
221+ ImportScope :: Module ( m) => m. items ( ) ,
222+ ImportScope :: Block ( b) => b. items ( ) ,
223+ }
224+ . filter_map ( use_stmt) ;
225+ let mut res = ImportGranularityGuess :: Unknown ;
226+ let ( mut prev, mut prev_vis, mut prev_attrs) = match use_stmts. next ( ) {
227+ Some ( it) => it,
228+ None => return res,
229+ } ;
230+ loop {
231+ if let Some ( use_tree_list) = prev. use_tree_list ( ) {
232+ if use_tree_list. use_trees ( ) . any ( |tree| tree. use_tree_list ( ) . is_some ( ) ) {
233+ // Nested tree lists can only occur in crate style, or with no proper style being enforced in the file.
234+ break ImportGranularityGuess :: Crate ;
235+ } else {
236+ // Could still be crate-style so continue looking.
237+ res = ImportGranularityGuess :: CrateOrModule ;
238+ }
239+ }
240+
241+ let ( curr, curr_vis, curr_attrs) = match use_stmts. next ( ) {
242+ Some ( it) => it,
243+ None => break res,
244+ } ;
245+ if eq_visibility ( prev_vis, curr_vis. clone ( ) ) && eq_attrs ( prev_attrs, curr_attrs. clone ( ) ) {
246+ if let Some ( ( prev_path, curr_path) ) = prev. path ( ) . zip ( curr. path ( ) ) {
247+ if let Some ( ( prev_prefix, _) ) = common_prefix ( & prev_path, & curr_path) {
248+ if prev. use_tree_list ( ) . is_none ( ) && curr. use_tree_list ( ) . is_none ( ) {
249+ let prefix_c = prev_prefix. qualifiers ( ) . count ( ) ;
250+ let curr_c = curr_path. qualifiers ( ) . count ( ) - prefix_c;
251+ let prev_c = prev_path. qualifiers ( ) . count ( ) - prefix_c;
252+ if curr_c == 1 && prev_c == 1 {
253+ // Same prefix, only differing in the last segment and no use tree lists so this has to be of item style.
254+ break ImportGranularityGuess :: Item ;
255+ } else {
256+ // Same prefix and no use tree list but differs in more than one segment at the end. This might be module style still.
257+ res = ImportGranularityGuess :: ModuleOrItem ;
258+ }
259+ } else {
260+ // Same prefix with item tree lists, has to be module style as it
261+ // can't be crate style since the trees wouldn't share a prefix then.
262+ break ImportGranularityGuess :: Module ;
263+ }
264+ }
265+ }
266+ }
267+ prev = curr;
268+ prev_vis = curr_vis;
269+ prev_attrs = curr_attrs;
270+ }
271+ }
272+
274273fn insert_use_ (
275274 scope : & ImportScope ,
276275 insert_path : & ast:: Path ,
0 commit comments