v.util: improve formatted_error by adding cached_file2sourcelines, so .split_into_lines is called just once (important for long source files with many errors)
parent
f6d7170e77
commit
d540b3f1a8
|
@ -83,12 +83,11 @@ fn (mut b Builder) myfree() {
|
|||
// for file in b.parsed_files {
|
||||
// }
|
||||
unsafe { b.parsed_files.free() }
|
||||
unsafe { util.cached_read_source_file('') or {} }
|
||||
util.free_caches()
|
||||
}
|
||||
|
||||
fn (b &Builder) exit_on_invalid_syntax() {
|
||||
// clear the source file cache, since it will not be needed anymore
|
||||
unsafe { util.cached_read_source_file('') or {} }
|
||||
util.free_caches()
|
||||
// V should exit with an exit code of 1, when there are errors,
|
||||
// even when -silent is passed in combination to -check-syntax:
|
||||
if b.pref.only_check_syntax {
|
||||
|
|
|
@ -83,9 +83,8 @@ pub fn formatted_error(kind string, omsg string, filepath string, pos token.Posi
|
|||
}
|
||||
}
|
||||
//
|
||||
source := read_file(filepath) or { '' }
|
||||
position := '$path:${pos.line_nr + 1}:${mu.max(1, pos.col + 1)}:'
|
||||
scontext := source_context(kind, source, pos).join('\n')
|
||||
scontext := source_file_context(kind, filepath, pos).join('\n')
|
||||
final_position := bold(position)
|
||||
final_kind := bold(color(kind, kind))
|
||||
final_msg := emsg
|
||||
|
@ -94,12 +93,39 @@ pub fn formatted_error(kind string, omsg string, filepath string, pos token.Posi
|
|||
return '$final_position $final_kind $final_msg$final_context'.trim_space()
|
||||
}
|
||||
|
||||
pub fn source_context(kind string, source string, pos token.Position) []string {
|
||||
[heap]
|
||||
struct LinesCache {
|
||||
mut:
|
||||
lines map[string][]string
|
||||
}
|
||||
|
||||
[unsafe]
|
||||
pub fn cached_file2sourcelines(path string) []string {
|
||||
mut static cache := &LinesCache(0)
|
||||
if isnil(cache) {
|
||||
cache = &LinesCache{}
|
||||
}
|
||||
if path.len == 0 {
|
||||
unsafe { cache.lines.free() }
|
||||
unsafe { free(cache) }
|
||||
cache = &LinesCache(0)
|
||||
return []string{}
|
||||
}
|
||||
if res := cache.lines[path] {
|
||||
return res
|
||||
}
|
||||
source := read_file(path) or { '' }
|
||||
res := source.split_into_lines()
|
||||
cache.lines[path] = res
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn source_file_context(kind string, filepath string, pos token.Position) []string {
|
||||
mut clines := []string{}
|
||||
if source.len == 0 {
|
||||
source_lines := unsafe { cached_file2sourcelines(filepath) }
|
||||
if source_lines.len == 0 {
|
||||
return clines
|
||||
}
|
||||
source_lines := source.split_into_lines()
|
||||
bline := mu.max(0, pos.line_nr - util.error_context_before)
|
||||
aline := mu.max(0, mu.min(source_lines.len - 1, pos.line_nr + util.error_context_after))
|
||||
tab_spaces := ' '
|
||||
|
|
|
@ -514,3 +514,11 @@ pub fn find_all_v_files(roots []string) ?[]string {
|
|||
}
|
||||
return files
|
||||
}
|
||||
|
||||
// free_caches knows about all `util` caches and makes sure that they are freed
|
||||
// if you add another cached unsafe function using static, do not forget to add
|
||||
// a mechanism to clear its cache, and call it here.
|
||||
pub fn free_caches() {
|
||||
unsafe { cached_read_source_file('') or {} }
|
||||
unsafe { cached_file2sourcelines('') }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue