Skip to main content

What Gets Detected

A class is considered used when Prune finds at least one reference to it. Understanding exactly which constructs count as a reference helps you interpret the report — and explains why a class you think is used might still be flagged.

Class references Prune recognizes

CategoryExamples
Inheritanceclass A extends B, class A implements I, interface I extends J, enum E implements I
Trait usageuse SomeTrait; inside a class
Instantiationnew ClassName()
Static accessClassName::method(), ClassName::$prop, ClassName::CONST, ClassName::class
instanceof$x instanceof ClassName
Exception handlingcatch (ExceptionType $e)
Type declarationsParameter, return, and property types — including nullable, union, and intersection types
Attributes#[SomeAttribute]
Docblock types@param, @return, @var, @throws, @extends, @implements, @mixin, @see, @template … of/extends, and bare FQCNs inside generics like Collection<App\Models\User>
Route controller stringsRoute::get('/x', 'App\Http\Controllers\FooController@index') — the FQCN before @
Class-name functionsclass_exists(), interface_exists(), class_implements(), class_parents(), is_a(), is_subclass_of(), app()

Notes on string-based detection

  • Docblocks: short type names are resolved through the file's use imports; fully qualified names are taken as-is.
  • Function calls like class_exists('App\\Models\\User') and route controller strings are only matched when the string is a fully qualified name (contains a backslash). Ambiguous short names are deliberately ignored to avoid false "uses".

What is not counted as a reference

  • Built-in and pseudo typesself, static, parent, int, string, float, bool, array, object, mixed, void, never, null, true, false, iterable, callable are never treated as class references.
  • Dynamic class namesnew $class(), $class::method(), container make() calls, etc.
  • Short string class names — class names passed as non-FQCN strings.
  • See Limitations & Risks for the complete picture.

Blade view references

For Blade analysis, the constructs that count as a view reference are listed in Blade Analysis.

Why this matters

If a class is only reachable through one of the constructs in the "not counted" list, Prune will report it as an orphan even though your application uses it at runtime. This is expected behavior for a static analyzer — always confirm before deleting.