コード例 #1
0
            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);
            }
コード例 #2
0
            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;
            }
コード例 #4
0
        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));
        }
コード例 #5
0
            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);
            }
コード例 #6
0
        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));
        }
コード例 #7
0
 public InlineRenameLocationSet(SymbolInlineRenameInfo renameInfo, RenameLocations renameLocationSet)
 {
     _renameInfo        = renameInfo;
     _renameLocationSet = renameLocationSet;
     this.Locations     = renameLocationSet.Locations.Where(RenameLocation.ShouldRename)
                          .Select(ConvertLocation)
                          .ToImmutableArray();
 }
コード例 #8
0
        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());
        }
コード例 #9
0
        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)));
        }
コード例 #10
0
ファイル: ConflictResolver.cs プロジェクト: jkotas/roslyn
        /// <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();
        }
コード例 #11
0
ファイル: ConflictResolver.cs プロジェクト: ruo2012/peachpie
        /// <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();
        }
コード例 #12
0
            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;
            }
コード例 #13
0
        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));
        }
コード例 #14
0
        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());
        }
コード例 #15
0
        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();
 }