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

Method resolve_class_implementation

src/definition/implementation.rs:131–200  ·  view source on GitHub ↗

Resolve go-to-implementation for a class/interface name. Resolves `name` to a fully-qualified class, checks that it is an interface or abstract class (or a non-final concrete class that may have subclasses), finds all implementors/subclasses, and returns their declaration locations.

(
        &self,
        uri: &str,
        content: &str,
        name: &str,
        ctx: &FileContext,
        name_offset: u32,
    )

Source from the content-addressed store, hash-verified

129 /// may have subclasses), finds all implementors/subclasses, and
130 /// returns their declaration locations.
131 fn resolve_class_implementation(
132 &self,
133 uri: &str,
134 content: &str,
135 name: &str,
136 ctx: &FileContext,
137 name_offset: u32,
138 ) -> Option<Vec<Location>> {
139 let class_loader = self.class_loader(ctx);
140
141 let fqn = ctx.resolve_name_at(name, name_offset);
142 let target = class_loader(&fqn)
143 .or_else(|| class_loader(name))
144 .map(Arc::unwrap_or_clone)?;
145
146 // Final classes cannot be extended, so there are no implementations.
147 if target.is_final {
148 return None;
149 }
150
151 // Whether the target is a concrete (non-abstract, non-interface)
152 // class. When it is, we include abstract subclasses in the
153 // results because the user is exploring the class hierarchy
154 // rather than looking for instantiable implementations.
155 let target_is_concrete = target.kind != ClassLikeKind::Interface && !target.is_abstract;
156
157 let target_short = target.name;
158 // Compute target FQN from the class's own namespace (most
159 // reliable), then fall back to fqn_uri_index, then to the FQN we
160 // resolved from the use-map, and finally to the short name.
161 let target_fqn = {
162 let from_class = crate::util::build_fqn(&target.name, target.file_namespace.as_deref());
163 if from_class.contains('\\') {
164 from_class
165 } else {
166 self.class_fqn_for_short(&target_short).unwrap_or_else(|| {
167 if fqn.contains('\\') {
168 fqn.clone()
169 } else {
170 target_short.to_string()
171 }
172 })
173 }
174 };
175
176 let implementors = self.find_implementors(
177 &target_short,
178 &target_fqn,
179 &class_loader,
180 target_is_concrete,
181 false,
182 );
183
184 if implementors.is_empty() {
185 return None;
186 }
187
188 let mut locations = Vec::new();

Callers 1

Calls 11

build_fqnFunction · 0.85
class_loaderMethod · 0.80
resolve_name_atMethod · 0.80
containsMethod · 0.80
class_fqn_for_shortMethod · 0.80
cloneMethod · 0.80
find_implementorsMethod · 0.80
pushMethod · 0.80
mapMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected