Skip to content

Fix generated code ordering with transitive Instantiator captures#196

Merged
dfed merged 4 commits intomainfrom
worktree-stateless-imagining-ritchie
Mar 10, 2026
Merged

Fix generated code ordering with transitive Instantiator captures#196
dfed merged 4 commits intomainfrom
worktree-stateless-imagining-ritchie

Conversation

@dfed
Copy link
Owner

@dfed dfed commented Mar 10, 2026

Summary

  • Fix topological sort in orderedPropertiesToGenerate to detect transitive optional dependencies by intersecting unfulfilled scope keys with both received properties and their unwrapped variants
  • Remove now-redundant onlyIfAvailableUnwrappedReceivedProperties computed property
  • Bump podspec to 1.5.2

Fixes #195

Test plan

  • New test run_writesConvenienceExtensionOnRootOfTree_whenInstantiatorClosureTransitivelyCapturesVariableDeclaredLaterAlphabetically passes
  • Full test suite (263 tests) passes with no regressions

🤖 Generated with Claude Code

dfed and others added 3 commits March 9, 2026 23:26
When a root @INSTANTIABLE has both an @Instantiated service and an
@Instantiated Instantiator<ChildVC> where the child transitively depends
on the service via @received(onlyIfAvailable: true), the generated code
placed the Instantiator closure before the service variable declaration,
causing a Swift compiler error: closure captures 'service' before it is
declared.

The topological sort in orderedPropertiesToGenerate now intersects
unfulfilled scope keys with both received properties and their unwrapped
variants, correctly detecting transitive optional dependencies. The
now-redundant onlyIfAvailableUnwrappedReceivedProperties computed
property has been removed. Bumps podspec to 1.5.2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mark the scope as fulfilled in the map before recursing into
dependencies, preventing cycles when two sibling scopes each have
optional received properties that unwrap to each other's property type.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dfed dfed self-assigned this Mar 10, 2026
@codecov
Copy link

codecov bot commented Mar 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.90%. Comparing base (e3708fb) to head (efd2dc8).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #196   +/-   ##
=======================================
  Coverage   99.90%   99.90%           
=======================================
  Files          32       32           
  Lines        3264     3274   +10     
=======================================
+ Hits         3261     3271   +10     
  Misses          3        3           
Files with missing lines Coverage Δ
Sources/SafeDICore/Generators/ScopeGenerator.swift 100.00% <100.00%> (ø)
Sources/SafeDITool/SafeDITool.swift 99.56% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dfed dfed marked this pull request as ready for review March 10, 2026 06:52
Instead of unwrapping all optional received properties (which could
create false dependencies for regular @received optional properties),
propagate onlyIfAvailable unwrapped properties transitively through
the scope tree, mirroring how receivedProperties propagates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@dfed dfed merged commit ebb6b3d into main Mar 10, 2026
25 checks passed
@dfed dfed deleted the worktree-stateless-imagining-ritchie branch March 10, 2026 07:15
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.

Generated code ordering bug: Instantiator closure captures variable before it is declared

1 participant