checker: "v -line-info" for a quick run to fetch info about objects on one line

This commit is contained in:
Alexander Medvednikov 2023-08-11 21:08:22 +03:00
parent 61ffbe1a8c
commit 3c26bfff55
4 changed files with 77 additions and 1 deletions

View File

@ -88,7 +88,7 @@ mut:
// 1 for statements directly at each inner scope level; // 1 for statements directly at each inner scope level;
// increases for `x := if cond { statement_list1} else {statement_list2}`; // increases for `x := if cond { statement_list1} else {statement_list2}`;
// increases for `x := optfn() or { statement_list3 }`; // increases for `x := optfn() or { statement_list3 }`;
files []ast.File // files []ast.File
expr_level int // to avoid infinite recursion segfaults due to compiler bugs expr_level int // to avoid infinite recursion segfaults due to compiler bugs
ensure_generic_type_level int // to avoid infinite recursion segfaults in ensure_generic_type_specify_type_names ensure_generic_type_level int // to avoid infinite recursion segfaults in ensure_generic_type_specify_type_names
cur_orm_ts ast.TypeSymbol cur_orm_ts ast.TypeSymbol
@ -116,6 +116,7 @@ mut:
inside_decl_rhs bool inside_decl_rhs bool
inside_if_guard bool // true inside the guard condition of `if x := opt() {}` inside_if_guard bool // true inside the guard condition of `if x := opt() {}`
inside_assign bool inside_assign bool
doing_line_info int // a quick single file run when called with v -line-info (contains line nr to inspect)
is_index_assign bool is_index_assign bool
comptime_call_pos int // needed for correctly checking use before decl for templates comptime_call_pos int // needed for correctly checking use before decl for templates
goto_labels map[string]ast.GotoLabel // to check for unused goto labels goto_labels map[string]ast.GotoLabel // to check for unused goto labels
@ -372,6 +373,11 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) {
c.error('a _test.v file should have *at least* one `test_` function', token.Pos{}) c.error('a _test.v file should have *at least* one `test_` function', token.Pos{})
} }
} }
// Print line info and exit
if c.pref.line_info != '' && c.doing_line_info == 0 {
c.do_line_info(c.pref.line_info, ast_files)
exit(0)
}
// Make sure fn main is defined in non lib builds // Make sure fn main is defined in non lib builds
if c.pref.build_mode == .build_module || c.pref.is_test { if c.pref.build_mode == .build_module || c.pref.is_test {
return return
@ -3274,6 +3280,20 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type {
} }
fn (mut c Checker) ident(mut node ast.Ident) ast.Type { fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
if c.doing_line_info > 0 {
// Mini LS hack (v -line-info "a.v:16")
// println('line_nr=${node.pos.line_nr} doing line nr=${c.doing_line_info}')
if node.pos.line_nr == c.doing_line_info {
println('===')
sym := c.table.sym(node.obj.typ)
println('VAR ${node.name}:${sym.name}')
struct_info := sym.info as ast.Struct
for field in struct_info.fields {
field_sym := c.table.sym(field.typ)
println('${field.name}:${field_sym.name}')
}
}
}
// TODO: move this // TODO: move this
if c.const_deps.len > 0 { if c.const_deps.len > 0 {
mut name := node.name mut name := node.name

View File

@ -0,0 +1,50 @@
// Copyright (c) 2019-2023 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license that can be found in the LICENSE file.
module checker
import v.ast
import os
fn (mut c Checker) do_line_info(line string, all_ast_files []&ast.File) {
// println("do_line_info '${line}'")
format_err := 'wrong format, use `-line-info "file.v:24"'
vals := line.split(':')
if vals.len != 2 {
eprintln(format_err)
return
}
file_name := vals[0]
line_nr := vals[1].int() - 1
if !file_name.ends_with('.v') || line_nr == -1 {
eprintln(format_err)
return
}
// println('ok ${c.files.len}')
// Find which file contains the line
mut found := false
mut found_path := ''
mut found_file_idx := -1
for i, file in all_ast_files {
base := os.base(file.path)
// println(base)
if base == file_name {
if found {
eprintln('more than one "${file_name}" found: "${file.path}" and "${found_path}"')
return
}
found = true
found_path = file.path
found_file_idx = i
}
}
if !found {
eprintln('file "${file_name}" not found among those parsed')
return
}
// println('found ${found_path}')
c.doing_line_info = line_nr
c.check_files([all_ast_files[found_file_idx]])
}

View File

@ -11,6 +11,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
util.timing_measure_cumulative(@METHOD) util.timing_measure_cumulative(@METHOD)
} }
mut struct_sym, struct_typ_idx := c.table.find_sym_and_type_idx(node.name) mut struct_sym, struct_typ_idx := c.table.find_sym_and_type_idx(node.name)
// struct_sym.jj0
mut has_generic_types := false mut has_generic_types := false
if mut struct_sym.info is ast.Struct { if mut struct_sym.info is ast.Struct {
if node.language == .v && !c.is_builtin_mod && !struct_sym.info.is_anon { if node.language == .v && !c.is_builtin_mod && !struct_sym.info.is_anon {

View File

@ -186,6 +186,7 @@ pub mut:
out_name_c string // full os.real_path to the generated .tmp.c file; set by builder. out_name_c string // full os.real_path to the generated .tmp.c file; set by builder.
out_name string out_name string
path string // Path to file/folder to compile path string // Path to file/folder to compile
line_info string // `-line-info="file.v:28"`: for "mini VLS" (shows information about objects on provided line)
// //
run_only []string // VTEST_ONLY_FN and -run-only accept comma separated glob patterns. run_only []string // VTEST_ONLY_FN and -run-only accept comma separated glob patterns.
// Only test_ functions that match these patterns will be run. -run-only is valid only for _test.v files. // Only test_ functions that match these patterns will be run. -run-only is valid only for _test.v files.
@ -805,6 +806,10 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
res.cmain = cmdline.option(current_args, '-cmain', '') res.cmain = cmdline.option(current_args, '-cmain', '')
i++ i++
} }
'-line-info' {
res.line_info = cmdline.option(current_args, arg, '')
i++
}
'-use-coroutines' { '-use-coroutines' {
res.use_coroutines = true res.use_coroutines = true
$if macos || linux { $if macos || linux {