diff options
author | Clemens Winter <clemenswinter1@gmail.com> | 2016-07-29 16:58:30 +0200 |
---|---|---|
committer | Clemens Winter <clemenswinter1@gmail.com> | 2016-08-02 14:42:33 +0200 |
commit | 17ba94221e4e120c1442b5611f8f339c0f642c65 (patch) | |
tree | 7b8db4f015db4e97f278864b10a259bee32999f1 /src | |
parent | 765aecbe3ca4e05c987dde4e868dca08c7585666 (diff) | |
download | dotty-17ba94221e4e120c1442b5611f8f339c0f642c65.tar.gz dotty-17ba94221e4e120c1442b5611f8f339c0f642c65.tar.bz2 dotty-17ba94221e4e120c1442b5611f8f339c0f642c65.zip |
Fix #1372: Add handler for `PatDef`s to REPL
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/ast/untpd.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/repl/CompilingInterpreter.scala | 79 |
2 files changed, 63 insertions, 21 deletions
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala index b3f8747dc..1fdfed0f4 100644 --- a/src/dotty/tools/dotc/ast/untpd.scala +++ b/src/dotty/tools/dotc/ast/untpd.scala @@ -447,6 +447,11 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { } } + /** Fold `f` over all tree nodes, in depth-first, prefix order */ + class UntypedDeepFolder[X](f: (X, Tree) => X) extends UntypedTreeAccumulator[X] { + def apply(x: X, tree: Tree)(implicit ctx: Context): X = foldOver(f(x, tree), tree) + } + override def rename(tree: NameTree, newName: Name)(implicit ctx: Context): tree.ThisTree[Untyped] = tree match { case t: PolyTypeDef => cpy.PolyTypeDef(t)(newName.asTypeName, t.tparams, t.rhs).asInstanceOf[tree.ThisTree[Untyped]] diff --git a/src/dotty/tools/dotc/repl/CompilingInterpreter.scala b/src/dotty/tools/dotc/repl/CompilingInterpreter.scala index e05ecb328..163bbea16 100644 --- a/src/dotty/tools/dotc/repl/CompilingInterpreter.scala +++ b/src/dotty/tools/dotc/repl/CompilingInterpreter.scala @@ -222,7 +222,7 @@ class CompilingInterpreter( if (delayOutput) previousOutput ++= resultStrings.map(clean) else if (printResults || !succeeded) - resultStrings.map(x => out.print(clean(x))) + resultStrings.foreach(x => out.print(clean(x))) if (succeeded) { prevRequests += req Interpreter.Success @@ -328,6 +328,7 @@ class CompilingInterpreter( private def chooseHandler(stat: Tree): StatementHandler = stat match { case stat: DefDef => new DefHandler(stat) case stat: ValDef => new ValHandler(stat) + case stat: PatDef => new PatHandler(stat) case stat @ Assign(Ident(_), _) => new AssignHandler(stat) case stat: ModuleDef => new ModuleHandler(stat) case stat: TypeDef if stat.isClassDef => new ClassHandler(stat) @@ -662,29 +663,65 @@ class CompilingInterpreter( private class GenericHandler(statement: Tree) extends StatementHandler(statement) - private class ValHandler(statement: ValDef) extends StatementHandler(statement) { - override val boundNames = List(statement.name) + private abstract class ValOrPatHandler(statement: Tree) + extends StatementHandler(statement) { + override val boundNames: List[Name] = _boundNames override def valAndVarNames = boundNames override def resultExtractionCode(req: Request, code: PrintWriter): Unit = { - val vname = statement.name - if (!statement.mods.is(Flags.AccessFlags) && - !(isGeneratedVarName(vname.toString) && - req.typeOf(vname.encode) == "Unit")) { - val prettyName = vname.decode - code.print(" + \"" + prettyName + ": " + - 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\") ") - } + if (!shouldShowResult(req)) return + val resultExtractors = boundNames.map(name => resultExtractor(req, name)) + code.print(resultExtractors.mkString("")) + } + + private def resultExtractor(req: Request, varName: Name): String = { + val prettyName = varName.decode + val varType = string2code(req.typeOf(varName)) + val fullPath = req.fullPath(varName) + + s""" + "$prettyName: $varType = " + { + | if ($fullPath.asInstanceOf[AnyRef] != null) { + | (if ($fullPath.toString().contains('\\n')) "\\n" else "") + + | $fullPath.toString() + "\\n" + | } else { + | "null\\n" + | } + |}""".stripMargin } + + protected def _boundNames: List[Name] + protected def shouldShowResult(req: Request): Boolean + } + + private class ValHandler(statement: ValDef) extends ValOrPatHandler(statement) { + override def _boundNames = List(statement.name) + + override def shouldShowResult(req: Request): Boolean = + !statement.mods.is(Flags.AccessFlags) && + !(isGeneratedVarName(statement.name.toString) && + req.typeOf(statement.name.encode) == "Unit") + } + + + private class PatHandler(statement: PatDef) extends ValOrPatHandler(statement) { + override def _boundNames = statement.pats.flatMap(findVariableNames) + + override def shouldShowResult(req: Request): Boolean = + !statement.mods.is(Flags.AccessFlags) + + private def findVariableNames(tree: Tree): List[Name] = tree match { + case Ident(name) if name.toString != "_" => List(name) + case _ => VariableNameFinder(Nil, tree).reverse + } + + private object VariableNameFinder extends UntypedDeepFolder[List[Name]]( + (acc: List[Name], t: Tree) => t match { + case _: BackquotedIdent => acc + case Ident(name) if name.isVariableName && name.toString != "_" => name :: acc + case Bind(name, _) if name.isVariableName => name :: acc + case _ => acc + } + ) } private class DefHandler(defDef: DefDef) extends StatementHandler(defDef) { @@ -836,7 +873,7 @@ class CompilingInterpreter( val stringWriter = new StringWriter() val stream = new NewLinePrintWriter(stringWriter) writer(stream) - stream.close + stream.close() stringWriter.toString } |