@@ -63,11 +63,43 @@ function displayError(
63
63
const sourceStyle = color ? "color: blue" : "" ;
64
64
for ( const error of errors ) {
65
65
console . error ( `%cError%c: ${ error . message } ` , red , "" ) ;
66
- if ( error instanceof PositionedError ) {
67
- const position = error . position ;
68
- const lines = source . slice ( 0 , position ?. position ) . split ( / \r ? \n / ) ;
69
- const line = lines . length ;
70
- const column = lines [ lines . length - 1 ] . length + 1 ;
66
+ if ( error instanceof PositionedError && error . position != null ) {
67
+ const { position, length } = error . position ;
68
+ const end = position + length ;
69
+ // The only instance returning -1 is useful
70
+ const startLine = source . lastIndexOf ( "\n" , position ) + 1 ;
71
+ let currentLine = startLine ;
72
+ let currentPosition = position ;
73
+
74
+ while ( true ) {
75
+ const index = source . indexOf ( "\n" , currentLine ) ;
76
+ const nextLine = index === - 1 ? source . length : index + 1 ;
77
+ const line = source . slice ( currentLine , nextLine ) . trimEnd ( ) ;
78
+ console . error ( line ) ;
79
+ let relativeStart = currentPosition - currentLine ;
80
+ let relativeEnd = Math . min ( end - currentLine , line . length ) ;
81
+ if ( relativeEnd - relativeStart === 0 ) {
82
+ if ( relativeStart !== 0 ) {
83
+ relativeStart -- ;
84
+ }
85
+ if ( relativeEnd !== line . length ) {
86
+ relativeEnd ++ ;
87
+ }
88
+ }
89
+ console . error (
90
+ `${ " " . repeat ( relativeStart ) } %c${
91
+ "^" . repeat ( relativeEnd - relativeStart )
92
+ } `,
93
+ red ,
94
+ ) ;
95
+ if ( end <= nextLine ) {
96
+ break ;
97
+ } else {
98
+ currentLine = currentPosition = nextLine ;
99
+ }
100
+ }
101
+ const line = source . slice ( 0 , startLine ) . split ( / \n (? ! $ ) / ) . length ;
102
+ const column = position - startLine + 1 ;
71
103
console . error ( ` at %c${ SOURCE } :${ line } :${ column } ` , sourceStyle ) ;
72
104
console . error ( ) ;
73
105
}
0 commit comments