diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2020-12-31 02:01:41 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2020-12-31 02:01:41 +0100 |
| commit | a7ef0c50bf3aaa697406f796c362795b03699b7b (patch) | |
| tree | b9b82bbf11278b60101357b11bfc105666f9a4e2 /src | |
| parent | 71e2e51443688c42c677cbd5d39c968b7b7cd031 (diff) | |
support completion on enums with assignment
Diffstat (limited to 'src')
| -rw-r--r-- | src/index/collector.odin | 13 | ||||
| -rw-r--r-- | src/server/analysis.odin | 12 | ||||
| -rw-r--r-- | src/server/completion.odin | 64 |
3 files changed, 84 insertions, 5 deletions
diff --git a/src/index/collector.odin b/src/index/collector.odin index d8cb451..75ad261 100644 --- a/src/index/collector.odin +++ b/src/index/collector.odin @@ -137,6 +137,7 @@ collect_enum_fields :: proc(collection: ^SymbolCollection, fields: [] ^ast.Expr, names := make([dynamic] string, 0, collection.allocator); + //ERROR no hover on n in the for, but elsewhere is fine for n in fields { if ident, ok := n.derived.(ast.Ident); ok { @@ -197,7 +198,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri symbol: Symbol; if value_decl, ok := decl.derived.(ast.Value_Decl); ok { - + //ERROR name is not completed or can be hovered name := string(file.src[value_decl.names[0].pos.offset:value_decl.names[0].end.offset]); if len(value_decl.values) == 1 { @@ -244,7 +245,15 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri token_type = .Enum; symbol.value = collect_union_fields(collection, v, package_map); symbol.signature = "union"; + case ast.Basic_Lit: + token = v; + symbol.value = collect_generic(collection, value_decl.values[0], package_map); + case ast.Ident: + token = v; + token_type = .Keyword; + symbol.value = collect_generic(collection, value_decl.values[0], package_map); case: // default + //log.infof("default %v", value_decl.values[0].derived); break; } @@ -340,6 +349,7 @@ get_package_mapping :: proc(file: ast.File, config: ^common.Config, uri: string) //collection specified if i := strings.index(imp.fullpath, ":"); i != -1 { + //ERROR hover on collection should show string collection := imp.fullpath[1:i]; p := imp.fullpath[i+1:len(imp.fullpath)-1]; @@ -377,6 +387,7 @@ get_package_mapping :: proc(file: ast.File, config: ^common.Config, uri: string) if imp.name.text != "" { name = imp.name.text; + //ERROR hover is wrong on name } else { diff --git a/src/server/analysis.odin b/src/server/analysis.odin index 9ee28b5..d84b43a 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -46,6 +46,7 @@ DocumentPositionContext :: struct { parent_comp_lit: ^ast.Comp_Lit, //used for completion implicit: bool, //used for completion binary: ^ast.Binary_Expr, //used for completion + assign: ^ast.Assign_Stmt, //used for completion hint: DocumentPositionContextHint, }; @@ -1304,7 +1305,7 @@ get_locals_value_decl :: proc(file: ast.File, value_decl: ast.Value_Decl, ast_co } -get_locals_stmt :: proc(file: ast.File, stmt: ^ast.Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext) { +get_locals_stmt :: proc(file: ast.File, stmt: ^ast.Stmt, ast_context: ^AstContext, document_position: ^DocumentPositionContext, save_assign := false) { ast_context.use_locals = true; ast_context.use_globals = true; @@ -1342,7 +1343,9 @@ get_locals_stmt :: proc(file: ast.File, stmt: ^ast.Stmt, ast_context: ^AstContex case Proc_Lit: get_locals_stmt(file, v.body, ast_context, document_position); case Assign_Stmt: - get_locals_assign_stmt(file, v, ast_context); + if save_assign { + get_locals_assign_stmt(file, v, ast_context); + } case Using_Stmt: get_locals_using_stmt(file, v, ast_context); case When_Stmt: @@ -1421,7 +1424,7 @@ get_locals_if_stmt :: proc(file: ast.File, stmt: ast.If_Stmt, ast_context: ^AstC return; } - get_locals_stmt(file, stmt.init, ast_context, document_position); + get_locals_stmt(file, stmt.init, ast_context, document_position, true); get_locals_stmt(file, stmt.body, ast_context, document_position); get_locals_stmt(file, stmt.else_stmt, ast_context, document_position); } @@ -1520,7 +1523,7 @@ get_locals_for_stmt :: proc(file: ast.File, stmt: ast.For_Stmt, ast_context: ^As return; } - get_locals_stmt(file, stmt.init, ast_context, document_position); + get_locals_stmt(file, stmt.init, ast_context, document_position, true); get_locals_stmt(file, stmt.body, ast_context, document_position); } @@ -2319,6 +2322,7 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP r := cast(^Tag_Stmt)node; get_document_position(r.stmt, position_context); case Assign_Stmt: + position_context.assign = cast(^Assign_Stmt)node; get_document_position(n.lhs, position_context); get_document_position(n.rhs, position_context); case Block_Stmt: diff --git a/src/server/completion.odin b/src/server/completion.odin index c11633f..1b3733d 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -398,6 +398,70 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc } + else if position_context.assign != nil && position_context.assign.rhs != nil && position_context.assign.lhs != nil { + + rhs_index: int; + + for elem in position_context.assign.rhs { + + if position_in_node(elem, position_context.position) { + break; + } + + else { + + //procedures are the only types that can return more than one value + if symbol, ok := resolve_type_expression(ast_context, elem); ok { + + if procedure, ok := symbol.value.(index.SymbolProcedureValue); ok { + + if procedure.return_types == nil { + return; + } + + rhs_index += len(procedure.return_types); + } + + else { + rhs_index += 1; + } + + } + + } + + } + + if len(position_context.assign.lhs) > rhs_index { + + log.info("in lhs %v", position_context.assign.lhs[rhs_index].derived); + + if lhs, ok := resolve_type_expression(ast_context, position_context.assign.lhs[rhs_index]); ok { + + log.infof("lhs %v", lhs); + + #partial switch v in lhs.value { + case index.SymbolEnumValue: + for name in v.names { + + item := CompletionItem { + label = name, + kind = .EnumMember, + detail = name, + }; + + append(&items, item); + + } + + } + + } + + } + + } + else if position_context.returns != nil && position_context.function != nil { return_index: int; |