diff --git a/compiler/src/dotty/tools/dotc/reporting/trace.scala b/compiler/src/dotty/tools/dotc/reporting/trace.scala index eda7ebe16f97..821f9ac6c85a 100644 --- a/compiler/src/dotty/tools/dotc/reporting/trace.scala +++ b/compiler/src/dotty/tools/dotc/reporting/trace.scala @@ -7,7 +7,23 @@ import config.Config import config.Printers import core.Mode -object trace { +/** Exposes the {{{ trace("question") { op } }}} syntax. + * + * Traced operations will print indented messages if enabled. + * Tracing depends on [[Config.tracingEnabled]] and [[dotty.tools.dotc.config.ScalaSettings.Ylog]]. + * Tracing can be forced by replacing [[trace]] with [[trace.force]] (see below). + */ +object trace extends TraceSyntax { + final val isForced = false + + /** Forces a particular trace to be printed out regardless of tracing being enabled. */ + object force extends TraceSyntax { + final val isForced = true + } +} + +abstract class TraceSyntax { + val isForced: Boolean @forceInline def onDebug[TD](question: => String)(op: => TD)(implicit ctx: Context): TD = @@ -15,7 +31,7 @@ object trace { @forceInline def conditionally[TC](cond: Boolean, question: => String, show: Boolean)(op: => TC)(implicit ctx: Context): TC = - if (Config.tracingEnabled) { + if (isForced || Config.tracingEnabled) { def op1 = op if (cond) apply[TC](question, Printers.default, show)(op1) else op1 @@ -23,18 +39,18 @@ object trace { @forceInline def apply[T](question: => String, printer: Printers.Printer, showOp: Any => String)(op: => T)(implicit ctx: Context): T = - if (Config.tracingEnabled) { + if (isForced || Config.tracingEnabled) { def op1 = op - if (printer.eq(config.Printers.noPrinter)) op1 + if (!isForced && printer.eq(config.Printers.noPrinter)) op1 else doTrace[T](question, printer, showOp)(op1) } else op @forceInline def apply[T](question: => String, printer: Printers.Printer, show: Boolean)(op: => T)(implicit ctx: Context): T = - if (Config.tracingEnabled) { + if (isForced || Config.tracingEnabled) { def op1 = op - if (printer.eq(config.Printers.noPrinter)) op1 + if (!isForced && printer.eq(config.Printers.noPrinter)) op1 else doTrace[T](question, printer, if (show) showShowable(_) else alwaysToString)(op1) } else op @@ -68,20 +84,27 @@ object trace { apply[T](s"==> $q?", (res: Any) => s"<== $q = ${showOp(res)}")(op) } - def apply[T](leading: => String, trailing: Any => String)(op: => T)(implicit ctx: Context): T = + def apply[T](leading: => String, trailing: Any => String)(op: => T)(implicit ctx: Context): T = { + val log: String => Unit = if (isForced) Console.println else { + var logctx = ctx + while (logctx.reporter.isInstanceOf[StoreReporter]) logctx = logctx.outer + logctx.log(_) + } + doApply(leading, trailing, log)(op) + } + + def doApply[T](leading: => String, trailing: Any => String, log: String => Unit)(op: => T)(implicit ctx: Context): T = if (ctx.mode.is(Mode.Printing)) op else { var finalized = false - var logctx = ctx - while (logctx.reporter.isInstanceOf[StoreReporter]) logctx = logctx.outer def finalize(result: Any, note: String) = if (!finalized) { ctx.base.indent -= 1 - logctx.log(s"${ctx.base.indentTab * ctx.base.indent}${trailing(result)}$note") + log(s"${ctx.base.indentTab * ctx.base.indent}${trailing(result)}$note") finalized = true } try { - logctx.log(s"${ctx.base.indentTab * ctx.base.indent}$leading") + log(s"${ctx.base.indentTab * ctx.base.indent}$leading") ctx.base.indent += 1 val res = op finalize(res, "") @@ -92,4 +115,4 @@ object trace { throw ex } } -} \ No newline at end of file +}