Skip to content

Fix "Generate method" to add static modifier for function pointers#80985

Merged
CyrusNajmabadi merged 7 commits intomainfrom
copilot/fix-generate-method-static-modifier
Nov 3, 2025
Merged

Fix "Generate method" to add static modifier for function pointers#80985
CyrusNajmabadi merged 7 commits intomainfrom
copilot/fix-generate-method-static-modifier

Conversation

Copy link
Contributor

Copilot AI commented Nov 2, 2025

Fix "Generate method" to add static modifier for function pointers

Fixes: Function pointers can only point to static methods in C#, but the "Generate method" code fix was not adding the static modifier when invoked from a non-static context.

Implementation Summary

Problem:

unsafe class C
{
    private void M()
    {
        delegate* managed<void> x = &M2;  // Invoke "Generate method" on M2
    }
}

Before: Generated private void M2() (missing static, causes CS8759)
After: Generates private static void M2()

Changes Made

  1. Modified src/Analyzers/Core/CodeFixes/GenerateMember/AbstractGenerateMemberService.cs

    • Updated TryDetermineTypeToGenerateInWorker to detect address-of contexts
    • Added inline check: if expression parent is AddressOfExpression, force static
    • Logic: if (!isStatic && expression.Parent != null && expression.Parent.RawKind == syntaxFacts.SyntaxKinds.AddressOfExpression)
  2. Added test cases in src/Analyzers/CSharp/Tests/GenerateMethod/GenerateMethodTests.cs

    • InferMethodFromAddressOfInNonStaticContext - simple name scenario &M2
    • InferMethodFromAddressOfInNonStaticContextWithQualifiedName - qualified name scenario &C.M2

Key Improvements (from PR feedback)

  • Simplified logic: removed unnecessary type checking - if we're generating a method for address-of, it must always be static
  • Better parameter usage: leverage syntaxFacts.SyntaxKinds directly
  • Inlined simple helper method for clarity
  • Comprehensive test coverage: both simple and qualified name scenarios

Verification

  • Build: Compiles successfully with no errors
  • Code Review: All feedback from @CyrusNajmabadi addressed
  • Tests: Added comprehensive test coverage
  • Code Quality: Simplified implementation, clearer intent
Original prompt

This section details on the original issue you should resolve

<issue_title>"Generate method" does not add static modifier when generating method for function pointer</issue_title>
<issue_description>Version Used: VS 18.0.0 Insiders [11123.170]

Steps to Reproduce:
Invoke the lightbulb menu and select "Generate method 'M2'".

unsafe class C
{
    private void M()
    {
        delegate* managed<void> x = &M2;
    }
}

Expected Behavior:
The method is generated with the static modifier.

Actual Behavior:
The method is generated without the static modifier, leading to an error:

unsafe class C
{
    private void M()
    {
        delegate* managed<void> x = &M2; // CS8759: Cannot create a function pointer for 'C.M2()' because it is not a static method
    }

    private void M2()
    {
        throw new NotImplementedException();
    }
}
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI self-assigned this Nov 2, 2025
- Modified TryDetermineTypeToGenerateInWorker to detect address-of expressions used with function pointers
- Added IsInFunctionPointerAddressOfContext helper method to check if expression is within address-of operator that targets a function pointer type
- Added test case InferMethodFromAddressOfInNonStaticContext to verify fix works in non-static contexts

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Copilot AI and others added 2 commits November 2, 2025 20:36
- Updated IsInFunctionPointerAddressOfContext to access AddressOfExpression directly from ISyntaxKindsService (which inherits from ISyntaxKinds)
- Fixed incorrect property access that was causing CS1061 error

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
- Simplified IsInFunctionPointerAddressOfContext with early returns to reduce nesting
- Removed redundant addressOfExpression variable and use expression.Parent directly
- Improved code readability

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix generate method to include static modifier for function pointers Fix "Generate method" to add static modifier for function pointers Nov 2, 2025
Copilot AI requested a review from CyrusNajmabadi November 2, 2025 20:46
if (syntaxKinds == null || expression.Parent.RawKind != syntaxKinds.AddressOfExpression)
return false;

var typeInfo = semanticModel.GetTypeInfo(expression.Parent, cancellationToken);
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot no need to do this type check. If we're ever generating a method for an adress-of operation, it must always be static no matter what

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the type check - now always returns true for address-of operations in fefc2ae

- Add WorkItem attribute to test method
- Simplify IsInAddressOfContext to use syntaxFacts.SyntaxKinds
- Remove unnecessary type check - address-of always requires static
- Add test for qualified name scenario (&C.M2)

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
{
// If we're generating a method for an address-of operation, it must always be static
return expression.Parent != null && expression.Parent.RawKind == syntaxFacts.SyntaxKinds.AddressOfExpression;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

@copilot this method is too simple. Just inline it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Inlined in 343d351e

The helper method was too simple, so inlined it directly into the condition check per feedback from @CyrusNajmabadi

Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
@CyrusNajmabadi
Copy link
Contributor

@dotnet/roslyn-ide ptal.

@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review November 3, 2025 18:10
@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner November 3, 2025 18:10
@CyrusNajmabadi CyrusNajmabadi enabled auto-merge (squash) November 3, 2025 18:10
@CyrusNajmabadi CyrusNajmabadi merged commit c9ed9bf into main Nov 3, 2025
24 of 25 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"Generate method" does not add static modifier when generating method for function pointer

4 participants