aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-10-06 00:23:55 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-10-06 00:23:55 -0400
commite64b11784cd430d27eb469039002c7e2c950b2fd (patch)
tree7e1d35bfa45ab5be3ba445443157768b8bfeb719
parent359c6ebffa2b9781bc772297182025d00ea4af29 (diff)
Resolve types from usings before global scope
-rw-r--r--src/server/analysis.odin48
-rw-r--r--tests/hover_test.odin28
2 files changed, 55 insertions, 21 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 1ee5ad6..41c78d8 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -9,11 +9,8 @@ import "core:odin/tokenizer"
import "core:path/filepath"
import path "core:path/slashpath"
import "core:reflect"
-import "core:slice"
-import "core:sort"
import "core:strconv"
import "core:strings"
-import "core:unicode/utf8"
import "src:common"
@@ -37,6 +34,7 @@ AstContext :: struct {
deferred_package: [DeferredDepth]string, //When a package change happens when resolving
deferred_count: int,
use_locals: bool,
+ use_usings: bool,
call: ^ast.Call_Expr, //used to determine the types for generics and the correct function for overloaded functions
value_decl: ^ast.Value_Decl,
field_name: ast.Ident,
@@ -69,6 +67,7 @@ make_ast_context :: proc(
file = file,
imports = imports,
use_locals = true,
+ use_usings = true,
document_package = package_name,
current_package = package_name,
uri = uri,
@@ -1617,6 +1616,18 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide
return resolve_local_identifier(ast_context, node, &local)
}
+ if ast_context.use_usings {
+ for u in ast_context.usings {
+ for imp in ast_context.imports {
+ if strings.compare(imp.name, u.pkg_name) == 0 {
+ if symbol, ok := lookup(node.name, imp.name, node.pos.file); ok {
+ return resolve_symbol_return(ast_context, symbol)
+ }
+ }
+ }
+ }
+ }
+
for imp in ast_context.imports {
if imp.name == ast_context.current_package {
continue
@@ -1700,16 +1711,6 @@ internal_resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ide
}
}
- for u in ast_context.usings {
- for imp in ast_context.imports {
- if strings.compare(imp.name, u.pkg_name) == 0 {
- if symbol, ok := lookup(node.name, imp.name, node.pos.file); ok {
- return resolve_symbol_return(ast_context, symbol)
- }
- }
- }
- }
-
return Symbol{}, false
}
@@ -2617,6 +2618,16 @@ resolve_location_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -
return symbol, true
}
+ if ast_context.use_usings {
+ usings := get_using_packages(ast_context)
+
+ for pkg in usings {
+ if symbol, ok := lookup(node.name, pkg, node.pos.file); ok {
+ return symbol, ok
+ }
+ }
+ }
+
if global, ok := ast_context.globals[node.name]; ok {
symbol.range = common.get_token_range(global.name_expr, ast_context.file.src)
uri := common.create_uri(global.expr.pos.file, ast_context.allocator)
@@ -2649,14 +2660,6 @@ resolve_location_identifier :: proc(ast_context: ^AstContext, node: ast.Ident) -
return symbol, ok
}
- usings := get_using_packages(ast_context)
-
- for pkg in usings {
- if symbol, ok := lookup(node.name, pkg, node.pos.file); ok {
- return symbol, ok
- }
- }
-
if symbol, ok := lookup(node.name, "$builtin", node.pos.file); ok {
return resolve_symbol_return(ast_context, symbol)
}
@@ -2869,6 +2872,9 @@ resolve_location_selector :: proc(ast_context: ^AstContext, selector_expr: ^ast.
set_ast_package_set_scoped(ast_context, ast_context.document_package)
if selector, ok := selector_expr.derived.(^ast.Selector_Expr); ok {
+ ast_context.use_usings = false
+ defer ast_context.use_usings = true
+
symbol = resolve_type_expression(ast_context, selector.expr) or_return
return resolve_symbol_selector(ast_context, selector, symbol)
}
diff --git a/tests/hover_test.odin b/tests/hover_test.odin
index 796787c..341b641 100644
--- a/tests/hover_test.odin
+++ b/tests/hover_test.odin
@@ -5151,6 +5151,34 @@ ast_hover_generic_proc_with_inlining :: proc(t: ^testing.T) {
}
test.expect_hover(t, &source, "test.foo :: #force_inline proc(data: $T)")
}
+
+@(test)
+ast_hover_using_import_statement_name_conflict :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package, context.temp_allocator)
+
+ append(&packages, test.Package{pkg = "my_package", source = `package my_package
+ Bar :: struct {
+ b: string,
+ }
+ `})
+
+ source := test.Source {
+ main = `package test
+ import "my_package"
+
+ Bar :: struct {
+ a: int,
+ }
+
+ main :: proc() {
+ using my_package
+ bar := Ba{*}r{}
+ }
+ `,
+ packages = packages[:],
+ }
+ test.expect_hover(t, &source, "my_package.Bar :: struct {\n\tb: string,\n}")
+}
/*
Waiting for odin fix