aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2021-05-08 14:12:16 +0200
committerDaniel Gavin <danielgavin5@hotmail.com>2021-05-08 14:12:16 +0200
commit6443fc0a31f2949993d7cd7806391fd5d7ee97c3 (patch)
treeec2a925c097dbb70d867560c7f30845fabeb2290
parentb3548adc1efcb143767e63d370efed1a60f724c5 (diff)
more work on generics and overloading
-rw-r--r--src/server/analysis.odin30
-rw-r--r--tests/completions_test.odin32
2 files changed, 52 insertions, 10 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 999c7c1..d928f7c 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -336,23 +336,28 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
using ast;
if params == nil {
- return index.Symbol {}, false;
+ return {}, false;
}
if results == nil {
- return index.Symbol {}, false;
+ return {}, false;
}
if ast_context.call == nil {
- return index.Symbol {}, false;
+ return {}, false;
}
call_expr := ast_context.call;
- poly_map := make(map[string]^Expr, 0, context.temp_allocator);
- i := 0;
+ poly_map := make(map[string]^Expr, 0, context.temp_allocator);
+ i := 0;
+ count_required_params := 0;
for param in params {
+ if param.default_value != nil {
+ count_required_params += 1;
+ }
+
for name in param.names {
if len(call_expr.args) <= i {
@@ -373,6 +378,10 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
}
}
+ if count_required_params > len(call_expr.args) || count_required_params == 0 || len(call_expr.args) == 0 {
+ return {}, false;
+ }
+
function_name := "";
function_range: common.Range;
@@ -402,16 +411,17 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast
if ident, ok := result.type.derived.(Ident); ok {
field := cast(^Field)index.clone_node(result, context.temp_allocator, nil);
-
- if m := &poly_map[ident.name]; m != nil {
+ if m, ok := poly_map[ident.name]; ok {
field.type = poly_map[ident.name];
append(&return_types, field);
- } else {
- return index.Symbol {}, false;
- }
+ }
}
}
+ if len(poly_map) != len(return_types) {
+ return {}, false;
+ }
+
symbol.value = index.SymbolProcedureValue {
return_types = return_types[:],
arg_types = params,
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 48000a0..9cd5a6f 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -304,6 +304,38 @@ index_package_completion :: proc(t: ^testing.T) {
test.expect_completion_details(t, &source, ".", {"my_package.My_Struct: struct"});
}
+@(test)
+ast_generic_make_completion :: proc(t: ^testing.T) {
+
+ source := test.Source {
+ main = `package test
+
+ make :: proc{
+ make_dynamic_array,
+ make_dynamic_array_len,
+ };
+
+ make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_second {
+ }
+
+ make_dynamic_array_len :: proc($T: typeid/[dynamic]$E, auto_cast len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_second {
+ }
+
+ My_Struct :: struct {
+ my_int: int,
+ }
+
+ main :: proc() {
+ my_array := make([dynamic]My_Struct, context.allocator);
+ my_array[2].*
+ }
+ `,
+ packages = {},
+ };
+
+ test.expect_completion_details(t, &source, ".", {"My_Struct.my_int: int"});
+}
+
/*
SymbolUntypedValue :: struct {