@@ -7,31 +7,28 @@ import config.Config
7
7
import config .Printers
8
8
import core .Mode
9
9
10
- abstract class TraceSyntax {
11
- 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 :
12
15
13
16
inline def onDebug [TD ](inline question : String )(inline op : TD )(using Context ): TD =
14
17
conditionally(ctx.settings.YdebugTrace .value, question, false )(op)
15
18
16
- inline def conditionally [TC ](inline cond : Boolean , inline question : String , inline show : Boolean )(op : => TC )(using Context ): TC =
17
- inline if (isForced || Config .tracingEnabled) {
18
- if (cond) apply[TC ](question, Printers .default, show)(op)
19
- else op
20
- }
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)
21
22
else op
22
23
23
- inline def apply [T ](inline question : String , inline printer : Printers .Printer , inline showOp : Any => String )(op : => T )(using Context ): T =
24
- inline if (isForced || Config .tracingEnabled) {
25
- if (! isForced && printer.eq(config.Printers .noPrinter)) op
26
- else doTrace[T ](question, printer, showOp)(op)
27
- }
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)
28
27
else op
29
28
30
- inline def apply [T ](inline question : String , inline printer : Printers .Printer , inline show : Boolean )(op : => T )(using Context ): T =
31
- inline if (isForced || Config .tracingEnabled) {
32
- if (! isForced && printer.eq(config.Printers .noPrinter)) op
33
- else doTrace[T ](question, printer, if (show) showShowable(_) else alwaysToString)(op)
34
- }
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)
35
32
else op
36
33
37
34
inline def apply [T ](inline question : String , inline printer : Printers .Printer )(inline op : T )(using Context ): T =
@@ -41,62 +38,41 @@ abstract class TraceSyntax {
41
38
apply[T ](question, Printers .default, show)(op)
42
39
43
40
inline def apply [T ](inline question : String )(inline op : T )(using Context ): T =
44
- apply[T ](question, Printers .default, false )(op)
41
+ apply[T ](question, false )(op)
45
42
46
- private def showShowable (x : Any )(using Context ) = x match {
43
+ private def showShowable (x : Any )(using Context ) = x match
47
44
case x : printing.Showable => x.show
48
45
case _ => String .valueOf(x)
49
- }
50
46
51
47
private val alwaysToString = (x : Any ) => String .valueOf(x)
52
48
53
49
private def doTrace [T ](question : => String ,
54
50
printer : Printers .Printer = Printers .default,
55
51
showOp : Any => String = alwaysToString)
56
- (op : => T )(using Context ): T = {
57
- // Avoid evaluating question multiple time, since each evaluation
58
- // may cause some extra logging output.
59
- lazy val q : String = question
60
- apply[T ](s " ==> $q? " , (res : Any ) => s " <== $q = ${showOp(res)}" )(op)
61
- }
62
-
63
- def apply [T ](leading : => String , trailing : Any => String )(op : => T )(using Context ): T = {
64
- val log : String => Unit = if (isForced) Console .println else {
65
- var logctx = ctx
66
- while (logctx.reporter.isInstanceOf [StoreReporter ]) logctx = logctx.outer
67
- report.log(_)(using logctx)
68
- }
69
- doApply(leading, trailing, log)(op)
70
- }
71
-
72
- def doApply [T ](leading : => String , trailing : Any => String , log : String => Unit )(op : => T )(using Context ): T =
73
- if (ctx.mode.is(Mode .Printing )) op
74
- 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)}"
75
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
76
64
def finalize (result : Any , note : String ) =
77
- if ( ! finalized) {
65
+ if ! finalized then
78
66
ctx.base.indent -= 1
79
- log(s " ${ctx.base.indentTab * ctx.base.indent} ${trailing(result)}$note" )
67
+ report. log(s " $margin ${trailing(result)}$note" )
80
68
finalized = true
81
- }
82
- try {
83
- log(s " ${ctx.base.indentTab * ctx.base.indent}$leading" )
69
+ try
70
+ report.log(s " $margin$leading" )
84
71
ctx.base.indent += 1
85
72
val res = op
86
73
finalize(res, " " )
87
74
res
88
- }
89
- catch {
90
- case ex : Throwable =>
91
- finalize(" <missing>" , s " (with exception $ex) " )
92
- throw ex
93
- }
94
- }
95
- }
96
-
97
- object trace extends TraceSyntax {
98
- final val isForced = false
99
- object force extends TraceSyntax {
100
- final val isForced = true
101
- }
102
- }
75
+ catch case ex : Throwable =>
76
+ finalize(" <missing>" , s " (with exception $ex) " )
77
+ throw ex
78
+ end trace
0 commit comments