Skip to content

Public API for partial events #77203

@jjonescz

Description

@jjonescz

Background and Motivation

Test plan: #76859
Implementation: #77202
Equivalent API for partial properties: #73411

We need to introduce public APIs related to the upcoming partial events and constructors feature.

These APIs correspond to existing APIs on IMethodSymbol and IPropertySymbol, which are used for key IDE features such as go-to-definition and find-all-references. We expect these APIs to be used by the same features for corresponding scenarios relating to events. No new APIs for constructors are needed because constructors implement IMethodSymbol.

Proposed API

namespace Microsoft.CodeAnalysis
{
     public interface IEventSymbol
     {
+        /// <summary>If this is the implementation part of a partial event, returns the symbol for the definition part. Otherwise, returns null.</summary>
+        IEventSymbol? PartialDefinitionPart { get; }

+        /// <summary>If this is the definition part of a partial event, returns the symbol for the implementation part. Otherwise, returns null.</summary>
+        IEventSymbol? PartialImplementationPart { get; }

+       /// <summary>Returns true if this is a partial definition part, otherwise false.</summary>
+       bool IsPartialDefinition { get; }
     }
}
partial class C
{
    // Symbol for this declaration of 'E' will:
    // - return null for PartialDefinitionPart
    // - return symbol for below 'E' declaration for PartialImplementationPart
    public partial event Action E;

    // Symbol for this declaration of 'E' will:
    // - return symbol for above 'E' declaration for PartialDefinitionPart
    // - return null for PartialImplementationPart
    public partial event Action E { add { } remove { } }
}

Notable behaviors:

  • These APIs only return values for original definition source symbols. So, for example, a retargeting symbol with a partial event underlying symbol will return null from these APIs.
  • If one of the partial declarations required by the language is missing, the APIs will return null. For example, if only the definition part of a partial event exists, then accessing PartialImplementationPart on it will return null.
  • The accessors of a partial event are considered partial methods, and their counterparts are returned from the corresponding APIs on IMethodSymbol. For example, if we had the definition part symbol for C.E.add, and we accessed PartialImplementationPart on it, we would get the implementation part symbol for C.E.add. Also, IMethodSymbol.IsPartialDefinition will return true for the definition part symbol for C.E.add.

Usage Examples

In EventSymbolReferenceFinder:

protected sealed override ValueTask<ImmutableArray<ISymbol>> DetermineCascadedSymbolsAsync(
    IEventSymbol symbol,
    Solution solution,
    FindReferencesSearchOptions options,
    CancellationToken cancellationToken)
{
    ImmutableArray<ISymbol> result = [];

    if (symbol.PartialDefinitionPart is { } definitionPart)
    {
        result = result.Concat(definitionPart);
    }

    if (symbol.PartialImplementationPart is { } implementationPart)
    {
        result = result.Concat(implementationPart);
    }

    return new(result);
}

Alternative Designs

Don't ship any new APIs and have users dig through the accessor symbols to locate the other property part instead. This seems cumbersome.

Risks

None.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions