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) {
|
||||
verror("$file_path doesn't exist")
|
||||
}
|
||||
mut raw_text := os.read_file(file_path) or {
|
||||
verror('scanner: failed to open $file_path')
|
||||
raw_text := util.read_file( file_path ) or {
|
||||
verror(err)
|
||||
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)
|
||||
// s.init_fmt()
|
||||
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, '')
|
||||
}
|
||||
}
|
||||
column := 0
|
||||
position := '${path}:${pos.line_nr+1}:$column:'
|
||||
// QTODO: retrieve source lines around pos.line_nr and add them here
|
||||
//
|
||||
mut column := 0
|
||||
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 {
|
||||
term.bold(position) // term.white(position))
|
||||
term.bold(position)
|
||||
} else {
|
||||
position
|
||||
}
|
||||
|
@ -71,7 +114,7 @@ pub fn formated_error(kind string /*error or warn*/, emsg string, filepath strin
|
|||
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 { '' }
|
||||
//
|
||||
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
|
||||
}
|
||||
|
||||
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