@@ -13,6 +13,7 @@ import config.SourceVersion
1313import StdNames .nme
1414import printing .Texts .Text
1515import ProtoTypes .NoViewsAllowed .normalizedCompatible
16+ import NameKinds .QualifiedName
1617import Decorators ._
1718
1819object ImportInfo {
@@ -45,7 +46,7 @@ object ImportInfo {
4546}
4647
4748/** Info relating to an import clause
48- * @param sym The import symbol defined by the clause
49+ * @param symf A function that computes the import symbol defined by the clause
4950 * @param selectors The selector clauses
5051 * @param qualifier The import qualifier, or EmptyTree for root imports.
5152 * Defined for all explicit imports from ident or select nodes.
@@ -62,7 +63,7 @@ class ImportInfo(symf: Context ?=> Symbol,
6263 case _ => None
6364 }
6465
65- def sym (using Context ): Symbol = {
66+ def importSym (using Context ): Symbol = {
6667 if (mySym == null ) {
6768 mySym = symf
6869 assert(mySym != null )
@@ -72,7 +73,7 @@ class ImportInfo(symf: Context ?=> Symbol,
7273 private var mySym : Symbol = _
7374
7475 /** The (TermRef) type of the qualifier of the import clause */
75- def site (using Context ): Type = sym .info match {
76+ def site (using Context ): Type = importSym .info match {
7677 case ImportType (expr) => expr.tpe
7778 case _ => NoType
7879 }
@@ -185,27 +186,46 @@ class ImportInfo(symf: Context ?=> Symbol,
185186
186187 private var myUnimported : Symbol = _
187188
188- private var myOwner : Symbol = null
189- private var myResults : SimpleIdentityMap [TermName , java.lang.Boolean ] = SimpleIdentityMap .empty
190-
191- /** Does this import clause or a preceding import clause import `owner.feature`? */
192- def featureImported (feature : TermName , owner : Symbol )(using Context ): Boolean =
193-
194- def compute : Boolean =
195- if isLanguageImport then
196- val isImportOwner = site.typeSymbol.eq(owner)
197- if isImportOwner then
198- if forwardMapping.contains(feature) then return true
199- if excluded.contains(feature) then return false
200- var c = ctx.outer
201- while c.importInfo eq ctx.importInfo do c = c.outer
202- (c.importInfo != null ) && c.importInfo.featureImported(feature, owner)(using c)
203-
204- if myOwner.ne(owner) || ! myResults.contains(feature) then
205- myOwner = owner
206- myResults = myResults.updated(feature, compute)
207- myResults(feature)
208- end featureImported
189+ private var featureCache : SimpleIdentityMap [TermName , java.lang.Boolean ] = SimpleIdentityMap .empty
190+
191+ /** Does this import clause or a preceding import clause enable or disable `feature`?
192+ * @param feature See featureImported for a description
193+ * @return Some(true) if `feature` is imported
194+ * Some(false) if `feature` is excluded
195+ * None if `feature` is not mentioned, or this is not a language import
196+ */
197+ def mentionsFeature (feature : TermName )(using Context ): Option [Boolean ] =
198+ def test (prefix : TermName , feature : TermName ): Option [Boolean ] =
199+ untpd.languageImport(qualifier) match
200+ case Some (`prefix`) =>
201+ if forwardMapping.contains(feature) then Some (true )
202+ else if excluded.contains(feature) then Some (false )
203+ else None
204+ case _ => None
205+ feature match
206+ case QualifiedName (prefix, name) => test(prefix, name)
207+ case _ => test(EmptyTermName , feature)
208+
209+ /** Does this import clause or a preceding import clause enable `feature`?
210+ *
211+ * @param feature a possibly quailified name, e.g.
212+ * strictEquality
213+ * experimental.genericNumberLiterals
214+ *
215+ * An excluded feature such as `strictEquality => _` in a language import
216+ * means that preceding imports are not considered and the feature is not imported.
217+ */
218+ def featureImported (feature : TermName )(using Context ): Boolean =
219+ if ! featureCache.contains(feature) then
220+ featureCache = featureCache.updated(feature,
221+ mentionsFeature(feature) match
222+ case Some (bv) => bv
223+ case None =>
224+ var c = ctx.outer
225+ while c.importInfo eq ctx.importInfo do c = c.outer
226+ (c.importInfo != null ) && c.importInfo.featureImported(feature)(using c)
227+ )
228+ featureCache(feature)
209229
210230 def toText (printer : Printer ): Text = printer.toText(this )
211231}
0 commit comments