diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 994c9986b0..6e0d60b26e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -88,7 +88,7 @@ mut: // 1 for statements directly at each inner scope level; // increases for `x := if cond { statement_list1} else {statement_list2}`; // 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 ensure_generic_type_level int // to avoid infinite recursion segfaults in ensure_generic_type_specify_type_names cur_orm_ts ast.TypeSymbol @@ -116,6 +116,7 @@ mut: inside_decl_rhs bool inside_if_guard bool // true inside the guard condition of `if x := opt() {}` 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 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 @@ -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{}) } } + // 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 if c.pref.build_mode == .build_module || c.pref.is_test { 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 { + 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 if c.const_deps.len > 0 { mut name := node.name diff --git a/vlib/v/checker/line_info.v b/vlib/v/checker/line_info.v new file mode 100644 index 0000000000..5379d05f32 --- /dev/null +++ b/vlib/v/checker/line_info.v @@ -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]]) +} diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 320e306f3a..723a9e8d7c 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -11,6 +11,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { util.timing_measure_cumulative(@METHOD) } mut struct_sym, struct_typ_idx := c.table.find_sym_and_type_idx(node.name) + // struct_sym.jj0 mut has_generic_types := false if mut struct_sym.info is ast.Struct { if node.language == .v && !c.is_builtin_mod && !struct_sym.info.is_anon { diff --git a/vlib/v/pref/pref.v b/vlib/v/pref/pref.v index 95806b3f93..28f54358c4 100644 --- a/vlib/v/pref/pref.v +++ b/vlib/v/pref/pref.v @@ -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 string 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. // 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', '') i++ } + '-line-info' { + res.line_info = cmdline.option(current_args, arg, '') + i++ + } '-use-coroutines' { res.use_coroutines = true $if macos || linux {