@@ -7,46 +7,28 @@ import config.Config
7
7
import config .Printers
8
8
import core .Mode
9
9
10
- /** Exposes the {{{ trace("question") { op } }}} syntax.
11
- *
12
- * Traced operations will print indented messages if enabled.
13
- * Tracing depends on [[Config.tracingEnabled ]] and [[dotty.tools.dotc.config.ScalaSettings.Ylog ]].
14
- * Tracing can be forced by replacing [[trace ]] with [[trace.force ]] (see below).
15
- */
16
- object trace extends TraceSyntax {
17
- final val isForced = false
18
-
19
- /** Forces a particular trace to be printed out regardless of tracing being enabled. */
20
- object force extends TraceSyntax {
21
- final val isForced = true
22
- }
23
- }
24
-
25
- abstract class TraceSyntax {
26
- val isForced : Boolean
10
+ /** This module is carefully optimized to give zero overhead if Config.tracingEnabled
11
+ * is false. The `trace` operation is called in various hotspots, so every tiny bit
12
+ * of overhead is unacceptable: boxing, closures, additional method calls are all out.
13
+ */
14
+ object trace :
27
15
28
16
inline def onDebug [TD ](inline question : String )(inline op : TD )(using Context ): TD =
29
17
conditionally(ctx.settings.YdebugTrace .value, question, false )(op)
30
18
31
- inline def conditionally [TC ](inline cond : Boolean , inline question : String , inline show : Boolean )(op : => TC )(using Context ): TC =
32
- inline if (isForced || Config .tracingEnabled) {
33
- if (cond) apply[TC ](question, Printers .default, show)(op)
34
- else op
35
- }
19
+ inline def conditionally [TC ](inline cond : Boolean , inline question : String , inline show : Boolean )(inline op : TC )(using Context ): TC =
20
+ if Config .tracingEnabled then
21
+ apply(question, if cond then Printers .default else Printers .noPrinter, show)(op)
36
22
else op
37
23
38
- inline def apply [T ](inline question : String , inline printer : Printers .Printer , inline showOp : Any => String )(op : => T )(using Context ): T =
39
- inline if (isForced || Config .tracingEnabled) {
40
- if (! isForced && printer.eq(config.Printers .noPrinter)) op
41
- else doTrace[T ](question, printer, showOp)(op)
42
- }
24
+ inline def apply [T ](inline question : String , inline printer : Printers .Printer , inline showOp : Any => String )(inline op : T )(using Context ): T =
25
+ if Config .tracingEnabled then
26
+ doTrace[T ](question, printer, showOp)(op)
43
27
else op
44
28
45
- inline def apply [T ](inline question : String , inline printer : Printers .Printer , inline show : Boolean )(op : => T )(using Context ): T =
46
- inline if (isForced || Config .tracingEnabled) {
47
- if (! isForced && printer.eq(config.Printers .noPrinter)) op
48
- else doTrace[T ](question, printer, if (show) showShowable(_) else alwaysToString)(op)
49
- }
29
+ inline def apply [T ](inline question : String , inline printer : Printers .Printer , inline show : Boolean )(inline op : T )(using Context ): T =
30
+ if Config .tracingEnabled then
31
+ doTrace[T ](question, printer, if show then showShowable(_) else alwaysToString)(op)
50
32
else op
51
33
52
34
inline def apply [T ](inline question : String , inline printer : Printers .Printer )(inline op : T )(using Context ): T =
@@ -56,55 +38,41 @@ abstract class TraceSyntax {
56
38
apply[T ](question, Printers .default, show)(op)
57
39
58
40
inline def apply [T ](inline question : String )(inline op : T )(using Context ): T =
59
- apply[T ](question, Printers .default, false )(op)
41
+ apply[T ](question, false )(op)
60
42
61
- private def showShowable (x : Any )(using Context ) = x match {
43
+ private def showShowable (x : Any )(using Context ) = x match
62
44
case x : printing.Showable => x.show
63
45
case _ => String .valueOf(x)
64
- }
65
46
66
47
private val alwaysToString = (x : Any ) => String .valueOf(x)
67
48
68
49
private def doTrace [T ](question : => String ,
69
50
printer : Printers .Printer = Printers .default,
70
51
showOp : Any => String = alwaysToString)
71
- (op : => T )(using Context ): T = {
72
- // Avoid evaluating question multiple time, since each evaluation
73
- // may cause some extra logging output.
74
- lazy val q : String = question
75
- apply[T ](s " ==> $q? " , (res : Any ) => s " <== $q = ${showOp(res)}" )(op)
76
- }
77
-
78
- def apply [T ](leading : => String , trailing : Any => String )(op : => T )(using Context ): T = {
79
- val log : String => Unit = if (isForced) Console .println else {
80
- var logctx = ctx
81
- while (logctx.reporter.isInstanceOf [StoreReporter ]) logctx = logctx.outer
82
- report.log(_)(using logctx)
83
- }
84
- doApply(leading, trailing, log)(op)
85
- }
86
-
87
- def doApply [T ](leading : => String , trailing : Any => String , log : String => Unit )(op : => T )(using Context ): T =
88
- if (ctx.mode.is(Mode .Printing )) op
89
- else {
52
+ (op : => T )(using Context ): T =
53
+ if ctx.mode.is(Mode .Printing ) || (printer eq Printers .noPrinter) then op
54
+ else
55
+ // Avoid evaluating question multiple time, since each evaluation
56
+ // may cause some extra logging output.
57
+ val q = question
58
+ val leading = s " ==> $q? "
59
+ val trailing = (res : Any ) => s " <== $q = ${showOp(res)}"
90
60
var finalized = false
61
+ var logctx = ctx
62
+ while logctx.reporter.isInstanceOf [StoreReporter ] do logctx = logctx.outer
63
+ def margin = ctx.base.indentTab * ctx.base.indent
91
64
def finalize (result : Any , note : String ) =
92
- if ( ! finalized) {
65
+ if ! finalized then
93
66
ctx.base.indent -= 1
94
- log(s " ${ctx.base.indentTab * ctx.base.indent} ${trailing(result)}$note" )
67
+ report. log(s " $margin ${trailing(result)}$note" )
95
68
finalized = true
96
- }
97
- try {
98
- log(s " ${ctx.base.indentTab * ctx.base.indent}$leading" )
69
+ try
70
+ report.log(s " $margin$leading" )
99
71
ctx.base.indent += 1
100
72
val res = op
101
73
finalize(res, " " )
102
74
res
103
- }
104
- catch {
105
- case ex : Throwable =>
106
- finalize(" <missing>" , s " (with exception $ex) " )
107
- throw ex
108
- }
109
- }
110
- }
75
+ catch case ex : Throwable =>
76
+ finalize(" <missing>" , s " (with exception $ex) " )
77
+ throw ex
78
+ end trace
0 commit comments