Skip to content

Commit 179452b

Browse files
committed
IDE: Generate fewer duplicates with imports
1 parent c61e8f2 commit 179452b

File tree

2 files changed

+48
-23
lines changed

2 files changed

+48
-23
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,10 +1157,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11571157
*/
11581158
def importedSymbols(expr: Tree, name: Name)(implicit ctx: Context): List[Symbol] = {
11591159
def lookup(name: Name): Symbol = expr.tpe.member(name).symbol
1160-
List(lookup(name.toTermName),
1161-
lookup(name.toTypeName),
1162-
lookup(name.moduleClassName),
1163-
lookup(name.sourceModuleName))
1160+
val symbols =
1161+
List(lookup(name.toTermName),
1162+
lookup(name.toTypeName),
1163+
lookup(name.moduleClassName),
1164+
lookup(name.sourceModuleName))
1165+
1166+
symbols.map(_.sourceSymbol).filter(_.exists).distinct
11641167
}
11651168

11661169
/**
@@ -1174,38 +1177,59 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
11741177
def importedSymbols(imp: Import,
11751178
selectorPredicate: untpd.Tree => Boolean = util.common.alwaysTrue)
11761179
(implicit ctx: Context): List[Symbol] = {
1177-
val symbols = imp.selectors.find(selectorPredicate) match {
1180+
imp.selectors.find(selectorPredicate) match {
11781181
case Some(id: untpd.Ident) =>
11791182
importedSymbols(imp.expr, id.name)
11801183
case Some(Thicket((id: untpd.Ident) :: (_: untpd.Ident) :: Nil)) =>
11811184
importedSymbols(imp.expr, id.name)
11821185
case _ =>
11831186
Nil
11841187
}
1185-
1186-
symbols.map(_.sourceSymbol).filter(_.exists).distinct
11871188
}
11881189

1190+
/**
1191+
* The list of select trees that resolve to the same symbols as the ones that are imported
1192+
* by `imp`.
1193+
*/
11891194
def importSelections(imp: Import)(implicit ctx: Context): List[Select] = {
1190-
val imported =
1191-
imp.selectors.flatMap {
1192-
case id: untpd.Ident =>
1193-
importedSymbols(imp.expr, id.name).map((_, id, None))
1194-
case Thicket((id: untpd.Ident) :: (newName: untpd.Ident) :: Nil) =>
1195-
val renaming = Some(newName)
1196-
importedSymbols(imp.expr, id.name).map((_, id, renaming))
1195+
def imported(sym: Symbol, id: untpd.Ident, rename: Option[untpd.Ident]): List[Select] = {
1196+
val noPosExpr = focusPositions(imp.expr)
1197+
val selectTree = Select(noPosExpr, sym.name).withPos(id.pos)
1198+
rename match {
1199+
case None =>
1200+
selectTree :: Nil
1201+
case Some(rename) =>
1202+
// Get the type of the symbol that is actually selected, and construct a select
1203+
// node with the new name and the type of the real symbol.
1204+
val name = if (sym.name.isTypeName) rename.name.toTypeName else rename.name
1205+
val actual = Select(noPosExpr, sym.name)
1206+
val renameTree = Select(noPosExpr, name).withPos(rename.pos).withType(actual.tpe)
1207+
selectTree :: renameTree :: Nil
11971208
}
1198-
imported.flatMap { case (symbol, name, rename) =>
1199-
val tree = Select(imp.expr, symbol.name).withPos(name.pos)
1200-
val renameTree = rename.map { r =>
1201-
// Get the type of the symbol that is actually selected, and construct a select
1202-
// node with the new name and the type of the real symbol.
1203-
val name = if (symbol.name.isTypeName) r.name.toTypeName else r.name
1204-
val actual = Select(imp.expr, symbol.name)
1205-
Select(imp.expr, name).withPos(r.pos).withType(actual.tpe)
1209+
}
1210+
1211+
imp.selectors.flatMap {
1212+
case Ident(nme.WILDCARD) =>
1213+
Nil
1214+
case id: untpd.Ident =>
1215+
importedSymbols(imp.expr, id.name).flatMap { sym =>
1216+
imported(sym, id, None)
1217+
}
1218+
case Thicket((id: untpd.Ident) :: (newName: untpd.Ident) :: Nil) =>
1219+
importedSymbols(imp.expr, id.name).flatMap { sym =>
1220+
imported(sym, id, Some(newName))
1221+
}
1222+
}
1223+
}
1224+
1225+
/** Replaces all positions in `tree` with zero-extent positions */
1226+
private def focusPositions(tree: Tree)(implicit ctx: Context): Tree = {
1227+
val transformer = new tpd.TreeMap {
1228+
override def transform(tree: Tree)(implicit ctx: Context): Tree = {
1229+
super.transform(tree).withPos(tree.pos.focus)
12061230
}
1207-
tree :: renameTree.toList
12081231
}
1232+
transformer.transform(tree)
12091233
}
12101234
}
12111235

compiler/src/dotty/tools/dotc/interactive/Interactive.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ object Interactive {
310310
case imp: untpd.Import if includeImports && tree.hasType =>
311311
val tree = imp.asInstanceOf[tpd.Import]
312312
val selections = tpd.importSelections(tree)
313+
traverse(imp.expr)
313314
selections.foreach(traverse)
314315
case utree: untpd.NameTree if tree.hasType =>
315316
val tree = utree.asInstanceOf[tpd.NameTree]

0 commit comments

Comments
 (0)