aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-07-28 08:38:00 -0400
committerBrad Lewis <22850972+BradLewis@users.noreply.github.com>2025-07-28 08:38:32 -0400
commit8aeba058399f3e64bdd6eea027982977db2998e7 (patch)
tree6bacc47450b5e0f8e8464aec6c3df5d59967c048
parent62cae61b822416979ff25b3672feb3679c93eebc (diff)
Correctly resolving using statements with aliases
-rw-r--r--src/server/analysis.odin23
-rw-r--r--tests/completions_test.odin44
2 files changed, 58 insertions, 9 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 8143bbf..48d2452 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -83,11 +83,16 @@ DeferredDepth :: 35
LocalGroup :: map[string][dynamic]DocumentLocal
+UsingStatement :: struct {
+ alias: string,
+ pkg_name: string,
+}
+
AstContext :: struct {
locals: [dynamic]LocalGroup, //locals all the way to the document position
globals: map[string]GlobalExpr,
recursion_map: map[rawptr]bool,
- usings: [dynamic]string,
+ usings: [dynamic]UsingStatement,
file: ast.File,
allocator: mem.Allocator,
imports: []Package, //imports for the current document
@@ -117,7 +122,7 @@ make_ast_context :: proc(
ast_context := AstContext {
locals = make([dynamic]map[string][dynamic]DocumentLocal, 0, allocator),
globals = make(map[string]GlobalExpr, 0, allocator),
- usings = make([dynamic]string, allocator),
+ usings = make([dynamic]UsingStatement, allocator),
recursion_map = make(map[rawptr]bool, 0, allocator),
file = file,
imports = imports,
@@ -134,14 +139,14 @@ make_ast_context :: proc(
return ast_context
}
-add_using :: proc(ast_context: ^AstContext, using_name: string) {
+add_using :: proc(ast_context: ^AstContext, using_name: string, pkg_name: string) {
for u in ast_context.usings {
- if u == using_name {
+ if u.alias == using_name {
return
}
}
- append(&ast_context.usings, using_name)
+ append(&ast_context.usings, UsingStatement{alias = using_name, pkg_name = pkg_name})
}
set_ast_package_deferred :: proc(ast_context: ^AstContext, pkg: string) {
@@ -1896,7 +1901,7 @@ 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.base, u) == 0 {
+ if strings.compare(imp.base, u.pkg_name) == 0 {
if symbol, ok := lookup(node.name, imp.name); ok {
return resolve_symbol_return(ast_context, symbol)
}
@@ -2906,7 +2911,9 @@ get_using_packages :: proc(ast_context: ^AstContext) -> []string {
//probably map instead
for u, i in ast_context.usings {
for imp in ast_context.imports {
- usings[i] = imp.name
+ if u.pkg_name == imp.name {
+ usings[i] = imp.name
+ }
}
}
@@ -3636,7 +3643,7 @@ get_locals_using :: proc(expr: ^ast.Expr, ast_context: ^AstContext) {
#partial switch v in symbol.value {
case SymbolPackageValue:
if ident, ok := expr.derived.(^ast.Ident); ok {
- add_using(ast_context, ident.name)
+ add_using(ast_context, ident.name, symbol.pkg)
}
case SymbolStructValue:
for name, i in v.names {
diff --git a/tests/completions_test.odin b/tests/completions_test.odin
index 1389550..9a5d20c 100644
--- a/tests/completions_test.odin
+++ b/tests/completions_test.odin
@@ -3878,7 +3878,7 @@ ast_completion_proc_enum_param :: proc(t: ^testing.T) {
@(test)
ast_completion_using_aliased_package :: proc(t: ^testing.T) {
- packages := make([dynamic]test.Package, context.temp_allocator)
+ packages := make([dynamic]test.Package, context.temp_allocator)
append(
&packages,
@@ -3908,6 +3908,48 @@ ast_completion_using_aliased_package :: proc(t: ^testing.T) {
}
@(test)
+ast_completion_using_aliased_package_multiple :: proc(t: ^testing.T) {
+ packages := make([dynamic]test.Package, context.temp_allocator)
+
+ append(
+ &packages,
+ test.Package {
+ pkg = "foo_pkg",
+ source = `package foo_pkg
+ foo :: proc() {}
+ `,
+ },
+ )
+
+ append(
+ &packages,
+ test.Package {
+ pkg = "bar_pkg",
+ source = `package bar_pkg
+ bar :: proc() {}
+ `,
+ },
+ )
+
+ source := test.Source {
+ main = `package test
+
+ import "foo_pkg"
+ import "bar_pkg"
+ fp :: foo_pkg
+
+ main :: proc() {
+ using fp
+ f{*}
+ }
+ `,
+ packages = packages[:],
+ }
+
+ test.expect_completion_details(t, &source, ".", {"foo_pkg.foo: proc()"})
+}
+
+@(test)
ast_completion_bitset_if_statement_in :: proc(t: ^testing.T) {
source := test.Source {
main = `package test