MCPcopy Create free account
hub / github.com/PHPantom-dev/phpantom_lsp / resolve_subject_outcome

Function resolve_subject_outcome

src/completion/resolver.rs:1033–1132  ·  view source on GitHub ↗

Resolve a subject to a [`SubjectOutcome`] in a single pass. This is the unified entry point for diagnostic subject resolution. It resolves the subject to `Vec ` (the same pipeline used by completion and hover) and classifies the result: - If any entry has `class_info`, return `Resolved`. - If all entries are primitive scalars, return `Scalar`. - If a type string refers to an unloada

(
    subject: &str,
    access_kind: AccessKind,
    ctx: &ResolutionCtx<'_>,
)

Source from the content-addressed store, hash-verified

1031/// `UnresolvableClass`.
1032/// - If the result is empty, return `Untyped`.
1033pub(crate) fn resolve_subject_outcome(
1034 subject: &str,
1035 access_kind: AccessKind,
1036 ctx: &ResolutionCtx<'_>,
1037) -> SubjectOutcome {
1038 let resolved = resolve_target_classes(subject, access_kind, ctx);
1039 if !resolved.is_empty() {
1040 // ── Check for class-bearing entries ──────────────────────
1041 let arced: Vec<Arc<ClassInfo>> = ResolvedType::into_arced_classes(resolved.clone());
1042 if !arced.is_empty() {
1043 return SubjectOutcome::Resolved(arced);
1044 }
1045
1046 // ── All entries are type-string-only (no class info) ────
1047 let joined = ResolvedType::types_joined(&resolved);
1048
1049 // Pure scalar — member access is a runtime crash.
1050 if joined.all_members_primitive_scalar() {
1051 let scalar = joined.non_null_type().unwrap_or(joined);
1052 return SubjectOutcome::Scalar(scalar);
1053 }
1054
1055 // stdClass / object — synthetic resolution.
1056 if resolved
1057 .iter()
1058 .any(|rt| rt.type_string.is_named_ci("stdclass") || rt.type_string.is_object())
1059 {
1060 let synthetic = Arc::new(ClassInfo {
1061 name: crate::atom::atom("stdClass"),
1062 ..ClassInfo::default()
1063 });
1064 return SubjectOutcome::Resolved(vec![synthetic]);
1065 }
1066
1067 // Non-scalar, non-class type — check for unresolvable class.
1068 if let Some(unresolved) = check_unresolvable_class_name(&joined, ctx.class_loader) {
1069 return SubjectOutcome::UnresolvableClass(unresolved);
1070 }
1071 return SubjectOutcome::Untyped;
1072 }
1073
1074 // ── Result is empty — classify why ──────────────────────────
1075 let expr = SubjectExpr::parse(subject);
1076
1077 // For call expressions, check the raw return type hint.
1078 if let SubjectExpr::CallExpr {
1079 callee,
1080 args_text: _,
1081 } = &expr
1082 {
1083 if let Some(scalar) = resolve_call_scalar_return(callee, access_kind, ctx) {
1084 return SubjectOutcome::Scalar(scalar);
1085 }
1086 // Try unresolvable class detection for function calls.
1087 if let SubjectExpr::FunctionCall(fn_name) = callee.as_ref()
1088 && let Some(fl) = ctx.function_loader
1089 && let Some(func_info) = fl(fn_name.as_str())
1090 && let Some(ref raw_type) = func_info.return_type

Callers 2

resolve_variable_subjectFunction · 0.85

Calls 15

resolve_target_classesFunction · 0.85
atomFunction · 0.85
resolved_to_arcsFunction · 0.85
cloneMethod · 0.80
non_null_typeMethod · 0.80

Tested by

no test coverage detected