diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2021-01-03 19:32:16 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2021-01-03 19:32:16 +0100 |
| commit | 9776aac4ec027dc5dc7d078372b425ab22fd9f47 (patch) | |
| tree | 7127829086d12bcc848159d519bdec77d3504285 /src/server | |
| parent | a7ef0c50bf3aaa697406f796c362795b03699b7b (diff) | |
infer enum completion in comp literals + start work on completion for directives
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/action.odin | 3 | ||||
| -rw-r--r-- | src/server/analysis.odin | 28 | ||||
| -rw-r--r-- | src/server/completion.odin | 162 |
3 files changed, 147 insertions, 46 deletions
diff --git a/src/server/action.odin b/src/server/action.odin new file mode 100644 index 0000000..ad13e0b --- /dev/null +++ b/src/server/action.odin @@ -0,0 +1,3 @@ +package server + + diff --git a/src/server/analysis.odin b/src/server/analysis.odin index d84b43a..1de7c54 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -287,22 +287,22 @@ resolve_type_comp_literal :: proc(ast_context: ^AstContext, position_context: ^D for elem in current_comp_lit.elems { - if position_in_node(elem, position_context.position) { - - if field_value, ok := elem.derived.(ast.Field_Value); ok { + if !position_in_node(elem, position_context.position) { + continue; + } - if comp_lit, ok := field_value.value.derived.(ast.Comp_Lit); ok { + if field_value, ok := elem.derived.(ast.Field_Value); ok { - if s, ok := current_symbol.value.(index.SymbolStructValue); ok { + if comp_lit, ok := field_value.value.derived.(ast.Comp_Lit); ok { - for name, i in s.names { + if s, ok := current_symbol.value.(index.SymbolStructValue); ok { - if name == field_value.field.derived.(ast.Ident).name { + for name, i in s.names { - if symbol, ok := resolve_type_expression(ast_context, s.types[i]); ok { - return resolve_type_comp_literal(ast_context, position_context, symbol, cast(^ast.Comp_Lit)field_value.value); - } + if name == field_value.field.derived.(ast.Ident).name { + if symbol, ok := resolve_type_expression(ast_context, s.types[i]); ok { + return resolve_type_comp_literal(ast_context, position_context, symbol, cast(^ast.Comp_Lit)field_value.value); } } @@ -1134,12 +1134,16 @@ make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type, id names := make([dynamic] string, context.temp_allocator); - for field in v.fields { + for n in v.fields { - if ident, ok := field.derived.(ast.Ident); ok { + if ident, ok := n.derived.(ast.Ident); ok { append(&names, ident.name); } + else if field, ok := n.derived.(ast.Field_Value); ok { + append(&names, field.field.derived.(ast.Ident).name); + } + } symbol.value = index.SymbolEnumValue { diff --git a/src/server/completion.odin b/src/server/completion.odin index 1b3733d..e518695 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -112,50 +112,94 @@ field_exists_in_comp_lit :: proc(comp_lit: ^ast.Comp_Lit, name: string) -> bool return false; } -get_comp_lit_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) { +get_directive_completion :: proc(ast_context: ^AstContext, postition_context: ^DocumentPositionContext, list: ^CompletionList) { + + list.isIncomplete = false; items := make([dynamic] CompletionItem, context.temp_allocator); - if position_context.parent_comp_lit.type != nil { + /* + Right now just return all the possible completions, but later on I should give the context specific ones + */ + + directive_list := [] string { + "file", + "line", + "packed", + "raw_union", + "align", + "no_nil", + "complete", + "no_alias", + "caller_location", + "require_results", + "type", + "bounds_check", + "no_bounds_check", + "assert", + "defined", + "procedure", + "load", + "partial", + }; - if symbol, ok := resolve_type_expression(ast_context, position_context.parent_comp_lit.type); ok { + for elem in directive_list { - if comp_symbol, ok := resolve_type_comp_literal(ast_context, position_context, symbol, position_context.parent_comp_lit); ok { + item := CompletionItem { + detail = elem, + }; - #partial switch v in comp_symbol.value { - case index.SymbolStructValue: - for name, i in v.names { + append(&items, item); - //ERROR no completion on name and hover - if resolved, ok := resolve_type_expression(ast_context, v.types[i]); ok { + } - if field_exists_in_comp_lit(position_context.comp_lit, name) { - continue; - } - resolved.signature = index.node_to_string(v.types[i]); - resolved.pkg = comp_symbol.name; - resolved.name = name; - resolved.type = .Field; +} + +get_comp_lit_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) { + + items := make([dynamic] CompletionItem, context.temp_allocator); + + if position_context.parent_comp_lit.type == nil { + return; + } + + if symbol, ok := resolve_type_expression(ast_context, position_context.parent_comp_lit.type); ok { + + if comp_symbol, ok := resolve_type_comp_literal(ast_context, position_context, symbol, position_context.parent_comp_lit); ok { - item := CompletionItem { - label = resolved.name, - kind = cast(CompletionItemKind) resolved.type, - detail = concatenate_symbols_information(ast_context, resolved), - documentation = resolved.doc, - }; + #partial switch v in comp_symbol.value { + case index.SymbolStructValue: + for name, i in v.names { - append(&items, item); + //ERROR no completion on name and hover + if resolved, ok := resolve_type_expression(ast_context, v.types[i]); ok { + + if field_exists_in_comp_lit(position_context.comp_lit, name) { + continue; } + + resolved.signature = index.node_to_string(v.types[i]); + resolved.pkg = comp_symbol.name; + resolved.name = name; + resolved.type = .Field; + + item := CompletionItem { + label = resolved.name, + kind = cast(CompletionItemKind) resolved.type, + detail = concatenate_symbols_information(ast_context, resolved), + documentation = resolved.doc, + }; + + append(&items, item); } } } } } - list.items = items[:]; - log.info("comp lit completion!"); + list.items = items[:]; } get_selector_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) { @@ -357,7 +401,65 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc ast_context.current_package = ast_context.document_package; } - if position_context.binary != nil && (position_context.binary.op.text == "==" || position_context.binary.op.text == "!=") { + if position_context.comp_lit != nil { + + if position_context.parent_comp_lit.type == nil { + return; + } + + field_name: string; + + for elem in position_context.comp_lit.elems { + + if position_in_node(elem, position_context.position) { + + if field, ok := elem.derived.(ast.Field_Value); ok { + field_name = field.field.derived.(ast.Ident).name; + } + + } + + } + + if field_name == "" { + return; + } + + if symbol, ok := resolve_type_expression(ast_context, position_context.parent_comp_lit.type); ok { + + if comp_symbol, ok := resolve_type_comp_literal(ast_context, position_context, symbol, position_context.parent_comp_lit); ok { + + if s, ok := comp_symbol.value.(index.SymbolStructValue); ok { + + for name, i in s.names { + + if name != field_name { + continue; + } + + if enum_symbol, ok := resolve_type_expression(ast_context, s.types[i]); ok { + + if enum_value, ok := enum_symbol.value.(index.SymbolEnumValue); ok { + + for enum_name in enum_value.names { + + item := CompletionItem { + label = enum_name, + kind = .EnumMember, + detail = enum_name, + }; + + append(&items, item); + } + } + } + } + } + } + } + } + + else if position_context.binary != nil && (position_context.binary.op.text == "==" || position_context.binary.op.text == "!=") { context_node: ^ast.Expr; enum_node: ^ast.Expr; @@ -389,13 +491,9 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc append(&items, item); } - } - } - } - } else if position_context.assign != nil && position_context.assign.rhs != nil && position_context.assign.lhs != nil { @@ -434,12 +532,8 @@ get_implicit_completion :: proc(ast_context: ^AstContext, position_context: ^Doc 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 { |