mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
vls: improve and simplify autocomplete; remove the scanner hack
Some checks are pending
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
Some checks are pending
Graphics CI / gg-regressions (push) Waiting to run
vlib modules CI / build-module-docs (push) Waiting to run
native backend CI / native-backend-ubuntu (push) Waiting to run
native backend CI / native-backend-windows (push) Waiting to run
Shy and PV CI / v-compiles-puzzle-vibes (push) Waiting to run
Sanitized CI / sanitize-undefined-clang (push) Waiting to run
Sanitized CI / sanitize-undefined-gcc (push) Waiting to run
Sanitized CI / tests-sanitize-address-clang (push) Waiting to run
Sanitized CI / sanitize-address-msvc (push) Waiting to run
Sanitized CI / sanitize-address-gcc (push) Waiting to run
Sanitized CI / sanitize-memory-clang (push) Waiting to run
sdl CI / v-compiles-sdl-examples (push) Waiting to run
Time CI / time-linux (push) Waiting to run
Time CI / time-macos (push) Waiting to run
Time CI / time-windows (push) Waiting to run
toml CI / toml-module-pass-external-test-suites (push) Waiting to run
Tools CI / tools-linux (tcc) (push) Waiting to run
Tools CI / tools-linux (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-macos (clang) (push) Waiting to run
Tools CI / tools-windows (gcc) (push) Waiting to run
Tools CI / tools-windows (msvc) (push) Waiting to run
Tools CI / tools-windows (tcc) (push) Waiting to run
Tools CI / tools-docker-ubuntu-musl (push) Waiting to run
vab CI / vab-compiles-v-examples (push) Waiting to run
vab CI / v-compiles-os-android (push) Waiting to run
wasm backend CI / wasm-backend (ubuntu-22.04) (push) Waiting to run
wasm backend CI / wasm-backend (windows-2022) (push) Waiting to run
This commit is contained in:
parent
963e3e8ae2
commit
9391b7c234
9 changed files with 86 additions and 40 deletions
|
@ -11,19 +11,31 @@ struct ACFieldMethod {
|
|||
typ string
|
||||
}
|
||||
|
||||
fn abs(a int) int {
|
||||
if a < 0 {
|
||||
return -a
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
||||
// Mini LS hack (v -line-info "a.v:16")
|
||||
if c.pref.is_verbose {
|
||||
println(
|
||||
'checker.ident() info.line_nr=${c.pref.linfo.line_nr} node.line_nr=${node.pos.line_nr} ' +
|
||||
' pwd="${os.getwd()}" file="${c.file.path}", ' +
|
||||
' pref.linfo.path="${c.pref.linfo.path}" node.name="${node.name}" expr="${c.pref.linfo.expr}"')
|
||||
'checker.ident_autocomplete() info.line_nr=${c.pref.linfo.line_nr} node.line_nr=${node.pos.line_nr} ' +
|
||||
' node.col=${node.pos.col} pwd="${os.getwd()}" file="${c.file.path}", ' +
|
||||
//' pref.linfo.path="${c.pref.linfo.path}" node.name="${node.name}" expr="${c.pref.linfo.expr}"')
|
||||
' pref.linfo.path="${c.pref.linfo.path}" node.name="${node.name}" col="${c.pref.linfo.col}"')
|
||||
}
|
||||
// Make sure this ident is on the same line as requeste, in the same file, and has the same name
|
||||
same_line := node.pos.line_nr in [c.pref.linfo.line_nr - 1, c.pref.linfo.line_nr + 1, c.pref.linfo.line_nr]
|
||||
if !same_line {
|
||||
return
|
||||
}
|
||||
same_name := c.pref.linfo.expr == node.name
|
||||
if !same_name {
|
||||
// same_name := c.pref.linfo.expr == node.name
|
||||
same_col := abs(c.pref.linfo.col - node.pos.col) < 3
|
||||
// if !same_name {
|
||||
if !same_col {
|
||||
return
|
||||
}
|
||||
abs_path := os.join_path(os.getwd(), c.file.path)
|
||||
|
@ -39,9 +51,14 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
|||
sym := c.table.sym(c.unwrap_generic(node.obj.typ))
|
||||
// sb.writeln('VAR ${node.name}:${sym.name} ${node.pos.line_nr}')
|
||||
nt := '${node.name}:${sym.name}'
|
||||
sb.writeln('{')
|
||||
if !c.pref.linfo.vars_printed[nt] { // avoid dups
|
||||
sb.writeln('===')
|
||||
sb.writeln('VAR ${nt}') //${node.name}:${sym.name}')
|
||||
// sb.writeln('===')
|
||||
// sb.writeln('VAR ${nt}') //${node.name}:${sym.name}')
|
||||
sb.writeln('\t"name":"${node.name}",')
|
||||
sb.writeln('\t"type":"${sym.name}",')
|
||||
sb.writeln('\t"fields":[')
|
||||
|
||||
// print_backtrace()
|
||||
/*
|
||||
if sym.kind == .alias {
|
||||
|
@ -75,9 +92,14 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
|||
fields << ACFieldMethod{build_method_summary(method), method_ret_type.name}
|
||||
}
|
||||
fields.sort(a.name < b.name)
|
||||
for field in fields {
|
||||
sb.writeln('${field.name}:${field.typ}')
|
||||
for i, field in fields {
|
||||
// sb.writeln('${field.name}:${field.typ}')
|
||||
sb.write_string('\t\t"${field.name}:${field.typ}"')
|
||||
if i < fields.len - 1 {
|
||||
sb.writeln(', ')
|
||||
}
|
||||
}
|
||||
sb.writeln('\n\t]\n}')
|
||||
res := sb.str().trim_space()
|
||||
if res != '' {
|
||||
println(res)
|
||||
|
|
|
@ -430,12 +430,13 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) {
|
|||
// After the main checker run, run the line info check, print line info, and exit (if it's present)
|
||||
if !c.pref.linfo.is_running && c.pref.line_info != '' { //'' && c.pref.linfo.line_nr == 0 {
|
||||
// c.do_line_info(c.pref.line_info, ast_files)
|
||||
println('setting is_running=true, pref.path=${c.pref.linfo.path} curdir' + os.getwd())
|
||||
// println('setting is_running=true, pref.path=${c.pref.linfo.path} curdir' + os.getwd())
|
||||
c.pref.linfo.is_running = true
|
||||
// println('linfo path=${c.pref.linfo.path}')
|
||||
for i, file in ast_files {
|
||||
// println(file.path)
|
||||
if file.path == c.pref.linfo.path {
|
||||
println('running c.check_files')
|
||||
// println('running c.check_files')
|
||||
c.check_files([ast_files[i]])
|
||||
exit(0)
|
||||
} else if file.path.starts_with('./') {
|
||||
|
|
|
@ -2635,6 +2635,13 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
|||
if p.disallow_declarations_in_script_mode() {
|
||||
return ast.SumTypeDecl{}
|
||||
}
|
||||
if p.is_vls && p.tok.is_key() {
|
||||
// End parsing after `type ` in vls mode to avoid lots of junk errors
|
||||
// If next token is a key, the type wasn't finished
|
||||
p.error('expecting type name')
|
||||
p.should_abort = true
|
||||
return ast.AliasTypeDecl{}
|
||||
}
|
||||
mut name := p.check_name()
|
||||
mut language := ast.Language.v
|
||||
if name.len == 1 && name[0].is_capital() {
|
||||
|
|
|
@ -125,6 +125,16 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
|
|||
}
|
||||
}
|
||||
p.check(.lcbr)
|
||||
// if p.is_vls && p.tok.kind == .key_struct { // p.tok.is_key() {
|
||||
if p.is_vls && p.tok.is_key() {
|
||||
// End parsing after `struct Foo {` in vls mode to avoid lots of junk errors
|
||||
// If next token after { is a key, the struct wasn't finished
|
||||
p.error('expected `}` to finish a struct definition')
|
||||
p.should_abort = true
|
||||
return ast.StructDecl{
|
||||
name: name
|
||||
}
|
||||
}
|
||||
pre_comments << p.eat_comments()
|
||||
mut i := 0
|
||||
for p.tok.kind != .rcbr {
|
||||
|
|
|
@ -4,7 +4,7 @@ module pref
|
|||
|
||||
fn (mut p Preferences) parse_line_info(line string) {
|
||||
// println("parse_line_info '${line}'")
|
||||
format_err := 'wrong format, use `-line-info "file.v:24:expr_to_look_up"'
|
||||
format_err := 'wrong format, use `-line-info "file.v:24:7"'
|
||||
vals := line.split(':')
|
||||
if vals.len != 3 {
|
||||
eprintln(format_err)
|
||||
|
@ -12,7 +12,8 @@ fn (mut p Preferences) parse_line_info(line string) {
|
|||
}
|
||||
file_name := vals[0]
|
||||
line_nr := vals[1].int() - 1
|
||||
expr := vals[2]
|
||||
col := vals[2].int() - 1
|
||||
// expr := vals[2]
|
||||
if !file_name.ends_with('.v') || line_nr == -1 {
|
||||
eprintln(format_err)
|
||||
return
|
||||
|
@ -20,20 +21,7 @@ fn (mut p Preferences) parse_line_info(line string) {
|
|||
p.linfo = LineInfo{
|
||||
line_nr: line_nr
|
||||
path: file_name
|
||||
expr: expr
|
||||
// expr: expr
|
||||
col: col
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_line_info_expr_to_program_text(raw_text string, linfo LineInfo) string {
|
||||
lines := raw_text.split('\n')
|
||||
lines_before := lines[..linfo.line_nr].join('\n')
|
||||
mut expr := linfo.expr
|
||||
if !expr.contains('.') {
|
||||
// Single variable, `foo` => `foo.xx`
|
||||
// expr += '.xxx'
|
||||
// expr = '_ = ' + expr
|
||||
expr = 'println(' + expr + ')'
|
||||
}
|
||||
lines_after := lines[linfo.line_nr..].join('\n')
|
||||
return lines_before + '\n' + expr + '\n' + lines_after
|
||||
}
|
||||
|
|
|
@ -266,7 +266,8 @@ pub struct LineInfo {
|
|||
pub mut:
|
||||
line_nr int // a quick single file run when called with v -line-info (contains line nr to inspect)
|
||||
path string // same, but stores the path being parsed
|
||||
expr string // "foo" or "foo.bar" V code (expression) which needs autocomplete
|
||||
// expr string // "foo" or "foo.bar" V code (expression) which needs autocomplete
|
||||
col int
|
||||
is_running bool // so that line info is fetched only on the second checker run
|
||||
vars_printed map[string]bool // to avoid dups
|
||||
}
|
||||
|
|
|
@ -111,14 +111,7 @@ pub fn new_scanner_file(file_path string, comments_mode CommentsMode, pref_ &pre
|
|||
if !os.is_file(file_path) {
|
||||
return error('${file_path} is not a .v file')
|
||||
}
|
||||
mut raw_text := util.read_file(file_path) or { return err }
|
||||
if pref_.line_info != '' {
|
||||
// Add line info expr to the scanner text
|
||||
abs_path := os.join_path(os.getwd(), file_path)
|
||||
if pref_.linfo.path in [file_path, abs_path] {
|
||||
raw_text = pref.add_line_info_expr_to_program_text(raw_text, pref_.linfo)
|
||||
}
|
||||
}
|
||||
raw_text := util.read_file(file_path) or { return err }
|
||||
mut s := &Scanner{
|
||||
pref: pref_
|
||||
text: raw_text
|
||||
|
|
|
@ -390,6 +390,10 @@ pub fn (t Token) is_next_to(pre_token Token) bool {
|
|||
return t.pos - pre_token.pos == pre_token.len
|
||||
}
|
||||
|
||||
pub fn (t Token) is_key() bool {
|
||||
return int(t.kind) > int(Kind.keyword_beg) && int(t.kind) < int(Kind.keyword_end)
|
||||
}
|
||||
|
||||
pub fn (t Token) str() string {
|
||||
mut s := t.kind.str()
|
||||
if s.len == 0 {
|
||||
|
|
20
vlib/v/token/token_test.v
Normal file
20
vlib/v/token/token_test.v
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2019-2024 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 token
|
||||
|
||||
fn test_is_key() {
|
||||
// Test that tokens with keyword kinds return true.
|
||||
assert Token{
|
||||
kind: .key_as
|
||||
}.is_key()
|
||||
assert Token{
|
||||
kind: .key_fn
|
||||
}.is_key()
|
||||
assert Token{
|
||||
kind: .key_mut
|
||||
}.is_key()
|
||||
assert !Token{
|
||||
kind: .name
|
||||
}.is_key()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue