Check whether the **raw** (unmerged) class declares a member with the given name and kind. The `owner` passed to hover methods is fully resolved (inheritance + virtual providers merged in). To distinguish "this class overrides the parent's method" from "this class merely inherits it", we load the raw class from the class_loader and check its own member lists.
(
owner: &ClassInfo,
member_name: &str,
member_kind: &MemberKindForOrigin,
class_loader: &dyn Fn(&str) -> Option<Arc<ClassInfo>>,
)
| 48 | /// the parent's method" from "this class merely inherits it", we load |
| 49 | /// the raw class from the class_loader and check its own member lists. |
| 50 | fn raw_class_has_member( |
| 51 | owner: &ClassInfo, |
| 52 | member_name: &str, |
| 53 | member_kind: &MemberKindForOrigin, |
| 54 | class_loader: &dyn Fn(&str) -> Option<Arc<ClassInfo>>, |
| 55 | ) -> bool { |
| 56 | // Build the FQN the same way the class loader expects. |
| 57 | let fqn = owner.fqn(); |
| 58 | |
| 59 | // Load the raw class. If the loader returns None (e.g. the class |
| 60 | // is only known through the current file's AST and not yet indexed), |
| 61 | // fall back to assuming the member is declared — this avoids hiding |
| 62 | // indicators when the project is only partially indexed. |
| 63 | let raw = match class_loader(&fqn) { |
| 64 | Some(c) => c, |
| 65 | None => return true, |
| 66 | }; |
| 67 | |
| 68 | match member_kind { |
| 69 | MemberKindForOrigin::Method => raw |
| 70 | .methods |
| 71 | .iter() |
| 72 | .any(|m| m.name.eq_ignore_ascii_case(member_name)), |
| 73 | MemberKindForOrigin::Property => raw.properties.iter().any(|p| p.name == member_name), |
| 74 | MemberKindForOrigin::Constant => raw.constants.iter().any(|c| c.name == member_name), |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | /// Build the origin indicator lines for a member. |
| 79 | /// |
no test coverage detected