rue_compiler/compile/item/
module.rs

1use rue_ast::{AstModuleItem, AstNode};
2use rue_diagnostic::DiagnosticKind;
3use rue_hir::{Declaration, ModuleDeclarations, ModuleSymbol, Symbol, SymbolId};
4
5use crate::{
6    Compiler, CompletionContext, SyntaxItem, SyntaxItemKind, compile_symbol_items,
7    compile_type_items, declare_symbol_items, declare_type_items,
8};
9
10pub fn declare_module(ctx: &mut Compiler, module: &AstModuleItem) -> SymbolId {
11    ctx.syntax_map_mut().add_item(SyntaxItem::new(
12        SyntaxItemKind::CompletionContext(CompletionContext::Item),
13        module.syntax().text_range(),
14    ));
15
16    let scope = ctx.alloc_child_scope();
17
18    let declarations = ModuleDeclarations::default();
19
20    let range = module.syntax().text_range();
21    ctx.push_scope(scope, range.start());
22    // TODO: Imports
23    ctx.pop_scope(range.end());
24
25    let symbol = ctx.alloc_symbol(Symbol::Module(ModuleSymbol {
26        name: module.name(),
27        scope,
28        declarations,
29    }));
30
31    if let Some(name) = module.name() {
32        if ctx.last_scope().symbol(name.text()).is_some() {
33            ctx.diagnostic(
34                &name,
35                DiagnosticKind::DuplicateSymbol(name.text().to_string()),
36            );
37        } else {
38            ctx.last_scope_mut().insert_symbol(
39                name.text().to_string(),
40                symbol,
41                module.export().is_some(),
42            );
43        }
44
45        ctx.declaration_span(Declaration::Symbol(symbol), name.text_range());
46    }
47
48    symbol
49}
50
51pub fn declare_module_types(ctx: &mut Compiler, module: &AstModuleItem, symbol: SymbolId) {
52    let (scope, mut declarations) = if let Symbol::Module(ModuleSymbol {
53        scope,
54        declarations,
55        ..
56    }) = ctx.symbol(symbol)
57    {
58        (*scope, declarations.clone())
59    } else {
60        unreachable!();
61    };
62
63    let range = module.syntax().text_range();
64    ctx.push_scope(scope, range.start());
65    declare_type_items(ctx, module.items(), &mut declarations);
66    ctx.pop_scope(range.end());
67
68    let Symbol::Module(ModuleSymbol {
69        declarations: updated,
70        ..
71    }) = ctx.symbol_mut(symbol)
72    else {
73        unreachable!();
74    };
75
76    *updated = declarations;
77}
78
79pub fn declare_module_symbols(ctx: &mut Compiler, module: &AstModuleItem, symbol: SymbolId) {
80    let (scope, mut declarations) = if let Symbol::Module(ModuleSymbol {
81        scope,
82        declarations,
83        ..
84    }) = ctx.symbol(symbol)
85    {
86        (*scope, declarations.clone())
87    } else {
88        unreachable!();
89    };
90
91    let range = module.syntax().text_range();
92    ctx.push_scope(scope, range.start());
93    declare_symbol_items(ctx, module.items(), &mut declarations);
94    ctx.pop_scope(range.end());
95
96    let Symbol::Module(ModuleSymbol {
97        declarations: updated,
98        ..
99    }) = ctx.symbol_mut(symbol)
100    else {
101        unreachable!();
102    };
103
104    *updated = declarations;
105}
106
107pub fn compile_module_types(ctx: &mut Compiler, module: &AstModuleItem, symbol: SymbolId) {
108    let (scope, declarations) = if let Symbol::Module(ModuleSymbol {
109        scope,
110        declarations,
111        ..
112    }) = ctx.symbol(symbol)
113    {
114        (*scope, declarations.clone())
115    } else {
116        unreachable!();
117    };
118
119    let range = module.syntax().text_range();
120    ctx.push_scope(scope, range.start());
121    compile_type_items(ctx, module.items(), &declarations);
122    ctx.pop_scope(range.end());
123}
124
125pub fn compile_module_symbols(ctx: &mut Compiler, module: &AstModuleItem, symbol: SymbolId) {
126    let (scope, declarations) = if let Symbol::Module(ModuleSymbol {
127        scope,
128        declarations,
129        ..
130    }) = ctx.symbol(symbol)
131    {
132        (*scope, declarations.clone())
133    } else {
134        unreachable!();
135    };
136
137    let range = module.syntax().text_range();
138    ctx.push_scope(scope, range.start());
139    compile_symbol_items(ctx, module.items(), &declarations);
140    ctx.pop_scope(range.end());
141}