compiler: color only the relevant part of the source code in error messages

pull/4823/head
eyelash 2020-05-10 17:24:29 +02:00 committed by GitHub
parent dae3907c5f
commit 1722171adc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 28 deletions

View File

@ -105,44 +105,36 @@ pub fn source_context(kind, source string, column int, pos token.Position) []str
tab_spaces := ' ' tab_spaces := ' '
for iline := bline; iline <= aline; iline++ { for iline := bline; iline <= aline; iline++ {
sline := source_lines[iline] sline := source_lines[iline]
mut cline := sline.replace('\t', tab_spaces) start_column := imin(column, sline.len)
if iline == pos.line_nr { end_column := imin(column + pos.len, sline.len)
cline = color(kind, cline) cline := if iline == pos.line_nr {
sline[..start_column] + color(kind, sline[start_column..end_column]) + sline[end_column..]
} else {
sline
} }
clines << '${iline+1:5d} | ' + cline clines << '${iline+1:5d} | ' + cline.replace('\t', tab_spaces)
// //
if iline == pos.line_nr { if iline == pos.line_nr {
// The pointerline should have the same spaces/tabs as the offending // The pointerline should have the same spaces/tabs as the offending
// line, so that it prints the ^ character exactly on the *same spot* // line, so that it prints the ^ character exactly on the *same spot*
// where it is needed. That is the reason we can not just // where it is needed. That is the reason we can not just
// use strings.repeat(` `, col) to form it. // use strings.repeat(` `, col) to form it.
mut pointerline := []string{} mut pointerline := ''
for i, bchar in sline { for bchar in sline[..start_column] {
if i < column { x := if bchar.is_space() {
mut x := bchar
if x == `\t` {
pointerline << tab_spaces
} else {
x = if x.is_space() {
bchar bchar
} else { } else {
` ` ` `
} }
pointerline << x.str() pointerline += x.str()
} }
continue underline := if pos.len > 1 {
} '~'.repeat(end_column - start_column)
if pos.len > 1 {
max_len := sline.len - pointerline.len // rest of the line
len := imin(max_len, pos.len)
underline := '~'.repeat(len)
pointerline << bold(color(kind, underline))
} else { } else {
pointerline << bold(color(kind, '^')) '^'
} }
break pointerline += bold(color(kind, underline))
} clines << ' | ' + pointerline.replace('\t', tab_spaces)
clines << ' | ' + pointerline.join('')
} }
} }
return clines return clines