Skip to content
This repository was archived by the owner on Sep 3, 2020. It is now read-only.

Commit a4afb32

Browse files
authored
Merge pull request #193 from wpopielarski/default-imports-grouping
Default imports grouping
2 parents 7347958 + af474be commit a4afb32

File tree

2 files changed

+283
-19
lines changed

2 files changed

+283
-19
lines changed

src/main/scala/scala/tools/refactoring/implementations/OrganizeImports.scala

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,35 @@ import scala.tools.refactoring.sourcegen.Formatting
1212
import scala.util.control.NonFatal
1313

1414
object OrganizeImports {
15+
val DefaultGroup = "*"
1516
/**
1617
* Abstract algorithms used by the implementation, extracted mostly for testing purposes
1718
*/
1819
private[implementations] object Algos {
1920
def groupImports[ImportT](getImportExpression: ImportT => String)(groups: Seq[String], imports: Seq[ImportT]): Seq[List[ImportT]] = {
2021
val distinctGroups = groups.distinct
21-
22-
case class Accumulator(remainingImports: Seq[ImportT] = imports, groups: Map[String, List[ImportT]] = Map()) {
23-
def assembleResult: Seq[List[ImportT]] = {
24-
val importGroups = distinctGroups.flatMap(groups.get(_))
25-
if (remainingImports.isEmpty) importGroups
26-
else importGroups :+ remainingImports.toList
27-
}
28-
}
29-
30-
distinctGroups.sortBy(-_.length).foldLeft(Accumulator()) { (acc, group) =>
31-
val (inGroup, remaining) = acc.remainingImports.partition { imp =>
32-
val expr = getImportExpression(imp)
22+
val acc = distinctGroups.map(_ -> scala.collection.mutable.ListBuffer.empty[ImportT]).toMap
23+
val assigned = imports.foldLeft(acc) { (acc, imp) =>
24+
val expr = getImportExpression(imp)
25+
val inGroup = distinctGroups.filter { group =>
3326
expr.startsWith(group + ".") || expr == group
3427
}
35-
36-
val newGroups = {
37-
if (inGroup.isEmpty) acc.groups
38-
else acc.groups + (group -> inGroup.toList)
28+
if (inGroup.nonEmpty) {
29+
val mostSpecificGroup = inGroup.sortBy(-_.length).head
30+
acc(mostSpecificGroup) += imp
3931
}
40-
41-
acc.copy(remainingImports = remaining, groups = newGroups)
42-
}.assembleResult
32+
acc
33+
}
34+
val unassigned = {
35+
val a = assigned.values.toList.flatten.map(getImportExpression)
36+
imports.filterNot { imp => a.contains(getImportExpression(imp)) }
37+
}
38+
if (assigned.keySet(DefaultGroup)) {
39+
assigned(DefaultGroup) ++= unassigned
40+
assigned.values.filter(_.nonEmpty).toSeq.map(_.toList)
41+
} else {
42+
assigned.values.filter(_.nonEmpty).toSeq.map(_.toList) :+ (unassigned.toList)
43+
}
4344
}
4445
}
4546

src/test/scala/scala/tools/refactoring/tests/implementations/imports/OrganizeImportsGroupsTest.scala

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,267 @@ class OrganizeImportsGroupsTest extends OrganizeImportsBaseTest {
161161
}
162162
"""
163163
} applyRefactoring organize(List("javava", "sca"))
164+
165+
@Test
166+
def defaultGroupInTheMiddleVersion1() = new FileSet {
167+
source becomes
168+
"""
169+
import org.xml.sax.Attributes
170+
171+
import java.util.AbstractList
172+
import java.util.BitSet
173+
import scala.io.Source
174+
175+
import scala.collection.mutable.HashMap
176+
import scala.collection.mutable.ListBuffer
177+
178+
trait Temp {
179+
// we need some code that use the imports
180+
val x: (ListBuffer[Int], HashMap[String, Int])
181+
val y: (AbstractList[Int], BitSet)
182+
val z: (Attributes, Source)
183+
}
184+
"""
185+
} applyRefactoring organize(List("org.xml", "*", "scala.collection"))
186+
187+
@Test
188+
def defaultGroupInTheMiddleVersion2() = new FileSet {
189+
source becomes
190+
"""
191+
import org.xml.sax.Attributes
192+
193+
import java.util.AbstractList
194+
import java.util.BitSet
195+
196+
import scala.io.Source
197+
198+
import scala.collection.mutable.HashMap
199+
import scala.collection.mutable.ListBuffer
200+
201+
trait Temp {
202+
// we need some code that use the imports
203+
val x: (ListBuffer[Int], HashMap[String, Int])
204+
val y: (AbstractList[Int], BitSet)
205+
val z: (Attributes, Source)
206+
}
207+
"""
208+
} applyRefactoring organize(List("org.xml", "java", "*", "scala.collection"))
209+
210+
@Test
211+
def defaultGroupInTheMiddleButEmpty() = new FileSet {
212+
source becomes
213+
"""
214+
import org.xml.sax.Attributes
215+
216+
import java.util.AbstractList
217+
import java.util.BitSet
218+
219+
import scala.collection.mutable.HashMap
220+
import scala.collection.mutable.ListBuffer
221+
import scala.io.Source
222+
223+
trait Temp {
224+
// we need some code that use the imports
225+
val x: (ListBuffer[Int], HashMap[String, Int])
226+
val y: (AbstractList[Int], BitSet)
227+
val z: (Attributes, Source)
228+
}
229+
"""
230+
} applyRefactoring organize(List("org", "java", "*", "scala"))
231+
232+
@Test
233+
def defaultGroupInTheBeginningVersion1() = new FileSet {
234+
source becomes
235+
"""
236+
import java.util.AbstractList
237+
import java.util.BitSet
238+
import scala.io.Source
239+
240+
import org.xml.sax.Attributes
241+
242+
import scala.collection.mutable.HashMap
243+
import scala.collection.mutable.ListBuffer
244+
245+
trait Temp {
246+
// we need some code that use the imports
247+
val x: (ListBuffer[Int], HashMap[String, Int])
248+
val y: (AbstractList[Int], BitSet)
249+
val z: (Attributes, Source)
250+
}
251+
"""
252+
} applyRefactoring organize(List("*", "org.xml", "scala.collection"))
253+
254+
@Test
255+
def defaultGroupInTheBeginningVersion2() = new FileSet {
256+
source becomes
257+
"""
258+
import org.xml.sax.Attributes
259+
260+
import scala.collection.mutable.HashMap
261+
import scala.collection.mutable.ListBuffer
262+
import scala.io.Source
263+
264+
import java.util.AbstractList
265+
import java.util.BitSet
266+
267+
trait Temp {
268+
// we need some code that use the imports
269+
val x: (ListBuffer[Int], HashMap[String, Int])
270+
val y: (AbstractList[Int], BitSet)
271+
val z: (Attributes, Source)
272+
}
273+
"""
274+
} applyRefactoring organize(List("*", "scala", "java"))
275+
276+
@Test
277+
def defaultGroupInTheBeginningButEmpty() = new FileSet {
278+
source becomes
279+
"""
280+
import org.xml.sax.Attributes
281+
282+
import scala.collection.mutable.HashMap
283+
import scala.collection.mutable.ListBuffer
284+
import scala.io.Source
285+
286+
import java.util.AbstractList
287+
import java.util.BitSet
288+
289+
trait Temp {
290+
// we need some code that use the imports
291+
val x: (ListBuffer[Int], HashMap[String, Int])
292+
val y: (AbstractList[Int], BitSet)
293+
val z: (Attributes, Source)
294+
}
295+
"""
296+
} applyRefactoring organize(List("*", "org", "scala", "java"))
297+
298+
@Test
299+
def noGroupingIsDefaultGrouping() = new FileSet {
300+
source becomes
301+
"""
302+
import java.util.AbstractList
303+
import java.util.BitSet
304+
import org.xml.sax.Attributes
305+
import scala.collection.mutable.HashMap
306+
import scala.collection.mutable.ListBuffer
307+
import scala.io.Source
308+
309+
trait Temp {
310+
// we need some code that use the imports
311+
val x: (ListBuffer[Int], HashMap[String, Int])
312+
val y: (AbstractList[Int], BitSet)
313+
val z: (Attributes, Source)
314+
}
315+
"""
316+
} applyRefactoring organize(List("*"))
317+
318+
@Test
319+
def defaultGroupInTheEndVersion1() = new FileSet {
320+
source becomes
321+
"""
322+
import org.xml.sax.Attributes
323+
324+
import scala.collection.mutable.HashMap
325+
import scala.collection.mutable.ListBuffer
326+
import scala.io.Source
327+
328+
import java.util.AbstractList
329+
import java.util.BitSet
330+
331+
trait Temp {
332+
// we need some code that use the imports
333+
val x: (ListBuffer[Int], HashMap[String, Int])
334+
val y: (AbstractList[Int], BitSet)
335+
val z: (Attributes, Source)
336+
}
337+
"""
338+
} applyRefactoring organize(List("org", "scala", "*"))
339+
340+
@Test
341+
def defaultGroupInTheEndVersion2() = new FileSet {
342+
source becomes
343+
"""
344+
import scala.collection.mutable.HashMap
345+
import scala.collection.mutable.ListBuffer
346+
import scala.io.Source
347+
348+
import java.util.AbstractList
349+
import java.util.BitSet
350+
351+
import org.xml.sax.Attributes
352+
353+
trait Temp {
354+
// we need some code that use the imports
355+
val x: (ListBuffer[Int], HashMap[String, Int])
356+
val y: (AbstractList[Int], BitSet)
357+
val z: (Attributes, Source)
358+
}
359+
"""
360+
} applyRefactoring organize(List("scala", "java", "*"))
361+
362+
@Test
363+
def defaultGroupInTheEndButEmpty() = new FileSet {
364+
source becomes
365+
"""
366+
import org.xml.sax.Attributes
367+
368+
import scala.collection.mutable.HashMap
369+
import scala.collection.mutable.ListBuffer
370+
import scala.io.Source
371+
372+
import java.util.AbstractList
373+
import java.util.BitSet
374+
375+
trait Temp {
376+
// we need some code that use the imports
377+
val x: (ListBuffer[Int], HashMap[String, Int])
378+
val y: (AbstractList[Int], BitSet)
379+
val z: (Attributes, Source)
380+
}
381+
"""
382+
} applyRefactoring organize(List("org", "scala", "java", "*"))
383+
384+
@Test
385+
def mostSpecificTakesPrecedence() = new FileSet {
386+
source becomes
387+
"""
388+
import scala.io.Source
389+
390+
import scala.collection.mutable.HashMap
391+
import scala.collection.mutable.ListBuffer
392+
393+
import java.util.AbstractList
394+
import java.util.BitSet
395+
import org.xml.sax.Attributes
396+
397+
trait Temp {
398+
// we need some code that use the imports
399+
val x: (ListBuffer[Int], HashMap[String, Int])
400+
val y: (AbstractList[Int], BitSet)
401+
val z: (Attributes, Source)
402+
}
403+
"""
404+
} applyRefactoring organize(List("scala", "scala.collection"))
405+
406+
@Test
407+
def fromSpecificToGeneral() = new FileSet {
408+
source becomes
409+
"""
410+
import scala.io.Source
411+
412+
import scala.collection.mutable.HashMap
413+
import scala.collection.mutable.ListBuffer
414+
415+
import java.util.AbstractList
416+
import java.util.BitSet
417+
import org.xml.sax.Attributes
418+
419+
trait Temp {
420+
// we need some code that use the imports
421+
val x: (ListBuffer[Int], HashMap[String, Int])
422+
val y: (AbstractList[Int], BitSet)
423+
val z: (Attributes, Source)
424+
}
425+
"""
426+
} applyRefactoring organize(List("scala.io", "scala"))
164427
}

0 commit comments

Comments
 (0)