public Session( RenameLocations renameLocationSet, Location renameSymbolDeclarationLocation, string originalText, string replacementText, OptionSet optionSet, Func <IEnumerable <ISymbol>, bool?> newSymbolsAreValid, CancellationToken cancellationToken) { _renameLocationSet = renameLocationSet; _renameSymbolDeclarationLocation = renameSymbolDeclarationLocation; _originalText = originalText; _replacementText = replacementText; _optionSet = optionSet; _hasConflictCallback = newSymbolsAreValid; _cancellationToken = cancellationToken; _renamedSymbolDeclarationAnnotation = new RenameAnnotation(); _conflictLocations = SpecializedCollections.EmptySet <ConflictLocationInfo>(); _replacementTextValid = true; _possibleNameConflicts = new List <string>(); // only process documents which possibly contain the identifiers. _documentsIdsToBeCheckedForConflict = new HashSet <DocumentId>(); _documentIdOfRenameSymbolDeclaration = renameLocationSet.Solution.GetDocument(renameSymbolDeclarationLocation.SourceTree).Id; _renameAnnotations = new AnnotationTable <RenameAnnotation>(RenameAnnotation.Kind); }
public Task <IInlineRenameLocationSet> FindRenameLocationsAsync(OptionSet optionSet, CancellationToken cancellationToken) { Task <RenameLocations> renameTask; lock (_gate) { if (_underlyingFindRenameLocationsTask == null) { // If this is the first call, then just start finding the initial set of rename // locations. _underlyingFindRenameLocationsTask = RenameLocations.FindAsync( this.RenameSymbolAndProjectId, _document.Project.Solution, optionSet, cancellationToken); renameTask = _underlyingFindRenameLocationsTask; // null out the option set. We don't need it anymore, and this will ensure // we don't call FindWithUpdatedOptionsAsync below. optionSet = null; } else { // We already have a task to figure out the set of rename locations. Let it // finish, then ask it to get the rename locations with the updated options. renameTask = _underlyingFindRenameLocationsTask; } } return(GetLocationSet(renameTask, optionSet, cancellationToken)); }
public SymbolInlineRenameInfo( IEnumerable <IRefactorNotifyService> refactorNotifyServices, Document document, TextSpan triggerSpan, string triggerText, ISymbol renameSymbol, bool forceRenameOverloads, ImmutableArray <DocumentSpan> definitionLocations, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken) { this.CanRename = true; _refactorNotifyServices = refactorNotifyServices; _document = document; _fallbackOptions = fallbackOptions; this.RenameSymbol = renameSymbol; this.HasOverloads = RenameLocations.GetOverloadedSymbols(this.RenameSymbol).Any(); this.MustRenameOverloads = forceRenameOverloads; _isRenamingAttributePrefix = CanRenameAttributePrefix(triggerText); this.TriggerSpan = GetReferenceEditSpan(new InlineRenameLocation(document, triggerSpan), triggerText, cancellationToken); this.DefinitionLocations = definitionLocations; }
public Task <SerializableRenameLocations> FindRenameLocationsAsync( PinnedSolutionInfo solutionInfo, SerializableSymbolAndProjectId symbolAndProjectId, SerializableRenameOptionSet options, CancellationToken cancellationToken) { return(RunServiceAsync <SerializableRenameLocations>(async() => { using (UserOperationBooster.Boost()) { var solution = await GetSolutionAsync(solutionInfo, cancellationToken).ConfigureAwait(false); var symbol = await symbolAndProjectId.TryRehydrateAsync( solution, cancellationToken).ConfigureAwait(false); if (symbol == null) { return null; } var result = await RenameLocations.FindLocationsAsync( symbol, solution, options.Rehydrate(), cancellationToken).ConfigureAwait(false); return result.Dehydrate(solution, cancellationToken); } }, cancellationToken)); }
public Session( RenameLocations renameLocationSet, Location renameSymbolDeclarationLocation, string originalText, string replacementText, OptionSet optionSet, Func<IEnumerable<ISymbol>, bool?> newSymbolsAreValid, CancellationToken cancellationToken) { _renameLocationSet = renameLocationSet; _renameSymbolDeclarationLocation = renameSymbolDeclarationLocation; _originalText = originalText; _replacementText = replacementText; _optionSet = optionSet; _hasConflictCallback = newSymbolsAreValid; _cancellationToken = cancellationToken; _renamedSymbolDeclarationAnnotation = new RenameAnnotation(); _conflictLocations = SpecializedCollections.EmptySet<ConflictLocationInfo>(); _replacementTextValid = true; _possibleNameConflicts = new List<string>(); // only process documents which possibly contain the identifiers. _documentsIdsToBeCheckedForConflict = new HashSet<DocumentId>(); _documentIdOfRenameSymbolDeclaration = renameLocationSet.Solution.GetDocument(renameSymbolDeclarationLocation.SourceTree).Id; _renameAnnotations = new AnnotationTable<RenameAnnotation>(RenameAnnotation.Kind); }
public Task <SerializableConflictResolution?> ResolveConflictsAsync( PinnedSolutionInfo solutionInfo, SerializableRenameLocations renameLocationSet, string replacementText, SerializableSymbolAndProjectId[] nonConflictSymbolIds, CancellationToken cancellationToken) { return(RunServiceAsync <SerializableConflictResolution?>(async() => { using (UserOperationBooster.Boost()) { var solution = await GetSolutionAsync(solutionInfo, cancellationToken).ConfigureAwait(false); var nonConflictSymbols = await GetNonConflictSymbolsAsync(solution, nonConflictSymbolIds, cancellationToken).ConfigureAwait(false); var rehydratedSet = await RenameLocations.TryRehydrateAsync(solution, renameLocationSet, cancellationToken).ConfigureAwait(false); if (rehydratedSet == null) { return null; } var result = await ConflictResolver.ResolveConflictsAsync( rehydratedSet, replacementText, nonConflictSymbols, cancellationToken).ConfigureAwait(false); return await result.DehydrateAsync(cancellationToken).ConfigureAwait(false); } }, cancellationToken)); }
public InlineRenameLocationSet(SymbolInlineRenameInfo renameInfo, RenameLocations renameLocationSet) { _renameInfo = renameInfo; _renameLocationSet = renameLocationSet; this.Locations = renameLocationSet.Locations.Where(RenameLocation.ShouldRename) .Select(ConvertLocation) .ToImmutableArray(); }
private static async Task <ConflictResolution> ResolveConflictsInCurrentProcessAsync( RenameLocations renameLocationSet, string replacementText, ImmutableHashSet <ISymbol> nonConflictSymbols, CancellationToken cancellationToken) { var resolution = await ResolveMutableConflictsAsync( renameLocationSet, replacementText, nonConflictSymbols, cancellationToken).ConfigureAwait(false); return(resolution.ToConflictResolution()); }
private static bool IsWrittenToOutsideOfConstructorOrProperty( IFieldSymbol field, RenameLocations renameLocations, TPropertyDeclaration propertyDeclaration, CancellationToken cancellationToken) { var constructorNodes = field.ContainingType.GetMembers() .Where(m => m.IsConstructor()) .SelectMany(c => c.DeclaringSyntaxReferences) .Select(s => s.GetSyntax(cancellationToken)) .Select(n => n.FirstAncestorOrSelf <TConstructorDeclaration>()) .WhereNotNull() .ToSet(); return(renameLocations.Locations.Any( loc => IsWrittenToOutsideOfConstructorOrProperty(loc, propertyDeclaration, constructorNodes, cancellationToken))); }
/// <summary> /// Performs the renaming of the symbol in the solution, identifies renaming conflicts and automatically resolves them where possible. /// </summary> /// <param name="renameLocationSet">The locations to perform the renaming at.</param> /// <param name="originalText">The original name of the identifier.</param> /// <param name="replacementText">The new name of the identifier</param> /// <param name="optionSet">The option for rename</param> /// <param name="hasConflict">Called after renaming references. Can be used by callers to /// indicate if the new symbols that the reference binds to should be considered to be ok or /// are in conflict. 'true' means they are conflicts. 'false' means they are not conflicts. /// 'null' means that the default conflict check should be used.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A conflict resolution containing the new solution.</returns> public static Task<ConflictResolution> ResolveConflictsAsync( RenameLocations renameLocationSet, string originalText, string replacementText, OptionSet optionSet, Func<IEnumerable<ISymbol>, bool?> hasConflict, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // when someone e.g. renames a symbol from metadata through the API (IDE blocks this), we need to return var renameSymbolDeclarationLocation = renameLocationSet.Symbol.Locations.Where(loc => loc.IsInSource).FirstOrDefault(); if (renameSymbolDeclarationLocation == null) { // Symbol "{0}" is not from source. throw new ArgumentException(string.Format(WorkspacesResources.Symbol_0_is_not_from_source, renameLocationSet.Symbol.Name)); } var session = new Session(renameLocationSet, renameSymbolDeclarationLocation, originalText, replacementText, optionSet, hasConflict, cancellationToken); return session.ResolveConflictsAsync(); }
/// <summary> /// Performs the renaming of the symbol in the solution, identifies renaming conflicts and automatically resolves them where possible. /// </summary> /// <param name="renameLocationSet">The locations to perform the renaming at.</param> /// <param name="originalText">The original name of the identifier.</param> /// <param name="replacementText">The new name of the identifier</param> /// <param name="optionSet">The option for rename</param> /// <param name="hasConflict">Called after renaming references. Can be used by callers to /// indicate if the new symbols that the reference binds to should be considered to be ok or /// are in conflict. 'true' means they are conflicts. 'false' means they are not conflicts. /// 'null' means that the default conflict check should be used.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A conflict resolution containing the new solution.</returns> public static Task<ConflictResolution> ResolveConflictsAsync( RenameLocations renameLocationSet, string originalText, string replacementText, OptionSet optionSet, Func<IEnumerable<ISymbol>, bool?> hasConflict, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // when someone e.g. renames a symbol from metadata through the API (IDE blocks this), we need to return var renameSymbolDeclarationLocation = renameLocationSet.Symbol.Locations.Where(loc => loc.IsInSource).FirstOrDefault(); if (renameSymbolDeclarationLocation == null) { // Symbol "{0}" is not from source. throw new ArgumentException(string.Format(WorkspacesResources.RenameSymbolIsNotFromSource, renameLocationSet.Symbol.Name)); } var session = new Session(renameLocationSet, renameSymbolDeclarationLocation, originalText, replacementText, optionSet, hasConflict, cancellationToken); return session.ResolveConflictsAsync(); }
public SymbolInlineRenameInfo( IEnumerable <IRefactorNotifyService> refactorNotifyServices, Document document, TextSpan triggerSpan, SymbolAndProjectId renameSymbolAndProjectId, bool forceRenameOverloads, CancellationToken cancellationToken) { this.CanRename = true; _refactorNotifyServices = refactorNotifyServices; _document = document; this.RenameSymbolAndProjectId = renameSymbolAndProjectId; this.HasOverloads = RenameLocations.GetOverloadedSymbols(this.RenameSymbolAndProjectId).Any(); this.ForceRenameOverloads = forceRenameOverloads; _isRenamingAttributePrefix = CanRenameAttributePrefix(document, triggerSpan, cancellationToken); this.TriggerSpan = GetReferenceEditSpan(new InlineRenameLocation(document, triggerSpan), cancellationToken); _shortenedTriggerSpan = this.TriggerSpan != triggerSpan; }
internal static async Task <ConflictResolution> ResolveConflictsAsync( RenameLocations renameLocationSet, string replacementText, ImmutableHashSet <ISymbol> nonConflictSymbols, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken)) { var solution = renameLocationSet.Solution; var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { var result = await client.TryRunRemoteAsync <SerializableConflictResolution>( WellKnownServiceHubServices.CodeAnalysisService, nameof(IRemoteRenamer.ResolveConflictsAsync), solution, new object[] { renameLocationSet.Dehydrate(solution, cancellationToken), replacementText, nonConflictSymbols?.Select(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)).ToArray(), }, callbackTarget : null, cancellationToken).ConfigureAwait(false); if (result.HasValue) { return(await result.Value.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); } } } return(await ResolveConflictsInCurrentProcessAsync( renameLocationSet, replacementText, nonConflictSymbols, cancellationToken).ConfigureAwait(false)); }
private static Task <MutableConflictResolution> ResolveMutableConflictsAsync( RenameLocations renameLocationSet, string replacementText, ImmutableHashSet <ISymbol> nonConflictSymbols, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // when someone e.g. renames a symbol from metadata through the API (IDE blocks this), we need to return var renameSymbolDeclarationLocation = renameLocationSet.Symbol.Locations.Where(loc => loc.IsInSource).FirstOrDefault(); if (renameSymbolDeclarationLocation == null) { // Symbol "{0}" is not from source. return(Task.FromResult(new MutableConflictResolution(string.Format(WorkspacesResources.Symbol_0_is_not_from_source, renameLocationSet.Symbol.Name)))); } var session = new Session( renameLocationSet, renameSymbolDeclarationLocation, replacementText, nonConflictSymbols, cancellationToken); return(session.ResolveConflictsAsync()); }
internal static async Task <ConflictResolution> ResolveConflictsAsync( RenameLocations renameLocationSet, string replacementText, ImmutableHashSet <ISymbol>?nonConflictSymbols, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken)) { var solution = renameLocationSet.Solution; var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false); if (client != null) { var serializableLocationSet = renameLocationSet.Dehydrate(solution, cancellationToken); var nonConflictSymbolIds = nonConflictSymbols?.SelectAsArray(s => SerializableSymbolAndProjectId.Dehydrate(solution, s, cancellationToken)) ?? default; var result = await client.TryInvokeAsync <IRemoteRenamerService, SerializableConflictResolution?>( solution, (service, solutionInfo, cancellationToken) => service.ResolveConflictsAsync(solutionInfo, serializableLocationSet, replacementText, nonConflictSymbolIds, cancellationToken), callbackTarget : null, cancellationToken).ConfigureAwait(false); if (result.HasValue && result.Value != null) { return(await result.Value.RehydrateAsync(solution, cancellationToken).ConfigureAwait(false)); } // TODO: do not fall back to in-proc if client is available (https://github.com/dotnet/roslyn/issues/47557) } } return(await ResolveConflictsInCurrentProcessAsync( renameLocationSet, replacementText, nonConflictSymbols, cancellationToken).ConfigureAwait(false)); }
public InlineRenameLocationSet(SymbolInlineRenameInfo renameInfo, RenameLocations renameLocationSet) { _renameInfo = renameInfo; _renameLocationSet = renameLocationSet; this.Locations = renameLocationSet.Locations.Where(l => !l.IsCandidateLocation || l.IsMethodGroupReference).Select(ConvertLocation).ToList(); }