From 6c59d99c5e1efcd5dae0cd5fb7ecf4fe7cba7408 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Sun, 12 Dec 2010 01:50:17 +0000 Subject: Finally figured out what needed to happen for import scala.`package`.Throwable not to break the repl. Closes #3673, no review. --- src/compiler/scala/tools/nsc/Interpreter.scala | 41 ++++++++++++---------- .../scala/tools/nsc/ast/TreePrinters.scala | 22 +++++++++--- .../scala/tools/nsc/ast/parser/Scanners.scala | 2 +- src/compiler/scala/tools/nsc/symtab/StdNames.scala | 13 ++++++- 4 files changed, 53 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index 4a502f0068..96c2900776 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -151,7 +151,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { import compiler.{ Traverser, CompilationUnit, Symbol, Name, Type, TypeRef, PolyType } import compiler.{ Tree, TermTree, ValOrDefDef, ValDef, DefDef, Assign, ClassDef, - ModuleDef, Ident, Select, TypeDef, Import, MemberDef, DocDef, + ModuleDef, Ident, BackQuotedIdent, Select, TypeDef, Import, MemberDef, DocDef, ImportSelector, EmptyTree, NoType } import compiler.{ opt, nme, newTermName, newTypeName } import nme.{ @@ -244,7 +244,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { /** the previous requests this interpreter has processed */ private val prevRequests = new ArrayBuffer[Request]() - private val usedNameMap = new mutable.HashMap[Name, Request]() + private val referencedNameMap = new mutable.HashMap[Name, Request]() private val boundNameMap = new mutable.HashMap[Name, Request]() private def allHandlers = prevRequests.toList flatMap (_.handlers) private def allReqAndHandlers = prevRequests.toList flatMap (req => req.handlers map (req -> _)) @@ -283,7 +283,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { } prevRequests += req - req.usedNames foreach (x => usedNameMap(x) = req) + req.referencedNames foreach (x => referencedNameMap(x) = req) req.boundNames foreach { name => if (boundNameMap contains name) { @@ -299,12 +299,12 @@ class Interpreter(val settings: Settings, out: PrintWriter) { quietBind("settings", "scala.tools.nsc.InterpreterSettings", isettings) // println("\n s1 = %s\n s2 = %s\n s3 = %s".format( - // tripart(usedNameMap.keysIterator.toSet, boundNameMap.keysIterator.toSet): _* + // tripart(referencedNameMap.keysIterator.toSet, boundNameMap.keysIterator.toSet): _* // )) } private def keyList[T](x: collection.Map[T, _]): List[T] = x.keys.toList sortBy (_.toString) - def allUsedNames = keyList(usedNameMap) + def allreferencedNames = keyList(referencedNameMap) def allBoundNames = keyList(boundNameMap) def allSeenTypes = prevRequests.toList flatMap (_.typeOf.values.toList) distinct def allDefinedTypes = prevRequests.toList flatMap (_.definedTypes.values.toList) distinct @@ -435,16 +435,16 @@ class Interpreter(val settings: Settings, out: PrintWriter) { case rh :: rest => val importedNames = rh.handler match { case x: ImportHandler => x.importedNames ; case _ => Nil } import rh.handler._ - val newWanted = wanted ++ usedNames -- boundNames -- importedNames + val newWanted = wanted ++ referencedNames -- boundNames -- importedNames rh :: select(rest, newWanted) } } /** Flatten the handlers out and pair each with the original request */ - select(allReqAndHandlers reverseMap { case (r, h) => ReqAndHandler(r, h) }, wanted).reverse + select(allReqAndHandlers reverseMap { case (r, h) => ReqAndHandler(r, h) }, wanted).reverse } - val code, trailingBraces, accessPath = new StringBuffer + val code, trailingBraces, accessPath = new StringBuilder val currentImps = mutable.HashSet[Name]() // add code for a new object to hold some imports @@ -688,10 +688,12 @@ class Interpreter(val settings: Settings, out: PrintWriter) { val importVars = new mutable.HashSet[Name]() override def traverse(ast: Tree) = ast match { - // XXX this is obviously inadequate but it's going to require some effort - // to get right. - case Ident(name) if !(name.toString startsWith "x$") => importVars += name - case _ => super.traverse(ast) + case Ident(name) => + // XXX this is obviously inadequate but it's going to require some effort + // to get right. + if (name.toString startsWith "x$") () + else importVars += name + case _ => super.traverse(ast) } } @@ -699,7 +701,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { * in a single interpreter request. */ private sealed abstract class MemberHandler(val member: Tree) { - lazy val usedNames: List[Name] = { + lazy val referencedNames: List[Name] = { val ivt = new ImportVarsTraverser() ivt traverse member ivt.importVars.toList @@ -713,7 +715,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { def extraCodeToEvaluate(req: Request, code: PrintWriter) { } def resultExtractionCode(req: Request, code: PrintWriter) { } - override def toString = "%s(used = %s)".format(this.getClass.toString split '.' last, usedNames) + override def toString = "%s(used = %s)".format(this.getClass.toString split '.' last, referencedNames) } private class GenericHandler(member: Tree) extends MemberHandler(member) @@ -799,7 +801,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { } private class ImportHandler(imp: Import) extends MemberHandler(imp) { - lazy val Import(expr, selectors) = imp + val Import(expr, selectors) = imp def targetType = stringToCompilerType(expr.toString) match { case NoType => None case x => Some(x) @@ -824,8 +826,9 @@ class Interpreter(val settings: Settings, out: PrintWriter) { val importedNames: List[Name] = selectorRenames filterNot (_ == USCOREkw) flatMap (_.bothNames) - override def resultExtractionCode(req: Request, code: PrintWriter) = + override def resultExtractionCode(req: Request, code: PrintWriter) = { code println codegenln(imp.toString) + } } /** One line of code submitted by the user for interpretation */ @@ -847,7 +850,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { val boundNames = handlers flatMap (_.boundNames) /** list of names used by this expression */ - val usedNames: List[Name] = handlers flatMap (_.usedNames) + val referencedNames: List[Name] = handlers flatMap (_.referencedNames) /** def and val names */ def defNames = partialFlatMap(handlers) { case x: DefHandler => x.boundNames } @@ -866,7 +869,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { * append to objectName to access anything bound by request. */ val ComputedImports(importsPreamble, importsTrailer, accessPath) = - importsCode(Set.empty ++ usedNames) + importsCode(Set.empty ++ referencedNames) /** Code to access a variable with the specified name */ def fullPath(vname: String): String = "%s.`%s`".format(objectName + accessPath, vname) @@ -1089,7 +1092,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) { def mkType(id: String): compiler.Type = stringToCompilerType(id) def dump(): String = ( - ("Names used: " :: allUsedNames) ++ + ("Names used: " :: allreferencedNames) ++ ("\nIdentifiers: " :: unqualifiedIds) ) mkString " " diff --git a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala index 9f2b8b4cbd..8d36bae609 100644 --- a/src/compiler/scala/tools/nsc/ast/TreePrinters.scala +++ b/src/compiler/scala/tools/nsc/ast/TreePrinters.scala @@ -17,6 +17,20 @@ trait TreePrinters { trees: SymbolTable => final val showOuterTests = false + /** Adds backticks if the name is a scala keyword. */ + def quotedName(name: Name): String = + if (nme.keywords(name.toTermName)) "`%s`" format name + else name.toString + + /** Turns a path into a String, introducing backquotes + * as necessary. + */ + def backquotedPath(t: Tree): String = t match { + case Select(qual, name) => "%s.%s".format(backquotedPath(qual), quotedName(name)) + case Ident(name) => quotedName(name) + case t => t.toString + } + class TreePrinter(out: PrintWriter) extends trees.AbsTreePrinter(out) { protected var indentMargin = 0 protected val indentStep = 2 @@ -102,7 +116,7 @@ trait TreePrinters { trees: SymbolTable => private def ifSym(tree: Tree, p: Symbol => Boolean) = symFn(tree, p, false) private def symNameInternal(tree: Tree, name: Name, decoded: Boolean): String = { - val nameToString: Name => String = if (decoded) _.decode else _.toString + val nameToString: Name => String = if (decoded) _.decode else quotedName def nameFn(sym: Symbol) = { val prefix = if (sym.isMixinConstructor) "/*%s*/".format(nameToString(sym.owner.name)) else "" prefix + tree.symbol.nameString @@ -206,9 +220,9 @@ trait TreePrinters { trees: SymbolTable => // Is this selector remapping a name (i.e, {name1 => name2}) def isNotRemap(s: ImportSelector) : Boolean = (s.name == nme.WILDCARD || s.name == s.rename) def selectorToString(s: ImportSelector): String = - if (isNotRemap(s)) s.name.toString else s.name.toString + "=>" + s.rename.toString + if (isNotRemap(s)) s.name.toString else s.name + "=>" + s.rename - print("import "); print(expr) + print("import "); print(backquotedPath(expr)) print(".") selectors match { case List(s) => @@ -337,7 +351,7 @@ trait TreePrinters { trees: SymbolTable => print(qual) case Select(qualifier, name) => - print(qualifier); print("."); print(symName(tree, name)) + print(backquotedPath(qualifier)); print("."); print(symName(tree, name)) case Ident(name) => print(symName(tree, name)) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 3322a5a28f..7dac7466b0 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -9,7 +9,7 @@ import scala.tools.nsc.util._ import Chars._ import Tokens._ import scala.annotation.switch -import scala.collection.mutable.{ListBuffer, ArrayBuffer} +import scala.collection.mutable.{ ListBuffer, ArrayBuffer } import scala.xml.Utility.{ isNameStart } /** See Parsers.scala / ParsersCommon for some explanation of ScannersCommon. diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala index 49009ece39..dabc55b462 100644 --- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala +++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala @@ -274,6 +274,18 @@ trait StdNames extends reflect.generic.StdNames with NameManglers { type NameType = TermName implicit def createNameType(name: String): TermName = newTermName(name) + final val keywords = Set[TermName]( + ABSTRACTkw, CASEkw, CLASSkw, CATCHkw, DEFkw, DOkw, ELSEkw, + EXTENDSkw, FALSEkw, FINALkw, FINALLYkw, FORkw, FORSOMEkw, IFkw, + IMPLICITkw, IMPORTkw, LAZYkw, MATCHkw, NEWkw, NULLkw, OBJECTkw, + OVERRIDEkw, PACKAGEkw, PRIVATEkw, PROTECTEDkw, RETURNkw, REQUIRESkw, + SEALEDkw, SUPERkw, THISkw, THROWkw, TRAITkw, TRUEkw, TRYkw, TYPEkw, + VALkw, VARkw, WITHkw, WHILEkw, YIELDkw + ) ++ Set[TermName]( + DOTkw, USCOREkw, COLONkw, EQUALSkw, ARROWkw, LARROWkw, SUBTYPEkw, + VIEWBOUNDkw, SUPERTYPEkw, HASHkw, ATkw + ) + /** Translate a String into a list of simple TypeNames and TermNames. * In all segments before the last, type/term is determined by whether * the following separator char is '.' or '#'. In the last segment, @@ -309,7 +321,6 @@ trait StdNames extends reflect.generic.StdNames with NameManglers { mkName(simple, div == '.') :: segments(rest, assumeTerm) } } - private def bitmapName(n: Int, suffix: String): TermName = newTermName(BITMAP_PREFIX + suffix + n) -- cgit v1.2.3