From 8a61ff432543a29234193cd1f7c14abd3f3d31a0 Mon Sep 17 00:00:00 2001 From: Felix Mulder Date: Wed, 2 Nov 2016 11:08:28 +0100 Subject: Move compiler and compiler tests to compiler dir --- .../src/dotty/tools/dotc/typer/ImportInfo.scala | 117 +++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 compiler/src/dotty/tools/dotc/typer/ImportInfo.scala (limited to 'compiler/src/dotty/tools/dotc/typer/ImportInfo.scala') diff --git a/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala new file mode 100644 index 000000000..3aa289181 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/typer/ImportInfo.scala @@ -0,0 +1,117 @@ +package dotty.tools +package dotc +package typer + +import ast.{tpd, untpd} +import ast.Trees._ +import core._ +import util.SimpleMap +import Symbols._, Names._, Denotations._, Types._, Contexts._, StdNames._, Flags._ +import Decorators.StringInterpolators + +object ImportInfo { + /** The import info for a root import from given symbol `sym` */ + def rootImport(refFn: () => TermRef)(implicit ctx: Context) = { + val selectors = untpd.Ident(nme.WILDCARD) :: Nil + def expr = tpd.Ident(refFn()) + def imp = tpd.Import(expr, selectors) + new ImportInfo(imp.symbol, selectors, isRootImport = true) + } +} + +/** Info relating to an import clause + * @param sym The import symbol defined by the clause + * @param selectors The selector clauses + * @param rootImport true if this is one of the implicit imports of scala, java.lang + * or Predef in the start context, false otherwise. + */ +class ImportInfo(symf: => Symbol, val selectors: List[untpd.Tree], val isRootImport: Boolean = false)(implicit ctx: Context) { + + lazy val sym = symf + + /** The (TermRef) type of the qualifier of the import clause */ + def site(implicit ctx: Context): Type = { + val ImportType(expr) = sym.info + expr.tpe + } + + /** The names that are excluded from any wildcard import */ + def excluded: Set[TermName] = { ensureInitialized(); myExcluded } + + /** A mapping from renamed to original names */ + def reverseMapping: SimpleMap[TermName, TermName] = { ensureInitialized(); myMapped } + + /** The original names imported by-name before renaming */ + def originals: Set[TermName] = { ensureInitialized(); myOriginals } + + /** Does the import clause end with wildcard? */ + def isWildcardImport = { ensureInitialized(); myWildcardImport } + + private var myExcluded: Set[TermName] = null + private var myMapped: SimpleMap[TermName, TermName] = null + private var myOriginals: Set[TermName] = null + private var myWildcardImport: Boolean = false + + /** Compute info relating to the selector list */ + private def ensureInitialized(): Unit = if (myExcluded == null) { + myExcluded = Set() + myMapped = SimpleMap.Empty + myOriginals = Set() + def recur(sels: List[untpd.Tree]): Unit = sels match { + case sel :: sels1 => + sel match { + case Thicket(Ident(name: TermName) :: Ident(nme.WILDCARD) :: Nil) => + myExcluded += name + case Thicket(Ident(from: TermName) :: Ident(to: TermName) :: Nil) => + myMapped = myMapped.updated(to, from) + myExcluded += from + myOriginals += from + case Ident(nme.WILDCARD) => + myWildcardImport = true + case Ident(name: TermName) => + myMapped = myMapped.updated(name, name) + myOriginals += name + } + recur(sels1) + case nil => + } + recur(selectors) + } + + /** The implicit references imported by this import clause */ + def importedImplicits: List[TermRef] = { + val pre = site + if (isWildcardImport) { + val refs = pre.implicitMembers + if (excluded.isEmpty) refs + else refs filterNot (ref => excluded contains ref.name.toTermName) + } else + for { + renamed <- reverseMapping.keys + denot <- pre.member(reverseMapping(renamed)).altsWith(_ is Implicit) + } yield TermRef.withSigAndDenot(pre, renamed, denot.signature, denot) + } + + /** The root import symbol hidden by this symbol, or NoSymbol if no such symbol is hidden. + * Note: this computation needs to work even for un-initialized import infos, and + * is not allowed to force initialization. + */ + lazy val hiddenRoot: Symbol = { + val sym = site.termSymbol + def hasMaskingSelector = selectors exists { + case Thicket(_ :: Ident(nme.WILDCARD) :: Nil) => true + case _ => false + } + if ((defn.RootImportTypes exists (_.symbol == sym)) && hasMaskingSelector) sym else NoSymbol + } + + override def toString = { + val siteStr = site.show + val exprStr = if (siteStr endsWith ".type") siteStr dropRight 5 else siteStr + val selectorStr = selectors match { + case Ident(name) :: Nil => name.show + case _ => "{...}" + } + i"import $exprStr.$selectorStr" + } +} -- cgit v1.2.3