mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
all: vls mode fixes and improvements; v -json-errors flag
This commit is contained in:
parent
a11de7263f
commit
652881c73b
7 changed files with 104 additions and 22 deletions
|
@ -29,35 +29,20 @@ const stderr_value = 2
|
||||||
// (Must be realized in Syscall) (Must be specified)
|
// (Must be realized in Syscall) (Must be specified)
|
||||||
// ref: http://www.ccfit.nsu.ru/~deviv/courses/unix/unix/ng7c229.html
|
// ref: http://www.ccfit.nsu.ru/~deviv/courses/unix/unix/ng7c229.html
|
||||||
pub const s_ifmt = 0xF000 // type of file
|
pub const s_ifmt = 0xF000 // type of file
|
||||||
|
|
||||||
pub const s_ifdir = 0x4000 // directory
|
pub const s_ifdir = 0x4000 // directory
|
||||||
|
|
||||||
pub const s_ifreg = 0x8000 // regular file
|
pub const s_ifreg = 0x8000 // regular file
|
||||||
|
|
||||||
pub const s_iflnk = 0xa000 // link
|
pub const s_iflnk = 0xa000 // link
|
||||||
|
|
||||||
pub const s_isuid = 0o4000 // SUID
|
pub const s_isuid = 0o4000 // SUID
|
||||||
|
|
||||||
pub const s_isgid = 0o2000 // SGID
|
pub const s_isgid = 0o2000 // SGID
|
||||||
|
|
||||||
pub const s_isvtx = 0o1000 // Sticky
|
pub const s_isvtx = 0o1000 // Sticky
|
||||||
|
|
||||||
pub const s_irusr = 0o0400 // Read by owner
|
pub const s_irusr = 0o0400 // Read by owner
|
||||||
|
|
||||||
pub const s_iwusr = 0o0200 // Write by owner
|
pub const s_iwusr = 0o0200 // Write by owner
|
||||||
|
|
||||||
pub const s_ixusr = 0o0100 // Execute by owner
|
pub const s_ixusr = 0o0100 // Execute by owner
|
||||||
|
|
||||||
pub const s_irgrp = 0o0040 // Read by group
|
pub const s_irgrp = 0o0040 // Read by group
|
||||||
|
|
||||||
pub const s_iwgrp = 0o0020 // Write by group
|
pub const s_iwgrp = 0o0020 // Write by group
|
||||||
|
|
||||||
pub const s_ixgrp = 0o0010 // Execute by group
|
pub const s_ixgrp = 0o0010 // Execute by group
|
||||||
|
|
||||||
pub const s_iroth = 0o0004 // Read by others
|
pub const s_iroth = 0o0004 // Read by others
|
||||||
|
|
||||||
pub const s_iwoth = 0o0002 // Write by others
|
pub const s_iwoth = 0o0002 // Write by others
|
||||||
|
|
||||||
pub const s_ixoth = 0o0001
|
pub const s_ixoth = 0o0001
|
||||||
|
|
||||||
fn C.utime(&char, &C.utimbuf) int
|
fn C.utime(&char, &C.utimbuf) int
|
||||||
|
|
24
vlib/os/util/util.v
Normal file
24
vlib/os/util/util.v
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module util
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
// TODO `select` doesn't work with time.Duration for some reason
|
||||||
|
pub fn execute_with_timeout(cmd string, timeout i64) ?os.Result {
|
||||||
|
ch := chan os.Result{cap: 1}
|
||||||
|
spawn fn [cmd] (c chan os.Result) {
|
||||||
|
res := os.execute(cmd)
|
||||||
|
c <- res
|
||||||
|
}(ch)
|
||||||
|
select {
|
||||||
|
a := <-ch {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
// timeout {
|
||||||
|
// 1000 * time.millisecond {
|
||||||
|
// timeout * time.millisecond {
|
||||||
|
timeout * 1_000_000 {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return os.Result{}
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ import v.markused
|
||||||
import v.depgraph
|
import v.depgraph
|
||||||
import v.callgraph
|
import v.callgraph
|
||||||
import v.dotgraph
|
import v.dotgraph
|
||||||
|
// import x.json2
|
||||||
|
|
||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
pub:
|
pub:
|
||||||
|
@ -475,7 +476,8 @@ pub fn (b &Builder) show_total_warns_and_errors_stats() {
|
||||||
println('checker summary: ${estring} V errors, ${wstring} V warnings, ${nstring} V notices')
|
println('checker summary: ${estring} V errors, ${wstring} V warnings, ${nstring} V notices')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if b.checker.nr_errors > 0 && b.pref.path.ends_with('.v') && os.is_file(b.pref.path) {
|
if !b.pref.is_vls && b.checker.nr_errors > 0 && b.pref.path.ends_with('.v')
|
||||||
|
&& os.is_file(b.pref.path) {
|
||||||
if b.checker.errors.any(it.message.starts_with('unknown ')) {
|
if b.checker.errors.any(it.message.starts_with('unknown ')) {
|
||||||
// Sometimes users try to `v main.v`, when they have several .v files in their project.
|
// Sometimes users try to `v main.v`, when they have several .v files in their project.
|
||||||
// Then, they encounter puzzling errors about missing or unknown types. In this case,
|
// Then, they encounter puzzling errors about missing or unknown types. In this case,
|
||||||
|
@ -519,6 +521,7 @@ pub fn (mut b Builder) print_warnings_and_errors() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mut json_errors := []util.JsonError{}
|
||||||
for file in b.parsed_files {
|
for file in b.parsed_files {
|
||||||
for err in file.errors {
|
for err in file.errors {
|
||||||
kind := if b.pref.is_verbose {
|
kind := if b.pref.is_verbose {
|
||||||
|
@ -526,9 +529,24 @@ pub fn (mut b Builder) print_warnings_and_errors() {
|
||||||
} else {
|
} else {
|
||||||
'error:'
|
'error:'
|
||||||
}
|
}
|
||||||
util.show_compiler_message(kind, err.CompilerMessage)
|
|
||||||
|
if b.pref.json_errors {
|
||||||
|
json_errors << util.JsonError{
|
||||||
|
message: err.message
|
||||||
|
path: err.file_path
|
||||||
|
line_nr: err.pos.line_nr + 1
|
||||||
|
col: err.pos.col + 1
|
||||||
|
}
|
||||||
|
// util.print_json_error(kind, err.CompilerMessage)
|
||||||
|
} else {
|
||||||
|
util.show_compiler_message(kind, err.CompilerMessage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if b.pref.json_errors {
|
||||||
|
util.print_json_errors(json_errors)
|
||||||
|
// eprintln(json2.encode_pretty(json_errors))
|
||||||
|
}
|
||||||
|
|
||||||
if !b.pref.skip_warnings {
|
if !b.pref.skip_warnings {
|
||||||
for file in b.parsed_files {
|
for file in b.parsed_files {
|
||||||
|
|
|
@ -1881,6 +1881,10 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if unknown_field_msg == '' {
|
if unknown_field_msg == '' {
|
||||||
|
if field_name == '' && c.pref.is_vls {
|
||||||
|
// VLS will often have `foo.`, skip the no field error
|
||||||
|
return ast.void_type
|
||||||
|
}
|
||||||
unknown_field_msg = 'type `${sym.name}` has no field named `${field_name}`'
|
unknown_field_msg = 'type `${sym.name}` has no field named `${field_name}`'
|
||||||
}
|
}
|
||||||
if sym.info is ast.Struct {
|
if sym.info is ast.Struct {
|
||||||
|
|
|
@ -249,9 +249,12 @@ pub fn parse_file(path string, mut table ast.Table, comments_mode scanner.Commen
|
||||||
eprintln('> ${@MOD}.${@FN} comments_mode: ${comments_mode:-20} | path: ${path}')
|
eprintln('> ${@MOD}.${@FN} comments_mode: ${comments_mode:-20} | path: ${path}')
|
||||||
}
|
}
|
||||||
mut p := Parser{
|
mut p := Parser{
|
||||||
scanner: scanner.new_scanner_file(path, comments_mode, pref_) or { panic(err) }
|
scanner: scanner.new_scanner_file(path, comments_mode, pref_) or { panic(err) }
|
||||||
table: table
|
table: table
|
||||||
pref: pref_
|
pref: pref_
|
||||||
|
// Only set vls mode if it's the file the user requested via `v -vls-mode file.v`
|
||||||
|
// Otherwise we'd be parsing entire stdlib in vls mode
|
||||||
|
is_vls: pref_.is_vls && path == pref_.path
|
||||||
scope: &ast.Scope{
|
scope: &ast.Scope{
|
||||||
start_pos: 0
|
start_pos: 0
|
||||||
parent: table.global_scope
|
parent: table.global_scope
|
||||||
|
|
|
@ -257,8 +257,9 @@ pub mut:
|
||||||
// forwards compatibility settings:
|
// forwards compatibility settings:
|
||||||
relaxed_gcc14 bool = true // turn on the generated pragmas, that make gcc versions > 14 a lot less pedantic. The default is to have those pragmas in the generated C output, so that gcc-14 can be used on Arch etc.
|
relaxed_gcc14 bool = true // turn on the generated pragmas, that make gcc versions > 14 a lot less pedantic. The default is to have those pragmas in the generated C output, so that gcc-14 can be used on Arch etc.
|
||||||
//
|
//
|
||||||
subsystem Subsystem // the type of the window app, that is going to be generated; has no effect on !windows
|
subsystem Subsystem // the type of the window app, that is going to be generated; has no effect on !windows
|
||||||
is_vls bool
|
is_vls bool
|
||||||
|
json_errors bool // -json-errors, for VLS and other tools
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LineInfo {
|
pub struct LineInfo {
|
||||||
|
@ -406,6 +407,9 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
|
||||||
'-check' {
|
'-check' {
|
||||||
res.check_only = true
|
res.check_only = true
|
||||||
}
|
}
|
||||||
|
'-vls-mode' {
|
||||||
|
res.is_vls = true
|
||||||
|
}
|
||||||
'-?', '-h', '-help', '--help' {
|
'-?', '-h', '-help', '--help' {
|
||||||
// Note: help is *very important*, just respond to all variations:
|
// Note: help is *very important*, just respond to all variations:
|
||||||
res.is_help = true
|
res.is_help = true
|
||||||
|
@ -561,6 +565,9 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
|
||||||
'-repl' {
|
'-repl' {
|
||||||
res.is_repl = true
|
res.is_repl = true
|
||||||
}
|
}
|
||||||
|
'-json-errors' {
|
||||||
|
res.json_errors = true
|
||||||
|
}
|
||||||
'-live' {
|
'-live' {
|
||||||
res.is_livemain = true
|
res.is_livemain = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,3 +210,44 @@ pub fn show_compiler_message(kind string, err errors.CompilerMessage) {
|
||||||
eprintln(bold('Details: ') + color('details', err.details))
|
eprintln(bold('Details: ') + color('details', err.details))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct JsonError {
|
||||||
|
pub:
|
||||||
|
path string
|
||||||
|
message string
|
||||||
|
line_nr int
|
||||||
|
col int
|
||||||
|
len int
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn print_json_errors(errs []JsonError) {
|
||||||
|
// Can't import x.json2 or json, so have to manually generate json
|
||||||
|
eprintln('[')
|
||||||
|
for i, e in errs {
|
||||||
|
msg := e.message.replace('"', '\\"').replace('\n', '\\n')
|
||||||
|
eprintln('{
|
||||||
|
"path":"${e.path}",
|
||||||
|
"message":"${msg}",
|
||||||
|
"line_nr":${e.line_nr},
|
||||||
|
"col":${e.col},
|
||||||
|
"len":${e.len}
|
||||||
|
}')
|
||||||
|
if i < errs.len - 1 {
|
||||||
|
eprintln(',')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eprintln(']')
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pub fn print_json_error(kind string, err errors.CompilerMessage) {
|
||||||
|
e := JsonError{
|
||||||
|
message: err.message
|
||||||
|
path: err.file_path
|
||||||
|
line_nr: err.pos.line_nr + 1
|
||||||
|
col: err.pos.col + 1
|
||||||
|
len: err.pos.len
|
||||||
|
}
|
||||||
|
eprintln(json2.encode_pretty(e))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue