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