@@ -5,7 +5,7 @@ import dotty.tools.dotc.ast.untpd
55import dotty .tools .dotc .core .Contexts ._
66import dotty .tools .dotc .core .Names .Name
77import dotty .tools .dotc .core .Phases .Phase
8- import dotty .tools .dotc .core .StdNames .ScalaTermNames
8+ import dotty .tools .dotc .core .StdNames .nme
99
1010
1111/** This phase collects and transforms top-level Import trees to handle definition shadowing.
@@ -15,7 +15,7 @@ import dotty.tools.dotc.core.StdNames.ScalaTermNames
1515 *
1616 * Import transformation is necessary for excluding its members when they are shadowed in the same run.
1717 * 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.
1919 *
2020 * This step is necessary for proper new run initialization since we need to import the previous run
2121 * into Context. It is accomplished in the following order:
@@ -40,23 +40,39 @@ class CollectTopLevelImports extends Phase {
4040 /** Transforms top-level imports to exclude intersecting members declared after the Import clause.
4141 * To properly handle imports such as: `import A.f; def f = 3` consequently making sure that original selectors are
4242 * 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.
4345 */
4446 private def transformTopLevelImports (trees : List [Tree ])(using Context ): List [Import ] =
4547 val definitions = collectTopLevelMemberDefs(trees)
4648
4749 trees.collect {
4850 case tree @ Import (expr, selectors) =>
4951 val definitionsAfterImport = definitions.filter(_._2 > tree.endPos.end).map(_._1)
50- val membersIntersection = expr.tpe.allMembers.map(_.name).intersect(definitionsAfterImport)
5152
52- val transformedSelectors = membersIntersection.map(collidingMember => {
53- untpd.ImportSelector (untpd.Ident (collidingMember), untpd.Ident (CollectTopLevelImports .nme.WILDCARD ))
54- }).toList
55-
56- val filteredSelectors = selectors.filterNot(importSelector => membersIntersection.contains(importSelector.imported.name))
57-
58- Import (expr, transformedSelectors.toList ::: filteredSelectors)
59- }
53+ val importedNames : List [Name ] = (if selectors.exists(_.isWildcard) then
54+ val allImportTypeMembers = expr.tpe.allMembers.map(_.name)
55+ val nonWildcardSelectors = selectors.filter(_.isWildcard)
56+ val renamedMembers = nonWildcardSelectors.map(_.imported.name)
57+ nonWildcardSelectors.map(_.rename) ++ allImportTypeMembers.filterNot(renamedMembers.contains)
58+ else
59+ selectors.map(_.rename)
60+ )
61+
62+ val shadowedMembers = importedNames.intersect(definitionsAfterImport)
63+ val adjustedSelectors = shadowedMembers.map(collidingMember => {
64+ untpd.ImportSelector (untpd.Ident (collidingMember), untpd.Ident (nme.WILDCARD ))
65+ })
66+
67+ val remainingSelectors = selectors.filterNot(importSelector => {
68+ shadowedMembers.contains(importSelector.rename)
69+ })
70+
71+ if remainingSelectors.isEmpty then
72+ None
73+ else
74+ Some (Import (expr, adjustedSelectors ++ remainingSelectors))
75+ }.flatten
6076
6177 private def collectTopLevelMemberDefs (trees : List [Tree ])(using Context ): List [(Name , Int )] =
6278 trees.collect {
@@ -67,7 +83,3 @@ class CollectTopLevelImports extends Phase {
6783
6884}
6985
70- object CollectTopLevelImports {
71- private lazy val nme : ScalaTermNames = new ScalaTermNames
72- }
73-
0 commit comments