aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2020-11-26 22:02:10 +0100
committerDanielGavin <danielgavin5@hotmail.com>2020-11-26 22:02:10 +0100
commit3f7be3c62f53617c97089d6a964aabab99ab2690 (patch)
tree8a889e91c567c2e7458cf6e40c9725a5d8495058 /src/server
parent37f790706008715ed361f69ab3e984f3022a2dc9 (diff)
start work on enum and unions
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin179
-rw-r--r--src/server/documents.odin2
2 files changed, 140 insertions, 41 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 3249375..3a82940 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -32,6 +32,7 @@ DocumentPositionContext :: struct {
identifier: ^ast.Node,
field: ^ast.Expr, //used for completion
call: ^ast.Expr, //used for signature help
+ returns: ^ast.Expr, //used for completion
hint: DocumentPositionContextHint,
};
@@ -401,10 +402,10 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
using ast;
- log.info("overload");
+ //log.info("overload");
if ast_context.call == nil {
- log.info("no call");
+ //log.info("no call");
return index.Symbol {}, false;
}
@@ -417,7 +418,6 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
if procedure, ok := f.value.(index.SymbolProcedureValue); ok {
if len(procedure.arg_types) < len(call_expr.args) {
- log.infof("bigger than %v, %v", len(procedure.arg_types), len(call_expr.args));
continue;
}
@@ -437,37 +437,12 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
}
else {
- log.debug("Failed to resolve call expr");
+ //log.debug("Failed to resolve call expr");
return index.Symbol {}, false;
}
}
- /*
- for proc_args, i in call_expr.args {
-
- if eval_call_expr, ok := resolve_type_expression(ast_context, call_expr.args[i], false); ok {
-
- #partial switch v in eval_call_expr.value {
- case index.SymbolProcedureValue:
- case index.SymbolGenericValue:
- if !common.node_equal(v.expr, proc_args.type) {
- break next_fn;
- }
- case index.SymbolStructValue:
- }
-
- }
-
- else {
- log.debug("Failed to resolve call expr");
- return index.Symbol {}, false;
- }
-
- }
- */
-
-
- log.debugf("return overload %v", f);
+ //log.debugf("return overload %v", f);
return f, true;
}
@@ -521,6 +496,15 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr, expec
return resolve_type_identifier(ast_context, v, expect_identifier);
case Basic_Lit:
return resolve_basic_lit(ast_context, v);
+ case Pointer_Type:
+ if v2, ok := v.elem.derived.(ast.Pointer_Type); !ok {
+ return resolve_type_expression(ast_context, v.elem, false);
+ }
+
+ else {
+ return resolve_type_expression(ast_context, node, false);
+ }
+
case Index_Expr:
indexed, ok := resolve_type_expression(ast_context, v.expr, false);
@@ -540,6 +524,9 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr, expec
case Call_Expr:
ast_context.call = node;
return resolve_type_expression(ast_context, v.expr, false);
+ case Implicit_Selector_Expr:
+ log.info(v);
+ return index.Symbol {}, false;
case Selector_Expr:
if selector, ok := resolve_type_expression(ast_context, v.expr); ok {
@@ -553,6 +540,10 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr, expec
ast_context.current_package = selector.scope;
}
+ else {
+ ast_context.current_package = ast_context.document_package;
+ }
+
for name, i in s.names {
if v.field != nil && strings.compare(name, v.field.name) == 0 {
return resolve_type_expression(ast_context, s.types[i], false);
@@ -590,6 +581,10 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr, expec
ast_context.current_package = symbol.scope;
}
+ else {
+ ast_context.current_package = ast_context.document_package;
+ }
+
for name, i in s2.names {
if v.field != nil && strings.compare(name, v.field.name) == 0 {
return resolve_type_expression(ast_context, s2.types[i], false);
@@ -632,6 +627,10 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
switch v in local.derived {
case Ident:
return resolve_type_identifier(ast_context, v);
+ case Union_Type:
+ return make_symbol_union_from_ast(ast_context, v), !expect_identifier;
+ case Enum_Type:
+ return make_symbol_enum_from_ast(ast_context, v), !expect_identifier;
case Struct_Type:
return make_symbol_struct_from_ast(ast_context, v), !expect_identifier;
case Proc_Lit:
@@ -677,6 +676,10 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
return resolve_type_identifier(ast_context, v);
case Struct_Type:
return make_symbol_struct_from_ast(ast_context, v), !expect_identifier;
+ case Union_Type:
+ return make_symbol_union_from_ast(ast_context, v), !expect_identifier;
+ case Enum_Type:
+ return make_symbol_enum_from_ast(ast_context, v), !expect_identifier;
case Proc_Lit:
if !v.type.generic {
return make_symbol_procedure_from_ast(ast_context, v, node.name), !expect_identifier;
@@ -803,7 +806,6 @@ resolve_symbol_return :: proc(ast_context: ^AstContext, symbol: index.Symbol, ok
#partial switch v in symbol.value {
case index.SymbolProcedureGroupValue:
if symbol, ok := resolve_function_overload(ast_context, v.group.derived.(ast.Proc_Group)); ok {
- //return resolve_symbol_return(ast_context, symbol);
return symbol, true;
}
else {
@@ -889,6 +891,53 @@ make_symbol_generic_from_ast :: proc(ast_context: ^AstContext, expr: ^ast.Expr)
return symbol;
}
+make_symbol_union_from_ast :: proc(ast_context: ^AstContext, v: ast.Union_Type) -> index.Symbol {
+
+ symbol := index.Symbol {
+ range = common.get_token_range(v, ast_context.file.src),
+ type = .Enum,
+ };
+
+ names := make([dynamic] string, context.temp_allocator);
+
+ for variant in v.variants {
+
+ if ident, ok := variant.derived.(ast.Ident); ok {
+ append(&names, ident.name);
+ }
+
+ }
+
+ symbol.value = index.SymbolUnionValue {
+ names = names[:],
+ };
+
+ return symbol;
+}
+
+make_symbol_enum_from_ast :: proc(ast_context: ^AstContext, v: ast.Enum_Type) -> index.Symbol {
+
+ symbol := index.Symbol {
+ range = common.get_token_range(v, ast_context.file.src),
+ type = .Enum,
+ };
+
+ names := make([dynamic] string, context.temp_allocator);
+
+ for field in v.fields {
+
+ if ident, ok := field.derived.(ast.Ident); ok {
+ append(&names, ident.name);
+ }
+
+ }
+
+ symbol.value = index.SymbolEnumValue {
+ names = names[:],
+ };
+
+ return symbol;
+}
make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type) -> index.Symbol {
@@ -903,9 +952,10 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type
for field in v.fields.list {
for n in field.names {
- identifier := n.derived.(ast.Ident);
- append(&names, identifier.name);
- append(&types, index.clone_type(field.type, context.temp_allocator));
+ if identifier, ok := n.derived.(ast.Ident); ok {
+ append(&names, identifier.name);
+ append(&types, index.clone_type(field.type, context.temp_allocator));
+ }
}
}
@@ -1238,6 +1288,7 @@ get_locals :: proc(file: ast.File, function: ^ast.Node, ast_context: ^AstContext
block, ok = proc_lit.body.derived.(ast.Block_Stmt);
if !ok {
+ log.error("Proc_List body not block");
return;
}
@@ -1245,6 +1296,8 @@ get_locals :: proc(file: ast.File, function: ^ast.Node, ast_context: ^AstContext
get_locals_stmt(file, stmt, ast_context, document_position);
}
+ log.info(ast_context.locals);
+
}
get_definition_location :: proc(document: ^Document, position: common.Position) -> (common.Location, bool) {
@@ -1258,6 +1311,7 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
position_context, ok := get_document_position_context(document, position, .Definition);
+
if !ok {
log.error("Failed to get position context");
return location, false;
@@ -1282,10 +1336,13 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
}
- else if position_context.selector != nil && position_context.field != nil {
+ else if position_context.selector != nil {
selector: index.Symbol;
+ ast_context.use_locals = true;
+ ast_context.use_globals = true;
+
selector, ok = resolve_type_expression(&ast_context, position_context.selector);
if !ok {
@@ -1294,14 +1351,18 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
field: string;
- switch v in position_context.field.derived {
- case ast.Ident:
- field = v.name;
- case:
- return location, false;
+ if position_context.field != nil {
+
+ switch v in position_context.field.derived {
+ case ast.Ident:
+ field = v.name;
+ }
+
}
#partial switch v in selector.value {
+ case index.SymbolEnumValue:
+ location.range = selector.range;
case index.SymbolStructValue:
for name, i in v.names {
if strings.compare(name, field) == 0 {
@@ -1362,6 +1423,9 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
selector: index.Symbol;
+ ast_context.use_locals = true;
+ ast_context.use_globals = true;
+
selector, ok = resolve_type_expression(&ast_context, position_context.selector);
if !ok {
@@ -1375,6 +1439,10 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
ast_context.current_package = selector.scope;
}
+ else {
+ ast_context.current_package = ast_context.document_package;
+ }
+
field: string;
if position_context.field != nil {
@@ -1387,12 +1455,32 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
}
#partial switch v in selector.value {
+ case index.SymbolEnumValue:
+ list.isIncomplete = false;
+
+ log.info("enum value");
+
+ for name in v.names {
+ symbol: index.Symbol;
+ symbol.name = name;
+ symbol.type = .EnumMember;
+ append(&symbols, symbol);
+ }
+
case index.SymbolStructValue:
list.isIncomplete = false;
for name, i in v.names {
+ if selector.uri != "" {
+ ast_context.current_package = selector.scope;
+ }
+
+ else {
+ ast_context.current_package = ast_context.document_package;
+ }
+
if symbol, ok := resolve_type_expression(&ast_context, v.types[i], false); ok {
symbol.name = name;
symbol.type = .Field;
@@ -1439,6 +1527,14 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
case index.SymbolStructValue:
for name, i in s.names {
+ if selector.uri != "" {
+ ast_context.current_package = selector.scope;
+ }
+
+ else {
+ ast_context.current_package = ast_context.document_package;
+ }
+
if symbol, ok := resolve_type_expression(&ast_context, s.types[i], false); ok {
symbol.name = name;
symbol.type = .Field;
@@ -1476,6 +1572,8 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
else {
+ log.infof("label %v", position_context.identifier);
+
/*
Just show the local and global symbols of the document
@@ -1627,6 +1725,7 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
switch n in node.derived {
case Bad_Expr:
+
if position_context.hint == .Completion && position_context.file.src[max(0, node.end.offset-1)] == '.' {
diff --git a/src/server/documents.odin b/src/server/documents.odin
index 05c0c3e..e5036c9 100644
--- a/src/server/documents.odin
+++ b/src/server/documents.odin
@@ -337,7 +337,7 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] Parse
parser.parse_file(&p, &document.ast);
document.imports = make([]Package, len(document.ast.imports), context.temp_allocator);
- document.package_name = path.dir(document.uri.path, context.temp_allocator);
+ document.package_name = strings.to_lower(path.dir(document.uri.path, context.temp_allocator), context.temp_allocator);
for imp, index in document.ast.imports {