luaur_analysis/methods/
constraint_generator_visit_constraint_generator.rs1use crate::enums::control_flow::ControlFlow;
2use crate::functions::does_call_error::does_call_error;
3use crate::records::constraint_generator::ConstraintGenerator;
4use crate::records::recursion_counter::RecursionCounter;
5use crate::records::recursion_limiter::RecursionLimiter;
6use crate::records::scope::Scope;
7use crate::type_aliases::scope_ptr_constraint_generator::ScopePtr;
8use alloc::vec::Vec;
9use luaur_ast::records::ast_expr_call::AstExprCall;
10use luaur_ast::records::ast_node::AstNode;
11use luaur_ast::records::ast_stat::AstStat;
12use luaur_ast::records::ast_stat_assign::AstStatAssign;
13use luaur_ast::records::ast_stat_block::AstStatBlock;
14use luaur_ast::records::ast_stat_break::AstStatBreak;
15use luaur_ast::records::ast_stat_class::AstStatClass;
16use luaur_ast::records::ast_stat_compound_assign::AstStatCompoundAssign;
17use luaur_ast::records::ast_stat_continue::AstStatContinue;
18use luaur_ast::records::ast_stat_declare_extern_type::AstStatDeclareExternType;
19use luaur_ast::records::ast_stat_declare_function::AstStatDeclareFunction;
20use luaur_ast::records::ast_stat_declare_global::AstStatDeclareGlobal;
21use luaur_ast::records::ast_stat_error::AstStatError;
22use luaur_ast::records::ast_stat_expr::AstStatExpr;
23use luaur_ast::records::ast_stat_for::AstStatFor;
24use luaur_ast::records::ast_stat_for_in::AstStatForIn;
25use luaur_ast::records::ast_stat_function::AstStatFunction;
26use luaur_ast::records::ast_stat_if::AstStatIf;
27use luaur_ast::records::ast_stat_local::AstStatLocal;
28use luaur_ast::records::ast_stat_local_function::AstStatLocalFunction;
29use luaur_ast::records::ast_stat_repeat::AstStatRepeat;
30use luaur_ast::records::ast_stat_return::AstStatReturn;
31use luaur_ast::records::ast_stat_type_alias::AstStatTypeAlias;
32use luaur_ast::records::ast_stat_type_function::AstStatTypeFunction;
33use luaur_ast::records::ast_stat_while::AstStatWhile;
34use luaur_ast::rtti::ast_node_as;
35use luaur_common::DFInt;
36use luaur_common::FFlag;
37use luaur_common::LUAU_ASSERT;
38
39impl ConstraintGenerator {
40 pub fn visit_scope_ptr_ast_stat(
41 &mut self,
42 scope: &ScopePtr,
43 stat: *mut AstStat,
44 ) -> ControlFlow {
45 unsafe {
46 let mut counter = RecursionCounter::recursion_counter_i32(&mut self.recursion_count);
47 let mut limiter: Option<RecursionLimiter> = None;
48
49 if self.recursion_count >= DFInt::LuauConstraintGeneratorRecursionLimit.get() as i32 {
50 self.report_code_too_complex((*stat).base.location);
51 return ControlFlow::None;
52 }
53
54 let scope_raw: *mut Scope = scope.as_ref() as *const Scope as *mut Scope;
57
58 let node = stat as *mut AstNode;
59 if (*node).is::<AstStatBlock>() {
60 self.visit_scope_ptr_ast_stat_block(scope, stat as *mut AstStatBlock)
61 } else if (*node).is::<AstStatIf>() {
62 self.visit_scope_ptr_ast_stat_if(scope, stat as *mut AstStatIf)
63 } else if (*node).is::<AstStatWhile>() {
64 self.visit_scope_ptr_ast_stat_while(scope, stat as *mut AstStatWhile)
65 } else if (*node).is::<AstStatRepeat>() {
66 self.visit_scope_ptr_ast_stat_repeat(scope, stat as *mut AstStatRepeat)
67 } else if (*node).is::<AstStatBreak>() {
68 ControlFlow::Breaks
69 } else if (*node).is::<AstStatContinue>() {
70 ControlFlow::Continues
71 } else if (*node).is::<AstStatReturn>() {
72 self.visit_scope_ptr_ast_stat_return(scope.clone(), stat as *mut AstStatReturn)
73 } else if (*node).is::<AstStatExpr>() {
74 let expr_stat = stat as *mut AstStatExpr;
75 self.check_pack_scope_ptr_ast_expr_vector_optional_type_id_bool(
76 scope,
77 (*expr_stat).expr,
78 &Vec::new(),
79 true,
80 );
81 let call = ast_node_as::<AstExprCall>((*expr_stat).expr as *mut AstNode);
82 if !call.is_null() && does_call_error(&*call) {
83 return ControlFlow::Throws;
84 }
85 ControlFlow::None
86 } else if (*node).is::<AstStatLocal>() {
87 self.visit_scope_ptr_ast_stat_local(scope, stat as *mut AstStatLocal)
88 } else if (*node).is::<AstStatFor>() {
89 self.visit_scope_ptr_ast_stat_for(scope, stat as *mut AstStatFor)
90 } else if (*node).is::<AstStatForIn>() {
91 self.visit_scope_ptr_ast_stat_for_in(scope, stat as *mut AstStatForIn)
92 } else if (*node).is::<AstStatAssign>() {
93 self.visit_scope_ptr_ast_stat_assign(scope, stat as *mut AstStatAssign)
94 } else if (*node).is::<AstStatCompoundAssign>() {
95 self.visit_scope_ptr_ast_stat_compound_assign(
96 scope,
97 stat as *mut AstStatCompoundAssign,
98 )
99 } else if (*node).is::<AstStatFunction>() {
100 self.visit_scope_ptr_ast_stat_function(scope, stat as *mut AstStatFunction)
101 } else if (*node).is::<AstStatLocalFunction>() {
102 self.visit_scope_ptr_ast_stat_local_function(
103 scope,
104 stat as *mut AstStatLocalFunction,
105 )
106 } else if (*node).is::<AstStatTypeAlias>() {
107 self.visit_scope_ptr_ast_stat_type_alias(scope, stat as *mut AstStatTypeAlias)
108 } else if (*node).is::<AstStatTypeFunction>() {
109 self.visit_scope_ptr_ast_stat_type_function(scope, stat as *mut AstStatTypeFunction)
110 } else if (*node).is::<AstStatDeclareGlobal>() {
111 self.visit_scope_ptr_ast_stat_declare_global(
112 scope_raw,
113 stat as *mut AstStatDeclareGlobal,
114 )
115 } else if (*node).is::<AstStatDeclareFunction>() {
116 self.visit_scope_ptr_ast_stat_declare_function(
117 scope,
118 stat as *mut AstStatDeclareFunction,
119 )
120 } else if (*node).is::<AstStatDeclareExternType>() {
121 self.visit_scope_ptr_ast_stat_declare_extern_type(
122 scope_raw,
123 stat as *mut AstStatDeclareExternType,
124 )
125 } else if (*node).is::<AstStatClass>() {
126 LUAU_ASSERT!(FFlag::DebugLuauUserDefinedClasses.get());
127 self.visit_scope_ptr_ast_stat_class(scope, stat as *mut AstStatClass)
128 } else if (*node).is::<AstStatError>() {
129 self.visit_scope_ptr_ast_stat_error(scope, stat as *mut AstStatError)
130 } else {
131 LUAU_ASSERT!(false, "Internal error: Unknown AstStat type");
132 ControlFlow::None
133 }
134 }
135 }
136}