aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/analysis.odin56
-rw-r--r--src/server/ast.odin6
-rw-r--r--src/server/build.odin55
-rw-r--r--src/server/collector.odin1
-rw-r--r--src/server/completion.odin8
-rw-r--r--src/server/generics.odin11
-rw-r--r--src/server/symbol.odin6
-rw-r--r--tests/hover_test.odin69
8 files changed, 193 insertions, 19 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 1e570b4..8e1d7f0 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -340,25 +340,43 @@ are_symbol_basic_same_keywords :: proc(a, b: Symbol) -> bool {
if are_keyword_aliases(a.name, b.name) {
return true
}
- if a.name != b.name {
+ a_value, a_ok := a.value.(SymbolBasicValue)
+ if !a_ok {
return false
}
- if _, ok := a.value.(SymbolBasicValue); !ok {
+
+ b_value, b_ok := b.value.(SymbolBasicValue)
+ if !b_ok {
return false
}
- if _, ok := b.value.(SymbolBasicValue); !ok {
+ if a_value.ident.name != b_value.ident.name {
return false
}
- if _, ok := keyword_map[a.name]; !ok {
+ if _, ok := keyword_map[a_value.ident.name]; !ok {
return false
}
- if _, ok := keyword_map[b.name]; !ok {
+ if _, ok := keyword_map[b_value.ident.name]; !ok {
return false
}
return true
}
+is_valid_nil_symbol :: proc(symbol: Symbol) -> bool {
+ if symbol.pointers > 0 {
+ return true
+ }
+
+ #partial switch v in symbol.value {
+ case SymbolMapValue, SymbolSliceValue, SymbolProcedureValue, SymbolDynamicArrayValue:
+ return true
+ case SymbolUnionValue:
+ return v.kind != .no_nil
+ }
+
+ return false
+}
+
is_symbol_same_typed :: proc(ast_context: ^AstContext, a, b: Symbol, flags: ast.Field_Flags = {}) -> bool {
// In order to correctly equate the symbols for overloaded functions, we need to check both directions
if same, ok := are_symbol_untyped_basic_same_typed(a, b); ok {
@@ -718,6 +736,7 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
call_symbol: Symbol
arg_symbol: Symbol
ok: bool
+ is_call_arg_nil: bool
if _, ok = call_arg.derived.(^ast.Bad_Expr); ok {
continue
@@ -726,9 +745,14 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
//named parameter
if field, is_field := call_arg.derived.(^ast.Field_Value); is_field {
named = true
- call_symbol, ok = resolve_call_arg_type_expression(ast_context, field.value)
- if !ok {
- break next_fn
+ if ident, is_ident := field.field.derived.(^ast.Ident); is_ident && ident.name == "nil" {
+ is_call_arg_nil = true
+ ok = true
+ } else {
+ call_symbol, ok = resolve_call_arg_type_expression(ast_context, field.value)
+ if !ok {
+ break next_fn
+ }
}
if ident, is_ident := field.field.derived.(^ast.Ident); is_ident {
@@ -744,7 +768,12 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
log.error("Expected name parameter after starting named parmeter phase")
return {}, false
}
- call_symbol, ok = resolve_call_arg_type_expression(ast_context, call_arg)
+ if ident, is_ident := call_arg.derived.(^ast.Ident); is_ident && ident.name == "nil" {
+ is_call_arg_nil = true
+ ok = true
+ } else {
+ call_symbol, ok = resolve_call_arg_type_expression(ast_context, call_arg)
+ }
}
if !ok {
@@ -783,6 +812,15 @@ resolve_function_overload :: proc(ast_context: ^AstContext, group: ast.Proc_Grou
break next_fn
}
+ if is_call_arg_nil {
+ if is_valid_nil_symbol(arg_symbol) {
+ continue
+ } else {
+ break next_fn
+ }
+
+ }
+
if !is_symbol_same_typed(ast_context, call_symbol, arg_symbol, proc_arg.flags) {
found := false
// Are we a union variant
diff --git a/src/server/ast.odin b/src/server/ast.odin
index edb9007..5548c23 100644
--- a/src/server/ast.odin
+++ b/src/server/ast.odin
@@ -527,11 +527,13 @@ collect_when_body :: proc(
}
collect_globals :: proc(file: ast.File) -> []GlobalExpr {
+ file_tags := parser.parse_file_tags(file, context.temp_allocator)
+ if !should_collect_file(file_tags) {
+ return {}
+ }
exprs := make([dynamic]GlobalExpr, context.temp_allocator)
defer shrink(&exprs)
- file_tags := parser.parse_file_tags(file, context.temp_allocator)
-
for decl in file.decls {
if value_decl, ok := decl.derived.(^ast.Value_Decl); ok {
collect_value_decl(&exprs, file, file_tags, decl, {})
diff --git a/src/server/build.odin b/src/server/build.odin
index 24e109d..a0ba276 100644
--- a/src/server/build.odin
+++ b/src/server/build.odin
@@ -34,7 +34,7 @@ platform_os: map[string]struct{} = {
}
-os_enum_to_string: map[runtime.Odin_OS_Type]string = {
+os_enum_to_string: [runtime.Odin_OS_Type]string = {
.Windows = "windows",
.Darwin = "darwin",
.Linux = "linux",
@@ -43,11 +43,28 @@ os_enum_to_string: map[runtime.Odin_OS_Type]string = {
.WASI = "wasi",
.JS = "js",
.Freestanding = "freestanding",
- .JS = "wasm",
.Haiku = "haiku",
.OpenBSD = "openbsd",
.NetBSD = "netbsd",
- .FreeBSD = "freebsd",
+ .Orca = "orca",
+ .Unknown = "unknown",
+}
+
+os_string_to_enum: map[string]runtime.Odin_OS_Type = {
+ "Windows" = .Windows,
+ "Darwin" = .Darwin,
+ "Linux" = .Linux,
+ "Essence" = .Essence,
+ "Freebsd" = .FreeBSD,
+ "Wasi" = .WASI,
+ "Js" = .JS,
+ "Freestanding" = .Freestanding,
+ "Wasm" = .JS,
+ "Haiku" = .Haiku,
+ "Openbsd" = .OpenBSD,
+ "Netbsd" = .NetBSD,
+ "Orca" = .Orca,
+ "Unknown" = .Unknown,
}
@(private = "file")
@@ -90,6 +107,38 @@ skip_file :: proc(filename: string) -> bool {
return false
}
+should_collect_file :: proc(file_tags: parser.File_Tags) -> bool {
+ if file_tags.ignore {
+ return false
+ }
+
+ if len(file_tags.build) > 0 {
+ when_expr_map := make(map[string]When_Expr, context.temp_allocator)
+
+ for key, value in common.config.profile.defines {
+ when_expr_map[key] = resolve_when_ident(when_expr_map, value) or_continue
+ }
+
+ if when_expr, ok := resolve_when_ident(when_expr_map, "ODIN_OS"); ok {
+ if s, ok := when_expr.(string); ok {
+ if used_os, ok := os_string_to_enum[when_expr.(string)]; ok {
+ found := false
+ for tag in file_tags.build {
+ if used_os in tag.os {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return false
+ }
+ }
+ }
+ }
+ }
+ return true
+}
+
try_build_package :: proc(pkg_name: string) {
if pkg, ok := build_cache.loaded_pkgs[pkg_name]; ok {
return
diff --git a/src/server/collector.odin b/src/server/collector.odin
index 607521e..bd6d040 100644
--- a/src/server/collector.odin
+++ b/src/server/collector.odin
@@ -666,6 +666,7 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri
case ^ast.Basic_Lit:
token = v^
symbol.value = collect_generic(collection, col_expr, package_map, uri)
+ token_type = .Unresolved
case ^ast.Ident:
token = v^
symbol.value = collect_generic(collection, col_expr, package_map, uri)
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 38b5cbe..75bec86 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -2271,14 +2271,14 @@ get_expression_string_from_position_context :: proc(position_context: ^DocumentP
}
- if position_context.field != nil {
- return src[position_context.field.pos.offset:position_context.field.end.offset]
- }
-
if position_context.selector != nil {
return src[position_context.selector.pos.offset:position_context.selector.end.offset]
}
+ if position_context.field != nil {
+ return src[position_context.field.pos.offset:position_context.field.end.offset]
+ }
+
return ""
}
diff --git a/src/server/generics.odin b/src/server/generics.odin
index 374ffc9..6f0be73 100644
--- a/src/server/generics.odin
+++ b/src/server/generics.odin
@@ -452,6 +452,17 @@ find_and_replace_poly_type :: proc(expr: ^ast.Expr, poly_map: ^map[string]^ast.E
v.pos.file = expr.pos.file
v.end.file = expr.end.file
}
+ case ^ast.Map_Type:
+ if expr, ok := get_poly_map(v.key, poly_map); ok {
+ v.key = expr
+ v.pos.file = expr.pos.file
+ v.end.file = expr.end.file
+ }
+ if expr, ok := get_poly_map(v.value, poly_map); ok {
+ v.value = expr
+ v.pos.file = expr.pos.file
+ v.end.file = expr.end.file
+ }
}
return visitor
diff --git a/src/server/symbol.odin b/src/server/symbol.odin
index 4e6b19f..42e5447 100644
--- a/src/server/symbol.odin
+++ b/src/server/symbol.odin
@@ -780,7 +780,7 @@ symbol_type_to_completion_kind :: proc(type: SymbolType) -> CompletionItemKind {
symbol_kind_to_type :: proc(type: SymbolType) -> SymbolKind {
#partial switch type {
- case .Function:
+ case .Function, .Type_Function:
return .Function
case .Constant:
return .Constant
@@ -796,6 +796,10 @@ symbol_kind_to_type :: proc(type: SymbolType) -> SymbolKind {
return .Key
case .Field:
return .Field
+ case .Unresolved:
+ return .Constant
+ case .Type:
+ return .Class
case:
return .Null
}
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index 562a2d6..b2af26a 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -4980,6 +4980,75 @@ ast_hover_proc_impl :: proc(t: ^testing.T) {
}
test.expect_hover(t, &source, "test.foo :: proc(a: int) -> int")
}
+
+@(test)
+ast_hover_proc_overload_generic_map :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ clear_dynamic_array :: proc "contextless" (array: ^$T/[dynamic]$E) {}
+ clear_map :: proc "contextless" (m: ^$T/map[$K]$V) {}
+ clear :: proc{
+ clear_dynamic_array,
+ clear_map,
+ }
+ main :: proc() {
+ foo: map[int]string
+ c{*}lear(&foo)
+ }
+ `,
+ }
+ test.expect_hover(t, &source, "test.clear :: proc(m: ^$T/map[$K]$V)")
+}
+
+@(test)
+ast_hover_proc_overload_basic_type_alias :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package, context.temp_allocator)
+
+ append(&packages, test.Package{pkg = "my_package", source = `package my_package
+ Bar :: int
+ `})
+
+ source := test.Source {
+ main = `package test
+ import "my_package"
+
+ foo_int :: proc(i: int) {}
+ foo_string :: proc(s: string) {}
+ foo :: proc {
+ foo_int,
+ foo_string,
+ }
+
+ main :: proc() {
+ bar: my_package.Bar
+ f{*}oo(bar)
+ }
+ `,
+ packages = packages[:],
+ }
+ test.expect_hover(t, &source, "test.foo :: proc(i: int)")
+}
+
+@(test)
+ast_hover_proc_overload_nil_pointer :: proc(t: ^testing.T) {
+ source := test.Source {
+ main = `package test
+ import "my_package"
+
+ foo_int :: proc(i: int) {}
+ foo_ptr :: proc(s: ^string) {}
+ foo :: proc {
+ foo_int,
+ foo_ptr,
+ }
+
+ main :: proc() {
+ f{*}oo(nil)
+ }
+ `,
+ }
+ test.expect_hover(t, &source, "test.foo :: proc(s: ^string)")
+}
/*
Waiting for odin fix