Skip to content

PHP: explain on a class node omits the file's imports, so "what does X depend on?" under-reports #75

Description

@filipechagas

Found while validating the fork on providers-api.lawnstarter.com for PE-80051 (adoption epic).

Version: graphify 0.9.40, fork origin/v8 = 5e9d95c11837aeabbbb5d90cb45544f49dc58ca4.

Summary

imports edges are attached to the file node, but a user asking "what does class X depend on?" naturally runs graphify explain "X" against the class node. The class node carries none of the imports, so explain reports a strict and silent subset of the real dependencies.

In the minimal case below explain "Consumer" reports zero dependencies for a class that depends on Thing.

Minimal reproduction

// src/Dep/Thing.php
<?php
namespace App\Dep;

class Thing {}
// src/Consumer.php
<?php
namespace App;

use App\Dep\Thing;

class Consumer
{
    public function make(): Thing { return new Thing(); }
}
$ graphify update .
$ graphify explain "Consumer"
Node: Consumer
  Source:    src/Consumer.php L6
  Degree:    2

Connections (2):
  --> .make() [method] [EXTRACTED] src/Consumer.php:L8
  <-- Consumer.php [contains] [EXTRACTED] src/Consumer.php:L6

Thing does not appear. It is only reachable from the file node:

$ graphify explain "Consumer.php"
Connections (2):
  --> Thing [imports] [EXTRACTED] src/Consumer.php:L4
  --> Consumer [contains] [EXTRACTED] src/Consumer.php:L6

Impact on the real repo

For App\Actions\Assessment\ScoreAssessmentAnswer, grep gives 8 adjudicated dependencies: AssessmentScorerService, ProviderAssessmentAnswer, ProviderAssessmentAnswerRepository, CarbonImmutable, ModelNotFoundException, Log, BaseAction, CheckAssessmentCompletion.

  • graphify explain "ScoreAssessmentAnswer" (class node) returns 4: ProviderAssessmentAnswerRepository, BaseAction, CheckAssessmentCompletion, AssessmentScorerService. Missing: ProviderAssessmentAnswer, CarbonImmutable, ModelNotFoundException, Log.
  • graphify explain "ScoreAssessmentAnswer.php" (file node) returns 7 — the imports — but misses CheckAssessmentCompletion, which is a constructor dependency in the same namespace and therefore has no use statement.

Neither single command returns the full set; only the union of both does. This failed the "what does X depend on?" gate question for the repo.

Suggested fix

Either roll the file's imports into explain output when the target is a class contained by that file, or have explain on a class note that imports live on the file node and print the file node's edges alongside.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions