Skip to content

Detect the _deprecated_file() call anywhere in a file's uses - #281

Open
sirreal wants to merge 2 commits into
masterfrom
fix-deprecated-file-detection
Open

Detect the _deprecated_file() call anywhere in a file's uses#281
sirreal wants to merge 2 commits into
masterfrom
fix-deprecated-file-detection

Conversation

@sirreal

@sirreal sirreal commented Aug 18, 2026

Copy link
Copy Markdown
Member

The importer flags a file as deprecated only when uses.functions[0] — the first recorded call in the file — is _deprecated_file(). Any call preceding it silently loses the deprecation flag, and an empty uses list raises an undefined-offset notice. The importer now searches the uses list for the _deprecated_file record and reads deprecation_version from that record.

Complements #277, which makes the exporter attach deprecation_version to the deprecating call's own record instead of index 0. With pre-#277 export data where the deprecating call isn't first, the version sits on the wrong record and the file stays unflagged — the same outcome as today, so this change is non-regressing under either exporter and becomes fully correct once #277 lands. The tests feed hand-built uses data to the importer, so they exercise the importer's contract without depending on the exporter's placement.

The after-other-calls test and the empty-uses test fail on master (one missed flag, one undefined-offset error); all pass with the fix, as does the full suite.

Found during the review of #262; extracted as a standalone change.

🤖 Generated with Claude Code

@sirreal sirreal left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

This is an agentic review, generated by Claude Code at the repository owner's request.

Ready to land.

Verified

  • CI green on 7.4 and 8.4; mergeable, clean, based on master.

  • Both bugs are real. master reads $file['uses']['functions'][0] unconditionally inside isset( $file['uses']['functions'] ) — an empty-but-set uses list is an undefined offset (notice on 7.4, warning on 8.x), and it then reads ['deprecation_version'] without an isset guard. The index-0-only check means any call preceding _deprecated_file() drops the flag.

  • The non-regression claim checks out. I walked the four cases against the pre-#277 exporter, which writes deprecation_version onto uses.functions[0] regardless of which record triggered it:

    • _deprecated_file at index 0 → old code and new code read the same record, same version. Identical.
    • _deprecated_file later → old code never looks past index 0 and does not flag; new code finds the record but it carries no deprecation_version (the version sits on record 0), so $deprecated_file stays false and it still does not flag. Identical.
    • Two deprecating calls → the loop breaks on the first _deprecated_file, which is also where pre-#277 put the version. Identical.

    So the change is a strict superset: it never flags less than today, and it starts flagging the missed cases once #277 places the version on the right record. The claim in the description is accurate.

  • The falsy path is unchanged downstream. import_file() sets file_meta['deprecated'] and the consumer at class-importer.php:742 is if ( ! empty( $this->file_meta['deprecated'] ) ). master produced null (plus a notice) for a version-less _deprecated_file; this produces false. Both falsy, no behavior change — and the notice is gone.

  • isset( $function_use['name'] ) plus === also makes this safe against the non-string name values that dynamic calls can produce (the importer already special-cases those elsewhere).

  • Tests pin the contract, and two are RED on master (missed flag, undefined offset), as claimed. Feeding hand-built uses arrays rather than parsing a fixture is the right call here: it tests the importer's contract independently of where the exporter happens to put the version, which is precisely the seam #277 moves.

Worth noting

  • Nothing blocking. One observation for the record: this is importer-side code, so the corpus-diff check in #284 will never cover it — the corpus diff compares exporter output only. Unit tests are the whole safety net for this file, which makes the five added here worth having.
  • The deprecated entry is stuffed into $data['doc']['tags'] as a string-keyed member of what is otherwise a numeric list of tag records. Pre-existing, out of scope, but it is why the test reads $tags['deprecated'] rather than searching the list — worth cleaning up someday.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant