diff options
| author | Bradley Lewis <22850972+BradLewis@users.noreply.github.com> | 2025-10-06 04:48:40 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-06 04:48:40 -0400 |
| commit | 7916a277e4597e869262a7685bc0b51b5af7916f (patch) | |
| tree | 7e1d35bfa45ab5be3ba445443157768b8bfeb719 | |
| parent | 359c6ebffa2b9781bc772297182025d00ea4af29 (diff) | |
| parent | e64b11784cd430d27eb469039002c7e2c950b2fd (diff) | |
Merge pull request #1078 from BradLewis/fix/using-pkg-name-conflicts
Resolve types from usings before global scope
| -rw-r--r-- | src/server/analysis.odin | 48 | ||||
| -rw-r--r-- | tests/hover_test.odin | 28 |
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 |