From a6ba30b8eb1968979db92d3a006d57343983e684 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 1 Apr 2011 17:18:34 +0000 Subject: Finding myself wanting a working -Ystop, I did ... Finding myself wanting a working -Ystop, I did the following. -Ystop-after:phase works -Ystop-before:phase works -Ystop:phase is a backward compat alias for -Ystop-after Until now -Ystop, although documented to "stop after phase", actually stopped before phase, to the consternation of some. Furthermore the programmatic way to influence the stop phase (protected def stopPhase in Global#Run) involved returning true if you wanted to stop before the phase. So now the command line option works as advertised, and the method has the same semantics. The only potential loser is some script which uses -Ystop: based on the actual behavior rather than the documented behavior. Well, someone had to lose. No review. --- src/compiler/scala/tools/nsc/Global.scala | 17 +++++++++++++++-- .../scala/tools/nsc/settings/ScalaSettings.scala | 5 ++++- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 40d8bd5c82..2e2f9c1ad7 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -661,8 +661,21 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable /** To be initialized from firstPhase. */ private var terminalPhase: Phase = NoPhase - /** Whether compilation should stop at or skip the phase with given name. */ - protected def stopPhase(name: String) = settings.stop contains name + // Calculate where to stop based on settings -Ystop-before or -Ystop-after. + // Slightly complicated logic due to wanting -Ystop-before:parser to fail rather + // than mysteriously running to completion. + private lazy val stopPhaseSetting = { + val result = phaseDescriptors sliding 2 collectFirst { + case xs if xs exists (settings.stopBefore contains _.phaseName) => if (settings.stopBefore contains xs.head.phaseName) xs.head else xs.last + case xs if settings.stopAfter contains xs.head.phaseName => xs.last + } + if (result exists (_.phaseName == "parser")) + globalError("Cannot stop before parser phase.") + + result + } + // The phase to stop BEFORE running. + protected def stopPhase(name: String) = stopPhaseSetting exists (_.phaseName == name) protected def skipPhase(name: String) = settings.skip contains name /** As definitions.init requires phase != NoPhase, and calling phaseDescriptors.head diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index c1067cbde9..f0d819538e 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -128,7 +128,8 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { val Ynosqueeze = BooleanSetting ("-Yno-squeeze", "Disable creation of compact code in matching.") val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") . withPostSetHook(set => util.Statistics.enabled = set.value) - val stop = PhasesSetting ("-Ystop", "Stop after phase") + val stopAfter = PhasesSetting ("-Ystop-after", "Stop after given phase") withAbbreviation ("-stop") // backward compat + val stopBefore = PhasesSetting ("-Ystop-before", "Stop before given phase") val refinementMethodDispatch = ChoiceSetting ("-Ystruct-dispatch", "policy", "structural method dispatch policy", List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache") @@ -154,6 +155,8 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { val exposeEmptyPackage = BooleanSetting("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly() + def stop = stopAfter + /** * Warnings */ -- cgit v1.2.3