@@ -10,6 +10,8 @@ import util.SimpleIdentityMap
1010import Symbols ._ , Names ._ , Types ._ , Contexts ._ , StdNames ._ , Flags ._
1111import Implicits .RenamedImplicitRef
1212import printing .Texts .Text
13+ import ProtoTypes .NoViewsAllowed .normalizedCompatible
14+ import Decorators ._
1315
1416object ImportInfo {
1517 /** The import info for a root import from given symbol `sym` */
@@ -55,62 +57,87 @@ class ImportInfo(symf: Context => Symbol, val selectors: List[untpd.Tree],
5557 /** The names that are excluded from any wildcard import */
5658 def excluded : Set [TermName ] = { ensureInitialized(); myExcluded }
5759
58- /** A mapping from renamed to original names */
59- def reverseMapping : SimpleIdentityMap [TermName , TermName ] = { ensureInitialized(); myMapped }
60+ /** A mapping from original to renamed names */
61+ def forwardMapping : SimpleIdentityMap [TermName , TermName ] = { ensureInitialized(); myForwardMapping }
6062
61- /** The original names imported by-name before renaming */
62- def originals : Set [TermName ] = { ensureInitialized(); myOriginals }
63+ /** A mapping from renamed to original names */
64+ def reverseMapping : SimpleIdentityMap [TermName , TermName ] = { ensureInitialized(); myReverseMapping }
6365
6466 /** Does the import clause end with wildcard? */
6567 def isWildcardImport : Boolean = { ensureInitialized(); myWildcardImport }
6668
6769 private [this ] var myExcluded : Set [TermName ] = null
68- private [this ] var myMapped : SimpleIdentityMap [TermName , TermName ] = null
69- private [this ] var myOriginals : Set [ TermName ] = null
70+ private [this ] var myForwardMapping : SimpleIdentityMap [TermName , TermName ] = null
71+ private [this ] var myReverseMapping : SimpleIdentityMap [ TermName , TermName ] = null
7072 private [this ] var myWildcardImport : Boolean = false
7173
7274 /** Compute info relating to the selector list */
7375 private def ensureInitialized (): Unit = if (myExcluded == null ) {
7476 myExcluded = Set ()
75- myMapped = SimpleIdentityMap .Empty
76- myOriginals = Set ()
77+ myForwardMapping = SimpleIdentityMap .Empty
78+ myReverseMapping = SimpleIdentityMap . Empty
7779 def recur (sels : List [untpd.Tree ]): Unit = sels match {
7880 case sel :: sels1 =>
7981 sel match {
8082 case Thicket (Ident (name : TermName ) :: Ident (nme.WILDCARD ) :: Nil ) =>
8183 myExcluded += name
8284 case Thicket (Ident (from : TermName ) :: Ident (to : TermName ) :: Nil ) =>
83- myMapped = myMapped.updated(to, from)
85+ myForwardMapping = myForwardMapping.updated(from, to)
86+ myReverseMapping = myReverseMapping.updated(to, from)
8487 myExcluded += from
85- myOriginals += from
8688 case Ident (nme.WILDCARD ) =>
8789 myWildcardImport = true
8890 case Ident (name : TermName ) =>
89- myMapped = myMapped.updated(name, name)
90- myOriginals += name
91+ myForwardMapping = myForwardMapping.updated(name, name)
92+ myReverseMapping = myReverseMapping.updated(name, name)
93+ case TypeBoundsTree (_, tpt) =>
94+ myWildcardImport = true // details are handled separately in impliedBounds
9195 }
9296 recur(sels1)
9397 case nil =>
9498 }
9599 recur(selectors)
96100 }
97101
102+ private [this ] var myImpliedBound : Type = null
103+
104+ def impliedBound (implicit ctx : Context ): Type = {
105+ if (myImpliedBound == null )
106+ myImpliedBound = selectors.lastOption match {
107+ case Some (TypeBoundsTree (_, untpd.TypedSplice (tpt))) => tpt.tpe
108+ case Some (TypeBoundsTree (_, tpt)) =>
109+ myImpliedBound = NoType
110+ ctx.typer.typedAheadType(tpt).tpe
111+ case _ => NoType
112+ }
113+ myImpliedBound
114+ }
115+
98116 private def implicitFlag (implicit ctx : Context ) =
99117 if (importImplied || ctx.mode.is(Mode .FindHiddenImplicits )) ImplicitOrImpliedOrGiven
100118 else Implicit
101119
102120 /** The implicit references imported by this import clause */
103121 def importedImplicits (implicit ctx : Context ): List [ImplicitRef ] = {
104122 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 {
123+ if (isWildcardImport)
124+ pre.implicitMembers(implicitFlag).flatMap { ref =>
125+ val name = ref.name.toTermName
126+ if (excluded.contains(name)) Nil
127+ else {
128+ val renamed = forwardMapping(ref.name)
129+ if (renamed == ref.name) ref :: Nil
130+ else if (renamed != null ) new RenamedImplicitRef (ref, renamed) :: Nil
131+ else if (! impliedBound.exists ||
132+ normalizedCompatible(ref, impliedBound, keepConstraint = false )) ref :: Nil
133+ else Nil
134+ }
135+ }
136+ else
137+ for
111138 renamed <- reverseMapping.keys
112139 denot <- pre.member(reverseMapping(renamed)).altsWith(_ is implicitFlag)
113- } yield {
140+ yield {
114141 val original = reverseMapping(renamed)
115142 val ref = TermRef (pre, original, denot)
116143 if (renamed == original) ref
@@ -149,7 +176,7 @@ class ImportInfo(symf: Context => Symbol, val selectors: List[untpd.Tree],
149176 def featureImported (feature : TermName , owner : Symbol )(implicit ctx : Context ): Boolean = {
150177 def compute = {
151178 val isImportOwner = site.widen.typeSymbol.eq(owner)
152- if (isImportOwner && originals .contains(feature)) true
179+ if (isImportOwner && forwardMapping .contains(feature)) true
153180 else if (isImportOwner && excluded.contains(feature)) false
154181 else {
155182 var c = ctx.outer
0 commit comments