Skip to content

Enhance the Rename API to allow existing roslyn-internal features to work solely using the public API. #71177

@CyrusNajmabadi

Description

@CyrusNajmabadi

Background and Motivation

Roslyn currently has a powerful Rename api, which we expose through:

Renamer.RenameSymbolAsync(
    Solution solution,
    ISymbol symbol,
    SymbolRenameOptions options,
    string newName,
    CancellationToken cancellationToken = default);

This works well for many needs, but has been insufficient for a pair of features that we currently have to keep internal only: Encapsulate-Field and Use-Auto-Property.

Enacpsulate field wants to replace a field with a new property and update nearly all references to reference that new property name instead. However, if the user chooses to preserve the field, then we still wants the constructor to write to the fields and not hte properties. As such, we have a filter that can be passed into rename to filter out the locations found in the constructor body so that they are not updated.

Similarly, Use-Auto-Prop wants to update all existing reference to some field, and update them to now be the name of the property that will be used in its stead. However, definitionally, rename then views these all as errors precisely because the reference locations change meaning. To address this, we have a set of symbols that we pass into rename where we say "it is acceptable to change binding meaning if you're binding to this new symbol"

Proposed API

I propose that we codify these two capabilities as advanced knobs on the options object pass to rename. Specifically:

public readonly record struct SymbolRenameOptions
{
+    // Locations in the solution that will not have references renamed within.
+    public ImmutableArray<DocumentSpan> IgnoreLocations { get; }

+    // Symbols that a reference can bind to that will not have conflict resolution performed on them.
+    public ImmutableArray<ISymbol> IgnoreConflictResolutionSymbols { get; }
}

Note: these capabilities are what rename already supports, it is just through internal APIs.

Note: i'm very open for better names here. Also, note: we want to make these all 'data' (and not something like lambda callbacks) as this operates on the server end and so has to be marshallable over to OOP. We can do this trivially with document-spans, and we already do this today with Symbol-IDs.

Doing this will make features like 'use auto prop' now be available in the code style layer. Which would be very nice for layering.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Concept-APIThis issue involves adding, removing, clarification, or modification of an API.Feature Requestapi-needs-workAPI needs work before it is approved, it is NOT ready for implementation

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions