diff options
author | Paul Phillips <paulp@improving.org> | 2011-05-07 06:54:53 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-05-07 06:54:53 +0000 |
commit | b72a9b1455f8f462192f0a6eb3a7544e7600505a (patch) | |
tree | 802af9c6687290397830f7f3bd6eeaf8a2517c2a /src | |
parent | 6b58c8522dfcebc267a24588d7f67def13ebc7d1 (diff) | |
download | scala-b72a9b1455f8f462192f0a6eb3a7544e7600505a.tar.gz scala-b72a9b1455f8f462192f0a6eb3a7544e7600505a.tar.bz2 scala-b72a9b1455f8f462192f0a6eb3a7544e7600505a.zip |
Made -Yno-predef work again, also in the repl.
do I import" code to notice _root_.scala.Predef too. Moved some of the
overly specialized, called-only-once functions in treeInfo inside the
one function which needs them. References #1931. No review.
Diffstat (limited to 'src')
6 files changed, 57 insertions, 47 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index 8a6f26c9b1..5184ebad19 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -318,38 +318,45 @@ abstract class TreeInfo { EmptyTree } - /** Top-level definition sequence contains a leading import of - * <code>Predef</code> or <code>scala.Predef</code>. + /** Is the tree Predef, scala.Predef, or _root_.scala.Predef? */ - def containsLeadingPredefImport(defs: List[Tree]): Boolean = defs match { - case List(PackageDef(_, defs1)) => - containsLeadingPredefImport(defs1) - case Import(Ident(nme.Predef), _) :: _ => - true - case Import(Select(Ident(nme.scala_), nme.Predef), _) :: _ => - true - case Import(_, _) :: defs1 => - containsLeadingPredefImport(defs1) - case _ => - false + def isPredefExpr(t: Tree) = t match { + case Ident(nme.Predef) => true + case Select(Ident(nme.scala_), nme.Predef) => true + case Select(Select(Ident(nme.ROOTPKG), nme.scala_), nme.Predef) => true + case _ => false } - /** Compilation unit is class or object 'name' in package 'scala' + /** Is this file the body of a compilation unit which should not + * have Predef imported? */ - def isUnitInScala(tree: Tree, name: Name) = tree match { - case PackageDef(Ident(nme.scala_), defs) => isImplDef(defs, name) - case _ => false - } + def noPredefImportForUnit(body: Tree) = { + // Top-level definition whose leading imports include Predef. + def containsLeadingPredefImport(defs: List[Tree]): Boolean = defs match { + case PackageDef(_, defs1) :: _ => containsLeadingPredefImport(defs1) + case Import(expr, _) :: rest => isPredefExpr(expr) || containsLeadingPredefImport(rest) + case _ => false + } + def isImplDef(trees: List[Tree], name: Name): Boolean = trees match { + case Import(_, _) :: xs => isImplDef(xs, name) + case DocDef(_, tree1) :: Nil => isImplDef(List(tree1), name) + case Annotated(_, tree1) :: Nil => isImplDef(List(tree1), name) + case ModuleDef(_, `name`, _) :: Nil => true + case ClassDef(_, `name`, _, _) :: Nil => true + case _ => false + } + // Compilation unit is class or object 'name' in package 'scala' + def isUnitInScala(tree: Tree, name: Name) = tree match { + case PackageDef(Ident(nme.scala_), defs) => isImplDef(defs, name) + case _ => false + } - private def isImplDef(trees: List[Tree], name: Name): Boolean = trees match { - case Import(_, _) :: xs => isImplDef(xs, name) - case DocDef(_, tree1) :: Nil => isImplDef(List(tree1), name) - case Annotated(_, tree1) :: Nil => isImplDef(List(tree1), name) - case ModuleDef(_, `name`, _) :: Nil => true - case ClassDef(_, `name`, _, _) :: Nil => true - case _ => false + ( isUnitInScala(body, nme.Predef) + || isUnitInScala(body, tpnme.ScalaObject) + || containsLeadingPredefImport(List(body))) } + def isAbsTypeDef(tree: Tree) = tree match { case TypeDef(_, _, _, TypeBoundsTree(_, _)) => true case TypeDef(_, _, _, rhs) => rhs.tpe.isInstanceOf[TypeBounds] diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index fd8926ddc5..8f6cd049bd 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -112,7 +112,7 @@ class IMain(val settings: Settings, protected val out: PrintWriter) extends Impo private def _initialize(): Boolean = { val source = """ |class $repl_$init { - | List(1) map (_ + 1) + | scala.collection.immutable.List(1) map (_ + 1) |} |""".stripMargin diff --git a/src/compiler/scala/tools/nsc/interpreter/Imports.scala b/src/compiler/scala/tools/nsc/interpreter/Imports.scala index b2706330e7..df8c1e7851 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Imports.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Imports.scala @@ -15,6 +15,9 @@ trait Imports { import definitions.{ ScalaPackage, JavaLangPackage, PredefModule } import memberHandlers._ + def isNoImports = settings.noimports.value + def isNoPredef = settings.nopredef.value + /** Synthetic import handlers for the language defined imports. */ private def makeWildcardImportHandler(sym: Symbol): ImportHandler = { val hd :: tl = sym.fullName.split('.').toList map newTermName @@ -88,7 +91,7 @@ trait Imports { * 2. A code fragment that should go after the code * of the new request. * - * 3. An access path which can be traverested to access + * 3. An access path which can be traversed to access * any bindings inside code wrapped by #1 and #2 . * * The argument is a set of Names that need to be imported. diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala index 330294f823..e4921bd898 100644 --- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala @@ -172,6 +172,10 @@ trait MemberHandlers { class ImportHandler(imp: Import) extends MemberHandler(imp) { val Import(expr, selectors) = imp def targetType = intp.typeOfExpression("" + expr) + // TODO: Need to track these specially to honor Predef masking attempts, + // because they must be the leading imports in the code generated for each + // line. We can use the same machinery as Contexts now, anyway. + def isPredefImport = treeInfo.isPredefExpr(expr) // wildcard imports, e.g. import foo._ private def selectorWild = selectors filter (_.name == nme.USCOREkw) diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index a92b5d7034..921abd6795 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -113,9 +113,8 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { val log = PhasesSetting ("-Ylog", "Log operations during") val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.") val Ynogenericsig = BooleanSetting ("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.") - val noimports = BooleanSetting ("-Yno-imports", "Compile without any implicit imports.") - // Not actually doing anything, so disabled. - // val nopredefs = BooleanSetting ("-Yno-predefs", "Compile without any implicit predefined values.") + val noimports = BooleanSetting ("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.") + val nopredef = BooleanSetting ("-Yno-predef", "Compile without importing Predef.") val Yprofile = PhasesSetting ("-Yprofile", "(Requires jvm -agentpath to contain yjgpagent) Profile CPU usage of given phases.") val YprofileMem = BooleanSetting ("-Yprofile-memory", "Profile memory, get heap snapshot after each compiler run (requires yjpagent, see above).") val YprofileClass = StringSetting ("-Yprofile-class", "class", "Name of profiler class.", "scala.tools.util.YourkitProfiling") diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 96d81d63a8..ee35cfa267 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -34,26 +34,23 @@ trait Contexts { self: Analyzer => var lastAccessCheckDetails: String = "" - /** List of objects and packages to import from in - * a root context. This list is sensitive to the - * compiler settings. + /** List of symbols to import from in a root context. Typically that + * is java.lang, scala, and scala.Predef, in that order. Exceptions: + * + * -- if -Yno-imports is given, nothing is imported + * -- if the unit is java defined, only java.lang is imported + * -- if -Yno-predef is given, if the unit has an import of Predef + * among its leading imports, or if the unit is scala.ScalaObject + * or scala.Predef, Predef is not imported. */ protected def rootImports(unit: CompilationUnit, tree: Tree): List[Symbol] = { import definitions._ - val imps = new ListBuffer[Symbol] - if (!settings.noimports.value) { - assert(isDefinitionsInitialized) - imps += JavaLangPackage - if (!unit.isJava) { - assert(ScalaPackage ne null, "Scala package is null") - imps += ScalaPackage - if (!(treeInfo.isUnitInScala(unit.body, nme.Predef) || - treeInfo.isUnitInScala(unit.body, tpnme.ScalaObject) || - treeInfo.containsLeadingPredefImport(List(unit.body)))) - imps += PredefModule - } - } - imps.toList + assert(isDefinitionsInitialized, "definitions uninitialized") + + if (settings.noimports.value) Nil + else if (unit.isJava) List(JavaLangPackage) + else if (settings.nopredef.value || treeInfo.noPredefImportForUnit(unit.body)) List(JavaLangPackage, ScalaPackage) + else List(JavaLangPackage, ScalaPackage, PredefModule) } def rootContext(unit: CompilationUnit): Context = |