diff --git a/src/analyzer/expr/call/new_analyzer.rs b/src/analyzer/expr/call/new_analyzer.rs index 45f55647..4d3efcf0 100644 --- a/src/analyzer/expr/call/new_analyzer.rs +++ b/src/analyzer/expr/call/new_analyzer.rs @@ -61,14 +61,14 @@ pub(crate) fn analyze( "self" => { let self_name = &context.function_context.calling_class.unwrap(); - get_named_object(*self_name, &None) + get_named_object(*self_name, None) } "parent" => { let self_name = &context.function_context.calling_class.unwrap(); let classlike_storage = codebase.classlike_infos.get(self_name).unwrap(); - get_named_object(classlike_storage.direct_parent_class.unwrap(), &None) + get_named_object(classlike_storage.direct_parent_class.unwrap(), None) } "static" => { let self_name = &context.function_context.calling_class.unwrap(); @@ -101,19 +101,10 @@ pub(crate) fn analyze( )); }; - let type_resolution_context = if let Some(id) = - context.function_context.calling_functionlike_id - { - if let Some(storage) = codebase.functionlike_infos.get(&id.to_ref()) { - &storage.type_resolution_context - } else { - &None - } - } else { - &None - }; + let type_resolution_context = + statements_analyzer.get_type_resolution_context(); - get_named_object(name_string, type_resolution_context) + get_named_object(name_string, Some(type_resolution_context)) } } } else { diff --git a/src/analyzer/expr/call/static_call_analyzer.rs b/src/analyzer/expr/call/static_call_analyzer.rs index 20ef14d3..c0a782b4 100644 --- a/src/analyzer/expr/call/static_call_analyzer.rs +++ b/src/analyzer/expr/call/static_call_analyzer.rs @@ -56,7 +56,7 @@ pub(crate) fn analyze( classlike_name = Some(*self_name); - get_named_object(*self_name, &None) + get_named_object(*self_name, None) } StrId::PARENT => { let self_name = @@ -107,21 +107,24 @@ pub(crate) fn analyze( }) } _ => { - classlike_name = Some(*name); + let type_resolution_context = + statements_analyzer.get_type_resolution_context(); - let type_resolution_context = if let Some(id) = - context.function_context.calling_functionlike_id - { - if let Some(storage) = codebase.functionlike_infos.get(&id.to_ref()) { - &storage.type_resolution_context - } else { - &None + let lhs = get_named_object(*name, Some(type_resolution_context)); + + match lhs.get_single() { + TAtomic::TNamedObject { name, .. } => { + classlike_name = Some(*name); + } + TAtomic::TGenericClassname { as_type, .. } => { + if let TAtomic::TNamedObject { name, .. } = &**as_type { + classlike_name = Some(*name); + } } - } else { - &None - }; + _ => (), + } - get_named_object(*name, type_resolution_context) + lhs } } } else { diff --git a/src/analyzer/expr/fetch/static_property_fetch_analyzer.rs b/src/analyzer/expr/fetch/static_property_fetch_analyzer.rs index b9dbfa05..e2dc71ee 100644 --- a/src/analyzer/expr/fetch/static_property_fetch_analyzer.rs +++ b/src/analyzer/expr/fetch/static_property_fetch_analyzer.rs @@ -98,20 +98,10 @@ pub(crate) fn analyze( EFFECT_READ_PROPS, ); - let type_resolution_context = if let Some(id) = context.function_context.calling_functionlike_id - { - if let Some(storage) = codebase.functionlike_infos.get(&id.to_ref()) { - &storage.type_resolution_context - } else { - &None - } - } else { - &None - }; - + let type_resolution_context = statements_analyzer.get_type_resolution_context(); analysis_data.set_expr_type( &stmt_class.1, - get_named_object(classlike_name, type_resolution_context), + get_named_object(classlike_name, Some(type_resolution_context)), ); let prop_name = match &stmt_name { diff --git a/src/analyzer/expr/xml_analyzer.rs b/src/analyzer/expr/xml_analyzer.rs index 1cc57b53..a99270e3 100644 --- a/src/analyzer/expr/xml_analyzer.rs +++ b/src/analyzer/expr/xml_analyzer.rs @@ -239,7 +239,7 @@ pub(crate) fn analyze( analysis_data.expr_types.insert( (pos.start_offset() as u32, pos.end_offset() as u32), - Rc::new(get_named_object(*xhp_class_name, &None)), + Rc::new(get_named_object(*xhp_class_name, None)), ); Ok(()) diff --git a/src/analyzer/stmt/try_analyzer.rs b/src/analyzer/stmt/try_analyzer.rs index e694b587..86ae11d5 100644 --- a/src/analyzer/stmt/try_analyzer.rs +++ b/src/analyzer/stmt/try_analyzer.rs @@ -170,7 +170,7 @@ pub(crate) fn analyze( let catch_var_id = &catch.1 .1 .1; - let mut catch_type = get_named_object(*catch_classlike_name, &None); + let mut catch_type = get_named_object(*catch_classlike_name, None); catch_context.remove_descendants( catch_var_id, diff --git a/src/code_info_builder/classlike_scanner.rs b/src/code_info_builder/classlike_scanner.rs index 4bc4e2d2..f62e571c 100644 --- a/src/code_info_builder/classlike_scanner.rs +++ b/src/code_info_builder/classlike_scanner.rs @@ -234,7 +234,7 @@ pub(crate) fn scan( { storage.template_extended_offsets.insert( interface_name, - vec![Arc::new(get_named_object(*class_name, &None))], + vec![Arc::new(get_named_object(*class_name, None))], ); } else { storage.template_extended_offsets.insert( diff --git a/src/file_scanner_analyzer/populator.rs b/src/file_scanner_analyzer/populator.rs index fde7bc9c..d9764d6b 100644 --- a/src/file_scanner_analyzer/populator.rs +++ b/src/file_scanner_analyzer/populator.rs @@ -319,6 +319,22 @@ fn populate_functionlike_storage( } } + if let Some(ref mut type_resolution_context) = storage.type_resolution_context { + for (_, type_param_map) in type_resolution_context.template_type_map.iter_mut() { + for (_, v) in type_param_map { + if force_type_population || v.needs_population() { + populate_union_type( + Arc::make_mut(v), + codebase_symbols, + reference_source, + symbol_references, + force_type_population, + ); + } + } + } + } + for (_, where_type) in storage.where_constraints.iter_mut() { populate_union_type( where_type, @@ -632,12 +648,7 @@ fn populate_data_from_trait( symbol_references: &mut SymbolReferences, safe_symbols: &FxHashSet, ) { - populate_classlike_storage( - trait_name, - codebase, - symbol_references, - safe_symbols, - ); + populate_classlike_storage(trait_name, codebase, symbol_references, safe_symbols); symbol_references.add_symbol_reference_to_symbol(storage.name, *trait_name, true); diff --git a/src/ttype/lib.rs b/src/ttype/lib.rs index 208dadc5..d7a496de 100644 --- a/src/ttype/lib.rs +++ b/src/ttype/lib.rs @@ -118,7 +118,7 @@ pub fn get_object() -> TUnion { #[inline] pub fn get_named_object( name: StrId, - type_resolution_context: &Option, + type_resolution_context: Option<&TypeResolutionContext>, ) -> TUnion { if let Some(type_resolution_context) = type_resolution_context { if let Some(t) = type_resolution_context