summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLex Spoon <lex@lexspoon.org>2008-02-18 21:22:08 +0000
committerLex Spoon <lex@lexspoon.org>2008-02-18 21:22:08 +0000
commit41dc7225084c735f0306e0ebb1a9da0fbd9886ff (patch)
tree071a5737f9f871bc8b5769584cdf5327ada971bc /src
parent1769b68a6d41010aebcd76d240c1a74166a99419 (diff)
downloadscala-41dc7225084c735f0306e0ebb1a9da0fbd9886ff.tar.gz
scala-41dc7225084c735f0306e0ebb1a9da0fbd9886ff.tar.bz2
scala-41dc7225084c735f0306e0ebb1a9da0fbd9886ff.zip
Generalizes the allowed inputs to the interpret...
Generalizes the allowed inputs to the interpreter to be any combination of phrases that can be placed inside a template. Instead of having one "request" object try to understand the entire combination of phrases, the code now uses multiple "member handlers" for each request, one member handler for each phrase.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala512
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
2 files changed, 241 insertions, 272 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index be954205f2..1833ff1065 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -10,6 +10,7 @@ import java.io.{File, PrintWriter, StringWriter, Writer}
import java.lang.{Class, ClassLoader}
import java.net.{URL, URLClassLoader}
+import scala.collection.immutable.ListSet
import scala.collection.mutable
import scala.collection.mutable.{ListBuffer, HashSet, ArrayBuffer}
@@ -78,6 +79,8 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
import compiler.CompilationUnit
import compiler.{Symbol,Name,Type}
import compiler.nme
+ import compiler.newTermName
+ import compiler.nme.{INTERPRETER_VAR_PREFIX, INTERPRETER_SYNTHVAR_PREFIX}
import Interpreter.string2code
/** construct an interpreter that reports to Console */
@@ -181,9 +184,27 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
private def newVarName() = {
val num = nextVarNameNo
nextVarNameNo += 1
- compiler.nme.INTERPRETER_VAR_PREFIX + num
+ INTERPRETER_VAR_PREFIX + num
}
+ /** next internal variable number to use */
+ private var nextInternalVarNo = 0
+
+ /** allocate a fresh internal variable name */
+ private def newInternalVarName() = {
+ val num = nextVarNameNo
+ nextVarNameNo += 1
+ INTERPRETER_SYNTHVAR_PREFIX + num
+ }
+
+
+ /** Check if a name looks like it was generated by newVarName */
+ private def isGeneratedVarName(name: String): Boolean =
+ name.startsWith(INTERPRETER_VAR_PREFIX) && {
+ val suffix = name.drop(INTERPRETER_VAR_PREFIX.length)
+ suffix.forall(_.isDigit)
+ }
+
/** generate a string using a routine that wants to write on a stream */
private def stringFrom(writer: PrintWriter => Unit): String = {
@@ -259,34 +280,31 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
* should be taken. Removes requests which cannot contribute
* useful imports for the specified set of wanted names.
*/
- def reqsToUse: List[Request] = {
- /** Loop through the requests in reverse and select
+ def reqsToUse: List[(Request,MemberHandler)] = {
+ /** Loop through a list of MemberHandlers and select
* which ones to keep. 'wanted' is the set of
* names that need to be imported, and
* 'shadowed' is the list of names useless to import
* because a later request will re-import it anyway.
*/
- def select(reqs: List[Request], wanted: Set[Name]): List[Request] = {
+ def select(reqs: List[(Request,MemberHandler)], wanted: Set[Name]):
+ List[(Request,MemberHandler)] = {
reqs match {
case Nil => Nil
- case req::rest =>
- val keepit = req.definesImplicit || (req match {
- case req:ImportReq =>
- req.importsWildcard ||
- req.importedNames.exists(wanted.contains)
- case _ =>
- req.boundNames.exists(wanted.contains)
- })
+ case (req,handler)::rest =>
+ val keepit =
+ (handler.definesImplicit ||
+ handler.importsWildcard ||
+ handler.importedNames.exists(wanted.contains(_)) ||
+ handler.boundNames.exists(wanted.contains(_)))
val newWanted =
if (keepit) {
- req match {
- case req:ImportReq =>
- wanted -- req.importedNames ++ req.usedNames
-
- case _ => wanted -- req.boundNames
- }
+ (wanted
+ ++ handler.usedNames
+ -- handler.boundNames
+ -- handler.importedNames)
} else {
wanted
}
@@ -294,13 +312,18 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
val restToKeep = select(rest, newWanted)
if(keepit)
- req :: restToKeep
+ (req,handler) :: restToKeep
else
restToKeep
}
}
- select(prevRequests.toList.reverse, wanted).reverse
+ val rhpairs = for {
+ req <- prevRequests.toList.reverse
+ handler <- req.handlers
+ } yield (req, handler)
+
+ select(rhpairs, wanted).reverse
}
val code = new StringBuffer
@@ -321,40 +344,37 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
// loop through previous requests, adding imports
// for each one
- for (req <- reqsToUse) {
- req match {
- case req:ImportReq =>
+ for ((req,handler) <- reqsToUse) {
// If the user entered an import, then just use it
// add an import wrapping level if the import might
// conflict with some other import
- if(req.importsWildcard ||
- currentImps.exists(req.importedNames.contains))
+ if(handler.importsWildcard ||
+ currentImps.exists(handler.importedNames.contains))
if(!currentImps.isEmpty)
addWrapper()
- code.append(req.line + ";\n")
+ if (handler.member.isInstanceOf[Import])
+ code.append(handler.member.toString + ";\n")
// give wildcard imports a import wrapper all to their own
- if(req.importsWildcard)
+ if(handler.importsWildcard)
addWrapper()
else
- currentImps ++= req.importedNames
+ currentImps ++= handler.importedNames
- case req =>
// For other requests, import each bound variable.
// import them explicitly instead of with _, so that
// ambiguity errors will not be generated. Also, quote
// the name of the variable, so that we don't need to
// handle quoting keywords separately.
- for (imv <- req.boundNames) {
+ for (imv <- handler.boundNames) {
if (currentImps.contains(imv))
addWrapper()
code.append("import ")
code.append(req.objectName + req.accessPath + ".`" + imv + "`;\n")
currentImps += imv
}
- }
}
addWrapper() // Add one extra wrapper, to prevent warnings
@@ -411,26 +431,20 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
* after being parsed.
*/
private def buildRequest(trees: List[Tree], line: String, lineName: String): Request =
- trees match {
- /* This case for assignments is more specialized than desirable: it only
- handles assignments to an identifier. It would be better to support
- arbitrary paths being assigned, but that is technically difficult
- because of the way objectSourceCode and resultObjectSourceCode are
- implemented in class Request. */
- case List(Assign(Ident(lhs), _)) =>
- new AssignReq(lhs, line, lineName)
- case _ if trees.forall(t => t.isInstanceOf[ValOrDefDef]) =>
- new DefReq(line, lineName)
- case List(_:TermTree) | List(_:Ident) | List(_:Select) =>
- new ExprReq(line, lineName)
- case List(_:ModuleDef) => new ModuleReq(line, lineName)
- case List(_:ClassDef) => new ClassReq(line, lineName)
- case List(t:TypeDef) if compiler.treeInfo.isAliasTypeDef(t) =>
- new TypeAliasReq(line, lineName)
- case List(_:Import) => new ImportReq(line, lineName)
- case _ =>
- reporter.error(null, "That kind of statement combination is not supported by the interpreter.")
- null
+ new Request(line, lineName)
+
+ private def chooseHandler(member: Tree): Option[MemberHandler] =
+ member match {
+ case member: DefDef =>
+ Some(new DefHandler(member))
+ case member: ValDef =>
+ Some(new ValHandler(member))
+ case member@Assign(Ident(_), _) => Some(new AssignHandler(member))
+ case member: ModuleDef => Some(new ModuleHandler(member))
+ case member: ClassDef => Some(new ClassHandler(member))
+ case member: TypeDef => Some(new TypeAliasHandler(member))
+ case member: Import => Some(new ImportHandler(member))
+ case _ => None
}
/** <p>
@@ -458,6 +472,19 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
case Some(trees) => trees
}
+ trees match {
+ case List(_:Assign) => ()
+
+ case List(_:TermTree) | List(_:Ident) | List(_:Select) =>
+ // Treat a single bare expression specially.
+ // This is necessary due to it being hard to modify
+ // code at a textual level, and it being hard to
+ // submit an AST to the compiler.
+ return interpret("val "+newVarName()+" = \n"+line)
+
+ case _ => ()
+ }
+
val lineName = newLineName
// figure out what kind of request
@@ -472,10 +499,6 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
if (printResults || !succeeded) {
// print the result
out.print(clean(interpreterResultString))
-
- // print out types of functions; they are not printed in the
- // request printout
- out.print(clean(req.defTypesSummary))
}
// book-keeping
@@ -556,94 +579,178 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
- /** One line of code submitted by the user for interpretation */
- private abstract class Request(val line: String, val lineName: String) {
- val trees = parse(line) match {
- case Some(ts) => ts
- case None => Nil
+ /** Class to handle one member among all the members included
+ * in a single interpreter request.
+ */
+ private sealed abstract class MemberHandler(val member: Tree) {
+ val usedNames: List[Name] = {
+ val ivt = new ImportVarsTraverser(boundNames)
+ ivt.traverseTrees(List(member))
+ ivt.importVars.toList
}
+ val boundNames: List[Name] = Nil
+ def valAndVarNames: List[Name] = Nil
+ def defNames: List[Name] = Nil
+ val importsWildcard = false
+ val importedNames: Seq[Name] = Nil
+ val definesImplicit =
+ member match {
+ case tree:MemberDef =>
+ tree.mods.hasFlag(symtab.Flags.IMPLICIT)
+ case _ => false
+ }
- /** name to use for the object that will compute "line" */
- def objectName = lineName + compiler.nme.INTERPRETER_WRAPPER_SUFFIX
+ def extraCodeToEvaluate(req: Request, code: PrintWriter) { }
+ def resultExtractionCode(req: Request, code: PrintWriter) { }
+ }
- /** name of the object that retrieves the result from the above object */
- def resultObjectName = "RequestResult$" + objectName
+ private class ValHandler(member: ValDef) extends MemberHandler(member) {
+ override val boundNames = List(member.name)
+ override def valAndVarNames = boundNames
- /** whether the trees need a variable name, as opposed to standing
- alone */
- val needsVarName: Boolean = false
+ override def resultExtractionCode(req: Request, code: PrintWriter) {
+ val vname = member.name
+ if (member.mods.isPublic &&
+ !(isGeneratedVarName(vname) &&
+ req.typeOf(compiler.encode(vname)) == "Unit"))
+ {
+ code.print(" + \"" + vname + ": " +
+ string2code(req.typeOf(vname)) +
+ " = \" + " +
+ " (if(" +
+ req.fullPath(vname) +
+ ".asInstanceOf[AnyRef] != null) " +
+ " ((if(" +
+ req.fullPath(vname) +
+ ".toString.contains('\\n')) " +
+ " \"\\n\" else \"\") + " +
+ req.fullPath(vname) + ".toString + \"\\n\") else \"null\\n\") ")
+ }
+ }
+ }
- /** A cache for the chosen variable name, if one has been calculated */
- var varNameCache: Option[String] = None
+ private class DefHandler(defDef: DefDef) extends MemberHandler(defDef) {
+ override val boundNames = List(defDef.name)
+ override def defNames = boundNames
- /** A computed variable name, if one is needed */
- def varName = varNameCache match {
- case None =>
- varNameCache = Some(newVarName)
- varNameCache.get
- case Some(name) =>
- name
+ override def resultExtractionCode(req: Request, code: PrintWriter) {
+ if (defDef.mods.isPublic)
+ code.print("+\""+string2code(defDef.name)+": "+
+ string2code(req.typeOf(defDef.name))+"\\n\"")
}
+ }
- /** list of methods defined */
- val defNames =
- for (DefDef(mods, name, _, _, _, _) <- trees if mods.isPublic)
- yield name
+ private class AssignHandler(member: Assign) extends MemberHandler(member) {
+ val lhs = member. lhs.asInstanceOf[Ident] // an unfortunate limitation
- /** list of val's and var's defined */
- val valAndVarNames = {
- val baseNames =
- for (ValDef(mods, name, _, _) <- trees if mods.isPublic)
- yield name
+ val helperName = newTermName(newInternalVarName())
+ override val valAndVarNames = List(helperName)
- if (needsVarName)
- compiler.encode(varName) :: baseNames // add a var name
- else
- baseNames
+ override def extraCodeToEvaluate(req: Request, code: PrintWriter) {
+ code.println("val "+helperName+" = "+member.lhs+";")
}
- /** list of modules defined */
- val moduleNames = {
- val explicit =
- for (ModuleDef(mods, name, _) <- trees if mods.isPublic)
- yield name
- val caseClasses =
- for {val ClassDef(mods, name, _, _) <- trees
- mods.isPublic
- mods.hasFlag(Flags.CASE)}
- yield name.toTermName
- explicit ::: caseClasses
+ /** Print out lhs instead of the generated varName */
+ override def resultExtractionCode(req: Request, code: PrintWriter) {
+ code.print(" + \"" + lhs + ": " +
+ string2code(req.typeOf(compiler.encode(helperName))) +
+ " = \" + " +
+ string2code(req.fullPath(helperName))
+ + " + \"\\n\"")
}
+ }
+
+ private class ModuleHandler(module: ModuleDef) extends MemberHandler(module) {
+ override val boundNames = List(module.name)
- /** list of classes defined */
- val classNames =
- for (ClassDef(mods, name, _, _) <- trees if mods.isPublic)
- yield name
+ override def resultExtractionCode(req: Request, code: PrintWriter) {
+ code.println(" + \"defined module " +
+ string2code(module.name)
+ + "\\n\"")
+ }
+ }
- /** list of type aliases defined */
- val typeNames =
- for (t @ TypeDef(mods, name, _, _) <- trees
- if mods.isPublic && compiler.treeInfo.isAliasTypeDef(t))
- yield name
+ private class ClassHandler(classdef: ClassDef)
+ extends MemberHandler(classdef)
+ {
+ override val boundNames =
+ List(classdef.name) :::
+ (if (classdef.mods.hasFlag(Flags.CASE))
+ List(classdef.name.toTermName)
+ else
+ Nil)
- /** all (public) names defined by these statements */
- val boundNames =
- defNames ::: valAndVarNames ::: moduleNames ::: classNames ::: typeNames
+ // TODO: MemberDef.keyword does not include "trait";
+ // otherwise it could be used here
+ def keyword: String =
+ if (classdef.mods.isTrait) "trait" else "class"
- /** list of names used by this expression */
- val usedNames: List[Name] = {
- val ivt = new ImportVarsTraverser(boundNames)
- ivt.traverseTrees(trees)
- ivt.importVars.toList
+ override def resultExtractionCode(req: Request, code: PrintWriter) {
+ code.print(
+ " + \"defined " +
+ keyword +
+ " " +
+ string2code(classdef.name) +
+ "\\n\"")
}
+ }
+
+ private class TypeAliasHandler(typeDef: TypeDef)
+ extends MemberHandler(typeDef)
+ {
+ override val boundNames =
+ if (typeDef.mods.isPublic && compiler.treeInfo.isAliasTypeDef(typeDef))
+ List(typeDef.name)
+ else
+ Nil
+
+ override def resultExtractionCode(req: Request, code: PrintWriter) {
+ code.println(" + \"defined type alias " +
+ string2code(typeDef.name) + "\\n\"")
+ }
+ }
+
+ private class ImportHandler(imp: Import) extends MemberHandler(imp) {
+ override def resultExtractionCode(req: Request, code: PrintWriter) {
+ code.println("+ \"" + imp.toString + "\\n\"")
+ }
+
+ /** Whether this import includes a wildcard import */
+ override val importsWildcard =
+ imp.selectors.map(_._1).contains(nme.USCOREkw)
+
+ /** The individual names imported by this statement */
+ override val importedNames: Seq[Name] =
+ for {
+ val (_,sel) <- imp.selectors
+ sel != null
+ sel != nme.USCOREkw
+ val name <- List(sel.toTypeName, sel.toTermName)
+ }
+ yield name
+ }
- /** Whether this request defines an implicit. */
- def definesImplicit = trees.exists {
- case tree:MemberDef =>
- tree.mods.hasFlag(symtab.Flags.IMPLICIT)
- case _ => false
+ /** One line of code submitted by the user for interpretation */
+ private class Request(val line: String, val lineName: String) {
+ val trees = parse(line) match {
+ case Some(ts) => ts
+ case None => Nil
}
+ /** name to use for the object that will compute "line" */
+ def objectName = lineName + compiler.nme.INTERPRETER_WRAPPER_SUFFIX
+
+ /** name of the object that retrieves the result from the above object */
+ def resultObjectName = "RequestResult$" + objectName
+
+ val handlers: List[MemberHandler] = trees.flatMap(chooseHandler(_))
+
+ /** all (public) names defined by these statements */
+ val boundNames = (ListSet() ++ handlers.flatMap(_.boundNames)).toList
+
+ /** list of names used by this expression */
+ val usedNames: List[Name] = handlers.flatMap(_.usedNames)
+
def myImportsCode = importsCode(Set.empty ++ usedNames)
/** Code to append to objectName to access anything that
@@ -671,12 +778,10 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
code.print(importsPreamble)
- // the variable to compute, if any
- if (needsVarName)
- code.println(" val " + varName + " = ")
-
code.println(indentCode(toCompute))
+ handlers.foreach(_.extraCodeToEvaluate(this,code))
+
code.println(importsTrailer)
//end the wrapper object
@@ -694,28 +799,13 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
code.println("object " + resultObjectName)
code.println("{ val result: String = {")
code.println(objectName + accessPath + ";") // evaluate the object, to make sure its constructor is run
- code.print("\"\"") // print an initial empty string, so later code can
+ code.print("(\"\"") // print an initial empty string, so later code can
// uniformly be: + morestuff
- resultExtractionCode(code)
- code.println("}")
+ handlers.foreach(_.resultExtractionCode(this, code))
+ code.println("\n)}")
code.println(";}")
})
- def resultExtractionCode(code: PrintWriter) {
- for (vname <- valAndVarNames) {
- code.print(" + \"" + vname + ": " +
- string2code(typeOf(vname)) +
- " = \" + " +
- " (if(" +
- fullPath(vname) +
- ".asInstanceOf[AnyRef] != null) " +
- " ((if(" +
- fullPath(vname) +
- ".toString.contains('\\n')) " +
- " \"\\n\" else \"\") + " +
- fullPath(vname) + ".toString + \"\\n\") else \"null\\n\") ")
- }
- }
/** Compile the object file. Returns whether the compilation succeeded.
* If all goes well, the "types" map is computed. */
@@ -750,11 +840,14 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
* @return ...
*/
def findTypes(objRun: compiler.Run): Map[Name, String] = {
+ def valAndVarNames = handlers.flatMap(_.valAndVarNames)
+ def defNames = handlers.flatMap(_.defNames)
+
def getTypes(names: List[Name], nameMap: Name=>Name): Map[Name, String] = {
/** the outermost wrapper object */
val outerResObjSym: Symbol =
compiler.definitions.getMember(compiler.definitions.EmptyPackage,
- compiler.newTermName(objectName))
+ newTermName(objectName))
/** the innermost object inside the wrapper, found by
* following accessPath into the outer one. */
@@ -762,7 +855,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
(accessPath.split("\\.")).foldLeft(outerResObjSym)((sym,name) =>
if(name == "") sym else
compiler.atPhase(objRun.typerPhase.next) {
- sym.info.member(compiler.newTermName(name)) })
+ sym.info.member(newTermName(name)) })
names.foldLeft(Map.empty[Name,String])((map, name) => {
val rawType =
@@ -802,139 +895,14 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
(stringFrom(str => orig.printStackTrace(str)), false)
}
}
-
- /** return a summary of the defined methods */
- def defTypesSummary: String =
- stringFrom(summ => {
- for (methname <- defNames)
- summ.println("" + methname + ": " +
- string2code(typeOf(methname)))
- })
- }
-
- /** A sequence of definition's. val's, var's, def's. */
- private class DefReq(line: String, lineName: String)
- extends Request(line, lineName)
-
- /** Assignment of a single variable: lhs = exp */
- private class AssignReq(val lhs: Name, line: String, lineName: String)
- extends Request(line, lineName) {
- override val needsVarName = true
-
- /** Perform the assignment, and then return the new value */
- override def toCompute = "{\n" + line + "\n;\n" + lhs + "\n}"
-
- /** Print out lhs instead of the generated varName */
- override def resultExtractionCode(code: PrintWriter) {
- code.print(" + \"" + lhs + ": " +
- string2code(typeOf(compiler.encode(varName))) +
- " = \" + " +
- string2code(fullPath(varName))
- + " + \"\\n\"")
-// override def resultExtractionCode(code: PrintWriter) {
-// {wrapperObj; lhs}
-// }
- }
}
- /** A single expression */
- private class ExprReq(line: String, lineName: String)
- extends Request(line, lineName) {
- override val needsVarName = true
-
- /** Skip the printout if the expression has type Unit */
- override def resultExtractionCode(code: PrintWriter) {
- if (typeOf(compiler.encode(varName)) != "Unit")
- super.resultExtractionCode(code)
- }
- }
-
- /** A module definition */
- private class ModuleReq(line: String, lineName: String)
- extends Request(line, lineName) {
- def moduleName = trees match {
- case List(ModuleDef(_, name, _)) => name
- }
- override def resultExtractionCode(code: PrintWriter) {
- super.resultExtractionCode(code)
- code.println(" + \"defined module " +
- string2code(moduleName)
- + "\\n\"")
- }
- }
-
- /** A class definition */
- private class ClassReq(line: String, lineName: String)
- extends Request(line, lineName) {
- def newClassName = trees match {
- case List(ClassDef(_, name, _, _)) => name
- }
-
- def classdef = trees.head.asInstanceOf[ClassDef]
-
- // TODO: MemberDef.keyword does not include "trait";
- // otherwise it could be used here
- def keyword: String =
- if (classdef.mods.isTrait) "trait" else "class"
-
- override def resultExtractionCode(code: PrintWriter) {
- super.resultExtractionCode(code)
- code.print(
- " + \"defined " +
- keyword +
- " " +
- string2code(newClassName) +
- "\\n\"")
- }
- }
-
- /** a type alias */
- private class TypeAliasReq(line: String, lineName: String)
- extends Request(line, lineName) {
- def newTypeName = trees match {
- case List(TypeDef(_, name, _, _)) => name
- }
-
- override def resultExtractionCode(code: PrintWriter) {
- super.resultExtractionCode(code)
- code.println(" + \"defined type alias " + newTypeName + "\\n\"")
- }
- }
-
- /** an import */
- private class ImportReq(line: String, lineName: String)
- extends Request(line, lineName) {
- override val boundNames = Nil
- override def resultExtractionCode(code: PrintWriter) {
- code.println("+ \"" + trees.head.toString + "\\n\"")
- }
-
- /** Whether this import includes a wildcard import */
- def importsWildcard =
- trees.exists {
- case Import(_, selectors) =>
- selectors.map(_._1).contains(nme.USCOREkw)
- case _ => false
- }
-
- /** The individual names imported by this statement */
- def importedNames: Seq[Name] =
- for {
- val Import(_, selectors) <- trees
- val (_,sel) <- selectors
- sel != null
- sel != nme.USCOREkw
- val name <- List(sel.toTypeName, sel.toTermName)
- }
- yield name
- }
-}
-
class NewLinePrintWriter(out: Writer, autoFlush: Boolean)
extends PrintWriter(out, autoFlush) {
def this(out: Writer) = this(out, false)
override def println() { print("\n"); flush() }
}
+}
/** Utility methods for the Interpreter. */
object Interpreter {
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 70597eb5db..9403280384 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -78,6 +78,7 @@ trait StdNames {
val INTERPRETER_LINE_PREFIX = "line"
val INTERPRETER_VAR_PREFIX = "res"
val INTERPRETER_IMPORT_WRAPPER = "$iw"
+ val INTERPRETER_SYNTHVAR_PREFIX = "synthvar$"
def LOCAL(clazz: Symbol) = newTermName(LOCALDUMMY_PREFIX_STRING + clazz.name+">")
def TUPLE_FIELD(index: Int) = newTermName(TUPLE_FIELD_PREFIX_STRING + index)