diff options
author | Paul Phillips <paulp@improving.org> | 2010-05-12 23:11:21 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-05-12 23:11:21 +0000 |
commit | fd5d20d2cf2dbe2e8c66b5d43167cd6fbc90220e (patch) | |
tree | 8f23ad3c30f05b628d7973aee6c0a26dd97b34ec | |
parent | 016d815104b1d44b2b899c68804dde500963fbcd (diff) | |
download | scala-fd5d20d2cf2dbe2e8c66b5d43167cd6fbc90220e.tar.gz scala-fd5d20d2cf2dbe2e8c66b5d43167cd6fbc90220e.tar.bz2 scala-fd5d20d2cf2dbe2e8c66b5d43167cd6fbc90220e.zip |
Notice and fail when a file given with -i is in...
Notice and fail when a file given with -i is incomplete (which under
other conditions in the repl is quite different from not compiling, thus
the bug.) Closes #3011, no review.
-rw-r--r-- | src/compiler/scala/tools/nsc/Interpreter.scala | 33 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/InterpreterLoop.scala | 72 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/MainGenericRunner.scala | 18 |
3 files changed, 66 insertions, 57 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala index 08a1017a57..749ee7bce9 100644 --- a/src/compiler/scala/tools/nsc/Interpreter.scala +++ b/src/compiler/scala/tools/nsc/Interpreter.scala @@ -578,26 +578,27 @@ class Interpreter(val settings: Settings, out: PrintWriter) { */ def interpret(line: String): IR.Result = interpret(line, false) def interpret(line: String, synthetic: Boolean): IR.Result = { - val req = requestFromLine(line, synthetic) match { - case Left(result) => return result - case Right(req) => req - } - // null indicates a disallowed statement type; otherwise compile and - // fail if false (implying e.g. a type error) - if (req == null || !req.compile) - return IR.Error + def loadAndRunReq(req: Request) = { + val (result, succeeded) = req.loadAndRun + if (printResults || !succeeded) + out print clean(result) - val (result, succeeded) = req.loadAndRun - if (printResults || !succeeded) - out print clean(result) + // book-keeping + if (succeeded && !synthetic) + recordRequest(req) - if (succeeded) { - if (!synthetic) - recordRequest(req) // book-keeping + if (succeeded) IR.Success + else IR.Error + } - IR.Success + requestFromLine(line, synthetic) match { + case Left(result) => result + case Right(req) => + // null indicates a disallowed statement type; otherwise compile and + // fail if false (implying e.g. a type error) + if (req == null || !req.compile) IR.Error + else loadAndRunReq(req) } - else IR.Error } /** A name creator used for objects created by <code>bind()</code>. */ diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala index 6124b58219..ce6d3149a3 100644 --- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala +++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala @@ -245,31 +245,18 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite case _ => true } - // this is about the illusion of snappiness. We call initialize() - // which spins off a separate thread, then print the prompt and try - // our best to look ready. Ideally the user will spend a - // couple seconds saying "wow, it starts so fast!" and by the time - // they type a command the compiler is ready to roll. - interpreter.initialize() - while (processLine(readOneLine)) { } } /** interpret all lines from a specified file */ - def interpretAllFrom(filename: String) { - val fileIn = File(filename) - if (!fileIn.exists) - return out.println("Error opening file: " + filename) - + def interpretAllFrom(file: File) { val oldIn = in val oldReplay = replayCommandStack - try { - fileIn applyReader { reader => - in = new SimpleReader(reader, out, false) - plushln("Loading " + filename + "...") - repl - } + try file applyReader { reader => + in = new SimpleReader(reader, out, false) + plushln("Loading " + file + "...") + repl() } finally { in = oldIn @@ -302,8 +289,10 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite List(("stdout", p.stdout), ("stderr", p.stderr)) foreach (add _).tupled } - def withFile(filename: String)(action: String => Unit) { - if (File(filename).exists) action(filename) + def withFile(filename: String)(action: File => Unit) { + val f = File(filename) + + if (f.exists) action(f) else out.println("That file does not exist") } @@ -369,7 +358,7 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite if (!line.startsWith(":")) return Result(true, interpretStartingWith(line)) - val tokens = line.substring(1).split("""\s+""").toList + val tokens = (line drop 1 split """\s+""").toList if (tokens.isEmpty) return withError(ambiguous(commands)) @@ -476,20 +465,25 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite // signal completion non-completion input has been received in.completion foreach (_.resetVerbosity()) - def reallyInterpret = { - interpreter.interpret(code) match { - case IR.Error => None - case IR.Success => Some(code) - case IR.Incomplete => - if (in.interactive && code.endsWith("\n\n")) { - out.println("You typed two blank lines. Starting a new command.") + def reallyInterpret = interpreter.interpret(code) match { + case IR.Error => None + case IR.Success => Some(code) + case IR.Incomplete => + if (in.interactive && code.endsWith("\n\n")) { + out.println("You typed two blank lines. Starting a new command.") + None + } + else in.readLine(CONTINUATION_STRING) match { + case null => + // we know compilation is going to fail since we're at EOF and the + // parser thinks the input is still incomplete, but since this is + // a file being read non-interactively we want to fail. So we send + // it straight to the compiler for the nice error message. + interpreter.compileString(code) None - } - else in.readLine(CONTINUATION_STRING) match { - case null => None // end of file - case line => interpretStartingWith(code + "\n" + line) - } - } + + case line => interpretStartingWith(code + "\n" + line) + } } /** Here we place ourselves between the user and the interpreter and examine @@ -551,8 +545,16 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite if (interpreter.reporter.hasErrors) return printWelcome() + + // this is about the illusion of snappiness. We call initialize() + // which spins off a separate thread, then print the prompt and try + // our best to look ready. Ideally the user will spend a + // couple seconds saying "wow, it starts so fast!" and by the time + // they type a command the compiler is ready to roll. + interpreter.initialize() repl() - } finally closeInterpreter() + } + finally closeInterpreter() } private def objClass(x: Any) = x.asInstanceOf[AnyRef].getClass diff --git a/src/compiler/scala/tools/nsc/MainGenericRunner.scala b/src/compiler/scala/tools/nsc/MainGenericRunner.scala index 79503a83b4..936ee3c1db 100644 --- a/src/compiler/scala/tools/nsc/MainGenericRunner.scala +++ b/src/compiler/scala/tools/nsc/MainGenericRunner.scala @@ -38,14 +38,23 @@ object MainGenericRunner { else if (settings.version.value) return errorFn("Scala code runner %s -- %s".format(versionString, copyrightString)) else if (command.shouldStopWithInfo) return errorFn(command getInfoMessage sampleCompiler) + def isE = !settings.execute.isDefault def dashe = settings.execute.value + + def isI = !settings.loadfiles.isDefault def dashi = settings.loadfiles.value - def slurp = dashi map (file => File(file).slurp()) mkString "\n" + + def combinedCode = { + val files = if (isI) dashi map (file => File(file).slurp()) else Nil + val str = if (isE) List(dashe) else Nil + + files ++ str mkString "\n\n" + } val classpath: List[URL] = new PathResolver(settings) asURLs /** Was code given in a -e argument? */ - if (!settings.execute.isDefault) { + if (isE) { /** If a -i argument was also given, we want to execute the code after the * files have been included, so they are read into strings and prepended to * the code given in -e. The -i option is documented to only make sense @@ -54,11 +63,8 @@ object MainGenericRunner { * This all needs a rewrite though. */ val fullArgs = command.thingToRun.toList ::: command.arguments - val code = - if (settings.loadfiles.isDefault) dashe - else slurp + "\n" + dashe - exitCond(ScriptRunner.runCommand(settings, code, fullArgs)) + exitCond(ScriptRunner.runCommand(settings, combinedCode, fullArgs)) } else command.thingToRun match { case None => |