Skip to content

Fix JsonPointer for properties transferred from $ref composition branches - #154

Open
torian257x wants to merge 1 commit into
wol-soft:masterfrom
torian257x:fix/b7-render-dedup
Open

torian257x wants to merge 1 commit into
wol-soft:masterfrom
torian257x:fix/b7-render-dedup

Conversation

@torian257x

@torian257x torian257x commented Jun 15, 2026 •

Copy link
Copy Markdown

Summary

Rebased onto current master and reduced to the one fix that still reproduces there.

A property merged into a composed schema's class from a $ref'd composition branch received the referenced definition's JSON pointer (e.g. /$defs/Extra/properties/age) instead of its position within the composition (/allOf/0/properties/age). PropertyAttributeSynthesizer now takes the pointer from the composition branch schema, falling back to the property's own pointer for inline branches.

Test

CompositionBranchJsonPointerTest:

  • testTransferredPropertyFromRefBranchHasCorrectJsonPointer — fails on master, passes with this change.
  • testTransferredPropertyFromInlineBranchHasCorrectJsonPointer — regression guard for inline branches.

What was dropped from the earlier version of this PR

The RenderQueue::addRenderJob deduplication + RenderJob changes were removed. Investigation showed the duplicate render they guarded against does not occur on master (the full suite renders with zero duplicates once the guard is removed) — it was an artifact of the class-name cache-key change from the now-closed B5 PR (#152), not an independent issue. Per the "fix the root cause, not a workaround" review note, only the synthesizer fix remains.

@torian257x

Copy link
Copy Markdown
Author

This PR addresses the B7 feedback from PR #150. I am an AI assistant working on behalf of @torian257x.

"B7 silent skip in RenderJob looks more like working on symptoms rather than fixing issues on the root."

Fixed. The class_exists guard was removed from RenderJob::render(). Dedup is now handled at the correct level in RenderQueue::addRenderJob(), which uses Schema object identity to distinguish cached reuse from genuine duplicates.

"The patch of cloneTransferredProperty looks reasonable but it's not covered by a test case."

Added testTransferredPropertyJsonPointerIsCorrect in B7RenderDedupTest.php, which asserts the transferred property has #[JsonPointer("/allOf/0/properties/age")].

@torian257x

Copy link
Copy Markdown
Author

Updated with tests that actually fail on master and pass on this branch.

Bug #1 discovered: PropertyAttributeSynthesizer used $branchProperty->getJsonSchema()->getPointer() for transferred composition branch properties. For inline allOf branches this gives the correct pointer (e.g. /allOf/0/properties/age). But for $ref'd branches this gives the $defs location (e.g. /$defs/Extra/properties/age) instead of the composition branch position.

Proving test: B7RenderDedupTest::testTransferredPropertyFromRefBranchHasCorrectJsonPointer

  • On upstream/master: transferred property gets JsonPointer(/$defs/Extra/properties/age)
  • On this branch: transferred property gets JsonPointer(/allOf/0/properties/age)

Bug #2 discovered: RenderQueue had no dedup, and RenderJob's class_exists guard silently skipped duplicate renders. Removing the guard (as previously done) exposed duplicate renders via file_exists(). The fix uses content-signature-based dedup in addRenderJob(): same target filename + same content signature = skip silently; same filename + different content = throw FileSystemException (duplicate $id).

All 2741 tests pass with these fixes applied (8 pre-existing failures unrelated to these changes).

…ches

A property merged into a composed schema's class from a $ref'd allOf/anyOf/oneOf
branch received the referenced definition's pointer (/$defs/...) instead of its
composition branch position (/allOf/0/...). Use the branch schema's pointer so the
generated #[JsonPointer] reflects where the property is composed from.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@torian257x
torian257x force-pushed the fix/b7-render-dedup branch from 65e5e2a to 4b7f452 Compare July 23, 2026 13:50
@torian257x torian257x changed the title Fix B7: render deduplication and RenderJob cleanup Fix JsonPointer for properties transferred from $ref composition branches Jul 23, 2026
@torian257x

Copy link
Copy Markdown
Author

@wol-soft — rebased onto current master and reduced to the one fix that still reproduces there:

  • Kept: the PropertyAttributeSynthesizer fix. A property merged into a composed class from a $ref'd composition branch was getting the referenced definition's pointer (/$defs/…) instead of its branch position (/allOf/0/…). Proving test CompositionBranchJsonPointerTest::testTransferredPropertyFromRefBranchHasCorrectJsonPointer fails on master, passes with the change.
  • Dropped: the RenderQueue::addRenderJob deduplication and RenderJob changes. Per your "work on the root cause, not a workaround" note, I checked whether the duplicate render actually happens — removing the guard entirely, the full suite renders with zero duplicates. The duplicate only appeared in combination with the class-name cache-key change from the now-closed Fix B5: class name compounding and cache key for JsonPointer #152, so it was an artifact of that, not an independent issue. Only the synthesizer fix remains.

PR body updated to match. mergeable: true.

@wol-soft

Copy link
Copy Markdown
Owner

I actually think we don't have a bug here. I can see the idea behind the fix but the JSON Pointer holds an RFC6901 pointer which is clearly defined to provide the path within a JSON schema which can be traversed key by key. This is actually the behaviour of the master. For the tested example: /allOf/0/properties/age can't be resolved within the document whereas the JSON Pointer generated by master can be resolved and is consequently the correct pointer.

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.

2 participants