diff --git a/nls/src/analyzer/semantic.rs b/nls/src/analyzer/semantic.rs index 360c37bb..2aa8acf4 100644 --- a/nls/src/analyzer/semantic.rs +++ b/nls/src/analyzer/semantic.rs @@ -1059,6 +1059,26 @@ impl<'a> Semantic<'a> { return; } + // Check selective imports: import colors.{Color} then Color.RED + for import in &self.imports { + if !import.is_selective { + continue; + } + let Some(ref items) = import.select_items else { continue }; + for item in items { + let local_name = item.alias.as_ref().unwrap_or(&item.ident); + if local_name != left_ident.as_str() { + continue; + } + let global_ident = format_global_ident(import.module_ident.clone(), item.ident.clone()); + if let Some(id) = self.symbol_table.find_symbol_id(&global_ident, self.symbol_table.global_scope_id) { + *left_ident = global_ident; + *symbol_id = id; + return; + } + } + } + // import package ident let import_stmt = self.imports.iter().find(|i| i.as_name == *left_ident); if let Some(import_stmt) = import_stmt { diff --git a/src/semantic/analyzer.c b/src/semantic/analyzer.c index f1c44e00..28a414e1 100644 --- a/src/semantic/analyzer.c +++ b/src/semantic/analyzer.c @@ -1542,6 +1542,17 @@ static void rewrite_select_expr(module_t *m, ast_expr_t *expr) { return; } + // Check selective imports: import math.{Color} then Color.RED + ast_import_select_t *select_ref = table_get(m->selective_import_table, ident->literal); + if (select_ref != NULL) { + char *global_ident = ident_with_prefix(select_ref->module_ident, select_ref->original_ident); + symbol_t *sym = symbol_table_get(global_ident); + if (sym) { + ident->literal = global_ident; + return; + } + } + // import ident ast_import_t *import = table_get(m->import_table, ident->literal); if (import) { diff --git a/tests/features/20260103_00_selective_imports.c b/tests/features/20260103_00_selective_imports.c index c0a77359..020dba4b 100644 --- a/tests/features/20260103_00_selective_imports.c +++ b/tests/features/20260103_00_selective_imports.c @@ -8,7 +8,7 @@ static void test_basic() { printf("%s", raw); // Should print output from selective imports - assert_string_equal(raw, "sqrt(16) = 4.000000\npow(2, 3) = 8.000000\nadd(5, 7) = 12\npi = 3.141593\nPoint: 10 , 20\nMAX_SIZE: 100\nutils.MIN_SIZE: 10\nformat_string: hello\n"); + assert_string_equal(raw, "sqrt(16) = 4.000000\npow(2, 3) = 8.000000\nadd(5, 7) = 12\npi = 3.141593\nPoint: 10 , 20\nColor.GREEN: 1\nMAX_SIZE: 100\nutils.MIN_SIZE: 10\nformat_string: hello\n"); } int main(void) { diff --git a/tests/features/cases/20260103_00_selective_imports/main.n b/tests/features/cases/20260103_00_selective_imports/main.n index 5acb50e0..ce3ee7de 100644 --- a/tests/features/cases/20260103_00_selective_imports/main.n +++ b/tests/features/cases/20260103_00_selective_imports/main.n @@ -2,6 +2,7 @@ import 'math_module.n'.{sqrt, pow, PI as pi} import 'math_module.n'.{add} import 'math_module.n'.{Point} +import 'math_module.n'.{Color} import 'utils.n' as utils import 'utils.n'.{MAX_SIZE} @@ -21,6 +22,10 @@ fn main() { var p = Point{x: 10, y: 20} println('Point:', p.x, ',', p.y) + // Test selective import of enum types + var col = Color.GREEN + println('Color.GREEN:', col as int) + // Test mixed imports (full module + selective) println('MAX_SIZE:', MAX_SIZE) println('utils.MIN_SIZE:', utils.MIN_SIZE) diff --git a/tests/features/cases/20260103_00_selective_imports/math_module.n b/tests/features/cases/20260103_00_selective_imports/math_module.n index 536dce63..0a43142d 100644 --- a/tests/features/cases/20260103_00_selective_imports/math_module.n +++ b/tests/features/cases/20260103_00_selective_imports/math_module.n @@ -29,6 +29,12 @@ type Point = struct { int y } +type Color = enum { + RED, + GREEN, + BLUE, +} + fn log(string msg) { println('math_module:', msg) }