@@ -15,7 +15,7 @@ import dotty.tools.dotc.core.StdNames.ScalaTermNames
15
15
*
16
16
* Import transformation is necessary for excluding its members when they are shadowed in the same run.
17
17
* This is done by finding all members defined after the Import clause calculating
18
- * their intersection with available members from selectors
18
+ * their intersection with available members from selectors including renaming.
19
19
*
20
20
* This step is necessary for proper new run initialization since we need to import the previous run
21
21
* into Context. It is accomplished in the following order:
@@ -40,23 +40,38 @@ class CollectTopLevelImports extends Phase {
40
40
/** Transforms top-level imports to exclude intersecting members declared after the Import clause.
41
41
* To properly handle imports such as: `import A.f; def f = 3` consequently making sure that original selectors are
42
42
* filtered to eliminate potential duplications that would result in compilation error.
43
+ *
44
+ * Transformed imports of which selectors were all shadowed will be ignored in the future runs.
43
45
*/
44
46
private def transformTopLevelImports (trees : List [Tree ])(using Context ): List [Import ] =
45
47
val definitions = collectTopLevelMemberDefs(trees)
46
48
47
49
trees.collect {
48
50
case tree @ Import (expr, selectors) =>
49
51
val definitionsAfterImport = definitions.filter(_._2 > tree.endPos.end).map(_._1)
50
- val membersIntersection = expr.tpe.allMembers.map(_.name).intersect(definitionsAfterImport)
51
52
52
- val transformedSelectors = membersIntersection.map(collidingMember => {
53
+ val importedNames : List [Name ] = (if selectors.exists(_.isWildcard) then
54
+ val allImportTypeMembers = expr.tpe.allMembers.map(_.name)
55
+ val renamedMembers = selectors.map(_.imported.name)
56
+ selectors.filter(_.isWildcard).map(_.rename) ++ allImportTypeMembers.filterNot(renamedMembers.contains)
57
+ else
58
+ selectors.map(_.rename)
59
+ )
60
+
61
+ val shadowedMembers = importedNames.intersect(definitionsAfterImport)
62
+ val adjustedSelectors = shadowedMembers.map(collidingMember => {
53
63
untpd.ImportSelector (untpd.Ident (collidingMember), untpd.Ident (CollectTopLevelImports .nme.WILDCARD ))
54
- }).toList
64
+ })
55
65
56
- val filteredSelectors = selectors.filterNot(importSelector => membersIntersection.contains(importSelector.imported.name))
66
+ val remainingSelectors = selectors.filterNot(importSelector => {
67
+ shadowedMembers.contains(importSelector.rename)
68
+ })
57
69
58
- Import (expr, transformedSelectors.toList ::: filteredSelectors)
59
- }
70
+ if remainingSelectors.isEmpty then
71
+ None
72
+ else
73
+ Some (Import (expr, adjustedSelectors ++ remainingSelectors))
74
+ }.flatten
60
75
61
76
private def collectTopLevelMemberDefs (trees : List [Tree ])(using Context ): List [(Name , Int )] =
62
77
trees.collect {
0 commit comments