Validate handwritten mock() method return type, visibility, and uniqueness#210
Merged
Validate handwritten mock() method return type, visibility, and uniqueness#210
Conversation
The @INSTANTIABLE macro now checks that a user-defined mock() method returns Self or the declaring type name. A wrong or missing return type produces an error with a fix-it that corrects the signature. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #210 +/- ##
========================================
Coverage 99.94% 99.94%
========================================
Files 40 40
Lines 5422 5584 +162
========================================
+ Hits 5419 5581 +162
Misses 3 3
🚀 New features to boost your workflow:
|
Add return type, public, and per-return-type duplicate validation for mock() methods declared on @INSTANTIABLE extensions. This brings extension mock validation to parity with the concrete declaration path. Also fix the not-public fix-it for both branches to clear the old first modifier's leading trivia after inserting `public` before it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Match each mock to its corresponding instantiate() method by return type and verify the mock has parameters for all dependencies. Also make Initializer.init(_: FunctionDeclSyntax) public so the macro can create Initializer instances for each extension mock function. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mirror the instantiate() validation model: compare parsed TypeDescriptions via strippingGenerics instead of base name string matching. This correctly handles nested types (Outer.Inner) and canonicalizes Self to the declaring type for duplicate detection, so `-> Self` and `-> TypeName` are treated as the same return type. Also makes TypeDescription.strippingGenerics public so the macro module can use it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The dependency-match step used raw mockReturnType to find the matching instantiate() method, so mock() -> Self never matched any instantiable and skipped argument validation entirely. Now Self is resolved to the extended type via strippingGenerics before the lookup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Self is not a valid return type for instantiate() on extensions (the visitor rejects it), so mock() -> Self should be rejected too. This removes Self canonicalization from the extension branch entirely — return type validation, duplicate detection, and argument validation all use the raw mockReturnType directly, matching mocks to their corresponding instantiate() methods by exact return type. Self remains valid on concrete type declarations where it is unambiguous. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
mockMethodIncorrectReturnTypeerror toFixableInstantiableErrorthat fires when a user-definedmock()method has an invalid return typeSelfor the type name@Instantiabletypes, the return type must match the extended type (e.g.-> Container<Bool>), mirroring the correspondinginstantiate()method —Selfis rejected, consistent withinstantiate()validationstrippingGenericscomparison (mirroringinstantiate()validation) rather than base name string matching, correctly handling nested types and generic specializationsinstantiate()method's dependenciespublic)Initializer.init(_: FunctionDeclSyntax)andTypeDescription.strippingGenericspublic so the macro module can use themTest plan
FixableInstantiableErrorTestsfor description and fix-it messageInstantiableMacroTestsfor concrete types: wrong return type, array-wrapped return type, no return type, returningSelf, returning the type nameInstantiableMacroTestsfor extensions: not public, wrong return type, array-wrapped return type, no return type, returningSelf(rejected), returning extended type, generic specialization, duplicate same-return-type, Self + type-name pair, multiple different-return-types, missing dependency argument, matching dependency argument🤖 Generated with Claude Code