@@ -5,6 +5,7 @@ package init
55
66import ast .tpd ._
77import core ._
8+ import util .SourcePosition
89import Decorators ._ , printing .SyntaxHighlighting
910import Types ._ , Symbols ._ , Contexts ._
1011
@@ -26,28 +27,44 @@ object Errors {
2627 def toErrors : Errors = this :: Nil
2728
2829 def stacktrace (using Context ): String = if (trace.isEmpty) " " else " Calling trace:\n " + {
29- var indentCount = 0
3030 var last : String = " "
3131 val sb = new StringBuilder
3232 trace.foreach { tree =>
33- indentCount += 1
3433 val pos = tree.sourcePos
35- val prefix = s " ${ " " * indentCount } -> "
34+ val prefix = " -> "
3635 val line =
3736 if pos.source.exists then
3837 val loc = " [ " + pos.source.file.name + " :" + (pos.line + 1 ) + " ]"
3938 val code = SyntaxHighlighting .highlight(pos.lineContent.trim.nn)
4039 i " $code\t $loc"
4140 else
4241 tree.show
42+ val positionMarkerLine =
43+ if pos.exists && pos.source.exists then
44+ positionMarker(pos)
45+ else " "
4346
44- if (last != line) sb.append(prefix + line + " \n " )
47+ if (last != line) sb.append(prefix + line + " \n " + positionMarkerLine )
4548
4649 last = line
4750 }
4851 sb.toString
4952 }
5053
54+ /** Used to underline source positions in the stack trace
55+ * pos.source must exist
56+ */
57+ private def positionMarker (pos : SourcePosition ): String = {
58+ val trimmed = pos.lineContent.takeWhile(c => c.isWhitespace).length
59+ val padding = pos.startColumnPadding.substring(trimmed).nn + " "
60+ val carets =
61+ if (pos.startLine == pos.endLine)
62+ " ^" * math.max(1 , pos.endColumn - pos.startColumn)
63+ else " ^"
64+
65+ s " $padding$carets\n "
66+ }
67+
5168 /** Flatten UnsafePromotion errors
5269 */
5370 def flatten : Errors = this match {
0 commit comments