internal override async Task <Solution> GetModifiedSolutionAsync(Document document, DocumentRenameOptions options, CancellationToken cancellationToken)
            {
                var solution = document.Project.Solution;

                // Get only types matching the original document name by
                // passing a document back with the original name. That way
                // even if the document name changed, we're updating the types
                // that are the same name as the analysis
                var matchingTypeDeclaration = await GetMatchingTypeDeclarationAsync(
                    document.WithName(_analysis.OriginalDocumentName),
                    cancellationToken).ConfigureAwait(false);

                if (matchingTypeDeclaration is object)
                {
                    var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                    var symbol = semanticModel.GetRequiredDeclaredSymbol(matchingTypeDeclaration, cancellationToken);

                    var symbolRenameOptions = new SymbolRenameOptions(
                        RenameOverloads: false,
                        RenameInComments: options.RenameMatchingTypeInComments,
                        RenameInStrings: options.RenameMatchingTypeInStrings,
                        RenameFile: false);

                    solution = await RenameSymbolAsync(solution, symbol, symbolRenameOptions, _analysis.NewSymbolName, cancellationToken).ConfigureAwait(false);
                }

                return(solution);
            }
    public async Task <ImmutableArray <IntentProcessorResult> > ComputeIntentAsync(
        Document priorDocument,
        TextSpan priorSelection,
        Document currentDocument,
        IntentDataProvider intentDataProvider,
        CancellationToken cancellationToken)
    {
        var renameIntentData = intentDataProvider.GetIntentData <RenameIntentData>();

        Contract.ThrowIfNull(renameIntentData);

        var renameService = priorDocument.GetRequiredLanguageService <IEditorInlineRenameService>();
        var renameInfo    = await renameService.GetRenameInfoAsync(priorDocument, priorSelection.Start, cancellationToken).ConfigureAwait(false);

        if (!renameInfo.CanRename)
        {
            return(ImmutableArray <IntentProcessorResult> .Empty);
        }

        var options = new SymbolRenameOptions(
            RenameOverloads: false,
            RenameInStrings: false,
            RenameInComments: false,
            RenameFile: false);

        var renameLocationSet = await renameInfo.FindRenameLocationsAsync(options, cancellationToken).ConfigureAwait(false);

        var renameReplacementInfo = await renameLocationSet.GetReplacementsAsync(renameIntentData.NewName, options, cancellationToken).ConfigureAwait(false);

        return(ImmutableArray.Create(new IntentProcessorResult(renameReplacementInfo.NewSolution, renameReplacementInfo.DocumentIds.ToImmutableArray(), EditorFeaturesResources.Rename, WellKnownIntents.Rename)));
    }
예제 #3
0
        public void RefreshRenameSessionWithOptionsChanged(SymbolRenameOptions newOptions)
        {
            if (_options == newOptions)
            {
                return;
            }

            _threadingContext.ThrowIfNotOnUIThread();
            VerifyNotDismissed();

            _options = newOptions;

            var cancellationToken = _cancellationTokenSource.Token;

            UpdateReferenceLocationsTask(_threadingContext.JoinableTaskFactory.RunAsync(async() =>
            {
                // Join prior work before proceeding, since it performs a required state update.
                // https://github.com/dotnet/roslyn/pull/34254#discussion_r267024593
                //
                // The cancellation token is passed to the prior work when it starts, not when it's joined. This is
                // the equivalent of TaskContinuationOptions.LazyCancellation.
                await _allRenameLocationsTask.JoinAsync(CancellationToken.None).ConfigureAwait(false);
                await TaskScheduler.Default;

                return(await _renameInfo.FindRenameLocationsAsync(_options, cancellationToken).ConfigureAwait(false));
            }));
        }
예제 #4
0
        public async Task <InlineRenameSessionInfo> StartInlineSessionAsync(
            Document document,
            TextSpan textSpan,
            CancellationToken cancellationToken)
        {
            if (_activeRenameSession != null)
            {
                throw new InvalidOperationException(EditorFeaturesResources.An_active_inline_rename_session_is_still_active_Complete_it_before_starting_a_new_one);
            }

            var editorRenameService = document.GetRequiredLanguageService <IEditorInlineRenameService>();
            var renameInfo          = await editorRenameService.GetRenameInfoAsync(document, textSpan.Start, cancellationToken).ConfigureAwait(false);

            var readOnlyOrCannotNavigateToSpanSessionInfo = await IsReadOnlyOrCannotNavigateToSpanAsync(
                _threadingContext, renameInfo, document, cancellationToken).ConfigureAwait(false);

            if (readOnlyOrCannotNavigateToSpanSessionInfo != null)
            {
                return(readOnlyOrCannotNavigateToSpanSessionInfo);
            }

            if (!renameInfo.CanRename)
            {
                return(new InlineRenameSessionInfo(renameInfo.LocalizedErrorMessage));
            }

            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var snapshot = text.FindCorrespondingEditorTextSnapshot();

            Contract.ThrowIfNull(snapshot, "The document used for starting the inline rename session should still be open and associated with a snapshot.");

            var options = new SymbolRenameOptions(
                RenameOverloads: renameInfo.MustRenameOverloads || GlobalOptions.GetOption(InlineRenameSessionOptionsStorage.RenameOverloads),
                RenameInStrings: GlobalOptions.GetOption(InlineRenameSessionOptionsStorage.RenameInStrings),
                RenameInComments: GlobalOptions.GetOption(InlineRenameSessionOptionsStorage.RenameInComments),
                RenameFile: GlobalOptions.GetOption(InlineRenameSessionOptionsStorage.RenameFile));

            var previewChanges = GlobalOptions.GetOption(InlineRenameSessionOptionsStorage.PreviewChanges);

            // The session currently has UI thread affinity.
            await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

            ActiveSession = new InlineRenameSession(
                _threadingContext,
                this,
                document.Project.Solution.Workspace,
                renameInfo.TriggerSpan.ToSnapshotSpan(snapshot),
                renameInfo,
                options,
                previewChanges,
                _uiThreadOperationExecutor,
                _textBufferAssociatedViewService,
                _textBufferFactoryService,
                _featureServiceFactory,
                _refactorNotifyServices,
                _asyncListener);

            return(new InlineRenameSessionInfo(ActiveSession));
예제 #5
0
            public async Task <IInlineRenameLocationSet> FindRenameLocationsAsync(SymbolRenameOptions options, CancellationToken cancellationToken)
            {
                var solution  = _document.Project.Solution;
                var locations = await Renamer.FindRenameLocationsAsync(
                    solution, this.RenameSymbol, options, cancellationToken).ConfigureAwait(false);

                return(new InlineRenameLocationSet(this, locations));
            }
예제 #6
0
        private static async Task <RenameLocations> FindLocationsInCurrentProcessAsync(
            ISymbol symbol, Solution solution, SymbolRenameOptions options, CodeCleanupOptionsProvider cleanupOptions, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(symbol);
            using (Logger.LogBlock(FunctionId.Rename_AllRenameLocations, cancellationToken))
            {
                symbol = await ReferenceProcessing.FindDefinitionSymbolAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

                // First, find the direct references just to the symbol being renamed.
                var originalSymbolResult = await AddLocationsReferenceSymbolsAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

                // Next, find references to overloads, if the user has asked to rename those as well.
                var overloadsResult = options.RenameOverloads ? await GetOverloadsAsync(symbol, solution, cancellationToken).ConfigureAwait(false) :
                                      ImmutableArray <SearchResult> .Empty;

                // Finally, include strings/comments if that's what the user wants.
                var(strings, comments) = await ReferenceProcessing.GetRenamableLocationsInStringsAndCommentsAsync(
                    symbol,
                    solution,
                    originalSymbolResult.Locations,
                    options.RenameInStrings,
                    options.RenameInComments,
                    cancellationToken).ConfigureAwait(false);

                var mergedLocations = ImmutableHashSet.CreateBuilder <RenameLocation>();

                using var _1 = ArrayBuilder <ISymbol> .GetInstance(out var mergedReferencedSymbols);

                using var _2 = ArrayBuilder <ReferenceLocation> .GetInstance(out var mergedImplicitLocations);

                var renameMethodGroupReferences = options.RenameOverloads || !GetOverloadedSymbols(symbol).Any();
                foreach (var result in overloadsResult.Concat(originalSymbolResult))
                {
                    mergedLocations.AddRange(renameMethodGroupReferences
                        ? result.Locations
                        : result.Locations.Where(x => x.CandidateReason != CandidateReason.MemberGroup));

                    mergedImplicitLocations.AddRange(result.ImplicitLocations);
                    mergedReferencedSymbols.AddRange(result.ReferencedSymbols);
                }

                // Add string and comment locations to the merged hashset
                // after adding in reference symbols. This allows any references
                // in comments to be resolved as proper references rather than
                // comment resolutions. See https://github.com/dotnet/roslyn/issues/54294
                mergedLocations.AddRange(strings.NullToEmpty());
                mergedLocations.AddRange(comments.NullToEmpty());

                return(new RenameLocations(
                           symbol, solution, options, cleanupOptions,
                           new SearchResult(
                               mergedLocations.ToImmutable(),
                               mergedImplicitLocations.ToImmutable(),
                               mergedReferencedSymbols.ToImmutable())));
            }
        }
예제 #7
0
 private RenameLocations(
     ISymbol symbol,
     Solution solution,
     SymbolRenameOptions options,
     SearchResult result)
 {
     Solution = solution;
     Symbol   = symbol;
     Options  = options;
     _result  = result;
 }
예제 #8
0
 internal static RenameLocations Create(
     ImmutableHashSet <RenameLocation> locations,
     ISymbol symbol,
     Solution solution,
     ImmutableArray <ISymbol> referencedSymbols,
     ImmutableArray <ReferenceLocation> implicitLocations,
     SymbolRenameOptions options)
 {
     return(new RenameLocations(
                symbol, solution, options,
                new SearchResult(locations, implicitLocations, referencedSymbols)));
 }
예제 #9
0
        public void RefreshRenameSessionWithOptionsChanged(SymbolRenameOptions newOptions)
        {
            if (_options == newOptions)
            {
                return;
            }

            _threadingContext.ThrowIfNotOnUIThread();
            VerifyNotDismissed();

            _options = newOptions;
            UpdateReferenceLocationsTask();
        }
예제 #10
0
 private RenameLocations(
     ISymbol symbol,
     Solution solution,
     SymbolRenameOptions options,
     CodeCleanupOptionsProvider fallbackOptions,
     SearchResult result)
 {
     Solution        = solution;
     Symbol          = symbol;
     Options         = options;
     FallbackOptions = fallbackOptions;
     _result         = result;
 }
        public async Task <IInlineRenameLocationSet> FindRenameLocationsAsync(SymbolRenameOptions options, CancellationToken cancellationToken)
        {
            var set = await _info.FindRenameLocationsAsync(optionSet : null, cancellationToken).ConfigureAwait(false);

            if (set != null)
            {
                return(new FSharpInlineRenameLocationSetLegacyWrapper(set));
            }
            else
            {
                return(null);
            }
        }
예제 #12
0
        public async Task <WorkspaceEdit?> HandleRequestAsync(RenameParams request, RequestContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;

            Contract.ThrowIfNull(document);

            var oldSolution   = document.Project.Solution;
            var renameService = document.Project.LanguageServices.GetRequiredService <IEditorInlineRenameService>();
            var position      = await document.GetPositionFromLinePositionAsync(ProtocolConversions.PositionToLinePosition(request.Position), cancellationToken).ConfigureAwait(false);

            var renameInfo = await renameService.GetRenameInfoAsync(document, position, cancellationToken).ConfigureAwait(false);

            if (!renameInfo.CanRename)
            {
                return(null);
            }

            var options = new SymbolRenameOptions(
                RenameOverloads: false,
                RenameInStrings: false,
                RenameInComments: false,
                RenameFile: false);

            var renameLocationSet = await renameInfo.FindRenameLocationsAsync(options, cancellationToken).ConfigureAwait(false);

            var renameReplacementInfo = await renameLocationSet.GetReplacementsAsync(request.NewName, options, cancellationToken).ConfigureAwait(false);

            var renamedSolution = renameReplacementInfo.NewSolution;
            var solutionChanges = renamedSolution.GetChanges(oldSolution);

            // Linked files can correspond to multiple roslyn documents each with changes.  Merge the changes in the linked files so that all linked documents have the same text.
            // Then we can just take the text changes from the first document to avoid returning duplicate edits.
            renamedSolution = await renamedSolution.WithMergedLinkedFileChangesAsync(oldSolution, solutionChanges, cancellationToken : cancellationToken).ConfigureAwait(false);

            solutionChanges = renamedSolution.GetChanges(oldSolution);
            var changedDocuments = solutionChanges
                                   .GetProjectChanges()
                                   .SelectMany(p => p.GetChangedDocuments(onlyGetDocumentsWithTextChanges: true))
                                   .GroupBy(docId => renamedSolution.GetRequiredDocument(docId).FilePath, StringComparer.OrdinalIgnoreCase).Select(group => group.First());

            var textDiffService = renamedSolution.Services.GetRequiredService <IDocumentTextDifferencingService>();

            var documentEdits = await ProtocolConversions.ChangedDocumentsToTextDocumentEditsAsync(changedDocuments, renamedSolution.GetRequiredDocument, oldSolution.GetRequiredDocument,
                                                                                                   textDiffService, cancellationToken).ConfigureAwait(false);

            return(new WorkspaceEdit {
                DocumentChanges = documentEdits
            });
        }
예제 #13
0
            public async Task <IInlineRenameLocationSet> FindRenameLocationsAsync(SymbolRenameOptions options, CancellationToken cancellationToken)
            {
                var references = new List <InlineRenameLocation>();

                var renameLocations = await _renameInfo.FindRenameLocationsAsync(
                    renameInStrings : options.RenameInStrings,
                    renameInComments : options.RenameInComments,
                    cancellationToken : cancellationToken).ConfigureAwait(false);

                references.AddRange(renameLocations.Select(
                                        ds => new InlineRenameLocation(ds.Document, ds.TextSpan)));

                return(new InlineRenameLocationSet(
                           _renameInfo, _document.Project.Solution,
                           references.ToImmutableArray()));
            }
예제 #14
0
        /// <summary>
        /// Find the locations that need to be renamed.  Can cross process boundaries efficiently to do this.
        /// </summary>
        public static async Task <LightweightRenameLocations> FindRenameLocationsAsync(
            ISymbol symbol, Solution solution, SymbolRenameOptions options, CodeCleanupOptionsProvider fallbackOptions, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution);
            Contract.ThrowIfNull(symbol);

            cancellationToken.ThrowIfCancellationRequested();

            using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken))
            {
                if (SerializableSymbolAndProjectId.TryCreate(symbol, solution, cancellationToken, out var serializedSymbol))
                {
                    var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                    if (client != null)
                    {
                        var result = await client.TryInvokeAsync <IRemoteRenamerService, SerializableRenameLocations?>(
                            solution,
                            (service, solutionInfo, callbackId, cancellationToken) => service.FindRenameLocationsAsync(solutionInfo, callbackId, serializedSymbol, options, cancellationToken),
                            callbackTarget : new RemoteOptionsProvider <CodeCleanupOptions>(solution.Workspace.Services, fallbackOptions),
                            cancellationToken).ConfigureAwait(false);

                        if (result.HasValue && result.Value != null)
                        {
                            var rehydrated = await TryRehydrateAsync(
                                solution, symbol, fallbackOptions, result.Value, cancellationToken).ConfigureAwait(false);

                            if (rehydrated != null)
                            {
                                return(rehydrated);
                            }
                        }

                        // TODO: do not fall back to in-proc if client is available (https://github.com/dotnet/roslyn/issues/47557)
                    }
                }
            }

            // Couldn't effectively search in OOP. Perform the search in-proc.
            var renameLocations = await HeavyweightRenameLocations.FindLocationsInCurrentProcessAsync(
                symbol, solution, options, fallbackOptions, cancellationToken).ConfigureAwait(false);

            return(new LightweightRenameLocations(
                       symbol, solution, options, fallbackOptions, renameLocations.Locations,
                       renameLocations.ImplicitLocations.IsDefault ? null : renameLocations.ImplicitLocations.Select(loc => SerializableReferenceLocation.Dehydrate(loc, cancellationToken)).ToArray(),
                       renameLocations.ReferencedSymbols.IsDefault ? null : renameLocations.ReferencedSymbols.Select(sym => SerializableSymbolAndProjectId.Dehydrate(solution, sym, cancellationToken)).ToArray()));
        }
예제 #15
0
 private LightweightRenameLocations(
     ISymbol symbol,
     Solution solution,
     SymbolRenameOptions options,
     CodeCleanupOptionsProvider fallbackOptions,
     ImmutableHashSet <RenameLocation> locations,
     SerializableReferenceLocation[]?implicitLocations,
     SerializableSymbolAndProjectId[]?referencedSymbols)
 {
     Symbol          = symbol;
     Solution        = solution;
     Options         = options;
     FallbackOptions = fallbackOptions;
     Contract.ThrowIfNull(locations);
     Locations          = locations;
     _implicitLocations = implicitLocations;
     _referencedSymbols = referencedSymbols;
 }
예제 #16
0
 public HeavyweightRenameLocations(
     ISymbol symbol,
     Solution solution,
     SymbolRenameOptions options,
     CodeCleanupOptionsProvider fallbackOptions,
     ImmutableHashSet <RenameLocation> locations,
     ImmutableArray <ReferenceLocation> implicitLocations,
     ImmutableArray <ISymbol> referencedSymbols)
 {
     Solution        = solution;
     Symbol          = symbol;
     Options         = options;
     FallbackOptions = fallbackOptions;
     Contract.ThrowIfNull(locations);
     Locations         = locations;
     ReferencedSymbols = referencedSymbols;
     ImplicitLocations = implicitLocations;
 }
            private async Task <RenameTrackingSolutionSet> RenameSymbolWorkerAsync(CancellationToken cancellationToken)
            {
                var document = _snapshotSpan.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
                var newName  = _snapshotSpan.GetText();

                Contract.ThrowIfNull(document, "Invoked rename tracking smart tag but cannot find the document for the snapshot span.");

                // Get copy of solution with the original name in the place of the renamed name
                var solutionWithOriginalName = CreateSolutionWithOriginalName(document, cancellationToken);

                var symbol = await TryGetSymbolAsync(solutionWithOriginalName, document.Id, cancellationToken).ConfigureAwait(false);

                Contract.ThrowIfNull(symbol, "Invoked rename tracking smart tag but cannot find the symbol.");

                var options         = new SymbolRenameOptions(RenameOverloads: _stateMachine.TrackingSession.ForceRenameOverloads);
                var renamedSolution = await Renamer.RenameSymbolAsync(solutionWithOriginalName, symbol, options, newName, cancellationToken).ConfigureAwait(false);

                return(new RenameTrackingSolutionSet(symbol, solutionWithOriginalName, renamedSolution));
            }
예제 #18
0
        private static async Task <Solution> RenameAsync(
            Solution solution,
            IFieldSymbol field,
            string finalName,
            Func <DocumentId, TextSpan, bool> filter,
            CodeCleanupOptionsProvider fallbackOptions,
            CancellationToken cancellationToken)
        {
            var options = new SymbolRenameOptions(
                RenameOverloads: false,
                RenameInStrings: false,
                RenameInComments: false,
                RenameFile: false);

            var initialLocations = await Renamer.FindRenameLocationsAsync(
                solution, field, options, fallbackOptions, cancellationToken).ConfigureAwait(false);

            var resolution = await initialLocations.Filter(filter).ResolveConflictsAsync(
                field, finalName, nonConflictSymbolKeys: default, cancellationToken).ConfigureAwait(false);
예제 #19
0
        /// <summary>
        /// Find the locations that need to be renamed.
        /// </summary>
        public static async Task <RenameLocations> FindLocationsAsync(
            ISymbol symbol, Solution solution, SymbolRenameOptions options, CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(solution);
            Contract.ThrowIfNull(symbol);

            cancellationToken.ThrowIfCancellationRequested();

            using (Logger.LogBlock(FunctionId.Renamer_FindRenameLocationsAsync, cancellationToken))
            {
                if (SerializableSymbolAndProjectId.TryCreate(symbol, solution, cancellationToken, out var serializedSymbol))
                {
                    var client = await RemoteHostClient.TryGetClientAsync(solution.Workspace, cancellationToken).ConfigureAwait(false);

                    if (client != null)
                    {
                        var result = await client.TryInvokeAsync <IRemoteRenamerService, SerializableRenameLocations?>(
                            solution,
                            (service, solutionInfo, cancellationToken) => service.FindRenameLocationsAsync(solutionInfo, serializedSymbol, options, cancellationToken),
                            cancellationToken).ConfigureAwait(false);

                        if (result.HasValue && result.Value != null)
                        {
                            var rehydrated = await TryRehydrateAsync(
                                solution, result.Value, cancellationToken).ConfigureAwait(false);

                            if (rehydrated != null)
                            {
                                return(rehydrated);
                            }
                        }

                        // TODO: do not fall back to in-proc if client is available (https://github.com/dotnet/roslyn/issues/47557)
                    }
                }
            }

            // Couldn't effectively search in OOP. Perform the search in-proc.
            return(await FindLocationsInCurrentProcessAsync(
                       symbol, solution, options, cancellationToken).ConfigureAwait(false));
        }
예제 #20
0
        public static KeyValueLogMessage Create(
            SymbolRenameOptions options, UserActionOutcome outcome,
            bool conflictResolutionFinishedComputing, bool previewChanges,
            IList <InlineRenameReplacementKind> replacementKinds)
        {
            return(KeyValueLogMessage.Create(LogType.UserAction, m =>
            {
                m[RenameInComments] = options.RenameInComments;
                m[RenameInStrings] = options.RenameInStrings;
                m[RenameOverloads] = options.RenameOverloads;

                m[Committed] = (outcome & UserActionOutcome.Committed) == UserActionOutcome.Committed;
                m[Canceled] = (outcome & UserActionOutcome.Canceled) == UserActionOutcome.Canceled;

                m[ConflictResolutionFinishedComputing] = conflictResolutionFinishedComputing;
                m[PreviewChanges] = previewChanges;

                m[RenamedIdentifiersWithoutConflicts] = replacementKinds.Count(r => r == InlineRenameReplacementKind.NoConflict);
                m[ResolvableReferenceConflicts] = replacementKinds.Count(r => r == InlineRenameReplacementKind.ResolvedReferenceConflict);
                m[ResolvableNonReferenceConflicts] = replacementKinds.Count(r => r == InlineRenameReplacementKind.ResolvedNonReferenceConflict);
                m[UnresolvableConflicts] = replacementKinds.Count(r => r == InlineRenameReplacementKind.UnresolvedConflict);
            }));
        }
        private static async Task <Solution> RenameAsync(
            Solution solution,
            IFieldSymbol field,
            string finalName,
            Func <Location, bool> filter,
            CancellationToken cancellationToken)
        {
            var options = new SymbolRenameOptions(
                RenameOverloads: false,
                RenameInStrings: false,
                RenameInComments: false,
                RenameFile: false);

            var initialLocations = await Renamer.FindRenameLocationsAsync(
                solution, field, options, cancellationToken).ConfigureAwait(false);

            var resolution = await initialLocations.Filter(filter).ResolveConflictsAsync(
                finalName, nonConflictSymbols: null, cancellationToken).ConfigureAwait(false);

            Contract.ThrowIfTrue(resolution.ErrorMessage != null);

            return(resolution.NewSolution);
        }
 async Task <IInlineRenameLocationSet> IInlineRenameInfo.FindRenameLocationsAsync(SymbolRenameOptions options, CancellationToken cancellationToken)
 => await FindRenameLocationsAsync(
     options.RenameInStrings,
     options.RenameInComments,
     cancellationToken).ConfigureAwait(false);
예제 #23
0
                public async Task <IInlineRenameReplacementInfo> GetReplacementsAsync(string replacementText, SymbolRenameOptions options, CancellationToken cancellationToken)
                {
                    var newSolution = _oldSolution;

                    foreach (var group in Locations.GroupBy(l => l.Document))
                    {
                        var document  = group.Key;
                        var oldSource = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

                        var newSource = oldSource.WithChanges(group.Select(l => new TextChange(l.TextSpan, replacementText)));
                        newSolution = newSolution.WithDocumentText(document.Id, newSource);
                    }

                    return(new InlineRenameReplacementInfo(this, newSolution, replacementText));
                }
            public async Task <IInlineRenameReplacementInfo> GetReplacementsAsync(string replacementText, SymbolRenameOptions options, CancellationToken cancellationToken)
            {
                var conflicts = await _renameLocationSet.ResolveConflictsAsync(
                    _renameInfo.GetFinalSymbolName(replacementText), nonConflictSymbols : null, cancellationToken : cancellationToken).ConfigureAwait(false);

                Contract.ThrowIfTrue(conflicts.ErrorMessage != null);

                return(new InlineRenameReplacementInfo(conflicts));
            }
 async Task <IInlineRenameReplacementInfo> IInlineRenameLocationSet.GetReplacementsAsync(string replacementText, SymbolRenameOptions options, CancellationToken cancellationToken)
 => await GetReplacementsAsync(replacementText, cancellationToken).ConfigureAwait(false);
예제 #26
0
 public Task <IInlineRenameLocationSet> FindRenameLocationsAsync(SymbolRenameOptions options, CancellationToken cancellationToken) => Task.FromResult <IInlineRenameLocationSet>(null);
예제 #27
0
        public InlineRenameSession(
            IThreadingContext threadingContext,
            InlineRenameService renameService,
            Workspace workspace,
            SnapshotSpan triggerSpan,
            IInlineRenameInfo renameInfo,
            SymbolRenameOptions options,
            bool previewChanges,
            IUIThreadOperationExecutor uiThreadOperationExecutor,
            ITextBufferAssociatedViewService textBufferAssociatedViewService,
            ITextBufferFactoryService textBufferFactoryService,
            IFeatureServiceFactory featureServiceFactory,
            IEnumerable <IRefactorNotifyService> refactorNotifyServices,
            IAsynchronousOperationListener asyncListener)
        {
            // This should always be touching a symbol since we verified that upon invocation
            _threadingContext = threadingContext;
            _renameInfo       = renameInfo;

            _triggerSpan     = triggerSpan;
            _triggerDocument = triggerSpan.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (_triggerDocument == null)
            {
                throw new InvalidOperationException(EditorFeaturesResources.The_triggerSpan_is_not_included_in_the_given_workspace);
            }

            _inlineRenameSessionDurationLogBlock = Logger.LogBlock(FunctionId.Rename_InlineSession, CancellationToken.None);

            _workspace = workspace;
            _workspace.WorkspaceChanged += OnWorkspaceChanged;

            _textBufferFactoryService        = textBufferFactoryService;
            _textBufferAssociatedViewService = textBufferAssociatedViewService;
            _textBufferAssociatedViewService.SubjectBuffersConnected += OnSubjectBuffersConnected;

            // Disable completion when an inline rename session starts
            _featureService            = featureServiceFactory.GlobalFeatureService;
            _completionDisabledToken   = _featureService.Disable(PredefinedEditorFeatureNames.Completion, this);
            RenameService              = renameService;
            _uiThreadOperationExecutor = uiThreadOperationExecutor;
            _refactorNotifyServices    = refactorNotifyServices;
            _asyncListener             = asyncListener;
            _triggerView = textBufferAssociatedViewService.GetAssociatedTextViews(triggerSpan.Snapshot.TextBuffer).FirstOrDefault(v => v.HasAggregateFocus) ??
                           textBufferAssociatedViewService.GetAssociatedTextViews(triggerSpan.Snapshot.TextBuffer).First();

            _options        = options;
            _previewChanges = previewChanges;

            _initialRenameText   = triggerSpan.GetText();
            this.ReplacementText = _initialRenameText;

            _baseSolution    = _triggerDocument.Project.Solution;
            this.UndoManager = workspace.Services.GetService <IInlineRenameUndoManager>();

            if (_renameInfo is IInlineRenameInfoWithFileRename renameInfoWithFileRename)
            {
                FileRenameInfo = renameInfoWithFileRename.GetFileRenameInfo();
            }
            else
            {
                FileRenameInfo = InlineRenameFileRenameInfo.NotAllowed;
            }

            InitializeOpenBuffers(triggerSpan);
        }
        public async Task <IInlineRenameReplacementInfo> GetReplacementsAsync(string replacementText, SymbolRenameOptions options, CancellationToken cancellationToken)
        {
            var info = await _set.GetReplacementsAsync(replacementText, optionSet : null, cancellationToken).ConfigureAwait(false);

            if (info != null)
            {
                return(new FSharpInlineRenameReplacementInfoLegacyWrapper(info));
            }
            else
            {
                return(null);
            }
        }
 public async Task <IInlineRenameReplacementInfo> GetReplacementsAsync(string replacementText, SymbolRenameOptions options, CancellationToken cancellationToken)
 {
     var conflicts = await _renameLocationSet.ResolveConflictsAsync(
         _renameInfo.RenameSymbol, _renameInfo.GetFinalSymbolName(replacementText), nonConflictSymbolKeys : default, cancellationToken).ConfigureAwait(false);