diff options
Diffstat (limited to 'test/files/presentation/t8941b/IdempotencyTest.scala')
-rw-r--r-- | test/files/presentation/t8941b/IdempotencyTest.scala | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/test/files/presentation/t8941b/IdempotencyTest.scala b/test/files/presentation/t8941b/IdempotencyTest.scala new file mode 100644 index 0000000000..af01b36898 --- /dev/null +++ b/test/files/presentation/t8941b/IdempotencyTest.scala @@ -0,0 +1,73 @@ +package scala.tools.nsc +package interactive +package tests.core + +import reporters.{Reporter => CompilerReporter} +import scala.tools.nsc.interactive.InteractiveReporter +import scala.reflect.internal.util.SourceFile + +/** Determistically interrupts typechecking of `code` when a defintion named + * `MagicInterruptionMarker` is typechecked, and then performs a targetted + * typecheck of the tree at the specal comment marker marker + */ +abstract class IdempotencyTest { self => + private val settings = new Settings + settings.usejavacp.value = true + + private object Break extends scala.util.control.ControlThrowable + + private val compilerReporter: CompilerReporter = new InteractiveReporter { + override def compiler = self.compiler + } + + object compiler extends Global(settings, compilerReporter) { + override def checkForMoreWork(pos: Position) { + } + override def signalDone(context: Context, old: Tree, result: Tree) { + // println("signalDone: " + old.toString.take(50).replaceAll("\n", "\\n")) + if (!interrupted && analyzer.lockedCount == 0 && interruptsEnabled && shouldInterrupt(result)) { + interrupted = true + val typed = typedTreeAt(markerPosition) + checkTypedTree(typed) + throw Break + } + super.signalDone(context, old, result) + } + + // we're driving manually using our own thread, disable the check here. + override def assertCorrectThread() {} + } + + import compiler._ + + private var interrupted = false + + // Extension points + protected def code: String + protected def shouldInterrupt(tree: Tree): Boolean = { + tree.symbol != null && tree.symbol.name.toString == "MagicInterruptionMarker" + } + protected def checkTypedTree(tree: Tree): Unit = {} + + + private val source: SourceFile = newSourceFile(code) + private def markerPosition: Position = source.position(code.indexOf("/*?*/")) + + def assertNoProblems() { + val problems = getUnit(source).get.problems + assert(problems.isEmpty, problems.mkString("\n")) + } + + def show() { + reloadSource(source) + try { + typedTree(source, true) + assert(false, "Expected to break out of typechecking.") + } catch { + case Break => // expected + } + assertNoProblems() + } + + def main(args: Array[String]) { show() } +} |