| File: Rename\IRenameRewriterLanguageService.cs | Web Access |
| Project: src\roslyn\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.LanguageService; using Microsoft.CodeAnalysis.PooledObjects; namespace Microsoft.CodeAnalysis.Rename; internal interface IRenameRewriterLanguageService : ILanguageService { /// <summary> /// This method annotates the given syntax tree with all the locations that need to be checked for conflict /// after the rename operation. It also renames all the reference locations and expands any conflict locations. /// </summary> /// <param name="parameters">The options describing this rename operation</param> /// <returns>The root of the annotated tree.</returns> SyntaxNode AnnotateAndRename(RenameRewriterParameters parameters); /// <summary> /// Based on the kind of the symbol and the new name, this function determines possible conflicting names that /// should be tracked for semantic changes during rename. /// </summary> /// <param name="symbol">The symbol that gets renamed.</param> /// <param name="newName">The new name for the symbol.</param> /// <param name="possibleNameConflicts">List where possible conflicting names will be added to.</param> void TryAddPossibleNameConflicts( ISymbol symbol, string newName, ICollection<string> possibleNameConflicts); /// <summary> /// Identifies the conflicts caused by the new declaration created during rename. /// </summary> /// <param name="replacementText">The replacementText as given from the user.</param> /// <param name="renamedSymbol">The new symbol (after rename).</param> /// <param name="renameSymbol">The original symbol that got renamed.</param> /// <param name="referencedSymbols">All referenced symbols that are part of this rename session.</param> /// <param name="baseSolution">The original solution when rename started.</param> /// <param name="newSolution">The resulting solution after rename.</param> /// <param name="reverseMappedLocations">A mapping from new to old locations.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>All locations where conflicts were caused because the new declaration.</returns> Task<ImmutableArray<Location>> ComputeDeclarationConflictsAsync( string replacementText, ISymbol renamedSymbol, ISymbol renameSymbol, IEnumerable<ISymbol> referencedSymbols, Solution baseSolution, Solution newSolution, IDictionary<Location, Location> reverseMappedLocations, CancellationToken cancellationToken); /// <summary> /// Identifies the conflicts caused by implicitly referencing the renamed symbol. /// </summary> /// <param name="renameSymbol">The original symbol that got renamed.</param> /// <param name="renamedSymbol">The new symbol (after rename).</param> /// <param name="implicitReferenceLocations">All implicit reference locations.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A list of implicit conflicts.</returns> Task<ImmutableArray<Location>> ComputeImplicitReferenceConflictsAsync( ISymbol renameSymbol, ISymbol renamedSymbol, IEnumerable<ReferenceLocation> implicitReferenceLocations, CancellationToken cancellationToken); /// <summary> /// Identifies the conflicts caused by implicitly referencing the renamed symbol. /// </summary> /// <param name="renamedSymbol">The new symbol (after rename).</param> /// <param name="semanticModel">The SemanticModel of the document in the new solution containing the renamedSymbol</param> /// <param name="originalDeclarationLocation">The location of the renamedSymbol in the old solution</param> /// <param name="newDeclarationLocationStartingPosition">The starting position of the renamedSymbol in the new solution</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A list of implicit conflicts.</returns> ImmutableArray<Location> ComputePossibleImplicitUsageConflicts( ISymbol renamedSymbol, SemanticModel semanticModel, Location originalDeclarationLocation, int newDeclarationLocationStartingPosition, CancellationToken cancellationToken); /// <summary> /// Identifies potential Conflicts into the inner scope locals. This may give false positives. /// </summary> /// <param name="token">The Token that may introduce errors else where</param> /// <param name="newReferencedSymbols">The symbols that this token binds to after the rename /// has been applied</param> /// <returns>Returns if there is a potential conflict</returns> bool LocalVariableConflict( SyntaxToken token, IEnumerable<ISymbol> newReferencedSymbols); /// <summary> /// Used to find if the replacement Identifier is valid /// </summary> /// <param name="replacementText"></param> /// <param name="syntaxFactsService"></param> bool IsIdentifierValid( string replacementText, ISyntaxFactsService syntaxFactsService); /// <summary> /// Gets the top most enclosing statement as target to call MakeExplicit on. /// It's either the enclosing statement, or if this statement is inside of a lambda expression, the enclosing /// statement of this lambda. /// </summary> /// <param name="token">The token to get the complexification target for.</param> SyntaxNode? GetExpansionTargetForLocation(SyntaxToken token); } internal abstract class AbstractRenameRewriterLanguageService : IRenameRewriterLanguageService { public abstract SyntaxNode AnnotateAndRename(RenameRewriterParameters parameters); public abstract Task<ImmutableArray<Location>> ComputeDeclarationConflictsAsync(string replacementText, ISymbol renamedSymbol, ISymbol renameSymbol, IEnumerable<ISymbol> referencedSymbols, Solution baseSolution, Solution newSolution, IDictionary<Location, Location> reverseMappedLocations, CancellationToken cancellationToken); public abstract Task<ImmutableArray<Location>> ComputeImplicitReferenceConflictsAsync(ISymbol renameSymbol, ISymbol renamedSymbol, IEnumerable<ReferenceLocation> implicitReferenceLocations, CancellationToken cancellationToken); public abstract ImmutableArray<Location> ComputePossibleImplicitUsageConflicts(ISymbol renamedSymbol, SemanticModel semanticModel, Location originalDeclarationLocation, int newDeclarationLocationStartingPosition, CancellationToken cancellationToken); public abstract SyntaxNode? GetExpansionTargetForLocation(SyntaxToken token); public abstract bool IsIdentifierValid(string replacementText, ISyntaxFactsService syntaxFactsService); public abstract bool LocalVariableConflict(SyntaxToken token, IEnumerable<ISymbol> newReferencedSymbols); public abstract void TryAddPossibleNameConflicts(ISymbol symbol, string newName, ICollection<string> possibleNameConflicts); protected static void AddConflictingParametersOfProperties( IEnumerable<ISymbol> properties, string newPropertyName, ArrayBuilder<Location> conflicts) { // check if the new property name conflicts with any parameter of the properties. // Note: referencedSymbols come from the original solution, so there is no need to reverse map the locations of the parameters foreach (var symbol in properties) { var prop = (IPropertySymbol)symbol; var conflictingParameter = prop.Parameters.FirstOrDefault( param => string.Equals(param.Name, newPropertyName, StringComparison.OrdinalIgnoreCase)); if (conflictingParameter != null) { conflicts.AddRange(conflictingParameter.Locations); } } } }