Skip to content

Fix mock closure types to use property type and handle erased existentials#251

Merged
dfed merged 1 commit intomainfrom
dfed/fix-builderClosureType-property-type
Apr 15, 2026
Merged

Fix mock closure types to use property type and handle erased existentials#251
dfed merged 1 commit intomainfrom
dfed/fix-builderClosureType-property-type

Conversation

@dfed
Copy link
Copy Markdown
Owner

@dfed dfed commented Apr 14, 2026

Summary

  • MockParameterNode.builderClosureType used concreteType for the closure return type, causing type mismatches when the property type differs (e.g., NetworkService fulfilled by DefaultNetworkService, or AnyService wrapping ConcreteService)
  • Changed to use instantiatedTypeDescription (property type) so SafeDIOverrides closures match the parent init signature
  • For erasedToConcreteExistential, the mock body now splits override vs default paths: overrides return the wrapper type directly, defaults wrap the concrete builder result
  • Helper function return types updated from concrete to property type throughout
  • Instantiator construction no longer double-wraps erased existentials
  • Added defaultBuilderCall(arguments:) to generate direct calls (e.g., ConcreteService(helper: helper)) instead of curried function references (e.g., ConcreteService.init(helper:)(helper)) in erased default paths — faster for the compiler to type-check

Test plan

  • 781 existing tests pass with updated expectations
  • Example SPM project compiles
  • CI passes (example Xcode projects compile with new generated code)

🤖 Generated with Claude Code

dfed added a commit that referenced this pull request Apr 14, 2026
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (4c55a55) to head (17cf0a5).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##              main      #251   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           41        41           
  Lines         6115      6213   +98     
=========================================
+ Hits          6115      6213   +98     
Files with missing lines Coverage Δ
Sources/SafeDICore/Generators/ScopeGenerator.swift 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from 04e65e2 to 38b6e2e Compare April 14, 2026 20:28
@dfed dfed changed the title Fix builderClosureType to use property type instead of concrete type Fix mock closure types to use property type and handle erased existentials Apr 14, 2026
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 14, 2026

@codex-review

@chatgpt-codex-connector
Copy link
Copy Markdown

Review Result (@codex-review)

I reviewed the PR changes and did not find any blocking issues.

The core fix (using property/instantiated type for generated closure signatures instead of concrete fulfillment type) appears consistent with the generated API shape expected by SafeDIOverrides, especially for protocol-typed dependencies and erased existential wrappers. The generator logic also now cleanly separates override-vs-default paths for erased existentials to avoid incorrect double-wrapping.。 Sources/SafeDICore/Generators/ScopeGenerator.swiftL892-L902 Sources/SafeDICore/Generators/ScopeGenerator.swiftL1458-L1516 Sources/SafeDICore/Generators/ScopeGenerator.swiftL1690-L1733

The updated snapshot-style expectations in tests reflect the intended type signatures and builder behavior (e.g., override closures typed to property protocols and instantiator helper return wiring). Tests/SafeDIToolTests/SafeDIToolMockGenerationTests.swiftL3631-L3654 Tests/SafeDIToolTests/SafeDIToolMockGenerationTests.swiftL3701-L3713

No follow-up code changes were required from this review pass, so I did not create a commit or a follow-up PR.


Validation / Checks run

  • git status --short && git branch --show-current && git log --oneline -5
  • git diff --name-only 400d234..38b6e2e
  • git diff --stat 400d234..38b6e2e && git diff 400d234..38b6e2e -- Sources/SafeDICore/Generators/ScopeGenerator.swift | sed -n '1,220p'
  • nl -ba Sources/SafeDICore/Generators/ScopeGenerator.swift | sed -n '885,930p;1450,1535p;1645,1735p'
  • nl -ba Tests/SafeDIToolTests/SafeDIToolMockGenerationTests.swift | sed -n '3600,3785p'
  • swift test -q (fails in this environment with no such module 'SafeDICore' from Tests/SafeDIToolTests/Helpers/SafeDIToolTestExecution.swift).

View task →

@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from 38b6e2e to 39504d3 Compare April 14, 2026 21:30
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 14, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 39504d3767

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch 2 times, most recently from 55dbb37 to a609395 Compare April 14, 2026 21:47
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 14, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a60939595e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift Outdated
Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from a609395 to f7a7b54 Compare April 14, 2026 22:02
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 14, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f7a7b54fae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift Outdated
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from f7a7b54 to f91cd57 Compare April 14, 2026 22:22
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 14, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f91cd579c7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from f91cd57 to c4ad163 Compare April 14, 2026 23:01
@dfed dfed self-assigned this Apr 14, 2026
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 14, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from c4ad163 to 23bddf7 Compare April 14, 2026 23:25
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 14, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23bddf7aab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from 23bddf7 to b665ab9 Compare April 14, 2026 23:48
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b665ab92de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from b665ab9 to aa1a9b4 Compare April 15, 2026 00:44
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aa1a9b48c9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aa1a9b48c9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift Outdated
Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from aa1a9b4 to 378ab0e Compare April 15, 2026 01:24
@dfed dfed marked this pull request as ready for review April 15, 2026 01:25
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 378ab0e347

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from 378ab0e to 030d747 Compare April 15, 2026 02:49
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

1 similar comment
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 030d747f48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift Outdated
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from 030d747 to fff3115 Compare April 15, 2026 03:03
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fff311596f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from fff3115 to 5f90597 Compare April 15, 2026 03:12
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from 5f90597 to 325e303 Compare April 15, 2026 03:13
@dfed
Copy link
Copy Markdown
Owner Author

dfed commented Apr 15, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 325e303964

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
…tials

MockParameterNode.builderClosureType used concreteType for the closure
return type, causing type mismatches when the property type differs from
the concrete type (e.g., protocol fulfilled by concrete, or type-erased
wrapper like AnyService).

Changes:
- builderClosureType now uses instantiatedTypeDescription (property type)
  so SafeDIOverrides closures match what the parent init expects
- For erasedToConcreteExistential, the mock body splits override vs
  default paths: overrides return the wrapper type directly, defaults
  wrap the concrete builder result (e.g., AnyService(ConcreteService()))
- Helper function return types updated from concrete to property type
- Instantiator construction no longer double-wraps erased existentials

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dfed dfed force-pushed the dfed/fix-builderClosureType-property-type branch from 325e303 to 17cf0a5 Compare April 15, 2026 03:36
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 17cf0a5834

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/SafeDICore/Generators/ScopeGenerator.swift
@dfed dfed merged commit 071ce62 into main Apr 15, 2026
17 checks passed
@dfed dfed deleted the dfed/fix-builderClosureType-property-type branch April 15, 2026 04:29
dfed added a commit that referenced this pull request Apr 20, 2026
…nit (#270)

## Summary
Capture convention/mechanism knowledge that wasn't load-bearing in the
code but has tripped up recent work. All additions are docs + one small
helper extraction — no behavior change.

## What's documented

**Cycle mechanisms table** (CLAUDE.md). Four related things —
`isPropertyCycle`, `cycleEdges`, `throwIfInvalidCycle`,
`validateMockRootScopeForCycles` — each doing a different job with
overlapping names. Table names them, says where each is set, and what it
does. Also explicit: if `throwIfInvalidCycle` accepts a cycle, every hop
is non-constant.

**`erasedToConcreteExistential` × property-type matrix** (CLAUDE.md
Common Pitfalls). The flag doesn't imply a constant property type — it's
orthogonal. Four rows cover all combinations and whether each can appear
in an accepted cycle. This mistake cost a round trip in #259 when
defensive branches were removed on a wrong "erased = constant"
assumption.

**Two-layer mock return type** (CLAUDE.md Mock generation specifics).
Inner closure type (`builderClosureType`, #251) vs outer `mock()` return
type (#266) are distinct concerns when a `customMock` returns a type
other than `Self`. Both layers have to agree.

**"Selected construction initializer"** (CLAUDE.md). SafeDI picks a
single canonical initializer per type. Validation that only matters for
the path SafeDI uses (e.g., `Self.*`-in-default-expression check) should
gate on this, not walk every initializer. Was #268's P1 bug class.

**"Structurally unreachable" claims need a failing test** (CLAUDE.md
Testing Philosophy). Codifies the discipline we're already trying to
hold — structural arguments are easy to get wrong.

**Inline /// comments**:
- `MockParameterNode.isPropertyCycle` cross-references `cycleEdges`
(per-root syntactic vs global feedback arc set).
- `MockContext.cycleEdges` cross-references `isPropertyCycle` (opposite
direction).
- `throwIfInvalidCycle` docstring expanded with explicit rejection
classes and acceptance condition.

## Code change

Add `InstantiableVisitor.canonicalConstructionInitializer` computed
property. Route the two existing `initializers.first(where: {
$0.isValid(forFulfilling: dependencies) })` call sites through it:
- `InstantiableVisitor.swift:377` (building `Instantiable.initializer`)
- `InstantiableMacro.swift:259` (the
`hasMemberwiseInitializerForInjectableProperties` guard)

Removes drift risk — previously the macro recomputed the selector
separately.

## Test plan
- [x] `swift test --traits sourceBuild` — 885 tests pass
- [x] `./CLI/lint.sh`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dfed added a commit that referenced this pull request Apr 20, 2026
…sts (#276)

## Summary
Five mock-generation tests carried `skipCompileVerification: true`
FIXMEs pointing at generator bugs that have since been fixed. Removing
the opt-outs confirms the fixes hold end-to-end (fresh parse → generated
code → actual swiftc typecheck).

## Changes
Removed the FIXME comments and `skipCompileVerification: true` flag on:

| Test | Bug | Fixed in |
|------|-----|----------|
|
`mock_usesMockOnly_whenProductionHasNoMockAndBothFulfillSameAdditionalType`
| mockOnly not coerced to fulfilled-slot type | #251 |
| `mock_sendableClosureDependencyProducesValidIdentifier` | `@escaping`
dropped on `@Sendable` closure on mock() | #267 |
| `mock_generatedForFullyLazyInstantiationCycle` | Fully-lazy cycles
produced self-referential `SafeDIMockConfiguration` defaults | #259 |
| `mock_extensionUserMockReturningAdditionalTypeUsedForProtocolProperty`
| customMock return type disagreement between root call site and type's
own `mock()` | #266 |
|
`mock_extensionUserMockReturningAdditionalTypeNotUsedForConcreteProperty`
| Same as above — sibling test | #266 |

## Test plan
- [x] `swift test --traits sourceBuild` — 901 tests pass (up from 901;
no tests added, but all five now exercise the compile-verification path)
- [x] `./CLI/lint.sh`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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