Skip to main content

luaur_analysis/methods/
data_flow_graph_builder_build.rs

1use crate::enums::scope_type::ScopeType;
2use crate::records::data_flow_graph::DataFlowGraph;
3use crate::records::data_flow_graph_builder::DataFlowGraphBuilder;
4use crate::records::def_arena::DefArena;
5use crate::records::dfg_scope::DfgScope;
6use crate::records::internal_error_reporter::InternalErrorReporter;
7use crate::records::push_scope::PushScope;
8use crate::records::refinement_key_arena::RefinementKeyArena;
9use luaur_ast::records::ast_stat_block::AstStatBlock;
10use luaur_common::macros::luau_timetrace_scope::LUAU_TIMETRACE_SCOPE;
11use luaur_common::FFlag;
12
13impl DataFlowGraphBuilder {
14    pub fn build(
15        block: *mut AstStatBlock,
16        def_arena: *mut DefArena,
17        key_arena: *mut RefinementKeyArena,
18        handle: *mut InternalErrorReporter,
19    ) -> DataFlowGraph {
20        LUAU_TIMETRACE_SCOPE!("DataFlowGraphBuilder::build", "Typechecking");
21
22        let mut builder = DataFlowGraphBuilder::data_flow_graph_builder_not_null_def_arena_not_null_refinement_key_arena(def_arena, key_arena);
23        builder.handle = handle;
24
25        let module_scope = {
26            let mut scope = Box::new(DfgScope {
27                parent: core::ptr::null_mut(),
28                scope_type: ScopeType::Linear,
29                bindings: crate::type_aliases::bindings::Bindings::new(
30                    crate::records::symbol::Symbol::default(),
31                ),
32                props: crate::type_aliases::props_data_flow_graph::Props::new(core::ptr::null()),
33            });
34            let ptr = scope.as_mut() as *mut DfgScope;
35            builder.scopes.push(scope);
36            ptr
37        };
38
39        let _ps = PushScope::push_scope(&mut builder.scope_stack, module_scope);
40        let _ = builder.visit_block_without_child_scope(block);
41        builder.resolve_captures();
42
43        if FFlag::DebugLuauFreezeArena.get() {
44            unsafe {
45                (*builder.def_arena).allocator.freeze();
46                (*builder.key_arena).allocator.freeze();
47            }
48        }
49
50        // C++: `return std::move(builder.graph);` — move the graph out of the
51        // owned builder (the rest of `builder` is dropped here).
52        builder.graph
53    }
54}