luaur_analysis/methods/
constraint_generator_check_index_name.rs1use crate::enums::value_context::ValueContext;
4use crate::functions::get_mutable_type::get_mutable_type_id;
5use crate::functions::get_table_type::get_table_type;
6use crate::functions::in_conditional::in_conditional;
7use crate::records::blocked_type::BlockedType;
8use crate::records::constraint_generator::ConstraintGenerator;
9use crate::records::has_prop_constraint::HasPropConstraint;
10use crate::records::inference::Inference;
11use crate::records::refinement_key::RefinementKey;
12use crate::type_aliases::constraint_v::ConstraintV;
13use crate::type_aliases::scope_ptr_constraint_generator::ScopePtr;
14use crate::type_aliases::type_id::TypeId;
15use alloc::string::String;
16use luaur_ast::records::ast_expr::AstExpr;
17use luaur_ast::records::location::Location;
18
19impl ConstraintGenerator {
20 pub fn check_index_name(
21 &mut self,
22 scope: &ScopePtr,
23 key: *const RefinementKey,
24 indexee: *mut AstExpr,
25 index: &String,
26 index_location: Location,
27 ) -> Inference {
28 unsafe {
29 let obj = self.check_scope_ptr_ast_expr(scope, indexee).ty;
30 let mut result: TypeId = core::ptr::null();
31
32 let mut tt = get_table_type(obj);
36
37 if tt.is_none() {
41 if let Some(local_domain) = self.local_types.find(&obj) {
42 if local_domain.size() == 1 {
43 let first = local_domain.order[0];
44 tt = get_table_type(first);
45 }
46 }
47 }
48
49 if let Some(tt) = tt {
50 if let Some(prop) = tt.props.get(index) {
51 if let Some(read_ty) = prop.read_ty {
52 result = read_ty;
53 }
54 }
55 }
56
57 if let Some(cached_has_prop_result) =
58 self.prop_index_pairs_seen.find(&(obj, index.clone()))
59 {
60 result = *cached_has_prop_result;
61 }
62
63 if result.is_null() {
64 result = (*self.arena).add_type(BlockedType::default());
65
66 let c = self.add_constraint_scope_ptr_location_constraint_v(
67 scope,
68 (*indexee).base.location,
69 ConstraintV::HasProp(HasPropConstraint {
70 result_type: result,
71 subject_type: obj,
72 prop: index.clone(),
73 context: ValueContext::RValue,
74 in_conditional: in_conditional(self.type_context),
75 suppress_simplification: false,
76 }),
77 );
78 let blocked = get_mutable_type_id::<BlockedType>(result);
79 (*blocked).set_owner(c as *const _);
80 *self
81 .prop_index_pairs_seen
82 .get_or_insert((obj, index.clone())) = result;
83 }
84
85 if !key.is_null() {
86 if let Some(ty) = self.lookup(
87 scope,
88 index_location,
89 (*key).def as crate::type_aliases::def_id_def::DefId,
90 false,
91 ) {
92 let refinement = self
93 .refinement_arena
94 .proposition_refinement_key_type_id(key, (*self.builtin_types).truthyType);
95 return Inference::inference_type_id_refinement_id(ty, refinement);
96 }
97
98 self.update_r_value_refinements_scope_ptr_def_id_type_id(
99 scope,
100 (*key).def as crate::type_aliases::def_id_def::DefId,
101 result,
102 );
103 }
104
105 if !key.is_null() {
106 let refinement = self
107 .refinement_arena
108 .proposition_refinement_key_type_id(key, (*self.builtin_types).truthyType);
109 Inference::inference_type_id_refinement_id(result, refinement)
110 } else {
111 Inference::inference_type_id_refinement_id(result, core::ptr::null_mut())
112 }
113 }
114 }
115}