feat: support SimpleLambdaExpressionSyntax in callback validation#1042
feat: support SimpleLambdaExpressionSyntax in callback validation#1042
Conversation
) TryGetCallbackLambda previously only handled ParenthesizedLambdaExpressionSyntax, explicitly skipping SimpleLambdaExpressionSyntax in delegate constructors. This caused the analyzer to miss validating single-parameter lambdas like `new Action<int>(x => { })`. Changes: - Widen TryGetCallbackLambda return type to LambdaExpressionSyntax - Add GetLambdaParameters helper to extract parameters from both lambda forms - Add GetDiagnosticNode helper for correct diagnostic span placement - Remove the SimpleLambdaExpressionSyntax bail-out guard - Add test cases for simple lambdas in delegate constructors Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAnalyzer and fixer expanded to accept general LambdaExpressionSyntax (including SimpleLambdaExpressionSyntax in delegate constructors). New helpers extract lambda parameters and diagnostic nodes; the fixer gains separate paths for parenthesized and simple lambdas and builds parameter lists from the mocked method symbol. Tests and test helpers updated. Changes
Sequence Diagram(s)sequenceDiagram
participant Source as Source (invocation + lambda)
participant Analyzer as Analyzer
participant Semantic as SemanticModel
participant Diagnostic as DiagnosticReporter
participant CodeFix as CodeFixProvider
Source->>Analyzer: Parse invocation\nTryGetCallbackLambda (returns LambdaExpressionSyntax)
Analyzer->>Analyzer: GetLambdaParameters()\nGetDiagnosticNode()
Analyzer->>Semantic: Resolve setup / mocked method symbols
Semantic-->>Analyzer: Method symbol(s) (or candidate)
Analyzer->>Diagnostic: Report diagnostic at diagnostic node
Diagnostic->>CodeFix: Request code fix
CodeFix->>Semantic: FindSingleMockedMethod / ResolveNewParameterListAsync
Semantic-->>CodeFix: Method symbol (or null)
CodeFix->>CodeFix: BuildParameterList() (types, modifiers, names)
CodeFix->>Source: Replace lambda (parenthesized or convert simple->parenthesized) preserving trivia
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the Moq.Analyzers callback validation logic to fully support SimpleLambdaExpressionSyntax when used within delegate constructors. Previously, these simple lambdas were explicitly skipped, leading to missed diagnostics. The changes involve refactoring the lambda detection and parameter extraction to handle both simple and parenthesized lambda forms consistently, ensuring that the analyzer correctly identifies signature mismatches for a broader range of callback expressions. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
|
Overall Grade Focus Area: Hygiene |
Security Reliability Complexity Hygiene |
Feedback
- Style enforcement gap between tests and production
- Test code repeatedly breaks naming and simple-style rules because the test projects don't share the same analyzer/formatter configuration as the library; unifying analyzer settings and applying code fixes in tests will stop these recurring violations.
- Compiler diagnostics treated as advisory rather than blocking
- Mechanical opportunities (const vs static readonly, redundant types, async naming) are left unfixed because relevant diagnostics aren't elevated; promoting those diagnostics to warnings/errors and failing CI on them prevents regression.
- Mechanical fixes not automated
- The issues are trivial and repetitive, so they persist when left to manual review. Add codefixers/format-on-save or pre-commit autofixes to remove this class of low-effort hygiene debt.
Code Review Summary
| Analyzer | Status | Updated (UTC) | Details |
|---|---|---|---|
| C# | Mar 9, 2026 1:08a.m. | Review ↗ |
There was a problem hiding this comment.
Code Review
This pull request extends the callback signature validation to support SimpleLambdaExpressionSyntax, which is a good improvement. The implementation is clean, using helper methods to handle both SimpleLambdaExpressionSyntax and ParenthesizedLambdaExpressionSyntax uniformly. The new test cases cover the changes well. My only concern is that the corresponding code fix provider (CallbackSignatureShouldMatchMockedMethodFixer) doesn't seem to be updated to handle simple lambdas, which means the code fix won't be available for these new scenarios. I've added a comment with more details.
The fixer previously only searched for ParameterListSyntax ancestors, which does not exist for simple lambdas. Now handles both cases: - Parenthesized lambdas: replace ParameterListSyntax (existing path) - Simple lambdas: convert to ParenthesizedLambdaExpressionSyntax Extracted FindSingleMockedMethod and BuildParameterList to reduce duplication between the two fix paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferences |
- Replace fragile .Parent chain with .Ancestors().OfType<>() pattern - Extract magic string "Fix Moq callback signature" to private const - Cap .ToArray() allocation with .Take(2) in FindSingleMockedMethod Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Simplification pass (rjmurillo-bot): Replaced fragile |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/CodeFixes/CallbackSignatureShouldMatchMockedMethodFixer.cs`:
- Around line 134-142: The new ParenthesizedLambdaExpressionSyntax currently
loses the original simple lambda's trivia; call WithTriviaFrom(simpleLambda) on
parenthesizedLambda before replacing the node so leading/trailing comments and
whitespace are preserved (i.e. create parenthesizedLambda, run
parenthesizedLambda = parenthesizedLambda.WithTriviaFrom(simpleLambda), then use
root.ReplaceNode(simpleLambda, parenthesizedLambda) and return
document.WithSyntaxRoot(newRoot)).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0a21b5fd-1091-425d-a5ec-eaed690b5b80
📒 Files selected for processing (3)
src/Analyzers/CallbackSignatureShouldMatchMockedMethodAnalyzer.cssrc/CodeFixes/CallbackSignatureShouldMatchMockedMethodFixer.cstests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodAnalyzerTests.cs
…ambda Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ents Extract ResolveNewParameterListAsync to eliminate DRY violation between FixParenthesizedCallbackSignatureAsync and FixSimpleLambdaCallbackSignatureAsync. Both methods shared identical semantic model resolution, symbol lookup, and parameter list construction. Add comments explaining the intentional SimpleLambdaExpressionSyntax fallthrough and the Take(2) short-circuit. Refs: PR #1042 review findings #2 and #3 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add SimpleLambdaTestData and ShouldFixSimpleLambdaCallbackSignature covering the FixSimpleLambdaCallbackSignatureAsync method. Tests verify: - Simple lambda with wrong parameter type gets rewritten to parenthesized lambda with correct type - Simple lambda with wrong parameter count gets rewritten to parenthesized lambda with correct parameters Uses CompilerDiagnostics.None because the fixer corrects the lambda parameters but does not update the outer delegate constructor type. Refs: PR #1042 review finding #1, issue #1012 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/CodeFixes/CallbackSignatureShouldMatchMockedMethodFixer.cs`:
- Around line 73-83: The fixer Replace of lambda parameters in
FixParenthesizedCallbackSignatureAsync can produce invalid code when the lambda
is wrapped in an explicit delegate construction (e.g., new Action<int>(...));
update the logic in FixParenthesizedCallbackSignatureAsync (and the similar
handling around lines 85-103) to detect if oldParameters' ancestor is an
ObjectCreationExpressionSyntax constructing a delegate type and either (a)
update the constructed delegate type to match the new parameter types when
feasible (use ResolveNewParameterListAsync result to compute the delegate's type
arguments) or (b) bail out / suppress this code action for that case so we don't
produce a mismatched explicit delegate constructor; ensure you reference and use
ResolveNewParameterListAsync, and check for ObjectCreationExpressionSyntax /
SimpleName/GenericName on the Type node before replacing parameters.
- Around line 153-161: BuildParameterList currently builds parameters from
mockedMethod without preserving original lambda parameter names, which breaks
callback bodies; change BuildParameterList to accept the original lambda
parameter nodes (e.g., a ParameterListSyntax.Parameters collection or
SimpleLambdaExpressionSyntax.Parameter) and map by position so that for each
mockedMethod.Parameters you reuse the original identifier when one exists at the
same index, only synthesizing a new name for newly added parameters; update the
method signature (e.g., BuildParameterList(SemanticModel semanticModel,
IMethodSymbol mockedMethod, int position, IEnumerable<ParameterSyntax>
originalParameters) or similar), use
originalParameters.ElementAtOrDefault(index) to pick the identifier token for
SyntaxFactory.Identifier, and keep type and modifiers logic the same for each
parameter.
In
`@tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodCodeFixTests.cs`:
- Around line 259-318: The test suite currently only covers block-bodied lambdas
inside explicit delegate construction (in SimpleLambdaTestData /
ShouldFixSimpleLambdaCallbackSignature) and misses the expression-bodied case;
add a new test case that uses a direct expression-bodied lambda (e.g. a
Returns({|Moq1100:x|} => 42) or Callback({|Moq1100:x|} => 42)) so the fixer's
ExpressionBody branch is exercised end-to-end, update SimpleLambdaTestData to
include that string pair (original and expected quickFix) and ensure the new
case is compiled within the same Template used by
ShouldFixSimpleLambdaCallbackSignature and included in
WithNamespaces().WithMoqReferenceAssemblyGroups().
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 8b295aca-96a2-4def-85cd-b2a30a3a2924
📒 Files selected for processing (2)
src/CodeFixes/CallbackSignatureShouldMatchMockedMethodFixer.cstests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodCodeFixTests.cs
tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodCodeFixTests.cs
Show resolved
Hide resolved
When a lambda is wrapped in an explicit delegate constructor like
new Action<int>((int x) => { }), replacing only the lambda parameters
produces invalid code (CS1661). Bail out for parenthesized lambdas
inside ObjectCreationExpressionSyntax to avoid offering a broken fix.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BuildParameterList now reuses the original parameter identifiers when they exist at the same index position. This prevents breaking callback bodies that reference the original names. For example, .Callback((int i) => i.ToString()) no longer renames i to s. Also adds expression-bodied simple lambda test coverage for the ExpressionBody branch in the fixer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/CodeFixes/CallbackSignatureShouldMatchMockedMethodFixer.cs`:
- Around line 90-109: FixSimpleLambdaCallbackSignatureAsync currently lacks the
same delegate-constructor early return as
FixParenthesizedCallbackSignatureAsync, so add the same bail-out guard used in
FixParenthesizedCallbackSignatureAsync to FixSimpleLambdaCallbackSignatureAsync
(i.e., detect when the lambda is being passed into a delegate
ObjectCreationExpression/constructor and return the original document without
changing the lambda); place this check before constructing the
ParenthesizedLambdaExpressionSyntax in FixSimpleLambdaCallbackSignatureAsync so
the fixer will skip converting simple lambdas that are inside delegate
constructors.
In
`@tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodCodeFixTests.cs`:
- Around line 319-321: The test currently suppresses compilation diagnostics
(using CompilerDiagnostics.None) for cases where the fixer only updates lambda
parameters but not outer delegate types; once you add the bail-out in
FixSimpleLambdaCallbackSignatureAsync, split expectations: for
delegate-constructor scenarios assert the fixer returns an unchanged document
(mirror the pattern used in
FixerReturnsUnchangedDocumentWhenSetupMethodNotFound) and for direct
simple-lambda scenarios assert the code-fix produces a compiling result (call
VerifyCodeFixAsync without suppressing diagnostics or with
CompilerDiagnostics.Errors) so the test verifies the fix actually compiles.
- Around line 259-276: The tests in SimpleLambdaTestData assert the fixer
produces rewritten lambdas with mismatched parameter types (e.g., new
Action<int>((string x) => ...)), which won't compile; after adding the bail-out
in FixSimpleLambdaCallbackSignatureAsync you should update those test cases to
expect no change (i.e., the original document remains unchanged) instead of the
non-compiling replacements—modify the three affected entries in
SimpleLambdaTestData to use the original input as the expected output.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: f8ee4461-6b72-4191-afce-1cb19191285d
📒 Files selected for processing (2)
src/CodeFixes/CallbackSignatureShouldMatchMockedMethodFixer.cstests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodCodeFixTests.cs
tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodCodeFixTests.cs
Show resolved
Hide resolved
tests/Moq.Analyzers.Test/CallbackSignatureShouldMatchMockedMethodCodeFixTests.cs
Outdated
Show resolved
Hide resolved
Add IsInsideDelegateConstructor guard to both RegisterCodeFixesAsync (preventing code action registration) and FixSimpleLambdaCallbackSignatureAsync (defense-in-depth) for simple lambdas inside delegate constructors. This matches the existing bail-out behavior for parenthesized lambdas. Update test expectations so delegate constructor cases expect the diagnostic to persist (fixer does not modify the document). Add CodeFixVerifier overload accepting iteration counts for bail-out tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) | `3.0.19` → `3.0.20` |  |  | --- ### Release Notes <details> <summary>meziantou/Meziantou.Analyzer (Meziantou.Analyzer)</summary> ### [`v3.0.20`](https://github.com/meziantou/Meziantou.Analyzer/releases/tag/3.0.20) [Compare Source](https://github.com/meziantou/Meziantou.Analyzer/compare/3.0.19...3.0.20) NuGet package: <https://www.nuget.org/packages/Meziantou.Analyzer/3.0.20> #### What's Changed - Fix MA0068 false positive for C# 14 extension block parameters by [@​Copilot](https://github.com/Copilot) in [#​1053](https://github.com/meziantou/Meziantou.Analyzer/pull/1053) **Full Changelog**: <meziantou/Meziantou.Analyzer@3.0.19...3.0.20> </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/rjmurillo/moq.analyzers). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4wIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
…1050) ## Summary - Introduces `FilteredArgumentList`, a zero-allocation `readonly struct` that wraps `SeparatedSyntaxList<ArgumentSyntax>` with a skip index - Replaces `ToArray()` + `RemoveAt()` pattern in `ConstructorArgumentsShouldMatchAnalyzer.VerifyMockAttempt`, eliminating 1-2 intermediate array allocations per `Mock<T>` constructor invocation when `MockBehavior` is present - All consumers (`AnyConstructorsFound`, `VerifyInterfaceMockAttempt`, `VerifyDelegateMockAttempt`, `VerifyClassMockAttempt`, `FormatArguments`) updated to use the struct's indexed access and `Count` property Closes #450 ## Test plan - [x] All 2978 existing tests pass with zero failures - [x] Clean build with zero warnings - [x] No behavioral changes; only allocation reduction 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved internal handling of constructor argument processing in the analyzer for more efficient mock verification. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Richard Murillo <rjmurillo@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…ifier (#1049) ## Summary - Removes `CompositeAnalyzer` and its entire project (`Moq.Analyzers.Test.Analyzers`), which was dead code not referenced by any test - Keeps `AllAnalyzersVerifier`, which is actively used by 4 test classes for false-positive verification - Both used reflection to discover all `DiagnosticAnalyzer` types, but only `AllAnalyzersVerifier` was wired into the test suite ## Details `CompositeAnalyzer` wrapped all analyzers into a single `DiagnosticAnalyzer` subclass. `AllAnalyzersVerifier` runs each analyzer individually through `AnalyzerVerifier<T>`. The latter approach gives better test isolation and diagnostic attribution. Since `CompositeAnalyzer` had zero usages, removing it is the correct reconciliation. **Files removed:** - `tests/Moq.Analyzers.Test.Analyzers/CompositeAnalyzer.cs` - `tests/Moq.Analyzers.Test.Analyzers/Moq.Analyzers.Test.Analyzers.csproj` **Files modified:** - `Moq.Analyzers.sln` (removed project entry and build configurations) - `tests/Moq.Analyzers.Test/Moq.Analyzers.Test.csproj` (removed project reference) ## Test plan - [x] Solution builds with zero warnings and zero errors - [x] All 2978 tests pass Closes #530 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Removed test analyzer project from the solution structure and updated related project configurations to streamline the build setup. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Richard Murillo <rjmurillo@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary Resolves #980. Extracts duplicated logic from three analyzer groups without changing behavior. - **Overridable member check**: `IsOverridableOrAllowedMockMember` extracted to `ISymbolExtensions`, replacing identical private methods (`IsPropertyOrMethod`, `IsOverridableOrTaskResultMember`, `IsAllowedMockMember`) in `SetupShouldBeUsedOnlyForOverridableMembersAnalyzer`, `SetupSequenceShouldBeUsedOnlyForOverridableMembersAnalyzer`, and `VerifyShouldBeUsedOnlyForOverridableMembersAnalyzer` - **MockBehavior reporting**: Added `TryReportMockBehaviorDiagnostic` and `TryHandleMissingMockBehaviorParameter` overloads with `messageArgs` plus shared `GetMockedTypeName` to `MockBehaviorDiagnosticAnalyzerBase`, removing duplicate methods from `SetExplicitMockBehaviorAnalyzer` and `SetStrictMockBehaviorAnalyzer` - **Event argument validation**: Replaced `RaiseEventArgumentsShouldMatchEventSignatureAnalyzer.ValidateArgumentTypesWithEventName` with existing `EventSyntaxExtensions.ValidateEventArgumentTypes` Net result: 122 lines added, 285 lines removed (163 lines reduced). ## Test plan - [x] All 2901 existing tests pass with zero failures - [x] Build succeeds with zero warnings - [x] No diagnostic IDs, messages, or categories changed - [x] No analyzer behavior changed, only structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Consolidated mock-behavior diagnostic reporting to a single path with support for formatted messages and overload-aware reporting. * Replaced many inlined helpers with shared reporting/handling flows for strict/explicit mock analyses. * Switched event-argument validation to context-based extension calls for consistency. * Centralized overridable/allowed-member checks into a single symbol extension used by setup, verify, and sequence analyzers. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Richard Murillo <rjmurillo@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Add 6 new tests covering critical gaps in PR #1042: - Analyzer: parenthesized lambda in delegate constructor (valid/invalid type/count) - Fixer: parenthesized lambda in delegate constructor bail-out - Fixer: direct simple lambda conversion for Returns (not just Callback) - SemanticModel: overload resolution failure fallback to candidate symbols Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
## Summary - Add `THIRD-PARTY-NOTICES.TXT` covering `Microsoft.CodeAnalysis.AnalyzerUtilities` (MIT, .NET Foundation and Contributors), the only third-party assembly bundled in the shipped NuGet package. - Pack the notices file into the NuGet package root alongside `README.md`. - Document a repeatable 7-step attribution procedure in `CONTRIBUTING.md` under Dependency Management, covering how to research licenses, identify authoritative copyright holders, and handle license-specific requirements (MIT, BSD, Apache-2.0). ## Motivation The project bundles `Microsoft.CodeAnalysis.AnalyzerUtilities.dll` inside the shipped `.nupkg`. Its MIT license requires reproducing the copyright notice and license text. No third-party notices file existed previously. ## What is and is not in scope Only **bundled** assemblies require attribution. Compile-time-only Roslyn SDK references (`Microsoft.CodeAnalysis.CSharp`, `.Workspaces`) are already present in the user's host and are not distributed. Dev-only tools (analyzers, test frameworks, benchmarks) are also excluded. ## Test plan - [x] `dotnet build` succeeds with zero warnings - [ ] Verify `THIRD-PARTY-NOTICES.TXT` appears in the packed `.nupkg` root - [ ] Review CONTRIBUTING.md rendering for the new attribution procedure section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Richard Murillo <rjmurillo@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract VerifySimpleLambdaConversionAsync helper to replace three near-identical test methods. Delegate CreateSyntheticDiagnostic to CreateSyntheticDiagnosticAtSpan to remove duplicated descriptor construction. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use candidate iteration instead of blind [0] selection - Check BaseObjectCreationExpressionSyntax for target-typed new - Change FixTitle to const Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Revert FixTitle from const back to static readonly per project's EffectiveCSharp analyzer rule ECS0200. Extract GetChangedTextAsync helper to eliminate duplicated CodeAction text extraction in tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rify candidate fallback Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Closes #1012.
TryGetCallbackLambdareturn type fromParenthesizedLambdaExpressionSyntax?toLambdaExpressionSyntax?, removing the explicit bail-out forSimpleLambdaExpressionSyntaxin delegate constructorsGetLambdaParametershelper to uniformly extract parameters from bothParenthesizedLambdaExpressionSyntaxandSimpleLambdaExpressionSyntaxGetDiagnosticNodehelper for correct diagnostic span placement on each lambda formTest plan
new Action<string>(x => { })andnew Func<string, int>(x => 42)produce no diagnosticnew Action<int>(x => { })(wrong type) andnew Action<int>(x => { })(argument count mismatch) produce Moq1100dotnet buildsucceeds with zero warnings🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests
Chores