@@ -12,15 +12,30 @@ import util.SourcePosition
12
12
import scala .collection .mutable
13
13
14
14
trait MessageRendering {
15
+ /** Remove ANSI coloring from `str`, useful for getting real length of
16
+ * strings
17
+ *
18
+ * @return string stripped of ANSI escape codes
19
+ */
15
20
def stripColor (str : String ): String =
16
21
str.replaceAll(" \u001B\\ [[;\\ d]*m" , " " )
17
22
23
+ /** When inlining a method call, if there's an error we'd like to get the
24
+ * outer context and the `pos` at which the call was inlined.
25
+ *
26
+ * @return a list of strings with inline locations
27
+ */
18
28
def outer (pos : SourcePosition , prefix : String )(implicit ctx : Context ): List [String ] =
19
29
if (pos.outer.exists) {
20
30
s " $prefix| This location is in code that was inlined at ${pos.outer}" ::
21
31
outer(pos.outer, prefix)
22
32
} else Nil
23
33
34
+ /** Get the sourcelines before and after the position, as well as the offset
35
+ * for rendering line numbers
36
+ *
37
+ * @return (lines before error, lines after error, line numbers offset)
38
+ */
24
39
def sourceLines (pos : SourcePosition )(implicit ctx : Context ): (List [String ], List [String ], Int ) = {
25
40
var maxLen = Int .MinValue
26
41
def render (xs : List [Int ]) =
@@ -39,6 +54,7 @@ trait MessageRendering {
39
54
(render(before), render(after), maxLen)
40
55
}
41
56
57
+ /** The column markers aligned under the error */
42
58
def columnMarker (pos : SourcePosition , offset : Int )(implicit ctx : Context ): String = {
43
59
val prefix = " " * (offset - 1 )
44
60
val whitespace = " " * pos.startColumn
@@ -51,21 +67,30 @@ trait MessageRendering {
51
67
s " $prefix| $whitespace${carets.show}"
52
68
}
53
69
70
+ /** The error message (`msg`) aligned under `pos`
71
+ *
72
+ * @return aligned error message
73
+ */
54
74
def errorMsg (pos : SourcePosition , msg : String , offset : Int )(implicit ctx : Context ): String = {
55
75
val leastWhitespace = msg.lines.foldLeft(Int .MaxValue ) { (minPad, line) =>
56
76
val lineLength = stripColor(line).length
57
- val padding =
58
- math.min(math.max(0 , ctx.settings.pageWidth.value - offset - lineLength), offset + pos.startColumn)
77
+ val currPad = math.min(
78
+ math.max(0 , ctx.settings.pageWidth.value - offset - lineLength),
79
+ offset + pos.startColumn
80
+ )
59
81
60
- if (padding < minPad) padding
61
- else minPad
82
+ math.min(currPad, minPad)
62
83
}
63
84
64
85
msg.lines
65
- .map { line => " " * (offset - 1 ) + " |" + (" " * (leastWhitespace - offset)) + line }
86
+ .map { line => " " * (offset - 1 ) + " |" + (" " * (leastWhitespace - offset)) + line}
66
87
.mkString(sys.props(" line.separator" ))
67
88
}
68
89
90
+ /** The separator between errors containing the source file and error type
91
+ *
92
+ * @return separator containing error location and kind
93
+ */
69
94
def posStr (pos : SourcePosition , diagnosticLevel : String , message : Message )(implicit ctx : Context ): String =
70
95
if (pos.exists) Blue ({
71
96
val file = pos.source.file.toString
@@ -82,15 +107,19 @@ trait MessageRendering {
82
107
(" -" * math.max(ctx.settings.pageWidth.value - stripColor(prefix).length, 0 ))
83
108
}).show else " "
84
109
110
+ /** Explanation rendered under "Explanation" header */
85
111
def explanation (m : Message )(implicit ctx : Context ): String = {
86
- val sb = new StringBuilder (hl """ |
87
- | ${Blue (" Explanation" )}
88
- | ${Blue (" ===========" )}""" .stripMargin)
112
+ val sb = new StringBuilder (
113
+ hl """ |
114
+ | ${Blue (" Explanation" )}
115
+ | ${Blue (" ===========" )}"""
116
+ )
89
117
sb.append('\n ' ).append(m.explanation)
90
118
if (m.explanation.lastOption != Some ('\n ' )) sb.append('\n ' )
91
119
sb.toString
92
120
}
93
121
122
+ /** The whole message rendered from `msg` */
94
123
def messageAndPos (msg : Message , pos : SourcePosition , diagnosticLevel : String )(implicit ctx : Context ): String = {
95
124
val sb = mutable.StringBuilder .newBuilder
96
125
sb.append(posStr(pos, diagnosticLevel, msg)).append('\n ' )
@@ -103,7 +132,7 @@ trait MessageRendering {
103
132
sb.toString
104
133
}
105
134
106
- def diagnosticLevel (cont : MessageContainer ): String = {
135
+ def diagnosticLevel (cont : MessageContainer ): String =
107
136
cont match {
108
137
case m : Error => " Error"
109
138
case m : FeatureWarning => " Feature Warning"
@@ -113,5 +142,4 @@ trait MessageRendering {
113
142
case m : Warning => " Warning"
114
143
case m : Info => " Info"
115
144
}
116
- }
117
145
}
0 commit comments