errors: print more informative and pretty errors
parent
d865fc26eb
commit
7a99949f0e
|
@ -55,19 +55,10 @@ pub fn new_scanner_file(file_path string, comments_mode CommentsMode) &Scanner {
|
||||||
if !os.exists(file_path) {
|
if !os.exists(file_path) {
|
||||||
verror("$file_path doesn't exist")
|
verror("$file_path doesn't exist")
|
||||||
}
|
}
|
||||||
mut raw_text := os.read_file(file_path) or {
|
raw_text := util.read_file( file_path ) or {
|
||||||
verror('scanner: failed to open $file_path')
|
verror(err)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
// BOM check
|
|
||||||
if raw_text.len >= 3 {
|
|
||||||
c_text := raw_text.str
|
|
||||||
if c_text[0] == 0xEF && c_text[1] == 0xBB && c_text[2] == 0xBF {
|
|
||||||
// skip three BOM bytes
|
|
||||||
offset_from_begin := 3
|
|
||||||
raw_text = tos(c_text[offset_from_begin], vstrlen(c_text) - offset_from_begin)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mut s := new_scanner(raw_text, comments_mode) // .skip_comments)
|
mut s := new_scanner(raw_text, comments_mode) // .skip_comments)
|
||||||
// s.init_fmt()
|
// s.init_fmt()
|
||||||
s.file_path = file_path
|
s.file_path = file_path
|
||||||
|
|
|
@ -53,13 +53,56 @@ pub fn formated_error(kind string /*error or warn*/, emsg string, filepath strin
|
||||||
path = path.replace(workdir, '')
|
path = path.replace(workdir, '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
column := 0
|
//
|
||||||
position := '${path}:${pos.line_nr+1}:$column:'
|
mut column := 0
|
||||||
// QTODO: retrieve source lines around pos.line_nr and add them here
|
|
||||||
mut source_context := ''
|
mut source_context := ''
|
||||||
|
source := util.read_file(filepath) or { '' }
|
||||||
|
source_lines := source.split_into_lines()
|
||||||
|
if source.len > pos.pos {
|
||||||
|
mut p := pos.pos
|
||||||
|
for ; p>=0; p-- {
|
||||||
|
if source[p] == `\r` || source[p] == `\n` {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
column = pos.pos - p
|
||||||
|
}
|
||||||
|
position := '${path}:${pos.line_nr+1}:$column:'
|
||||||
|
//
|
||||||
|
bline := pos.line_nr - error_context_before
|
||||||
|
aline := pos.line_nr + error_context_after
|
||||||
|
mut clines := []string
|
||||||
|
for iline, sline in source_lines {
|
||||||
|
if iline >= bline && iline <= aline {
|
||||||
|
mut cline := '${iline+1:5d}| $sline'
|
||||||
|
if iline == pos.line_nr && emanager.support_color {
|
||||||
|
cline = term.red( cline )
|
||||||
|
}
|
||||||
|
clines << cline
|
||||||
|
//
|
||||||
|
if iline == pos.line_nr {
|
||||||
|
// The pointerline should have the same spaces/tabs as the offending
|
||||||
|
// line, so that it prints the ^ character exactly on the *same spot*
|
||||||
|
// where it is needed. That is the reason we can not just
|
||||||
|
// use strings.repeat(` `, col) to form it.
|
||||||
|
mut pointerline := []string
|
||||||
|
for i, c in cline {
|
||||||
|
if i < column {
|
||||||
|
x := if c.is_space() { c } else { ` ` }
|
||||||
|
pointerline << x.str()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pointerline << if emanager.support_color { term.bold(term.blue('^')) } else { '^' }
|
||||||
|
break
|
||||||
|
}
|
||||||
|
clines << ' ' + pointerline.join('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
source_context += clines.join('\n')
|
||||||
//
|
//
|
||||||
final_position := if emanager.support_color {
|
final_position := if emanager.support_color {
|
||||||
term.bold(position) // term.white(position))
|
term.bold(position)
|
||||||
} else {
|
} else {
|
||||||
position
|
position
|
||||||
}
|
}
|
||||||
|
@ -71,7 +114,7 @@ pub fn formated_error(kind string /*error or warn*/, emsg string, filepath strin
|
||||||
term.bold(term.bright_blue(kind))
|
term.bold(term.bright_blue(kind))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final_msg := emsg
|
final_msg := if emanager.support_color { term.bold(emsg) } else { emsg }
|
||||||
final_context := if source_context.len > 0 { '\n$source_context' } else { '' }
|
final_context := if source_context.len > 0 { '\n$source_context' } else { '' }
|
||||||
//
|
//
|
||||||
return '$final_position $final_kind $final_msg $final_context'.trim_space()
|
return '$final_position $final_kind $final_msg $final_context'.trim_space()
|
||||||
|
|
|
@ -158,3 +158,19 @@ pub fn path_of_executable(path string) string {
|
||||||
}
|
}
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_file(file_path string) ?string {
|
||||||
|
mut raw_text := os.read_file(file_path) or {
|
||||||
|
return error('failed to open $file_path')
|
||||||
|
}
|
||||||
|
// BOM check
|
||||||
|
if raw_text.len >= 3 {
|
||||||
|
c_text := raw_text.str
|
||||||
|
if c_text[0] == 0xEF && c_text[1] == 0xBB && c_text[2] == 0xBF {
|
||||||
|
// skip three BOM bytes
|
||||||
|
offset_from_begin := 3
|
||||||
|
raw_text = tos(c_text[offset_from_begin], vstrlen(c_text) - offset_from_begin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return raw_text
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue