aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2021-01-03 19:32:16 +0100
committerDanielGavin <danielgavin5@hotmail.com>2021-01-03 19:32:16 +0100
commit9776aac4ec027dc5dc7d078372b425ab22fd9f47 (patch)
tree7127829086d12bcc848159d519bdec77d3504285 /src/server
parenta7ef0c50bf3aaa697406f796c362795b03699b7b (diff)
infer enum completion in comp literals + start work on completion for directives
Diffstat (limited to 'src/server')
-rw-r--r--src/server/action.odin3
-rw-r--r--src/server/analysis.odin28
-rw-r--r--src/server/completion.odin162
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 {