mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
vls: autocomplete for module functions: e.g. os. ...
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 (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (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 (clang) (push) Waiting to run
Tools CI / tools-linux (gcc) (push) Waiting to run
Tools CI / tools-linux (tcc) (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
71d32ea6ad
commit
db661204d9
3 changed files with 72 additions and 6 deletions
|
@ -18,6 +18,9 @@ fn abs(a int) int {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (mut c Checker) run_ac(ast_file &ast.File) {
|
||||||
|
}
|
||||||
|
|
||||||
fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
||||||
// Mini LS hack (v -line-info "a.v:16")
|
// Mini LS hack (v -line-info "a.v:16")
|
||||||
if c.pref.is_verbose {
|
if c.pref.is_verbose {
|
||||||
|
@ -25,16 +28,14 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
||||||
'checker.ident_autocomplete() info.line_nr=${c.pref.linfo.line_nr} node.line_nr=${node.pos.line_nr} ' +
|
'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}", ' +
|
' 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}" expr="${c.pref.linfo.expr}"')
|
||||||
' pref.linfo.path="${c.pref.linfo.path}" node.name="${node.name}" col="${c.pref.linfo.col}"')
|
' pref.linfo.path="${c.pref.linfo.path}" node.name="${node.name}" node.mod="${node.mod}" 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
|
// 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]
|
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 {
|
if !same_line {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// same_name := c.pref.linfo.expr == node.name
|
|
||||||
same_col := abs(c.pref.linfo.col - node.pos.col) < 3
|
same_col := abs(c.pref.linfo.col - node.pos.col) < 3
|
||||||
// if !same_name {
|
|
||||||
if !same_col {
|
if !same_col {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -42,6 +43,14 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
||||||
if c.pref.linfo.path !in [c.file.path, abs_path] {
|
if c.pref.linfo.path !in [c.file.path, abs_path] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Module autocomplete
|
||||||
|
// `os. ...`
|
||||||
|
if node.name == '' && node.mod != 'builtin' {
|
||||||
|
c.module_autocomplete(node)
|
||||||
|
return
|
||||||
|
} else if node.name == '' && node.mod == 'builtin' {
|
||||||
|
return
|
||||||
|
}
|
||||||
mut sb := strings.new_builder(10)
|
mut sb := strings.new_builder(10)
|
||||||
if node.kind == .unresolved {
|
if node.kind == .unresolved {
|
||||||
// println(node)
|
// println(node)
|
||||||
|
@ -67,6 +76,7 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mut fields := []ACFieldMethod{cap: 10}
|
mut fields := []ACFieldMethod{cap: 10}
|
||||||
|
mut methods := []ACFieldMethod{cap: 10}
|
||||||
if sym.kind == .struct {
|
if sym.kind == .struct {
|
||||||
// Add fields, but only if it's a struct.
|
// Add fields, but only if it's a struct.
|
||||||
struct_info := sym.info as ast.Struct
|
struct_info := sym.info as ast.Struct
|
||||||
|
@ -85,11 +95,13 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
||||||
fields << ACFieldMethod{'cap', 'int'}
|
fields << ACFieldMethod{'cap', 'int'}
|
||||||
}
|
}
|
||||||
// array_info := sym.info as ast.Array
|
// array_info := sym.info as ast.Array
|
||||||
|
} else if sym.kind == .string {
|
||||||
|
fields << ACFieldMethod{'len', 'int'}
|
||||||
}
|
}
|
||||||
// Aliases and other types can have methods, add them
|
// Aliases and other types can have methods, add them
|
||||||
for method in sym.methods {
|
for method in sym.methods {
|
||||||
method_ret_type := c.table.sym(method.return_type)
|
method_ret_type := c.table.sym(method.return_type)
|
||||||
fields << ACFieldMethod{build_method_summary(method), method_ret_type.name}
|
methods << ACFieldMethod{build_method_summary(method), method_ret_type.name}
|
||||||
}
|
}
|
||||||
fields.sort(a.name < b.name)
|
fields.sort(a.name < b.name)
|
||||||
for i, field in fields {
|
for i, field in fields {
|
||||||
|
@ -99,6 +111,14 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
||||||
sb.writeln(', ')
|
sb.writeln(', ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sb.writeln('\n\t], "methods":[')
|
||||||
|
|
||||||
|
for i, method in methods {
|
||||||
|
sb.write_string('\t\t"${method.name}:${method.typ}"')
|
||||||
|
if i < methods.len - 1 {
|
||||||
|
sb.writeln(', ')
|
||||||
|
}
|
||||||
|
}
|
||||||
sb.writeln('\n\t]\n}')
|
sb.writeln('\n\t]\n}')
|
||||||
res := sb.str().trim_space()
|
res := sb.str().trim_space()
|
||||||
if res != '' {
|
if res != '' {
|
||||||
|
@ -108,9 +128,36 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Checker) module_autocomplete(node ast.Ident) {
|
||||||
|
mut sb := strings.new_builder(10)
|
||||||
|
// println(c.table.fns)
|
||||||
|
sb.writeln('{"methods":[')
|
||||||
|
prefix := node.mod + '.'
|
||||||
|
mut empty := true
|
||||||
|
for _, f in c.table.fns {
|
||||||
|
mut name := f.name
|
||||||
|
if name.starts_with(prefix) {
|
||||||
|
empty = false
|
||||||
|
if name.contains('__static__') {
|
||||||
|
name = name.replace('__static__', '.')
|
||||||
|
}
|
||||||
|
name = name.after('.') // The user already typed `mod.`, so suggest the name without module
|
||||||
|
sb.writeln('"${name}:int" ,')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !empty {
|
||||||
|
sb.go_back(2) // remove final ,
|
||||||
|
}
|
||||||
|
sb.writeln(']}')
|
||||||
|
println(sb.str().trim_space())
|
||||||
|
}
|
||||||
|
|
||||||
fn build_method_summary(method ast.Fn) string {
|
fn build_method_summary(method ast.Fn) string {
|
||||||
mut s := method.name + '('
|
mut s := method.name + '('
|
||||||
for i, param in method.params {
|
for i, param in method.params {
|
||||||
|
if i == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
s += param.name
|
s += param.name
|
||||||
if i < method.params.len - 1 {
|
if i < method.params.len - 1 {
|
||||||
s += ', '
|
s += ', '
|
||||||
|
|
|
@ -444,6 +444,7 @@ pub fn (mut c Checker) check_files(ast_files []&ast.File) {
|
||||||
abs_path := os.join_path(os.getwd(), file.path).replace('/./', '/') // TODO: join_path shouldn't have /./
|
abs_path := os.join_path(os.getwd(), file.path).replace('/./', '/') // TODO: join_path shouldn't have /./
|
||||||
if abs_path == c.pref.linfo.path {
|
if abs_path == c.pref.linfo.path {
|
||||||
c.check_files([ast_files[i]])
|
c.check_files([ast_files[i]])
|
||||||
|
c.run_ac(ast_files[i])
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4054,7 +4055,8 @@ fn (mut c Checker) resolve_var_fn(func &ast.Fn, mut node ast.Ident, name string)
|
||||||
|
|
||||||
fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
|
||||||
if c.pref.linfo.is_running {
|
if c.pref.linfo.is_running {
|
||||||
// Mini LS hack (v -line-info "a.v:16")
|
// LS hack (v -line-info "a.v:16")
|
||||||
|
// TODO perf $if
|
||||||
c.ident_autocomplete(node)
|
c.ident_autocomplete(node)
|
||||||
}
|
}
|
||||||
// TODO: move this
|
// TODO: move this
|
||||||
|
|
|
@ -1490,8 +1490,25 @@ fn (mut p Parser) name_expr() ast.Expr {
|
||||||
// prepend the full import
|
// prepend the full import
|
||||||
mod = p.imports[p.tok.lit]
|
mod = p.imports[p.tok.lit]
|
||||||
}
|
}
|
||||||
|
if p.pref.linfo.is_running {
|
||||||
|
// VLS autocomplete for module fns: `os...`
|
||||||
|
// TODO perf $if
|
||||||
|
// p.module_autocomplete(node)
|
||||||
|
}
|
||||||
|
line_nr := p.tok.line_nr
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
|
if p.is_vls && p.tok.line_nr != line_nr {
|
||||||
|
// The user typed `os.`, we have to display all possible `os` functions.
|
||||||
|
// Turn this name expression into an Ident, since that is what expected
|
||||||
|
// by `Checker.ident_autocomplete()`
|
||||||
|
return ast.Ident{
|
||||||
|
name: ''
|
||||||
|
mod: mod
|
||||||
|
pos: p.prev_tok.pos()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p.expr_mod = mod
|
p.expr_mod = mod
|
||||||
}
|
}
|
||||||
lit0_is_capital := if p.tok.kind != .eof && p.tok.lit.len > 0 {
|
lit0_is_capital := if p.tok.kind != .eof && p.tok.lit.len > 0 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue