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

Function analyze_use_block

src/completion/use_edit.rs:233–306  ·  view source on GitHub ↗

Analyse the file content and return a [`UseBlockInfo`] describing the existing `use` block. This replaces the older `find_use_insert_position` — instead of a single append-at-bottom position, callers get a structure that supports alphabetical insertion via [`UseBlockInfo::insert_position_for`]. The scanning logic distinguishes top-level `use` imports from trait `use` statements inside class/enum

(content: &str)

Source from the content-addressed store, hash-verified

231/// `use` statements inside class/enum/trait bodies by tracking brace
232/// depth.
233pub(crate) fn analyze_use_block(content: &str) -> UseBlockInfo {
234 let mut existing: Vec<(u32, String)> = Vec::new();
235 let mut namespace_line: Option<u32> = None;
236 let mut php_open_line: Option<u32> = None;
237
238 // Track brace depth so we can distinguish top-level `use` imports
239 // from trait `use` statements inside class/enum/trait bodies.
240 //
241 // With semicolon-style namespaces (`namespace Foo;`), imports live
242 // at depth 0 and class bodies are at depth 1.
243 //
244 // With brace-style namespaces (`namespace Foo { ... }`), imports
245 // live at depth 1 and class bodies are at depth 2.
246 //
247 // We compute depth at the START of each line and track whether we
248 // saw a brace-style namespace to set the right threshold.
249 let mut brace_depth: u32 = 0;
250 let mut uses_brace_namespace = false;
251
252 for (i, line) in content.lines().enumerate() {
253 let trimmed = line.trim();
254
255 // The depth at the start of this line (before counting its braces).
256 let depth_at_start = brace_depth;
257
258 // Update brace depth for the NEXT line.
259 for ch in trimmed.chars() {
260 match ch {
261 '{' => brace_depth += 1,
262 '}' => brace_depth = brace_depth.saturating_sub(1),
263 _ => {}
264 }
265 }
266
267 if trimmed.starts_with("<?php") && php_open_line.is_none() {
268 php_open_line = Some(i as u32);
269 }
270
271 // Match `namespace Foo\Bar;` or `namespace Foo\Bar {`
272 // but not `namespace\something` (which is a different construct).
273 if trimmed.starts_with("namespace ") || trimmed.starts_with("namespace\t") {
274 namespace_line = Some(i as u32);
275 if trimmed.contains('{') {
276 uses_brace_namespace = true;
277 }
278 }
279
280 // The maximum brace depth at which `use` statements are still
281 // namespace imports (not trait imports inside a class body).
282 let max_import_depth = if uses_brace_namespace { 1 } else { 0 };
283
284 // Match `use Foo\Bar;`, `use Foo\{Bar, Baz};`, etc.
285 // Only at the import level — deeper means trait `use` inside a
286 // class/enum/trait body.
287 if depth_at_start <= max_import_depth
288 && (trimmed.starts_with("use ") || trimmed.starts_with("use\t"))
289 && !trimmed.starts_with("use (")
290 && !trimmed.starts_with("use(")

Calls 4

extract_use_sort_keyFunction · 0.85
containsMethod · 0.80
pushMethod · 0.80
mapMethod · 0.45