From 28ce0ddfebfd671094e8da231923ff96fb72dd47 Mon Sep 17 00:00:00 2001 From: Daniel Gavin Date: Wed, 5 May 2021 23:43:12 +0200 Subject: begun argument underlining --- src/testing/testing.odin | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/testing') diff --git a/src/testing/testing.odin b/src/testing/testing.odin index e74fb0e..7b30e93 100644 --- a/src/testing/testing.odin +++ b/src/testing/testing.odin @@ -145,6 +145,16 @@ expect_signature_labels :: proc(t: ^testing.T, src: ^Source, expect_labels: []st } +expect_signature_parameter_position :: proc(t: ^testing.T, src: ^Source, position: int) { + setup(src); + + help, ok := server.get_signature_information(src.document, src.position); + + if help.activeParameter != position { + testing.errorf(t, "expected parameter position %v, but received %v", position, help.activeParameter); + } +} + expect_completion_details :: proc(t: ^testing.T, src: ^Source, trigger_character: string, expect_details: []string) { setup(src); -- cgit v1.2.3 From 9c2090e0395d68bb9a89cfd3f69f863375a27f54 Mon Sep 17 00:00:00 2001 From: Daniel Gavin Date: Sun, 9 May 2021 18:38:44 +0200 Subject: make now works again --- src/common/ast.odin | 15 +++------ src/index/indexer.odin | 1 - src/server/analysis.odin | 74 ++++++++++++++++++++++++++++++++++----------- src/server/completion.odin | 4 +-- src/server/signature.odin | 2 +- src/testing/testing.odin | 3 +- tests/completions_test.odin | 47 ++++++++++++++++++++++++++-- 7 files changed, 110 insertions(+), 36 deletions(-) (limited to 'src/testing') diff --git a/src/common/ast.odin b/src/common/ast.odin index e6ab8ac..839c7f5 100644 --- a/src/common/ast.odin +++ b/src/common/ast.odin @@ -492,12 +492,6 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool { } case Poly_Type: return true; - //return node_equal(n.sp) - //if n, ok := a.derived.(Poly_Type); ok { - // ret := node_equal(n.type, m.type); - // ret &= node_equal(n.specialization, m.specialization); - // return ret; - //} case Ellipsis: if n, ok := a.derived.(Ellipsis); ok { return node_equal(n.expr, m.expr); @@ -549,8 +543,10 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool { } case Array_Type: if n, ok := a.derived.(Array_Type); ok { - ret := node_equal(n.len, m.len); - ret &= node_equal(n.elem, m.elem); + ret := node_equal(n.elem, m.elem); + if n.len != nil && m.len != nil { + ret &= node_equal(n.len, m.len); + } return ret; } case Dynamic_Array_Type: @@ -614,9 +610,6 @@ node_equal_node :: proc(a, b: ^ast.Node) -> bool { } case Typeid_Type: return true; - //if n, ok := a.derived.(Typeid_Type); ok { - // return node_equal(n.specialization, m.specialization); - //} case: log.warn("Unhandled poly node kind: %T", m); } diff --git a/src/index/indexer.odin b/src/index/indexer.odin index 2020992..ce031f1 100644 --- a/src/index/indexer.odin +++ b/src/index/indexer.odin @@ -59,7 +59,6 @@ lookup :: proc(name: string, pkg: string, loc := #caller_location) -> (Symbol, b } for built in indexer.built_in_packages { - if symbol, ok := memory_index_lookup(&indexer.static_index, name, built); ok { log.infof("lookup name: %v pkg: %v, symbol %v location %v", name, pkg, symbol, loc); return symbol, true; diff --git a/src/server/analysis.odin b/src/server/analysis.odin index d928f7c..c90e2fe 100644 --- a/src/server/analysis.odin +++ b/src/server/analysis.odin @@ -178,7 +178,7 @@ resolve_poly_spec_node :: proc(ast_context: ^AstContext, call_node: ^ast.Node, s case Implicit: case Undef: case Basic_Lit: - case Poly_Type: + case Poly_Type: if expr := get_poly_node_to_expr(call_node); expr != nil { poly_map[m.type.name] = expr; } @@ -354,7 +354,7 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast for param in params { - if param.default_value != nil { + if param.default_value == nil { count_required_params += 1; } @@ -372,6 +372,12 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast continue; } + if type_id, ok := param.type.derived.(Typeid_Type); ok { + if !common.node_equal(call_expr.args[i], type_id.specialization) { + return {}, false; + } + } + resolve_poly_spec_node(ast_context, call_expr.args[i], param.type, &poly_map); i += 1; @@ -392,7 +398,7 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast function_name = selector.field.name; function_range = common.get_token_range(selector, ast_context.file.src); } else { - return index.Symbol {}, false; + return {}, false; } symbol := index.Symbol { @@ -402,6 +408,7 @@ resolve_generic_function_symbol :: proc(ast_context: ^AstContext, params: []^ast }; return_types := make([dynamic]^ast.Field, context.temp_allocator); + argument_types := make([dynamic]^ast.Field, context.temp_allocator); for result in results { @@ -410,21 +417,40 @@ 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, ok := poly_map[ident.name]; ok { - field.type = poly_map[ident.name]; + field := cast(^Field)index.clone_node(result, context.temp_allocator, nil); + field.type = m; append(&return_types, field); - } + } else { + append(&return_types, result); + } + } else { + append(&return_types, result); } } - if len(poly_map) != len(return_types) { - return {}, false; + for param in params { + + if len(param.names) == 0 { + continue; + } + + //check the name for poly + if poly_type, ok := param.names[0].derived.(ast.Poly_Type); ok && param.type != nil { + if m, ok := poly_map[poly_type.type.name]; ok { + field := cast(^Field)index.clone_node(param, context.temp_allocator, nil); + field.type = m; + append(&argument_types, field); + } + } else { + append(&argument_types, param); + } + } symbol.value = index.SymbolProcedureValue { return_types = return_types[:], - arg_types = params, + arg_types = argument_types[:], }; return symbol, true; @@ -449,8 +475,7 @@ resolve_generic_function_ast :: proc(ast_context: ^AstContext, proc_lit: ast.Pro return resolve_generic_function_symbol(ast_context, proc_lit.type.params.list, proc_lit.type.results.list); } -is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: index.Symbol) -> bool -{ +is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: index.Symbol) -> bool { //relying on the fact that a is the call argument to avoid checking both sides for untyped. if untyped, ok := a.value.(index.SymbolUntypedValue); ok { if basic, ok := b.value.(index.SymbolBasicValue); ok { @@ -627,6 +652,18 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou if procedure, ok := f.value.(index.SymbolProcedureValue); ok { + count_required_params := 0; + + for arg in procedure.arg_types { + if arg.default_value == nil { + count_required_params += 1; + } + } + + if count_required_params > len(call_expr.args) { + break next_fn; + } + if len(procedure.arg_types) < len(call_expr.args) { continue; } @@ -643,17 +680,21 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou call_symbol, ok = resolve_type_expression(ast_context, arg); - if !ok { + if !ok { break next_fn; } - arg_symbol, ok = resolve_type_expression(ast_context, procedure.arg_types[i].type); + if procedure.arg_types[i].type != nil { + arg_symbol, ok = resolve_type_expression(ast_context, procedure.arg_types[i].type); + } else { + arg_symbol, ok = resolve_type_expression(ast_context, procedure.arg_types[i].default_value); + } - if !ok { + if !ok { break next_fn; } - - if !is_symbol_same_typed(ast_context, call_symbol, arg_symbol) { + + if !is_symbol_same_typed(ast_context, call_symbol, arg_symbol) { break next_fn; } @@ -1019,7 +1060,6 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -> (i return return_symbol, ok; } else if node.name == "context" { - //if there are more of these variables that hard builtin, move them to the indexer return index.lookup("Context", ast_context.current_package); } else if v, ok := common.keyword_map[node.name]; ok { //keywords diff --git a/src/server/completion.odin b/src/server/completion.odin index 86ed681..3fc4917 100644 --- a/src/server/completion.odin +++ b/src/server/completion.odin @@ -161,10 +161,10 @@ field_exists_in_comp_lit :: proc(comp_lit: ^ast.Comp_Lit, name: string) -> bool return false; } -get_attribute_completion :: proc(ast_context: ^AstContext, postition_context: ^DocumentPositionContext, list: ^CompletionList) { +get_attribute_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) { } -get_directive_completion :: proc(ast_context: ^AstContext, postition_context: ^DocumentPositionContext, list: ^CompletionList) { +get_directive_completion :: proc(ast_context: ^AstContext, position_context: ^DocumentPositionContext, list: ^CompletionList) { list.isIncomplete = false; diff --git a/src/server/signature.odin b/src/server/signature.odin index fb3f8e6..c1cdbe3 100644 --- a/src/server/signature.odin +++ b/src/server/signature.odin @@ -128,7 +128,7 @@ get_signature_information :: proc(document: ^Document, position: common.Position if value, ok := call.value.(index.SymbolProcedureValue); ok { parameters := make([]ParameterInformation, len(value.arg_types), context.temp_allocator); - + for arg, i in value.arg_types { if arg.type != nil { diff --git a/src/testing/testing.odin b/src/testing/testing.odin index 7b30e93..ebaf4fc 100644 --- a/src/testing/testing.odin +++ b/src/testing/testing.odin @@ -73,6 +73,7 @@ setup :: proc(src: ^Source) { There is a lot code here that is used in the real code, then i'd like to see. */ + index.indexer.static_index = index.make_memory_index(index.make_symbol_collection(context.allocator, &common.config)); index.indexer.dynamic_index = index.make_memory_index(index.make_symbol_collection(context.allocator, &common.config)); for src_pkg in src.packages { @@ -108,7 +109,7 @@ setup :: proc(src: ^Source) { return; } - if ret := index.collect_symbols(&index.indexer.dynamic_index.collection, file, uri.uri); ret != .None { + if ret := index.collect_symbols(&index.indexer.static_index.collection, file, uri.uri); ret != .None { return; } } diff --git a/tests/completions_test.odin b/tests/completions_test.odin index 9cd5a6f..47f9e5a 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_slice :: proc(t: ^testing.T) { + + source := test.Source { + main = `package test + Allocator :: struct { + + } + Context :: struct { + allocator: Allocator, + } + make_slice :: proc($T: typeid/[]$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_slice := make_slice([]My_Struct, 23); + my_slic* + } + `, + packages = {}, + }; + + test.expect_completion_details(t, &source, "", {"test.my_slice: []My_Struct"}); +} + +/* + Figure out whether i want to introduce the runtime to the tests + @(test) ast_generic_make_completion :: proc(t: ^testing.T) { @@ -313,20 +345,28 @@ ast_generic_make_completion :: proc(t: ^testing.T) { make :: proc{ make_dynamic_array, make_dynamic_array_len, + make_dynamic_array_len_cap, + make_map, + make_slice, }; - + make_slice :: proc($T: typeid/[]$E, auto_cast len: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_second { + } + make_map :: proc($T: typeid/map[$K]$E, auto_cast cap: int = DEFAULT_RESERVE_CAPACITY, allocator := context.allocator, loc := #caller_location) -> T { + } 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 { } + make_dynamic_array_len_cap :: proc($T: typeid/[dynamic]$E, auto_cast len: int, auto_cast cap: 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); + allocator: Allocator; + my_array := make([dynamic]My_Struct, 343, allocator); my_array[2].* } `, @@ -335,6 +375,7 @@ ast_generic_make_completion :: proc(t: ^testing.T) { test.expect_completion_details(t, &source, ".", {"My_Struct.my_int: int"}); } +*/ /* -- cgit v1.2.3