@@ -10,6 +10,7 @@ import util.SimpleIdentityMap
1010import Symbols ._ , Names ._ , Types ._ , Contexts ._ , StdNames ._ , Flags ._
1111import Implicits .RenamedImplicitRef
1212import printing .Texts .Text
13+ import Decorators ._
1314
1415object ImportInfo {
1516 /** The import info for a root import from given symbol `sym` */
@@ -55,62 +56,86 @@ class ImportInfo(symf: Context => Symbol, val selectors: List[untpd.Tree],
5556 /** The names that are excluded from any wildcard import */
5657 def excluded : Set [TermName ] = { ensureInitialized(); myExcluded }
5758
58- /** A mapping from renamed to original names */
59- def reverseMapping : SimpleIdentityMap [TermName , TermName ] = { ensureInitialized(); myMapped }
59+ /** A mapping from original to renamed names */
60+ def forwardMapping : SimpleIdentityMap [TermName , TermName ] = { ensureInitialized(); myForwardMapping }
6061
61- /** The original names imported by-name before renaming */
62- def originals : Set [TermName ] = { ensureInitialized(); myOriginals }
62+ /** A mapping from renamed to original names */
63+ def reverseMapping : SimpleIdentityMap [TermName , TermName ] = { ensureInitialized(); myReverseMapping }
6364
6465 /** Does the import clause end with wildcard? */
6566 def isWildcardImport : Boolean = { ensureInitialized(); myWildcardImport }
6667
6768 private [this ] var myExcluded : Set [TermName ] = null
68- private [this ] var myMapped : SimpleIdentityMap [TermName , TermName ] = null
69- private [this ] var myOriginals : Set [ TermName ] = null
69+ private [this ] var myForwardMapping : SimpleIdentityMap [TermName , TermName ] = null
70+ private [this ] var myReverseMapping : SimpleIdentityMap [ TermName , TermName ] = null
7071 private [this ] var myWildcardImport : Boolean = false
7172
7273 /** Compute info relating to the selector list */
7374 private def ensureInitialized (): Unit = if (myExcluded == null ) {
7475 myExcluded = Set ()
75- myMapped = SimpleIdentityMap .Empty
76- myOriginals = Set ()
76+ myForwardMapping = SimpleIdentityMap .Empty
77+ myReverseMapping = SimpleIdentityMap . Empty
7778 def recur (sels : List [untpd.Tree ]): Unit = sels match {
7879 case sel :: sels1 =>
7980 sel match {
8081 case Thicket (Ident (name : TermName ) :: Ident (nme.WILDCARD ) :: Nil ) =>
8182 myExcluded += name
8283 case Thicket (Ident (from : TermName ) :: Ident (to : TermName ) :: Nil ) =>
83- myMapped = myMapped.updated(to, from)
84+ myForwardMapping = myForwardMapping.updated(from, to)
85+ myReverseMapping = myReverseMapping.updated(to, from)
8486 myExcluded += from
85- myOriginals += from
8687 case Ident (nme.WILDCARD ) =>
8788 myWildcardImport = true
8889 case Ident (name : TermName ) =>
89- myMapped = myMapped.updated(name, name)
90- myOriginals += name
90+ myForwardMapping = myForwardMapping.updated(name, name)
91+ myReverseMapping = myReverseMapping.updated(name, name)
92+ case TypeBoundsTree (_, tpt) =>
93+ myWildcardImport = true // details are handled separately in impliedBounds
9194 }
9295 recur(sels1)
9396 case nil =>
9497 }
9598 recur(selectors)
9699 }
97100
101+ private [this ] var myImpliedBound : Type = null
102+
103+ def impliedBound (implicit ctx : Context ): Type = {
104+ if (myImpliedBound == null )
105+ myImpliedBound = selectors.lastOption match {
106+ case Some (TypeBoundsTree (_, untpd.TypedSplice (tpt))) => tpt.tpe
107+ case Some (TypeBoundsTree (_, tpt)) =>
108+ myImpliedBound = NoType
109+ ctx.typer.typedAheadType(tpt).tpe
110+ case _ => NoType
111+ }
112+ myImpliedBound
113+ }
114+
98115 private def implicitFlag (implicit ctx : Context ) =
99116 if (importImplied || ctx.mode.is(Mode .FindHiddenImplicits )) ImplicitOrImpliedOrGiven
100117 else Implicit
101118
102119 /** The implicit references imported by this import clause */
103120 def importedImplicits (implicit ctx : Context ): List [ImplicitRef ] = {
104121 val pre = site
105- if (isWildcardImport) {
106- val refs = pre.implicitMembers(implicitFlag)
107- if (excluded.isEmpty) refs
108- else refs filterNot (ref => excluded contains ref.name.toTermName)
109- } else
110- for {
122+ if (isWildcardImport)
123+ pre.implicitMembers(implicitFlag).flatMap { ref =>
124+ val name = ref.name.toTermName
125+ if (excluded.contains(name)) Nil
126+ else {
127+ val renamed = forwardMapping(ref.name)
128+ if (renamed == ref.name) ref :: Nil
129+ else if (renamed != null ) new RenamedImplicitRef (ref, renamed) :: Nil
130+ else if (! impliedBound.exists || (ref <:< impliedBound)) ref :: Nil
131+ else Nil
132+ }
133+ }
134+ else
135+ for
111136 renamed <- reverseMapping.keys
112137 denot <- pre.member(reverseMapping(renamed)).altsWith(_ is implicitFlag)
113- } yield {
138+ yield {
114139 val original = reverseMapping(renamed)
115140 val ref = TermRef (pre, original, denot)
116141 if (renamed == original) ref
@@ -149,7 +174,7 @@ class ImportInfo(symf: Context => Symbol, val selectors: List[untpd.Tree],
149174 def featureImported (feature : TermName , owner : Symbol )(implicit ctx : Context ): Boolean = {
150175 def compute = {
151176 val isImportOwner = site.widen.typeSymbol.eq(owner)
152- if (isImportOwner && originals .contains(feature)) true
177+ if (isImportOwner && forwardMapping .contains(feature)) true
153178 else if (isImportOwner && excluded.contains(feature)) false
154179 else {
155180 var c = ctx.outer
0 commit comments